基于Websocket接口的SQL注入利用

  • A+
所属分类:安全文章

昨天在测某项目的时候发现前端中使用的Websocket协议(以下简称WS)传参,因为刚好那天群的某*行的老哥也在测内网的一个使用Websocket协议的应用,所以特意去了解了一下,研究测试后发现存在SQL注入,当时问表哥们sqlmap是否支持该注入,答案是否定的,但表哥给出了解决方案,我们后面讲。

Websocket是什么?

WebSocket是H5开始提供的一种在单个TCP连接上进行全双工通讯的协议,它使得client与server之间的数据交换变得更加简单,在websocketAPI 中浏览器和服务器只需做一个握手,两者之间就可以进行互相传送数据。

模拟环境搭建

因为测试目标的敏感,我将采用PHP模拟存在注入的环境并进行测试。
PHP 使用 Websocket可以用第三方的扩展来实现 如:workerman,swoole
因为 workerman搭建起来比较简单 且 支持 Linux和 Windows 环境所以使用 Workerman来搭建。
去workerman官网下载好内核的包

image.png
下载后 放入 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 文件将 代码填入测试

image.png
在 命令行 输入 php -f server.php测试

image.png
这样 说明我们的 WS服务端 就已经搭建好了

使用我下载的 Websocket客户端工具 测试

image.png
成功交互

根据 demo 写一个与数据库交互的 并 存在 SQL Inject 的代码

ws库 info 表结构

image.png

<?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客户端测试工具连接测试

image.png
可以看到 成功从数据库查询并返回数据

注入发现与利用
通过上面的代码我们不难判断出是有注入的

这里利用的话 我们有两种方法:

1.手工注入

即利用websocket客户端与服务端进行交互的方法,在参数中闭合插入SQL代码从而执行恶意的sql语句

查看当前数据库

image.png
查看当前数据库用户

image.png
2.使用sqlmap
开头说到 sqlmap不能跑 websocket协议的注入,但是表哥给出了解决方法,即中转注入
这里我说一下原理即通过 websocket客户端包装sqlmap注入的流量然后通过客户端与服务端交互进行注入。
这里我画一张图来表示

image.png
这里需要自己编写中转的工具,比较麻烦本人又是脚本小子所以感到苦恼想到万能的Gayhub于是去搜索一番,发现了 rr 师傅的 WebSocket中转注入工具

image.png
同时也支持 手工注入
在python 执行python main.py --port 服务端口
然后访问就可以进行手工注入
如果是手工注入的话直接下载Websocket客户端工具测试就可以了没必要使用该功能(python web 搭建起来对小白真的不太友好。)

后话
对于Websocket这一块还有太多的技术没有完善,包括WAF对一些WS的流量并没有检测 导致以上安全问题没有得到很好的解决.
希望此篇文章能给大家一些思路,同时也感谢大家肯花时间耐心的看完整篇文章,文笔较水,如果文中有什么地方说得不对还望表哥们斧正,也欢迎各位一起交流技术共同进步。
Tips:Burp最新版本已经支持对websocket协议的数据包进行抓取,感谢key师傅的提醒