▷ 작성자 : Hong10 (hong10@a3sc.co.kr)
▷ 편집자 : 니키 (ngnicky@a3sc.co.kr)

문서 작성일 : 2009년 2월 5일
최종 수정일 : 2009년 2월 5일

Hong10님께서 이번에는 "Microsoft Excel Could Allow Remote Code Execution(MS08-14)" 에 대해 집중 분석을 하였습니다. 개요 및 설명 (1부), 취약점 분석 (2부)로 하여 포스팅을 하겠습니다.


2. 취약점 분석
먼저 exploit 코드를 살펴 보면 취약한 헤더를 부분을 공략하기 위하여 특별히 제작 한 Resource 가 있습니다. 그리고 나서 Resource 뒷 바이트를 실행 시키고자 하는 바이너리와 합쳐 AV에 탐지가 안되게끔 임의로 Encode 을 함을 알 수 있습니다. 여기서 공격코드는 제가 작성한 Windows Universal ShellCode를 사용을 함으로 논의에서 빼겠습니다.

핵심은 어떻게 해서 헤더를 변조 시켜 Ret Address 를 공격 코드에 향하게 하는지 에 대하여 분석을 하겠습니다. Exploit 코드를 통하여 취약한 엑셀 파일을 생성 후 위에서 분석 한 구조체를 통하여 디버깅 한 결과 특이한 점 3가지를 발견 할 수 있었습니다.

첫 번째 엑셀 루틴에서 파일을 오픈 할 시 헤더를 분석하여 각 Storage 를 Open 하여 Stack  에 할당 하는데 읽어 드리는 사이즈가 헤더에서 정의한 Storage Dir 보다 큰 경우 파일에서 그 사이즈만큼 해당 Stack 에 값을 재할당 합니다.




위 그림에서는 사이즈가 아직 Storage 보다 크지 않기 때문에 바뀌지 않고 있습니다. 하지만 Trace 을 진행하다 보면(마지막 Storage Open 시 레코드의 사이즈가 전체 사이즈 보다 많으면 Stack에 옮기는 작업을 중단 합니다.) 그러한 루틴은 다음과 같이 확인 할 수있습니다.



위 그림에서 eax는 전체 사이즈를 나타내며 ecx는 레코드의 사이즈를 나타냅니다. 그리고 두 값을 비교하는 구문이 있는데 이것은 다음 그림에서 설명 드리겠습니다.

위에서 설명한 사이즈 비교 구문을 리턴 했을 때의 루틴입니다. Cmp [local1],edi 코드 부분을 살펴 보면 위에서 설명한 비교구문이 점프를 타지 않았다면 [local1] 값에는 1이 담겨 지게 되므로 점프를 타게 됩니다. 이는 아래의 cmp esi,809(809 레코드는 엑셀 문서 포맷에서 문서의 시작을 알립니다)

이런 루틴을 타지 않겠다는 의미이며 더 이상 Stack에 값을 할 당하지 않게 됩니다. 그리고 현재 ecx값(사이즈)은 0x5169 이며 esi 값은 0x8a2d(레코드) 값입니다. 이는 파일 오프셋의 0x2260 에 있는 값이며 후에 문제가 발생 되는 부분이기도 합니다.




어째든 최종적으로 0x00136d74 스택 메모리에는 다음과 같은 값이 할당 되었습니다.

두 번째 특이한 점은Storage 는 레코드 값으로 형성 되어 있습니다.엑셀을 이러한 레코드 값과 뒤에 할당 되어 있는 값을 읽어 드려 수행을 합니다. 이때 레코드 값이 DF 값이면 MsofallocMemcore 이란 함수를 사용하여 공격코드가 존재하는 오프셋 위치에서 사이즈 만큼 메모리에 할 당을 합니다. 해당 레코드 값을 엑셀 포맷 문서에서 찾아 본 결과 엑셀에서 그래프 같은 것을 쓸 때 생성되는 레코드 값인걸 알 수 있었습니다.




위 그림에서 문제가 되는 루틴을 자세히 살펴 보겠습니다.

300C1015   .  8B45 70       mov eax, dword ptr ss:[ebp+70]
300C1018   .  8B4D 64       mov ecx, dword ptr ss:[ebp+64]
300C101B   .  8941 04       mov dword ptr ds:[ecx+4], eax

Ebp+64 주소 값은 첫 번째 특이한 점에서 살펴본 주소 값입니다. 이 주소 값에 는 0x0013f8bc 라는 값이 할당이 되어있습니다. 그리고 ebp+70 에는 MsoAllocMemCore 함수에서 할당한 쉘 주소를 가리키는 주소 값을 가지고 있습니다. 거기에 0x0013f8bc+0x4 = 0x0013f8c0 이 되며 이 주소에는 쉘 주소를 가리키는 값을 담게 됩니다.

그림에 보면 eax 값은 0x0995000c 값이며 주소를 찾아 확인 해보면 쉘 주소임을 알 수 있습니다. 아래는 파일 오프셋의 0xe30 부근에 레코드가 0xd1e 이며 사이즈가 0x0d0a 인 값이 존재 함을 알 수있습니다.




이 값 다음에 e40 부근에 쉘 코드들이 시작 되었고 0xe3c+0xd0a = 1b46 즉 파일 오프셋 0x1b47 에 보면 다음과 같이 레코드가 0xdf 인 값을 발견 할 수 있습니다.



이는 DF 레코드 값을 처리 할 때 그 이전에 사이즈 만큼을 메모리에 할당 함을 알 수 있었습니다.

세 번째 엑셀 루틴에서 레코드 사이즈가 0x2020 보다 크다면 특정 루틴으로 향하게 됩니다. 이때 모든 루틴을 수행 하고 나서 다시 함수를 부른 주소로 돌아 갈 때 “add ebp,0x13d8 “ 라는 루틴이 존재합니다. Stack 값을 살펴 보면 ret address 는 쉘 코드가 존재하는 메모리 시작 주소를 가리키고 있으며 그 ret address 를 가리키는 Stack 값은 파일에 존재하는 특정 값으로 할당이 됩니다.

이는 첫 번째 특이한 점에서 Storage 을 Open 할 때 헤더에서 해석한 Storage Size 가 크다면 그 사이즈만큼(아마도 다음 Storage 분석을 위한 루틴인 듯) Stack 에 저장 하는데 이때 ret address 까지 덮어 씌울 수 있어서 두 번째 특이한 점에서 할당된 쉘 코드 주소로 변경 할 수 있어 실행 될 수 있었습니다.




위 그림에서 cmp eax,2020 과 비교를 하며 eax는 문제가 되는 레코드 사이즈 0x5169 값입니다.이렇게 점프를 타게 되고 쭉 trace를 하다 보면 다음과 루틴이 나오면 결국 쉘 주소로 리턴 됨을 알 수 있습니다.



위 그림에서 알 수 있듯이 add ebp,13d8 루틴으로 인해 리턴 어드레스 주소는 0x13f8c0 이며 이는 두 번째 특이한 점에서 할당된 쉘 주소를 가리키는 값임을 알 수 있습니다. 다음은 0x0905000c 루틴 입니다. 실행하면 쉘 이 실행 됨을 알 수 있습니다.



3. 취약한 엑셀 파일 만들기
분석 한 것을 토대로 취약한 엑셀 파일을 새로 만들어 보겠습니다. 참고로 DF 레코드 관련 된 엑셀 파일은 디폴트 페이지로 C:\Program Files\Microsoft Office\OFFICE11\1042 에 존재하는 XL8GALRY.XLS 파일이 있으며 예상대로 그래프 관련 엑셀 파일 이었습니다. 이 파일을 취약점 이 존재하는 파일을 만들기 위하여 다음과 같은 순서를 따르면 됩니다.

Storage 의 적정 레코드 위치(0x1de 레코드가 끝나는 오프셋)에 사이즈를 0xd0a 을 setting 한다.



 
setting 한 4바이트 뒤에 쉘 코드를 복사하여 붙여 넣는다.



0xd0a 사이즈를 setting 한 오프셋부터 0xd0a 를 더한 오프셋 위치에 다음 값을 붙여 넣습니다.



역시 setting 한 오프셋부터 0x70a 을 더한 오프셋 위치에서 다음 값을 붙여 넣으면 완성이다. 단 주의점은 ret address 위치 인데 만약 이 과정을 마친 후에 파일을 실행 했을 경우 아마 대부분 exception이 뜰 것이다.

Exception 주소를 살펴 보면 ret address 가 엉뚱한 위치를 가리켜서 그러한 것이니 해당 값을 파일에서 검색한 뒤 원하는 0xbcf81300 값으로 바꾸어 주면 쉘 을 실행할 수 잇습니다 



분석이 모자라 완벽히 리턴 어드레스 오프셋 위치까진 알 순 없었지만 그래도 취약점이 존재하는 엑셀 파일을 수동으로 만들어 볼 수 있었습니다. 이를 바탕으로 최근 패치 된 엑셀 바이너리를 분석 함으로써 새로운 취약점을 찾아 볼까 합니다.


Copyright(c) 1998-2009 A3 Security ,LTD


Disclaimer
※ 현재 ㈜에이쓰리시큐리티에서 테스트 및 분석 중에 있으며, 이 문서는 계속 업데이트될 것입니다. 본 문서는 보안취약점으로 인한 피해를 최소화하는 데 도움이 되고자 작성되었으나, 본 문서에 포함된 대응방안의 유효성이나 기타 예상치 못한 시스템의 오작동 발생에 대하여서는 ㈜에이쓰리시큐리티에서는 일체의 책임을 지지 아니합니다.