15'' whitehat contest, (= 16'' UXG)
hwp 파일이 삽입된 pct파일(mac 이미지 확장자)을 읽을 때, imsReadChar 함수를 사용하게 되는데, 이 때 size검사를 하지 않아 BOF 취약점이 존재한다.
isgdi32.dll 로드 -> impct9.flt ( parser ) 로드 -> isgdi32.dll의 imsReadChar함수 호출 하는 식으로 동작한다.
1차 BOF는 정상적인 hwp.exe module에서 imsReadChar를 호출하는 과정에서 발생하는데, 이 때 1Byte를 size로 읽어와서 전달하기 때문에 256Byte 이상 쓸 수 없다. 그래서 1차, 2차로 나눠서 code를 삽입했다. injection된 code의 동작은 이렇다. 일단 RTL해서 VirtualAllocEx를 호출한 후, RETN하며 injection code section으로 코드의 진행 흐름을 바꿨다.
size에 98을 넣어 BOF 발생시켜 stack에 code injection ( 1차 BOF ) -> 2번의 RET 후에 HncXerCo 부분이 진행. ( 이는 정상적인 module ) -> RTL로 VirtualAllocEx (12DED8, 1000size, MEM_COMMIT, PAGE_EXECUTE_READWRITE)호출해 DEP 우회 -> RETN하면서 12DED4(injection area)로 실행흐름 변경 -> NOP를 타고 내려오다 LoadLibraryA로 isgdi32의 주소를 구한다음12C60을 더해 imsReadChar의 주소를 구한다.
(실제로 PEView로 isgdi32의 EAT 를 확인해보면 imsReadChar 부분의 Data는 12C60이다.)
RAV Data Value 000A6AC4 00012C60 imsReadChar -> string size arg 위치에 139를 넣고 imsReadChar를 호출 ( 2차 BOF ) -> imsReadChar에서 code를 쓴 후, 이번에는 RETN시 바로 injection code의 시작지점으로 간다. -> 실질적인 악성파일을 생성하고, 실행하는 code가 진행된다. ( pct 파일에서 1byte 씩 읽어와서 악성파일에 writefile로 쓰는데, 생각대로라면 pct에 악성파일의 Hex값이 있어야 하는데 없다. pct는 mac 이미지 확장자라서 windows에서 읽으려면 decoding이 필요한 것 같다. 그래서 imsReadChar를 이용해서 읽는 것이고, 이 함수를 통해 decoding 되면 악성파일에 들어가는 hex값이 나온다.즉 이미지파일 decoding 자체가 암호화처럼 쓰였다.)
* code 제작자가 바로 LoadLibrary 쪽으로 가지 않고 HncXerCo를 stack, register 초기화 목적으로 사용한 걸 보면, 이 module에 대해 잘 알고있는 것으로 보인다.(ROP) 게다가 이 module으로 RET하게 되도록 code가 작성되었는데, 이는 이 module의 주소가 고정적, 즉 ASLR의 적용을 받지 않는 module이어야만 가능하다.