SH1R0_HACKER
stack 3 본문
stack3.c
#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();
}
}
새로운 win() 함수가 등장했다.
우리의 목표는 이 함수를 실행시키는 것이다.
하지만 main 함수에 win() 함수를 실행하는 부분은 존재하지 않아서 fp를 변조해야 할 것 같다.
[ 취약점 파악 및 분석 ]
1. disas main
2. disas win
아래는 어셈블리어 해석이다.
1. main
0x08048438 <+0>: push ebp
0x08048439 <+1>: mov ebp,esp
0x0804843b <+3>: and esp,0xfffffff0
0x0804843e <+6>: sub esp,0x60
0x08048441 <+9>: mov DWORD PTR [esp+0x5c],0x0
// 변수 fp : esp+0x5c
0x08048449 <+17>: lea eax,[esp+0x1c]
// 변수 buffer : esp+0x1c
0x0804844d <+21>: mov DWORD PTR [esp],eax
0x08048450 <+24>: call 0x8048330 <gets@plt>
0x08048455 <+29>: cmp DWORD PTR [esp+0x5c],0x0
// fp가 0이랑 같은지 비교
0x0804845a <+34>: je 0x8048477 <main+63>
0x0804845c <+36>: mov eax,0x8048560
0x08048461 <+41>: mov edx,DWORD PTR [esp+0x5c]
0x08048465 <+45>: mov DWORD PTR [esp+0x4],edx
0x08048469 <+49>: mov DWORD PTR [esp],eax
0x0804846c <+52>: call 0x8048350 <printf@plt>
// x/s 0x8048560 "calling fuction pointer, jumping to 0x%08x\n"
0x08048471 <+57>: mov eax,DWORD PTR [esp+0x5c]
0x08048475 <+61>: call eax
0x08048477 <+63>: leave
0x08048478 <+64>: ret
2. win
0x08048424 <+0>: push ebp
0x08048425 <+1>: mov ebp,esp
0x08048427 <+3>: sub esp,0x18
0x0804842a <+6>: mov DWORD PTR [esp],0x8048540
// "code flow successfully changed"
0x08048431 <+13>: call 0x8048360 <puts@plt>
0x08048436 <+18>: leave
0x08048437 <+19>: ret
fp의 위치 : esp+0x5c
buffer의 위치 : esp+0x1c
이 문제를 풀기 위해서는 fp 변수의 값을 win 함수의 시작주소로 수정해야한다.
buffer 변수를 가득 채우고 다음 스택에 존재하는 fp변수를 수정하자.
[ Exploit ]
1. buffer 변수와 fp 변수의 거리
64byte
2. win() 함수의 시작주소
0x8048424
A를 64byte만큼 쓰고 그 fp에 win() 함수의 시작주소를 리틀엔디언으로 작성한다.