'bug class'에 해당되는 글 1건

  1. 2012.06.20 널 페이지 할당과 버그 클래스

일반적으로 프로그램의 버그를 찾는데 있어서 많은 사람들이 사용하는 것이

막 찾아주는(?) 더미 퍼징( dummy fuzzing ) 이다.


간단하게 인터넷에서 구할 수 있는 자료들만으로도 생각보다 괜찮은 효율로

버그들을 찾아낼 수 있으며, 그로 인한 공격가능한 상황을 만들 수도 있다.


이러한 퍼징을 통한 버그 찾는 방법들은 보통 디버거나 모니터링해주는 프로세스가

대상 프로그램의 익셉션 상황을 잡아내서 로그를 남겨주는 것이 보통의 구조인데,

이러한 더미퍼징으로 찾는 대부분의 크래쉬는 보통 메모리 커럽션을 발생시키게 된다.

이 때 이런 익셉션의 상황을 종합해서 이것이 어떤 버그인지를 분류한다.


이는 보통 크게 6가지로 나뉜다.


1) Read Access Violation Near NULL

2) Read Access Violation Not Near NULL

3) Write Access Violation Near NULL

4) Write Acesss Violation Not Near NULL

5) Invalid Instruction Pointer

6) Unknown


이런 분류는 크게 Access Violation이 어떤 상황에서 일어났는지가 중요한 기준으로

사용되는데, 그때 사용되는 또 다른 중요한 기준이  NULL 근처인가 아닌가하는 기준이다.


NULL 포인터 근처에서 Access Violation이 일어난 경우와 그렇지 않은 경우를

구분하는 이유는 NULL포인터가 아닌경우에 일어나는 Access Violation의 경우

보통 익셉션이 일어나는 주소를 변경할 수 있는 경우가 많기 때문이다.

또한, NULL 포인터 근처가 아닌곳에서 일어나는 Access Violation이 할당할 수 있는 

메모리인 경우에도 역시 공격할 수 있는 형태의 버그가 되어 

일반적으로 NULL 근처가 아닌경우의 Access Violation을 선호하는 경향이 크다.

(라고 일반적으로 생각하지만, 결국 그렇지는 않다 -_-)


그렇지만, Access Violation이 일어나는 곳이 NULL 근처이거나 아니거나 이와는 상관없이

이러한 크래쉬들은 모두 공격시에 도움이 많이 된다.


NULL 포인터 근처에서의 Access Violation의 경우는 일반적으로 원격에서 공격을 하여

로컬권한의 쉘을 얻거나, 원하는 악성코드를 설치하는 경우보다는 

로컬에서의 권한상승을 위해 사용되는 경우가 매우 많다.


대표적으로 알고있는 유명한 Exploit이 Linux의 sendpage() exploit이다.

sendpage() exploit은 Linux system call 인 sendpage() 함수내에서 발생되는

NULL 포인터 익셉션에 기반하고 있다. 

sendpage() 함수안에 예외처리를 하지 않음으로서 함수포인터의 값이 NULL일때 

호출시킴으로서 커널 권한상승을 꾀하는 것이다.


이러한 NULL 포인터 예외는 커널에서 일어날 경우 그 위험성이 대단히 크게 작용한다.

따라서 대부분의 운영체제에서 NULL 포인터 근처에 메모리 할당을 강제적으로 막고 있다.


그동안 윈도우즈 운영체제 역시 NULL 포인터에 메모리를 할당하기 어려운 것으로 알려져 

왔는데, 우연히 들린 jz님의 블로그에서 다음과 같이 윈도우즈 NULL page를 할당하는 

방법을 확인할 수 있었다.

http://jz.pe.kr/63


요약하자면, 32비트 운영체제의 경우 0xFFFFFFFF 부터 메모리를 할당시켜 0x1000 

바이트를 할당하게 되면, 순환구조로 0x00000000의 메모리의 값이 할당된다는 것이다. 


일반적으로 Windows 운영체제의 .sys 파일은 매우 퍼징하기 쉽다.

이는 IOCTL계열의 함수를 통해 각 인터페이스 함수들을 퍼징해주면 되는데, 

vmware와 같은 가상화 프로그램과 이를 windbg에 물려서 사용한다면,

초보자라도 대단히 쉽게 Windows 커널 퍼저를 구성할 수 있다.


이를 통해 백신이라던가, driver를 사용하는 디바이스 프로그램들을 퍼징한다면

NULL 포인터 근처의 Access Violation을 얻어낼 수 있을 것이다.


그렇다면 우리는 보통 다음과 같은 형태의 공격코드를 작성할 수 있다.


1. NULL page를 할당한다

2. 필요한 값들을 NULL page에 넣어준다.

3. NULL 포인터 근처의 Access Violation을 얻을 수 있는 sys파일의 인터페이스 함수를 호출한다.

4. 커널에서 호출된 sys파일의 인터페이스 함수는 커널권한으로 NULL page에 접근하게 된다.

5. 커널 권한을 얻어낼 수 있다.


최근 국내에도 제로데이를 찾고자 하는 노력들이 많이 보이고 있다.

대부분의 연구하는 해커들이 잘 찾고 있지만, 

혹여나 안일한 마음으로 아 이런 크래쉬는 공격할 수 없을것 같아 라고 생각한다면,

그동안 알고 있던 NULL page 할당을 생각해 봤으면 좋겠다.


안전한 크래쉬는 없다.

물론 모든 프로그램의 버그가 크래쉬로 연결되는 것은 아니고,

모든 크래쉬가 공격가능한 것은 아니다.


그렇지만 언제나 생각지 못한 공격방법은 있는 것이다.

그리고 취약점을 찾는 과정도 매우 중요하지만,

공격방법을 찾아내는 과정 역시 매우 중요하다.


다른 해커들이 만들어내지 못하는 공격방식을 찾아내는 즐거움

NULL page를 할당하는 저런 기발한 생각들이

우리 해커들을 움직이게 하는것이 아닐까

Posted by Individual-N

댓글을 달아 주세요