sweetchip's blog


오랜만의 포스팅!


지난번 데프콘에 갈 기회가 생겨서 다녀오게 되었는데 귀국후 바로 인코그니토 CTF와 친척들과의 휴가, 그리고 인코그니토 발표까지


대략 2주동안 힘들게 지낸끝에 모든일이 끝났다 ㅎㅎ..



2월 말까지 BOB 프로젝트로 웹브라우저 취약점 헌팅과 7월 말까지 WhiteHash를 진행하게 되면서 다시 한번 웹브라우저 취약점 헌팅에 도전하면서


IE를 분석하게될 일이 있었는데 VTGuard에 대해서 몇글자 써보려고 한다.




IE 10부터 VTGuard가 적용되었는데 이는 IE만의 Memory Protection중 하나이다.


VTGuard의 원래 이름은 Vtable Guard인데 원래 Vtable에 있어야 하는 일정한 쿠키값과 현재 Vtable의 쿠키값을 비교해서 무결성을 체크하는 기법이다.


그 원리에 대해서 간단하게 알아보자




우선 mshtml.dll의 내부를 뜯어보면 __vtguard 라는 함수가 자리를 차지하고 있는데 함수의 내용을 살펴보면


mov edi, edi

int 3

retn


이 끝이다. 처음 봤을때는 이게 진짜 끝인가 하고 이름을 좀더 추측해서 여러가지를 찾아봤지만 이 vtguard 함수가 끝이다.




그러다가 xref를 살펴보니 엄청나게 많은 양의 참조가 있는것을 보았는데 대부분 사용되는 것은 구조체안의 또다른 구조체 어느 값(vtable값중 일부)과 vtguard의 주소를 비교하는 것을 볼 수 있다.




이처럼 처음 mov ecx, [esi] 로 vtable의 pointer를 얻어오고 cmp dword ptr [ecx 328h]로 vtable cookie를 확인하는 것을 볼 수 있다.


간단하게 다시 글로 나타내면


|ptr to vtable| ???? | ???? | ???? | ???? | ???? | <- Heap Object

|????|????|????|????|????|cookie| <- Vtable


대략 이런 형태로 볼 수 있는데, 이때 cookie 값에는 mshtml이 로드된 뒤, (base address offset __vtguard) 의 값이 저장되어 있을 것이다.





그렇다면 어떤 효과가 있을까?


Heap Overflow에서는 효과가 적을 수도 있겟지만, Use After Free 취약점에 대해서는 어느정도 방어가 가능하다.


만약 위 그림의 .text:636dc10f의 ESI 레지스터가 Free된 Object의 포인터이고 공격자가 Object의 내용을 조종한 상태라고 가정한다.


또한 정상적인 Heap object와 vtable에는 각각 정상적인 ptr to vtable값과 cookie값이 들어가 있을 것이다.


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

정상적인 Heap Object

|Ptr to vtable (0x100a324b)| ???? | ???? | ???? | ???? | ???? | <- Heap Object

|????|????|????|????|????|cookie (0x63d2dfb4)| <- Vtable

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

UAF 취약점으로 인하여 변조된 Heap Object

|Ptr to vtable (0x12121212)| 0x12121212 | 0x12121212 | 0x12121212 | 0x12121212 | 0x12121212| <- Fake Heap Object

|0x0c0c0c0c|0x0c0c0c0c|0x0c0c0c0c| ... |0x0c0c0c0c|cookie(0x0c0c0c0c)| <- Fake Vtable

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


Object를 0x12121212 로 채워넣고 0x12121212 주소에는 0x0c0c0c0c가 채워져있다.


이 상태로 Vtguard 루틴으로 들어갈 경우 cmp dword ptr [ecx 328], offset __vtguard 부분에서 걸러지고




이후 프로세스가 혼자 죽어버린다.




엄청난 우회법은 현재 나와있지 않은 상태이다.


하지만 Vtguard는 __vtguard 함수의 주소를 Cookie로 사용하고 있기때문에 Information disclosure 버그로 mshtml의 Base Address 주소와


현재 mshtml 버전의 __vtguard 함수의 Offset만 더해서 구해주고 Fake Vtable에 삽입하면 된다.


하지만 말처럼 Information disclosure 버그를 찾는게 쉬운게 아니라서 조금더 간단한 방법을 찾아봐야 한다.



일단 Vtguard는 모든 Vtable에 대하여 적용된 것이 아니다.


또한 vtguard 체크 부분은 함수 실행 직전에 존재하며 함수 실행 여부는 이전의 분기문에서 결정된다.


또한 Heap object에는 생각보다 많은 정보를 담고 있다. 예를들어 다른 object의 주소같은것도 포함되어있다.



그러므로 UAF가 발생하고 Fake Object를 제작한 다음


vtable 함수 호출 분기문 이전에 여러 분기문으로 옮겨 다닐 수 있다면 Vtguard에 영향받지 않을 수도 있다는 것이다.


왜냐하면 조금전에 Vtguard는 모든 Vtable에 대해서 적용되지 않았기 때문에 아래와 같은 일이 일어날 수 있다.


|ptr to vtable| Heap object | ???? | ???? | ???? | ???? | <- Heap Object

|????|????|????|????|????|cookie| <- Vtable


Object가 만약 이렇게 구성되어 있고 운이 좋다면 Heap object 를 사용하는 분기문으로 이동 할 수도 있다.


|ptr to vtable| ???? | ???? | ???? | ???? | ???? | <- Heap object

|????|????|????|????|????|????| <- Vtable


그리고 이처럼 그 Object는 Vtguard가 적용되지 않은 Vtable의 주소를 가지고 있으면 게임 끝이다. (vtguard는 일부에만 적용된 것이므로 은근 이런 case가 간혹 있다. 끝까지 잘 찾아보자.)


이로써 (운이 좋으면) Vtguard에 영향을 받지 않고도 EIP Control이 가능하다.



Conclusion.


운이 좋으면 Vtguard에 영향받지 않고 EIP를 바꿔버릴 수 있다. 포기하지 말고 끝까지 살펴보자.



Reference


http://neilscomputerblog.blogspot.kr/2014/04/vtguard.html




만약 틀린 정보가 있으면 댓글 달아주시면 감사하겠습니다. (졸면서 글을 쓰고 있네요.. 틀린점이 있을지도.. ㅋㅋ )


바로 수정하겠습니다!


ps. 같이 연구하면서 도움을 주신 몽형 감사합니다.


신고

Comment 2