1. 취약점 분석, 실제 데이터 흐름 분석 및 시각화


CanSecWest 2012에서 악성코드 샘플 및 PoC 파일 분석을 위해 제안한 기술입니다. 여기서는 취약점 분석을 위해 사용될 수 있는 많은 방법들 중에서 DBI(Dynamic Binary Instrumentation)와 데이터 흐름 분석을 사용하였습니다. 이를 시각화하여 분석을 쉽고 빠르게 할 수 있도록 도와주고 있습니다.


Control flow differential analysis result



2. SDhash와 Gephi를 이용한 악성코드 클러스터링 시각화 도구


악성코드 샘플들 간의 유사성을 알아내기 위해 SDhash를 이용하여 클러스터링을 수행하고, 이를 시각화하여 보여줍니다.


An example cluster excerpt from the graph produced by converting SDhash scored hashes to GDF


3. 악성코드 API 호출 및 심볼 정보 시각화 도구


악성코드에서 사용되는 API 호출과 바이너리에 포함된 심볼 정보를 시각화하여 보여주는 도구입니다. 파이썬으로 제작되었으며 코드가 공개되어 있습니다.



AND

문서 기록

2013.04.10 00:41 AM 1 문서 작성 시작

2013.04.10 03:52 AM 1 문서 작성 완료

 

문서 개요

행동 익명화와 익명화에 이용되는 프록시 서버에 대한 개념을 배운 윈도우에서 SSH 터널을 이용하여 프록시를 연결하는 방법을 다룬다.

 

문서 내용

 

행동 익명화

나는 악성 코드를 배포한 공격자라고 하자. 내가 배포한 악성 코드는 금융 기관의 PC들을 공격했고 악성 코드를 배포한 사이트를 수사관들이 살펴보기 시작했다. 그리고 지금 나의 눈에는 특정 기관으로 생각되는 IP들이 사이트에 접속하는 것을 보게 되었다. 나는 지금 수사를 방해하기 위해 어떤 행동을 해야 하는가? 나는 이들을 가지고 놀고 싶다.

 

여러분이 위의 상황이면 어떻게 것인가? 공격자는 특정 IP들에 대해 공격 전략을 바꿔 수사망을 흔들어 놓을 수도 있으며, 웹사이트 자체를 은폐하여 조사를 방해할 수도 있다. 더욱이 IP들에 대해 DDOS 공격을 가해 보복할 수도 있다.

 



 

행동 익명화는 이처럼 신분을 노출시키지 않고 어떠한 작업을 수행하는 것이다. 공격자 또한 행동 익명화를 있으며, 악성코드 연구자 또는 수사관 또한 악성코드를 분석하기 위해 행동 익명화가 필요하다.

 

행동 익명화의 종류는 토르를 이용한 익명 브라우징, 프록시 서버를 이용한 익명 브라우징으로 나눌 있으며 문서에서는 프록시 서버를 이용한 익명 브라우징을 주된 내용으로 다룬다.

 

*그림 출처 : http://blog.daum.net/fidesmd2/171

 

프록시 서버

프록시 서버는 일반적으로 클라이언트와 서버 사이에 중간자 시스템으로 설계되었고, 대역폭 절감, 콘덴츠 필터링 등을 위해 흔히 사용된다. 하지만 인터넷에서 익명성을 보장하기 위한 목적으로도 사용된다.

  흔히 프록시 서버는 토르와 비교되는데, 이들의 가장 차이는 프록시 서버는 서버 자체에서 요청한 클라이언트를 있다는 것이고 토르의 최종 노드에서는 요청한 클라이언트를 모른다는 것이다.

 

 


 

  이러한 요청한 클라이언트를 아는 프록시 서버의 특성 때문에 프록시의 유형은 투명한 프록시, 익명성을 보장하는 프록시, 매우 높은 익명성을 보장하는 프록시로 나뉜다.

 

  • 투명한 프록시 : 요청 클라이언트의 정보를 HTTP 추가 헤더를 설정하여 서버에 전송한다.
  • 익명성을 보장한 프록시 : 요청 클라이언트의 정보를 서버에 보여주지는 않지만, 프록시를 통해 전송되었다는 정보를 포함한다.
  • 높은 익명성을 보장하는 프록시 : 대상 서버에 어떠한 정보도 제공하지 않는다. 서버는 프록시를 통해 전송되었다는 정보를 없다.

 

 

윈도우에서 SSH 터널 프록시 사용

프록시로 연결하는 방법 가장 좋은 방법은 SSH 터널을 통해 포트를 포워딩하는 방식이며, SSH 터널은 사용자 PC 포트를 오픈하여 SSH 통해 서버로 연결한 서버를 SOCKS4/5 프록시로 사용할 있게 한다.

 

인터넷 어플리케이션을 SSH 터널을 통해 프록시하는 데는 다음과 같이 4가지 이유가 있다.

 

  • 보안 : 사용자와 서버 사이의 로컬 트래픽이 암호화된다.
  • 프라이버시 : 사용자의 실제 IP 주소를 감춘다.
  • 기술적 이유 : 다른 장소에서 IP 기반 인증 메커니즘을 사용하는 어플리케이션에 접근해야할
  • 그리고 그냥.. 가능하니까 :)

 

그렇다면 어떻게 서버를 통해 프록시 연결을 하는 것인가?

 

SSH 프록시 서버 사용을 위한 준비물은 다음과 같다.

  • 사용할 있는 SSH 프록시 서버
  • Putty
  • 브라우저(IE, FireFox )

 

*직접 SSH 프록시 서버를 구축해서 실습을 해야한다면 SSH 프록시 서버 구축을 위해 "How to setup an SSH Proxy Server using Putty and Spoon Proxy" 참조하기 바란다. 필자는 직접 SSH 프록시 서버를 구축하였으며, 아래 내용은 해당 서버를 이용한 정보이다.

 

Putty 실행하면 다음과 같은 설정창을 보게 된다.

 



 

  • Host Name : SSH 프록시 서버의 주소를 적는다.
  • Port : 서버에서 지원하는 SSH 포트 번호(일반적으로 22) 적는다.
  • Connection type : SSH 설정한다.

 

* 이후 계속 사용하기 위해서 세션에 대한 정보를 저장해 둔다. 여기서는 SSH TEST 저장한다.

 

Connection -> SSH 누르면 SSH 세팅 정보가 나오며 다음과 같이 설정해 준다.

 


 

  • Enable Compression 체크
  • Preferred SSH protocol version : SSH 서버에서 지원하는 버전으로 설정(일반적으로 2 설정)

 

Connection - SSH - Tunnels 누르면 SSH 터널에 대한 설정을 해줄  있다.



  • Source port : 사용자의 PC에서 사용되지 않는 포트 번호를 적는다. 여기서는 4567 적었다.
    포트는 사용자 PC에서 프록시 서버 포트로 사용될 , SSH 터널로 포워딩될 포트이다.
  • Dynamic, Auto 설정해준다.

 

Add 누르면 입력한 포트번호가 다음과 같이 포워딩된 포트 목록에 추가된다.

 

 

이제 설정이 모두 완료되었다.

다시 Session 눌러 설정한 세션 정보를 저장한다.

 

 

저장된 세션에 접속하고 서버에서 제공한(또는 설정한) 계정명과 비밀번호를 입력하면 다음과 같이 접속하게 된다. Putty 통해 SSH 프록시 서버를 사용하기 위해서는 반드시 서버에 로그인 상태여야 한다.

 

 

서버에 로그인된 상태에서

파이어폭스 - 설정 - 고급 - 네트워크 - 연결란의 설정을 누르고 다음과 같이 설정해준다.

 

 

*필자는 IE에서 먼저 시도해보았으나 SOCKS 프로토콜 사용이 원활히 진행되지 않아 파이어폭스에서 진행하였다.

 

접속 IP 확인해보면 외부에서 확인한 필자의 IP 실제 PC에서의 IP 다르단 것을 확인 있다.

 

 

마치며

일단 문서에서는 '높은 익명성을 보장하는 프록시' 대한 증명을 전혀 하지 않았다. 점에 대해서는 추후 문서에 추가할 예정이다.

  필자는 행동 익명화에 대해 공부하기 전에는 단순히 공격자만이 행동 익명화를 요구하는지 알았으나 수사관 또한 공격자의 감시를 피하기 위해 행동 익명화가 요구된다는 사실을 알게 되었다. 이를 포함한 많이 부족한 지식을 조금이라도 채워준 저자들에 대해 감사를 표한다.

 

참조

Malware Analyst's Cookbook and DVD, p10-17

Proxy Connections With SSH or PUTTY

(http://www.webhostingtalk.com/showthread.php?t=539067)

How to setup an SSH Proxy Server using Putty and Spoon Proxy

(http://www.pccured.com/blog/how-to-setup-ssh-proxy/)

Putty 0.60(r3) (http://www.chiark.greenend.org.uk/~sgtatham/putty/)

'Analysis > Reverse Engineering' 카테고리의 다른 글

자식 프로세스 디버깅하기  (0) 2012.09.08
AND

웹브라우저 디버깅을 위한 windbg 심볼 파일 경로 설정

Analysis/WinDbg 2013. 3. 19. 18:24 Posted by 알 수 없는 사용자


WinDbg에서 심볼 정보는 디버깅을 수행하는데 있어서 매우 중요하고, 필수적인 요소라고 할 수 있습니다. 이번 포스팅에서 소개할 내용은 웹브라우저 디버깅을 위한 심볼 파일 경로입니다. 최근 가장 많이 사용되고 있는 웹브라우저인 구글의 크롬과 모질라의 파이어폭스, 그리고 꾸준히 사용되고 있지만 최근에는 그 사용량이 많이 줄어든 인터넷익스플로러가 있습니다. 이 외에도 애플의 사파리나 오페라 등의 브라우저가 존재하지만 여기서는 기본적으로 인터넷익스플로러, 크롬, 파이어폭스에 대한 심볼 파일 경로만을 소개합니다.


  • 웹브라우저 심볼 파일 서버
    [IE] http://msdl.microsoft.com/download/symbols
    [Chrome] http://chromium-browser-symsrv.commondatastorage.googleapis.com
    [Firefox] http://symbols.mozilla.org/firefox


WinDbg를 실행한 후 아래 그림과 같이 [File]-[Symbol File Path]를 선택해 줍니다.



심볼 경로를 아래 그림과 같이 추가해 줍니다.

입력 형식은 SRV*[DIR_PATH]*[SYMBOL_SERVER] 이고, 세미콜론으로 구분하시면 됩니다.



끝~ :)

디버깅 시작!


'Analysis > WinDbg' 카테고리의 다른 글

windbg에서 idle 프로세스 찾기  (1) 2013.03.09
AND

windbg에서 idle 프로세스 찾기

Analysis/WinDbg 2013. 3. 9. 20:03 Posted by munggeun

windbg에서 idle 프로세스 찾기

 

1)

Idle 프로세스의 주소를 가지고 있는 PsIdleProcess 변수를 이용하는 것이다.

 

kd> !process poi(nt!PsIdleProcess) 0

PROCESS 82d38640 SessionId: none Cid: 0000 Peb: 00000000 ParentCid: 0000

DirBase: 00185000 ObjectTable: 88e01b80 HandleCount: 491.

Image: Idle

* poi(x) : x 가리키는 곳의

* process [address] 0 : address 있는 _EPROCESS 구조체를 참조하여 마스크 0(가장 최소한의 정보) 표현

 

kd> dt _EPROCESS 82d38640

ntdll!_EPROCESS

+0x000 Pcb : _KPROCESS

+0x098 ProcessLock : _EX_PUSH_LOCK

+0x0a0 CreateTime : _LARGE_INTEGER 0x0

…...

+0x160 PageDirectoryPte : _HARDWARE_PTE_X86

+0x160 Filler : 0

+0x168 Session : (null)

+0x16c ImageFileName : [15] "Idle"

 

2)

프로세스 컨트롤 블록인 _KPCR extension _KPRCB Idle 쓰레드 주소를 이용하는 것이다.

 

kd> !prcb

PRCB for Processor 0 at 82d2ed20:

Current IRQL -- 28

Threads-- Current 82d38380 Next 00000000 Idle 82d38380 -> Idle 쓰레드

Processor Index 0 Number (0, 0) GroupSetMember 1

Interrupt Count -- 0005617a

Times -- Dpc 0000001f Interrupt 00000039

Kernel 0003403e User 00000399

 

kd> !thread -p 82d38380 0

PROCESS 853e88e8 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000

DirBase: 00185000 ObjectTable: 88e01b80 HandleCount: 491.

Image: System

 


 

번째 방식과 번째 방식의 차이점은 Idle 프로세스이냐 System 프로세스이냐 인데

System 프로세스는 Idle 프로세스와 존재하는 메모리 영역부터 다르므로

번째 방법으로 찾는 것이 맞는다고 본다.

 

kd> dc 82d38640-30 -> Idle 프로세스 주변 메모리 검사

82d38610 00000000 00000000 00000000 00000000 ................

82d38620 00000000 00000000 00000000 00000000 ................

82d38630 00000000 00000000 00989680 00000000 ................

82d38640 00260003 00000000 82d38648 82d38648 ..&.....H...H...

82d38650 82d38650 82d38650 00185000 00000000 P...P....P......

82d38660 00000000 00000000 00000000 82d38560 ............`...

82d38670 82d38560 00000000 00010001 00000000 `...............

82d38680 00000001 82d38684 82d38684 00000000 ................

 

kd> dc 853e88e8-30 -> System 프로세스 주변 메모리 검사

853e88b8 00000000 00000000 00000000 00000000 ................

853e88c8 045c005b e36f7250 00000083 00000003 [.\.Pro.........

853e88d8 00000000 02000007 82d39cc0 88e05ec1 .............^..

853e88e8 00260003 00000000 853e88f0 853e88f0 ..&.......>...>.

853e88f8 853e88f8 853e88f8 00185000 00000000 ..>...>..P......

853e8908 00000000 00000000 00000000 853e87f0 ..............>.

853e8918 85633620 00000000 00010001 00000000 6c.............

853e8928 00000001 853e892c 853e892c 00000000 ....,.>.,.>.....

 

System 프로세스 앞에는 헤더가 붙는데 Idle 프로세스 앞에는 헤더가 붙지 않고,

_EPROCESS 구조체의 실제 필드값들을 살펴보면 비슷한(완전히 똑같지는 않은) 점이 많다.

 

생각에는 System 프로세스가 먼저 실행 되고 후에 Idle 프로세스가 System 프로세스를 복사하면서

생성되는 같은데 부분은 살펴봐야겠다.

 

살펴보니 Idle 프로세스의 CreateTime 필드값은 0인데 반해 System 프로세스의 CreateTime 필드값는 0 아니다.

Idle 프로세스는 일종의 특수한 프로세스라고 생각해야 같다. --a

 

* Idle 프로세스는 단순히 사용 중이지 않은 CPU 자원을 나타내기 위한 프로세스이다.

 

남은 의문점)

Idle 프로세스는 언제 생성되는가?

Idle 프로세스 앞에는 헤더 및 오브젝터 헤더가 붙지 않는가?

Idle 프로세스는 풀에 존재하지 않는가?

 

참고)

https://groups.google.com/forum/?fromgroups=#!topic/microsoft.public.windbg/vlgDfK0XrNU

windbg help '!pcr', '!prcb', '!process' 항목

 

 
AND


* 이 글은 Corelan Team에서 'corelanc0d3r'님께서 작성한 글을 번역한 것입니다. 개인적으로 궁금해서 번역한 글이고, 저의 영어 실력이 형편없는 관계로 실제 원본과 내용이 많이 다를 수 있으니 유의하시기 바랍니다. 혹시 내용 중에 잘못 된 부분이 있다면 수정해 주시면 감사하겠습니다. :)


[원제] DEPS - Precise Heap Spray on Firefox and IE10

2013년 2월 19일 by Corelan Team(corelanc0d3r)


1. 소개(Introduction)


지난주에 교육용 프로그램을 리뷰하고 업데이트하던 중에 최신 버전에서는 더 이상 작업하지 않는 파이어폭스 9에서의 힙 스프레이 스크립트를 발견하였다. 트릭I 은 파이어폭스 9와 인터넷 익스플로러 9에서 정밀한 힙 스프레이를 수행하기 위해 사용했었다. 그리고 이러한 변화가 파이어폭스나 인터넷 익스플로러 10 에서는 어떤 유용한 효과도 없다는 것을 깨달았다. 이러한 문제에서 정밀한 힙 스프레이나 다른 어떤 힙 스프레이를 수행하기 위해서는 더 이상 이런 고전적인 BSTR 스트링 할당에만 의존할 수 없겠다고 생각했다.


파이어폭스 9 힙 스프레이는 보기에도 좋지 않을 뿐만 아니라 매우 느리고, 익스플로잇에 대한 신뢰도 좋지 않을 것이다. 만약 힙 스프레이가 완료되고, 버그가 발생되기 전에 사용자가 브라우저 프로세스를 종료시킬 수 있는 기회를 얻는다면, 쉘(shell)을 볼 수 없을 것이다.


물론, 최신 브라우저에서 정밀한 힙 스프레이를 수행할 수 없다는 것을 의미하지는 않는다. Core Security에서 Federico Muttis와 Anibal Sacco은 최근 HTML5 스프레이에 대한 연구 결과를 공개하였다. 이는 최신 브라우저에서 힙 할당을 수행하기 위해 새로운 기술을 활용할 수 있는 좋은 방법을 제공한다. 이 기술의 장점은 HTML5가 인터넷 익스플로러나 파이어폭스에만 국한되지 않기 때문에 구글 크롬과 사파리와 같은 웹킷(Webkit) 기반의 브라우저에서도 가능하다는 것이다. Federico & Anibal은 HTML5 기반 스프레이 루틴을 생성할 수 있는 스크립트 소스를 공개했다. 이 스크립트(HTML5Spray.zip)는 여기서 다운로드 할 수 있다. 어쨌든, HTML5를 사용하지 않고, 다른 것을 시도해보기로 했다.


Use-After-Free 시나리오가 문제가 될 수 있는 브라우저에서 이미 해제된 객체를 재사용하기 위해 BSTR 스트링을 사용한다는 것은 이미 잘 알려진 사실이다. 이는 객체의 상단에 위치한 vtable 포인터를 발견할 수 있을 것이고, 해제된 객체를 BSTR 스트링으로 교체한 후, BSTR 헤더 필드가 정확하게 배치될 것이다. 다시 말해서 객체를 대체할 수는 있지만, 컨트롤하기 위한 무언가를 vtable 포인터로 속일 수는 없을 것이다.


이러한 문제를 극복하기 위한 기술은 DOM(Document Object Model) 엘리먼트(Element)를 기반으로 하는 것이다. 이 기술은 하나 이상의 DOM 엘리먼트(image, div 등)를 생성하고, 속성을 설정해야 하며, 해제된 객체에 쓰고자하는 페이로드(payload)를 포함해야한다. 예를 들어 image의 경우에는 .src 또는 .title 등의 속성이 될 수 있고, div 객체의 경우에는 .className이 고정 옵션이 되어야할 것이다.


어찌됐든 이렇게 정밀한 할당을 수행할 수 있기 때문에, 완전히 진행된 힙 스프레이를 위해 동일한 기술을 사용할 수 있다는 것을 확인해 보고 싶다. 일단 일부 크기로 실험해 본 후, 파이어폭스와 모든 버전의 인터넷 익스플로러와 함께 스크립트를 집어넣어 관리할 것이다. 이 힙 스프레이는 높은 메모리 영역에서 수행될 것이기 때문에 이전에 사용했던 파이어폭스 9와 인터넷 익스플로러 9에 대한 힙 스프레이보다 성능이 더 좋을 것이다. 또한 기본 EMET(Enhanced Mitigation Experience Toolkit) 힙 스프레이 프로텍션을 우회할 수도 있다.


2. 기술(The technique)


이 기술의 아이디어는 다수의 DOM 엘리먼트를 생성하고, 특정 값으로 엘리먼트 속성을 설정하는 것에 기반을 둔다. 이 개념을 버튼(button) 엘리먼트를 이용하여 테스트해 보았다. 그리고 나중에 다양한 엘리먼트를 조합하여 사용해 볼 수 있을 것이다. 그렇기 때문에 이 기술의 이름을 “DOM Element Property Spray”라고 지었다. 정보보안 업계에서는 혼란스럽게 4글자의 약어로 만드는 것에 대한 강한 욕구가 있는 것 같다. 그래서 이 기술의 이름을 "DEPS"로 결정했다. 만일 좋아하는 보안 어플라이언스가 DEPS 방지를 주장한다면 그것이 무엇인지 알 수 있을 것이다. 또는 모를 수도 있을 것이다. 다시 말하지만, 정밀한 할당을 유발하는 DOM 엘리먼트의 사용은 새로운 것이 아니다. 그러나 이 개념을 기반으로 한 힙 스프레이는 보지 못했다.


DEPS 기술은 다음 4단계로 이루어진다.


  • 페이지에 div 엘리먼트 삽입
  • 다수의 button 생성
  • 페이로드와 함께 title 속성 설정, 원하는 길이를 가지고 있는지 확인하기위해 substring() 사용
  • div에 button 추가


3. 스크립트(The script)


기본 스크립트는 다음과 같다.



여기에서 이 스크립트 파일(deps_corelan_ff_ie_spray.zip)을 다운받을 수 있다. 다운받은 압축 파일의 패스워드는 ‘infected’이다.


보시다시피 이 스크립트는 더 이상 0x0c0c0c0c에 위치한 ROP 체인의 시작을 얻는 것에 초점을 맞추고 있지 않다. 이제는 더 이상 직접 코드를 실행하지 않고(DEP를 먼저 해제하지 않고), vtable 역참조(dereference)를 위한 대상으로써 0x0c0c0c0c와 nop를 사용할 수 있기 때문에, 0x0c0c0c0c의 사용은 그 진가를 잃어버렸다. 그 위에 대상 주소를 네 번 같은 바이트로 구성할 필요가 없다. 할당은 4바이트로 정렬되어야 하고, 매번 정확한 지점을 공격하는데 문제가 없어야 한다.


document에서 div 엘리먼트는 플레이스홀더(placeholder)로 사용된다. 그래서 div_container.appendChild() 함수는 엘리먼트를 저장할 수 있고, 또 메모리에서 이 엘리먼트들의 타이틀 속성을 저장할 수 있다. 그리고 이것들을 그 곳에 계속 유지할 수 있다. 할당 크기로 인해서 모든 청크(chunks)들은 기본 힙의 VirtualAllocdBlocks 리스트의 일부가 된다.


스크립트의 현재 버전은 파이어폭스에서 0x20202210 또는 0x20302210을 대상으로 하고(사용한 반복 횟수에 따라 0x20302210이 매우 신뢰할 수 있었다.), 인터넷 익스플로러 8/9/10(XP/Win7/Win8)에서는 0x20202228 또는 0x20302228로 한다. 더 이상 정밀한 힙 스프레이를 수행하기 위해서 인터넷 익스플로러 버전을 구별할 필요가 없기 때문에 이는 매우 흥미로운 것이다. 실험한 결과로부터 0x20202228보다 더 신뢰할 수 있는 0x20302228을 발견하였다.


물론 그것이 필요하거나 원하는 일이라면, 스크립트에서 오프셋 값을 변경하고, 다른 주소로 ROP 체인의 실제 시작을 이동하는 것은 매우 쉬운 일이다. 이 높은 메모리 범위의 편리한 부작용은 아스키(ASCII)로 출력 가능한 문자로 구성된 주소를 포함한 더 높은 메모리 주소 영역을 공격해야 한다는 것이다. 그리고 타이트한 문자 제한을 가진 옛날 방식의 스택 버퍼 오버플로를 발견한 경우에는 몇 가지 추가적인 이득을 제공할 것이다.


만약 다른 엘리먼트 속성을 사용하려면, obj.style.fontFamily를 사용 해봐도 좋다. 사실 예측 가능한 주소를 얻기 위해 필요한 반복 횟수를 줄여야 동시에 다른 두 개의 속성을 설정할 수 있다.



마지막으로 이 기술은 이 시점에서 어떤 데이터 랜덤도, 또는 변수명과 eval()와 함께 보기 싫은 트릭도 필요로 하지 않는다. 또한 스프레이가 상대적으로 빠른 방법으로 전달될 수 있도록 보장하는 것을 돕는다.


4. 테스트 환경(Test environment)


모든 경우는 완전히 패치 된 버전의 운영체제에서 특정 브라우저의 최신 32비트 버전이 사용되었다. 테스트는 가상머신(VirtualBox, VMWare)과 물리머신에서 수행되었으며, 재부팅 후에 작동하도록 검증되었다.


모든 테스트는 윈도우 7에서 EMET 3.5 활성화 & 힙 스프레이 탐지/방지 설정과 함께 수행되었다.



윈도우 8에서는 기본 인터넷 익스플로러 10을 설치하여 테스트하였다.


5. 결과(Results)


윈도우 7에서 파이어폭스 18:



윈도우 XP에서 인터넷 익스플로러 8:



윈도우 7에서 인터넷 익스플로러 9:



윈도우 8에서 인터넷 익스플로러 10:



모든 경우에 “AAAABBBBCCCCDDDD...” 문자열(기본적으로 ROP 체인이 배치된 곳을 표시)을 포함한 청크의 힙 레이아웃은 다음과 같다.


 VirtualAlloc 청크 헤더(0x20 바이트) 

 Junk(공백)

 ROP 체인(AAAABBBBCCCCDDDD...)

 Shellcode

 Junk(공백)



6. 스프레이 분석(Spray analysis)


DEPS 힙 스프레이의 기본 버전을 실행할 때, 정확히 무슨 일이 일어나는가? 윈도우 XP SP3, IE8에서 일부 트레이싱(tracing)과 로깅(logging)을 살펴본다.


먼저 핵심 루틴을 변경하고, 자바스크립트에서 WinDBG와 상호 작용하기위해 Math.atan2() 함수를 추가한다.


for (var i = 0; i < 0x500; i++)
{
	Math.atan2(0xbabe, "[*] Creating object button....");
	var obj = document.createElement("button");

	Math.atan2(0xbabe, "[*] Assigning data to title.");
	obj.title = data.substring(0,0x40000-0x58); //aligned spray 

	Math.atan2(0xbabe, "[*] Let's AppendChild");
	div_container.appendChild(obj);
}


WinDBG에서 아래 브레이크포인트는 Math.atan2()의 메시지를 출력한다.


bu jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g"


다음으로 아래 브레이크포인트는 버튼이 생성되는 것을 확인하기 위해 설정한다.


bp mshtml!CButton::CreateElement+16 ".printf \"Object at %08x\",eax; .echo;"


html 페이지를 실행할 때, WinDBG는 "Creating object button" 메시지를 표시해야 하고, CreateElement 함수에서 멈춰야한다.


[*] Creating object button....
Object at 00214dc0
eax=00214dc0 ebx=6363c470 ecx=7c9101bb edx=00000058 esi=032114f0 edi=020bf190
eip=639944f7 esp=020bf130 ebp=020bf134 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
mshtml!CButton::CreateElement+0x16:

639944f7 8bf0 mov esi,eax


모든 서브시퀀스 할당 로그와 콜 스택 출력을 위해 RtlAllocateHeap에 브레이크포인트를 설정한다.


bp ntdll!RtlAllocateHeap+117 ".printf \"Allocate at %08x\", eax; .echo; k; .echo; g"


이렇게 브레이크포인트를 설정하고, 프로세스를 계속해서 실행하면, 한 번의 반복 내에서 모든 할당에 대한 정보를 얻을 수 있다. 한 번의 반복은 다음과 같은 할당들을 생성한다.


Allocate at 0293d588
Allocate at 0293ea00
Allocate at 02866780
Allocate at 039b0020 <--- First interesting allocation
Allocate at 0293eb68
Allocate at 03b50020 <--- Second interesting allocation
Allocate at 02917718
Allocate at 001eff28
Allocate at 001effd8
Allocate at 00217d18
Allocate at 0293d568

Allocate at 002150c0


첫 번째 흥미로운 할당은 정확히 디버깅 메시지 "Assigning data to title."가 출력된 후에 발생한다. 그리고 이는 다음과 같은 콜스택을 갖는다.


Allocate at 039b0020
ChildEBP RetAddr
020bf330 77124b32 ntdll!RtlAllocateHeap+0xeac
020bf344 77124c5f OLEAUT32!APP_DATA::AllocCachedMem+0x4f
020bf354 633a8242 OLEAUT32!SysAllocStringByteLen+0x2e
020bf368 6338f693 jscript!PvarAllocBstrByteLen+0x6c
020bf3d4 63390403 jscript!JsStrSubstrCore+0x1d8
020bf3f4 633a8561 jscript!JsStrSubstring+0x20
020bf45c 633a7127 jscript!NatFncObj::Call+0x103
020bf4e0 633a6650 jscript!NameTbl::InvokeInternal+0x2a2
020bf514 6339f39f jscript!VAR::InvokeByDispID+0x17c
020bf554 633a67c9 jscript!VAR::InvokeJSObj+0xb8
020bf590 633a77ff jscript!VAR::InvokeByName+0x170
020bf5dc 633a85c7 jscript!VAR::InvokeDispName+0x7a
020bf60c 633a83a9 jscript!VAR::InvokeByDispID+0xce
020bf7a8 633a5ab0 jscript!CScriptRuntime::Run+0x28ab
020bf890 633a59f7 jscript!ScrFncObj::CallWithFrameOnStack+0xff
020bf8dc 633a5743 jscript!ScrFncObj::Call+0x8f
020bf958 633891f1 jscript!CSession::Execute+0x175
020bf9a4 63388f65 jscript!COleScript::ExecutePendingScripts+0x1c0
020bfa08 63388d7f jscript!COleScript::ParseScriptTextCore+0x29a

020bfa30 635bf025 jscript!COleScript::ParseScriptText+0x30


첫 번째 할당이 jscript!JsStrSubstring을 사용했기 때문에, 이는 JScript 코드에 의해 실행되었다고 가정한다.


data.substring(0,0x40000-0x58);


두 번째 할당은 정확히 디버깅 메시지 "Let’s AppendChild"가 출력되기 전에 발생한다. 그리고 콜스택은 다음과 같다.


Allocate at 03b50020

ChildEBP RetAddr
020bf16c 63651871 ntdll!RtlAllocateHeap+0xeac
020bf190 6364130b mshtml!CAttrValue::InitVariant+0x154
020bf1c8 63641259 mshtml!CAttrArray::Set+0x174
020bf1f0 636518d7 mshtml!CAttrArray::Set+0x51
020bf224 63651849 mshtml!CAttrArray::SetString+0x44
020bf23c 6366913f mshtml!BASICPROPPARAMS::SetString+0x69
020bf2a4 63610e83 mshtml!BASICPROPPARAMS::SetStringProperty+0x200
020bf2cc 63610eb8 mshtml!CBase::put_StringHelper+0x64
020bf2e8 6366906f mshtml!CBase::put_String+0x29
020bf318 636430c9 mshtml!GS_BSTR+0x1ab
020bf38c 6366418a mshtml!CBase::ContextInvokeEx+0x5d1
020bf3dc 6362b6ce mshtml!CElement::ContextInvokeEx+0x9d
020bf408 63642eec mshtml!CInput::VersionedInvokeEx+0x2d
020bf458 633a6d37 mshtml!PlainInvokeEx+0xea
020bf498 633a6c75 jscript!IDispatchExInvokeEx2+0xf8
020bf4d4 633a9cfe jscript!IDispatchExInvokeEx+0x6a
020bf594 633a9f3c jscript!InvokeDispatchEx+0x98
020bf5c8 633a77ff jscript!VAR::InvokeByName+0x135
020bf614 633a75bf jscript!VAR::InvokeDispName+0x7a
020bf7a8 633a5ab0 jscript!CScriptRuntime::Run+0x1f27


이번 할당은 SetString을 사용했기 때문에, 실제로 속성에 데이터를 할당한 것으로 가정한다.


여기서 다음과 같은 조합을 사용하였다.


  • substring() 사용
  • DOM 엘리먼트 속성 이용
  • 이전 HTML 문서에서 생성된 div에 엘리먼트 추가
  • 데이터 복사본 생성 보장
  • 메모리에 할당


substring()으로 만들어진 문자열은 결국 사라지지만, SetString()으로 할당된 데이터는 메모리에 남아있다.


(thanks sinn3r for your windbg analysis of the spray)


7. 관련 게시글


Exploit writing tutorial part 11 : Heap Spraying Demystified

Metasploit Bounty ? the Good, the Bad and the Ugly

Root Cause Analysis ? Memory Corruption Vulnerabilities

Heap Layout Visualization with mona.py and WinDBG

HITB2012AMS Day 1 ? Window Shopping

Many roads to IAT

mona.py ? the manual

Universal DEP/ASLR bypass with msvcr71.dll and mona.py

Jingle BOFs, Jingle ROPs, Sploiting all the things… with Mona v2 !!

Corelan T-Shirt contest ? Derbycon 2012



-----------------------------------------

[출처] Corelan Team(corelanc0d3r)

https://www.corelan.be/index.php/2013/02/19/deps-precise-heap-spray-on-firefox-and-ie10/



AND