Page MenuHomePhabricator

Change 836235 to MediaWiki allows web-shell upload during installation/"installer race"
Closed, InvalidPublicSecurity

Description

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.

NOTE: as of the submission date of this report, the change is not merged. However due to the severity I am reporting this privately as a security bug.

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)

Details

Risk Rating
Informational
Author Affiliation
Wikimedia Communities

Event Timeline

Mstyles changed Risk Rating from N/A to Medium.

The change in question was abandoned. Can this bug be closed and made public?

sbassett moved this task from In Progress to Frozen on the Security-Team board.
sbassett subscribed.

The change in question was abandoned. Can this bug be closed and made public?

Yes. I'd agree there's value in making this public so as to inform and have folks avoid this potential scenario in the future.

sbassett triaged this task as Lowest priority.Nov 14 2022, 4:56 PM
sbassett changed Author Affiliation from N/A to Wikimedia Communities.
sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".
sbassett changed the edit policy from "Custom Policy" to "All Users".
sbassett changed Risk Rating from Medium to Informational.
sbassett added a project: SecTeam-Processed.