SH1R0_HACKER
008. Buffer Overflow in C++ (1) 본문
C++ 언어에서도 버퍼오버플로우가 발생할 수 있습니다.
[ String Buffer Overflow ]
위 예제는 20byte의 buf를 할당하고 std::cin 함수를 통해 문자열을 입력받습니다.
하지만 여기서도 입력한 문자열의 길이를 검사하는 부분이 없어서 20byte 이상의 문자열을 입력한다면
버퍼오버플로우가 발생할 수 있습니다.
위 예제에서는 string 타입으로 buf를 할당하는 모습입니다.
std::string는 입력받는 길이에 따라 메모리를 자동으로 할당하기 때문에 버퍼오버플로우가 발생하지 않습니다.
[ Container Overflow ]
C++에서는 데이터 관리를 편하게 하기 위해 벡터, 큐와 같은 여러 종류의 컨테이너들을 지원합니다.
main 함수를 살펴보면 다음과 같습니다.
std::vector<int> v;
13행에서 비어있는 vector v를 생성합니다.
vector 컨테이너는 자동으로 메모리가 할당되는 배열이라고 생각하면 됩니다.
v.resize(size);
15행에서 백터의 크기를 사용자가 입력한 size로 변경합니다.
v.assign(size, 0x41414141);
16행에서는 0x41414141로 초기화된 size개의 원소를 할당합니다.
다음은 f 함수입니다.
vector v를 src 매개변수로 받습니다.
std::vector<int> dest(5)
7행에서 기본값(0)으로 초기화 된 5개의 원소를 가지는 vector dest를 생성합니다.
std::copy(src.begin(), src.end(), dest.begin());
8행에서는 copy함수를 이용하여
src.begin() 부터 src.end() 전 까지의 모든 원소들을 dest.begin() 부터 시작하는 곳에 복사합니다.
src가 dest(5) 보다 크다면 오버플로우가 발생하기 때문에 7행을
std::vector<int> dest(src);
로 바꾸어주면 오버플로우 취약점을 막을 수 있습니다.
위 예제는 int형 vector v를 선언한 후 std::fill_n 함수를 통해
v.begin() 부터 10개의 배열을 0x42로 초기화 하는 코드입니다.
하지만 위 코드에서는 백터의 크기를 따로 지정해주지 않았기 때문에 7행의 코드가 실행되는 순간
버퍼오버플로우가 발생합니다.
이러한 취약점을 막기 위해서는 아래와 같이 벡터를 선언할 때 크기를 지정해 주면 됩니다.
C++에서 반복자(iterator)는 컨테이너에 저장된 원소를 순회하고 접근할 수 있도록 합니다.
반복자를 사용할 때 크기 계산을 정확하게 하지 않는다면 오버플로우가 발생할 수 있습니다.
위 코드는 int형 vector c를 20번 순회합니다.
그러나 f 함수의 매개변수로 전달된 c의 크기가 20을 넘지 않는다면 e의 위치는 c의 바깥을 가리키게 되어
Out-of-Bound Access가 발생합니다.
실제로 컴파일을 시도하면 아래와 같은 오류가 발생합니다.
이 취약점은 for문의 반복 횟수를 벡터의 크기로 지정해주면 됩니다.
아래의 예제는 long long형인 idx 변수를 insert_table 함수의 매개변수 pos로 넘겨주고
pos 값이 table.size() 보다 크거나 같다면 overflow! 문구를 출력하고 종료하고,
pos값이 table.size() 보다 작다면 table[pos]에 value를 대입하는 코드입니다.
long long 자료형의 범위는 아래와 같습니다.
-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
따라서 idx 값으로 음수를 넘겨준다면 if문을 항상 만족하지 않으므로
std::vector 객체의 범위를 벗어난 쓰기가 발생합니다.
따라서 배열의 인덱스로 사용되는 정수형 변수는 unsigned 자료형으로 선언해 사용해야 합니다.
'System > System Exploitation' 카테고리의 다른 글
009. Buffer Overflow in C++ (3) (0) | 2021.02.13 |
---|---|
009. Buffer Overflow in C++ (2) (0) | 2021.02.09 |
007. Integer issues (0) | 2021.02.07 |
006. 초기화되지 않은 메모리 (0) | 2021.02.07 |
005. Double Free & Use After Free (0) | 2021.02.07 |