记:暑期记录BUU刷题小日记,记录一下解题过程的同时与大家分享交流
启动靶场
进来就是大标题,Can you guess it?
什么人啊,我不要面子的吗?让我猜我就猜,属时有点小讨厌(你觉得呢?)
这里我尝试了几个常用查询语句,毫无办法(猜不出来)
例如:admin,admin123,hack,hacker等
这里提交查询后,会进行一个跳转到index.php目录中
现在查看源码,可以看见href跳转链接,进入链接后即可看见源码
------当然了,在最开始的提交查询页面,有Source的超链接(早点击一下,少走十年弯路)这里点了链接,只能知道源代码,还是需要提交查询,获得Index.php目录(index.php信息很关键,后面需要使用)
------平时做题目时,特别是方向不明确时,不要过于执着一个方向去解,可能是条死胡同,先把所有的方向都观察一下,再去细细研究
进入源代码的审计
<?php
include 'config.php'; // FLAG is defined in config.php
if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
exit("I don't know what you are thinking, but I won't let you read it :)");
}
if (isset($_GET['source'])) {
highlight_file(basename($_SERVER['PHP_SELF']));
exit();
}
$secret = bin2hex(random_bytes(64)); //这后面看着都很高级,但对我们来说没用,从前面即可获得flag
if (isset($_POST['guess'])) {
$guess = (string) $_POST['guess'];
if (hash_equals($secret, $guess)) {
$message = 'Congratulations! The flag is: ' . FLAG;
} else {
$message = 'Wrong.';
}
}
?>
看提示说是flag在config.php里,现在就是要考虑如何访问
我试了试直接访问
------家人们,到这里特别接近Flag,说明我们思路是正确
------这里我有些迷茫了,有的函数不认识
函数解析
1.preg_match()
preg_match()函数来执行一个正则表达式匹配操作
preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])
函数来执行一个正则表达式匹配操作,目的是检查当前请求的PHP脚本文件名(通过
$_SERVER['PHP_SELF']
获取)是否以config.php
结尾,同时允许config.php
后面紧跟任意数量的斜杠(/
),但斜杠是可选的。小知识课堂:
1.点(
.
)在正则表达式中是特殊字符,用于匹配除换行符以外的任何单个字符。因此,这里使用反斜杠(\
)对点进行转义,以匹配实际的点字符。2.斜杠(/)是正则表达式的定界符之一,因此当需要匹配斜杠字符时,需要使用反斜杠进行转义。
3.(*)在正则表达式中,
*
是一个量词,表示前面的元素可以出现0次或多次
4.($)
:这个符号表示字符串的末尾。它确保匹配发生在字符串的结束处。
2.$_SERVER['PHP_SELF']理解
$_SERVER['PHP_SELF']
不是一个函数,而是一个超全局变量(superglobal variable),它在 PHP 中用于获取当前正在执行脚本的文件名。
echo $_SERVER['PHP_SELF'];
这将输出当前脚本的路径和文件名(不包含查询字符串)。
例如,如果你的脚本位于
http://example.com/test/myscript.php
,那么echo $_SERVER['PHP_SELF'];
将输出/test/myscript.php
3.basename()
basename()
函数会返回路径中的文件名部分 假如路径是/index.php/config.php 浏览器的解析结果都是index.php 而basename会返回config.php 就算后面跟上多余的字符也会返回文件名部分。(个人理解是:输出网址目录的最后一个文件名,丢掉其他复杂的内容)
例如:
var_dump(basename("\xfconfig.php")); // => config.php var_dump(basename("config.php/\xf")); // => config.php
函数都理解的差不多了,感觉很快就能得到flag
开始构建upload(这样还不能获得Flag)
/index.php/config.php/?source
结果如图(没有获取flag,是否些许伤心呢?)
------问题出在basename函数上
basename()函数漏洞
basename()函数会返回路径中的文件名部分,但是它会去掉文件名开头的非ASCII值!
------用不可显字符绕过正则(后面加 %80 – %ff 的任意字符)
构建真正upload(包真的,比珍珠还真,家人们留个赞赞,支持一下,清风万分感谢)
/index.php/config.php/%ff?source
成功获取Flag
知识点小结:
1.$_SERVER['PHP_SELF']
不是一个函数,而是一个超全局变量(superglobal variable),它在 PHP 中用于获取当前正在执行脚本的文件名。
2.basename()
函数会返回路径中的文件名部分
3.basename()函数漏洞绕过使用不可回显字符,(后面加%80-%ff的任意字符)
4.preg_match()函数正则匹配时细小知识点,点(.)斜杠(/)反斜杠(\) 量词(*)等是否有印象
我清风 与诸君共勉,共创辉煌篇章。