2019 浙江省大学生网络与信息安全竞赛-决赛 WriteUp
🏛️ 组织架构
指导单位:浙江省委网信办
主办单位:浙江省教育厅
承办单位:杭州电子科技大学
竞赛委员会:浙江省大学生网络与信息安全竞赛委员会
📊 赛事规模
参赛院校:全省 50 所高校
参赛队伍:共 269 支队伍报名(本科组 221 支,专科组 48 支)
决赛规模:100 支队伍(本科组 80 支,专科组 20 支)
决赛赛制:持续 8 小时的团体闯关解题模式
题目范围:涵盖 Web 安全、逆向分析、密码学、二进制漏洞挖掘等
Web
逆转思维(PHP 伪协议 + 文件包含 + 反序列化 __toString())

题目源代码
1 |
|
代码要求首先满足 isset($text) && file_get_contents($text, 'r') === "welcome to the zjctf"
也就是说,text 参数对应的内容必须严格等于 welcome to the zjctf
file_get_contents() 不仅可以读取普通文件,还可以读取 PHP 支持的伪协议
这里最方便的是使用 data:// 伪协议直接构造内容
1 | data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY= |
通过第一层判断后,代码进入
1 | if(preg_match("/flag/",$file)){ |
这里明显想阻止我们直接包含 file=flag.php,但是提示了 useless.php,我们通过第一层的伪协议去读取源码
在 PHP 中,当对象被当作字符串使用时,会自动触发 __toString()
1 |
|
如果传 file=useless.php,就会执行 include("useless.php");
这样 Flag 类就被加载进当前 PHP 运行环境。加载之后,程序继续执行
1 | $password = unserialize($password); |
这里的 echo $password; 会触发 __toString() 方法
只要我们把对象的 $file 属性设置为 flag.php,就可以读取 file_get_contents("flag.php")
最终 Payload:/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}