CVE-2020-7982:OpenWrt RCE漏洞
2020-03-27 11:10:00 Author: www.4hou.com(查看原文) 阅读量:207 收藏

背景

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如若转载,请注明原文地址


文章来源: https://www.4hou.com/posts/mMKr
如有侵权请联系:admin#unsafe.sh