文章总结: 文章详解利用图片EXIF信息进行SQL注入的技巧。通过CTF实战演示,使用exiftool修改图片comment构造payload,利用PHP的finfo::file函数未过滤直接入库的漏洞执行SQL语句。文章涵盖解题思路、源码分析及底层调试,揭示此类二次注入风险并建议对文件信息进行严格过滤。 综合评分: 88 文章分类: WEB安全,CTF,漏洞分析,渗透测试

可以看到,命令已经成功注入到了comment中,上传该图片,就可以发现明显有延迟,所以命令注入成功。
之后拿flag就很简单了,利用into outfile写入一句话木马即可,这里就不赘述了。
那么,究竟是什么函数会导致这样的SQL注入呢?
抱着深究的心态把题目源代码拷贝下来进行分析(所有可以getshell的题目都可以把题目拿下来进行分析,可以学到更多的东西)
题目源代码分析
首先一些登录文件就不看了,直接看最重要的,会造成SQL注入的那几个文件(为了防止篇幅过长,我这里仅将关键代码进行展示)
$filename = md5(md5(rand(1,10000))).".zip";
$filetype = (new finfo)->file($_FILES['file']['tmp_name']);
$filepath = "upload/".$filename;
$sql = "INSERT INTO file(filename,filepath,filetype) VALUES ('".$filename."','".$filepath."','".$filetype."');";
- 上方代码第一行就是前面说的,将随机数md5存储文件
- 第二行这里使用到了
finfo::file,这里便是我们的注入点 - 第三行是目录的拼接
- 第四行就是存在SQL注入的SQL语句
if(mysqli_num_rows($result)>0){
while($row=mysqli_fetch_assoc($result)){
echo "<li>";
echo "filename:<a href='".$row["filepath"]."'>".$row["filename"]."</a> filetype:".$row["filetype"]."<br>";
}
echo "</li>";
}
这一段代码就比较简单,就是将存储的文件名列出来
那么造成注入的罪魁祸首就是这一行代码:
$filetype = (new finfo)->file($_FILES['file']['tmp_name']);
这里使用finfo::file方法,这个方法在PHP手册介绍如下,但是并不是很详细,后半部分将会对这一个函数进行底层代码跟踪分析。
finfo::file底层跟进
finfo::file方法在ext/fileinfo/fileinfo.c中
其中finfo中有这么几个方法:
class finfo
{
/** @alias finfo_open */
publicfunction __construct(int $flags = FILEINFO_NONE, ?string $magic_database = null) {}
/**
* @param resource|null $context
* @return string|false
* @alias finfo_file
*/
publicfunction file(string $filename, int $flags = FILEINFO_NONE, $context = null) {}
/**
* @param resource|null $context
* @return string|false
* @alias finfo_buffer
*/
publicfunction buffer(string $string, int $flags = FILEINFO_NONE, $context = null) {}
/**
* @return bool
* @alias finfo_set_flags
*/
publicfunction set_flags(int $flags) {}
}
我们跟进finfo::file
我们在下方图中位置下三个断点
将前面题目拉下来的源文件放在一个文件夹中进行调试
源文件如下:
将upload.php修改如下
$filename = md5(md5(rand(1,10000))).".zip";
$filetype = (new finfo)->file($_FILES['file']['tmp_name']);
$filepath = "upload/".$filename;
var_dump($filetype);
die(0);
开启调试,上传注入文件后程序便会停止在断点处
第一个断点处,421行,这个断点处调用包装器打开资源并返回流对象
第二个断点处,431-432行,进入magic_stream,单步调试,监视ms以及ret_val
进入file_or_stream
直接看file_or_stream的return
跟进file_getbuffer,下方其实就可以看到ms->o.buf已经获取到了exif信息
后面的就不继续跟进了,但是可以肯定的是file()方法可以检测图片的EXIF信息,并且作为题目中的filetype传入数据库造成注入
$filetype = (new finfo)->file($_FILES['file']['tmp_name']);
总结
虽然是几年前的trick,但是每弄清楚一个trick,攻击面就会更广。
学习网安实战课程,戳“阅读原文”
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:蚁景网安 《一张图片也能 SQL 注入?》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论