pass-5-利用系统特性绕过

Windows利用系统本身的命名规则绕过:

先看一下利用Windows特性绕过

  1. 大小写绕过:针对对大小写不敏感的系统如 windows 例如test.PhP

  2. 以下为不符合规则的Windows文件

shell.php. 文件名后加 '.' 适用于上传的文件名没有被修改
shell.php空格 文件名后加空格
shell.php.空格. 文件名+'.'+空格+'.' 适用于上传的文件名没有被修改
shell.php:1.jpg 文件名后加冒号 适用于上传的文件名没有被修改
shell.php::$DATA 文件名加NTFS ADS特性::$DATA
shell.php::$DATA...... 文件名::$DATA.....

均会被windows系统自动去掉不符合规则符号后面的内容

ADS是nfts磁盘格式的一个特性,由于NTFS交换数据流,在上传文件时,如果系统对请求正文的filename匹配不当的话可能会导致绕过

上传的文件名 服务器表面现象 生成的文件内容
test.php:a.jpg 生成test.php
test.php::$DATA 生成test.php <?php phpinfo():?>
test.php::$INDEX_ALLOCATION 生成test.php文件夹
test.php::$DATA.jpg 生成0.jpg <?php phpinfo():?>
test.php::$DATA\aaa.jpg 生成aaa.jpg <?php phpinfo():?>

在php环境下可以上传test.php::$DATA

参考:NTFS ADS的前世今生

Linux也可利用系统本身的命名规则绕过

linux命名规则

1、文件名最大长度为255

2、全路径长度最大为4096(16级最大文件长度)

3、区分大小写

4、除“/”之外所有字符都可以使用

5、linux不以文件扩展名区分文件类型,对linux来说一切皆文件。

image-20210804194600049

源码分析

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}
  1. 首先 trim( )函数 移除字符串两侧的空白字符

    • 假设上传test.php+空格,这时服务器获取到的后缀是.php+空格,该文件不再黑名单中,因此上传功。
    • 由于windows文件系统的特性,会去除后面的空格,导致test.php+空格=test.php
  2. deldot( ) 删除文件名末尾的点

    • 假设上传test.php.这时服务器获取到的后缀是,不在黑名单中,因此文件上传成功
    • 但是由于windows文件系统的特性导致test.php.=test.php
  3. strchr( $file_name,' . ')函数 是搜索.在文件名中的位置,并返回从该位置(包括此位置)到字符串结尾的所有字符

    • 从头开始,找到第一个满足的就开始截取

      image-20210804164206412

  4. strrchr( $file_name,' . ')函数 函数和3中的strchr不同,看看下面的图体会一下,源码用的此函数

    • image-20210804170943055
  5. str_ireplace('::$DATA', '', $file_ext)将::$DATA去掉

  6. 使用 trim($file_ext) 移除字符串两侧的空白字符

  7. 禁止上传如下后缀文件

image-20210804162706873

  1. 文件重命名文年月日星期+1000~9000+后缀名
  2. 上传成功

上传

分析上面的源码后,思路逐渐清晰,前两步尾部去点,去空格,第五步去::$DATA,对于windows来说算致命打击,但是转换没转换大小写,可以用test.PHp绕过windows系统

利用linux的特性,创建一个类似文件如test.\php可以绕过linux系统

image-20210804194605473

上传一个test.\php,看到上传的后缀名没了,所以上传的不是linux系统,而是windows系统

image-20210805104213653

因此利用windows不区分大小写特性来绕过

上传1.PHp

连接成功

image-20210805104522077

posted @ 2021-08-05 10:47  1ink  阅读(382)  评论(0编辑  收藏  举报