Level16 풀이.
pw = 'about to cause mass'
일단 c 코드가 나왔는데 본 것도 있고, 처음 보는 것도 있다.
슥 보니 fgets가 있는 것으로 보아 버퍼 오버플로우가 발생할 것이다. 한 줄씩 분석해보자.
일단 void shell()은 shell이라는 함수가 있는 정도가 setreuid(3097,3097)은 shell이 실행되면 다음 level17 권한으로 실행되는 것으로 보인다.
system(“/bin/sh”) 은 /bin/sh의 쉘을 실행한다.
void printit()는 printit 함수이고, printf(“hello there!\n”); 주어진 hello there!를 출력.
main 아래부터 설명하면, int crap은 변수 crap를 선언. void(*call)()=printit; 함수포인터 call를 선언하고, printit를 대입한다. char buf[20] 20byte 크기의 buf 배열을 선언.
fgets(buf,48,stdin); 최대 48byte 까지 입력받아 buf에 저장.
call(); 함수포인터 call을 실행.
일단 함수 포인터는 간단히 말해 하수를 가리키고 있는 포인터이고, 포인터는 메모리의 주소를 가리킨다. 함수도 시작되는 주소가 있으므로, 포인터로 함수를 가리키는 게 가능하다.
일단 return type (*변수명)(인수의 목록);
void (*call) () 인수의 목록에는 call이 가리키고 있는 함수에서 필요한 것들 들어간다.
ex)int a,int b 이 문제에서는 함수 포인터가 printit 함수를 가리키도록 하고 있다.
즉 call을 실행하면, printit 함수가 실행 될 거다.
일단 제대로 실행이 되면 “Hello there” 가 화면에 출력되고 종료될 것이다. 그래서 결국 마지막에는 shell 함수가 실행되도록 해야 한다.
즉 buf에서 버퍼 오버플로우를 일으켜서 함수 포인터 *call부분에 shell 함수의 주소를 덮어 씌우는 것.
일단 gdb 실행.
일단 main + 24 = lea eax,[ebp-56] 부분을 보면, buf에서 ebp 거리를 확인 할 수 있다. 즉 거리는 56
main + 36 = mov eax, DWORD PTR[ebp-16] call에서 ebp까지의 거리를 확인 가능. 즉 거리는 16.
buf[20] - call 까지 거리 = (buf[20] - ebp까지 거리) - (call – ebp까지 거리) = 56 –16 = 40.
쉘 주소는 0x80484d0 이다. p shell.
즉 이제는 buf-call거리 + shell 함수의 주소
python –c ‘print“\x90”*40+“\xd9\x84\x04\x08:’cat | ./attackme.
CF) 끝. 이 문제도 BOF 문제이다. BOF가 중요한 거 같다.