一次失败的路由器固件分析——CVE-2023-1389分析及复现


漏洞简介

Tenable 的研究人员在 TP-Link Archer AX21 (AX1800) 的 Web 管理界面中发现了未经身份验证的命令注入。在默认配置中,此接口只能通过 LAN(而不是 WAN)访问。

漏洞分析(失败)

固件下载:https://www.tp-link.com/us/support/download/archer-ax21/v3/#Firmware

解压缩获得固件包,如图:


本想使用QEMU、FirmAE和firmware-analysis-toolkit运行固件包,但是探索了3天(借助ChatGPT、Google等)都没成功,无奈只好先分析文件吧,使用binwalk剥开第一层套娃,获得ubi文件,如图:

直接提取文件发生错误,如图:

参考https://blog.csdn.net/weixin_43487849/article/details/126281966先提取镜像剥开第二层套娃,如图:

文件系统明显在img-92724675_vol-ubi_rootfs.ubifs,然后再在剥开第三层套娃提取squashfs文件系统,获得squashfs-root目录,然后就是正常的Linux目录结构了,如图:

简单了解了下OpenWRT操作系统,web服务为uhttp,/www目录结构说明:

cgi-bin:此文件从luci-base下拷贝过来的,存放luci启动脚本
index.html :http请求的主页面,默认是/www/index.html
luci-static:存放HTML相关文件,包含CSS、JS及网页图片等文件

/usr/lib/lua/目录结构说明:

/usr/lib/lua/5.1:Lua 5.1版本的库文件和模块
/usr/lib/lua/5.2:Lua 5.2版本的库文件和模块
/usr/lib/lua/5.3:Lua 5.3版本的库文件和模块
/usr/lib/lua/luci:LuCI Web界面框架的库文件和模块
/usr/lib/lua/luci/i18n:LuCI Web界面框架的国际化文件
/usr/lib/lua/luci/controller:LuCI Web界面框架的控制器文件
/usr/lib/lua/luci/model:LuCI Web界面框架的模型文件
/usr/lib/lua/luci/view:LuCI Web界面框架的视图文件
/usr/lib/lua/luci/tools:LuCI Web界面框架的工具类文件
/usr/lib/lua/luci/protocols:LuCI Web界面框架支持的网络协议库文件和模块
/usr/lib/lua/luci/sys:LuCI Web界面框架的系统相关库文件和模块
/usr/lib/lua/luci/util:LuCI Web界面框架的实用工具库文件和模块
/usr/lib/lua/luci/rpc:LuCI Web界面框架的RPC库文件和模块
/usr/lib/lua/luci/template:LuCI Web界面框架的模板文件

查看lua文件发现部分内容乱码,本以为这是结尾没想到才是开始,使用file命令发现是字节码,5.1版本,如图:

参考https://vovohelo.medium.com/unscrambling-lua-7bccb3d5660文章,使用:

git clone https://github.com/openwrt/luci.git
mkdir ./ref/; find ./luci-master/libs/ -iname "*.lua" -exec bash -c 'luac -o ./ref/`basename {}` {}' \;
mkdir ./sample/; find ./usr/lib/lua/luci/ -iname "*.lua" -exec cp {} ./sample/ \;
./ulua.py -r ref/ -s sample/ -f usr/lib/lua/luci/sgi/cgi.lua -o cgi.lua

然而很不幸,如图:

参考https://openpunk.com/journal/stripping-lua-protos文章,以失败告终,参考https://blog.ihipop.com/2018/05/5110.html文章,重新编译补丁版的luadec,编译成功但是仍然无法解密。回到Lua bytecode基本原理查看文件头发现与其他luac5.1字节码文件头截然不同的是lua_Number为0x04,如图:

通过多方查找资料,终于在一篇文章中找到了答案:

LUA_NUMBER被定义为float,即32位大小,对于双精度浮点来说,它被定义为double,表示64位长度。目前,在macOS系统上编译的Lua,它的大小为64位长度。
______
安全客资讯平台,公众号:HULK一线技术杂谈
Lua程序逆向之Luac文件格式分析

https://github.com/superkhung/luadec-tplink中找到了编译好的OSX中的luadec,如图:

并且可以在macOS中成功解密Lua bytecode,困扰我7天的大门终于被打开,差点就和其他夭折的文章聚会了,本以为我迈出了我IoT安全的一大步,然而却是一场空。

使用该存储库在linux下编译也可以成功解密Lua bytecode,编译命令如下:

cd luadec-tolink-master/lua-5.1
make linux
export LD_LIBRARY_PATH=`pwd`/src/
cd ../luadec
make LUAVER=5.1

编译后在luadec-tolink-master/luadec目录下生成luadec、luaopswap、luareplace文件,解密结果如图:

并不能获取关键代码,使用firmwalker查看文件可以发现一些信息但与该漏洞无关:

https://github.com/craigz28/firmwalker

漏洞原因

根据Tenable公布的技术细节:在/cgi-bin/luci/; stock =/locale端点上country表单写回调的country参数容易受到简单的命令注入漏洞的攻击。country 参数用于调用 popen函数,该参数以 root 身份执行,但仅在初始请求中首次设置后。

也就是说,要利用此问题,攻击者首先必须将有效负载作为 country 参数的一部分发送以设置值,并且在向country结点发送第二个请求(相同或否)时,第一个有效负载将作为 popen 命令的一部分执行。

Poc

连续两次发送类似于以下内容的请求将在第二个请求上运行 $(id>/tmp/out) 命令,创建包含 id 命令输出的 /tmp/out 文件。

POST /cgi-bin/luci/;stok=/locale?form=country HTTP/1.1
Host: <target router>
Content-Type: application/x-www-form-urlencoded

operation=write&country=$(id>/tmp/out)

修复建议

TP-Link 已发布固件版本 1.1.4 Build 20230219,通过删除易受攻击的回调来修复此问题。

参考文献

https://www.tenable.com/security/research/tra-2023-11
https://blog.csdn.net/weixin_43487849/article/details/126281966
https://skowronski.tech/2021/02/hacking-into-tp-link-archer-c6-shell-access-without-physical-disassembly/
https://vovohelo.medium.com/unscrambling-lua-7bccb3d5660
https://openpunk.com/journal/stripping-lua-protos
https://blog.ihipop.com/2018/05/5110.html
https://www.brettlischalk.com/posts/tplink-tlwr810n-firmware-analysis
https://skowronski.tech/2021/02/hacking-into-tp-link-archer-c6-shell-access-without-physical-disassembly/
https://sourceforge.net/projects/unluac/
https://github.com/sztupy/luadec51
https://github.com/superkhung/luadec-tplink

声明:Hack All Sec的博客|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 一次失败的路由器固件分析——CVE-2023-1389分析及复现


Hacker perspective for security