CVE-2020-7982:OpenWrt RCE漏洞 - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

CVE-2020-7982:OpenWrt RCE漏洞

ang010ela 漏洞 2020-03-27 10:10:00
2005480
收藏

导语:​研究人员在OpenWrt中发现一个RCE漏洞,影响数百万网络设备。

背景

OpenWRT

openwrt vulnerability hacking

OpenWRT是一款免费的基于linux的操作系统,主要用于嵌入式设备尤其是网络路由器中。从账号数来看,安装量超过百万。

OpenWRT package manager(包管理器)

要在OpenWRT系统中安装或升级软件,就需要使用一个名为opgk的小工具。其功能和作用相当于Debian系系统的apt功能。

Opkg通过非加密的HTTP连接来从downloads.openwrt.org 下载可用的package列表。Package列表是经过数字签名的。这确保了package二五年间在处理前可被验证,如果验证失败,就不进行下一步。

理论上讲,通过使用签名可以在HTTP传输信道本身并不安全的情况下防止package列表或文件被修改。

漏洞

当用户使用opkg install

分析器会遍历每个包记录,并对每个不同类型的域执行不同的动作。在分析SHA256sum 域时间,会调用pkg_set_sha256:

312              else if ((mask & PFM_SHA256SUM) && is_field("SHA256sum", line))
313                      pkg_set_sha256(pkg, line + strlen("SHA256sum") + 1);

pkg_set_sha256 会尝试将SHA256sum 域从十六进制解码为二进制,并以内部表示形式保存:

244 char *pkg_set_sha256(pkg_t *pkg, const char *cksum)
245 {
246      size_t len;
247      char *p = checksum_hex2bin(cksum, &len);
248
249      if (!p || len != 32)
250              return NULL;
251
252      return pkg_set_raw(pkg, PKG_SHA256SUM, p, len);
253 }

如果解码失败,就不会保存哈希值。

真正的漏洞其实位于checksum_hex2bin函数中。

234 char *checksum_hex2bin(const char *src, size_t *len)
235 {
236      size_t slen;
237      unsigned char *p;
238      const unsigned char *s = (unsigned char *)src;
239      static unsigned char buf[32];
240
241      if (!src) {
242              *len = 0;
243              return NULL;
244      }
245
246      while (isspace(*src))
247              src++;
248
249      slen = strlen(src);
250
251      if (slen > 64) {
252              *len = 0;
253              return NULL;
254      }
255
256      for (p = buf, *len = 0;
257           slen > 0 && isxdigit(s[0]) && isxdigit(s[1]);
258           slen--, s += 2, (*len)++)
259              *p++ = hex2bin(s[0]) * 16 + hex2bin(s[1]);
260
261      return (char *)buf;
262 }

从中可以看出,s和src变量指向的是相同的地址。

Package列表分析完成后,就会通过HTTP来下载package。

验证步骤如下:

下载的package大小与package列表中指定的相等:

1379      pkg_expected_size = pkg_get_int(pkg, PKG_SIZE);
1380
1381      if (pkg_expected_size > 0 && pkg_stat.st_size != pkg_expected_size) {
1382              if (!conf->force_checksum) {
1383                      opkg_msg(ERROR,
1384                               "Package size mismatch: %s is %lld bytes, expecting %lld bytes\n",
1385                               pkg->name, (long long int)pkg_stat.st_size, pkg_expected_size);
1386                      return -1;
1387              } else {
1388                      opkg_msg(NOTICE,
1389                               "Ignored %s size mismatch.\n",
1390                               pkg->name);
1391              }
1392      }

如果package中指定了SHA256哈希值,也必须匹配:

1415      /* Check for sha256 value */
1416      pkg_sha256 = pkg_get_sha256(pkg);
1417      if (pkg_sha256) {
1418              file_sha256 = file_sha256sum_alloc(local_filename);
1419              if (file_sha256 && strcmp(file_sha256, pkg_sha256)) {
1420                      if (!conf->force_checksum) {
1421                              opkg_msg(ERROR,
1422                                       "Package %s sha256sum mismatch. "
1423                                       "Either the opkg or the package index are corrupt. "
1424                                       "Try 'opkg update'.\n", pkg->name);
1425                              free(file_sha256);
1426                              return -1;
1427                      } else {
1428                              opkg_msg(NOTICE,
1429                                       "Ignored %s sha256sum mismatch.\n",
1430                                       pkg->name);
1431                      }
1432              }
1433              if (file_sha256)
1434                      free(file_sha256);
1435      }

因为checksum_hex2bin无法解码SHA256sum域,1418行的代码就被绕过了。

看起来该漏洞应该是2017年2月引入的,距今拥有3年时间,具体参见:

https://git.openwrt.org/?p=project/opkg-lede.git;a=blobdiff;f=libopkg/file_util.c;h=155d73b52be1ac81d88ebfd851c50c98ede6f012;hp=912b147ad306766f6275e93a3b9860de81b29242;hb=54cc7e3bd1f79569022aa9fc3d0e748c81e3bcd8;hpb=9396bd4a4c84bde6b55ac3c47c90b4804e51adaf

漏洞利用

漏洞利用的前提是攻击者入侵了提供package的web服务器。攻击者必须要能够拦截或替换设备和downloads.openwrt.org之间的通信,或控制设备使用的DNS服务器,将downloads.openwrt.org指向攻击者控制的web服务器。

使用包嗅探或ARP缓存投毒的本地网络攻击也是可能的,但是还没有进行测试。

安全建议

研究报告漏洞后,OpenWRT就移除了package列表中SHA256sum的空格。这可以一定程度上缓解对用户带来的危险。checksum_hex2bin中的漏洞在2月1日发布的OpenWRT v18.06.7 和v19.07.1版本中进行了修复。研究人员建议用户尽快更新OpenWRT。

本文翻译自:https://blog.forallsecure.com/uncovering-openwrt-remote-code-execution-cve-2020-7982如若转载,请注明原文地址
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务