护网杯预选赛 WP
转载自:https://qingchenldl.github.io/2018/10/13/%E6%8A%A4%E7%BD%91%E6%9D%AFWP-BitPwn/#more
WEB easy tornado
http://49.4.79.198:31809/file?filename=Orz.txt&signature=0434ba1fadd43ce31661c315fbb8a9c6
Orz.txt render()
http://49.4.79.198:31809/file?filename=hint.txt&signature=78423a4ae34f2a6e9088a35ef650af22
hint.txt md5(cookie_secret + md5(filename))
http://49.4.79.198:31809/file?filename=flag.txt&signature=dbc862f7ca4cd3dd4ba82c6e7ff6d6af
flag.txt /fllllllllllag
容易看出来,读文件的url就是,filename=(想读的文件名)加上一个签名,而签名是md5(cookie_secret + md5(filename))
问题就在于cookie_secret是什么。又看到Orz.txt里面有提示 render(),这个是生成模板的函数,于是想到模板注入STTI。
在读取文件失败的这个链接中,发现STTI漏洞:
结合Tornado框架,想到的是:
在Tornado的前端页面模板中,Tornado提供了一些对象别名来快速访问对象,具体定义可以参考Tornado官方文档!
这里我想将的是Handler这个对象,Handler指向的处理当前这个页面的RequestHandler对象!
于是payload为:
得到cookie_secret,利用这个cookie_secret,可以写脚本,来获得相应文件的签名值。
ltshop
¥5一包辣条
5包辣条换一包辣条王
9999999包辣条王换flag
看到第三个要求,很容易想到不是常规解法,可能会用到溢出。
但是问题在于就算是溢出,我们也应该至少能换一个辣条之王才行,但是我们只有20元,只能买4包辣条,一个辣条之王也换不了。
这里算是纠结了一下,最后想到利用条件竞争,试验发现一个账户的两个登陆同时买辣条,只会扣一次钱,却会得到两个辣条。利用burpsuite进行条件竞争:
这里多设置几个线程
看到已经购买到很多的辣条
再看此时的账户,已经有足够的辣条了。
下面考虑溢出:
**
int: 2**32-1 = 4294967295
long: 2**63 -1 = 9223372036854775807
longlong: 2**64-1 = 18446744073709551615
**
但是要注意一点,这个题的逻辑是,numer*5<最大值
所以,其临界值应该为:18446744073709551615 / 5 == 3689348814741910323
于是尝试:3689348814741910323+1 == 3689348814741910324
溢出后的值比较小,在辣条的数量之内,从而兑换成功。
注意另一点,溢出的时候不能太大,因为太大导致溢出后的值过大而超过辣条的数量,出现这种情况
此时的账户:
再兑换flag,即可:
PWN
gettingstart
用 IDA 打开程序:
发现可以溢出 buf 从而修改掉 v7 和 v8 的值来通过验证,所以构造利用脚本:
得到 flag :flag{e47ba37e5e4fe4d6538f91955c63ef23}
Misc
迟来的签到题
easy xor???
提示xor,base64解码后异或
写个脚本爆破下
import base64
Crypto
fez
fez.py
fez.log
048d26224aae9f6be49f13202c0b173c2346909fcbba868d5d9b7431002957c5c01c546530f84e45b8a3892526401c007bca7d39b0b7
69d41820c61c7e8fb47fde8f09064f24af72dc6251e97e72bdc2d7c0b4696110ef84f30da6ac88b7059500f8e814cec9e9e13bcafad8
32e7094533a1e76ac8acdeb882c0d6965ca954d75dfd00e759b5aff9663f41d49ae70ee18fd3c067ad7ae577433ad2512b764f4b2eb2
Feistel加密方法,轮函数也是异或
这里给出了print出的值,所以知道
**
**
test和用flag填充的m的长度都为54
加密使用的K值是不知道的,所以写不出解密函数,但可以通过给出的testans与ans异或使K消掉
记最后一轮flag加密后的为L7和R7,test加密的为tL7和tR7,初始test为tL0和tR0
则ai=tLi^Li=tRi+1^Ri+1^tLi+1^Li+1
而且Ri=Li+1
所以ai=ai+1^tLi+1^Li+1
最终得到L0和R0
exp
import os def xor(a,b):
assert len(a)==len(b)c=""for i in range(len(a)): c+=chr(ord(a[i])^ord(b[i]))return ctest='048d26224aae9f6be49f13202c0b173c2346909fcbba868d5d9b7431002957c5c01c546530f84e45b8a3892526401c007bca7d39b0b7'.decode('hex')
testans='69d41820c61c7e8fb47fde8f09064f24af72dc6251e97e72bdc2d7c0b4696110ef84f30da6ac88b7059500f8e814cec9e9e13bcafad8'.decode('hex')
ans='32e7094533a1e76ac8acdeb882c0d6965ca954d75dfd00e759b5aff9663f41d49ae70ee18fd3c067ad7ae577433ad2512b764f4b2eb2'.decode('hex')tL7=testans[0:27] tR7=testans[27:54] L7=ans[0:27] R7=ans[27:54]
tL0=test[27:54] tR0=test[0:27]
a6=tR7^R7^tL7^L7^tR1
tL6^L6 a6=xor(xor(tR7,R7),xor(tL7,L7))
a5=xor(xor(tL7,L7),a6)
a4=xor(a6,a5)
a3=xor(a5,a4)
a2=xor(a4,a3)
a1=xor(a3,a2)
a0=xor(a2,a1)
L0=xor(tL0,a1)
R0=xor(tR0,a0)
print R0+L0
运行结果:
**λ python fez_exp.py
flag{festel_weak_666_lol88fj3820}叡↓泺y蝵:;铸醛o磋萸?**