1. 풀이
- hint 파일을 통해 level16과 달리 printit() 함수만 선언되어있고, (*call) 함수 포인터 또한 printit으로 초기화 되어있음
- level16에서는 상위 level의 권한을 부여하고 /bin/sh로 쉘을 실행하였으나, level17에서는 쉘코드를 작성하여 (*call) 함수 포인터의 값을 쉘코드의 주소로 덮어쓰면 문제를 풀 수 있음을 예상
① Procedure Prelude
0x080484a8 <main+0>: push %ebp
0x080484a9 <main+1>: mov %esp,%ebp
0x080484ab <main+3>: sub $0x38,%esp
- 지역변수에 56byte(0x38) 할당
② void (*call)()=printit;
0x080484ae <main+6>: movl $0x8048490,0xfffffff0(%ebp)
- (*call) 함수 포인터에 $0x8048490 값 즉, printit() 함수의 주소를 저장
- printit() 함수를 disassembly 하면 시작 주소를 알 수 있으며, (*call) 함수 포인터는 0xfffffff0에 저장되어 있는것을 알 수 있음.
③ fgets(배열, 문자 길이, STDIN)
0x080484b8 <main+16>: pushl 0x804967c // STDIN
0x080484be <main+22>: push $0x30 // 문자길이 (0x30 = 48)
0x080484c0 <main+24>: lea 0xffffffc8(%ebp),%eax // 0xffffffc8 (buf의 주소)
0x080484c3 <main+27>: push %eax // buf 주소
0x080484c4 <main+28>: call 0x8048350 <fgets>
- 즉, fgets()를 통해 0xffffffc8 (buf의 주소)에 사용자 입력값을 받음
- ②와 ③을 통해 buf와 (*call) 사이에 20byte 만큼의 dummy가 있으며, 나머지 12 byte 공간에 crap(4byte)+dummy(8byte)가 저장되어 있음
- fgets() 실행 후인 main+33 지점에 bp 설정 및 level17 실행 후 esp 메모리 값을 확인
- 위 결과를 통해 메모리 결과를 예측해보면 다음과 같음
④ setreuid(0xc1a,0xc1a) 및 call()
0x080484cf <main+39>: push $0xc1a
0x080484d4 <main+44>: push $0xc1a
0x080484d9 <main+49>: call 0x8048380 <setreuid>
0x080484de <main+54>: add $0x10,%esp
0x080484e1 <main+57>: mov 0xfffffff0(%ebp),%eax
0x080484e4 <main+60>: call *%eax
- level18 권한 부여 후 call()
- 따라서, (*call) 함수 포인터가 가리키는 주소를 shellcode의 주소로 덮어쓴다면, level18의 쉘읠 획득할 수 있을것
'문제풀이 > FTZ' 카테고리의 다른 글
FTZ Level19 풀이 (0) | 2022.11.08 |
---|---|
FTZ Level18 풀이 (0) | 2022.11.07 |
FTZ Level16 풀이 (0) | 2022.11.05 |
FTZ Level15 풀이 (0) | 2022.11.05 |
FTZ Level14 풀이 (0) | 2022.11.05 |