探索基于.NET下实现一句话木马之ashx篇
0x01 前言
在渗透测试的时候各种php版的一句话木马已经琳琅满目,而.net平台下的一句话木马则百年不变,最常见的当属下面这句
笔者感觉有必要挖坑一下.net平台里的一句话木马,经过一番摸索填坑终于可以总结出了.net下的三驾马车,于是乎有了这个系列的文章。今天是第一篇着重介绍一般处理程序 (ashx)下的工作原理和如何实现一句话木马的介绍,当然介绍之前笔者找到了一款ashx马儿
这个马儿已经实现了菜刀可连,可用,还是挺棒的,但因为体积过大,并且在服务端实现了大多数功能,其实更像是一个大马,只是对客户端的菜刀做了适配可用,所以不能说是一句话木马了,至于要打造一款居家旅行必备的菜刀马,还得从原理上搞清楚 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请求。
httpruntime将http请求转交给 httpapplication,httpapplication代表着程序员创建的web应用程序。httpapplication创建针对此http请求的 httpcontext对象,这些对象包含了关于此请求的诸多其他对象,主要是httprequest、httpresponse、httpsessionstate等。这些对象在程序中可以通过page类或者context类进行访问,而接下来的一句话木马就是通过context类进行请求交互的。
0x03 一句话的实现
3.1、同步处理:ihttphandler
首先可以打开c:\windows\microsoft.net\framework\v4.0.30319\config\ 目录下的web.config 文件,找到httphandlers结点,应该可以看到如下这样的代码
.net framework在处理http请求时的所采用的默认handler。而如果我们要用编程的方式来操控一个http请求,我们就需要实现ihttphandler接口,来定制我们自己的需求。ihttphandler的定义是这样的:
由上面可以看出ihttphandler要求实现一个方法和一个属性。其中 processrequest,从名字(处理请求)看就知道这里应该放置我们处理请求的主要代码。isreusable属性,msdn上是这样解释的:获取一个值,该值指示其他请求是否可以使用 ihttphandler 实例。也就是说后继的http请求是不是可以继续使用实现了该接口的类的实例。如果返回true,则httphandler能得到重用,或许某些场合下,是可以达到性能优化的目的。但是,它也可能会引发新的问题:httphandler实例的一些状态会影响后续的请求,也正是由于这个原因在默认情况下,都是不重用的。在通常情况下,当实现isreusable时返回false,虽然性能上不是最优,但却是最安全的做法。
了解了基本原理后,笔者开始手动打造一句话小马,这个马儿要和php或者同胞兄弟aspx一样,仅仅在服务端存放体积很小的一段代码,参考aspx一句话木马的实现原理,发现是基于jscript.net语言中的eval方法去执行任意字符串的,所以首当其冲考虑用jscript,并且需要实现ihttphandler这个接口,查询资料后得到在jscript.net和vb.net中均采用implements去实现,最终写出一句话木马服务端代码:
这里有必要简单的介绍一下jscript.net的语法;和大多数语言类似导入命名空间也是通过import,以下摘自微软描述
script简单语法就介绍到这里,更多的语法可参考微软官方文档:
万事俱备,打开浏览器输入 context.response.write(datetime.now.tostring()) 成功打印出当前时间
3.2、异步处理:ihttpasynchandler
在asp.net程序中,适当地使用异步是可以提高服务端吞吐量的。 这里所说的适当地使用异步,一般是说:当服务器的压力不大且很多处理请求的执行过程被阻塞在各种i/o等待(以网络调用为主)操作上时, 而采用异步来减少阻塞工作线程的一种替代同步调用的方法。 反之,如果服务器的压力已经足够大,或者没有发生各种i/o等待,那么,在此情况下使用异步是没有意义的。那么在httphandler的接口里要想支持异步,则必须使用另一个接口:ihttpasynchandler
这个接口也很简单只有二个方法,在.net中,异步都是建立在iasyncresult接口之上的,而beginprocessrequest / endprocessrequest是对这个接口最直接的使用方式。笔者通过创建一个c#的demo来演示异步处理的过程
值得注意的是processrequest方法和isreusable属性可以不实现它们,但必须要保留下来,因为这个方法也是接口的一部分。核心方法是beginprocessrequest,其中参数asynccallback是一个内部委托,那么就需要定义一个委托,将来通过异步的方式回调自定义的方法writefile 来写入文件。知道原理后就开始着手打造异步调用的一句话木马,和ihttphandler一样需要通过jscript.net的eval方法去实现代码执行,有点遗憾之处笔者查询资料后发现jscript.net暂时不支持委托类型,不过只需要在beginprocessrequest方法里增加httpcontext.current.response.end();就可以实现功能并且不让程序抛出异常,实现的代码如下:
打开浏览器,测试效果如下
0x04 菜刀连接
圈内常说武功再高,也怕菜刀;那么就有必要了解一下菜刀在连接aspx的时候会发送什么数据了,经过抓包得到下图的请求
对于.net平台的应用程序默认连接后发送的可执行字符串是response.write,而这样的输出需要继承的对象是page类,所以至今为止,在菜刀的层面.net下仅支持aspx,再来看一般处理程序中已经继承了httpcontext对象实例化后的变量context,由此可以构造出
修改好后用菜刀连接成功,如下图
基于优化考虑将handlerspy.ashx进一步压缩体积后只有531字节,而asynchandlerspy.ashx也才719字节。
0x05 防御措施
通过菜刀连接的方式,添加可以检测菜刀关键特征的规则;对于web应用来说,尽量保证代码的安全性;
0x06 小结
文章中不足之处在于jscript异步处理的时候没有能够用委托的方式去调用,这是一个遗憾,如果有同学提出了更好的解决方法,欢迎多多交流;还有本文提供了两种方式实现ashx一句话的思路,当然还有更多编写一句话的技巧有待发掘,下次将介绍另外一种姿势,敬请期待;文章的代码片段请点这里
0x07 参考链接