The change to fix T318753, change 836235, causes the logo file to be uploaded to static/images/icon.<EXT>, where <EXT> is provided from the base64 string input, after the installer is successfully executed. This can be exploited to upload a web shell, as there is no check on the allowed file extension.
Is this actually an issue?
Yes.
This bug only affects the first-time installation. However, this is the only requirement. An attacker that locates a fresh, unconfigured MediaWiki instance can take over the server. The attacker does not need a database access (as they can use SQLite to set up MediaWiki), and they do not need a FTP access (while LocalSettings.php must be uploaded manually, the logo file is uploaded automatically during the final step).
I haven't tried a step-by-step reproduction (yet), and this is a code analysis based report. Please let me know how to download the changeset to my testing environment so that I can test.
Exploit
There are two ways to exploit this:
- Without path traversal: file is placed at static/images/icon.php (the file name after the dot can be controlled, but must not include a semicolon or a slash)
- Windows exclusive, with path traversal: file can be placed anywhere with any filename/extension.
No path traversal variant
This payload, if uploaded, drops icon.php containing <?php echo "Hi";: a/php;base64,PD9waHAgZWNobyAiSGkiOw==
This works if there is no configuration preventing PHP execution in images directory. The code in the patch automatically creates the static/images if missing, so it is likely that directory-scoped .htaccess does not exist.
Path traversal variant
This uses two behaviors observed in PHP 7.4 and Windows (did not test in PHP8.0 or 8.1):
- file_put_contents does not require that intermediate directories all exist, if traversed. nonexistent/../test.txt is always a valid path for writing, regardless of whether nonexistent directory actually exists.
- Instead of /, \ can be used as a directory separator. This bypasses the code's explode function that splits a MIME type.
This payload, if uploaded to Windows-running server, drops sh.php containing <?php echo "Hi"; to the current directory: a/a\..\..\sh.php;base64,PD9waHAgZWNobyAiSGkiOw==.
Other information
- CWE: CWE-434 (Unrestricted Upload of File with Dangerous Type)
- OWASP: A04/2021 (Insecure Design)
- Software: PHP7.4 (used to generate the payload), MediaWiki version: Change 836235 (NOT MERGED)
- CVE: Inapplicable (change is not merged to the repository)
- CVSS: 8.1 (High) - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
- Affects Wikimedia: No (change not merged or released)