CVE-2019-12272 OpenWrt图形化管理界面LuCI命令注入分析
漏洞简介
- OpenWrt LuCI是一款用于OpenWrt(Linux发行版)的图形化配置界面。
- OpenWrt LuCI 0.10及之前版本中的admin/status/realtime/bandwidth_status和admin/status/realtime/wireless_status端点存在命令注入漏洞。该漏洞源于外部输入数据构造可执行命令过程中,网络系统或产品未正确过滤其中的特殊元素。攻击者可利用该漏洞执行非法命令。
环境搭建
- 由于OpenWrt中自带LuCI,只需要使用虚拟机正常运行OpenWrt即可,在这里使用VMware运行OpenWrt虚拟机。
- OpenWrt版本:Chaos Calmer OpenWrt 15.05.1
- 下载地址:https://archive.openwrt.org/chaos_calmer/15.05.1/x86/generic/openwrt-15.05.1-x86-generic-combined-ext4.img.gz
安装成功后成功访问LuCI主页:
设置登陆密码后成功登陆:
为了直接分析LuCI源码,在虚拟机中找到LuCI的地址并使用tar打包:
由于openwrt中没有文件下载工具,而LuCI已经把目录映射了,直接将打包文件移动至http映射目录下,走http下载LuCI源码:
POC
传入Payload: http://192.168.153.4/cgi-bin/luci/admin/status/realtime/bandwidth_status/eth0$(id>cmd)
:
成功执行命令:
漏洞分析
- LuCI采用了典型的MVC三层架构,并使用Lua脚本开发;在解析请求时,首先进入admin/status.lua中的controller入口进行路由,然后调用相应的model进行处理。
而漏洞的触发点是在controller的bandwidth_status函数中,该函数将用户传入的字符串直接格式化到命令中并执行,造成了RCE。
- 代码具体执行过程如下: 使用HTTP访问路径/admin/status/realtime/bandwidth_status(或wireless_status)/[param],首先进入index entry进行路由,在路由中使用dispatcher的call函数调用了action_bandwidth函数: Controller/index.lua:
Dispatcher.lua中的call函数:
然后,进入action_bandwidth函数,url解析路由之后的部分将被当做参数传入,未过滤而使用%q直接将参数格式化到字符串中。%q将在iface外包裹双引号。
使用io.popen执行命令,在bash下,双引号中的$()或``会执行,从而达到命令执行的目的:
此处相当于执行命令:sh -c luci-bwc –i “eth0$(id>cmd)” 2>/dev/null:
使用EXP执行ping命令后,可以在openwrt下查看到执行的命令:
exp脚本
脚本已上传:https://github.com/HACHp1/LuCI_RCE_exp 执行效果:
斜杠绕过
在执行的命令中需要斜杠(/
)时,由于路径解析的问题,斜杠无法使用,此时可以考虑使用bash内置变量来代替。
遇到的坑
- 最开始的时候考虑使用
${HOME:0:1}
来替代。然后发现并不能成功。但是直接在命令行中、重新开一个lua脚本执行、直接在lua交互处执行却都可以执行。
- 最后发现问题竟然是在LuCI中
$HOME
变量没有值,但是在正常情况是有值的,在此处卡的时间很长。
解决办法
在LuCI中,${PATH:0:1}
是没有被更改的,可以直接使用。测试payload为:ls ${PATH:0:1}
。
漏洞修复方案分析
查看源码修复漏洞的地方,新的源码使用gsub将iface中的单引号去掉,并在最外层加上了单引号,这样整个iface参数就仅作为字符串而不会被执行:
在源码中输出一下:
Iface参数被单引号包裹,作为r参数传入luci-bwc,不会执行ls命令:
写在最后
- 整个漏洞与半年前爆出的thinkphp RCE都与路由解析和controller相关,可见MVC构建的controller处比较容易出现安全漏洞。由于MVC模型的特性,Controller是MVC模式函数调用的入口,如果攻击者能够控制controller或者能够注入并利用controller,就容易出现漏洞。
参考资料
- https://www.jianshu.com/p/bfb93c4e8dc9
- https://forum.openwrt.org/t/vulnerable-releases-for-cve-2019-12272/38564
- https://blog.csdn.net/ballack_linux/article/details/81331527
- https://github.com/openwrt/luci/commit/9e4b8a91384562e3baee724a52b72e30b1aa006d