본문 바로가기

WARGAME/hackerschool ftz,lob

[해커스쿨 ftz] level 15 -> level 16

hint
#include <stdio.h>

main ()
{
int crap;
int *check;
char buf[20];

fgets(buf, 45, stdin);
if ( *check == 0xdeadbeef)
{
setreuid(3096, 3096);
system("/bin/sh");
}
}



풀이
1. 변수 check가 포인터 변수가 되어서 이 곳에 0xdeadbeef를 직접 넣으면 안되고, 0xdeadbeef값이 담긴 주소값을 넣어줘야 한다.
그러기 위해서 buf의 20바이트를 0xdeadbeef로 채우고 포인터 변수 check에 buf의 시작 주소를 적어 넣으면 분기문 안으로 들어가 쉘을 얻을 수 있다.
1-1 $ cp attackme ./tmp/attackme
1-2 gdb attackme
1-3 disas main
1-4 b *main+26
1-5 r
1-6 AAAAAAAAAAAAAAA
1-7 x/16xw $esp
1-8 변수 buf의 위치 확인


는 실패하였다. ASLR이 걸려있지 않은데 ebp의 위치가 계속 바뀐다. 
따라서, 스택 구조를 완벽히 알아보고 brute force 하기로 한다.

다시 풀이
1. gdb를 이용하여 스택 구조 확인 

위 그림을 보면 총 56바이트를 할당하고 있고, fget()함수의 매개변수로 buf를 넣는데, ebp-56의 위치에서 가져오고 있다.

또한, 밑의 main+32에서 분기문에 들어가기 위해 변수 check를 ebp-16에서 가져오고 있다.

그럼 스택 구조는 다음과 같이 추측 할 수 있다.

low address ... | buf[20] | dummy[20] | check(4) | dummy[8] | crap(4) | sfp(4) | ret | ... high address


확인해보기 위해 다음과 같이 간단한 소스를 작성하여 gdb로 확인해본다.




그러면 아래와 같이 스택 구조를 알 수 있다.

low address ... | buf[20] | dummy[20] | check(4) | crap(4) | dummy[8] | sfp(4) | ret | ... high address


이제 이를 이용하여 buf에는 0xdeadbeef를 넣고 check에는 0xbfffffff부터 감소하며 주소값을 넣어본다.


2. brute force 

다음과 같이 소스를 작성하고 실행한다.



그러면 0xbfffeace 에서 쉘이 떨어진다.