探索sqlmap在WebSocket安全测试中的应用

WebSocket与HTTP的区别

WebSocket,对于初次接触的人来说,往往会引发一个疑问:既然我们已经有了广泛使用的HTTP协议,为何还需要引入另一种协议?WebSocket又能为我们带来哪些实质性的好处呢?

这背后的答案在于HTTP协议的一个关键限制——通信的发起权始终掌握在客户端手中。简单来说,如果你想知道今天的天气,你(客户端)需要主动向天气服务(服务器)发送请求,而后服务器才会返回你所需的信息。但HTTP协议并不支持服务器主动推送信息给客户端,这在某些应用场景下显得尤为不便。

想象一下,如果你正在参与一个活跃的聊天室,想要实时获取其他用户的消息,使用HTTP协议意味着你需要不断地发起请求来“轮询”服务器,看是否有新的消息产生。这种方式不仅效率低下,还极大地浪费了资源,因为客户端需要不断建立和维护与服务器的连接。

为了解决这个问题,WebSocket协议应运而生。它的出现彻底打破了HTTP协议的局限,实现了真正的双向通信——服务器可以主动推送信息给客户端,而客户端也能随时向服务器发送数据。这种双向、平等、实时的通信模式,使得WebSocket成为了一种高效的服务器推送技术,广泛应用于实时聊天、股票交易、在线游戏等多种场景。

SQLmap简介

SQLMap是一个功能强大的自动化SQL注入工具,主要用于扫描、发现并利用给定的URL中的SQL注入漏洞。

SQLMap主要设计用于测试HTTP(S)协议下的Web应用程序的SQL注入漏洞。它基于HTTP请求和响应来检测和分析SQL注入的可能性。这意味着,SQLMap并不直接支持非HTTP协议的数据库访问或测试,如通过TCP/IP直接连接数据库服务器。

WebSocket转HTTP进行SQLmap扫描

由于SQLMap仅支持HTTP(S)协议,直接用它来扫描WebSocket接口是不可行的。为了克服这一限制,我们可以设计一个中间代理解决方案。具体来说,可以开发一个自定义脚本作为中间层,负责将SQLMap生成的HTTP请求转换为WebSocket消息,并将这些消息发送到WebSocket服务器。同样,这个脚本还需要捕获来自WebSocket服务器的响应,将其转换为HTTP响应格式,然后返回给SQLMap。

需要安装 websocket-client

pip install websocket-client

工具脚本如下:

from datetime import datetime
# 导入创建WebSocket连接的库
from websocket import create_connection
# 导入HTTP服务器的基础类和HTTPServer类
from http.server import BaseHTTPRequestHandler, HTTPServer
# 导入用于多线程HTTP服务器的类
from socketserver import ThreadingMixIn
from urllib.parse import unquote
import json
from urllib.parse import urlparse, parse_qs # 定义一个函数,用于发送消息到WebSocket服务器并接收响应
def send_msg(url, date):
# 创建一个WebSocket连接
ws = create_connection(url, header=extra_headers)
# 接收WebSocket服务器的初始响应
resp = ws.recv()
print(f'====================={datetime.now().strftime("%H:%M:%S")}=====================')
print(resp)
# 构造要发送的JSON字符串
d = date
# 打印要发送的JSON字符串
print('JSON + + + + + + + + + +')
print(d)
# 发送JSON字符串到WebSocket服务器
ws.send(d)
# 接收WebSocket服务器的响应
resp = ws.recv()
print('RESP + + + + + + + + + +')
print(resp)
print('==================================================')
return resp # 定义一个HTTP请求处理器类
class Handler(BaseHTTPRequestHandler): # 处理GET请求的方法
def do_GET(self):
# 设置HTTP响应状态码为200(成功)
self.send_response(200)
# 过滤掉其他请求影响
if str(self.path[:3]) == '/ws':
url_ws = f'http://{hostname}:{str(serverport)}/ws?' + unquote(self.path[4:])
dist_params = parses(url_ws)
dates = data_dict
key = type_conversion(dist_params, dates)
update_nested_dict(dates, key)
par_date = str(dates).replace("'", '"')
# 设置响应的内容类型为文本
self.send_header('Content-Type', 'text')
# 结束HTTP头部信息的发送
self.end_headers()
# 调用send_msg函数发送参数并接收响应,然后将响应写入HTTP响应体
resp = send_msg(ws_url, par_date)
self.wfile.write(bytes(resp, "utf-8")) # 定义一个继承自HTTPServer并支持多线程的服务器类
class ThreadingSimpleServer(ThreadingMixIn, HTTPServer):
pass # 定义一个函数,用于启动HTTP服务器
def run():
# 创建一个服务器实例,监听所有IP地址的9000端口,并使用Handler类处理请求
server = ThreadingSimpleServer((hostname, serverport), Handler) try:
# 让服务器一直运行,直到接收到键盘中断信号
server.serve_forever()
except KeyboardInterrupt:
pass # 递归函数来提取所有的key
def extract_keys(d, parent_key='', keys=None):
if keys is None:
keys = []
if isinstance(d, dict):
for k, v in d.items():
new_key = k if not parent_key else f"{parent_key}.{k}"
if isinstance(v, dict):
extract_keys(v, new_key, keys)
else:
keys.append(new_key)
return keys # 获取所有values
def extract_values(d, values=None):
if values is None:
values = []
if isinstance(d, dict):
for k, v in d.items():
if isinstance(v, dict):
# 如果是嵌套字典或列表,则递归调用
if isinstance(v, dict):
values.extend(extract_values(v))
elif isinstance(v, list):
for item in v:
if isinstance(item, (dict, list)):
# 如果是嵌套在列表中的字典或列表,继续递归
values.extend(extract_values(item))
else:
# 如果列表中的项不是字典或列表,则直接添加
values.append(item)
else:
# 如果值不是字典或列表,则直接添加
values.append(v)
return values def parses(ws_url):
# 使用urlparse解析URL
parsed_url = urlparse(ws_url) # 获取查询字符串
query_string = parsed_url.query # 使用parse_qs解析查询字符串为字典(注意:如果有多个相同key的参数,值会是列表)
params = parse_qs(query_string)
return params # 类型转换
def type_conversion(dist_p, ys_date):
for key in dist_p:
path = key.split('.')
val = ys_date
for i in path:
val = val[i]
try:
if isinstance(val, str):
dist_p[key] = str(dist_p[key][0])
elif isinstance(val, int):
dist_p[key] = int(dist_p[key][0])
elif isinstance(val, float):
dist_p[key] = float(dist_p[key][0])
elif isinstance(val, list):
dist_p[key] = list(dist_p[key][0][1:-1])
except:
dist_p[key] = str(dist_p[key][0])
return dist_p def update_nested_dict(d, u):
for key, value in u.items():
if '.' in key:
# 分解嵌套路径
keys = key.split('.')
sub_dict = d
for k in keys[:-1]:
sub_dict = sub_dict.setdefault(k, {})
# 更新最后一个键的值
sub_dict[keys[-1]] = value
else:
# 直接更新非嵌套键
d[key] = value if __name__ == '__main__':
# http服务ip+端口
hostname = "localhost"
serverport = 9909 # WebSocket接口url
ws_url = input('Url: ')
# 发送内容(数据类型为字符串的字典)
send_text = input('\nDate: ')
# WebSocket请求头
extra_headers = {
'Sec-Websocket-Protocol': input('\nSec-Websocket-Protocol: ')
}
# json格式化请求数据
data_dict = json.loads(send_text)
# 获取所有的请求数据中所有的key和value
all_keys = extract_keys(data_dict)
all_values = extract_values(data_dict)
# 根据key和value拼接初始url
url = f'{hostname}:{str(serverport)}/ws?'
for i in range(len(all_keys)):
url = url + str(all_keys[i]) + '=' + str(all_values[i]) + '&'
if i+1 == len(all_keys):
url = url[:-1]
# 输出所访问的url
print("\n" + url) run()

当您运行此程序后,您将被要求输入WebSocket接口的URL、要传输的数据以及Sec-WebSocket-Protocol头部信息(您可以根据项目需求自行调整相关代码,位于168行到175行之间的部分)。随后,程序将返回与WebSocket连接建立过程中使用的HTTP协议的初始URL。

这个URL的生成是基于传输数据的JSON格式进行解析而得到的。当您变更URL中的参数值时,与该参数相对应的JSON数据中的值也会相应地进行调整,并随后被发送到WebSocket接口。所以具备了sqlmap扫描参数的条件,可以通过sqlmap -u "localhost:9909/ws?key1=value1&key2=&value2"命令来进行sqlmap扫描。

当您通过浏览器访问指定的WebSocket接口时,您不仅能够成功地接收到返回的数据,而且在浏览器的控制台中还能清晰地看到发送的请求数据以及相应的响应结果。这一流程确保了数据传输的透明性和可追踪性,为您提供了更加直观和便捷的调试与监控体验。

SQLmap扫描

使用以下命令进行扫描

python sqlmap.py -u "ulr"

扫描中

探索sqlmap在WebSocket安全测试中的应用的更多相关文章

  1. Web测试中常见分享问题

         Web测试中,由于开发通常指注重完成H5页面的逻辑功能,对各种系统.浏览器等考虑不周,同时Android端各类机型碎片化,容易产生兼容性问题,这其中以分享类型为最. 本文简单分析总结一些测试 ...

  2. WEB 业务测试中需要关注的问题

    汇总起来分为:    1.浏览器自身的一些操作,后退键,刷新键,样式兼容,多浏览器之间的一些操作 2.键盘快捷键的一些支持 3.所有前端校验,必须也在后端代码进行校验,验证后端是否校验可越过前端校验进 ...

  3. 反向代理在Web渗透测试中的运用

    在一次Web渗透测试中,目标是M国的一个Win+Apache+PHP+MYSQL的网站,独立服务器,对外仅开80端口,网站前端的业务系统比较简单,经过几天的测试也没有找到漏洞,甚至连XSS都没有发现, ...

  4. Jmeter—7 测试中使用到的定时器和逻辑控制器

    1 测试中提交数据有延时1min,所以查询数据是否提交成功要设置定时器. 固定定时器页面:单位是毫秒 [dinghanhua] 2 集合点.Synchronizing Timer 集合点编辑:集合用户 ...

  5. TV测试中的按键长按操作模拟

    从UiAutomator在TV测试中的局限性说起: 智能TV的操作和手机的操作有很大不同,一般智能TV的操作为遥控器按键操作,来向TV OS发送  KeyCode,以完成指定操作. UiAutomat ...

  6. [转]移动App测试中的最佳做法

    Daniel Knott 用过各种不同编程语言和软件质量保证工具.他在软件开发和测试方面干了七年,自2010年起,他一直在德国汉堡的XING AG公司就职,几个项目里,比如XING调查和XING建议, ...

  7. 算法效果AB测试中的PV-UV不对称性

    (转载请注明原创于潘多拉盒子) 算法效果的AB测试,是指在相同的应用场景下,对比不同算法的效果.通常的做法是,按照PV或UV随机分配流量到算法上,计算算法的CTR或转化率进行对比.为了表述简单,我们假 ...

  8. Junit 4 测试中使用定时任务操作

    难度:测试中执行线程操作 package com.hfepc.job.dataCollection.test; import java.util.Date; import java.util.List ...

  9. app测试中遇到问题总结

    工作总结: 1 这两天由于工作,需要进行抓包,使用了Charles,fidder,发现一个坑点: charles没有抓到返回值的时候,默认是不在列表显示请求信息的,能不能设置,我就不知道了,但是可以在 ...

  10. 移动App测试中的最佳做法

    一说起软件测试,测试员想到肯定是去检查文件,功能,API,性能并确定软件是否安全,以及关于软件特定部分的其他事项.但是对于移动测试,测试员不得不基于用户移动使用模式考虑移动相关的功能. 本文是基于我的 ...

随机推荐

  1. Python 爬虫必备杀器,xpath 解析 HTML

    最近工作上写了个爬虫,要爬取国家标准网上的一些信息,这自然离不了 Python,而在解析 HTML 方面,xpath 则可当仁不让的成为兵器谱第一. 你可能之前听说或用过其它的解析方式,像 Beaut ...

  2. Python 学习记录 (4)

    Plotly常见可视化方案:以鸢尾花数据为例 简单介绍: Ploty库也有大量统计可视化方案,并且这些可视化方案具有交互化属性. 主要对鸢尾花数据进行处理与可视化. 所展示的结果为交互界面的截图情况, ...

  3. 在不同形式的for循环中使用break、continue、return的效果

    我们在循环中,经常会有跳出循环,跳出本次循环继续下次循环等的场景,今天我们简单分享下.主要使用到的关键字是,break.continue.return.先将结果总结: ①在foreach中不能使用br ...

  4. MySql 9 in Docker 主从切换

    继上一篇<MySql 9 in Docker 利用克隆插件搭建主从>我们说了主从复制后, 那么我们接下来说说如何手动的进行主从切换. 动手~ 1. 原主库设置 切断应用对主库的访问 主库设 ...

  5. redmine部署,踩坑而过

    背景:部门想用个工具来做项目执行进度的管理,为了保证数据私有并且不想花钱,选了redmine. 环境:阿里云服务器,windows server R2企业版 软件版本构成: 官方版本说明http:// ...

  6. 调用import71

    在调用import71,将E00转换成coverage的时候,需要注意两点: 1.e00文件路径,需要包含.e00后缀: 2.输入路径的文件夹必须不存在,在转换的时候,工具会进行新建. 参考 http ...

  7. 【位运算】codeforces 1775 C. Interesting Sequence

    题意 输入一个正整数 \(T(1 \leq T \leq 2000)\),代表 \(T\) 组测试用例.对于每个测试用例: 输入两个整数 \(n, m(0 \leq n, m \leq 10^{18} ...

  8. Docker目录汇总

    Docker目录汇总 Docker资料分享 Docker 教程 | 菜鸟教程 Docker入门级简易手册 Docker - 从入门到实践 Kubernetes中文手册 Kubernetes 指南 我的 ...

  9. 2024年1月Java项目开发指南8:统一数据返回格式

    有时候返回一个字符串,有时候返回一串数字代码,有时候返回一个对象-- 不过怎么说,我们返回的内容往往具有三个 1.消息代码 code 2.消息内容 msg 3.数据内容 data 接下来,我们要编写一 ...

  10. 【Rive】波动文字

    1 前言 ​ 本文将使用文本修改器(Text Modifiers)做文字动画,实现文字波动效果. ​ 按以下步骤可以创建一个 Modifier Group 和 Range. ​ 部分参数的释义如下. ...