昨天在測某項目的時候發現前端中使用的Websocket協議(以下簡稱WS)傳參,因為剛好那天群的某*行的老哥也在測內網的一個使用Websocket協議的應用,所以特意去了解了一下,研究測試后發現存在SQL注入,當時問表哥們sqlmap是否支持該注入,答案是否定的,但表哥給出了解決方案,我們后面講。
Websocket是什么?
WebSocket是H5開始提供的一種在單個TCP連接上進行全雙工通訊的協議,它使得client與server之間的數據交換變得更加簡單,在websocketAPI 中瀏覽器和服務器只需做一個握手,兩者之間就可以進行互相傳送數據。
模擬環境搭建
因為測試目標的敏感,我將采用PHP模擬存在注入的環境並進行測試。
PHP 使用 Websocket可以用第三方的擴展來實現 如:
workerman,swoole
因為 workerman搭建起來比較簡單 且 支持 Linux和 Windows 環境所以使用 Workerman來搭建。
去workerman官網下載好內核的包: https://www.workerman.net/download
下載后 放入 PHP項目下 查看 官方的 demo 代碼
<?php use Workerman\Worker; require_once'./Workerman/Autoloader.php'; //創建一個Worker監聽2346端口,使用websocket協議通 $ws_worker= new Worker("websocket://0.0.0.0:2346"); //啟動4個進程對外提供服務 $ws_worker->count= 4; //當收到客戶端發來的數據后返回hello$data給客戶端 $ws_worker->onMessage= function($connection,$data) { //向客戶端發送hello$data $connection->send('hello'. $data); }; //運行 Worker::runAll();
因為Workerman只支持 phpcli模式下運行 且 官方文檔中提示在Windows中只能單進程運行所以 $ws_worker->count= 4;
這一行代碼可以刪除
新建一個 php 文件將 代碼填入測試
在 命令行 輸入 php -f server.php測試
這樣 說明我們的 WS服務端 就已經搭建好了
使用我下載的 Websocket客戶端工具 測試
成功交互
根據 demo 寫一個與數據庫交互的 並 存在 SQL Inject 的代碼
ws 庫 info 表結構
<?php use Workerman\Worker; require_once'./Workerman/Autoloader.php'; //數據庫連接字符串 $username="root"; $password="root"; $add= "mysql:host=localhost;dbname=ws"; $cdb= new PDO($add,$username,$password);//實例化PDO //創建一個Worker監聽6666端口,使用websocket協議通訊 $ws_worker= new Worker("websocket://0.0.0.0:6666"); $ws_worker->onMessage= function($connection,$data){ global $cdb;//設置$cdb為全局變量 $res= ''; $result=$cdb->query("SELECT email FROM info WHERE user = '$data'"); while($row=$result->fetch()){ $res= $row['email']; } $connection->send('YourSQL is: SELECT email FROM info WHERE user ='.$data); $connection->send('Recevieddata:'.$res); }; Worker::runAll(); ?>
當遇到 使用 Websocket協議傳參的應用時,可以使用ws 客戶端測試工具
根據前端代碼中傳輸的參數進行Fuzz測試,Burp也能抓取Websocket 的數據。
將代碼跑起來 然后用ws客戶端測試工具連接測試
可以看到 成功從數據庫查詢並返回數據
注入發現與利用
通過上面的代碼我們不難判斷出是有注入的
這里利用的話 我們有兩種方法:
1.手工注入
即 利用 websocket客戶端 與 服務端 進行交互的方法
在參數中 閉合插入SQL代碼 從而執行惡意的sql語句
查看當前數據庫
查看當前數據庫用戶
2.使用sqlmap
開頭說到 sqlmap不能跑 websocket協議的注入
但是表哥給出了解決方法,即中轉注入
這里我說一下原理 即通過 websocket 客戶端包裝sqlmap
注入的流量 然后通過客戶端 與 服務端交互進行注入
這里 我畫一張圖來表示
這里需要自己編寫中轉的工具,比較 麻煩 本人又是腳本小子
所以感到苦惱想到萬能的Gayhub 於是去搜索一番
發現了 rr 師傅的 WebSocket中轉注入工具
同時也支持 手工注入
在python 執行python main.py --port 服務端口
然后訪問 就可以進行手工 注入
如果是手工注入的話直接下載 Websocket 客戶端工具測試就可以了 沒必要使用該功能
python web 搭建起來對小白真的不太友好。。
后 話
對於Websocket這一塊還有太多的技術沒有完善,包括WAF對一些WS的流量並沒有檢測 導致以上安全問題沒有得到很好的解決.
希望此篇文章能給大家一些思路,同時也感謝大家肯花時間耐心的看完整篇文章,文筆較水,如果文中有什么地方說得不對還望表哥們斧正,也歡迎各位一起交流技術共同進步。
·END·