이번에 풀이할 문제는 HackCTF의 BOF_PIE 문제다. 문제 명만 봤을 때는 pie 보호 기법이 걸린 상태로 bof 공격을 해야 할 것 같다.
마찬가지로 bof_pie라는 이름의 elf 파일이 주어져 있으니, 동작 확인 -> 보호 기법 확인 -> 코드 확인 순서로 풀이를 진행하겠다.
문제 파일을 실행하면 "Hello, Do you know j0n9hyun?"과 "j0n9hyun is 0x56555909"라는 알 수 없는 16진수 값이 출력된 후 입력을 받는다. 입력 값으로 1을 주니 "Nah ..."가 출력됐다.
보호 기법을 확인해보니 NX bit와 문제 이름처럼 PIE 보호 기법이 걸려 있는 것을 볼 수 있다.
main 함수는 welcome 함수를 호출한 뒤 "Nah..."를 출력해준 뒤 종료된다. welcome 함수를 확인해보겠다.
welcome 함수에서 문구들이 출력되는 것을 알 수 있다. 또한 앞서 봤던 알 수 없는 16자리 값은 welcome의 주소라는 것을 알 수 있다. 문구들이 출력된 후 scanf 함수를 통해 입력을 받는데, 이 때 서식 지정자가 %s인 것을 알 수 있다. 이럴 경우 입력 값의 제한이 없어지기 때문에 스택 오버플로우가 발생한다.
NX bit가 걸려 쉘 코드 삽입을 할 수 없으므로 혹시 shell이나 flag를 얻게 해주는 함수가 있는지 찾아봤다.
j0n9hyun 함수에서 flag를 출력해주는 로직이 존재함을 알 수 있다. 마음 같아서는 ret를 위 사진의 함수 주소로 변조하고 싶지만 pie 기법이 걸려 있기 때문에 단순한 방법으로는 안된다.
지금까지 관찰해본 바에 따르면 이 pie 보호 기법의 특징은 랜덤한 base 주소가 정해진 후, 이 주소 + 원래 함수의 주소로 함수 주소가 매핑된다는 것이다.(지금까지 겪은 바를 통한 추론이기 때문에 확실하지는 않다.)
웬만한 케이스에서 pie 보호 기법이 걸려 있다면 ret 변조로 exploit 하기는 힘들지만, 이 문제의 경우 맨 처음에 welcome 함수의 주소가 출력됐으므로 (출력된 welcome 주소) - (매핑되기 전 welcome 함수의 주소)를 연산한다면 base 주소를 알 수 있게 된다.
얻은 base 주소에 매핑되기 전 j0n9hyun 함수의 주소를 더한다면 랜덤한 주소로 매핑된 j0n9hyun 함수의 주소를 알 수 있게 된다.
이 주소로 ret를 변조한다면 flag를 얻을 수 있을 것이다.
일단 welcome과 j0n9hyun의 매핑 전 주소를 gdb를 통해 확인해보겠다.
주소를 확보했으므로 바로 exploit 코드를 작성하겠다.
from pwn import *
payload = b'A'*22
flag_addr = b"890"
#p = process('./bof_pie')
p = remote('ctf.j0n9hyun.xyz', 3008)
p.recvuntil('j0n9hyun is ')
address = p.recvline()[:-2]
address = address[:-2]+flag_addr
print(address)
payload += p32(int(address,16))
p.sendline(payload)
p.interactive()
원래는 위에서 말한 대로 base 주소를 매핑 후 welcome 주소 - 매핑 전 welcome 주소로 구하려 했지만, 여러 번 실행시켜보니 함수의 뒤 세 자리 주소는 고정이라는 것을 깨달았다.
출력되는 welcome 주소의 뒤 세 자리를 제외한 나머지 자리 주소를 base 주소라고 가정하고, 구한 base 주소에 j0n9hyun의 뒤 세 자리 주소를 더해준 후 ret를 변조시켜서 풀었다.
'Wargame > HackCTF' 카테고리의 다른 글
[HackCTF] RTL_World (0) | 2021.06.30 |
---|---|
[HackCTF] Yes or no (0) | 2021.05.25 |
[HackCTF] Offset (0) | 2021.05.11 |
[HackCTF] Simple_Overflow_ver_2 (0) | 2021.05.11 |
[HackCTF] Basic_FSB (2) | 2021.05.05 |