[정보보안] 시스템 해킹(버퍼 오버플로우, 포맷 스트링, 힙 스프레이, 레이스 컨디션)

[정보보안] 시스템 해킹(버퍼 오버플로우,포맷 스트링, 힙 스프레이, 레이스 컨디션)

Buffer Overflow(버퍼 오버플로우)

버퍼 오버플로우는 시스템 해킹의 대표적인 공격 방법 중 하나이다.
버퍼(Buffer)라는 것은 보통 데이터가 저장되는 메모리 공간을 일컫는데 단순히 메인 메모리만이 아닌 다른 하드웨어에서 사용하는 임시 저장 공간 역시 버퍼라고 부른다.
오버플로우(Overflow)는 단어 뜻에서 유추할 수 있듯이 데이터가 지정된 크기의 공간보다 커서 해당 메모리 공간을 벗어 나는 경우 사용한다.


데이터의 길이에 대한 불명확한 정의를 악용한 덮어쓰기로 인해 발생한다.
예를 들면 8바이트 문자열을 넣을 수 있는 버퍼가 존재한다고 가정하자.
그리고 이 메모리 공간 뒤에는 컴퓨터를 동작하는데 중요한 기능을 수행하는 코드가 존재한다고 생각해보자. 우리는 이 8비트 공간에 8개의 문자만 입력할 수 있다.
그런데 이보다 더 길이가 긴 문자열을 임의로 입력해서 넣으면 중요한 기능을 수행하는 코드가 영향을 받게 되어 제대로 된 기능을 수행하지 못하는 상황이 발생한다.

결론적으로 버퍼 공간의 크기보다 큰 데이터를 저장하게 해서 일어나는 오버플로우(Overflow)를 이용한 공격이다.


보통 개발된 프로그래밍 언어의 버퍼 오버플로우에 취약한 함수가 있는 경우 이를 이용해 공격을 시도하며 공격이 성공할 경우 시스템의 권한을 상승시키거나 악성 행위를 하도록 할 수 있기 때문에 반드시 이 공격에 대한 방어를 철저히 해야 한다.
버퍼 오버플로우에 취약한 함수

  • strcpy, stract, gets, fscanf, scanf, sprintf, sscanf, vfscanf, vspringf, vscanf, vsscanf, streadd, strecpy, strtrns
  • 이러한 함수들의 공통적인 특징은 처리하는 문자열의 최대 길이를 정하지 않았다.

스택 버퍼 오버플로우의 절차

  1. 공격 셀 코드를 버퍼에 저장한다.
  2. 루트 권한으로 실행되는 프로그램 상에서 특정 함수의 스택 버퍼를 오버플로우시켜서 공격 셀 코드가 저장되어 있는 버퍼의 주소로 반환 주소를 변경한다.
  3. 특정 함수의 호출이 완료되면 조작된 반환 주소인 공격 셀 코드의 주소가 반환된다.
  4. 공격 셀 코드가 실행되어 루트 권한을 획득하게 된다.

대응책

  • 프로그래밍 시 경계값 검사를 적용하고 최신 운영체제로 패치


포맷 스트링 공격

버퍼 오버플로우와 다르게 데이터 형태에 대한 불명확한 정의로 인한 문제이다.

  • 취약점으로 스택(stack)에 비정상적으로 접근한다.
  • write가 허용 된 memory segment에 원하는 값을 삽입 할 수 있다.
2000년도 후반에 해커들 사이에서 큰 반항을 일으키는 보고서 하나가 발표되었다.
Format String Attack
이것은 기존에 널리 사용되고 있던 Buffer Overflow 공격 기법에 견줄 만한 강력한 해킹 기법이었다.
이해킹 기법이 발표되고 나서 그 동안 별 문제 없어 보였던 각종 프로그램들에 대한 취약점이 속속 발표되고 해당 프로그램을 제작했던 회사들은 이 취약점을 해결하기 위해 분주해지기 시작했다.


Format String?

포맷 스트링 공격에 대해 알아보기 전에 Format String이 무엇인지 알아보자.
다음은 일반 C프로그램에서 흔히 찾아볼 수 있는 printf함수이다.
직관적으로 ""안에 포함되어 있는 "Hello, %s\n"이 Format String이다.
즉 Format String은 이 Format String을 사용하는 함수에 대해, 어떤 형식 혹은 형태를 지정해주는 문자열을 의미한다.

일반적으로 프로그래머들은 어떤 프로그램을 작성할 때, 다음과 같은 형식으로 작성한다.

하지만 어떤 프로그래머들은 위와 같은 형태를 이용하지 않고 프로그래밍을 보다 편하게 하기 위해서 다음과 같이 사용하는 경우가 있다.
이와 같은 형태의 프로그래밍은 잘못된 것은 아니다.
어떻게 보면 같은 기능을 수행하는 두 가지의 코드 중 '2번'의 소스코드 '1번'의 소스코드보다 적은 양의 소스코드를 사용한다.
따라서 '2번'의 소스코드 형태가 좀 더 현명한 소스코드로 보일 수 있다.
그러나 '2번'의 소스코드를 이용하여 프로그래밍하는 경우에는 해커들에게 프로그램의 흐름을 바꿀 수 있는 기회를 제공하게 된다는 사실을 깨달아야 한다.

프로그래머의 잘못은 무엇일까?
printf함수에 의해서 해석되는 "str"은 출력하고자 하는 문자열이 아니라 printf함수에서 사용할 각종 형식 지시자(%d ,%s, %c..등)를 포함한 Format String으로 인식하게 된다.


예를 들면 %s를 사용하게 되면 해당하는 데이터의 문자열에 대해서 출력을 하게 된다. 하지만 이에 대해 임의적으로 %x라는 포맷 스트링으로 바꾸어준다면 컴파일을 실행시킬 때 문자열에 대한 값이 나오는 것이 아니라 주소에 대한 값이 나오게 되는 것을 볼 수 있다.
이렇게 되면 메모리 열람이 가능하게 되고 이렇게 열람을 할 수 있으면 메모리 조작도 가능해진다. 
해당 메모리에 대해 값을 바꾸어 집어넣게 되면 메모리에 주소 값이 바뀌게 된다.
이러한 공격을 포맷 스트링 공격이라고 한다.


힙 스프레이(페이로드 전달 기법)

특징

  • 이 기법은 공격자가 원하는 페이로드를 예측 가능한 메모리 주소에 둘 수 있다는 사실에서 기인하여 단순히 페이로드를 배치해 둔 주소로 점프
  • 자바스크립트를 이용하여 Heap 메모리 영역에 뿌리듯이(Spraying) Shell Code를 채우는 기법
힙 스프레이가 제대로 동작하려면 EIP(Elastic IP)를 제어하기 전에 힙 공간에서 메모리 덩어리를 할당하고 그 공간에 내용을 채워야 함
즉, 메모리 오염(버퍼 오버플로우, SEH 등등) 공격하기 전에 대상 애플리케이션의 메모리 영역에 원하는 데이터를 삽입할 수 있어야 함
EIP를 제어하기 전에 예측 가능한 메모리 위치에 데이터를 할당할 수 있으면, 힙 스프레이와 같은 기법을 사용할 수 있음.

공격원리

  • 힙의 결정적이고 예측 가능한 특성을 공격에 활용함
  • 즉, 공격자가 원하는 페이로드를 예측 가능한 위치에 삽입할 수 있다는 의미

공격 코드 실행 순서

  1. 힙 스프레이 실행
  2. 버그 / 취약점 동작
  3. EIP가 힙을 가리키도록 제어


레이스 컨디션(Race Condition)

한정된 자원을 동시에 이용하려는 여러 프로세스가 자원의 이용을 위해 경쟁을 벌이는 현상
레이스 컨디션을 이용하여 root권한을 얻는 공격을 레이스 컨디션 공격이라고 한다.

레이스 컨디션 공격의 기본 개념
  1. 취약 프로그램이 생성하는 임시 파일의 이름을 파악합니다.
  2. 생성될 임시 파일과 같은 이름의 파일을 생성합니다.
  3. 이에 대한 심볼릭 링크를 생성합니다.
  4. 원본 파일을 지운 채 취약 프로그램이 심볼릭 링크를 건 파일과 같은 파일을 생성할 때까지 기다립니다.
  5. 생성되었을 때, 심볼릭 링크를 이용해서 파일 내용을 변경합니다.
  6. 시스템은 변경된 파일을 자신이 생성한 임시 파일로 생각하고 프로세스를 진행시킬 것이고, 공격자는 관리자권한으로 실행되는 프로그램에 끼어들어 무언가를 할 수 있는 여지를 만듭니다.



출처

댓글

이 블로그의 인기 게시물

[Python] # -*- coding: utf-8 -*-를 쓰는 이유

[소프트웨어공학] NS(Nassi-Schneiderman) 차트

[컴퓨터네트워크] Telnet이란?