level16 --- about to cause mass
우선 level16의 디렉터리를 확인한다.
attackme라는 의심스러운 파일이 존재한다. attackme는 level17의 권한을 가지고 있고, setuid가 걸려있는 파일이다.
우리가 공격할 대상이 attackme일 가능성이 크다고 생각하고 hint를 보자.
일반적인 실행흐름이라면 printit()함수를 실행하여 "Hello there!"를 실행하고 종료할것이다.
하지만 shell() 함수가 있고 level17의 배시셸을 띄우는 것을 확인할 수 있다.
즉, 우리가 buf를 통해 printit()의 주소를 shell()의 주소로 수정하면 shell 함수가 실행되면서 level17의 쉘이 뜰 것이다.
gdb를 통해 attackme를 분석하자.
hint의 소스코드를 보면 int crap(4 byte), void *(call) (4 byte), char buf[20](20 byte)를 통해 총 0x1C(28 byte)가 할당된다고 예상할 수 있다.
하지만 gdb를 통해 분석해보면 0x38(56 byte)가 할당되었음을 확인할 수 있다.
28 byte의 dummy가 gcc에 의해 생성된 것이다.
dummy가 어디부분에 얼마만큼 삽입되었는지 확인하기 위해 아래 소스를 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <stdio.h> void shell() { setreuid(3097,3097); system("/bin/sh"); } void printit() { printf("Hello there!\n"); } main() { int crap; void (*call)()=printit; char buf[20]; fgets(buf,48,stdin); call(); printf(" INput is : %s\n &buf : %p\n &call : %p\n &crap : %p\n", buf, buf, &call, &crap); } | cs |
위 소스를 컴파일하고 실행하면 아래와 같은 결과를 얻을 수 있다.
주소값을 보고 메모리를 그려보면 아래와 같이 그려볼 수 있다.
즉, 우리는 *call()의 주소를 shell()함수의 시작주소로 바꾸면 shell() 함수를 실행시킬 수 있다.
shell() 함수의 시작주소를 알기위해 gdb를 사용한다.
shell 함수가 존재한다는것을 알기 때문에 "disas shell"을 통해서 shell() 함수의 주소를 알 수 있다.
이제 attackme를 공격 가능하다.
40개의 dummy + shell함수의 주소를 이용해 공격하자.
'Wargame > FTZ' 카테고리의 다른 글
해커스쿨 FTZ level18 (0) | 2018.08.05 |
---|---|
해커스쿨 FTZ level17 (0) | 2018.08.04 |
해커스쿨 FTZ level15 (0) | 2018.08.04 |
해커스쿨 FTZ level14 (0) | 2018.08.02 |
해커스쿨 FTZ level13 (스택 가드) (0) | 2018.08.02 |