Upload-labs靶场_第1~12关总结

Upload-labs靶场_第1~12关总结

前言

  本文章写第1关到12关的writeup,文章中的顺序是按照关卡所涉及到绕过技巧而进行排序,后面13至20关另开文章来总结。下载的靶场版本只有20关,现在有第21关。

Upload-labs靶场的过关方式不唯一,本文章仅供参考。若出现错误,请大佬纠正~

靶场介绍

来自于README.md文件的内容:
  upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。

靶场下载链接: https://github.com/c0ny1/upload-labs.

环境: Window2003作为服务器,集成环境phpStudy2018

Tip: php的版本不能太高,否则会导致某些关卡无法进行漏洞利用,博主是使用php的5.2.17版本,并且服务器是window2003并未在Linux环境下进行测试。

/* * * * * * * * * * * * 所使用的一句话木马 * * * * * * * * * * * */
<?php phpinfo(); @eval($_POST['shell']); ?>

第1至12关

Upload-labs靶场_第1~12关总结

前十二关所涉及的过滤技巧

客户端

  第1关中,在客户端,即浏览器,利用JavaScript语言来对用户上传的文件进行检测,因此这种机制较为容易攻击。
  在靶场第一关就给出该类型的文件上传漏洞:修改前端JS代码即可成功上传代码

Upload-labs靶场_第1~12关总结


服务端

一、黑名单过滤

1:在第3以及第4关中利用特殊后缀来进行绕过。

  1.1:第3关,后端服务器只过滤了四种常见后缀,因此可以利用php3或者php5后缀来上传木马文件,从而达到get shell。

Tip:
  靶场环境是由phpStudy所搭建而成,http-conf文件默认是注释掉php3,php5和phtml等后缀,因此服务端无法解析到这些后缀的文件(但能成功上传,却无法利用菜刀或者蚁剑连接,即getshell失败),所以需要修改配置文件。


学习链接:
https://blog.csdn.net/qq_43480081/article/details/102504348

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结

部分源码如下,完整源码请自行查看
...
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array('.asp','.aspx','.php','.jsp');
        $file_name = trim($_FILES['upload_file']['name']);
    ...
}

  1.2:而第4关利用.htaccess文件来使得upload文件夹中的所有文件都会以php的方式进行解析,因此把shell.php的后缀名改成shell.png,最终服务器都会将shell.png以php的方式进行解析

百度百科:
  .htaccess文件(或者"分布式配置文件"),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。

  1.2.1 先在本地编写.htaccess文件,文件内容如下,并且上传至服务器。上传成功后,上传木马文件,将后缀改成允许的后缀名即可利用工具来getshell。

	.htaccess文件内容:
	SetHandler application/x-httpd-php

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结

2:第5关大小写绕过

  2.1:从源码分析得出,虽有黑名单但未进行后缀名大小写转化,因此第5关利用大小写绕过来上传木马文件。

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结

部分源码如下,完整源码请自行查看
...
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = ... //黑名单数组
        $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)) {
            ...
        } else {
            ...
        }
    } else {
       ...
    }
}


3:第6关空格绕过

  3.1:从源码分析得出,虽有黑名单但未进行前后空格进行处理,因此第6关利用空格进行绕过。

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结

部分源码如下,完整源码请自行查看
...
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = ... //黑名单数组
        $file_name = $_FILES['upload_file']['name'];
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA

        if (!in_array($file_ext, $deny_ext)) {
            ...
        } else {
            ...
        }
    } else {
       ...
    }
}


4:第7关点绕过以及第9关的点空绕过

  4.1:从第7关的源码分析得出,虽有黑名单但未进行点进行处理,因此第7关利用点绕过。

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结

部分源码如下,完整源码请自行查看
...
...
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = ..黑名单数组
        $file_name = trim($_FILES['upload_file']['name']);
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            ...
        } else {
            ...
        }
    } else {.
  			...
    }
}

  4.2:从第9关的源码分析得出,可以利用点空来进行绕过,因为程序先处理字符串中最后一位点,再获取后缀名。

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结

部分源码如下,完整源码请自行查看
...
...
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = ..黑名单数组
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            ...
        } else {
            ...
        }
    } else {.
  			...
    }
}


5:第8关::$DATA绕过

  5.1:分析第8关的源码可以得出,程序再检验的时候并未对::$DATA进行过滤,因此可以利用Window文件系统NTFS的特性来进行绕过。(目的让服务器不检查后缀从而达到绕过的效果)

来自某位大佬的博客:
  这道题利用的是Windows下NTFS文件系统的一个特性,即NTFS文件系统的存储数据流的一个属性 DATA 时,就是请求 a.asp 本身的数据,如果a.asp 还包含了其他的数据流,比如 a.asp:lake2.asp,请求 a.asp:lake2.asp::$DATA,则是请求a.asp中的流数据lake2.asp的流数据内容。(小白的我还是懵懂,如果有大佬能通俗易懂地给我讲解一下,将感激不尽)

博客链接:https://www.jianshu.com/p/b1a130902b4e

Upload-labs靶场_第1~12关总结

Upload-labs靶场_第1~12关总结

部分源码如下,完整源码请自行查看
...
...
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = ... //黑名单数组
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            ...
        } else {
            ...
        }
    } else {.
  			...
    }
}


6:第10关双重后缀名绕过

  6.1:分析第10关的源码可以得知,程序将出现再黑名单数组中的字符串代替成空字符串,因此可以用双重后缀名来达到绕过效果,例如phPHPp替换字符串后变成了php。

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结

部分源码如下,完整源码请自行查看
...
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = ... //黑名单数组
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.$file_name;        
       ...
    } else {
        ...
    }
}


二、白名单过滤

1:修改头部中的MIME值。

  1.1:第2关,后端程序通过检测请求头部中MIME属性的值从而来判断用户上传的文件是否为图片。因此利用Burp Suite来修改Request中的MIME属性从而绕过检测。

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结

部分源码如下,完整源码请自行查看
...
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}


2:字符截断

  2.1:当读取到字符串的结束符的时候,字符串将会被认为处理完毕即使后面存在字符。比如在C语言当中字符串" abc\0123",当程序读取结束字符"\0"时,即认为字符串已经读取完毕从而停止继续读取,最终字符串为"abc\0"。在第11和12关中就是利用该特性,路径可控的情况下进行字符截断。

Tip:
  在这俩关中,需把php-in配置文件中的magic_quotes_gpc修改成Off才可以进行字符截断利用。magic_quotes_gpc在On的情况下,后端将会把输入的空字符即%00以及0x00进行转义,导致无法进行字符截断。

参考链接:https://www.cnblogs.com/timelesszhuang/p/3726736.html

  2.2:在第十一关中,Burp Suite抓取报文分析知道,可控路径是通过Get方式传递数据的,因此直接在url中进行截断。

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结

  2.2:第十二关和十一关类似,是以POST方式提交数据,因此利用Burp Suite的拦截功能来对请求头进行修改。

Upload-labs靶场_第1~12关总结
Upload-labs靶场_第1~12关总结


总结

  学习过程中,对于知识的总结很有必要,特别是知识面比较广以及多的情况下,否则会出现“提笔忘字”的情况。

上一篇:文件上传 Upload-labs (1 - 2关)


下一篇:get the emmc capacity in kernel