반응형
32비트 운영체제에서 size_t는 unsigned int long은 int
64비트 운영체제에서 size_t는 unsigned long long은 long long
size_t는 객체의 최대 사이즈이기 때문에 항상 unsigned
32bit 에서는 int가 최대 자료형, 64bit에서는 long long이 최대
묵시적 형 변환에 따른 취약점
- 대입연산 : 작은 정수 자료형에 큰 정수를 저장하는 경우, 작은 정수의 크기에 맞춰서 상위 바이트가 소멸됨.
- 정수승격 : char short 같은 자료형이 연산될 때 발생 . char형과 char형의 덧셈의 경우 1byte가 아닌 4byte의 결과 출력 컴퓨터가 int형을 기반으로 연산하기 때문에 발생.
- 피연산자가 불일치할 경우 형 변환 : int와 double 더하면 int가 double로 형변환 된 후에 연산 진행됨.
- int< long< long long < float<double< long double 순으로 변환
Integer Issues
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *buf;
int len;
printf("Length: ");
scanf("%d", &len);
buf = (char *)malloc(len + 1);
if(!buf) {
printf("Error!");
return -1;
}
read(0, buf, len);
}
- 만약 공격자가 len으로 -1을 입력한 경우
- malloc(0)에도 메모리는 할당됨.
- read의 파라미터에서 3번째 인자는 size_t이고 -1이 들어오면 32비트 운영체제라고 가정했을 때
- 2^32 -1 이 호출됨. (-1은 11111....111111)
char *create_tbl(unsigned int width, unsigned int height, char *row) {
unsigned int n;
int i;
char *buf;
n = width * height;
buf = (char *)malloc(n);
if(!buf)
return NULL;
for(i = 0; i < height; i++)
memcpy(&buf[i * width], row, width);
return buf;
}
width = 65536 , height = 65537 대입 시 width * height는 2*32 + 65536
결국 n에는 65536만 들어간다.
for에서는 memory 돌면서 copy하는데 65536만 들어갔기 때문에 버퍼 오버플로우 발생
char *read_data(int fd) {
char *buf;
int length = get_int(fd); // length는 사용자가 입력할 수 있는 값입니다.
if(!(buf = (char *)malloc(MAX_SIZE))) // #define MAX_SIZE 0x8000
error("malloc: %m");
if(length < 0 || length + 1 >= MAX_SIZE) {
free(buf);
error("bad length: %d", value);
}
if(read(fd, buf, length) <= 0) {
free(buf);
error("read: %m");
}
buf[length] = '\0';
return buf;
}
만약 length 를 2^31 - 1 (양수의 최대값 01111.....1111) 로 지정했다면
length + 1은 음수 값이 된다.
따라서 read(fd,buf,2^31-1)이 수행되어 힙 오버플로우 발생
반응형
'Security' 카테고리의 다른 글
[systemhacking] Uninitialized value (0) | 2021.11.22 |
---|---|
[systemhacking] Buffer overflow c++ (0) | 2021.11.22 |
[systemhacking] Memory corruption (0) | 2021.11.18 |
[systemhacking] format string bug (0) | 2021.11.17 |
[systemhacking] Off-by-one (0) | 2021.11.11 |