0x01 前言 在滲透測試的時候各種PHP版的一句話木馬已經琳琅滿目,而.NET平臺下的一句話木馬則百年不變,最常見的當屬下麵這句 筆者感覺有必要挖坑一下.NET平臺里的一句話木馬,經過一番摸索填坑終於可以總結出了.NET下的三駕馬車,於是乎有了這個系列的文章。今天是第一篇著重介紹一般處理程式 (A ...
0x01 前言
在滲透測試的時候各種PHP版的一句話木馬已經琳琅滿目,而.NET平臺下的一句話木馬則百年不變,最常見的當屬下麵這句
筆者感覺有必要挖坑一下.NET平臺里的一句話木馬,經過一番摸索填坑終於可以總結出了.NET下的三駕馬車,於是乎有了這個系列的文章。今天是第一篇著重介紹一般處理程式 (ASHX)下的工作原理和如何實現一句話木馬的介紹,當然介紹之前筆者找到了一款ashx馬兒 https://github.com/tennc/webshell/blob/master/caidao-shell/customize.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簡單語法就介紹到這裡,更多的語法可參考微軟官方文檔:https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/z688wt03(v%3dvs.100)
萬事俱備,打開瀏覽器輸入 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 參考鏈接
http://www.freebuf.com/articles/web/11687.html