Protostar - Stack 3 (버퍼 오버플로우 공격 + 메모리 참조)

oolongeya

·

2021. 8. 24. 11:57

stack3.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#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();
  }
}
cs

 

win 함수가 실행되면 code flow successfully changed 라는 문구가 출력된다.

아마 저 win 함수를 실행하는 것이 이 문제의 목표일 것

 

volatile int (*fp) 부분에서

 

*fp라는 것은 메모리 주소를 저장할 수 있는 포인터 변수 fp를 선언한 것이다.

 

아래 부분에는 만약 fp 라면 출력하고, 마지막에 fp(); 로 fp 주소를 실행한다.

 

win 함수의 위치를 확인해보자

disas win 으로 주소값을 확인하거나

 

p win 으로 시작주소만 확인할 수 있다.

 

main+40 부분에서 cmp 하는 부분이 있는데 0x0과 [rbp-0x8] 의 값을 비교한다.

그렇게 해서 main+45 부분, je 만약 두 값이 같다면 main+82로 점프한다.

 

아마 if 문일 것이다. if(fp) fp값이 0과 같다면 중간 과정을 생략해버리고 함수의 끝으로 가는 것 같다.

 

실제로 간단한 값을 입력 후 fp값을 확인해보면,

 

0인 것을 알 수 있다. 0과 비교해서 같으니 중간 과정 생략이라고 생각하면 된다.

 

즉 이 fp 주소를 win 함수의 시작 주소로 덮어씌우면 되는 것

 

cmp 부분에 브레이크 포인트를 걸고 시작해보겠다.

 

peda를 이용해 패턴을 만들고 패턴값을 입력한다.

 

 

0x4134414165414149 값이 들어가있고

 

몇 바이트의 거리인지 확인한다.

 

패턴을 만들고 사용할 때 주의할점은 

 

' 패턴 ' 구조인데, 복사해서 사용할 때는 양 끝의 ' ' 는 복사하는게 아니다.

패턴만 복사해서 사용해야한다.

 

이후 a를 72개 패딩한 뒤 win의 주소값을 덮어서 입력

 

플래그를 얻을 수 있다.

 

이 방법이 아닌 다른 방법으로도 플래그를 얻을 수 있다.

 

이 내용은 아래의 링크를 참고하고 pwn을 먼저 설치해야한다.

 

https://kkomii22.tistory.com/50

 

최신 칼리 리눅스 pwn 설치, 오류 해결

리눅스에서 자동, 무작위값, 빠르게 반복 행위 같은 경우 해킹대회에서 필요한 경우도 있는데, 이 경우 pwn을 이용하면 쉽게 문제를 해결할 수 있다. pwn 설치를 위해 터미널을 이용하는데 루트 권

kkomii22.tistory.com

 

 

stack3_attack.py 파일을 생성해준다.

 

 

 

 

ImportError : No module named pathlib2 오류 발생 시

pip install pathlib2 명령어를 통해 설치할 수 있다.

 

아래 처럼 작성한 뒤

 

python stack3_attack.py 로 입력하면 된다.

 

반응형