catalog
1. 漏洞描述 2. 漏洞触发条件 3. 漏洞影响范围 4. 漏洞代码分析 5. 防御方法 6. 攻防思考
1. 漏洞描述
Metinfo系统是基于PHP+MYSQL的信息发布系统,该系统存在逻辑缺陷导致条件注入,可修改任意管理员信息
Relevant Link:
2. 漏洞触发条件
从save_met_cookie()中可以看出,此处可执行任意sql语句。正好此处为update的met_admin_table表,所以可直接修改任意用户密码等任意操作了。
比如修改密码,只需要利用met_cookie_filter[]=’,admin_pass=密码 where admin_id=1#即可
3. 漏洞影响范围
Metinfo <=5.3
4. 漏洞代码分析
/admin/include/common.inc.php
.. //$met_cookie第一次赋值给$met_cookie_filter变量,相当于初始化 $met_cookie_filter=$met_cookie; foreach(array(‘_COOKIE‘, ‘_POST‘, ‘_GET‘) as $_request) { //通过foreach注册GPC变量,导致可以重新覆盖$met_cookie_filter变量 foreach($$_request as $_key => $_value) { $_key{0} != ‘_‘ && $$_key = daddslashes($_value,0,0,1); $_M[‘form‘][$_key]=daddslashes($_value,0,0,1); } } $met_cookie=array(); //又通过$met_cookie=$met_cookie_filter变量赋值,导致$met_cookie变量可控 $met_cookie=$met_cookie_filter; ..
继续跟进daddslashes函数的全局过滤,/admin/include/global.func.php
/*POST变量转换*/ function daddslashes($string, $force = 0 ,$sql_injection =0,$url =0) { !defined(‘MAGIC_QUOTES_GPC‘) && define(‘MAGIC_QUOTES_GPC‘, get_magic_quotes_gpc()); if(!MAGIC_QUOTES_GPC || $force) { if(is_array($string)) { foreach($string as $key => $val) { $string[$key] = daddslashes($val, $force); } } else { $string = addslashes($string); } } if(is_array($string)) { if($url) { //$string=‘‘; foreach($string as $key => $val) { $string[$key] = daddslashes($val, $force); } } else { foreach($string as $key => $val) { $string[$key] = daddslashes($val, $force); } } } else { //当SQL_DETECT不为1或者sql_injection为1时,进入字符的过滤,此时会转义单引号为\’ if(SQL_DETECT != 1 || $sql_injection == 1) { $string = str_ireplace("\"","/",$string); $string = str_ireplace("‘","/",$string); $string = str_ireplace("*","/",$string); $string = str_ireplace("~","/",$string); $url = str_ireplace("\"","/",$url); $url = str_ireplace("‘","/",$url); $url = str_ireplace("*","/",$url); $url = str_ireplace("~","/",$url); $string = str_ireplace("select", "\sel\ect", $string); $string = str_ireplace("insert", "\ins\ert", $string); $string = str_ireplace("update", "\up\date", $string); $string = str_ireplace("delete", "\de\lete", $string); $string = str_ireplace("union", "\un\ion", $string); $string = str_ireplace("into", "\in\to", $string); $string = str_ireplace("load_file", "\load\_\file", $string); $string = str_ireplace("outfile", "\out\file", $string); $string = str_ireplace("sleep", "\sle\ep", $string); $string = str_ireplace("where", "\where", $string); $string_html=$string; $string = strip_tags($string); if($string_html!=$string) { $string=‘‘; } $string = str_replace("%", "\%", $string); // } } return $string; }
这里漏洞的根源在于Metinfo进行了自定义的所谓的转义处理,但是却没有做到转义的完备性,缺少了对反引号的转义导致,如果攻击者同时输入"单引号"和"反引号",Metinfo只会对其中的"单引号"进行转义,导致出现"\\‘"这种结果,用于转义单引号的反斜杠被"吞噬"了,从而导致PAY重新获得攻击能力
我们继续回溯,寻找和$met_cookie变量的调用有关的利用点
/admin/include/global.func.php
function save_met_cookie() { global $met_cookie,$db,$met_admin_table; $met_cookie[‘time‘] = time(); //$met_cookie通过json_encode函数处理成$json,直接拼接到$query字符串 $json=json_encode($met_cookie); $username=$met_cookie[metinfo_admin_id]?$met_cookie[metinfo_admin_id]:$met_cookie[metinfo_member_id]; $username=daddslashes($username,0,1); //传入查询 $query="update $met_admin_table set cookie=‘$json‘ where id=‘$username‘"; $user=$db->query($query); }
json_encode函数会将\、\0之类的特殊字符转义,所以前面转议后的\’就变成\\’,刚好把\这个字符转义了,导致成功引入引号。这是注入的关键
以上可以看到,只需要在common.inc.php后引用这些函数,$met_cookie变量都会受到影响
5. 防御方法
/admin/include/common.inc.php
.. $met_cookie_filter=$met_cookie; foreach(array(‘_COOKIE‘, ‘_POST‘, ‘_GET‘) as $_request) { foreach($$_request as $_key => $_value) { $_key{0} != ‘_‘ && $$_key = daddslashes($_value,0,0,1); $_M[‘form‘][$_key]=daddslashes($_value,0,0,1); } } $met_cookie=array(); /**/ $met_cookie=addslashes(stripslashes($met_cookie_filter)); /**/ ..
6. 攻防思考
Copyright (c) 2015 LittleHann All rights reserved