백악관에서 C와 C++ 사용 중단 촉구? : 메모리 엑세스 취약성 이란?

한 문장으로 요약하면 백악관에서 C와 C+의 메모리 취약성 때문에 사용 중단을 촉구한다는 내용입니다.

메모리 엑세스 취약성

5문장 정도로 요약하면 아래와 같습니다.

미국 대통령 조 바이든의 행정부가 소프트웨어 개발자들에게 취약한 언어인 C와 C++ 사용 중단을 촉구했습니다. 대신 메모리 안전 프로그래밍 언어를 사용하라고 권고했습니다. 이러한 권고는 사이버 공격 위험을 감소시키기 위한 것으로, 메모리 안전 언어는 소프트웨어 버그 및 취약성으로부터 안전합니다. 현재의 취약점 중 70%는 메모리 안전 문제에서 비롯된 것으로 나타났습니다. 국가 사이버 책임자는 이를 통해 모든 종류의 취약점을 방지할 수 있다고 설명했습니다. 국가 사이버 보안 국도 메모리 안전 프로그래밍 언어 사용을 촉구하며, 러스트를 안전한 예로 언급했습니다. 전문가들은 C와 C++에서 다른 안전한 언어로의 전환은 어려울 수 있지만, 변화가 필요하다고 강조하고 있습니다.

이 기사를 읽고 궁금한 점이 2가지 생겼습니다.

  1. 메모리 취약성이란 무엇이며
  2. 메모리 안전 언어와 메모리 취약 언어는 무엇일까?

메모리 취약성

메모리 취약성은 주로 프로그래밍에서 발생하는 오류로, 개발자가 코드를 작성할 때 실수로 메모리를 잘못 다루거나 부주의한 코드를 작성할 때 나타납니다. 여기서 메모리는 컴퓨터의 작업 공간을 의미하며, 프로그램이 실행되는 동안 데이터를 저장하고 처리하는 곳입니다.

간단하게 설명하면, 프로그램이 메모리를 관리하지 않거나 잘못된 방식으로 사용할 때 발생하는 문제입니다.

이로 인해 해커들이 공격을 시도하여 시스템에 피해를 줄 수 있습니다.

메모리 취약성의 주요 원인

버퍼 오버플로우 (Buffer Overflow)

프로그램이 특정 데이터를 처리할 때 할당된 메모리 공간을 넘어가게 되면 발생합니다. 이는 공격자가 악의적인 데이터를 주입하여 프로그램의 흐름을 조작할 수 있는 위험을 초래합니다.

버퍼 오버플로우의 가장 흔한 상황 중 하나는 문자열을 저장하는 배열에서 발생하는 경우입니다. 예를 들어, 다음과 같은 C 언어의 코드가 있다고 가정해봅시다

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

int main() {
    char buffer[5]; // 크기가 5인 문자열을 저장할 수 있는 배열

    // 사용자로부터 입력을 받음
    printf("문자열을 입력하세요: ");
    gets(buffer);

    // 입력받은 문자열을 출력
    printf("입력한 문자열: %s\n", buffer);

    return 0;
}

위 코드에서 buffer는 크기가 5인 배열로 선언되었습니다. 그런데 사용자가 5자 이상의 긴 문자열을 입력하면 어떻게 될까요?

예를 들어, 사용자가 “HelloWorld”라는 10자리 문자열을 입력한다면, 이 문자열은 buffer 배열의 크기를 초과하게 됩니다. 이때, “HelloWorld”의 일부 또는 전체가 다른 메모리 주소에 영향을 미치게 되어 예상치 못한 결과가 발생할 수 있습니다.

버퍼 오버플로우는 메모리를 할당받은 배열이나 버퍼의 경계를 넘어서 데이터가 쓰여질 때 발생하며,

이는 프로그램의 비정상적인 동작을 유발할 수 있습니다.

이러한 오류는 해커들이 시스템에 악의적인 코드를 삽입하는 데 사용될 수 있어 매우 심각한 보안 문제가 될 수 있습니다.

간단히 말해서, 버퍼 오버플로우는 프로그램이 예상치 못한 메모리 영역을 침범하게 하여 해커가 제어를 탈취하고 악의적인 코드를 실행하게 만드는 공격입니다

포인터 문제

잘못된 포인터 사용은 메모리 취약성을 초래할 수 있습니다. 유효하지 않은 메모리 주소에 접근하거나 메모리를 해제한 후에도 해당 메모리를 사용하려고 시도하는 경우 문제가 발생할 수 있습니다.

  1. 메모리 주소의 오용:
    • 포인터는 메모리 주소를 저장하는 변수로, 해당 주소에 저장된 데이터에 직접 접근할 수 있습니다.
    • 포인터를 사용할 때, 올바른 메모리 주소를 가리키지 않거나, 초기화되지 않은 포인터를 사용하는 경우 문제가 발생할 수 있습니다.
  2. 해제되거나 할당되지 않은 메모리 사용:
    • 동적 메모리 할당을 통해 메모리를 사용하는 경우, 해당 메모리를 명시적으로 해제하지 않으면 메모리 누수가 발생합니다.
    • 해제된 메모리를 계속 사용하려고 하거나, 이미 해제된 메모리에 접근하는 경우 프로그램 동작이 예측할 수 없게 됩니다.
  3. 다중 포인터 오용:
    • 포인터를 이중, 삼중으로 중첩하여 사용하는 경우, 올바른 메모리 주소를 가리키지 않거나 잘못된 연산으로 메모리에 손상을 줄 수 있습니다.
  4. Wild 포인터:
    • 초기화되지 않은 포인터를 사용하면 그 포인터는 “야생 포인터(Wild Pointer)”가 됩니다.
    • 이런 포인터는 어떤 메모리 주소를 가리키는지 알 수 없으며, 사용 시 예상치 못한 동작을 유발할 수 있습니다.

메모리 안전 언어와 메모리 취약 언어

메모리 안전 언어

메모리 안전 언어설명
Rust메모리 안전성과 고성능을 결합한 시스템 프로그래밍 언어. 소유권 시스템과 라이프타임을 활용하여 메모리 오류 방지.
Swift (스위프트)Apple이 개발한 언어로 안전한 메모리 관리와 자동 참조 계산, 강력한 타입 시스템을 통해 안정성을 갖춤.
Java메모리 관리를 가상 머신을 통해 수행하며 포인터 연산이 없어 안전성을 제공. 가비지 컬렉션으로 메모리 누수 방지(완벽하진 않음).
C# (C Sharp).NET 프레임워크에서 사용되며 가비지 컬렉션을 통한 메모리 안전성 제공.

메모리 취약 언어

메모리 취약 언어설명
C메모리를 직접 조작할 수 있는 기능을 가지고 있어 프로그래머가 주의하지 않으면 버퍼 오버플로우 등 취약점이 발생 가능.
C++C의 기능을 포함하면서 객체 지향 프로그래밍도 지원. 포인터 및 메모리 관리 기능으로 취약성이 발생할 수 있음.
Assembly Language기계어에 가까운 낮은 수준의 언어로 메모리를 직접 다룸. 프로그래머가 주의하지 않으면 취약점이 발생할 수 있음.

기사를 읽고 나니 또 궁금한 점이 꼬리에 꼬리를 무네요…ㅎ.

  1. 말로만 듣던 RUST는 어떤 언어일까?
  2. 가비지 컬렉터? 메모리 누수 완벽하게 방지 안된다고 들었는데…? 왜 그런거지?
  3. Assembly라는 언어도 들어는 봤는데 고인물 언어…. Swift는 또 어떤 언어지?

시간이 될 때 정리해 봐야겠습니다…ㅎ

참고하면 좋은 글

백악관, ‘C’와 ‘C++’ 사용 중단 촉구··· 전문가들 “시의적절한 권고” – CIO Korea

Leave a Comment

목차