[N1CTF 2018]eating_cms parse_url函数漏洞

进入就是一个登陆界面,随便输入一个账号密码抓包看看

发现有数据库语句,便试试万能密码

1'or'1'='1'#

 发现被过滤了,一般这种题有个register.php和一个地方可以读取到源码的,我们要寻找试试

发现有注册界面,注册登陆一下

 发现进入一个user.php页面,翻一下没有跟我们输入有关的回显,我们关注到有个page参数,不知道可不可以帮助我们读取到源码,直接伪协议试试

?page=php://filter/read=convert.base64-encode/resource=user.php

发现返回的是200,但是没有内容,说明读取的文件格式或许有问题,我们试试把后缀删了瞅瞅

 读取到源码,全部下载下来

没有upload.php,这个源码是后面要用的,这里不清楚(懒得删了) 

在user.php的源码界面找到我们能够读取源码的地方

果然是自己拼接了.php后缀,不过关注点不在这里

将源码看了一遍后大概理清楚

function Filter($string)
{
    global $mysqli;
    $blacklist = "information|benchmark|order|limit|join|file|into|execute|column|extractvalue|floor|update|insert|delete|username|password";
    $whitelist = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'(),_*`-@=+><";
    for ($i = 0; $i < strlen($string); $i++) {
        if (strpos("$whitelist", $string[$i]) === false) {//$string字符传必须是可见字符 strpos函数查找$string字符串在白名单中的位置
            Hacker();
        }
    }
    if (preg_match("/$blacklist/is", $string)) {//通过白名单后,也要通过黑名单
        Hacker();
    }
    if (is_string($string)) {//字符串
        return $mysqli->real_escape_string($string);//防止SQL攻击,进行转义
    } else {
        return "";
    }
}

一个非常强大的过滤,在登陆和注册界面都调用了,因此暂时不用考虑sql注入了,可疑点

function filter_directory()//过滤
{
    $keywords = ["flag","manage","ffffllllaaaaggg"];
    $uri = parse_url($_SERVER["REQUEST_URI"]);//解析url并解析组成部分
    parse_str($uri['query'], $query);//将查询字符串解析到变量中,query是数组名 $uri['query']代表的是传入参数
//    var_dump($query);
//    die();
    foreach($keywords as $token)
    {
        foreach($query as $k => $v)
        {
            if (stristr($k, $token))//查找$k是否在$token出现
                hacker();
            if (stristr($v, $token))
                hacker();
        }
    }
}

 parse_url函数

对url进行解析,并且利用parse_str函数将传入的键值对当作关联数组传入$query数组,进行过滤没有$kewords才不会出来hacker();突破点就在这了,flag我还可以理解,但是后面两个我们看源码的时候怎么会用到,估计就是提示我们了,利用之前的include拼接读取源码,但是这里有个过滤需要绕过;幸运的是查询parse_url函数作用的时候跳出来了一个漏洞详情,我们便去看看

parse_url函数的解释和绕过_q1352483315的博客-CSDN博客_urlparse函数

可以猜想parse_url函数是利用一些特殊符号来分割不同属性的,如: / ?等 

如果我们在path那里构造成两个//,第一个被解析为根目录,第二个/user就会报错flase了,与分割url方法不符,因此可以构造成

//user.php?page=php://filter/convert.base64-encode/resource=ffffllllaaaaggg

可以让parse_url函数报错(低版本的了)

 继续读取

 发现包含了一个什么文件,我们直接进入url瞅瞅,发现是一个上传文件

利用之前的读取源码瞅瞅

<?php
$allowtype = array("gif","png","jpg");
$size = 10000000;
$path = "./upload_b3bb2cfed6371dfeb2db1dbcceb124d3/";
$filename = $_FILES['file']['name'];
if(is_uploaded_file($_FILES['file']['tmp_name'])){
    if(!move_uploaded_file($_FILES['file']['tmp_name'],$path.$filename)){
        die("error:can not move");
    }
}else{
    die("error:not an upload fileï¼");
}
$newfile = $path.$filename;
echo "file upload success<br />";
echo $filename;
$picdata = system("cat ./upload_b3bb2cfed6371dfeb2db1dbcceb124d3/".$filename." | base64 -w 0");
echo "<img src='data:image/png;base64,".$picdata."'></img>";
if($_FILES['file']['error']>0){
    unlink($newfile);
    die("Upload file error: ");
}
$ext = array_pop(explode(".",$_FILES['file']['name']));
if(!in_array($ext,$allowtype)){
    unlink($newfile);
}
?>

 发现跟我们平常不一样的是:不是讲图片内容保存在哪个目录下面去,而是利用system命令进行cat打开我们传入的$filename文件名并且base64文件内容,然后输出一个字符串,后面过滤了必须要gif,png,jpg为后缀,我们抓包修改就行了,随便传一个图片看看效果

明显输出,我们可以看到linux命令的操作通道符

我们利用分号来进行闭合前面命令,在输入我们需要的命令,然后注释后面的

 进行ls /查看上级目录 

发现没用,可能是空格或者斜杠被过滤了,利用/**/代替空格还是如此,看来是斜杠被过滤了

如何返回上一级,因为有;的存在,我们可以先执行cd ..,再来ls,达到返回上一级的效果 

接着cat flag文件即可 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值