标题 简介 类型 公开时间
关联规则 关联知识 关联工具 关联文档 关联抓包
参考1(官网)
参考2
参考3
详情
[SAFE-ID: JIWO-2024-3226]   作者: 小螺号 发表于: [2022-12-09]

本文共 [119] 位读者顶过


0x00 WSMan 与 WinRM

什么是WSMan?

[出自:jiwo.org]

以下定义来自 DMTF WS-MAN 和微软 WS-Management Protocol

另一个广泛应用于Windows系统的管理架构WMI也是基于DMTF定义的CIM协议标准


WSMan全称 Web Services Management,也叫WS-Man、WS-Management,是一个基于SOAP的设施管理协议的开源标准,可用于与任何实现了该协议的计算机设备交换管理数据。注意WSMan是标准定义而不是具体实现。

先介绍几个核心的概念:

Schema and Message

WSMan使用消息进行管理数据交换,这些消息由XML进行表示,WSMan中定义了一系列的XML Schemas用于构建消息 ,查看示例: https://www.dmtf.org/dsp/DSP8015

Resource

在每一个消息中会引用要处理的目标资源(Resource),资源由一个唯一的URI来对应(Resource URI),示例:http://schemas.microsoft.com/wbem/wsman/1

Action

此外WSMan还为消息定义了要对引用资源进行的动作(Action),比如WinRM支持 Get、Put、Create、Delete、Enumerate等,winrs.exe就是通过Create http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd这个资源来实现命令执行。

什么是WinRM?

WinRM是微软自己对WSMan标准的实现,提供了比较丰富的资源管理功能,从Windows XP开始集成于 Windows操作系统中。执行winrm get winrm/config/client时客户端所发送的消息,可以看到上面介绍的Resource以及Action。

这个消息表示对资源 http://schemas.microsoft.com/wbem/wsman/1/config/client 进行 http://schemas.xmlsoap.org/ws/2004/09/transfer/Get 操作


WinRM服务返回200响应,并附带以下SOAP响应消息:


来看 winrm/config/client 这个URI,通过winrm命令可以查询到它是一个别名。


0x01 在Windows中使用WinRM

本小节存在大量命令行实例,不感兴趣可直接跳过,如未特别指定则默认在Powershell环境下进行测试。

配置WinRM

从Windows Server 2012 R2开始,WinRM服务默认自动启动,并监听0.0.0.0:5985和

127.0.0.1:47001,更老的版本需要使用命令行进行配置。

winrm命令


quickconfig所做的事:

1. 配置winrm服务为自启动

2. 启用对远程管理服务的防火墙例外

3. 添加默认端口的监听器

Powershell


手动配置


客户端侧,需要配置允许连接任意远程WinRM服务,否则将无法访问任何外部WinRM服务,本文的末尾会介绍如何绕过这一限制


Powershell中实现了一个名为WSMan的驱动器,能够如同操作注册表那样访问WinRM的配置


连接远程Powershell会话


WinRM实现WSMan的规范并扩展增强了部分的管理能力,通过WinRM能够连接到交互式的Powershell,支持断开重连,相当于是Windows版本的ssh。

在Powershell中使用WinRM


执行命令

winrs.exe底层使用资源: http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd


访问WMI

推荐在WinRM可用时使用WinRM替代WMI来规避WMI的流量特征,由于远程WMI使用RPC作为底层协议,从流量层面来看会更加敏感一些,而WinRM的http(s)流量通过可配置url前缀、端口号更能达到隐蔽效果。

winrm


Powershell


0x02 WinRM插件

https://learn.microsoft.com/en-us/windows/win32/winrm/winrm-plugin-api

WinRM提供了插件机制,可加载native的dll作为插件来扩展WinRM的能力,用户注册自己的插件到WinRM以提供自定义资源。

WinRM把自带的许多功能也作为插件加载,比如前面用到的shell、powershell、wmi,通过 regquery 查询所有已注册插件:


插件运行在与WinRM服务独立的进程 wsmprovhost.exe 中,如果为插件开启了进程共享,那么多个插件将运行在同一进程。

查看插件配置:


利用场景

在渗透活动中,如果已经获取了主机的管理权限,那么可以注册自己的插件来实现权限维持,还可以将

原生的插件(比如pwrshplugin.dll)替换为添加了其他执行步骤的DLL,当管理员或者自动化程序通过

WinRM连接时,达到自启动的目的。


一个简单的插件


编译为DLL放到 C:\Program Files\winrmplug.dll : 编译需要链接WSMSVC.lib,否则会报错找不到符号


注册插件

插件注册需要用到一个XML,这个XML中包含了WinRM服务需要的所有插件配置信息:


命令行注册命令为:


执行 winrm get http://test.evilcorp.com/Test 验证:


插件的限制

1. 插件DLL只能放在 %windir%\System32 (32位在 SysWOW64 )和 %ProgramFiles% 或子目录;

2. 新插件注册需要重启WinRM服务(但是修改已有插件会自动应用修改);

解决:修改现有插件的注册表配置,将XML中的Filename修改到 c:\Program Files ,编写DLL动态转发原DLL相关功能,并实现自己的目的

3. 插件输入输出很麻烦,必须是XML格式,不利于工具开发;

解决:WsmSvc.dll提供了SHELL功能,能够直接收发二进制数据

4. 无法随WinRM服务自动启动,需有客户端访问才会加载插件DLL。

0x03 Remote PSSession 输入输出传递分析

前面说到了二进制输入输出的需求,如果直接使用WSManPluginObjectResult是无法直接输出二进制数据的,需要自己构造,并且Get等动作无法实现”长连接“效果。而这些问题在远程的PSSession中不存在,那么是否可以深入了解其实现原理,借鉴到自己的插件上呢?

WSMan.Automation

首先来看winrm的执行过程,执行winrm时最终执行的是winrm.vbs,通过查看该文件源码可得知最终是通过WSMan.Automation这一COM完成操作。


使用OleView查看该COM所包含的TypeLib定义,其中比较关键的是IWSManEx以及IWSManSession,

IWSManSession中可以看到比较熟悉的Action相关方法:


并没有看到与数据交互有关的方法,同时winrm也并没有提供一个叫做shell的子命令。

程序集 Microsoft.WSMan.Management 中用到了 {BCED617B-EC03-420b-8508-977DC7A686BD} COM,也就是WSMan.Automation的GUID:


WsmSvc.dll!WSManSendShellInput

再来看远程PSSession执行时的情况,在

System.Management.Automation.Runspaces.Internal.ClientRemotePowerShell 的构造函数中有 这样一段:


继续跟进 CreatePowerShellDataStructureHandler 方法,调用了虚方法 CreateClientCommandTransportManager



WSManClientSessionTransportManager 类实现了 CreateClientCommandTransportManager 方法:



WSManClientCommandTransportManager::SendData



最后调用 WsmSvc.dll!WSManSendShellInput 完成输入数据的传递,在MSDN可查询该函数的文档,

同时Windows SDK也包含该函数的定义在wsman.h头文件中:


0x04 实现远程连接命令执行的BOF

由于BOF存在的一些限制(比如无法长期保持内存),然而WinRM的API存在持续性的回调用户代码行为,故实现长会话的PSSession比较困难,这里采用执行一次连接一次的方式,只为给大家提供一个思路~

编写代码


起步

由于笔者所测试的版本里面BOF无法使用类和普通的全局变量,所以将贯穿整个BOF的变量保存到结构体中,通过全局的指针 globals 来引用。



预定义头部

考虑到exe与BOF兼容性,通过宏来将正常api替换成BOF形式的API调用


连接目标服务器



处理输入输出



绕过TrustedHosts

前提提到过客户端使用WsmSvc.dll会有远程主机限制TrustedHosts,为了绕过限制,笔者hook了

WsmSvc.dll导入表中的 RegQueryValueExW 函数,让TrustedHosts直接返回 "*"。




测试

测试环境: CS4.5



0x05 总结

WinRM是一个成熟的、在Windows生态中应用广泛的管理协议,在渗透实战中可优先考虑使用WinRM

进行横向和权限维持,通过本文对WinRM原理、实战的一些分析,希望能为攻击与防御带来更多的思

路。

评论

暂无
发表评论
 返回顶部 
热度(119)
 关注微信