我正在审核安全工具,我决定一个好的方法是创建我自己的"不安全的区域" (使用随机生成的假数据),因此我设置了一个易受sql注入的区域。但是,我实际上似乎无法注入它。我注意到,当我给它一个错误的查询时,"以下是找到的帐户"不打印,但错误消息也不打印。
有人可以告诉我,如果我做错了吗?
<?php
$resultHTML;
if (isset($_POST['email']) || isset($_GET['email'])) {
$conn = mysqli_connect($servername,$username,$password);
if ($conn) {
//this part is insecure (intentionally for testing)
if (isset($_GET['email'])) {
$query = "SELECT * from badSQL.Two WHERE email = '$_GET[email]'";
} else {
$query = "SELECT * from badSQL.Two WHERE email = '$_POST[email]'";
}
//echo $query;
$result = $conn->query($query);
if ($result) {
$resultHTML = "Here are the accounts found: ";
$hasAccount = false;
while ($row = mysqli_fetch_assoc($result)) {
$hasAccount = true;
$resultHTML .= "<br>".print_r($row);
}
if ($hasAccount === false) {
$resultHTML = "No accounts found.";
}
}
} else {
$resultHTML = "DB Connection could not be established: ".$conn->connect_error;
}
}
?>
<html>
<head>
<title>Two BadSQL Test</title>
</head>
<body>
<h1>Two Website!</h1>
<br>
<h3>Forgot Password</h3>
<p>Enter your email below, and click submit:</p>
<form id="forgotForm" method="get">
<input type="text" name="email" />
<input type="submit" value="submit" />
</form>
<br>
<div id="results"><?php echo $resultHTML; ?></div>
</body>
</html>
答案 0 :(得分:1)
1' OR '1'='1
应该是有效的SQLi,因为它将评估为:
"SELECT * from badSQL.Two WHERE email = '1' OR '1'='1'"
电子邮件地址始终是错误的并不重要,因为它使用了OR
子句。考虑1
将始终等于1
,整个表达式将始终成立。因此,上述脚本将“跳过”所有电子邮件检查,然后尝试找到满足'1' = '1'
条件的第一个用户。这与表中的第一个用户(通常是管理员,因为ID为1,导致进一步利用)相关。
为防止出现这种情况,我建议您使用stored procedures or parameterised queries,并使每个表中的第一个用户拥有尽可能少的权限。我还建议您查看 OWASP SQLi Prevention Cheat Sheet 。
等效的非易受攻击的PHP参数化查询看起来像:
$stmt = $dbConnection->prepare('SELECT * FROM badSQL.TwoWHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// Do something with $row
}
另外,我建议不要故意让自己的网站更容易受到攻击,因为为封装的假数据创建漏洞可以作为合法攻击的载体。
希望这会有所帮助:)