探索基于.NET下实现一句话木马之ashx篇 0x01 前言 0x02 简介 0x03 一句话的实现 0X04 菜刀连接 0x05 防御措施 0x06 小结 0x07 参考链接

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

0x01 前言

在渗透测试的时候各种PHP版的一句话木马已经琳琅满目,而.NET平台下的一句话木马则百年不变,最常见的当属下面这句

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

笔者感觉有必要挖坑一下.NET平台里的一句话木马,经过一番摸索填坑终于可以总结出了.NET下的三驾马车,于是乎有了这个系列的文章。今天是第一篇着重介绍一般处理程序 (ASHX)下的工作原理和如何实现一句话木马的介绍,当然介绍之前笔者找到了一款ashx马儿 https://github.com/tennc/webshell/blob/master/caidao-shell/customize.ashx 

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

这个马儿已经实现了菜刀可连,可用,还是挺棒的,但因为体积过大,并且在服务端实现了大多数功能,其实更像是一个大马,只是对客户端的菜刀做了适配可用,所以不能说是一句话木马了,至于要打造一款居家旅行必备的菜刀马,还得从原理上搞清楚 ashx的运行过程。

0x02 简介

从Asp.Net 2.0开始,Asp.Net提供了称为一般处理程序的处理程序,允许我们使用比较简单的方式定义扩展名为ashx的专用处理程序。对于Asp.Net应用来说,网站最快的处理结果就是HTML网页,生成网页的工作通常使用扩展名为Aspx的Web窗体来完成。对于处理结果不是HTML的请求,都可以通过一般处理程序完成。例如生成RSS Feed、XML、图片等。 一般处理程序是Asp.Net应用中最为简单、高效的处理程序,在处理返回类型不是HTML的请求中有着重要的作用。通常是实现IHttpHandler接口,因为不必继承自Page类,所以没有那么多事件需要处理,不必消耗太多资源,所以性能方面要比Aspx高。

Http请求进入 Asp.Net Runtime以后,它的管道由托管模块(NOTE:Managed Modules)和处理程序(NOTE:Handlers)组成,并且由管道来处理这个 Http请求。

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

HttpRuntime将Http请求转交给 HttpApplication,HttpApplication代表着程序员创建的Web应用程序。HttpApplication创建针对此Http请求的 HttpContext对象,这些对象包含了关于此请求的诸多其他对象,主要是HttpRequest、HttpResponse、HttpSessionState等。这些对象在程序中可以通过Page类或者Context类进行访问,而接下来的一句话木马就是通过Context类进行请求交互的。

0x03 一句话的实现

3.1、同步处理:IHttpHandler

首先可以打开C:WINDOWSMicrosoft.NETFrameworkv4.0.30319CONFIG 目录下的web.config 文件,找到httpHandlers结点,应该可以看到如下这样的代码

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

.Net Framework在处理Http请求时的所采用的默认Handler。而如果我们要用编程的方式来操控一个Http请求,我们就需要实现IHttpHandler接口,来定制我们自己的需求。IHttpHandler的定义是这样的:

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

由上面可以看出IHttpHandler要求实现一个方法和一个属性。其中 ProcessRequest,从名字(处理请求)看就知道这里应该放置我们处理请求的主要代码。IsReusable属性,MSDN上是这样解释的:获取一个值,该值指示其他请求是否可以使用 IHttpHandler 实例。也就是说后继的Http请求是不是可以继续使用实现了该接口的类的实例。如果返回true,则HttpHandler能得到重用,或许某些场合下,是可以达到性能优化的目的。但是,它也可能会引发新的问题:HttpHandler实例的一些状态会影响后续的请求,也正是由于这个原因在默认情况下,都是不重用的。在通常情况下,当实现IsReusable时返回false,虽然性能上不是最优,但却是最安全的做法。

了解了基本原理后,笔者开始手动打造一句话小马,这个马儿要和PHP或者同胞兄弟Aspx一样,仅仅在服务端存放体积很小的一段代码,参考Aspx一句话木马的实现原理,发现是基于Jscript.Net语言中的eval方法去执行任意字符串的,所以首当其冲考虑用Jscript,并且需要实现IhttpHandler这个接口,查询资料后得到在Jscript.Net和VB.Net中均采用implements去实现,最终写出一句话木马服务端代码:

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

这里有必要简单的介绍一下Jscript.Net的语法;和大多数语言类似导入命名空间也是通过Import,以下摘自微软描述

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

script简单语法就介绍到这里,更多的语法可参考微软官方文档:https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/z688wt03(v%3dvs.100)

万事俱备,打开浏览器输入 context.Response.Write(DateTime.Now.ToString()) 成功打印出当前时间

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

3.2、异步处理:IHttpAsyncHandler

在ASP.NET程序中,适当地使用异步是可以提高服务端吞吐量的。 这里所说的适当地使用异步,一般是说:当服务器的压力不大且很多处理请求的执行过程被阻塞在各种I/O等待(以网络调用为主)操作上时, 而采用异步来减少阻塞工作线程的一种替代同步调用的方法。 反之,如果服务器的压力已经足够大,或者没有发生各种I/O等待,那么,在此情况下使用异步是没有意义的。那么在HttpHandler的接口里要想支持异步,则必须使用另一个接口:IhttpAsyncHandler

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

这个接口也很简单只有二个方法,在.net中,异步都是建立在IAsyncResult接口之上的,而BeginProcessRequest / EndProcessRequest是对这个接口最直接的使用方式。笔者通过创建一个C#的Demo来演示异步处理的过程

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

值得注意的是ProcessRequest方法和IsReusable属性可以不实现它们,但必须要保留下来,因为这个方法也是接口的一部分。核心方法是BeginProcessRequest,其中参数asyncCallback是一个内部委托,那么就需要定义一个委托,将来通过异步的方式回调自定义的方法writeFile 来写入文件。知道原理后就开始着手打造异步调用的一句话木马,和IhttpHandler一样需要通过Jscript.Net的eval方法去实现代码执行,有点遗憾之处笔者查询资料后发现Jscript.Net暂时不支持委托类型,不过只需要在BeginProcessRequest方法里增加HttpContext.Current.Response.End();就可以实现功能并且不让程序抛出异常,实现的代码如下:

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

打开浏览器,测试效果如下

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

0X04 菜刀连接

圈内常说武功再高,也怕菜刀;那么就有必要了解一下菜刀在连接ASPX的时候会发送什么数据了,经过抓包得到下图的请求

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

 对于.NET平台的应用程序默认连接后发送的可执行字符串是Response.Write,而这样的输出需要继承的对象是Page类,所以至今为止,在菜刀的层面.NET下仅支持ASPX,再来看一般处理程序中已经继承了HttpContext对象实例化后的变量context,由此可以构造出

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

修改好后用菜刀连接成功,如下图

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

基于优化考虑将HandlerSpy.ashx进一步压缩体积后只有531字节,而AsyncHandlerSpy.ashx也才719字节。

探索基于.NET下实现一句话木马之ashx篇
0x01 前言
0x02 简介
0x03 一句话的实现
0X04 菜刀连接
0x05 防御措施
0x06 小结
0x07 参考链接

0x05 防御措施

通过菜刀连接的方式,添加可以检测菜刀关键特征的规则;对于Web应用来说,尽量保证代码的安全性;

0x06 小结

 文章中不足之处在于Jscript异步处理的时候没有能够用委托的方式去调用,这是一个遗憾,如果有同学提出了更好的解决方法,欢迎多多交流;还有本文提供了两种方式实现ashx一句话的思路,当然还有更多编写一句话的技巧有待发掘,下次将介绍另外一种姿势,敬请期待;文章的代码片段请点这里

0x07 参考链接

https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/e2h4yzx6%28v%3dvs.100%29

http://www.freebuf.com/articles/web/11687.html