前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VanillaRat功能代码分析

VanillaRat功能代码分析

作者头像
鸿鹄实验室
发布2021-04-29 17:35:18
4260
发布2021-04-29 17:35:18
举报
文章被收录于专栏:鸿鹄实验室鸿鹄实验室

前言

VanillaRat是一款由C#编写的remote administration tool,其github地址如下:https://github.com/dmhai/VanillaRAT

其功能如下:

  • Remote Desktop Viewer (With remote click)
  • File Browser (Including downloading, drag and drop uploading, and file opening)
  • Process Manager
  • Computer Information
  • Hardware Usage Information (CPU usage, disk usage, available ram)
  • Message Box Sender
  • Text To Speech
  • Screen Locker
  • Live Keylogger (Also shows current window)
  • Website Opener
  • Application Permission Raiser (Normal -> Admin)
  • Clipboard Text (Copied text)
  • Chat (Does not allow for client to close form)
  • Audio Recorder (Microphone)
  • Process Killer (Task manager, etc.)
  • Remote Shell
  • Startup
  • Security Blacklist (Drag client into list if you don't want connection. Press del. key on client to remove from list)

本文将从功能实现的角度来简单分析其功能实现的方法,并以此为想要编写C2的小伙伴们提供思路,毕竟很多代码我们都是可以直接拿过来用的。由于RAT不同于C2,所以本文更多的关注功能方面而忽略其通信方法。

信息获取--杀软

首先我们来分析其信息获取功能,在VanillaRat上线之后,会显示基本的目标信息,效果如下:

其默认端口、解析地址均写在了ClientSettings.cs中:

而基础的信息获取的实现,其代码文件如下

我们先来看一下杀软获取的代码:

代码语言:javascript
复制
       public static string GetAntivirus()
        {
            try
            {
                string Name = string.Empty;
                bool WinDefend = false;
                string Path = @"\\" + Environment.MachineName + @"\root\SecurityCenter2";
                using (ManagementObjectSearcher MOS =
                    new ManagementObjectSearcher(Path, "SELECT * FROM AntivirusProduct"))
                {
                    foreach (var Instance in MOS.Get())
                    {
                        if (Instance.GetPropertyValue("displayName").ToString() == "Windows Defender")
                            WinDefend = true;
                        if (Instance.GetPropertyValue("displayName").ToString() != "Windows Defender")
                            Name = Instance.GetPropertyValue("displayName").ToString();
                    }

                    if (Name == string.Empty && WinDefend)
                        Name = "Windows Defender";
                    if (Name == "")
                        Name = "N/A";
                    return Name;
                }
            }
            catch
            {
                return "N/A";
            }
        }

我们可以清楚的看到

代码语言:javascript
复制
@"\root\SecurityCenter2"
SELECT * FROM AntivirusProduct

等字样,是很明显的WMI得到利用方法,而在C#中一般用来获取硬件等信息的类为ManagementObjectSearcher。效果如下

信息获取--系统版本

先来上代码吧:

代码语言:javascript
复制

        [DllImport("kernel32.dll")]
        private static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetCurrentProcess();

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string moduleName);

        [DllImport("kernel32")]
        private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

        public static bool Is64BitOperatingSystem()
        {
            // Check if this process is natively an x64 process. If it is, it will only run on x64 environments, thus, the environment must be x64.
            if (IntPtr.Size == 8)
                return true;
            // Check if this process is an x86 process running on an x64 environment.
            IntPtr moduleHandle = GetModuleHandle("kernel32");
            if (moduleHandle != IntPtr.Zero)
            {
                IntPtr processAddress = GetProcAddress(moduleHandle, "IsWow64Process");
                if (processAddress != IntPtr.Zero)
                {
                    bool result;
                    if (IsWow64Process(GetCurrentProcess(), out result) && result)
                        return true;
                }
            }

            // The environment must be an x86 environment.
            return false;
        }

        private static string HKLM_GetString(string key, string value)
        {
            try
            {
                RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(key);
                return registryKey?.GetValue(value).ToString() ?? string.Empty;
            }
            catch
            {
                return string.Empty;
            }
        }

        public static string GetWindowsVersion()
        {
            string osArchitecture;
            try
            {
                osArchitecture = Is64BitOperatingSystem() ? "64-bit" : "32-bit";
            }
            catch (Exception)
            {
                osArchitecture = "32/64-bit (Undetermined)";
            }

            string productName = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName");
            string csdVersion = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CSDVersion");
            string currentBuild = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuild");
            if (!string.IsNullOrEmpty(productName))
                return
                    $"{productName}{(!string.IsNullOrEmpty(csdVersion) ? " " + csdVersion : string.Empty)} {osArchitecture} (OS Build {currentBuild})";
            return string.Empty;
        }

这个是使用的winapi来进行版本的获取,可以参考该文章:https://www.cnblogs.com/fresky/archive/2012/11/27/2791482.html

它这里自己实现了判断的功能,而c#中是自带了如何判断的即:

代码语言:javascript
复制
Environment.Is64BitOperatingSystem

然后就是通过注册表来查询具体信息了,效果如下:

信息获取--地区等

RAT上显示的如下:

即cpu类型、电脑名、内存、国家、省份、城市。

电脑名获取:

代码语言:javascript
复制
        public static string GetName()
        {
            return Environment.MachineName;
        }

内存获取:

代码语言:javascript
复制
        public static int GetRamAmount()
        {
            try
            {
                int RamAmount = 0;
                using (ManagementObjectSearcher MOS = new ManagementObjectSearcher("Select * From Win32_ComputerSystem")
                )
                {
                    foreach (ManagementObject MO in MOS.Get())
                    {
                        double Bytes = Convert.ToDouble(MO["TotalPhysicalMemory"]);
                        RamAmount = (int) (Bytes / 1048576);
                        break;
                    }
                }

                return RamAmount;
            }
            catch
            {
                return -1;
            }
        }

CPU类型:

代码语言:javascript
复制
        public static string GetGPU()
        {
            try
            {
                string Name = string.Empty;
                using (ManagementObjectSearcher MOS =
                    new ManagementObjectSearcher("SELECT * FROM Win32_DisplayConfiguration"))
                {
                    foreach (ManagementObject MO in MOS.Get()) Name += MO["Description"] + " ;";
                }

                Name = RemoveLastChars(Name);
                return !string.IsNullOrEmpty(Name) ? Name : "N/A";
            }
            catch
            {
                return "N/A";
            }
        }

地区信息,这个的实现还是比较有意思的,通过请求http://ip-api.com/json/来从返回的json串中得到相关的信息。代码如下:

代码语言:javascript
复制
            try
            {
                DataContractJsonSerializer JS = new DataContractJsonSerializer(typeof(GeoInfo));
                HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("http://ip-api.com/json/");
                Request.UserAgent = "Mozilla/5.0 (Windows NT 6.3; rv:48.0) Gecko/20100101 Firefox/48.0";
                Request.Proxy = null;
                Request.Timeout = 10000;
                using (HttpWebResponse Response = (HttpWebResponse)Request.GetResponse())
                {
                    using (Stream DS = Response.GetResponseStream())
                    {
                        using (StreamReader Reader = new StreamReader(DS))
                        {
                            string ResponseString = Reader.ReadToEnd();
                            using (MemoryStream MS = new MemoryStream(Encoding.UTF8.GetBytes(ResponseString)))
                            {
                                GeoInfo = (GeoInfo)JS.ReadObject(MS);
                            }
                        }
                    }
                }
            }
            catch { }

            GeoInfo.Ip = string.IsNullOrEmpty(GeoInfo.Ip) ? "N/A" : GeoInfo.Ip;
            GeoInfo.Country = string.IsNullOrEmpty(GeoInfo.Country) ? "N/A" : GeoInfo.Country;
            GeoInfo.CountryCode = string.IsNullOrEmpty(GeoInfo.CountryCode) ? "-" : GeoInfo.CountryCode;
            GeoInfo.Region = string.IsNullOrEmpty(GeoInfo.Region) ? "N/A" : GeoInfo.Region;
            GeoInfo.City = string.IsNullOrEmpty(GeoInfo.City) ? "N/A" : GeoInfo.City;
            GeoInfo.Timezone = string.IsNullOrEmpty(GeoInfo.Timezone) ? "N/A" : GeoInfo.Timezone;
            GeoInfo.Isp = string.IsNullOrEmpty(GeoInfo.Isp) ? "N/A" : GeoInfo.Isp;
        }

依赖于

代码语言:javascript
复制
using System.Runtime.Serialization.Json;

命令执行--shell

VanillaRat提供了shell来执行命令。显示如下:

核心代码位置在RemoteShellStream:

这边仿写了一个:

键盘记录

主类在:

然后在StreamClasses中调用:

就先分析到这里吧,还有很多功能,下次一定。

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

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

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

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

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