UPLAOD-LABS2

less7

任务

拿到一个shell服务器

提示

禁止上传所有可以解析的后缀

发现所有可以解析的后缀都被禁了

查看一下源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".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_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)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

第六关的源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".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 = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

通过源码我们发现,第七关少了删除文件名末尾的

 $file_name = deldot($file_name) //删除文件末尾的点

第七关没有对末尾的点进行一定的限制,那么就可以用了,在文件的末尾加上一个点看看

上传了3.php,然后在文件末尾加上一个点,文件上传成功

less8

提示

禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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后缀文件

源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".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 = strtolower($file_ext); //转换为小写
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

也是观察的源代码,发现没有对pHp6进行限制,就先上传一个看看,发现是可以的

这个显然有点勉强,从源代码着手看看

与第七关的代码对比一下,这一关没有字符串的限制

$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA

在文件的末尾加上::DATA看看eg 3.php::DATA

less9

ps

只允许上传.jpg|.png|.gif后缀的文件

源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".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 = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

发现它先将后缀名后的'.'删除,然后删除空格

先按照提示的上传jpg,是可以的上传的

从代码出发

只过滤了一次点,那么就用上两个点

"点+空格+点"过滤,抓包之后进行修改

eg

3.php. .

也是可以的

less10

ps

从文件名中去除.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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字符!

源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");

        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $file_name)) {
            $img_path = $UPLOAD_ADDR . '/' .$file_name;
            $is_upload = true;
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

file_name = str_ireplace(deny_ext,"", $file_name); //这段代码是去除黑名单里面的名称

换句话说就是文件后缀没有了,那么就可以双写绕过,后面也是试了一下pHp6也是可以的

less11

提示

本pass上传路径可控

源代码

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        }
        else{
            $msg = '上传失败!';
        }
    }
    else{
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}

1.$ext_arr = array('jpg','png','gif'); 这里使用了数组做了一个白名单,也就是只能上传这三种类型的 文件

2.file_ext = substr(_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);

截取文件名的后缀从点的位置开始截取,并且使用的是循环的方式截取,不是采用 一次性

对($_FILES['upload_file']['name']进行验证,也是对上面代码的进一步验证,限制文件的类型

  1. if(in_array(file_ext,ext_arr)){ 判断上传的文件名后缀是否在白名单中,如果在进入循环。

  2. $temp_file = $_FILES['upload_file']['tmp_name']; 进入循环,给上传的文件放在一个临时的目录下,并且生成一个临时文件名

5.$img_path = _GET\['save_path'\]."/".rand(10, 99).date("YmdHis").".".file_ext;(这一步是关键)

使用$_GET['save_path']接受自定义的路径,并且随机从10,99的数组在随机生成一个文件名,

在拼接上$file_Ext 前面截取的后缀名。

6.(move_uploaded_file(temp_file,img_path)){

最终将前面保存的temp_file临时文件移动 到img_path

借鉴一下其他师傅的

原理 :

00截断利用的是php的漏洞,php的基础是C语言实现的,在C语言中认为%00是结束的符号,所以就基础了c的特性,在PHP<5.3.4的版本中,在进行存储文件时碰见了move_uploaded_file这个函数的时候,这个函数读取到hex值为00的字符,认为读取结束,就终止了后面的操作,出现00截断

绕过思路:

首先使用的是白名单,从代码中可以看出他首先对上传的文件名的后缀进行了验证。

所以在第一步上传$_FILES['upload_file']['name'],文件名的时候必须后缀是.jpg.png.gif的格式。绕过后缀名的验证后,进入到循环。最后重点他保存的文件是

$img_path = _GET\['save_path'\]."/".rand(10, 99).date("YmdHis").".".file_ext;,由上传路径决定的,原参数$_GET['save_path'],save_path=../upload/。 那么上传路径可控的 。我们就使用%00截断,把上传的路径修改为文件名。最后利用move_uploade_file这个函数发挥出%00截断的功能。

假如我们没有使用%00截断前最终上传的文件名可能是

../upload/ 237298 .png

$_GET['save_path'] rand(10, 99).date("YmdHis") $file_ext;

使用%00截断后

../upload/1.php%00 237298 .png

$_GET['save_path'] rand(10, 99).date("YmdHis") $file_ext;

最后 保存的文件就变成了

../upload/1.php

因为到%00后面的结束了

思路就是要先上传.php类型的 然后%00截断路径,就可以上传成功

less12

提示还是路径可控

源代码

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        }
        else{
            $msg = "上传失败";
        }
    }
    else{
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}

与上一关的差不多,就下面的地方不同

$img_path = _GET\['save_path'\]."/".rand(10, 99).date("YmdHis").".".file_ext;

$img_path = _POST\['save_path'\]."/".rand(10, 99).date("YmdHis").".".file_ext;

POST方法较为特殊,直接在明文中添加%00不会被服务器解码,得将%00进行url编码后再提交

服务器会自动解码

save_path"=../upload/4.php%00

选中%00进行编码

less13

提示

本pass检查图标内容开头2个字节

源代码

function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //只读2字节
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);    
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    
    $fileType = '';    
    switch($typeCode){      
        case 255216:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';
        }    
        return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "文件未知,上传失败!";
    }else{
        $img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        }
        else{
            $msg = "上传失败";
        }
    }
}

检查的是文件头部信息,通过检查文件的前2个字节,检查上传文件二进制的头部信息,来进行判断文件的类型。所以这一关修改后缀是没有用的

使用图片码进行绕过

第一种方法

将图片用编辑器打开,在最后加上<?php phpinfo();?>,图片还是可以正常打开的

第二种方法

准备好一张图片和一句话木马php文件,将其放在桌面上使用命令去合成

copy 1.png/b + 2.php/a 3.png

做好就可以直接上传,显示上传成功

less14

提示

本pass使用getimagesize()检查是否为图片文件

源代码

function isImage($filename){
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
        $info = getimagesize($filename);
        $ext = image_type_to_extension($info[2]);
        if(stripos($types,$ext)){
            return $ext;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $res = isImage($temp_file);
    if(!$res){
        $msg = "文件未知,上传失败!";
    }else{
        $img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").$res;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        }
        else{
            $msg = "上传失败";
        }
    }
}

首先知道函数的意思

getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息

复制代码
array getimagesize ( string $filename [, array &$imageinfo ] )

getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽

$info = getimagesize($filename);

如果上传的文件是php格式就得不到图片的尺寸,就会返回错误,后面的代码就无法执行,文件就没办法成功上传

结合任务

上传一个图片马到服务器,所以上传刚刚做好的图片码看看

include.php?file=/upload/图片的链接,就可以查看了

less15

提示

本pass重新渲染了图片

源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径
    $filename = $_FILES['upload_file']['name'];
    $filetype = $_FILES['upload_file']['type'];
    $tmpname = $_FILES['upload_file']['tmp_name'];

    $target_path=$UPLOAD_ADDR.basename($filename);

    // 获得上传文件的扩展名
    $fileext= substr(strrchr($filename,"."),1);

    //判断文件后缀与类型,合法才进行上传操作
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //使用上传的图片生成新的图片
            $im = imagecreatefromjpeg($target_path);

            if($im == false){
                $msg = "该文件不是jpg格式的图片!";
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                $newimagepath = $UPLOAD_ADDR.$newfilename;
                imagejpeg($im,$newimagepath);
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = $UPLOAD_ADDR.$newfilename;
                unlink($target_path);
                $is_upload = true;
            }
        }
        else
        {
            $msg = "上传失败!";
        }

    }else if(($fileext == "png") && ($filetype=="image/png")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //使用上传的图片生成新的图片
            $im = imagecreatefrompng($target_path);

            if($im == false){
                $msg = "该文件不是png格式的图片!";
            }else{
                 //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".png";
                $newimagepath = $UPLOAD_ADDR.$newfilename;
                imagepng($im,$newimagepath);
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = $UPLOAD_ADDR.$newfilename;
                unlink($target_path);
                $is_upload = true;               
            }
        }
        else
        {
            $msg = "上传失败!";
        }

    }else if(($fileext == "gif") && ($filetype=="image/gif")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //使用上传的图片生成新的图片
            $im = imagecreatefromgif($target_path);
            if($im == false){
                $msg = "该文件不是gif格式的图片!";
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".gif";
                $newimagepath = $UPLOAD_ADDR.$newfilename;
                imagegif($im,$newimagepath);
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = $UPLOAD_ADDR.$newfilename;
                unlink($target_path);
                $is_upload = true;
            }
        }
        else
        {
            $msg = "上传失败!";
        }
    }else{
        $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
    }
}

这个函数的主要功能就是,使用上传的图片去生成一张新的图片,生成的结果会返回一个变量,

成功返回ture,失败返回false。并且这个函数,可以在他进行重新创建图片的时候,会将我们图片的信息和非图片的信息进行分离,也就是说如果我们在一张图片中加入了代码,那么他会 在你上传后把这张图片在新建的时候把其中的代码筛选出来,并且去除。最后只保留你的图片信息,在进行排序重建。

图片的二次渲染的操作就是在imagecreatefrom这里进行的

图片码也是可以的,后面这道题是要重新看看的

less17

提示

需要代码审计

源代码

$is_upload = false;
$msg = null;

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_ADDR . '/' . $file_name;

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

解析

创建了一个只包含图片文件的白名单,随后提取出文件的后缀名,将文件移动至上传目录后再判断是否合法 ,不合法就删除。我们可以使用条件竞争方法(即在文件被删除之前访问该文件 )绕过。此方法需要不停且迅速地上传、访问文件。我们使用BurpSuite和Python进行上传和访问

相关推荐
青い月の魔女25 分钟前
数据结构初阶---二叉树
c语言·数据结构·笔记·学习·算法
网络安全(king)26 分钟前
网络安全攻防学习平台 - 基础关
网络·学习·web安全
qq_5895681033 分钟前
node.js web框架koa的使用
笔记·信息可视化·echarts
Hacker_Nightrain1 小时前
网络安全与加密
安全·web安全
stm 学习ing1 小时前
HDLBits训练6
经验分享·笔记·fpga开发·fpga·eda·verilog hdl·vhdl
stm 学习ing2 小时前
HDLBits训练4
经验分享·笔记·fpga开发·课程设计·fpga·eda·verilog hdl
炸毛的飞鼠2 小时前
汇编语言学习
笔记·学习
风无雨2 小时前
react杂乱笔记(一)
前端·笔记·react.js
胡西风_foxww2 小时前
【ES6复习笔记】Class类(15)
javascript·笔记·es6·继承··class·静态成员
网安墨雨3 小时前
浅谈TARA在汽车网络安全中的关键角色
网络·web安全·汽车