한 문장으로 요약하면 백악관에서 C와 C+의 메모리 취약성 때문에 사용 중단을 촉구한다는 내용입니다.
5문장 정도로 요약하면 아래와 같습니다.
미국 대통령 조 바이든의 행정부가 소프트웨어 개발자들에게 취약한 언어인 C와 C++ 사용 중단을 촉구했습니다. 대신 메모리 안전 프로그래밍 언어를 사용하라고 권고했습니다. 이러한 권고는 사이버 공격 위험을 감소시키기 위한 것으로, 메모리 안전 언어는 소프트웨어 버그 및 취약성으로부터 안전합니다. 현재의 취약점 중 70%는 메모리 안전 문제에서 비롯된 것으로 나타났습니다. 국가 사이버 책임자는 이를 통해 모든 종류의 취약점을 방지할 수 있다고 설명했습니다. 국가 사이버 보안 국도 메모리 안전 프로그래밍 언어 사용을 촉구하며, 러스트를 안전한 예로 언급했습니다. 전문가들은 C와 C++에서 다른 안전한 언어로의 전환은 어려울 수 있지만, 변화가 필요하다고 강조하고 있습니다.
이 기사를 읽고 궁금한 점이 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”의 일부 또는 전체가 다른 메모리 주소에 영향을 미치게 되어 예상치 못한 결과가 발생할 수 있습니다.
버퍼 오버플로우는 메모리를 할당받은 배열이나 버퍼의 경계를 넘어서 데이터가 쓰여질 때 발생하며,
이는 프로그램의 비정상적인 동작을 유발할 수 있습니다.
이러한 오류는 해커들이 시스템에 악의적인 코드를 삽입하는 데 사용될 수 있어 매우 심각한 보안 문제가 될 수 있습니다.
간단히 말해서, 버퍼 오버플로우는 프로그램이 예상치 못한 메모리 영역을 침범하게 하여 해커가 제어를 탈취하고 악의적인 코드를 실행하게 만드는 공격입니다
포인터 문제
잘못된 포인터 사용은 메모리 취약성을 초래할 수 있습니다. 유효하지 않은 메모리 주소에 접근하거나 메모리를 해제한 후에도 해당 메모리를 사용하려고 시도하는 경우 문제가 발생할 수 있습니다.
- 메모리 주소의 오용:
- 포인터는 메모리 주소를 저장하는 변수로, 해당 주소에 저장된 데이터에 직접 접근할 수 있습니다.
- 포인터를 사용할 때, 올바른 메모리 주소를 가리키지 않거나, 초기화되지 않은 포인터를 사용하는 경우 문제가 발생할 수 있습니다.
- 해제되거나 할당되지 않은 메모리 사용:
- 동적 메모리 할당을 통해 메모리를 사용하는 경우, 해당 메모리를 명시적으로 해제하지 않으면 메모리 누수가 발생합니다.
- 해제된 메모리를 계속 사용하려고 하거나, 이미 해제된 메모리에 접근하는 경우 프로그램 동작이 예측할 수 없게 됩니다.
- 다중 포인터 오용:
- 포인터를 이중, 삼중으로 중첩하여 사용하는 경우, 올바른 메모리 주소를 가리키지 않거나 잘못된 연산으로 메모리에 손상을 줄 수 있습니다.
- Wild 포인터:
- 초기화되지 않은 포인터를 사용하면 그 포인터는 “야생 포인터(Wild Pointer)”가 됩니다.
- 이런 포인터는 어떤 메모리 주소를 가리키는지 알 수 없으며, 사용 시 예상치 못한 동작을 유발할 수 있습니다.
메모리 안전 언어와 메모리 취약 언어
메모리 안전 언어
메모리 안전 언어 | 설명 |
---|---|
Rust | 메모리 안전성과 고성능을 결합한 시스템 프로그래밍 언어. 소유권 시스템과 라이프타임을 활용하여 메모리 오류 방지. |
Swift (스위프트) | Apple이 개발한 언어로 안전한 메모리 관리와 자동 참조 계산, 강력한 타입 시스템을 통해 안정성을 갖춤. |
Java | 메모리 관리를 가상 머신을 통해 수행하며 포인터 연산이 없어 안전성을 제공. 가비지 컬렉션으로 메모리 누수 방지(완벽하진 않음). |
C# (C Sharp) | .NET 프레임워크에서 사용되며 가비지 컬렉션을 통한 메모리 안전성 제공. |
메모리 취약 언어
메모리 취약 언어 | 설명 |
---|---|
C | 메모리를 직접 조작할 수 있는 기능을 가지고 있어 프로그래머가 주의하지 않으면 버퍼 오버플로우 등 취약점이 발생 가능. |
C++ | C의 기능을 포함하면서 객체 지향 프로그래밍도 지원. 포인터 및 메모리 관리 기능으로 취약성이 발생할 수 있음. |
Assembly Language | 기계어에 가까운 낮은 수준의 언어로 메모리를 직접 다룸. 프로그래머가 주의하지 않으면 취약점이 발생할 수 있음. |
기사를 읽고 나니 또 궁금한 점이 꼬리에 꼬리를 무네요…ㅎ.
- 말로만 듣던 RUST는 어떤 언어일까?
- 가비지 컬렉터? 메모리 누수 완벽하게 방지 안된다고 들었는데…? 왜 그런거지?
- Assembly라는 언어도 들어는 봤는데 고인물 언어…. Swift는 또 어떤 언어지?
시간이 될 때 정리해 봐야겠습니다…ㅎ