前言:
要想检测图片中是否含有木马脚本,首先从制作原理来分析这种木马程序。这种木马程序是十六进制编码写的,图片的十六进制代码中主要包含<% ( ) %>、<? ( ) ?> 、<script | /script>, 所以我们可以通过检测十六进制代码来检测木马脚本。
如何测试:
1.创建一个txt文件,名字改成1.jpg。
2.将<%eval request(“keio”)%> 存为1.php。
//前端代码
<html>
<head>
<meta charset="utf-8">
<title>多图上传</title>
<script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
<script type="text/javascript" defer="true" src="js/upload.js"></script>
</head>
<body>
<form id="form1" enctype="multipart/form-data">
<input type="file" name="file" id="file" multiple="multiple">//multiple开启多图上传
<input type="text" name="abcd">
<input id="but1" type="button" value="点击上传">
</form>
<div id="ulList"></div>
</body>
</html>
JQajax传送到php和简单的文件核验
//判断文件类型
function isAssetTypeAnImage(ext) {
return ['png', 'jpg', 'jpeg'].
indexOf(ext.toLowerCase()) !== -1;
}
//获取上传图片临时路径
function getObjectURL(file) {
var url = null ;
if (window.createObjectURL!=undefined) {
url = window.createObjectURL(file) ;
} else if (window.URL!=undefined) {
url = window.URL.createObjectURL(file) ;
} else if (window.webkitURL!=undefined) {
url = window.webkitURL.createObjectURL(file) ;
}
return url ;
}
$('#but1').click(function () {
$("#ulList").empty();
var formData = new FormData()
var Upload = $("#file");//获取当前上传inputID
var length = Upload[0].files.length;//文件上传几个
if(length>5){
alert("超出单次上传限制,单次最多只能是5张!");
return;
}
var items = Upload[0].files;//文件上传信息
if(length>0){
for(var i=0;i<length;i++){
var fileName = items[i].name; // 获取文件名
var fileSize = items[i].size; // 获取文件大小
var fileType = items[i].type; // 获取文件类型
//获取最后一个.的位置
var index= fileName.lastIndexOf(".");
//获取后缀
var ext = fileName.substr(index+1);
//输出结果
if(!isAssetTypeAnImage(ext)){
alert("文件类型出错,请重新上传文件!");
return;
}
if(fileSize>10240000){
alert("文件超出限制,请上传小于10M的文件!");
return;
}
formData.append('upFile[]', items[i], items[i].name);//自动叠加的
$("#ulList").append('<img src="'+getObjectURL(Upload[0].files[i])+'">');
}
//console.log(formData.getAll('upFile[]'))//可以打印输出看下
$.ajax({
url:"upload_file.php",
type:"post",
data:formData,
processData:false,
contentType:false,
success : function(data){
}
})
}
});
upload_file.php
<?php
/**
* 将图片转为16进制,并检测是否含有异常代码
*/
function fileToHex($cc){
$fpc=fopen($cc,"rb");
$datac=fread($fpc,filesize($cc));
$newdata=bin2hex($datac);
if (preg_match("/(3c25.*?28.*?29.*?253e)|(3c3f.*?28.*?29.*?3f3e)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)/is", $newdata)){
return 1;
}
}
//判断创建子目录
function mkdirs_($path, $mode = 0777){
if(is_dir($path)){
return ;//'无法创建,已经是目录了'
}else{
if(mkdir($path, $mode, true)) {
return;// '创建成功'
}else{
return;// '创建失败'
}
}
}
//判断是否有上传文件
if(!isset($_FILES)){
exit('没选中文件');
}
$allowedExts = array("gif", "jpeg", "jpg", "png");//允许上传的图片后缀
$name = $_FILES["upFile"]["name"];//获取当前上传图片名称的数组
$count = (count((array)$name));//php7以后count获取当前上传个数
for($i=0;$i<$count;$i++){
$temp = explode(".", $_FILES["upFile"]["name"][$i]);
$extension = end($temp);
$Leibie = $_FILES["upFile"]["type"][$i];
if((($Leibie == "image/gif")
|| ($Leibie == "image/jpeg")
|| ($Leibie == "image/jpg")
|| ($Leibie == "image/pjpeg")
|| ($Leibie == "image/x-png")
|| ($Leibie == "image/png"))
&& ($_FILES["upFile"]["size"][$i] < 10240000)
&& in_array($extension, $allowedExts)){//二次图片核验
$ststime = date("Ymd",time());
$Mingming = time().mt_rand(10, 999999).".".$extension;//重新定义的文件名称
mkdirs_('image/'.$ststime.'');//创建子目录
if(fileToHex($_FILES["upFile"]["tmp_name"][$i])==1){//异常检测
echo $_FILES["upFile"]["name"][$i]."危险文件";exit;
}else{
if (file_exists("image/".$ststime."/".$Mingming)){
echo "image/".$ststime."/".$Mingming." 文件已经存在。";
}else{
// 如果 image 目录不存在该文件则将文件上传到 image 目录下
move_uploaded_file($_FILES["upFile"]["tmp_name"][$i], "image/".$ststime."/".$Mingming);
}
}
}else{
echo "非法的文件格式";exit;
}
}
if ($_FILES["upFile"]["error"][$i] > 0){
echo "错误:: " . $_FILES["file"]["error"] . "<br>";exit;
}
// echo '<pre>';
// print_r($_FILES);
?>
到这里算是传送到php文件成功了
下面就是页面反馈的危险图片提示:
如果需要前台点击图片的右上角删除,删除对应的图片。
由于时间不多了暂时不写了,先把思路给下:
$("#ulList").append输出带绑定点击事件的
(注意阻止冒泡事件),
然后点击div,则删除对应的upFile[]
然后点击div,则删除对应的upFile[]