本文最后更新于17 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
一、访问网站
检查一下源代码
发现一个php文件
二、访问php文件
发现一个hint.php,访问一下,发现flag在ffffllllaaaagggg文件里

三、分析代码
1.$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
给出了白名单,是source.php 和 hint.php
2.(in_array($page, $whitelist))
用于检测$page
是不是$whitelist
中的一个值,因为payload不会只有白名单中的一个值,所以无法满足
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
mb_strpos函数: 查找字符串在另一个字符串中首次出现的位置
mb_strpos ($haystack , $needle , $offset )
$haystack:被搜索的字符串
$needle: 要查找的字符串
$offset: 可选参数,指定从哪个字符开始搜索
//如果为正数,则从字符串的开头开始计算;如果是负数,则从字符串的末尾开始计算
//没有的话默认是0,即从开头开始搜索
mb_substr函数: 从一个字符串中提取子字符串
mb_substr ($str , $start , $length )
//substr() 函数只针对英文字符,而mb_substr()对于中文也适用
$str: 原始字符串
$start: 起始位置,如果为正数,则从字符串的开头开始计算;如果是负数,则从字符串的末尾开始计算
$length: 可选参数,表示要提取的子字符串的长度,如果没赋值,则提取从开始到字符串结束的所有字符
在这里,它将 $page
变量的值和一个问号字符 ‘?’ 连接在一起,形成一个新的字符串,在这个新的字符串中查找问号是否存在,如果存在就会截取?前面的字符串赋予给$_page
4.(in_array($_page, $whitelist))
对$_page
进行检测
结合起来发现,只需要传入一个在白名单内的文件名(source.php或者hint.php)并在后面加上问号?就可以保证在第二次if(in_array($_page, $whitelist))
匹配查找的内容在白名单,返回true,退出checkfile方法
四、构造payload
?file=source.php?/ffffllllaaaagggg
输入,页面没有回显,尝试进行目录穿越
?file=source.php?/../../../../ffffllllaaaagggg
成功获取flag
总结
- 文件包含
- 目录穿越
- in_array函数:匹配输入是否在名单中,不能多不能少
- mb_strpos函数: 查找字符串在另一个字符串中首次出现的位置
- mb_substr函数: 从一个字符串中提取子字符串