當前位置:
首頁 > 最新 > 用世界上最好的語言開發自動化注入工具

用世界上最好的語言開發自動化注入工具

大家好,我是小編

今天帶來一篇關於注入工具開發的文章

來自Gcow團隊的特特

我預感

這是一篇會引來腥風血雨的文章

大家評論區見

前言

「我就說php是世界上最好的語言,不服來投稿打我臉」

本文使用世界上最好的語言(PHP)針對某h站系統而開發的自動化注入工具。

首先來明確工具開發中的幾點:

正常頁面和錯誤頁面的區別

該工具自動化判斷表名以及表中欄位的數據長度

使用緩存機制(讀取和寫入)

使用php cli(命令行)模式

開始分析

可能有人會問了「為何不用python,而用php?」

因為這個注入點比較特殊,是一個302頁面跳轉處的注入,從資料庫中查詢到某個域名後會輸出到頁面後跳轉,否則因查詢不到某個域名造成死循環。

輸出頁面的代碼如下:

go.click();

Href參數有值的情況下為正常,否則異常

document.write("");

go.click();

異常之後就會存在死循環,因為href都為空

之所以使用php是因為這裡是302頁面,python獲取不到頁面內容,而php則可以獲取到內容。

對於工具開發,必不可少的是http請求函數,php現成的有file_get_contents相對來說並不好用,如果請求不到,使用就會產生異常,為此將要用的curl封裝了一個函數:

先來測試一下,主要還是測試是否能獲取到302頁面的內容,代碼如下:

獲取到的內容如下:

使用「------------」分界線,將正確頁面和錯誤頁面分割開來。

href參數中有值的是正常頁面,否則為異常頁面。

我們接下來試著採用接收命令行參數的方式具體實現吧!

具體實現

Php cli模式接收命令行參數的超全局數組為$argv:

首先我們要想到如何實現-u這些內容,所以將獲取的東西封裝並且命名為GetHostId,這個函數中不需要參數,需要獲取全局變數可以使用兩種形式:$GLOBALS和global $argv。

這裡我們還是使用$GLOBALS的方式獲取,因為最後會將這些函數封裝在一個類裡面,能夠更加靈活。

根據上圖可知,數組下標為0的數值是無用的,需要刪掉$GLOBALS[「argv」][0]:

這裡第一行就將下標為0的值刪掉了,因為第1個就是執行的文件名,所以直接刪掉,然後進行賦值。

接下來,命令行中需要兩個參數:一個是--host或-h,另一個為--id,函數已封裝完畢:

這裡我們當前文件接收命令行參數就有了兩種形式:

程序這樣做顯得不靈活了,為了解決這裡位置不能隨意調換的問題可以再封裝一個函數:

這樣獲取命令行參數就可以不分先後順序了!

這裡已經獲取到了域名以及id,接下來還需要另一個參數--batch:

如果參數存在則默認使用http;

如果參數不存在則在命令行中獲取,已將獲取這部分封裝成了函數;

GetInput函數是獲取命令行中的值,而GetHttp是調用GetInput獲取用戶輸入的是http或是http協議:

這裡獲取到http或者https協議拼接到host後,將拼接的值進行存活的判斷。

封裝一個is_survival函數:

存活返回true;

否則false;

判斷存活本應判斷狀態碼,但判斷狀態碼並不嚴格,這裡使用正則表達式來進行匹配,返回值如下:

正則所匹配的東西應該是href中的值,正則表達式如下:/href=」(.+)」/i

以上就是判斷存活的必要條件,接著繼續:

這裡存活條件為href中有值否則是死亡狀態。

死亡狀態有兩種情況:

一種是無法訪問;

另一種是輸入的id值不正確

繼續往下:

查詢不到內容的情況:

函數中同時會自動測試五次,五次過後依就獲取不到便自動退出。

驗證測試

這裡我們驗證其是否存活,從字典中獲取表名,然後測試取出的表是否存在。

在本地創建一個dictionary目錄,並且寫入一個名為tables.txt的字典文件:

接下來在此封裝兩個函數,一是GetContents,另一個是GetTables:

這裡我們通過GetTables函數中調用GetContents函數獲取字典內容,然後返回到GetTables函數中,將內容以回車分割為數組並且返回數組。

接下來我們還要再接著封裝一個名為TablesSurvival的函數,然後返回值為數組,這裡我們將查表的SQL :+and+exists(select%20*%20from%20admin)拼接上去

成功測試表名存在後:

再封裝一個名為GetColumns的函數;

此函數獲取dictionary目錄下的columns.txt文件中的內容,並以回車分割具體實現

具體實現:

這裡欄位名的格式和表名的格式略有不同,格式如下:

到這裡為止,我們的程序已經可以自動化測試表名以及欄位名,現在可以試著將前面相同功能的函數進行合併:

比如GetColumns和GetTables,這兩個函數合併後名稱為GetTablesOrColumns。

TablesSurvival和ColumnsSurvival合併為TablesOrColumnsSurvival。

試著運行:

證實代碼精簡後,還是一樣的運行結果。

此時已知表名以及欄位名稱,既是自動化工具,自然少不了測試欄位中內容的長度。

將獲取字元長度的代碼封裝,名為GetStringLength,返回值為數組:

可以看到我們返回的格式為:[表名,欄位長度=>欄位名,欄位長度=>欄位名]。

已經得知表名、欄位名以及欄位內容長度,接著定義一個名為SqlInjection,就不需要返回值了:

到這裡基礎已經完成了。

緩存機制

雖然基礎已經完成了,但還需要一個緩存機制。

我們將獲取到的內容寫入到文件夾下,我們的緩存目錄結構如下:Data目錄->域名目錄->表名目錄->欄位文本

現在封裝一個名為TextPut函數:

隨後在GetStringLength中調用textput函數,將欄位中的字元長度及欄位名寫入到以域名的名稱命名的文本中:

寫入文本格式如下:

然後在SqlInjection函數中調用並將注入到的數據寫入文件中:

成功將獲取到的數據寫入到文件中,但還要進行一次判斷,封裝一個名為is_cache函數:

並且將SqlInjection函數增加一個cache形參,方便緩存機制。

最終程序調用如上,還應該寫一個名為DumpContent的函數,將注入到的數據列印出來。

程序調用最終如下:

測試一下緩存機制:

username欄位測試到第四個字元,退出程序:

程序果斷退出了,接著再來運行一次:

還在獲取第四個字元是因為我們設置的是:「只有讀取到了寫入文件之後才會跳到第五個字元」

然而這裡還沒讀取到第四個字元,所以程序還是從第四個字元開始後靜靜的等待執行完畢。

本次分享就到這裡了,感謝大家的閱讀!

其實工具開發旨在思路,無論用什麼語言只要可以實現便是達到目的。

自動化測試工具地址:https://github.com/only-wait/tools/tree/master/h%E7%AB%99%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 漏洞銀行 的精彩文章:

Diffie-Hellman密鑰交換演算法在移動安全防護實踐

TAG:漏洞銀行 |