1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-12-21 05:35:54 +01:00

Beginning of work on the building blocks for PSH->Meterp bindings

This commit is contained in:
OJ 2016-03-22 16:06:43 +10:00
parent 6e5afca1b3
commit ee807408ec
11 changed files with 397 additions and 7 deletions

View File

@ -6,7 +6,7 @@
#define _METERPRETER_SOURCE_COMMON_COMMON_H
/*! @brief Set to 0 for "normal", and 1 to "verbose", comment out to disable completely. */
//#define DEBUGTRACE 0
#define DEBUGTRACE 0
#include <stdlib.h>
#include <stdio.h>

View File

@ -11,6 +11,7 @@
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
#include "powershell_bridge.h"
#include "powershell_bindings.h"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
@ -34,6 +35,7 @@ Command customCommands[] =
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
{
hMetSrv = remote->met_srv;
gRemote = remote;
DWORD result = initialize_dotnet_host();

View File

@ -0,0 +1,47 @@
/*!
* @file powershell_bindings.cpp
* @brief Wrapper functions for bridging native meterp calls to powershell
*/
extern "C" {
#include "../../common/common.h"
#include "powershell_bindings.h"
}
Remote* gRemote = NULL;
VOID MeterpreterInvoke(unsigned int isLocal, unsigned char* input, unsigned int inputLength, unsigned char** output, unsigned int* outputLength)
{
dprintf("[PSH BINDING] Input %p of %d bytes received", input, inputLength);
/*
dprintf("[PYTHON] a function was invoked on: %s", self->ob_type->tp_name);
const char* packetBytes = NULL;
BOOL isLocal = FALSE;
Py_ssize_t packetLength = 0;
PyArg_ParseTuple(args, "is#", &isLocal, &packetBytes, &packetLength);
dprintf("[PYTHON] packet %p is %u bytes and is %s", packetBytes, packetLength, isLocal ? "local" : "not local");
Packet packet = { 0 };
packet.header = *(PacketHeader*)packetBytes;
packet.payload = (PUCHAR)(packetBytes + sizeof(PacketHeader));
packet.payloadLength = (ULONG)packetLength - sizeof(TlvHeader);
// If the functionality doesn't require interaction with MSF, then
// make the packet as local so that the packet receives the request
// and so that the packet doesn't get sent to Meterpreter
packet.local = isLocal;
command_handle(gRemote, &packet);
// really not sure how to deal with the non-local responses at this point.
if (packet.partner == NULL)
{
// "None"
return Py_BuildValue("");
}
PyObject* result = PyString_FromStringAndSize(packet.partner->payload, packet.partner->payloadLength);
packet_destroy(packet.partner);
return result;
*/
}

View File

@ -0,0 +1,13 @@
/*!
* @file powershell_bindings.h
* @brief Declarations for bindings to meterpreter functions that can be called from Powershell.
*/
#ifndef _METERPRETER_SOURCE_EXTENSION_POWERSHELL_BINDINGS_H
#define _METERPRETER_SOURCE_EXTENSION_POWERSHELL_BINDINGS_H
extern Remote* gRemote;
VOID MeterpreterInvoke(unsigned char* input, unsigned int inputLength, unsigned char** output, unsigned int* outputLength);
#endif

View File

@ -1,5 +1,5 @@
/*!
* @file powershell_bridge.c
* @file powershell_bridge.cpp
* @brief Wrapper functions for bridging native meterp calls to powershell
*/
extern "C" {

View File

@ -273,11 +273,13 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\source\extensions\powershell\powershell.c" />
<ClCompile Include="..\..\source\extensions\powershell\powershell_bindings.cpp" />
<ClCompile Include="..\..\source\extensions\powershell\powershell_bridge.cpp" />
<ClCompile Include="..\..\source\extensions\powershell\powershell_runner.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\source\extensions\powershell\powershell.h" />
<ClInclude Include="..\..\source\extensions\powershell\powershell_bindings.h" />
<ClInclude Include="..\..\source\extensions\powershell\powershell_bridge.h" />
<ClInclude Include="..\..\source\extensions\powershell\powershell_runner.h" />
</ItemGroup>

View File

@ -0,0 +1,148 @@
using System;
namespace MSF.Powershell
{
public enum PacketType
{
Request = 0,
Response = 1,
PlainRequest = 10,
PlainResponse = 11
};
[Flags]
public enum MetaType
{
None = 0,
String = 1 << 16,
Uint = 1 << 17,
Raw = 1 << 18,
Bool = 1 << 19,
Qword = 1 << 20,
Compressed = 1 << 21,
Group = 1 << 30,
Complex = 1 << 31
};
public enum ExtensionBase
{
Stdapi = 0,
Incognito = 20000,
Priv = 20000,
Kiwi = 20000
};
public enum TlvType
{
// Actual types
Any = MetaType.None,
Method = MetaType.String | 1,
RequestId = MetaType.String | 2,
Exception = MetaType.Group | 3,
Result = MetaType.Uint | 4,
String = MetaType.String | 10,
Uint = MetaType.Uint | 11,
Bool = MetaType.Bool | 12,
Length = MetaType.Uint | 25,
Data = MetaType.Raw | 26,
Flags = MetaType.Uint | 27,
ChannelId = MetaType.Uint | 50,
ChannelType = MetaType.String | 51,
ChannelData = MetaType.Raw | 52,
ChannelDataGroup = MetaType.Group | 53,
ChannelClass = MetaType.Uint | 54,
ChannelParentId = MetaType.Uint | 55,
SeekWhence = MetaType.Uint | 70,
SeekOffset = MetaType.Uint | 71,
SeekPos = MetaType.Uint | 72,
ExceptionCode = MetaType.Uint | 300,
ExceptionString = MetaType.String | 301,
LibraryPath = MetaType.String | 400,
TargetPath = MetaType.String | 401,
MigratePid = MetaType.Uint | 402,
MigrateLen = MetaType.Uint | 403,
TransType = MetaType.Uint | 430,
TransUrl = MetaType.String | 431,
TransUa = MetaType.String | 432,
TransCommTimeout = MetaType.Uint | 433,
TransSessExp = MetaType.Uint | 434,
TransCertHash = MetaType.Raw | 435,
TransProxyHost = MetaType.String | 436,
TransProxyUser = MetaType.String | 437,
TransProxyPass = MetaType.String | 438,
TransRetryTotal = MetaType.Uint | 439,
TransRetryWait = MetaType.Uint | 440,
TransGroup = MetaType.Group | 441,
MachineId = MetaType.String | 460,
Uuid = MetaType.Raw | 461,
CipherName = MetaType.String | 500,
CipherParameters = MetaType.Group | 501,
PeerHost = MetaType.String | 1500,
PeerPort = MetaType.Uint | 1501,
LocalHost = MetaType.String | 1502,
LocalPort = MetaType.Uint | 1503,
// STDAPI stuff
ComputerName = MetaType.String | (ExtensionBase.Stdapi + 1040),
OsName = MetaType.String | (ExtensionBase.Stdapi + 1041),
UserName = MetaType.String | (ExtensionBase.Stdapi + 1042),
Architecture = MetaType.String | (ExtensionBase.Stdapi + 1043),
LangSystem = MetaType.String | (ExtensionBase.Stdapi + 1044),
Sid = MetaType.String | (ExtensionBase.Stdapi + 1045),
Domain = MetaType.String | (ExtensionBase.Stdapi + 1046),
LoggedOnUserCount = MetaType.Uint | (ExtensionBase.Stdapi + 1047),
Mount = MetaType.Group | (ExtensionBase.Stdapi + 1207),
MountName = MetaType.String | (ExtensionBase.Stdapi + 1208),
MountType = MetaType.Uint | (ExtensionBase.Stdapi + 1209),
MountSpaceUser = MetaType.Qword | (ExtensionBase.Stdapi + 1210),
MountSpaceTotal = MetaType.Qword | (ExtensionBase.Stdapi + 1211),
MountSpaceFree = MetaType.Qword | (ExtensionBase.Stdapi + 1212),
MountUncPath = MetaType.String | (ExtensionBase.Stdapi + 1213),
Pid = MetaType.Uint | (ExtensionBase.Stdapi + 2300),
ProcessName = MetaType.String | (ExtensionBase.Stdapi + 2301),
ProcessPath = MetaType.String | (ExtensionBase.Stdapi + 2302),
ProcessGroup = MetaType.Group | (ExtensionBase.Stdapi + 2303),
ProcessArch = MetaType.Uint | (ExtensionBase.Stdapi + 2306),
ParentPid = MetaType.Uint | (ExtensionBase.Stdapi + 2307),
ProcessSession = MetaType.Uint | (ExtensionBase.Stdapi + 2308),
// PRIV stuff
ElevateTechnique = MetaType.Uint | (ExtensionBase.Priv + 200),
ElevateServiceName = MetaType.String | (ExtensionBase.Priv + 201),
// KIWI stuff
KiwiPwdId = MetaType.Uint | (ExtensionBase.Kiwi + 1),
KiwiPwdResult = MetaType.Group | (ExtensionBase.Kiwi + 2),
KiwiPwdUserName = MetaType.String | (ExtensionBase.Kiwi + 3),
KiwiPwdDomain = MetaType.String | (ExtensionBase.Kiwi + 4),
KiwiPwdPassword = MetaType.String | (ExtensionBase.Kiwi + 5),
KiwiPwdAuthHi = MetaType.Uint | (ExtensionBase.Kiwi + 6),
KiwiPwdAuthLo = MetaType.Uint | (ExtensionBase.Kiwi + 7),
KiwiPwdLmHash = MetaType.String | (ExtensionBase.Kiwi + 8),
KiwiPwdNtlmHash = MetaType.String | (ExtensionBase.Kiwi + 9),
// INCOGNITO stuff
IncognitoListTokensDelegation = MetaType.String | (ExtensionBase.Incognito + 2),
IncognitoListTokensImpersonation = MetaType.String | (ExtensionBase.Incognito + 3),
IncognitoListTokensTokenOrder = MetaType.Uint | (ExtensionBase.Incognito + 4),
IncognitoImpersonateToken = MetaType.String | (ExtensionBase.Incognito + 5),
IncognitoGenericResponse = MetaType.String | (ExtensionBase.Incognito + 6),
IncognitoUserName = MetaType.String | (ExtensionBase.Incognito + 7),
IncognitoPassword = MetaType.String | (ExtensionBase.Incognito + 8),
IncognitoServerName = MetaType.String | (ExtensionBase.Incognito + 9),
IncognitoGroupName = MetaType.String | (ExtensionBase.Incognito + 10)
};
}

View File

@ -38,8 +38,11 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Enumerations.cs" />
<Compile Include="Meterpreter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Runner.cs" />
<Compile Include="Tlv.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -1,4 +1,5 @@
using System;
using MSF.Powershell;
using System;
using System.Collections.Generic;
using System.Text;
@ -8,10 +9,17 @@ namespace MSF.PowershellTester
{
static void Main(string[] args)
{
var x = MSF.Powershell.Runner.Get("Default");
System.Console.Write(x.Execute("$x = $(whoami)"));
System.Console.Write(x.Execute("$x"));
MSF.Powershell.Runner.Remove("Default");
//var x = MSF.Powershell.Runner.Get("Default");
//System.Console.Write(x.Execute("$x = $(whoami)"));
//System.Console.Write(x.Execute("$x"));
//MSF.Powershell.Runner.Remove("Default");
Tlv t = new Tlv();
t.Pack(TlvType.ElevateTechnique, 1);
t.Pack(TlvType.ElevateServiceName, "abcd1234");
var x = t.Bytes;
var y = 0;
}
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace MSF.Powershell
{
public static class Meterpreter
{
private delegate void MeterpreterInvoke(uint isLocal, byte[] input, uint inputSize, ref IntPtr output, ref uint outputSize);
private static MeterpreterInvoke _callback = null;
public static void SetInvocationPointer(Int64 callbackPointer)
{
_callback = (MeterpreterInvoke)Marshal.GetDelegateForFunctionPointer(new IntPtr(callbackPointer), typeof(MeterpreterInvoke));
}
public static string RandomString(int length)
{
var r = new Random();
var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var bytes = new byte[length];
for (int i = 0; i < length; ++i)
{
bytes[i] = (byte)chars[r.Next(chars.Length)];
}
return Encoding.ASCII.GetString(bytes);
}
internal static byte[] InvokeMeterpreterBinding(bool isLocal, byte[] input)
{
if (_callback != null)
{
IntPtr output = IntPtr.Zero;
try
{
uint outputLength = 0;
_callback(isLocal ? 1U : 0U, input, (uint)input.Length, ref output, ref outputLength);
var result = new byte[outputLength];
Marshal.Copy(output, result, 0, result.Length);
return result;
}
finally
{
if (output != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(output);
}
}
}
return null;
}
}
}

108
powershell/MSF.Powershell/Tlv.cs Executable file
View File

@ -0,0 +1,108 @@
using System;
using System.IO;
using System.Net;
using System.Text;
namespace MSF.Powershell
{
public class Tlv
{
private MemoryStream _stream = null;
public byte[] Bytes
{
get
{
if (_stream != null)
{
return _stream.ToArray();
}
return null;
}
}
public Tlv()
{
_stream = new MemoryStream();
}
public void Pack(TlvType t, bool b)
{
ValidateMetaType(MetaType.Bool, t);
Append(t, b ? new byte[] { 1 } : new byte[] { 0 });
}
public void Pack(TlvType t, uint i)
{
ValidateMetaType(MetaType.Uint, t);
Append(t, ToBytes(i));
}
public void Pack(TlvType t, int i)
{
ValidateMetaType(MetaType.Uint, t);
Append(t, ToBytes(i));
}
public void Pack(TlvType t, Int64 i)
{
ValidateMetaType(MetaType.Qword, t);
Append(t, ToBytes(i));
}
public void Pack(TlvType t, string s)
{
ValidateMetaType(MetaType.String, t);
var value = Encoding.UTF8.GetBytes(s + "\x00");
Append(t, value);
}
public void Pack(TlvType t, Tlv tlv)
{
ValidateMetaType(MetaType.Group, t);
var tlvBytes = tlv.Bytes;
if (tlvBytes != null)
{
Append(t, tlv.Bytes);
}
}
public void Pack(TlvType t, byte[] value)
{
ValidateMetaType(MetaType.Raw, t);
Append(t, value);
}
private void Append(TlvType t, byte[] value)
{
var type = ToBytes((int)t);
var length = ToBytes(value.Length);
_stream.Write(length, 0, length.Length);
_stream.Write(type, 0, type.Length);
_stream.Write(value, 0, value.Length);
}
private void ValidateMetaType(MetaType expected, TlvType actual)
{
if ((MetaType)((TlvType)expected & actual) != expected)
{
throw new ArgumentException("Invalid Meta type given");
}
}
private byte[] ToBytes(Int64 i)
{
return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i));
}
private byte[] ToBytes(int i)
{
return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i));
}
private byte[] ToBytes(uint i)
{
return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i));
}
}
}