티스토리 뷰


헙... 8월 MS보안 패치는 엄청나게 많군요.. --;;;

퀵하게 패치들을 훓어 보던 중

스택기반 버퍼 오버플로우 취약점 발견...

예제로 활용하면 좋을 것 같아서 간단히 정리해봅니다...

스택 BOF는 기본적으로 많이들 아시겠지만.....

정리를 위해서....

한번 더~~~ ^^;;;;

 

 

제 1장

 

 

여러분은

스택기반 버퍼 오버플로우 취약점을 분석 시

무엇을 찾아야한다고 생각하시나요????

 

1) 허용 가능한 스택의 크기를 확인하라..

 

허용된 로컬 스택의 버퍼 공간을 알아야...

Exploit 만들 때 RET 덮을 위치를 찾을 수 있고.....

탐지 시그니처를 만들 때 pcre에 적용할 문자열의 길이를 알 수 있으니까....

 

2) 어찌하여 스택오버플로우가 발생했는 지 원인을 파악하라...

 

취약점의 원인을 찾는 것은 기본...

물론, 이건 쉬운 일은 아니다..

코드를 그대로 따라가는 것은 쉬우나... 그 원인을 정확히 따라가려면 코드레벨이 아니라 프로그램의 전체적인 논리를 알아야 하기 때문에... T.T

원인을 파악하게 되면....

비공식 패치를 만드는 데 활용하거나

 벤더의 패치가 나왔을 때 Diffing(비교분석) 하여 원인 해결을 확인할 수 있다..

 

3)  메모리 복사 지점을 찾아라.....

 

"백문이불여일견" ... 백날 버퍼 넘친다고 말하면 무엇하게는가....

실제로 분석하는 과정에서 메모리 복사 지점을 찾아서

실제 버퍼가 넘쳐서 RET 부분을 덮어쓰는 부분을 확인한다...

또한, 할당된 로컬 스택공간의 전체에 처음부터 복사하지 않고

스택의 중간 부분에서부터 복사를 하는 경우도 종종 있다...

그렇다면, 실제 메모리 복사 지점에서 소스를 찾아 

RET까지의 버퍼 길이를 계산하는 것도 필요하다... 

 

4)  실제 CALL의 흐름이 바뀌는 부분을 확인하라.

 

스택에는 많은 RET 가 존재한다....

바로 전의 CALL의 RET를 덮어쓸 수도 있고..

더 많은 데이터를 사용하여 그 이전 CALL의 RET 주소를 덮어쓸 수도 있다....

어떤 RET가 덮어쓰여지는 지 확인하면

사용자가 원하는 공격코드로 점프하는 흐름 변경이

어느 CALL의 Return에서 발생하는 지 파악할 수 있다.

 

5)  취약점을 모두 파악했다면, Exploit를 만들어서 계산기를 띄워보자.. ^^

 

 

Hidden 언어로 적었더니... 좀 두서가 없군여.

이해를..... ^^;;;

우리는 취약점 분석을 위해 방대한 모든 애플의 내부를 분석해볼 수는 없습니다... ^^;;

따라서, 목적에 따라 다소 차이는 있겠지만....

위의 요소들만 제대로 파악한다면...

그것이 스택오버플로 취약점을 모두 분석한 것이라 볼 수 있을 것 같습니다.... ^^V  

 

 

제 2장

 

 

그럼, 오늘 패치가 나온 CVE-2010-2564(MS10-050) 취약점에 대입시켜 살펴볼까염???

 

Summary:

 

-       취약한 파일 : moviemk.exe (.MSWMM 확장자 파일)

-       취약점 형식 : 스택기반의 버퍼 오버플로우

-       코드 실행 가능성: CALL 흐름은 사용자 제어가 가능하나 스택가드(Security_cookie???) 방식이 적용되어 있어.. 이를 우회하는 방식을 이용한 Exploit 제작필요..

 

 

Detail:

 

TIP!!! 째려보세요~  

스택오버플로우 분석시 Memory Watch 플러그인 이용하면 도움이 되지용 ~~

          

1)    스택의 범위 확인 :

 

012557FE  |> \8B07                       MOV     EAX, DWORD PTR [EDI]

01255800  |.  8D8D F0F7FFFF              LEA     ECX, DWORD PTR [EBP-810]  ECX = 000AEE04 (대략 2064(0x810) – 알파)

01255806  |.  51                         PUSH    ECX

01255807  |.  FF33                       PUSH    DWORD PTR [EBX]

01255809  |.  8BCF                       MOV     ECX, EDI

0125580B  |.  FF10                       CALL    DWORD PTR [EAX]

0125580D  |.  8D8D F0EFFFFF              LEA     ECX, DWORD PTR [EBP-1010]

 

2)    메모리 복사

 

01254341   .  FF75 EC                    PUSH    DWORD PTR [EBP-14]                                      ; /String2 = "????????????????????????????????????????????

01254344   .  FF75 0C                    PUSH    DWORD PTR [EBP+C]                                       ; |String1 = 00AEE04

01254347   .  FF15 B0120001              CALL    DWORD PTR [<&KERNEL32.lstrcpyW>]                        ; \lstrcpyW

 

7C7DBB14  |.  FF75 0C                    PUSH    DWORD PTR [EBP+C]                                       ; /src = ??????????????

7C7DBB17  |.  FF75 08                    PUSH    DWORD PTR [EBP+8]                                       ; |dest = 00AEE04

7C7DBB1A  |.  FF15 58127D7C              CALL    DWORD PTR [<&ntdll.wcscpy>]                             ; \wcscpy

 

 로컬 스택 공간은 2064 정도 남았는데 길이 체크없이 복사될 문자열은 4096 정도로 Overflow……

 


 

3)    콜의 흐름을 바꾸기 위해 Overwrite 되는 Return 위치 확인

 

0116015A   $  3B0D C8F82C01              CMP     ECX, DWORD PTR [12CF8C8]

01160160   .  75 09                      JNZ     SHORT moviemk.0116016B

01160162   .  F7C1 0000FFFF              TEST    ECX, FFFF0000

01160168   .  75 01                      JNZ     SHORT moviemk.0116016B

0116016A   .  C3                         RETN

0116016B   >  E9 05000000                JMP     moviemk.01160175

 

원래 대로라면, 위의 RETN  실행 후에 콜의 흐름이 아래처럼 EIP=41414141 Overwrite된 지점으로 바뀌어야 하지만… (계산기가 뿅~~~~~)

현재 Movie Maker에는 스택을 보호하는 기능이 포함되어 있어서 Exception이 발생하고 만다…..

 

4)    스택 보호 : 버퍼 오버플로우 후 코드 실행 방해….

 

다음 코드를 통해 함수의 처음에 다음의 [12CF8C8]  값을 가져와서 스택에 박는다…..

 

01255793  |.  A1 C8F82C01                MOV     EAX, DWORD PTR [12CF8C8]

01255798  |.  56                         PUSH    ESI

01255799  |.  8BF1                       MOV     ESI, ECX

0125579B  |.  8B4D 08                    MOV     ECX, [ARG.1]

0125579E  |.  85C9                       TEST    ECX, ECX

012557A0  |.  8945 F0                    MOV     [LOCAL.4], EAX

 

그럼… Overflow 나기 전 스택의 모습은 다음과 같다…

………. | Cookie?? | SEH | EBP | RET |

 

000AF600   000AF638

000AF604   00003BAD                                 

000AF608   000AF700  Pointer to next SEH record

000AF60C   012977E4  SE handler

000AF610   FFFFFFFF

000AF614  /000AF70C

000AF618  |01254799  RETURN to moviemk.01254799 from moviemk.0125577F

 

다음과 같이 함수가 종료되기 전, 다시 [12CF8C8]  값을 읽어와서 아까 박아놓았던 스택의 값과 비교한다. 따라서, 이 부분을 우리가 확~~~ 덮어버렸으니 올바르게 Return 되지 않고 Exception 처리되어버림…

 

0116015A   $  3B0D C8F82C01              CMP     ECX, DWORD PTR [12CF8C8]

01160160   .  75 09                      JNZ     SHORT moviemk.0116016B

01160162   .  F7C1 0000FFFF              TEST    ECX, FFFF0000

01160168   .  75 01                      JNZ     SHORT moviemk.0116016B

0116016A   .  C3                         RETN

 

 

이러한 스택보호 방식을 우회하는 방법도 나와있는 것 같으니..

우회방법을 이용하 쉘코드 제작은 시간 날 때 다시 봐야겠습니다..

 

 

 

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

다시 검토해볼 여유없이 그냥 올립니다..

두서없고.. 오타 많아도 이해해 주세요~~ ^^;;;


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

 

댓글
댓글쓰기 폼