还在用winrm吗?浅谈http.sys的使用姿势

本文详细介绍了Windows系统的http.sys组件,探讨了其端口复用功能、HTTPS隧道实现尝试以及如何利用http.sys开发网站管理工具如Joker。同时,文章还涉及了如何通过http.sys进行WinRM迁移和RD网关的远程桌面复用,尽管过程复杂,但提供了对这些技术的深入理解。

编者注:1.本文仅供学习研究,严禁从事非法活动,任何后果由使用者本人负责。2.本文一切操作都在管理员权限之下。

1. 什么是http.sys

http.sys是一个Windows系统的核心组件,能够让任何应用程序通过它提供的接口,以http协议进行信息通讯。微软在Win2003加入了Http.sys,用于侦听http流量并根据URL进行处理,允许任意用户进程共享专用于HTTP流量的TCP端口。也就是说,多个程序可以使用同一端口进行http的监听,而Http.sys充当了nginx的⻆色。通过netsh命令可以对http.sys的命名空间进行一系列操作,比如说IIS服务器,它的最底层就是HTTP.sys驱动。

HTTP.sys有两个特点:

  1. 1. 允许端口复用,可以让多个程序使用同一个端口进行监听。

  2. 2. 对HOST敏感,可以通过HOST进行分发流量。

系统当中会有一些默认的http.sys的保留注册项,如下:

 

而目前业内的普遍用法是使用5985端口的WinRM注册项,将其迁移到80端口进行复用,由于winrm服务在系统自带的命名空间当中已经被注册,命名空间与winrm程序之间已经有对应了,所以将winrm开在80端口就可以了,由于存在IIS的服务器,IIS的80端口占用也是在Http.sys之后,所以并不会有什么报错。

#将winRM迁移至80
winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="80"}
#将winRM还原为5985
winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="5985"}
#客户端连接命令
winrs -r:http://ip -u:user -p:pwd "whoami"
#pwd可为hash

2. 为什么研究它

由于针对Linux已经有比较成熟的端口复用手段,比如使用iptables与socks5脚本相结合,而我们一直只知道存在Windows的http.sys,并且知道这东西能复用,但是不知道如何复用,没有进行工具化。

3. HTTPS 隧道

在一开始,最理想的状态就是通过http.sys起一个HTTPS proxy的服务,让客户端通过HTTP CONNECT method来使用HTTPS代理服务。然而事实却是残酷的。

一起看一下HTTPS Proxy 的包:

图片

 

可以看出,PATH与HOST都是代理的目标与端口,继续测试。

图片

 

不难看出,HTTP CONNECT方法是不允许使用/作为uri的,我们再来看下HTTP.sys的注册要求。

图片

 

矛盾点出现了,HTTP CONNECT不能有/,HTTPSYS必须要/。改协议?改驱动?显然是不可能的,这条路放弃。

4. 网站管理工具

都研究这么久了,放弃http.sys研究定是不甘心的,思考之后我想到了可以通过他得天独厚的优势,做个网站管理工具。于是我开始找相关的项目,最后找到了一个HTTP.sys的Demo:

https://docs.microsoft.com/en-us/windows/win32/http/http-server-sample-application

进行一系列修改,得到了Joker工具。

https://github.com/ZhuriLab/Joker

4.1 基于路径复用

Joker.exe "http://*:{PORT}/{PATH}"

图片

 

可直接使用一些网站管理工具进行连接,配置如下:

图片

 

 连接密码随便填写。

图片

 

4.2 基于HOST进行复用

Joker.exe "http://{HOST}:{PORT}/"

图片

 

配置如下:

图片

 

图片

 

这样,在正常访问80端口的时候为正常业务,在带特殊的host访问80端口的时候则为网站管理程序。

5. 适配Regorg

正当整个研究要结束时,有一个工具在我的脑海里浮现了出来——Regeorg,一款TunnelWebShell工具。他的使用情景也是在不出网的地方进行正向代理,它虽然不能采用CONNECT方法,但是使用GET、POST方法进行数据传输同样也能得到隐藏的目的。

我于是写了一个适配regeorg的demo,也就是开源在Joker当中的JokerTunnel

使用方法:

  1. Server端执行 tunnel.exe <url1> <url2> <url3> ...

  2. 使用regeorg客户端连接。

图片

 

图片

 

本地测试访问某购物网站速度还可以:

图片

 

6. RD网关(域环境)

就当研究即将结束的时候,我突然想到这一个问题,是不是所有Windows自带的Web类型的系统服务都是通过HTTP.sys进行端口开放的?若是这样,岂不是可以通过端口复用的方式进行远程桌面连接?话不多说,开始搞。

在Win2019上进行测试,开启RD远程桌面网关,看下http.sys保留注册项的变化。

  • 未安装RD网关

图片

 

  • 安装RD网关

图片

 

图片

 

当RD网关安装完成后,可以发现http.sys多了两个443端口的注册项,证明了之前的猜想,RD网关确实是通过http.sys启动的,那么下一步就配置一下进行远程桌面与Web的复用。正当我配置RD过程中,服务器管理器显示了这句话:

图片

 

翻阅过大量文献后,我发现RD Gateway 需要域环境,那就在域环境去搞吧。

6.1 开启RD服务

图片

 

图片

 

6.2 配置RD Gateway

进入RD 网关资源策略

图片

 

图片

 

选择认证方式与可登录的组员。

图片

 

配置网络资源,配置RDGW可以连接到所有域内机器。

图片

 

6.3 安装SSL

图片

 

创建自签名证书。

图片

 

将证书导出,并安装到远程客户端机器(攻击机),远程客户端机器需要将DNS解析到域DNS上或者绑定hosts文件。

6.4 创建服务器场

图片

 

将需要远程拨上去的机器域名或者ip添加到服务器场。

6.5 远程登录

更改本地的mstsc的配置,配置如下:

图片

 

远程计算机输入域内机器,进行登录,登录过程中会使用两次凭据,一次为RD网关的凭证,一个是登录目的机器的凭证。

图片

 

图片

 

图片

 

从流量上来看,通过RD网关远程登录的机器,客户机与远程机器是完全没有流量交互的,再看下RD网关的情况。

图片

 

可以看出,客户机与RD网关完全是通过443进行流量交互的。

图片

 

而正常情况下,去访问RD网关机器的443端口是一个Web界面。

6.6 总结

RD网关的使用在步骤上整体非常繁琐,我们盘点一下需要的前置条件:

  1. 机器在域内

  2. 需要明文的域票据

  3. 步骤繁琐,很难将这些操作转换为命令行命令

  4. 防火墙允许443端口入站

总体来讲,使用RD网关远程桌面登录进行网站管理,配置步骤会很繁琐,前置条件也较多,若管理员只是为了传输文件或者不需要GUI界面,则Joker的启动方式会更为方便一些。

<think> 我们被要求提供在Windows服务器上批量启用WinRM服务的方法。根据引用资料,我们可以总结出以下步骤: 1. 单机启用WinRM服务的基本命令是: winrm quickconfig 2. 配置认证方式和加密方式: - 启用基本认证(Basic authentication): winrm set winrm/config/service/auth @{Basic="true"} - 允许非加密通信(为了兼容性,但生产环境建议使用加密): winrm set winrm/config/service @{AllowUnencrypted="true"} 3. 但是,这些命令需要在每台服务器上执行,如何批量执行呢? 批量执行方法: 方法1:使用组策略(Group Policy)部署 - 在域控制器上创建组策略对象(GPO) - 在计算机配置->策略->管理模板->Windows组件->Windows远程管理(WinRM)中配置相关设置 - 包括启用WinRM服务、设置监听端口、认证方式等 - 将GPO链接到需要启用WinRM的OU(组织单位)上 方法2:使用PowerShell远程执行(需要已有远程执行通道,如PSRemoting已开启或使用其他远程管理工具) - 假设我们已经在所有目标服务器上启用了PSRemoting(或者使用域管理员账户可以通过WMI远程执行命令),那么我们可以使用Invoke-Command来批量执行。 示例脚本: ``` $servers = Get-Content -Path "C:\servers.txt" # 假设这个文件里是每行一个服务器名或IP $credential = Get-Credential # 输入管理员凭据 Invoke-Command -ComputerName $servers -Credential $credential -ScriptBlock { # 启用WinRM服务 winrm quickconfig -quiet # 使用-quiet参数避免交互确认 # 设置基本认证 winrm set winrm/config/service/auth '@{Basic="true"}' # 允许非加密通信(可选,根据安全要求调整) winrm set winrm/config/service '@{AllowUnencrypted="true"}' } ``` 方法3:使用Ansible等自动化工具 - 如果已经配置了WinRM,则可以使用Ansible的win_ping模块测试连接,然后使用win_command模块执行命令。但第一次配置时,通常需要先通过其他方式(如SSH或者使用Ansible的raw模块通过PSRemoting)来启用WinRM。 方法4:使用PSTools工具包中的psexec - 下载Sysinternals PSTools - 使用以下命令在每台服务器上执行: psexec \\remotecomputer -u domain\admin -p password winrm quickconfig -quiet psexec \\remotecomputer -u domain\admin -p password winrm set winrm/config/service/auth '@{Basic="true"}' psexec \\remotecomputer -u domain\admin -p password winrm set winrm/config/service '@{AllowUnencrypted="true"}' 注意事项: - 启用基本认证和允许非加密通信存在安全风险,建议在安全的内网环境中使用,或者使用HTTPS(WinRM over SSL)来加密通信。 - 若需要启用HTTPS,则需要为每台服务器配置证书。 根据引用[3]中的提示,在PowerShell中执行上述winrm set命令可能会报错,此时可以尝试在CMD中执行。因此,在批量脚本中,我们可以通过powershell调用cmd来执行,或者直接写在批处理文件中。 例如,在方法2的Invoke-Command中,我们可以这样写: ``` Invoke-Command -ComputerName $servers -Credential $credential -ScriptBlock { cmd.exe /c "winrm set winrm/config/service/auth @{Basic='true'}" cmd.exe /c "winrm set winrm/config/service @{AllowUnencrypted='true'}" } ``` 当然,更推荐使用PowerShell来配置,因为winrm命令实际上是配置WinRM的,PowerShell也有对应的配置命令(如Set-Item),但使用winrm命令更直接。 引用: [^1]: [WinRM官方文档](https://learn.microsoft.com/en-us/windows/win32/winrm/installation-and-configuration-for-windows-remote-management) [^2]: 引用中提到了基础配置步骤 [^3]: 引用中提到在CMD中执行设置命令可以避免报错 [^4]: 引用中介绍了WinRM的作用 相关问题: §§相关问题§§ 1. 如何为WinRM配置HTTPS以提高安全性? 2. 如何使用组策略批量配置WinRM? 3. 如何验证WinRM服务已经成功启用并可以远程连接? 4. WinRM服务启用失败的可能原因有哪些? </think> ### Windows服务器批量启用WinRM服务方法 #### 方法1:使用PowerShell远程执行(推荐) ```powershell # 服务器列表文件(每行一个IP或主机名) $servers = Get-Content -Path "C:\servers.txt" # 凭据设置(需管理员权限) $cred = Get-Credential -Message "输入管理员凭据" Invoke-Command -ComputerName $servers -Credential $cred -ScriptBlock { # 启用WinRM服务 winrm quickconfig -quiet -force # 配置基本认证 winrm set winrm/config/service/auth '@{Basic="true"}' # 允许非加密通信(测试环境) winrm set winrm/config/service '@{AllowUnencrypted="true"}' # 配置防火墙规则 netsh advfirewall firewall add rule name="WinRM-HTTP" dir=in action=allow protocol=TCP localport=5985 # 验证服务状态 Get-Service -Name WinRM | Select-Object Status, StartType } ``` > **说明**: > - `-quiet`参数避免交互提示 > - 首次执行需在每台服务器手动启动一次WinRM服务以生成配置文件[^3] #### 方法2:通过组策略部署(域环境) 1. **创建GPO策略**: ```powershell # 配置WinRM服务自动启动 Set-GPRegistryValue -Name "WinRM_Enable" -Key "HKLM\SYSTEM\CurrentControlSet\Services\WinRM" -ValueName "Start" -Type DWord -Value 2 # 启用基本认证 Set-GPRegistryValue -Name "WinRM_Enable" -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" -ValueName "AllowBasic" -Type DWord -Value 1 ``` 2. **配置监听端口**: ```powershell # 创建监听器 $command = 'winrm create winrm/config/Listener?Address=*+Transport=HTTP' Set-GPPrefRegistryValue -Name "WinRM_Enable" -Context Computer -Action Update -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM" -ValueName "AutoConfig" -Type String -Value $command ``` 3. **应用到目标OU**: ```powershell Get-GPO -Name "WinRM_Enable" | New-GPLink -Target "OU=Servers,DC=novice,DC=com" ``` #### 方法3:使用Ansible批量配置 ```yaml # winrm_enable.yml --- - name: 批量启用WinRM hosts: windows_servers tasks: - name: 启动WinRM服务 win_service: name: WinRM start_mode: auto state: started - name: 配置认证方式 win_shell: | winrm set winrm/config/service/auth '@{Basic="true"}' winrm set winrm/config/service '@{AllowUnencrypted="true"}' - name: 开放防火墙端口 win_firewall_rule: name: WinRM-HTTP localport: 5985 action: allow direction: in protocol: tcp state: present enabled: yes ``` 执行命令:`ansible-playbook -i hosts winrm_enable.yml` #### 故障排查要点 1. **权限问题**: - 需使用**本地管理员**或**域管理员**权限执行 - 检查UAC限制:`Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -Value 0` 2. **端口冲突**: ```powershell # 检查端口占用 Get-Process -Id (Get-NetTCPConnection -LocalPort 5985).OwningProcess ``` 3. **服务启动失败**: ```powershell # 查看事件日志 Get-WinEvent -LogName "Microsoft-Windows-WinRM/Operational" -MaxEvents 20 ``` > **安全建议**:生产环境应启用HTTPS(端口5986)并配置证书加密传输[^1] ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值