VanillaRat功能代码分析

  • A+
所属分类:逆向工程


前言


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


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上线之后,会显示基本的目标信息,效果如下:


VanillaRat功能代码分析


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


VanillaRat功能代码分析

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


VanillaRat功能代码分析


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


       public static string GetAntivirus()        {            try            {                string Name = string.Empty;                bool WinDefend = false;                string Path = @"\" + Environment.MachineName + @"rootSecurityCenter2";                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"; } }


我们可以清楚的看到


@"rootSecurityCenter2"SELECT * FROM AntivirusProduct


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


VanillaRat功能代码分析



信息获取--系统版本


先来上代码吧:


[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(@"SOFTWAREMicrosoftWindows NTCurrentVersion", "ProductName"); string csdVersion = HKLM_GetString(@"SOFTWAREMicrosoftWindows NTCurrentVersion", "CSDVersion"); string currentBuild = HKLM_GetString(@"SOFTWAREMicrosoftWindows NTCurrentVersion", "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#中是自带了如何判断的即:


Environment.Is64BitOperatingSystem


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


VanillaRat功能代码分析


信息获取--地区等


RAT上显示的如下:


VanillaRat功能代码分析


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


电脑名获取:


        public static string GetName()        {            return Environment.MachineName;        }


内存获取:


        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类型:


        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串中得到相关的信息。代码如下:


            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; }


依赖于


using System.Runtime.Serialization.Json;


命令执行--shell


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


VanillaRat功能代码分析


核心代码位置在RemoteShellStream:


VanillaRat功能代码分析


这边仿写了一个:


VanillaRat功能代码分析



键盘记录


VanillaRat功能代码分析


主类在:


VanillaRat功能代码分析



然后在StreamClasses中调用:


VanillaRat功能代码分析




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


     ▼
更多精彩推荐,请关注我们

VanillaRat功能代码分析



本文始发于微信公众号(鸿鹄实验室):VanillaRat功能代码分析

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: