这是一个反序列化缺陷,它利用了重置密码功能 (spip.php?page=spip_pass) 中对 #ENV 标签的危险使用,具体位于 /ecrire/balise/formulaire_.php 中的这一行:
function protege_champ($texte){
if (is_array($texte))
$texte = array_map('protege_champ',$texte);
else {
// ne pas corrompre une valeur serialize
if (preg_match(",^[abis]:\d+[:;],", $texte) AND unserialize($texte)!=false)
return $texte;
$texte = entites_html($texte);
$texte = str_replace("'","'",$texte);
}
return $texte;
}
protege_champ 函数存在多种缺陷。用于验证输入的正则表达式(RE)检查存在缺陷,很容易被绕过。代码在未进行适当验证的情况下调用了 unserialize() 函数,从而允许执行任意代码。手动利用极其容易。例如,如果我们想执行 phpinfo();,可以这样操作:
oubli=s:19:"<?phpinfo(); ?>";
如果服务器返回预期输出,则说明其存在漏洞。我们该如何修补?实际上相当简单。下面是我编写的一个基本补丁:
function protege_champ($texte) {
if (is_array($texte)) {
$texte = array_map('protege_champ', $texte);
} else {
if (!isValidInput($texte)) {
$texte = 'Malicious input detected';
} else {
$texte = entites_html($texte);
$texte = str_replace("'", "'", $texte);
}
}
return $texte;
}
修补后的 protege_champ() 函数包含了输入验证、清理以及对恶意输入的处理。