⊙ 문제의 소스를 보자) |
[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 |