从ctfshow再看文件包含
最后更新时间:
文章总字数:
预计阅读时间:
从ctfshow看文件包含
之前对文件包含的认识总局限于伪协议(因为做题中最常见,通过伪协议来读取源码文件,然后再下一步),今天就借助ctfshow靶场的题总结一下常见的文件包含考法,更细更少见的姿势就在复现比赛题的时候再学习吧。
伪协议利用
PHP伪协议总结 - 个人文章 - SegmentFault 思否
最常用的就php://filter和data写入文件来过检测,至于那种直接可以执行php代码的,我感觉除了靶场也不会再出现了。
web78
1 |
|
最经典的?file=php://filter/convert.base64-encode/resource=flag.php
也可以利用这个filter来读取一些敏感的文件,通常为index.php等题目环境的源码,也有一些通用的敏感文件,说实话在目前这个阶段一次都没有用过,最多提权的时候要看一下这些文件。
windows:
1 | C:\boot.ini //查看系统版本 |
linux:
1 | /root/.ssh/authorized_keys |
可以使用绝对路径读取,也可以使用../来跳出目录限制读取,至于直接读到flag还是别想了。
远程文件包含
环境要求
- allow_url_fopen=On(默认为On) 规定是否允许从远程服务器或者网站检索数据
- allow_url_include=On(php5.2之后默认为Off) 规定是否允许include/require远程文件
如果可以远程文件包含,就可以先把一句话木马写到自己的服务器上,再通过http协议来包含进来。
注意包含的时候自己的服务器上一定要开一个php的web服务器!不然只是把文件包含了进来(写到了注释里),没有进行解析!
详见ctfshow web357
日志文件包含
日志文件包含首先必须要日志文件可以正常包含进来,通过file传入日志文件的路径(例如nginx日志文件路径是/var/log/nginx/access.log),如果可以看到日志信息就大概率可以进行包含。
通过在ua头写入一句话马,发送两次,再包含日志文件执行代码即可。
条件竞争
利用session.upload_progress进行文件包含和反序列化渗透 - FreeBuf网络安全行业门户
主要是通过PHP_SESSION_UPLOAD_PROGRESS加条件竞争来进行session文件包含,话不多说上脚本:
1 | import io |
这个脚本可解决web82-86
绕过死亡exit
web87
1 |
|
法一:利用base64编码
通过file传入php://filter/write=convert.base64-decode/resource=1.php
利用base64写入将原来的exit内容当base64解码,注意对齐位数,不然无法正确解码我们写入的马。
base64解码的时候会自动跳过无法识别的字符且四个一组识别。
插播一个关于base64的小知识点,web88,过滤了=号,但是我们的马base64结果有等号,这时候可以通过在?>后面加一些无关紧要的字符来使得base64的结果等号消失,其实也可以直接去掉等号,因为等号并不会影响base64的解析,解析的时候会自动删掉。
1 | payload:?file=%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%44%25%36%33%25%36%46%25%36%45%25%37%36%25%36%35%25%37%32%25%37%34%25%32%45%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%44%25%36%34%25%36%35%25%36%33%25%36%46%25%36%34%25%36%35%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%33%31%25%32%45%25%37%30%25%36%38%25%37%30 |
法二:利用rot13编码。
Rot13(rotate by 13 places)是一种简单的字符替换加密方法,加密和解密使用相同的算法,即对于给定的输入文本,将其应用于Rot13两次将返回原始文本。
条件是PHP不开启短标签,也就是<??>
并不会被识别为php。通过file传入php://filter/write=string.rot13/resource=3.php
,然后传已经rot13过一次的马,这样在写入文件的时候再rot13一次刚好就回到了原来的情况,而固定写入的exit只经过了一次rot13编码,从而失去效果。
为什么条件是不开启短标签呢,因为rot13只替换了字母,原来固定写入的exit依然具有<??>
,要是能被识别成php代码,就会报错,从而导致马无法正常解析。
1 | payload: |
其实还可以采用其他的编码格式来绕过,只要php://filter/write的过滤器支持就可以用,比如web117,过滤了base64和rot13,可以采用ucs-2编码
我们就可以借用convert.iconv过滤器,从而进行编码的转换,写入我们需要的代码,然后转换掉死亡代码,ucs-2编码本质和rot13一样,都是转两次就回到了原来的。
更好的是这个还没有rot13的限制条件,因为转换之后也不是短标签了,但是限制是需要php支持iconv,使用convert.iconv过滤器相当于使用iconv函数
1 | payload: |
参考链接:
https://blog.csdn.net/qq_46918279/article/details/120106832