概括 :
SQL 注入是一种网络安全漏洞,允许攻击者干扰应用程序对其数据库的查询。它通常允许攻击者查看他们通常无法检索的数据。这可能包括属于其他用户的数据,或应用程序本身能够访问的任何其他数据。
描述 :
我在文件上传功能上发现了 SQL 注入。在文件上传时,只允许少数图像扩展名,所以我使用文件名作为有效负载检查 XSS(例如"><img src=x onerror=alert(document.domain).png),它成功但问题是它是一个自我 XSS。查看生成的错误后,我看到错误说“此属性必须是有效的文件名”。我想如果我将有效负载更改为 SQL 注入的有效负载作为文件名会怎样,所以我将文件名设置为--sleep(15).png并且它起作用了。我检查了更多的睡眠有效载荷,它们也都有效。
我是如何发现这个漏洞的?
上传文件
2.我上传了一个以xss payload为名字的文件("><img src=x onerror=alert(document.domain>.png)
XSS 负载
3.我发现了一个XSS,但它是一个自我XSS
自我 XSS
4.我检查了触发的错误,有趣的是“这个属性必须是一个有效的文件名”
XSS 负载
触发错误
5.然后我再次上传文件并将XSS有效负载更改为SQLi有效负载并检查burp中的响应
睡眠负载
睡眠负载
睡眠负载
睡眠负载
我使用的有效载荷:
易受攻击的代码(据我所知):
<?php $target_dir = “上传/”; $target_file = $target_dir 。basename($_FILES[“fileToUpload”][“name”]); $上传确定 = 1; $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION)); // 检查图像文件是真实图像还是假图像 if(isset($_POST[“submit”])) { $check = getimagesize($_FILES[“fileToUpload”][“tmp_name”]); if($check !== false) { echo “文件是图像 -” . $check[“mime”] 。“。”; $上传确定 = 1; } else { echo “文件不是图像。”; $上传确定 = 0; } } ?>
在上面提到的 PHP 代码中,它检查上传的文件是否是实际图像,但不检查文件名,它是实际文件名还是有效负载。
2. $target_file 指定要上传的文件的路径
3. $uploadOk=1 还没用(后面会用到)
4. $imageFileType 保存文件的文件扩展名(小写)
5.接下来,检查图像文件是真实图像还是假图像
使用正则表达式检查有效文件名的代码(据我所知):
$filename = '../../test.jpg'; if (preg_match('/^[\/\w\-. ]+$/', $filename)) echo 'VALID FILENAME'; 否则 回显“无效文件名”;
应添加上述代码以检查上传的文件是否具有有效的文件名或不是有效的文件名。
为什么会这样?
在我看来,
发生这种情况是因为后台的 PHP 代码正在检查文件是否是图像文件,但没有检查文件名是有效文件名还是有效负载。
影响 :
基于时间的 SQL 注入会增加 CPU 和内存资源(如 RAM、缓存和处理器)的消耗,还会降低服务器速度。如果进一步利用基于时间的 SQL 注入,它可用于从数据库中提取数据。
计算的 CVSS:
向量字符串 - CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H
得分 - 7.1
缓解措施:
准备好的语句(带有参数化查询):
编写准备好的语句可以确保 SQL 代码结构不会改变,并且数据库可以区分查询和数据。作为一个好处,它还使您的代码看起来更干净,更易于阅读。参数化 SQL 查询允许您在 SQL 查询中放置参数而不是常量值。参数仅在执行查询时才取值,这允许查询以不同的值和不同的目的重用。
输入验证:
输入验证是测试应用程序接收到的输入是否符合应用程序中定义的标准的过程。它可以像严格键入参数一样简单,也可以像使用正则表达式或业务逻辑来验证输入一样复杂。
转义用户输入:
允许用户输入包含诸如 ' “ $ \ 之类的字符可能会导致 SQL 查询中断,甚至更糟,正如我们所了解的,将它们打开以进行注入攻击。转义用户输入是在这些字符前面加上反斜杠 ( \ ) 的方法,这会导致它们被解析为常规字符串而不是特殊字符。
在我的情况下缓解:
为了克服这个 SQL sleep 命令的问题,MySQL 使用了两个参数:
1.interactive_timeout 2.wait_timeout
这些需要设置某些值以帮助查询运行到该设置时间。默认情况下,这两个参数都将值设置为 28800 秒(例如 8 小时)。
要在 MySQL 中设置这些参数而不重新启动它,请在其终端中运行以下两个命令:
SET GLOBAL interactive_timeout = 180; SET GLOBAL wait_timeout = 180;
需要在 MySQL 的my.cnf文件中的 mysqld 部分添加这些参数,以便重启数据库服务器后生效。
此外,在每个脚本的末尾,添加 mysql_close() 函数,以便在查询完成后关闭与数据库的连接。
如果您对服务器具有 root 访问权限,请使用以下命令编辑 my.cnf :
$定位我的.cnf
它将显示 MySQL 配置文件的位置,然后使用以下命令编辑 my.cnf :
$vi /etc/my.cnf
并在 my.cnf 中添加这一行:
等待超时 = 60
时间以秒为单位。
因此,连接将在等待 60 秒后自动关闭。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。