十五、图片检测函数绕过
1、代码分析
getimagesize 是获取图片的大小,如果头文件不是图片会报错直接可以用图片马绕过检测。
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、绕过攻击
再用文件包含漏洞引入 jpeg/gif 图片即可 getshell
十六、绕过图片二次渲染
1、简介
有些图片上传,会对上传的图片进行二次渲染后在保存,体积可能会更小,图片会模糊一些,但是符合网站的需求。例如新闻图片封面等可能
需要二次渲染,因为原图片占用的体积更大。访问人数太多时候会占用很大带宽。二次渲染后的图片内容会减少,如果里面包含后门代码,
可能会被省略。导致上传的图片马,恶意代码被清除。
2、代码分析
只允许上传 JPG PNG gif,在源码中使用 imagecreatefromgif 函数对图片进行二次生成。生成的图片保存在upload 目录下。
$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的图片文件!";
}
}
3、绕过图片二次渲染
首先判断图片是否允许上传 gif,gif 图片在二次渲染后,与原图片差别不会太大。所以二次渲染攻击最好用 git 图片马。
制作图片马:
将原图片上传,下载渲染后的图片进行对比,找相同处,覆盖字符串,填写一句话后门,或者恶意指令。
使用工具:HxDHexEditor2.3.0.0
原图片与渲染后的图片这个位置的字符串没有改变,所在原图片这里替换成<?php phpinfo();?>直接上传即可。
十七、文件名可控绕过
1、简介
文件上传时,文件名的可被客户端修改控制,会导致漏洞产生。
2、代码分析
$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 . '文件夹不存在,请手工创建!';
}
}
采用黑名单限制上传文件,但是 $_POST['save_name']文件是可控的,可被客户端任意修改,造成安全漏洞.
3、绕过攻击
主要有两种:
1.上传文件,文件采用%00 截断,抓包解码例如 pinfo.php%00.php 截断后pinfo.php 或者使用/.
2.与中间的漏洞配合使用,例如 iis6.0 上传 1.php;1.jpg,apache 上传 1.php.a 也能解析文件,a.asp;1.jpg 解析成 asp
3.1 %00截断
%00 截断需要gpc关闭,抓包,解码,提交即可截断文件名,php版本小于 5.3.4
3.2 /.截断