当前位置: 首页 > ai >正文

使用 AFL++ 对 IoT 二进制文件进行模糊测试 - 第二部分

在上一部分中,我们研究了如何使用 AFL++ 对简单的物联网二进制文件进行模糊测试。这些程序接受来自文件的输入,并且易于模糊测试。

在本文中,我们将研究套接字二进制文件。使用套接字进行网络通信的模糊测试二进制文件与使用基于文件 I/O 的模糊测试二进制文件不同。Vanilla AFL 和 AFL++ 不支持对套接字二进制文件进行模糊测试,尽管AFLNet和AFLNW等项目使用 AFL 的修改版本进行模糊测试。不过,本文我们将了解如何使用普通的 AFL++ 来模糊测试网络程序。httpd此处的二进制文件/usr/sbin/httpd是固件的 Web 服务器,可以作为模糊测试的候选对象。

httpd我们可以像下面这样启动sudo。需要使用 Sudo 才能绑定到 80 端口。

img

请注意,qemu 是从www/目录内部启动的,因为这是 Web 资源(html、css、js 文件)所在的位置。虽然它显示了绑定错误,但运行后netstat可以确认它httpd确实在监听 80 端口。

img

我们可以打开http://127.0.0.1来交叉检查Web界面是否可以访问。

img

还可以使用 访问 Web 界面curl

img

使用拦截代理(例如 Burp Suite),我们可以查看正在发送的实际 HTTP 请求。尝试使用凭据登录仪表板admin:123456将导致 POST 请求,如下所示。

img

在上图中,我们通过附加*-p 8080*到 qemu 命令行在端口 8080(而不是 80)上运行 Web 服务器。

从这里开始,我们的想法是使用模糊器以微妙的方式修改这个基本请求,从而使 Web 服务器崩溃。

最简单的方法是通过网络发送实际请求。然而,这会很慢。更聪明且推荐的方法是让 Web 服务器从文件中读取 HTTP 请求数据。我们将分别讨论这两种方法。

使用 Radamsa 进行简单模糊测试

Radamsa不是模糊测试器。它是一个测试用例生成器,可以读取文件并以微妙的方式对其进行修改。如何使用修改后的输出取决于我们。在这里,我们将文件的输出发送到正在运行的 Web 服务器。

# fuzz-radamsa.py
import socket
import pyradamsabase_login_request = open("base-login-request.txt", "rb").read()rad = pyradamsa.Radamsa()
i = j = 0while True:# Create a modified request based on the base requestfuzzed_request = rad.fuzz(base_login_request)sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 1 second timeoutsock.settimeout(1)sock.connect(("127.0.0.1", 8080))j += 1print(f"[+] Request {j} - ", end="")sock.sendall(fuzzed_request)try:sock.recv(50000)print("OK")except Exception as ex:i += 1open(f"interesting/{i}.txt", "wb").write(fuzzed_request)print(f" {ex} -> saved to {i}.txt")sock.close()

上述代码使用 Radamsa 根据基础登录请求生成修改后的请求数据。然后,这些数据通过套接字发送到运行在 8080 端口的 Web 服务器。如果服务器在 1 秒内没有响应,则输入将保存到目标目录中的文件中。

我们可以按照所示运行模糊测试器。

img

请求 3 在响应时超时,相应的输入被保存到1.txt 文件中。需要注意的是,超时并不等同于崩溃。如果服务器在请求 3 时崩溃,后续请求将无法成功。这种模糊测试效率极低、速度慢且容易出错,并且经常会导致误报。

使用 AFL++ 进行模糊测试

如前所述,要使用 AFL 进行模糊测试,程序必须接受来自文件的输入。我们没有httpd的源代码,无法根据我们的目的进行修改。因此,我们只能采取二进制级别的修改,例如修补汇编指令和LD_PRELOAD技巧。使用后者,我们可以覆盖网络函数,libc使其接受来自文件的输入。GitHub上的desockmulti项目可以用于此目的。

在演示如何使用*desockmulti 之前,*我们需要进行一些修改。httpd二进制文件目前使用该函数 fork 到后台daemon。我们不希望在模糊测试过程中出现这种 fork 行为。

img

我们需要重写daemon它,使其返回 0,而不是真正地进行分叉。这可以通过使用 LD_PRELOAD 或修改汇编指令来实现。

我们需要做的另一个修改是让httpd只处理一个请求(不像典型的 Web 服务器那样无限期地处理请求),然后退出。这样我们就能知道是哪个请求(如果有的话)导致了 Web 服务器崩溃。

要关闭套接字

http://www.xdnf.cn/news/2072.html

相关文章:

  • 基于 Requests 与 Ollama 的本地大模型交互全栈实践指南
  • Trae 宝藏功能实测:从 Mcp 搭建天气系统,到 AI 重塑 Excel 数据处理
  • 精通线程池:业务场景中的实践、优化与监控
  • maven打包时配置多环境参数
  • 深入理解二叉树遍历:递归与栈的双重视角
  • php一些命名规范 和 css命名规范
  • 支付宝小程序组件与页面构造器使用指南:从页面到组件的正确迁移
  • 【Agent实战】从0到1开发一个Python 解释器 MCP SSE Server
  • RocketMQ 主题与队列的协同作用解析(既然队列存储在不同的集群中,那要主题有什么用呢?)---管理命令、配置安装(主题、消息、队列与 Broker 的关系解析)
  • 7年经验的Java程序员的技术知识概览(及分阶段学习计划、资源推荐、职业发展建议)
  • 基于Java(JSP)+MySQL实现深度学习的音乐推荐系统
  • Queue和Deque
  • #ifndef #else #endif条件编译
  • C语言基础语法详解:从入门到掌握
  • 【FreeRTOS】事件标志组
  • Linux文件操作命令
  • QPS说明
  • 提升变电站运维效率:安科瑞无线测温系统创新应用
  • oracle数据库物理结构
  • Python异常处理实战指南:从基础语法到设计哲学
  • windows一键测速DNS并切换
  • MQTT学习资源
  • 极域教师管理CMD命令操作
  • kaggle配置
  • WebUI可视化:第7章:系统优化与部署实战
  • 新手如何学习人工智能
  • C语言实现对哈希表的操作:创建哈希表与扩容哈希表
  • Vue3 生命周期与Hooks
  • C语言----函数栈帧讲解
  • Flink 系列之七 - Data Stream API的源算子原理