해당 CVE-2012-4792 IE 제로데이취약점분석은크게다음 2부분으로나눌수있다.
- use-free-after 취약점분석
- exploit 성공할수있는 EIP 제어방법
이번 글에서는 다음 블로그의내용을 따라가는 것으로 use-after-free 취약점을 이해해 보도록 하자.
Happy New Year Analysis of CVE-2012-4792 ( 출처: Exodus Team )
http://blog.exodusintel.com/2013/01/02/happy-new-year-analysis-of-cve-2012-4792/
일단 poc 코드를디버거(windbg)에붙여서실행해보자.
>windbg.exe -g -G -o “C:Program FilesInternet Exploreriexplore.exe” “C:poc.html”
[그림] CVE-2012-4792 POC(poc.html) 코드
다음 지점에서 크래쉬(Memory Access Violation) 가 발생한다.
해당 Access Violation이 발생하는 지점의 값이 어디로부터 전달된 것인지 파악하기 위해 발생지점을 역으로 추적해 보자.
[EAX+0DCh]은 EDI로부터 전달된 EAX 레지스트리 값을 참고하고 있고,
이 값은 mshtml!CElement::FindDefaultElem (635dcdbe)값의 리턴값이라는 것을 알았다.
635c3b61 56 push esi
635c3b62 6a01 push 1
635c3b64 ffb1a4010000 push dword ptr [ecx+1A4h]
635c3b6a e84f920100 call mshtml!CElement::FindDefaultElem (635dcdbe)
635c3b6f 8bf8 mov edi,eax
635c3b71 3bfe cmp edi
635c3b73 0f85350d1c00 jne mshtml!CMarkup::OnLoadStatusDone+0x4ef (637848ae) **** 637848ae 지점으로점프하는지점
637848ae 8b07 mov eax,dword ptr [edi] *** EDI(mshtml!CElement::FindDefaultElem 리턴값)
637848b0 57 push edi
637848b1 8975b0 mov dword ptr [ebp-50h],esi
637848b4 8975c0 mov dword ptr [ebp-40h],esi
637848b7 8975c8 mov dword ptr [ebp-38h],esi
637848ba 8975c4 mov dword ptr [ebp-3Ch],esi
637848bd 8975cc mov dword ptr [ebp-34h],esi
637848c0 8975d0 mov dword ptr [ebp-30h],esi
637848c3 ff90dc000000 call dword ptr [eax+0DCh] ****** 크래쉬발생지점
우리는 이번 취약점이 Heap 상에서 할당 및 해제되는 개체로 인하여 발생한다는 것을 이미 알고 있다.
따라서, 문제가 발생하는 EDI 값에 대한 좀 더 많은 정보를 추적하기 위해 windbg 에서 제공하는 Heap 명령을 사용한다. (매우 유용한 기능)
이 때, GFlags를 이용하면 해당 Heap에 대한 Call Stack 정보를 얻을 수 있다.
Call Stack 정보를 통해 해당 Heap 메모리의 상태(state)가 free 되었다는 것과 mshtml!CButton::’vector deleing destructor’ 함수를 통해서 해제되었다는 것을 추정할 수 있다.
639943c0 mshtml!CButton::`vector deleting destructor’ = <no type information>
[그림] CButton 객체를 해제하는 코드
CButton 개체는 mshtml!CButton::CreateElement함수를 통해 생성되고,HeapAlloc 후에 할당된 메모리 주소를 알 수 있다.
639944e1 mshtml!CButton::CreateElement = <no type information>
poc스크립트 코드를 기반으로 다음과 DOM Tree 구조를 그려볼 수 있다.
| e2 | q | element
—–> | e0 | form | object
—–> | e1 | dfn | object
—–> | button | element
[그림] DOM Tree
그럼, 이제 실제 디버깅을 통해 코드의 진행과정과 객체 생성/소멸 과정을 확인해보자.
이 때, windbg 에서 제공하는 log 메시지를 활용하고, 중간 디버깅 메시지를 출력하기 위해 다음 아이디어를 활용한다. (Good ^^;;;)
- 일단 소스코드 사이에 출력할 디버깅 문자열을 Math.atan2함수의 파라미터로 사용한다.이때,다른 함수를 사용해도 무방.
- jscript!JsAtan2 함수를 BP 로 걸어서 진입지점에서 브레이크를 건다.
- 멈춰진 진입지점에서 파라미터로 들어온 디버그 문자열 위치를 찾아서 로그(log) 메시지로 출력한다.
633b5f09 jscript!JsAtan2 = <no type information>
우리가 사용한 디버깅 메시지는 아래의 위치에서 찾을 수 있다.
이제 다음과 같이 디버깅을 위한 poc 를 수정한다.
[그림] 디버깅용 POC 코드
앞서 확인한 정보를 기반으로 다음 3 지점에 BP를 설정하고 로그메시지를 남긴다.
- 디버그 메시지 출력
: jscript!JsAtan2 진입에서 브레이크 걸리면 poi(poi(esp+14)+8)+8) 값을 출력하고 달려라.
>bp jscript!JsAtan2 “.printf “%mu”, poi(poi(poi(esp+14)+8)+8);.echo;g”
- CButton 객체 생성
: 함수 내부의 HeapAlloc() 된 후 브레이크 걸리면,할당받은 주소 eax 찍고 달려라.
>bp mshtml!CButton::CreateElement+0x16 “.printf “Created CButton at %p”, eax;.echo;g”
- CButton 객체 소멸
: 함수의 내부에서 HeapFree() 된 후 브레이크 걸리면,해제된 메모리 주소 ecx 찍고 달려라.
>bp mshtml!CButton::`scalar deleting destructor’ “.printf “Deleting CButton at %p”, eax;.echo;g”
이제 새로 수정된 new_poc.html 파일로 디버거를 다시 시작한다.
>windbg.exe -g -G -o “C:Program FilesInternet Exploreriexplore.exe” “C:new_poc.html”
디버거를 잠시 <pause>시킨 후 다음 BP를 걸고 달려보자…
굳이 디버로 각 지점을 따라가지 않아도, 디버깅 메시지를 통해 실행과정과 CButton 개체의 생성/소멸 순서를 한 눈에 파악할 수 있다.
Access Violation을 발생시키는 EDI 주소(0x002bcc68)가 CButton 객체인 것을 확인할 수 있다.
다음 “2. exploit 성공할수있는 EIP 제어방법” 은 다음편에서 알아보자.