SH1R0_HACKER

007. Integer issues 본문

System/System Exploitation

007. Integer issues

SH1R0_HACKER 2021. 2. 7. 15:23

C언어나 C++ 언어를 사용할 때 정수의 형 변환을 제대로 고려하지 못하면 취약점이 발생합니다.

아래는 사이트는 자료형들의 표현 범위입니다.

 

docs.microsoft.com/ko-kr/cpp/cpp/data-type-ranges?view=msvc-160

 

데이터 형식 범위

자세한 정보: 데이터 형식 범위

docs.microsoft.com


< 묵시적 형 변환 >

 

대입 연산의 경우 좌변과 우변의 자료형이 다를 경우 묵시적으로 형 변환이 일어나게 됩니다.

작은 정수 자료형에 큰 정수를 저장하는 경우, 작은 정수의 크기에 맞춰서 상위 바이트가 소멸됩니다.

 

double 형 변수 num1을 정의하고 12.34를 대입한 후,

int 형 변수 num2에 num1을 대입한 후 출력하게 되면 소수점을 무시한 12만 출력되는것을

확인할 수 있습니다.

 


정수 승격은 char이나 short 같은 자료형이 연산될 때 일어납니다.

크기가 4byte보다 작은 자료형의 값을 계산할 때는 int형으로 변환하여 연산이 수행됩니다.

 

위 코드를 실행하면 다음 결과가 나옵니다.

 

분명히 크기가 2byte인 short num1과 num2끼리 연산을 했는데

연산결과는 크기가 4byte인 int형으로 되었다는것을 확인할 수 있습니다.

 


피연산자가 불일치 할 경우에도 형 변환이 일어납니다.

int < long < long long < float < double< long double 순으로 변환되며,

작은 바이트에서 큰 바이트로, 정수에서 실수로 형 변환이 일어나게 됩니다.

 

예를 들면, int형과 double형을 더하면 int형이 double형으로 변환된 후 연산이 진행됩니다.


위 코드는 사용자로부터 len값을 입력받고 len+1 만큼 메모리를 동적할당 받고,

read 함수를 통해 len 크기 만큼 buf에 데이터를 입력받습니다.

 

만약 공격자가 len 값으로 -1을 넣는다면 어떻게 되는지 보겠습니다.

11행에서 buf = (char*)malloc(0) 가 호출되고

 

18행에서 read (0, buf, -1) 이 호출됩니다.

 

read 함수의 원형은 아래와 같습니다.

read(int fd, void *buf, size_t nbytes);

 

read 함수의 세 번째 인자는 size_t 형이므로 묵시적 형 변환이 일어납니다.

따라서 read 함수를 호출할 때, 32비트 아키텍처라고 가정하면

read(0, buf, pow(2, 32) -1) 이 호출됩니다.

 

그러므로 지정된 크기의 버퍼를 넘는 데이터를 넣을 수 있어 힙 오버플로우가 발생합니다.


위 코드의 create_tbl 함수는 width와 height, row를 인자로 받고 테이블을 초기화한다.

그런데 6행의 n에 pow(2, 32)가 넘어가는 값이 저장된다면 문제가 발생합니다.

pow(2, 32) = 4,294,967,296

 

unsigned int형의 값의 범위는 0 ~ 4,294,967,295

 

width값이 65,536이고 height값이 65,537이라면 n에 4,295,032,832가 들어가야합니다.

n은 pow(2, 32) + 65,536과 같으므로 실제로 저장되는 값은 65,536이 됩니다.

그러나 memcpy 함수에서 반복문을 순회하면서 메모리를 복사하기 때문에

버퍼 오버플로우가 발생하게 됩니다.


Q. 어떤 line이 취약할까요?

8번째 라인을 보면 길이를 검사하는 과정인데 사용자가 입력한 값이

0 미만이거나 length + 1 값이 MAX_SIZE보다 크거나 같다면 종료시킵니다.

 

이때 length에 int형 최대값 0x7FFFFFFF (2,147,483,647) 값을 넣어버리면

0x7FFFFFFF (2,147,483,647) < 0은 false

2,147,483,647에 1을 더해버리면 -2,147,483,648이 되면서

-2,147,483,648 >= 0x8000 도 false가 됩니다.

 

그러면 13번째 line에서 read(fd, buf, 0x7FFFFFFF)가 호출되어 힙 오버플로우가 발생하게 됩니다.

'System > System Exploitation' 카테고리의 다른 글

009. Buffer Overflow in C++ (2)  (0) 2021.02.09
008. Buffer Overflow in C++ (1)  (0) 2021.02.09
006. 초기화되지 않은 메모리  (0) 2021.02.07
005. Double Free & Use After Free  (0) 2021.02.07
004. Format String Bug  (0) 2021.02.07