NETGEAR 系列路由器命令执行漏洞简析
NETGEAR 系列路由器命令执行漏洞简析
2016年12月7日,国外网站exploit-db上爆出一个关于NETGEAR R7000路由器的命令注入漏洞。一时间,各路人马开始忙碌起来。厂商忙于声明和修复,有些人忙于利用,而我们则在复现的过程中寻找漏洞的本质。
一.漏洞简介
1.漏洞简介
2016年12月7日,NETGEAR R7000路由器在exploit-db上被爆出存在远程命令执行漏洞,随着安全研究人员的不断深入,R8000和R6400这两款路由器也被证实有同样的问题。 2016年12月13日,NETGEAR官网上确认漏洞存在,对部分受影响的设备发出了beta
版的固件补丁。 2016年12月14日,受影响的设备型号增加至11种。
2.漏洞影响
NETGEAR R6250 NETGEAR R6400 NETGEAR R6700 NETGEAR R6900 NETGEAR R7000 NETGEAR R7100LG NETGEAR R7300DST NETGEAR R7900 NETGEAR R8000NETGEAR D6220 NETGEAR D6400*
二.漏洞复现与分析
1.漏洞复现
通过ZoomEye网络空间搜素引擎我们可以寻找此次受影响的设备的ip
curl -v "https://ip:port/cgi-bin/;echo$IFS"testt" --insecure
2.漏洞分析
①灵感篇
此次漏洞分析的灵感源于小伙伴检测中发现的一个问题,让我们走了不少弯路,顺利定位到问题所在。 当我们执行ps
命令时,出现了如下的结果:很有意思的是,我们请求的url出现在了以nobody
用户运行的进程里,这让我们可以根据关键词"sh -c"和"/tmp/cgi_result"去定位关键代码的位置。
在漏洞分析的过程中,另一个小伙伴给出了一个链接,DD-WRT HTTPd的远程命令执行。其中命令执行的部分如下,与本次漏洞很像。于是HTTPD
就成了我们这次重点关注的对象。
从官网下载NETGEAR R7000的固件并通过如下命令解开固件。
binwalk -eM R7000-V1.0.7.2_1.1.93.chk
解开固件之后我们寻找到了相关的文件/usr/sbin/httpd
,确认与cgi_result
有关之后,我们对httpd
进行了逆向。
②逆向篇
根据前文的介绍,我们通过搜索字符串,找到了对应的函数sub_36C34
,F5看反编译的伪码,出现cgi_result
这一字符串的地方如下:
if ( !strcmp((const char *)&v53, "POST") )
{
...
}
else if ( !strcmp((const char *)&v53, "OPTIONS") )
{
...
}
else
{
v36 = fopen("/tmp/cgi_result", "r");
if ( v36 )
{
fclose(v36);
system("rm -f /tmp/cgi_result");
if ( acosNvramConfig_match((int)&unk_F0378, (int)"2") )
puts("\r\n##########delete /tmp/cgi_result ############\r");
}
v33 = (const char *)&unk_F070F;
v34 = (char *)&v45;
}
sprintf(v34, v33, &v50);
system((const char *)&v45);
memset(&v49, 0, 0x40u);
可以看到else
里的逻辑是先判断/tmp/cgi_result
这一文件是否存在,存在则删除该文件,v33
为unk_F070F
的地址值,unk_F070F
的值为/www/cgi-bin/%s > /tmp/cgi_result
,v34
为v45
的地址值。继续向下,可以看到v50替换了v33中的 %s 并赋值给了v34。v50具体是什么我们暂时不清楚。然后再使用system()
函数执行v45对应的值,也就是前面v34的值。 。据此推断,此处应该就是命令执行的触发点了。我们开始向上溯源。 首先,我们先看一下sub_36C34函数的几个参数的内容
int __fastcall sub_36C34(const char *a1, int a2, const char *a3, int a4)
根据其中的代码内容以及写入的文件/tmp/post_data.txt
可知,a1
为POST
数据包的body
部分,a3
可能为url
,a4
为一个整数,用于判断是否为POST
的数据包 查看xrefs graph to
生成的调用图:
我们从main函数开始看起,main函数直接调用了sub_147A0函数
sub_147A0函数中如此调用了sub_100A0函数
sub_100A0(&s1, a105, (int)&a87, dword_F217F8);
其中s1
为http
报文内容,a105
为s1的地址值。
在sub_100A0函数中,POST
数据交给sub_19600
函数处理,GET
数据交给sub_19B3C
函数处理,还有一些其它情况交给sub_1A1C0
函数处理,再交给sub_19B3C
处理。我们跟了调用sub_19600函数的一些关键过程。
int __fastcall sub_100A0(char *a1, const char *a2, int a3, int a4)
{
char *v9; // r4@5
const char *v10; // r3@6
int v11; // r7@6
bool v12; // zf@6
...
s1 = a1;
v9 = (int)s1;
...
do
{
v10 = (unsigned __int8)*v9;
v11 = v9++;
v12 = v10 == 0;
if ( v10 )
v12 = v10 == 32;
}
while ( !v12 );
//移动到HTTP报文第一个空格的位置
...
LABEL_27:
if ( *(_BYTE *)(v11 + 1) == 47 )
++v9;
//移动到HTTP报文中/的位置
..
return (int)sub_19600((const char *)v9, v248, v4);
}
可以看到,sub_19600函数将指针移动到HTTP报文中第一个/
的位置,也就是网站路径的位置,然后通过调用LABEL_27:就可以获取网站的目录。这样获取到的内容就是最初始的内容被传递到了下一个函数 sub_19600。
char *__fastcall sub_19600(const char *a1, const char *a2, int a3)
{
const char *v3; // r6@1
const char *v4; // r4@1
int v5; // r5@1
char *result; // r0@1 v3 = a2;
v4 = a1;
v5 = a3;
result = strstr(a1, "cgi-bin");
if ( result )
{
if ( acosNvramConfig_match((int)"cgi_debug_msg", (int)"1") )
printf("\r\n##########%s(%d)url=%s\r\n", "handle_options", 1293, v4);
result = (char *)sub_36C34(v3, v5, v4, 2);
}
return result;
}
sub_19600
函数没有做任何处理,就直接将获取到的路径传递到了sub_36C34
。
int __fastcall sub_36C34(const char *a1, int a2, const char *a3, int a4)
{
v6 = a3; v12 = strstr(v6, "cgi-bin");
if(v12)
{
...
memset(&v50, 0, 0x40u);//给V50分配了64字节的空间,故我们可执行命令的最大长度为64字节
...
}
else
{
if ( v24 )
{
if ( v22 )
v25 = 0;
else
v25 = v23 & 1;
if ( v25 )
strcpy((char *)&v50, v20);
}
else
{
strncpy((char *)&v50, v20, v22 - 1 - v21);
}
}
...
...
...
if ( !strcmp((const char *)&v53, "POST") )
{
...
}
else if ( !strcmp((const char *)&v53, "OPTIONS") )
{
...
}
else
{
v36 = fopen("/tmp/cgi_result", "r");
if ( v36 )
{
fclose(v36);
system("rm -f /tmp/cgi_result");
if ( acosNvramConfig_match((int)&unk_F0378, (int)"2") )
puts("\r\n##########delete /tmp/cgi_result ############\r");
}
v33 = (const char *)&unk_F070F;
v34 = (char *)&v45;
}
sprintf(v34, v33, &v50);
system((const char *)&v45);
memset(&v49, 0, 0x40u);
}
在sub_36C34
函数中,会检测url
中是否含有cgi-bin
,如果含有,则进行一系列分割操作,并将cgi-bin
后面的值赋给v50
,而参数v50则正如我们之前分析的那样,替换了v33中的 %s 之后赋值给v34并被 system()
函数执行,造成了命令执行漏洞。
之后我们继续跟了sub_19B3C
和sub_1A1C0
这两个函数,发现最终也跟sub_19600
函数殊途同归。不过是因为HTTP
请求的不同(POST
和OPTIONS
)而导致不同的函数去处理罢了。
③固件对比篇
2016年11月13日,NETGEAR
在其官网发布了新的beta
固件,我们对其进行了更进。 按照上文同样的方法,我们对httpd
进行了逆向,xrefs
图如下:整体函数没有太大变化,让我们来看一下具体细节上的变化。 一路跟下来,在sub_14958
,sub_100A0
和sub_197B8
这些函数中都没有看到对url
进行处理,在sub_36EB4
中我们发现官方对其进行了过滤。
int __fastcall sub_36EB4(const char *a1, int a2, const char *a3, int a4)
{
const char *v6; // r4@1
...
v6 = a3;
if ( !strchr(a3, 59) && !strchr(v6, 96) && !strchr(v6, 36) && !strstr(v6, "..") )
//ascii对照表:59=>; 96=>` 36=>$
{
...
}
}
我们可以看到,官方的beta固件过滤了; \ $
和..
,但是我们依旧可能可以绕过这些过滤执行命令,例如||
(未测试)。
至于官方后续的更新,我们会继续更进。 如有错误,欢迎指正:)
三.漏洞影响
下图为ZoomEye网络空间搜素引擎上最早曝光的受影响设备R7000,R8000和R6400的全球分布情况。
事实上,还有很多内网的设备我们无法探测,对于这些内网设备,通过csrf
攻击仍然可以威胁到内网的安全。这里提供一个以往的案例供大家参考: http://www.2cto.com/article/201311/254364.html 。由于本次漏洞可以执行任意命令,故威胁远比案例中修改dns
要大,希望可以引起大家的重视。
四.修复建议
目前官方仅推出了beta版的补丁,可以根据官网的提示刷新固件 由于新版本beta固件可能还存在一定的安全问题,我们仍然建议关闭路由器远程管理页面。 对比之前受影响的设备,如果不能进入管理界面,也可以通过下列url
关闭。
http(s)://ip:port/cgi-bin/;killall$IFS’httpd’
五.参考链接
1.https://www.seebug.org/vuldb/ssvid-92571 2.https://www.exploit-db.com/exploits/40889/ 3.http://kb.netgear.com/000036386/CVE-2016-582384 4.http://www.kb.cert.org/vuls/id/582384 5.https://github.com/rapid7/metasploit-framework/issues/7698 6.http://www.freebuf.com/news/122596.html
NETGEAR 系列路由器命令执行漏洞简析的更多相关文章
- Samba 4.x.x全版本存在命令执行漏洞
Samba 4.0.0到4.1.10版本的nmbd(the NetBIOS name services daemon)被发现存在远程命令执行漏洞.CVE编号为CVE-2014-3560.目前官方已经发 ...
- D-Link service.cgi远程命令执行漏洞复现
1.1 概述 友讯集团(D-Link),成立于1986年,1994年10月于台湾证券交易所挂牌上市,为台湾第一家上市的网络公司,以自创D-Link品牌行销全球,产品遍及100多个国家. 1月17日,C ...
- thinkphp5.x命令执行漏洞复现及环境搭建
楼主Linux环境是Centos7,LAMP怎么搭不用我废话吧,别看错了 一.thinkphp5.X系列 1.安装composer yum -y install composer 安装php拓展 yu ...
- 2020/1/28 PHP代码审计之命令执行漏洞
0x00 命令执行漏洞原理 应用程序有时需要调用一些执行系统命令的函数,如在PHP中,使用system.exec.shell_exec.passthru.popen.proc_popen等函数可以执行 ...
- Spring Framework 远程命令执行漏洞(CVE-2022-22965)
Spring Framework 远程命令执行漏洞 (CVE-2022-22965) 近日,Spring 官方 GitHub issue中提到了关于 Spring Core 的远程命令执行漏洞,该漏洞 ...
- HFS远程命令执行漏洞入侵抓鸡黑阔服务器
先来科普一下: HFS是什么? hfs网络文件服务器 2.3是专为个人用户所设计的HTTP档案系统,如果您觉得架设FTP Server太麻烦,那么这个软件可以提供您更方便的网络文件传输系统,下载后无须 ...
- ASP代码审计 -4.命令执行漏洞总结
命令执行漏洞: 保存为cmd.asp,提交链接: http://localhost/cmd.asp?ip=127.0.0.1 即可执行命令 <%ip=request("ip" ...
- 小白日记36:kali渗透测试之Web渗透-手动漏洞挖掘(二)-突破身份认证,操作系统任意命令执行漏洞
手动漏洞挖掘 ###################################################################################### 手动漏洞挖掘 ...
- JBOSSAS 5.x/6.x 反序列化命令执行漏洞(CVE-2017-12149)
本文主要记录一下JBOSSAS 5.x/6.x 反序列化命令执行漏洞的测试过程 仅供学习 文中利用到漏洞环境由phith0n维护: JBoss 5.x/6.x 反序列化漏洞(CVE-2017-1214 ...
随机推荐
- openstack核心组件--neutron网络服务(4)
一.neutron 介绍: Neutron 概述 传统的网络管理方式很大程度上依赖于管理员手工配置和维护各种网络硬件设备:而云环境下的网络已经变得非常复杂,特别是在多租户场景里,用户随时都可能需要 ...
- Java日志体系(一)发展历程
一.日志框架的分类 门面型日志框架: JCL: Apache基金会所属的项目,是一套Java日志接口,之前叫Jakarta Commons Logging,后更名为Commons Logging SL ...
- Java之属性和普通方法
一.定义类 上一节讲了很多深奥的理论,那么这节我们就得实践一下,先简单描述一下我们的实体世界:有一个学生小明,那么这个学生就是一个对象,这个对象有哪些属性和方法呢,我们可以先简单抽象一下,属性有(姓名 ...
- Postman的安装和升级
安装postman Postman本地应用程序 Postman可以作为Mac,Windows和Linux操作系统的本地应用程序. 要安装Postman,请转到应用界面,并根据你的平台点击Mac/Win ...
- Leetcode之动态规划(DP)专题-309. 最佳买卖股票时机含冷冻期(Best Time to Buy and Sell Stock with Cooldown)
Leetcode之动态规划(DP)专题-309. 最佳买卖股票时机含冷冻期(Best Time to Buy and Sell Stock with Cooldown) 股票问题: 121. 买卖股票 ...
- Sql 备忘——行号
SELECT row_number() over(order by Product.ID) as [row_number]
- day29 元类及异常处理
元类及异常处理 元类 什么是元类 在python中,一切皆对象,对象是由类产生的,那么类是不是对象呢? 举例: class A: pass print(type(A)) # <class 'ty ...
- 【LOJ】#3095. 「SNOI2019」字符串
LOJ#3095. 「SNOI2019」字符串 如果两个串\(i,j\)比较\(i < j\),如果离\(a_{i}\)最近的不同的数是\(a_{k}\),如果\(j < k\)那么\(i ...
- Clone()方法详解
一.克隆的原理与应用 clone在堆上分配内存,分配的内存和源对象(即调用clone方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域, 填充完成之后,clone方法返回,一个新的相同的 ...
- 使用alias简化kubectl输入
在使用Kubernetes的过程中,我们需要经常使用kubectl(客户端)命令,经常敲下kubectl是非常繁琐的,使用Linux的alias可以为一些常见的命令起别名,这样使用起来就方便多了. ⒈ ...