w20webshell之文件上传

  • 1.什么是文件上传?
    将本地文件传输到指定位置。
  • 2.什么是webshell
    给恶意脚本提供运行环境
  • 3.文件上传所需要的条件
    a.文件成功上传,未被删除
    b.知道文件路径
    c.文件所在系统支持脚本运行
  • 4.文件上传流程
    支持任意文件上传的文件上传
    a.恶意文件上传成功
    b.根据服务器返回的文件路径,进行访问
    c.根据访问结果判断文件所在系统是否支持脚本运行。
    限制文件类型的文件上传(可绕过客户端的情况)
    a.开启burpsuite工具和浏览器代理插件,进行抓包
    b.将伪装的恶意文件,进行后缀名修改回来
    c.对Content-Type进行修改。
    d.恶意文件上传成功
    e.根据服务器返回的文件路径,进行访问
    i.根据访问结果判断文件所在系统是否支持脚本运行。
  • 5.webshell有哪些
    菜刀、蚁剑、冰蝎

中国蚁剑

w20webshell之文件上传_第1张图片
以上是中国蚁剑的添加链接界面,可以看到连接类型可支持ASP、PHP、JSP、PHP4等。在文件上传的过程中,针对黑名单情况,就可以上传蚁剑支持的webshell文件。


w20webshell之文件上传_第2张图片
中国蚁剑编码器支持4种,当default测试连接失败的时候,可以换其他编码器


开始闯关文件上传靶场

一、实验环境

攻击工具:burpsuite2021.12、中国蚁剑
靶场:upload-labs
浏览器:google

二、实验目的
演示爆破文件上传,了解文件上传漏洞

三、实验步骤

1.Pass-01

w20webshell之文件上传_第3张图片
2.随意上传一个php脚本,试探一下,结果发现被拦截了
w20webshell之文件上传_第4张图片
3.此时还无法判断是前端拦截还是后端拦截,先假设是前端拦截,我们先从绕过客户端校验开始着手:思路1–禁用前端js;思路2–替换js;思路3–不调用前端的校验函数

思路1:
w20webshell之文件上传_第5张图片
思路2:
在index.php文件中发现校验函数,替换index.php。
w20webshell之文件上传_第6张图片
步骤1
  准备一个自己写的index.php,本文copy源index.php,然后修改允许上传类型
w20webshell之文件上传_第7张图片
  右键index.php,选中override content,然后选中存放index.php的文件夹,此时的index.php的路径要跟源文件的路径保持一致。
w20webshell之文件上传_第8张图片

结果
w20webshell之文件上传_第9张图片
4.此时我们可以得出:该文件上传利用的前端js进行校验,并且是校验文件的后缀名来识别文件类型,可通过以上方式绕过前端js校验。


1.Pass-02

w20webshell之文件上传_第10张图片
2.随意上传一个非图片类型的文件,比如1.txt文件,发现提示:文本类型不正确。此时的提示没有告知用户需要上传什么格式,但猜测应该是要求图片格式。
w20webshell之文件上传_第11张图片
3.我们可以试着将上传的文件修改后缀来试试,通过BP工具,修改1.png文件为1.txt,尝试能否绕过客户端校验,结果上传成功了。猜测可能对方是根据content-type来识别文件类型,为了验证猜想,上传1.txt文件修改content-type
w20webshell之文件上传_第12张图片
4.上传1.txt文件修改content-type,验证是否是根据content-type来识别文件类型。也上传成功,验证了猜想
w20webshell之文件上传_第13张图片


1.Pass-03 绕过黑名单之文件后缀

03实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
03源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array('.asp','.aspx','.php','.jsp');
        $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)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            
            if (move_uploaded_file($temp_file,$img_path)) {
                 $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

2.通过代码审计,不允许上传asp、aspx、php、jsp后缀的文件,尝试绕过校验的方式进行文件上传:上传一个包含 php代码的1.txt,通过bp工具,修改后缀名的方式尝试上传。结果上传失败。
w20webshell之文件上传_第14张图片
w20webshell之文件上传_第15张图片
3.修改为其他可运行的文件,比如php4、php5、phtml后缀,文件上传成功, 此时这些类型的文件,需要apache服务器,同时在配置文件夹中需要有AddType application/x-httpd-php .php .phtml .phps .php1 .php4 .pht 的命令,需要重启apache,访问php4的文件,结果被浏览器自动下载了。说明没有被解释成脚本语言。
w20webshell之文件上传_第16张图片

5.使用phpstudy2018,选择php5.2.17版本,然后继续上传php4文件,文件成功被解释。
w20webshell之文件上传_第17张图片
w20webshell之文件上传_第18张图片


1.Pass-04 绕过黑名单之.htaccess

04实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
04源码

w20webshell之文件上传_第19张图片

2.因此我们可以上传.htaccess文件,实现能够访问脚本文件、执行脚本即可。
.htaccess内容为:

#当服务器收到任意请求时,服务器会将其当作PHP脚本来处理,而不是直接将其作为静态图片返回给用户。

SetHandler application/x-httpd-php

w20webshell之文件上传_第20张图片
4.上传成功后,再上传ht.jpg文件,ht.jpg内的代码如下:


echo 'Pass-04 success';
?>

在这里插入图片描述


1.Pass-05 绕过黑名单之空格

05实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
05源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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 = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

2.由代码审计可知,不能使用Pass-04的解题方法进行.htaccess文件绕过,对于上传的文件名,先删除文件名末尾的点,然后首位去空,被过滤的文件类型有:

.php”,.php5”,.php4”,.php3”,.php2”,.html”,.htm”,.phtml”,.pht”,.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”

3.因此我们可构造出"05.php. .",因为代码只对文件末尾的’.‘和空格只处理一次,而且拼接后文件路径是时间+文件后缀,所以这种文件被代码处理后就是’时间.’
w20webshell之文件上传_第21张图片

4.成功上传,得到的文件可以直接被执行。(备注:基于.htaccess文件才行)
w20webshell之文件上传_第22张图片
5. 思路2,通过代码可以发现,并没有对后缀进行大小写限制,因此可以构造全大写的’05-02.PHP’,文件成功上传
在这里插入图片描述


1.Pass-06

06实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
06源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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 = $_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)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file,$img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

2.通过代码审计,可以发现对后缀名做了小写的处理,但是没有处理空格,因此可以构造 '06.php '。
w20webshell之文件上传_第23张图片
3.成功上传。
在这里插入图片描述


1.Pass-07

07实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
07源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

2.通过代码审计,发现该代码虽然对后缀做了小写和首尾去空的处理,但是strrchr($file_name, ‘.’); 会返回将第一个查到’.'的位置到字符串结尾的所有字符;这里我们可以构造 ‘07.php.’
w20webshell之文件上传_第24张图片

3.上传成功
在这里插入图片描述


1.Pass-08

08实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
08源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

2.通过代码审计发现,少了如下代码

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

3.构造’08.php$DATA’
w20webshell之文件上传_第25张图片
4.文件上传成功
w20webshell之文件上传_第26张图片


1.Pass-09

09实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
09源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

2.通过代码审计发现只对文件末尾的’.'和空格只处理一次,可以构造 ‘09.php. .’
w20webshell之文件上传_第27张图片
3.文件上传成功,得到处理后的文件 ‘09.php.’
在这里插入图片描述


1.Pass-10

10实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
10源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","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);
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.$file_name;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

2.str_ireplace 函数的示例如下


echo str_ireplace("world","John","Hello world!");
?>
输出
Hello John!

3.通过代码审计,主要是通过替换函数处理后缀,因此可构造’10.pphphp’
w20webshell之文件上传_第28张图片
4.成功上传
在这里插入图片描述


1.Pass-11

11实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
11源码
$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类型文件!";
    }
}

2.strrpos函数的示例如下


$str = "hello World!";
$pos = strrpos($str,"o"); // 查找'o'在字符的最后一个出现位置。如果未找到,则返回false。
echo $pos; //输出7

3.通过代码审计,发现通过save_path文件进行传参,内容中发现有”/”和$file_ext说明该参数为可控的,因此magic_quotes_runtime=Off,重启apache,使用%00进行截断。
w20webshell之文件上传_第29张图片
4.服务端读取到%00时会自动结束
w20webshell之文件上传_第30张图片
5.直接访问11.php,访问成功
w20webshell之文件上传_第31张图片


1.Pass-12

12实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
12源码
$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类型文件!";
    }
}

2.跟上一关不同的地方在于,本关是用POST方式,需要在body请求体中进行%00
w20webshell之文件上传_第32张图片
3.成功上传
在这里插入图片描述


1.Pass-13

13实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
13源码
function getReailFileType($filename){
    $file = fopen($filename, "rb"); //fopen函数打开一个文件
    $bin = fread($file, 2); //只读2字节
    fclose($file);
    $strInfo = @unpack("C2chars", $bin); //unpack函数用于将二进制数据按照指定的格式进行解包,将其转换为具有特定数据类型的值或数组
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    //intval() 函数用于获取变量的整数值。通过默认十进制,转换成int的数值
    $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_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}

2.本关要求上传图片马,因此我们可以通过cmd来构造图片马文件
w20webshell之文件上传_第33张图片
3.phpinfo()写入13.php
w20webshell之文件上传_第34张图片
4.成功上传
gif
w20webshell之文件上传_第35张图片
jpg
w20webshell之文件上传_第36张图片
png

后记:需要注意,哪怕一些原图上传,也存在无法解析的问题,因此可以自行构造图片,通过代码审计发现是通过头两个字节来确定文件类型,因此可以记事本打开图片,只保留头部信息大约10个字节(只要大于2字节就行),并在后面补充一句话木马。

w20webshell之文件上传_第37张图片


1.Pass-14

14实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
14源码
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)>=0){
            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_PATH."/".rand(10, 99).date("YmdHis").$res;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}

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


$remote_png_url = 'http://www.runoob.com/wp-content/themes/w3cschool.cc/assets/img/logo-domain-green2.png';
$img_data = getimagesize($remote_png_url);
print_r($img_data );
?>
输出结果:
Array
(
    [0] => 290 //索引 0 给出的是图像宽度的像素值
    [1] => 69 //索引 1 给出的是图像高度的像素值
    [2] => 3  //索引 2 给出的是图像的类型,返回的是数字,其中1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
    [3] => width="290" height="69" //索引 3 给出的是一个宽度和高度的字符串,可以直接用于 HTML 的  标签
    [bits] => 8  //索引 bits 给出的是图像的每种颜色的位数,二进制格式
    [mime] => image/png //索引 mime 给出的是图像的 MIME 信息,此信息可以用来在 HTTP Content-type 头信息中发送正确的信息,如: header("Content-type: image/jpeg");
)

3.image_type_to_extension($info[2])函数,根据图像的类型返回对应的后缀。

4.使用上一关一样的操作,通过cmd/记事本构造图片,构造图片马

cmd:
copy 原图.png /b + 一句话木马.php /a  渲染后的图片.png
记事本:
保留头部两个字节

jpg
w20webshell之文件上传_第38张图片
png
w20webshell之文件上传_第39张图片

gif
w20webshell之文件上传_第40张图片


1.Pass-15

15实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
15源码
function isImage($filename){
    //需要开启php_exif模块
    $image_type = exif_imagetype($filename);
    switch ($image_type) {
        case IMAGETYPE_GIF:
            return "gif";
            break;
        case IMAGETYPE_JPEG:
            return "jpg";
            break;
        case IMAGETYPE_PNG:
            return "png";
            break;    
        default:
            return false;
            break;
    }
}

$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_PATH."/".rand(10, 99).date("YmdHis").".".$res;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}

2.开启php_exif模块。
w20webshell之文件上传_第41张图片
3.exif_imagetype()函数用于确定图像的类型,此函数读取给定图像的第一个字节并检查其签名
4.跟上一关一样的构造图片马方式。(有些靶场有问题,无法正常上传)


1.Pass-16

16实验环境
靶场:upload-labs
浏览器:google
服务器:phpstudy2018
php:5.2.17
抓包工具:burpsuite2021.12
编辑工具:emeditor
16源码
$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_PATH.'/'.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格式的图片!";
                @unlink($target_path);
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagejpeg($im,$img_path);
                @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格式的图片!";
                @unlink($target_path);
            }else{
                 //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".png";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagepng($im,$img_path);

                @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格式的图片!";
                @unlink($target_path);
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".gif";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagegif($im,$img_path);

                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上传出错!";
        }
    }else{
        $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
    }
}

2.strrchr($file_name, ‘.’)函数会返回将第一个查到’.'的位置到字符串结尾的所有字符;
示例如下:


echo strrchr("Hello world! What a beautiful day!",What);
?>
输出结果
What a beautiful day!

3.substr()函数,截取并返回字符串的一部分。substr(string,start,length)


echo substr("Hello world",6);
?>
输出结果
world

4.通过代码审计,发现里面进行了二次渲染,因此我们无法前置构造图片,可先上传一个原图,得到渲染后的图片,通过emeditor比较两者的区别(观察没有改动的地方),再把融合一句话木马后的图片进行比较,把一句话木马替换到没改动的地方。
w20webshell之文件上传_第42张图片

一句话木马的二进制,可先在空白记事本写好 ,然后用emeditor打开,如果打开显示的是utf-8,可以点击“文件”-“重新载入”-“二进制”。
在这里插入图片描述

gif
w20webshell之文件上传_第43张图片

你可能感兴趣的:(webshell,蚁剑,菜刀)