前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何用0day漏洞黑掉西部数据NAS存储设备

如何用0day漏洞黑掉西部数据NAS存储设备

作者头像
FB客服
发布2018-02-23 16:55:52
1.4K0
发布2018-02-23 16:55:52
举报
文章被收录于专栏:FreeBufFreeBuf

我们以入侵和破解设备为乐,今天,要向大家展示的是近期我们对西部数据(Western Digital )网络存储设备(NAS)的漏洞发现和入侵利用过程。点击阅读原文观看入侵视频。

漏洞发现

去年年中,我打算入手一台支持硬件解码的NAS存储来搭建Plex流媒体服务平台,经过一番比较,在一位朋友的推荐下,我选择了西部数据(Western Digital )的MyCloud PR4100,该存储设备完全满足我所有的功能需求。把该设备添加进网络之后,可以通过一个Web界面访问登录,由于我对使用设备有安全洁癖,所以在登录开启SSH连接之后,我开始对其网页服务功能进行了安全审计,并发现了以下存在漏洞:

登录验证绕过漏洞

很惊讶,我很快发现了一个用cookie和PHP session进行登录检查的bug。虽然使用cookie认证并不都是坏事,但该设备的使用方式存在问题,请看以下脚本:

/lib/login_checker.php

function login_check() { $ret = 0; if (isset($_SESSION['username'])) { if(isset($_SESSION['username']) && $_SESSION['username'] != "") $ret = 2; //login, normal user if ($_SESSION['isAdmin'] == 1) $ret = 1; //login,admin } else if (isset($_COOKIE['username'])) { if (isset($_COOKIE['username'])&& $_COOKIE['username'] != "") $ret = 2; //login, normaluser if ($_COOKIE['isAdmin'] == 1) $ret = 1; //login,admin } return $ret; }

代码包含一个名为 “login_check”的函数,后台PHP脚本通过调用该函数对预登录用户进行认证校验。函数代码显示,可以通过两种方式进行认证,一种是session方式的“username”“isAdmin”判断,另一种是cookie方式的判断。由于cookie由用户执行产生,所以攻击者同样可以构造满足脚本调用的恶意请求。上述代码认证方式可以归纳为以下方式:

当存在“username” 变量且不为空时,用户作为正常权限用户登录; 当存在“isAdmin”变量且不为空时,用户作为管理员登录;

这意味着,只要使用php脚本进行登录验证时,攻击者就可以构造特殊cookie变量绕过验证。

补丁更新导致新的漏洞

然而,就在我的研究过程中,该存储设备的一个固件更新释出对上述bug的修复补丁。但更不可思议的是,该补丁却导致了另外一种方式的验证绕过漏洞。以下是更新后的登录验证脚本:

/var/www/web/lib/login_checker.php

function login_check() { $ret = 0; if (isset($_SESSION['username'])) { if(isset($_SESSION['username']) && $_SESSION['username'] != "") $ret = 2; //login, normal user if ($_SESSION['isAdmin'] == 1) $ret = 1; //login,admin } else if (isset($_COOKIE['username'])) { if(isset($_COOKIE['username']) && $_COOKIE['username'] != "") $ret = 2; //login, normal user if ($_COOKIE['isAdmin'] == 1) $ret = 1; //login, admin if(wto_check($_COOKIE['username']) === 0) //wto check fail $ret = 0; } return $ret; } ?>

更新后的代码第40行,增加了对用户验证的 “wto_check()”方法,用户名和IP地址都是该方法的参数。当前登入用户保持操作状态,则返回1,超时则返回0。“wto_check()”实现代码如下:

/var/www/web/lib/login_checker.php

/* return value: 1: Login, 0: No login */ function wto_check($username) { if (empty($username)) return 0; exec(sprintf("wto -n \"%s\" -i '%s' -c",escapeshellcmd($username), $_SERVER["REMOTE_ADDR"]), $login_status); if ($login_status[0] === "WTO CHECK OK") return 1; else return 0; } /*ret: 0: no login, 1: login, admin, 2: login, normal user */

上述代码第11行中,用户名和IP地址被初始化为wto变量参数,而问题就出在用来处理整个命令字符串的方法“escapeshellcmd()”,该方法不会对-n参数中配对的引号进行转义,这就给了攻击者重新构造或绕过验证的可能,因此,我们可以添加新的参数绕过验证并执行任意用户登录。

Freebuf百科:escapeshellcmd()对字符串中可能会欺骗shell命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec()或 system()函数,或者执行操作符之前进行转义。反斜线(\)会在以下字符之前插入: #&;`|*?~<>^()[]{}$\, \x0A 和 \xFF。 而' 和 " 仅在不配对的时候被转义,在 Windows 平台上,所有这些字符以及 % 都会被前缀 ^ 来转义。(详细请参考 php.net相关说明)

这里,最好使用Escapeshellarg方法函数,Escapeshellarg()会将任何引起参数或命令结束的字符进行转义,如单引号“’”会被转义为“\’”,双引号“””会被转义为“\””,分号“;”会被转义为“\;”,这样escapeshellarg会将参数内容限制在一对单引号或双引号里面,转义参数中所包含的单引号或双引号,使其无法对当前执行进行截断,实现防范命令绕过或注入攻击的目的。

命令注入漏洞

大多数的西部数据MyCloud设备Web界面,实际上是由CGI脚本来实现的,这些脚本中大部分二进制文件都存在着相同的功能模式,如从请求包中获取post/get/cookie值,然后应用这些值执行相关命令。然而,大多数情况下,这些命令会使用到用户提交的一些未经安全处理的恶意数据。例如,以下设备中存在的代码:

php/users.php

15 $username = $_COOKIE['username']; 16 exec("wto -n\"$username\" -g", $ret);

代码把包含cookie值的全局变量数组$_COOKIE命名为”$username”,之后,该”$username”作为后续“exec()”命令执行的调用参数。因为没有任何过滤措施,可以这样更改一下,把username值设为:

username=$(touch /tmp/1)

那么执行命令将会变为:

wto -n "$(touch /tmp/1)" -g

很容易就执行了用户的自定义命令。

由于命令行参数被双引号封装,在执行“$(COMMANDHERE)”语法时,命令“touch /tmp/1”先于wto前就已经执行,并把返回结果作为-n参数。这种web接口对内置脚本的交互调用模式,明显会导致命令注入漏洞。而且,使得注意的是,所有通过web端构造的命令都会被以root权限执行。

其它Bug

除了以上两个高危漏洞之外,该设备在web服务方面还存在其它一些严重Bugs,比如以下文件中正常登录验证行为被错误地注释掉:

6 //include("../lib/login_checker.php"); 7// 8///* login_check() return 0: no login, 1: login, admin, 2: login, normal user*/ 9//if (login_check() == 0) 10//{ 11// echo json_encode($r); 12// exit; 13//}

而以下上传功能文件可以针对设备系统,执行无需用户验证的,任意目录位置的任意文件上传:

addons/upload.php

2 //if(!isset($_REQUEST['name'])) throw newException('Name required'); 3//if(!preg_match('/^[-a-z0-9_][-a-z0-9_.]*$/i', $_REQUEST['name'])) throw newException('Name error'); 4// 5//if(!isset($_REQUEST['index'])) throw new Exception('Index required'); 6//if(!preg_match('/^[0-9]+$/', $_REQUEST['index'])) throw new Exception('Indexerror'); 7// 8//if(!isset($_FILES['file'])) throw new Exception('Upload required'); 9//if($_FILES['file']['error'] != 0) throw new Exception('Upload error');

10 11$path = str_replace('//','/',$_REQUEST['folder']); 12$filename = str_replace('\\','',$_REQUEST['name']); 13$target = $path . $filename . '-' .$_REQUEST['index']; 14 15//$target = $_REQUEST['folder'] .$_REQUEST['name'] . '-' . $_REQUEST['index'];

16 17move_uploaded_file($_FILES['file']['tmp_name'], $target); 18 19 20//$handle = fopen("/tmp/debug.txt", "w+"); 21//fwrite($handle, $_FILES['file']['tmp_name']); 22//fwrite($handle, "\n"); 23//fwrite($handle, $target); 24//fclose($handle);

25 26// Might execute too quickly. 27sleep(1);

除此之外,我们还发现了另外一个个远程命令执行漏洞(RCE)和身份验证命令执行漏洞,在此就不作公开。由于这些漏洞在此之前,没人发现或爆料过,可以算是西部数据NAS设备的0day漏洞。

漏洞总结

1 x 登录验证绕过漏洞 1 x 任意文件上传漏洞 1 x 无需用户验证的远程代码执行漏洞 1x 身份验证命令执行漏洞

漏洞影响范围

涉及西部数据以下型号系列的NAS设备

My Cloud My Cloud Gen 2 My Cloud Mirror My Cloud PR2100 My Cloud PR4100 My Cloud EX2 Ultra My Cloud EX2 My Cloud EX4 My Cloud EX2100

后续的补丁更新和相关情况,请继续关注我们的Twitter @exploiters

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-03-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 漏洞发现
    • 登录验证绕过漏洞
      • 补丁更新导致新的漏洞
        • 命令注入漏洞
          • 其它Bug
          • 漏洞总结
          • 漏洞影响范围
          相关产品与服务
          对象存储
          对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档