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

+ Recent posts