·
PHP代码如下:
<?php
//error_reporting(0);
$link =mysqli_connect('localhost', 'root', 'root', 'test');
if (!$link) {
die('Could not connect to MySQL: ' .mysqli_connect_error());
}
$link->set_charset("utf8");
function clean($str){
if(get_magic_quotes_gpc()){
$str=stripslashes($str);
}
return htmlentities($str, ENT_QUOTES);
}
$username =@clean((string)$_GET['username']);
$password =@clean((string)$_GET['password']);
$query='select *from user where username=\''.$username.'\' AND password=\''.$password.'\';';
var_dump($query);//提示:htmlentities函数的效果可以通过右键查看网页源代码来看效果
echo "<br/>";
$result=mysqli_query($link,$query);
if(!$result ||mysqli_num_rows($result) < 1){
die('Invalid password!');
}
$row = mysqli_fetch_assoc($result);
echo "Hello".$row['username']."</br>";
echo "Yourpassword is:".$row['password']."</br>";
?>
分析:(1)观察代码行:
$query='select *from user where username=\''.$username.'\' AND password=\''.$password.'\';';
var_dump($query);
可以知道在网址栏输入的格式为:username=\xxxx&password=……
其中username和password都是字符串类型的变量,所以输入的内容是包含在字符串内的,即包含在两个单引号中间。
(2)如果使用参数是整型的那样的注入方法,结果会很尴尬……
后面一串全都显示出来了……
(3)右键查看网页源代码,那么这串代码的形式就显示出来了,用户名密码都被单引号包含起来了,说明用户名密码都是字符串,在最后还
有
一个’;’……
(4)在遇到了带有引号的SQL查选时,本能的反应就是要逃脱单引号,要么就是生成一个单引号,要么就是省略掉一个单引号。生成单引号的方法我们试过了已经不能实现了,因为htmlentities函数的作用,那么就要考虑省掉一个单引号,上网查阅资料,省掉单引号的一种方法就是使用反斜杠,而本题正好没有过滤掉反斜杠,那么就考虑使用反斜杠。这属于一种SQL注入方式——没有正确过滤转义字符。
此处参考网址:http://blog.csdn.net/wusuopubupt/article/details/8752348
摘录文章中的一段话:
例如,将用户名变量(即username)设置为:
a’ or ‘t’=’t(为什么要这样写?应为name=’username’ –>name=’a’ or ‘t’=’t’ 这样单引号刚好闭合)
,此时原始语句发生了变化:
SELECT * FROM users WHERE name = ‘a’ OR ‘t’=’t’;
如果这种代码被用于一个认证过程,那么这个例子就能够强迫选择一个合法的用户名,因为赋值’t’=’t永远是正确的。
于是我试图构造逻辑式进行注入,记得学长上课的时候讲过用1=0和1=1的判断注入点,那么1=1是一个恒成立的逻辑式,跟上面的形式有一丢丢相似,于是又上网查阅相关资料。
相关网址:http://blog.csdn.net/most_rabbitfishes/article/details/71514118
利用编码技术进行绕过是本题的一个思路,or 1=1即%6f%72%20%31%3d%31
试一试,发现,咦?成功了????于是试了试1=0……emmmm不行,再试试2=2?3=3?……凡是恒等式,n=n均可以,n为整数。
PayLoad:
?username=admin\&password=or 1=1%23