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

CVE-2020-7248 OpenWRT libubox标记二进制数据序列化漏洞(更新中)

提要

        该文档会一直处于更新当中,当状态为完毕后,才是更新完成。由于网络上关于该漏洞原理的分析文档和资源实在是太少,而本人关于该方向也才是刚入门,能力有限,所以复现需要的时间较长,需要补充和学习的东西较多,若大家有什么建议,欢迎评论区一起讨论进步。

漏洞简介

        OpenWrt是一套针对嵌入式设备的Linux操作系统,libubox是其中的一个提供事件循环、二进制格式处理、Linux链表实现和JSON辅助处理的基础库。

        该漏洞与标记的二进制数据的JSON转换部分(blob)有关。Blob属性有足够大的double类型数值,由blobmsg_format_json处理,会溢出为堆栈上分配的JSON输出指定的缓冲区数组。攻击者可以向blobmsg_format_json提供特制的二进制blob或JSON输入,从而在double值序列到JSON缓冲区时造成堆栈溢出。

        libubox库是OpenWrt项目的核心组件,并在项目的其他部分使用。通过在项目的LXR[1]中查找上述易受攻击的blobmsg_format_json函数,可以看到这些相互依赖关系,该函数揭示了netifd、procd、ubus、rpcd、uhttpd中的引用。也就是说,依赖调用到blobmsg_format_json的有很多其它的部分,我们本次复现主要针对rpcd对这个漏洞的利用。

        简单介绍一下rpcb

参考:

[OpenWrt Wiki] Security Advisory 2020-01-31-2 - libubox tagged binary data JSON serialization vulnerability (CVE-2020-7248)

论文:A Grounded Theory Based Approach to Characterize So! ware" Attack Surfaces

受影响的漏洞版本:

        OpenWrt 18.06.0 - 18.06.6

        OpenWrt 19.07.0-rc1 - 19.07.0

漏洞原理分析

        本次我们选取的漏洞分析环境的版本是Openwrt18.06.5,具体的漏洞的源代码等内容我们在另一篇博客,关于CVE-2020-7982的漏洞复现中,已经提到了代码的位置,如下地址参考:

CVE-2020-7982 OpenWrt 远程命令执行漏洞学习(完结)_openwrt 漏洞-CSDN博客

本次实验要分析的源代码的参考地址如下,后续我们不再赘述

https://git.openwrt.org/?p=project/libubox.git;a=blob;f=blobmsg_json.c;h=ec8b482c30c96a355aca58651632bc509a16bedf;hb=HEAD

根据漏洞的介绍,我们需要先找到libubox的源代码

该项目的地址如下

https://git.openwrt.org/?a=project_list;pf=project

之后我们在blobmsg_json.h中可以找到我们想要的函数blobmsg_format_json

根据函数的内容声明,其会先调用blobmsg_format_json_with_cb这个函数,我们可以在blobmsg_json.c文件中找到这个函数

首先定义了一个strbuf的结构体s,并且初始化内容为0。strbuf 结构体通常用于在C语言中表示可变长度的字符串缓冲区。它通常包含有关缓冲区内容和大小的信息,以便可以方便地进行字符串操作。

一般而言,strbuf 结构体可能包含以下成员:

  • char *buf:指向存储字符串数据的内存缓冲区的指针。
  • size_t len:当前字符串的长度。
  • size_t alloc:分配给缓冲区的内存空间大小。

之后其调用函数setup_strbuf 具体如下图

我们首先先找到blob_attr这个数据结构的结构样式,我们可以找到blob.h这个文件,我们在其中可以看到blob_attr这个结构,如下图所示

其中uint32_t是一个32位,也就是4字节的数据类型,而data是一个可变长度的数据类型,所以一般来说,原始的blob_attr结构的长度应该是32位。

那么首先setup_strbuf函数会调用blob_len函数来进行处理,我们同样可以在blob.h文件中找到函数blob_len,如下图

我们可以根据最开始的引用,

在文件utils.h中找到函数be32_to_cpu的结构,最终我们发现了两个

总的来说,其作用就是定义了一个内联函数 blob_len,用于计算属性的有效载荷长度。通过 be32_to_cpu 宏将 attr->id_len 中的大端字节序转换为CPU本地字节序。CPU本地字节序则表示CPU处理器默认采用的字节序方式。因为不同的CPU架构可能采用不同的字节序,所以需要在不同字节序之间进行转换,以确保数据在不同平台上的正确解释和处理。这具体可以参考计组相关的知识。然后使用按位与操作符和 BLOB_ATTR_LEN_MASK 来提取有效载荷长度,并减去 struct blob_attr 的大小。其中我们在blob.h中看到了

        这样一个定义,BLOB_ATTR_ID_MASK被定义为了0x7f000000,其二进制的形式是1111111000000000000000000000000,根据按位与的运算逻辑,本质就是把有效载荷数据的前7位进行按位与操作,而后续多出来的字节数据都会被置为0,最终其有效长度也是8x4bit=32bit,也就是4B的长度大小。

        最终我们获得了attr的长度,将其赋值给s的len这样一个成员变量。

和其相关的漏洞原理我们也参考了论文中的一些内容

我们在数据包auc.c中可以看到如下的代码:

这段代码是一段 C 语言代码,看起来是基于 libubox 库进行的一些操作。根据代码的上下文,它似乎是在处理 HTTP 请求和响应的元数据信息。第 679 行通过调用 DPRINTF 函数打印出了一个变量 cl 的 status_code 值。第 680 行通过调用 blobmsg_format_json_indent 函数将 cl->meta 中的头部信息格式化为 JSON 并打印出来。第 681 行使用 blobmsg_parse 函数解析了 cl->meta 中的头部信息,并将解析结果存储在 tb 变量中。

我们可以结合libuboxblobmsg_json.h的具体内容来判断。

这个函数blobmsg_format_json_with_cb我们前面已经提到了,所以这里不赘述其内容。

这里除了用到了这个函数,过程中还会用到blobmsg_puts函数

其中对于第147行代码而言,这行代码使用了C语言中的memcpy函数,其目的是将内存区域c的前len个字节复制到s->buf + s->pos所指向的内存区域中。在这里,s是一个结构体或者对象,buf和pos可能是该结构体中的成员变量,用来表示缓冲区和偏移量。那么漏洞就在这里,我们可以构造特殊的JSON数据传入,使其在将double数据序列化到JSON缓冲区的时候,导致缓冲区的溢出

漏洞环境搭建

漏洞复现

payload

$ ubus call luci getFeatures '{ "banik": 00192200197600198000198100200400.1922 }'

漏洞修复

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • MySQL SQL 编程练习
  • 深度解读大语言模型中的Transformer架构
  • Jetpack Compose 通过 OkHttp 发送 HTTP 请求的示例
  • FTP传输的两种模式的技术原理和应用
  • vue3+element-plus 实现动态菜单和动态路由的渲染
  • 传神社区|数据集合集第7期|法律NLP数据集合集
  • 【芯智雲城】详解智能电机驱动在汽车中的应用
  • GUI界面开发之tkinter(二) 学习文本组件
  • k8s部署kafka集群
  • Navicat图形化管理工具安装教程
  • vue接入google map自定义marker教程
  • Microsoft 365 Office BusinessPro LTSC 2024 for Mac( 微软Office办公套件)
  • 学习Numpy的奇思妙想
  • 【深度学习】PyTorch框架(5):Transformer和多注意力机制
  • 流淌在机械键盘上的魔法 源自这颗芯片
  • 【Leetcode】101. 对称二叉树
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • Python进阶细节
  • Redis的resp协议
  • ubuntu 下nginx安装 并支持https协议
  • 安装python包到指定虚拟环境
  • 给github项目添加CI badge
  • 跨域
  • 码农张的Bug人生 - 初来乍到
  • 排序(1):冒泡排序
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 前端面试之CSS3新特性
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 【云吞铺子】性能抖动剖析(二)
  • FaaS 的简单实践
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • 阿里云ACE认证之理解CDN技术
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • #100天计划# 2013年9月29日
  • #define 用法
  • #pragma pack(1)
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (2)STM32单片机上位机
  • (4)事件处理——(7)简单事件(Simple events)
  • (C语言)共用体union的用法举例
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (pojstep1.3.1)1017(构造法模拟)
  • (Qt) 默认QtWidget应用包含什么?
  • (多级缓存)缓存同步
  • (分布式缓存)Redis持久化
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (四)库存超卖案例实战——优化redis分布式锁
  • (算法二)滑动窗口
  • (转)我也是一只IT小小鸟
  • (最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)
  • *算法训练(leetcode)第四十天 | 647. 回文子串、516. 最长回文子序列
  • .gitattributes 文件
  • .NET C# 操作Neo4j图数据库