源码分析
$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的图片文件!";
}
}
简单的来说就是会把上传的文件在后台检测,把无关的代码过滤,或者被重写,然后在回显到web上。一个动图gif回显回来直接会被简化只留第一帧,会把后面几帧过滤,然后就回显回来就不会动了。
PNG的文件格式有个特性,就是在IDAT(图像数块)开始的地方写入字符串等等不会损坏图片的显示(一般改完都是一片黑)但是在kali里面是显示损坏的,因为改完还需要计算这个crc值(我这里对png的格式是简单的讲一下,想要了解跟多,可以去看看其他大佬的文章)
但是这样传,是传不上去的,会报错
寻找一番计算crc值的脚本,但是并没有找到,但是找到一个计算PLTE数据块crc值脚本,那么就需要有PLTE数据块的的png文件了,这种一般的图片是没有的所以我就直接放在这了,免积分下载!->colortype索引为03的索引彩色图像-网络安全文档类资源-CSDN下载
这种的木马就需要覆盖在PLTE数据块里面,写入之后用脚本重新计算这个文件的crc值,然后修改文件里的crc值,然后上传就可以了,现在我们先写入
然后保存,然后通过网上大佬的脚本,修改一下匹配字节的代码和文件名,就变成了下面这样
import binascii
import re
png = open(r'7.png', 'rb')
a = png.read()
png.close()
hexstr = binascii.b2a_hex(a)
''' PLTE crc '''
data = '504c5445' + re.findall('504c5445(.*?)70485973', hexstr)[0]
crc = binascii.crc32(data[:-16].decode('hex')) & 0xffffffff
print (hex(crc))
这个py脚本要用python2运行,高版本运行会报错,然后我们直接运行这个脚本
然后就得到了这个文件的crc值了,然后把图片文件的crc值改成算出来的就差不多完成了
然后保存文件上传,这边看到也是上传成功了
然后配合pass13关的文件包含漏洞连接一下
连接成功了,证明木马没有被过滤
最后,我试了gif的文件格式无论php代码插在哪里都会被过滤,jpg用脚本改出来的虽然可以正常显示但是传不上去,有大佬懂的话,欢迎私信讨论