• 【文件上传漏洞绕过方式】


    目录

    前言

    正文

    总结


    前言

      目前,文件上传往往在业务中不可避免,也是极其容易出现上传漏洞。根据owasptop10中的排名,文件上传漏洞(属于攻击检测和防范不足)高居其中。今天和大家分享常见的文件上传的绕过方式。

    正文

     绕过方式一:前端绕过

     首先,根据前端页面队上传文件的过滤来看,过滤主要是根据如下的JS代码实现:

    1. function checkFile() {
    2. var file = document.getElementsByName('upload_file')[0].value;
    3. if (file == null || file == "") {
    4. alert("请选择要上传的文件!");
    5. return false;
    6. }
    7. //定义允许上传的文件类型
    8. var allow_ext = ".jpg|.png|.gif|.php";
    9. //提取上传文件的类型
    10. var ext_name = file.substring(file.lastIndexOf("."));
    11. //判断上传文件类型是否允许上传
    12. if (allow_ext.indexOf(ext_name + "|") == -1) {
    13. var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
    14. alert(errMsg);
    15. return false;
    16. }
    17. }

    这种我们就可以采用这些方式绕过:1. 删除浏览器事件;2.burpsuite 抓包修改文件后缀名绕过;3.构造本地上传表单绕过。4.浏览器禁止JS运行(相当于删除了浏览器事件)。

    删除浏览器事件

    浏览器禁止JS运行

    burp suite抓包修改数据

    绕过方式二:黑名单绕过

     首先看一看过滤的一些关键代码:

    1. $is_upload = false;
    2. $msg = null;
    3. if (isset($_POST['submit'])) {
    4. if (file_exists(UPLOAD_PATH)) {
    5. $deny_ext = array('.asp','.aspx','.php','.jsp');
    6. $file_name = trim($_FILES['upload_file']['name']);
    7. $file_name = deldot($file_name); //删除文件名末尾的点
    8. $file_ext = strrchr($file_name, '.'); //将.和后面的内容显示出来
    9. $file_ext = strtolower($file_ext); //转换为小写
    10. $file_ext = str_ireplace('::$DATA', '', $file_ext); //去除字符串::$DATA
    11. $file_ext = trim($file_ext); //去掉前后的空格
    12. if(!in_array($file_ext, $deny_ext)) {
    13. $temp_file = $_FILES['upload_file']['tmp_name'];
    14. $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
    15. if (move_uploaded_file($temp_file,$img_path)) {
    16. $is_upload = true;
    17. } else {
    18. $msg = '上传出错!';
    19. }
    20. } else {
    21. $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
    22. }
    23. } else {
    24. $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    25. }
    26. }

    从上述代码中可以看出来:在代码层面上,通过黑名单的方式过滤了后缀名为:asp、aspx、php、jsp 的文件。并且过滤了:大小写绕过、::$data绕过、空格绕过、点绕过方式。

    这种情况下,如果httpd.conf文件中存在如下的配置,那么我们就可以采用配置文件中允许的后缀名进行绕过:

    不允许上传.asp,.aspx,.php,.jsp后缀文件,但是可以上传其他任意后缀。比如说:.phtml .phps .php5 .pht,但如果上传的是.php5这种类型文件的话,如果想要被当成php执行的话,需要有个前提条件,即Apache的httpd.conf有如上述配置。

     

    绕过方式三:.htaccess文件绕过

    绕过方式二中,我们可以看出来,黑名单中过滤了许多的文件后缀。除了.htaccess后缀。.htaccess文件的作用是:.htaccess就是httpd.conf的衍生品,它起着和httpd.conf相同的作用。使用条件:1.mod rewrite 模块开启;2. /etc/apache2/apache2.conf 中设置AllowOverride ALL。

    .htaccess文件中写入任选如下内容:

    1. 方式一:AddType application/x-httpd-php .gif
    2. 方式二:
    3. "*.gif">
    4. SetHandler application/x-httpd-php #在当前目录下,如果匹配到.gif文件,则被解析成PHP代码执行
    5. AddHandler php5-script .gif #在当前目录下,如果匹配到.gif文件,则被解析成PHP代码执行

    成功绕过:

     绕过方式四:文件后缀名绕过

    文件后缀名 绕过有如下的几种方式:1. 大小写绕过;2.空格绕过;3. 使用符号.绕过;4.使用::$DATA绕过;5. 双写文件后缀名绕过。

    过滤代码可以参考黑名单过滤代码。让绕过实现:

     

     

     

    绕过方式五:利用apache解析漏洞绕过

    Apache 从右向左解析,遇到不认识的文件名会跳过。比如 muma.php.xx.jpg,看似是一个jpg文件,但是交到apache进行处理的时候,apache找不到.php后缀名的文件,所以,apache会从右向左一个一个剥离,直到找到了.php文件。然后才交给php处理。 

     

    绕过方式六:%00截断绕过

    过滤方式:使用白名单过滤:

    1. $is_upload = false;
    2. $msg = null;
    3. if(isset($_POST['submit'])){
    4. $ext_arr = array('jpg','png','gif');
    5. $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    6. if(in_array($file_ext,$ext_arr)){
    7. $temp_file = $_FILES['upload_file']['tmp_name'];
    8. $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
    9. if(move_uploaded_file($temp_file,$img_path)){
    10. $is_upload = true;
    11. } else {
    12. $msg = '上传出错!';
    13. }
    14. } else{
    15. $msg = "只允许上传.jpg|.png|.gif类型文件!";
    16. }
    17. }

    绕过前提:php版本小于5.3.29,且php.int 内的magic_quotes_gpc为关闭状态。原理是:我们上传 1.php%00.jpg 时,首先后缀名是合法的jpg格式,可以绕过前端的检测。上传到后端后,后端判断文件名后缀的函数会认为其是一个.jpg格式的文件,可以躲过白名单检测。但是在保存文件时,保存文件时处理文件名的函数在遇到%00字符认为这是终止符,于是丢弃后面的 .jpg,于是我们上传的 1.php%00.jpg 文件最终会被写入 1.php 文件中并存储在服务端。

    get请求方式如下:

    post请求方式如下:

    写入这个后,我们需要将%00转码后再进行转发,选择%00后点击右键,按照图中所示转码

     绕过方式七:条件竞争绕过

    如果知道是先将文件存储后再判断后缀名,如果不在黑名单里面的话就保留,如果在黑名单里面的话就删除,因此可以利用特性进行条件竞争:

    首先:bp发送给Intruder,查看发送文件名字为shell.php,发送内容为:

    '); ?>

    以上一句话木马的意思是,如果该页面被人访问,会自动创建一个php文件到本目录里面。设置数据包无限重发:

    第二步:在burpsuite重放数据包之前,打开python脚本运行,脚本代码如下所示:

    1. import requests //导入request模块
    2. url = "http://127.0.0.1/upload/upload/shell.php" // 指定url
    3. while True: //使用while循环多次发送请求
    4. html = requests.get(url) //通过get方式请求url
    5. if html.status_code == 200: //进行if判断:如果返回的状态码是200 就终端循环
    6. print("OK,request is final")
    7. break
    8. else:
    9. print("NO,again request")

    第三步:运行脚本,并开始重放攻击:

     绕过方式八:文件内容绕过

      我们可以再文件头部中添加一些用来描述如图片特性的特征值,将这些特征值用来伪装php文件。

    1. function getReailFileType($filename){
    2. $file = fopen($filename, "rb");
    3. $bin = fread($file, 2); //只读2字节
    4. fclose($file);
    5. $strInfo = @unpack("C2chars", $bin);
    6. $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
    7. $fileType = '';
    8. switch($typeCode){
    9. case 255216:
    10. $fileType = 'jpg';
    11. break;
    12. case 13780:
    13. $fileType = 'png';
    14. break;
    15. case 7173:
    16. $fileType = 'gif';
    17. break;
    18. default:
    19. $fileType = 'unknown';
    20. }
    21. return $fileType;
    22. }
    23. $is_upload = false;
    24. $msg = null;
    25. if(isset($_POST['submit'])){
    26. $temp_file = $_FILES['upload_file']['tmp_name'];
    27. $file_type = getReailFileType($temp_file);
    28. if($file_type == 'unknown'){
    29. $msg = "文件未知,上传失败!";
    30. }else{
    31. $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
    32. if(move_uploaded_file($temp_file,$img_path)){
    33. $is_upload = true;
    34. } else {
    35. $msg = "上传出错!";
    36. }
    37. }
    38. }

    绕过方法:1.图片木马;2.添加图片特征值。

    制作图片木马:

    copy 1.php/a + xiaozhupeiqi.jpg/b muma.jpg

    添加特征值,如再1.php中添加:GIF89a,这gif图片的特征值。

    总结

      未知攻焉知防。最后给大家推荐几个在线练习文件上传漏洞的靶场。瑞斯拜!!!

    My Upload

    upload-labs

  • 相关阅读:
    MATLAB学习
    sklearn机器学习——day13
    过滤数据、只要数值型数据,问题与解决
    C语言中可变参数函数的实现——printf
    UGeek大咖说 | 顺丰科技:全链路压测中的可观测性实践
    1.填空题 进制转换Oct.2023
    B. Trouble Sort
    汉字风格迁移篇--SAFont:使用自我注意机制的自动字体合成
    Java枚举(Enum)的使用
    Spring源码编译一次性通过遇到问题如何解决?
  • 原文地址:https://blog.csdn.net/qq_55213436/article/details/126091664