tmxklab
[FTZ] Level16 풀이 본문
1. 문제확인
1) 사용자 및 패스워드 : level16 / about to cause mass
2) 파일확인
3) hint 코드 설명
#include <stdio.h>
// level17 쉘 권한 획득할 수 있는 함수
void shell(){
setreuid(3097, 3097);
system("/bin/sh");
}
void printit(){
printf("Hello there!\n");
}
main()
{ int crap;
void (*call)()=printit; // 함수 포인터call변수가 printit함수의 주소를 가리킴
char buf[20];
fgets(buf, 48, stdin);
call(); // printit함수 호출
}
- shell()은 level17 쉘 권한을 획득할 수 있는 함수이며 printit()은 printf() 한 줄
- 함수 포인터 call변수가 printit()를 호출하도록 되어있음
- fgets()로 인해 buf(20bytes)배열의 크기보다 더 큰 입력 받을 수 있음 -> bof 취약점 존재
2. 접근방법
1) attackme 디버깅
- mov DWORD PTR [ebp-16], 0x8048500 : 0x8048500 printit()의 시작 주소 값이므로 함수 포인터의 위치가 [ebp-16]임을 알 수 있음
- <main+24>부터 보면 eax에 [ebp-56]의 주소 값을 넣고 push한 뒤 fgets함수를 호출함 → fgets함수의 첫 번째 인자는 buf이므로 buf의 위치는 [ebp-56]
- <main+36>부터 보면 eax에 [ebp-16]의 값을 넣고 call에 의해 호출함(정상 흐름에는 printit함수가 호출됨)
- shell() 시작 주소 값 : 0x080484d0
- printit() 시작 주소 값 : 0x08048500
2) 스택구조
3) 결론
- printit()대신에 shell()를 호출하기 위해 함수 포인터 call변수에 shell()의 시작 주소 값을 넣어야 함
- 따라서, fgets()를 통해서 buf배열의 크기(20bytes)보다 더 큰 입력 값을 받을 수 있으므로 call변수의 위치를 찾아 shell()의 시작 주소 값을 채워 넣으면 됨
- buf에 call변수 직전인 40bytes만큼 쓰레기 값을 채우고 다음에 오는 call 변수에 shell()의 시작 주소 값인 0x080484d0을 채워 넣으면됨
3. 풀이
1) 공격 코드 작성
buf[20bytes] + dummy[20bytes] + call[4bytes, shell() 시작 주소 값]
2) bof 수행
'War Game > FTZ' 카테고리의 다른 글
[FTZ] Level18 풀이 (0) | 2020.01.12 |
---|---|
[FTZ] Level17 풀이 (0) | 2020.01.12 |
[FTZ] Level15 풀이 (0) | 2020.01.12 |
[FTZ] Level14 풀이 (0) | 2020.01.12 |
[FTZ] Level13 풀이 (0) | 2020.01.12 |
Comments