背景知识要求:能够看懂简单的HTML, PHP, SQL代码
SQL原理: 通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。简单来说就是本来是用户输入数据的地方,结果被输入了一段代码,而服务器将会执行这段代码,导致用户获得原本不能获得的信息和权限。
举一个简单的例子:
假设在一个服务器中有login.html和login.php文件,源码如下:
longin.html
<html>
<body>
<br><br><h2>Login</h2><br><br>
<form action="login.php" method="POST">
Username:
<input type="text" name="username">
Password:
<input type="text" name="password">
<input type="submit" value="Submit">
</form>
</body>
</html>
login.php
<html>
<body>
<?php
//建立连接
$conn = mysqli_connect('localhost','root','*******');
if (!$conn)
{
die('Could not connect: ' . mysqli_error());
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$name=$_POST["username"];
$passwd=$_POST["password"];
//sql语句
$sql = "SELECT * FROM login WHERE username='$name' AND password='$passwd'";
mysqli_select_db( $conn, 'User' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('Fail' . mysqli_error($conn));
}
$row = mysqli_fetch_array($retval, MYSQLI_ASSOC);
//是否登入成功
if($row)
echo 'Login success';
else
echo 'ERROR Incorrect username or password';
// 释放内存
mysqli_free_result($retval);
mysqli_close($conn);
?>
</body>
</html>
这两个文件能够模拟一个简单的登入过程,
login.html接受用户输入的username和passwd,并通过post方式发送给login.php,
login.php处理判断用户输入的username和passwd在数据库中能否查询到,查到则登入成功,否则失败,具体逻辑如下
$sql = "SELECT * FROM login WHERE username='$name' AND password='$passwd'";
if($row)
echo 'Login success';
else
echo 'ERROR Incorrect username or password';
判断依据是只要sql查询结果不为空,就认为username和password在数据库中存在,既登入成功。
从攻击者的角度来看,假设我们需要登入而又不知到username和passwd,按照正常情况是不可能登入的。但是如果可以利用向username或passwd中写入代码,则可以绕过登入判断。
先来看第一句代码
$sql = "SELECT * FROM login WHERE username='$name' AND password='$passwd'";
在服务器处理用户提交的数据时,该语句将变成下面这样:(假设用户输入值为username=admin, password=abc123)
$sql = "SELECT * FROM login WHERE username='admin' AND password='abc123'";
如果改变输入值为username=‘ OR 1=1-- ,则语句将变为:
$sql = "SELECT * FROM login WHERE username='' OR 1=1 -- ' AND password='abc123'";
在sql语法中"-- "为单行注释符号,因为1=1是恒为真的,所以where字句WHERE username='' OR 1=1 -- '
是恒为真的,而password被注释掉了,所以该sql语句执行后是一定有选择结果的(而且不止一个)。
根据登入判断条件,由于查询结果不为空,所以判断登入成功。