今天给各位分享Exif网站源码分享的知识,其中也会对网站源码分析进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
客户端
js检查
一般都是在网页上写一段javascript脚本,校验上传文件的后缀名,有白名单形式也有黑名单形式。
查看源代码可以看到有如下代码对上传文件类型进行了限制:
<scripttype=&34;>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);\nreturnfalse;\n}\n}</script>
我们可以看到对上传文件类型进行了限制。
绕过方法
我们直接删除代码中onsubmit事件中关于文件上传时验证上传文件的相关代码即可。
或者可以不加载所有js,还可以将html源码copy一份到本地,然后对相应代码进行修改,本地提交即可。
burp改包,由于是js验证,我们可以先将文件重命名为js允许的后缀名,在用burp发送数据包时候改成我们想要的后缀。
即可上传成功:
服务端
黑名单
特殊可解析后缀
if(file_exists(UPLOAD_PATH)){\n$deny_ext=array(&39;,&39;,&39;,&39;);\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;.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}
这里做了黑名单处理,我们可以通过特殊可解析后缀进行绕过。
绕过方法
之前在https://www.jianshu.com/p/1ccbab572974中总结过,这里不再赘述,可以使用php3,phtml等绕过。
上传.htaccess
if(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=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}\n?>
我们发现黑名单限制了很多后缀名,但是没有限制.htaccess
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置.通过htaccess文件,可以实现:网页301重定向、自定义404页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
绕过方法
我们需要上传一个.htaccess文件,内容为:
SetHandlerapplication/x-httpd-php\n
这样所有的文件都会解析为php,接下来上传图片马即可
后缀大小写绕过
if(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=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}
我们发现对.htaccess也进行了检测,但是没有对大小写进行统一。
绕过方法
后缀名改为PHP即可
空格绕过
if(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=$_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}
黑名单没有对文件中的空格进行处理,可在后缀名中加空格绕过。
绕过方法
点绕过
if(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_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}
windows会对文件中的点进行自动去除,所以可以在文件末尾加点绕过,不再赘述
::$DATA绕过
同windows特性,可在后缀名中加”::$DATA”绕过,不再赘述
路径拼接绕过
if(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}
这里对文件名进行了处理,删除了文件名末尾的点,并且把处理过的文件名拼接到路径中。
绕过方法
这里我们可以构造文件名1.PHP..(点+空格+点),经过处理后,文件名变成1.PHP.,即可绕过。
双写绕过
if(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;);\n\n$file_name=trim($_FILES[&39;][&39;]);\n$file_name=str_ireplace($deny_ext,&34;,$file_name);\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=UPLOAD_PATH.&39;;\n}\n}
绕过方法
这里我们可以看到将文件名替换为空,我们可以采用双写绕过:1.pphphp
白名单
MIME检查
if(isset($_POST[&39;])){\nif(file_exists(UPLOAD_PATH)){\nif(($_FILES[&39;][&39;]==&39;)||($_FILES[&39;][&39;]==&39;)||($_FILES[&39;][&39;]==&39;)){\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;;\n}\n}else{\n$msg=UPLOAD_PATH.&39;;\n}
绕过方法
这里检查Content-type,我们burp抓包修改即可绕过:
%00截断
if(isset($_POST[&39;])){\n$ext_arr=array(&39;,&39;,&39;);\n$file_ext=substr($_FILES[&39;][&39;],strrpos($_FILES[&39;][&39;],&34;)+1);\nif(in_array($file_ext,$ext_arr)){\n$temp_file=$_FILES[&39;][&39;];\n$img_path=$_GET[&39;].&34;.rand(10,99).date(&34;).&34;.$file_ext;\n\nif(move_uploaded_file($temp_file,$img_path)){\n$is_upload=true;\n}else{\n$msg=&39;;\n}\n}else{\n$msg=&34;;\n}\n}
$img_path直接拼接,因此可以利用%00截断绕过
绕过方法
然后直接访问/upload/1.php即可
00截断(post)
if(isset($_POST[&39;])){\n$ext_arr=array(&39;,&39;,&39;);\n$file_ext=substr($_FILES[&39;][&39;],strrpos($_FILES[&39;][&39;],&34;)+1);\nif(in_array($file_ext,$ext_arr)){\n$temp_file=$_FILES[&39;][&39;];\n$img_path=$_POST[&39;].&34;.rand(10,99).date(&34;).&34;.$file_ext;\n\nif(move_uploaded_file($temp_file,$img_path)){\n$is_upload=true;\n}else{\n$msg=&34;;\n}\n}else{\n$msg=&34;;\n}\n}\n?>
save_path是通过post传进来的,还是利用00截断,但这次需要在二进制中进行修改,因为post不会像get对%00进行自动解码。
绕过方法
接下来访问1.php即可
文件内容检查
文件幻数检测
主要是检测文件内容开始处的文件幻数,比如图片类型的文件幻数如下,要绕过jpg文件幻数检测就要在文件开头写上下图的值:
Value=FFD8FFE000104A464946
要绕过gif文件幻数检测就要在文件开头写上下图的值
Value=474946383961要绕过png文件幻数检测就要在文件开头写上下面的值
Value=89504E47
然后在文件幻数后面加上自己的一句话木马代码就行了
文件相关信息检测
图像文件相关信息检测常用的就是getimagesize()函数
只需要把文件头部分伪造好就ok了,就是在幻数的基础上还加了一些文件信息
有点像下面的结构
GIF89a(…somebinarydataforimage…)<?phpphpinfo();?>(…skippingtherestofbinarydata…)
本次环境中的文件头检测,getimagesize,php_exif都可以用图片马绕过:
copynormal.jpg/b+shell.php/awebshell.jpg\n
文件加载检测
一般是调用API或函数去进行文件加载测试,常见的是图像渲染测试,甚至是进行二次渲染(过滤效果几乎最强)。对渲染/加载测试的攻击方式是代码注入绕过,对二次渲染的攻击方式是攻击文件加载器自身。
对渲染/加载测试攻击-代码注入绕过
可以用图像处理软件对一张图片进行代码注入
用winhex看数据可以分析出这类工具的原理是
在不破坏文件本身的渲染情况下找一个空白区进行填充代码,一般会是图片的注释区
对于渲染测试基本上都能绕过,毕竟本身的文件结构是完整的
二次渲染
imagecreatefromjpeg二次渲染它相当于是把原本属于图像数据的部分抓了出来,再用自己的API或函数进行重新渲染在这个过程中非图像数据的部分直接就隔离开了
if(isset($_POST[&39;])){\n//获得上传文件的基本信息,文件名,类型,大小,临时文件路径\n$filename=$_FILES[&39;][&39;];\n$filetype=$_FILES[&39;][&39;];\n$tmpname=$_FILES[&39;][&39;];\n\n$target_path=UPLOAD_PATH.basename($filename);\n\n//获得上传文件的扩展名\n$fileext=substr(strrchr($filename,&34;),1);\n\n//判断文件后缀与类型,合法才进行上传操作\nif(($fileext==&34;)&&($filetype==&34;)){\nif(move_uploaded_file($tmpname,$target_path))\n{\n//使用上传的图片生成新的图片\n$im=imagecreatefromjpeg($target_path);\n\nif($im==false){\n$msg=&34;;\n@unlink($target_path);\n}else{\n//给新图片指定文件名\nsrand(time());\n$newfilename=strval(rand()).&34;;\n$newimagepath=UPLOAD_PATH.$newfilename;\nimagejpeg($im,$newimagepath);\n//显示二次渲染后的图片(使用用户上传图片生成的新图片)\n$img_path=UPLOAD_PATH.$newfilename;\n@unlink($target_path);\n$is_upload=true;\n}\n}else{\n$msg=&34;;\n}\n\n}elseif(($fileext==&34;)&&($filetype==&34;)){\nif(move_uploaded_file($tmpname,$target_path))\n{\n//使用上传的图片生成新的图片\n$im=imagecreatefrompng($target_path);\n\nif($im==false){\n$msg=&34;;\n@unlink($target_path);\n}else{\n//给新图片指定文件名\nsrand(time());\n$newfilename=strval(rand()).&34;;\n$newimagepath=UPLOAD_PATH.$newfilename;\nimagepng($im,$newimagepath);\n//显示二次渲染后的图片(使用用户上传图片生成的新图片)\n$img_path=UPLOAD_PATH.$newfilename;\n@unlink($target_path);\n$is_upload=true;\n}\n}else{\n$msg=&34;;\n}\n\n}elseif(($fileext==&34;)&&($filetype==&34;)){\nif(move_uploaded_file($tmpname,$target_path))\n{\n//使用上传的图片生成新的图片\n$im=imagecreatefromgif($target_path);\nif($im==false){\n$msg=&34;;\n@unlink($target_path);\n}else{\n//给新图片指定文件名\nsrand(time());\n$newfilename=strval(rand()).&34;;\n$newimagepath=UPLOAD_PATH.$newfilename;\nimagegif($im,$newimagepath);\n//显示二次渲染后的图片(使用用户上传图片生成的新图片)\n$img_path=UPLOAD_PATH.$newfilename;\n@unlink($target_path);\n$is_upload=true;\n}\n}else{\n$msg=&34;;\n}\n}else{\n$msg=&34;;\n}\n}
本关综合判断了后缀名、content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染。
绕过方法
得去找图片经过GD库转化后没有改变的部分,再将未改变的部分修改为相应的php代码。
条件竞争
if(isset($_POST[&39;])){\n$ext_arr=array(&39;,&39;,&39;);\n$file_name=$_FILES[&39;][&39;];\n$temp_file=$_FILES[&39;][&39;];\n$file_ext=substr($file_name,strrpos($file_name,&34;)+1);\n$upload_file=UPLOAD_PATH.&39;.$file_name;\n\nif(move_uploaded_file($temp_file,$upload_file)){\nif(in_array($file_ext,$ext_arr)){\n$img_path=UPLOAD_PATH.&39;.rand(10,99).date(&34;).&34;.$file_ext;\nrename($upload_file,$img_path);\n$is_upload=true;\n}else{\n$msg=&34;;\nunlink($upload_file);\n}\n}else{\n$msg=&39;;\n}\n}
这里先将文件上传到服务器,然后通过rename修改名称,再通过unlink删除文件,因此可以通过条件竞争的方式在unlink之前,访问webshell。
绕过方法
然后不断访问webshell:
上传成功。
参考链接:
https://blog.csdn.net/Kevinhanser/article/details/81613003https://secgeek.net/bookfresh-vulnerability/https://xz.aliyun.com/t/2435
2人点赞
知识归纳
文章到此结束,如果本次分享的Exif网站源码分享和网站源码分析的问题解决了您的问题,那么我们由衷的感到高兴!
