SUA 시스템 해킹 스터디 - 취약점 종류

170804 (이어서)

지난 PE 파일 구조에 이어 이번에는 각종 SW 취약점과 분류 형태를 알아보겠다.


소프트웨어 취약점

SW에는 다양한 버그들이 존재한다. 이러한 버그들 중에는 단순한 메모리 누수부터 공격이 가능한 버그까지 매우 다양한 종류가 있다.


1. 취약점

취약점이란, 사용자에게 허용된 권한 이상의 동작이나 정보 열람을 가능하게 하는 소프트웨어의 설계 상의 허점이나 결함을 말한다. 더 포괄적인 의미로는 소프트웨어 뿐만 아니라 하드웨어, 절차 및 관리 등이 모두 포함되지만 여기서 말하는 취약점은 기술적인 SW 취약점으로 한정한다.

프로그램은 사람이 만드는 데, 완벽한 사람은 없으니 누구나 실수를 한다. 즉, 대부분의 프로그램은 취약점이 아직 발견되지 않은 것이라 봐도 무방하다. 일반적으로 취약점이 발견되면 해당 취약점을 공격하여 원하는 코드를 실행하거나 특정 목적을 달성하는 공격 코드 또한 공개된다. 이런 취약점 공격 코드를 Exploit 라고 부르며, Exploit 이란 용어는 이러한 공격 코드를 이용한 공격 행위 일체를 포함시키기도 한다.

Exploit 코드 및 취약점은 취약점 공개 사이트, 유료 Exploit 툴킷에서 볼 수 있지만 공개되지 않은 채 범죄에 악용되는 Exploit도 존재한다.

초창기에는 대부분의 Exploit이 C, Perl로 작성됐지만 최근 컴파일이 필요없는 스크립트 언어, 다양한 라이브러리를 지원하는 Python과 Ruby로 작성되고 있다.


2. 취약점의 발견과 패치

취약점을 발견하는 연구자는 대가 없이 제보하기도 하지만, 판매하거나 명예, 공부, 불법적인 크래킹이 목적인 경우도 있다. 취약점이 발견되고 패치가 개발되기 전까지의 기간에 이루어지는 공격을 제로 데이 공격 이라 부른다.


취약점 분류


1. Memory Corruption 취약점

Memory Corruption 취약점은 버그로 인한 메모리 오염, 즉 예상되지 않은 메모리 값 변경이나 참조 등에 의해 발생한다. 원인은 대부분 안전하지 않은 함수의 사용, 잘못된 함수 사용 등 프로그래밍 실수로 인해 발생하며 Buffer Overflow 취약점 또한 이 취약점 종류다.


주로 메모리 경계를 검사하지 않는 함수 사용으로 인해 스택을 덮어쓰게 되어 발생하는 취약점이다. 대표적인 취약함수로 strcpy, gets, scanf, strcat, getwd, sprintf 등이 있다. 예시는 아래와 같다.

char buf[20];
strcpy(buf, argv[1]); // 경계값 검사하지 않음
char buf[20];
len = strlen(argv[1]);
strncpy(buf, argv[1], len); // 문자열 길이가 20을 넘을 시 BOF 발생

이처럼 메모리 복사, 문자열 복사함수는 반드시 정확한 검증을 거친 후에 수행하도록 해야 한다.


스택 버퍼 오버플로우와 비슷하나 그 대상이 힙 메모리다. 또한 메모리 구조가 다르므로 취약점 공격 기법도 다르다.

int *buf = (int*)malloc(20);
strcpy(buf, argv[1]); // 경계값 검사하지 않음


정해진 자료형보다 큰 수를 저장할 때 발생하는 오버플로우 문제로, 조건문 등에서 정해진 분기문이 아닌 다른 분기문을 실행하도록 하여 취약점을 발생시킬 수 있다.

unsigned char maxlen = 0;
char len = 0;
char buf[30] = {0, };

len = strlen(argv[1]);  // 128바이트 이상 입력 시 음수로 인식
if (len > 30) {
  printf("Error!! Max Size:30\n");
} else {
  printf("Vuln!!\n");
  strcpy(buf, argv[1]);
}

위 예시를 보면 30개 이상 문자열 입력 시 에러가 발생하며 취약함수가 실행되지 않지만, signed char는 128 이상의 수를 음수로 인식하므로 if 문을 통과한다.


포맷스트링을 지정해 주지 않고 사용할 때 발생하는 취약점으로 %n, %hn 등의 일부 포맷스트링을 이용하여 메모리 값을 변조하게 된다.

strcpy(buf, argv[1]);
printf(buf);  // FSB


최근 브라우저에서 많이 발견되는 취약점이다. 말 그대로 Free된 포인터를 사용할 때 발생한다. 자바스크립트, 파일 로딩 등으로 힙 메모리를 조작할 수 있는 상황에서 공격이 가능하다.

free(object);
object->method(); // Free된 포인터 사용


Free된 메모리를 다시 Free할 때 발생하며, 대부분 프로그래밍 실수로 인해 발생한다. Integer Overflow 등의 취약점으로 인해 발생하기도 한다.

int * ptr;
{
  ...
  free(ptr);
}
...
free(ptr);  // Double Free 취약점 발생


메모리 값이 지정되지 않은, 초기화되지 않은 포인터(Null Pointer)에 값을 넣으려 할 때 발생한다. 예시는 아래와 같다.

char * ptr = null;
...
*ptr = '1234' // Null Pointer Reference

이 외에도 Race Condition 등 다양한 취약점들이 존재한다.


[질문 내용 정리]

이 속성을 가진 섹션은 메모리에서 다른 프로세스와 공유할 수 있다. 값은 0x10000000이다.

PointerToRawData는 파일에서 각 섹션의 시작 위치를 나타낸다. 즉, code/data가 파일의 어디에 있는지 알려주는 변수다.

보통 인텔 프로세서에서 지원하는 메모리 관리 기법은 세그먼테이션과 페이징이다. 세그먼테이션과 페이징은 주소 공간을 특정 영역으로 나눈다는 공통점이 있지만, 나누는 방식에서 차이가 있다. 세그먼테이션은 전체 영역을 원하는 크기로 나누어 관리하는 방식이고, 페이징은 일정한 단위로 잘라진 조각을 모아 원하는 크기로 관리하는 방식이다.