我正在创建一个SQL注入演示作为我班级的项目。我已经创建了一个登录页面,但我似乎无法注入它。这是我为该页面编写的内容。我试过盲目SQLi用username字段创建多个子句。我能想到的唯一另一件事是使用子查询或更改我的代码以使其更容易。
编辑*尝试注入用户名字段*
<?php // Check to see if there was a request method that is a post type
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
// Check to see if username field is null
if (!empty($_POST['username'])) {
// Connect to the server using credentials
$con = mysql_connect('localhost','root','sqlcool1');
// If the connection was not successful
if (!$con){
echo 'OUCH';
die('Could not connect: '.mysql_error());
}
// Select the correct database from the server
$db = mysql_select_db('injectme',$con);
// Pass a sql query through the table to pull the user field that was entered in the form
// Return the results in an array
$sql = mysql_query('SELECT * FROM user WHERE username = "' . $_POST['username'] . '"');
$row = mysql_fetch_row($sql);
// compare $row["password"] to $_post["password"]
// if they match it's good: log them in
// if not, they're beat: don't log them in
if ($_POST["username"] == $row[1] && $_POST["password"] == $row[2]) {
// do something to let them know that it worked
echo('<html>
<head>
<meta http-equiv="refresh" content="3; url=search.php">
</head>
<body>
<p style="color:green">logged in</p>
</body>
</html>');
} else {
// do something to let them know it didn't work
echo('<p style="color: red">Invalid username or password.</p>');
echo('<form name="login" action="login.php" method="POST">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" name="submit_button" value="Submit">
<button type="submit" formaction="register.php">Register</button>
</form>');
}
//Close the connected session with the server
mysql_close($con);
} else {
// Repost Form
echo ('<p style="color: red"> No username / password provided.</p>');
echo('<form name="login" action="login.php" method="POST">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" name="submit_button" value="Submit">
<button type="submit" formaction="register.php">Register</button>
</form>');
}
}
else
{
echo('<form name="login" action="login.php" method="POST">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" name="submit_button" value="Submit">
<button type="submit" formaction="register.php">Register</button>
</form>');
}
?>
答案 0 :(得分:12)
您发布的代码完全容易受到攻击,可用于查看整个数据库的内容。利用它的一种方法是基于时间的攻击,如果条件为真,则创建人为的长响应时间。
考虑以下用户名:
&#34; UNION SELECT(WHEN&#34; A&#34; =(SUBSTR(密码,1,1))然后休眠(5)ELSE 1 END)作为用户名,1作为密码来自用户LIMIT 0,1 -
如果响应时间超过5秒,您可以知道第一个字符的值是&#34; A&#34;否则只测试另一个角色。之后,您必须为字符串中的其他位置重复相同的模式,直到找到密码的所有字符。之后,您可以直接使用管理员密码。由于它需要大量查询,因此这些类型的攻击通常都是脚本化的。
如果您想了解更多相关信息,请将其称为Blind SQL Injection。
答案 1 :(得分:5)
要成功利用此漏洞,您需要能够注入一些代码,以便生成的SQL语句将返回将通过后续测试的内容:
$_POST["username"] == $row[1] && $_POST["password"] == $row[2]
所以第二列需要等于提交的用户名,第三行需要等于提交的密码。
现在,当提交的用户名注入时,您就遇到了问题。
因为您无法提供满足将一些数据注入结果集方面的用户名,并且为注入值的注入代码注入了与用户名相同的用户名值用户名方面。
前者非常简单(假设用户中有三列):
username := '" UNION SELECT 1, "admin", "'
password := ''
这导致:
SELECT * FROM user WHERE username = "" UNION SELECT 1, "admin", ""
但是,$_POST["username"] == $row[1]
部分仍然无法解析,因为您需要使第二个SELECT返回提交的用户名作为用户名列值。而那是不可能的。
现在,如果你只是移除$_POST["username"] == $row[1]
它就可以了。
答案 2 :(得分:0)
这取决于你想要注射的东西。如果您尝试注入第二个查询,则无法执行此操作 - mysql_query
函数不支持多个查询。来自the docs:
mysql_query()向与指定link_identifier关联的服务器上的当前活动数据库发送唯一查询(不支持多个查询)。
当然,它仍然容易受到额外的WHERE
子句注射。