Buffer Overflow , 내가 처음 만들고/공격하고/방어한 보안 취약점

특별한 이유가 있는 건 아니지만, 이번엔 Buffer Overflow 에 대해 써보고 싶었어요. 제가 처음으로 시도해본 공격이자, 동시에 처음으로 방어하는 방법을 배운 기법이기 때문이죠.

요즘은 메모리를 안전하게 관리해주는 언어들이 많아서 이런 문제를 직접 마주할 일은 줄었지만, 이 개념을 이해하고 있으면 다른 분야에서도 도움이 돼요.
생각해보면 임베디드나 IoT 시스템에서는 아직도 C++ 같은 언어를 많이 쓸까요? 저는 특정 분야에만 주로 있었던 터라 다른 업계에서는 요즘 어떤 게 표준인지 잘 모르겠네요. (Namu Wiki)


1. Buffer Overflow 란?

버퍼 오버플로우는 프로그램이 메모리 버퍼에 할당된 크기보다 더 많은 데이터를 쓸 때 발생합니다.
주로 C나 C++처럼 메모리 관리를 직접 해야 하는 언어에서 자주 발생해요.

공격자는 이 취약점을 악용해 프로그램 흐름을 바꾸거나, 악성 코드를 실행할 수 있어 보안상 매우 심각한 이슈입니다.


2. 주요 공격 유형

1) 스택 기반 오버플로우

  • 지역 변수 버퍼를 넘쳐서 리턴 주소를 덮어씀
  • 쉘코드를 삽입하고 실행 흐름을 탈취

2) 힙 기반 오버플로우

  • 동적으로 할당된 메모리를 공격
  • 함수 포인터나 객체 구조 변경 가능

3) 포맷 스트링 공격

  • %s, %x 같은 포맷 문자열을 악용
  • 메모리를 임의로 읽거나 쓸 수 있음

3. 예시 코드 (C)

#include <stdio.h>
#include <string.h>

void vulnerable_function() {
    char buffer[10];
    printf("Enter input: ");
    gets(buffer); // 위험! 길이 제한 없음
    printf("You entered: %s\n", buffer);
}

int main() {
    vulnerable_function();
    return 0;
}

설명:
buffer는 10바이트만 저장할 수 있지만, gets()는 입력 길이를 확인하지 않아요.
따라서 10자 이상 입력하면 인접한 메모리를 덮어쓸 수 있고, 심하면 리턴 주소까지 바뀔 수 있습니다.
실제 공격에서는 쉘코드를 삽입하거나 프로그램 흐름을 완전히 탈취할 수 있어요.


4. 방어 방법

  • gets() 같은 위험한 함수 대신 fgets() 사용
  • 스택 카나리(Stack Canary)로 오버플로우 탐지
  • ASLR(주소 공간 배치 무작위화) 활성화
  • NX 비트 설정으로 실행 불가능한 메모리 보호

마무리 생각

버퍼 오버플로우는 겉보기엔 단순한 프로그래밍 실수처럼 보이지만, 시스템 전체를 장악할 수 있는 심각한 취약점이에요.
요즘은 메모리 관리를 자동으로 해주는 언어를 많이 쓰니까 크게 신경 쓰지 않을 수도 있겠지만,
만약 임베디드나 저수준 프로그래밍을 하게 된다면 꼭 알아둬야 할 개념이에요.

By Mark

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다