0x01 前言
本文是探索.NET三驾马车实现一句话木马的完结篇,如果前两篇没有看的同学可以浏览FreeBuf 地址(ashx一句话 、 asmx一句话),至于这三篇文章包含的代码片段已经同步到笔者的 github上,如果有需求请自取。 那么闲话少叙,回归正题。SVC是 .NET WCF程序的扩展名至于有什么作用那还得先谈谈WCF。
0x02 简介和原理
WCF (WindowsCommunication Foundation) 是微软为构建面向服务的应用程序所提供的统一编程模型,能够解决不同应用程序域,不同平台之间的通信问题。WCF统一了多重分布式技术:Webservice、.NetRemoting、.Net企业服务、微软的消息队列(MSMQ),在WCF的结构中有下面几个概念:
1. 契约(ServiceContract): 契约是属于一个服务公开的公共接口,定义了服务端公开的服务方法、使用的传输协议、可访问的地址以及传输的消息格式等等,简单的说契约的作用就是告诉我们能干什么;
2. 地址(Address): 在WCF框架中,每个服务都具有唯一的地址,其他服务或者客户端通过这个地址来访问到这个服务;
3. 绑定(Binding): 定义了服务与外部通信的方式。它由一组称为绑定元素的元素而构成,这些元素组合在一起形成通信基础结构;
4. 终结点(EndPoint): 终结点是用来发送或接收消息的,一个终结点由三个要素组成,分别是:地址、绑定和契约;
对于.Net而言,WebService请求处理器则是一个 .NET Framework 自带的 ISAPI Extension。Web请求处理器用于解析收到的SOAP请求,调用 WebService,然后生成相应的SOAP应答。Web服务器得到SOAP应答后,在通过HTTP应答的方式将其返回给客户端,但WebService也支持HTTP POST请求,仅需要在服务端增加一项配置即可。
对于本文来说只需要掌握契约的使用即可,下面通过一个简单的demo来演示
上面的代码中[ServiceContract]是接口Iservice1声明的特性,表示这个是一个契约;[OperationContract]在接口方法DoWork上声明表示该方法是一个对外的服务,远程客户端能够调用到这个方法;定义TestService类去实现接口,并且实现接口里的DoWork方法,方法体内返回当前的日期时间;简要的说明后通过Visual Studio调试如下:
点击WCF测试客户端右侧 “ 调用“ 成功返回了当前的时间结果,这就是一个简单的WCF程序的定义和调用。
0x03 SVC小马的实现
通常用IDE生成的WCF文件由三部分组成,如果要实现WCF的小马,需要将三部分整合到一个文件中,扩展名是svc。新建WCF的时候三个文件默认名分别为Service1.svc 、Service1.svc.cs 、IService.cs ,整合代码分两步走,第一步先将接口文件IService.cs里的代码块放入Service.svc.cs文件中;第二步将Service1.svc.cs文件和Service1.svc合并; 最终三块代码整合一起,再加上实现了创建aspx马儿和CMD执行命令的功能,俨然诞生了一个WCF的小马,代码如下:
输入ver命令,返回执行结果。
把文件部署到IIS7下然后访问 http://IP/service2.svc?singleWsdl
看到这段wsdl中包含了定义的cmdShell方法,还有对应返回的webShellResponse这个xml元素节点,将来命令执行的结果全部位于webShellResult节点之间,若想可视化的 操作还需要借助SoapUI这款工具来实现调用,工具下载地址网上有很多,笔者下载的是5.2.1版本,安装新建项目后选择添加 ”Add WSDL“
点击OK后可见左侧多出了代码里定义的两个方法,点击节点下的Request 按钮就可以发送请求测试了。
到此虽然小马已经实现,但不是笔者的目标,笔者期望的还是随便传入一句话就可以到达任意执行的目的,所以还得继续往下转化。
0X04 菜刀连接
根据C#版本的小马加上之前两篇文章中利用Jscript.Net的语法就可以很容易写出一句话小马服务端,查看C#中 ServiceContract元数据可以看出本质上就是ServiceContractAttribute,OperationContract对应的是OperationContractAttribute。如下图
在Jscript.Net中实现这两个功能的分类是WebMethodAttribute类和ScriptMethodAttribute类,最终写出一句话木马服务端代码:
打开SoapUI 输入 DateTime.Now.ToString() ,成功打印出当前时间。
其实请求的数据是一条SOAP消息,也是一个普通的XML文档,但必须要包含Envelope 命名空间、不能包含DTD引用和XML处理指令;
Envelope元素是SOAP消息的根元素,它的存在就可认为这个XML是一个SOAP消息、Body元素包含准备传送到消息最终端点的数据,上面的tem:exec和tem:text元素是应用程序专用的元素,并不是标准SOAP的一部分,发送HTTP请求的时候只需修改tem:Ivan就可以实现任意代码执行,至此SVC版本的一句话小马也已经实现。这里还需要注意一点,web.config里必须要配置。
其中最关键的当属 httpGetEnabled= true ,如果不配置这个选项浏览的时候会看到如下的提示
好在遇到上述配置的概率不大,因开发环境下Visual Studio会自动添加这个选项到配置文件中去,开发人员在部署的时候基于习惯会拷贝到生成环境下,所以大概率支持HTTP请求。可惜的是菜刀暂时不支持SOAP消息返回的数据格式,笔者考虑的解决方案重写客户端来支持SOAP消息返回;还有就是基于优化考虑将svcLessSpy.svc进一步压缩体积后只有339个字节。
0x05 防御措施
1. 对于Web应用来说,尽量保证代码的安全性;
2. 对于IDS规则层面来说,上传的时候可以加入OperationContractAttribute、ServiceContractAttribute、eval等关键词的检测
0x06 小结
1. Svc大有替代asmx的趋势,也是微软未来主推的服务,相信会有越来越多的.NET应用程序支持WCF,svc一句话木马被攻击者恶意利用的概率也会越来越多;
2. 目前中国菜刀还不支持svc扩展,需要改进或者有条件的可以开发一款属于svc和asmx一句话木马专属定制的工具;
3. 文章的代码片段请参考 https://github.com/Ivan1ee ;
0x07 参考链接
https://docs.microsoft.com/en-us/dotnet/framework/wcf/getting-started-tutorial
https://www.cnblogs.com/oec2003/archive/2010/07/21/1782324.html
*本文作者:360云影实验室,转载请注明来自FreeBuf.COM