1. 풀이

- level17의 권한을 부여하고 /bin/sh를 실행하는 shell() 함수와 문자를 출력하는 printit() 함수가 존재

- (*call) 함수 포인터를 printit() 함수 시작주소로 초기화 및 fgets()로 사용자 입력을 받은 후 call() 호출

- 즉, (*call)를 shell() 함수의 주소를 가리키게 한다면 문제를 풀 수 있을 것임

 

 

 Procedure Prelude

0x08048518 <main+0>:    push   %ebp
0x08048519 <main+1>:    mov    %esp,%ebp
0x0804851b <main+3>:    sub    $0x38,%esp

- 지역변수에 56byte(0x38) 할당

 

② void (*call)()=printit;

0x0804851e <main+6>:    movl   $0x8048500,0xfffffff0(%ebp) // printit() 함수 주소

- (*call) 함수 포인터에 $0x8048500 값 즉, printit() 함수의 주소를 저장

- printit() 함수를 disassembly 하면 시작 주소를 알 수 있으며, (*call) 함수 포인터는 0xfffffff0에 저장되어 있는것을 알 수 있음.

- 또한,같은 방법으로 shell() 함수의 시작 주소(0x080484d0)를 알 수 있음

 

③ fgets(배열, 문자 길이, STDIN)
0x08048528 <main+16>:   pushl  0x80496e8 // STDIN
0x0804852e <main+22>:   push   $0x30 // 문자길이 (0x30 = 48)
0x08048530 <main+24>:   lea    0xffffffc8(%ebp),%eax // 0xffffffc8 (buf의 주소)
0x08048533 <main+27>:   push   %eax // buf 주소
0x08048534 <main+28>:   call   0x8048384 <fgets> 
- 즉, fgets()를 통해 0xffffffc8 (buf의 주소)에 사용자 입력값을 받음

- ②와 ③을 통해 buf와 (*call) 사이에 20byte 만큼의 dummy가 있으며, 나머지 12 byte 공간에 crap(4byte)+dummy(8byte)가 저장되어 있음

- fgets() 실행 후인 main+33 지점에 bp 설정 및 level16 실행 후 esp 메모리 값을 확인

 

④ call()
0x0804853c <main+36>:   mov    0xfffffff0(%ebp),%eax
0x0804853f <main+39>:   call   *%eax

- printit() 호출

 

-  메모리 구조는 위 그림과 같으며, 아래 그림 처럼 (*call) 함수 포인터를 shell() 함수의 주소로 설정할 경우 쉘을 획득할 수 있음

 

- buf와 dummy의 40byte 만큼의 NOP 슬라이드와 shell() 함수의 시작주소를 Littel Endian 방식으로 페이로드 작성

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level18 풀이  (0) 2022.11.07
FTZ Level17 풀이  (0) 2022.11.07
FTZ Level15 풀이  (0) 2022.11.05
FTZ Level14 풀이  (0) 2022.11.05
FTZ Level13 풀이  (0) 2022.11.04

+ Recent posts