万能密码欺骗的一般原理

PHP 登录后台的防注入攻击

如今,互联网上的攻击、入侵事件频发,攻击手段越来越多样,攻击工具也泛滥成灾,这其中尤其以注入攻击最为常见。因为这种攻击方式技术门槛低,攻击工具多。注入攻击利用网站页面的用户提交数据功能,恶意编造具有攻击破坏性质的特殊数据字符串,提交给网站执行。如果网站源代码设计不健壮,对提交的数据没有做严格的防范过滤,就很容易被利用,黑客可以以此为突破口,攻入网站服务器。

万能密码欺骗的一般原理

每个网站都要发布信息、更新内容,必须有登录后台,有登录就有提交。每个试图入侵网站的人都想用最快最简单的方法达到目的,猜测或破解后台密码显然是一种高效的手段。于是网络上便有了破解后台登录的万能密码。

下面结合语句进行具体分析。

来看一下这条语句:

  1. SELECT * FROM admin WHERE Username=
  2. ‘”.$username.”‘ AND Password= ‘”.$password.”‘

这是一个标准的SQL 查询语句,查找表里面记录的用户的账号密码和用户提交的账号和密码是否匹配,如果查找到或者查找成功(找到和查找成功有非常大的区别,万能密码正是利用了这一点),则系统就认为您是合法的管理员了。

正常的思路是如何猜对用户名和密码,即从“找到”的角度出发,从而成功非法侵入。显然,猜对的可能性非常小。于是有人另辟蹊径,从“查找成功”入手。

分析这条语句,要让其“查询成功”,只要让电脑“认为”查询结果为真即可,而不必理会用户名和密码,于是有人想到了逻辑运算“OR”,只要“OR”一个真值,电脑就认为查询成功了。

这里我们假设在用户名处输入 1′ or 1=1 or ‘1’=’1,密码随便输入,假设输入“123”,那么上面这条语句在执行时就变成了:

  1. SELECT * FROM admin WHERE Username=’1′
  2. OR 1=1 OR ‘1’=’1′ AND Password=’123′

分析一下语句的逻辑判断,看看是怎样执行的。

首先,逻辑运算的优先顺序是NOT>OR>AND(非> 或> 与)。根据这样的优先顺序,上面语句中先执行的是’1’=’1′ AND Password=’123’,’1’=’1′ 条件当然为真,Password=’123′ 为假(当然也有例外,那就是管理员真的把密码设成123),所以,进行AND 操作后,结果为假。

相应地,语句中Username=’1′ 条件为假,1=1 条件为真,那么简化一下逻辑判断,就是“假OR 真 OR 假”。显然这条语句经过逻辑运算后其结果为真。

这样,虽然没有提交正确的用户名和密码,但却得到了一个结果为真的逻辑判断,从而成功地骗过电脑,侵入了系统。

 

回到PHP 环境下,为了防止上面提到的类似万能密码的欺诈,PHP 中专门有一个安全选项是针对这招的,就是magic_ quotes_gpc 项。

设置magic_quotes_gpc =ON,提交数据中的单引号在执行时会被转义成“\’”。

还以上面的语句为例,当我们把用户名输入成1’or1=1 or ‘1’=’1 时,SQL 语句就变成了:

  1. SELECT * FROM admin WHERE Username=’1\’
  2. OR 11=1 OR\’1\’=\’1\’ AND Password=’123′

这样就无法绕过密码验证了。所谓道高一尺,魔高一丈,针对这样的安全设置,网上又出来一种新构造的字符串的攻击方式,即:

‘OR 1=1 后面跟注释符。如,’OR 1=1/* ,或 ’OR1=1// ,或 ’OR 1=1#。

其基本思想是把不好构造处理的部分统统利用注释符注释掉。还是以上面的语句为例,假设用户名输入‘OR1=1/* 那么SQL 语句就变成了:

  1. SELECT * FROM admin WHERE Username
  2. =’1\’ OR 11=1/* OR \’1\’=\’1\’ AND Password
  3. =’123′

由于“/*”在PHP 中表示注释的意思,其后的部分是不执行的,结果上面的语句实际上执行的是:

  1. SELECT*FROM admin WHERE Username=’1\’ OR 11=1

经过逻辑运算,结果仍为真,这样就再次成功地骗过了电脑。

 

 

应对办法

 

对从页面提交的数据,无论是什么性质的数据,在执行查询等数据库操作前,一定要对提交上来的字符串进行过滤。

首先, 要过滤掉一些可能带来潜在威胁的, 诸如”‘,<,>,””,or,OR,and,AND,script,SCRIPT,;,FROM,from,delete,DELETE,update,UPDATE,-” 等字符,把字符串中的这些字符全部替换掉,一个不留。

另外,还有个相对简单一点的过滤办法,就是清除字符串中所有的空格字符。

要构造注入攻击语句,少不了OR 等逻辑运算符,而逻辑运算符有效执行而不是被当作字符,就需要空格字符分隔。把所有的空格字符全部清除掉,等于去掉了OR 等字符串作为逻辑运算符的功能。

再以前面的语句为例,清除空格字符后,语句变成了:

  1. SELECT * FROM admin WHERE Username=’1\’OR1=1

经过过滤处理后,构造的语句显然没有攻击功能了。

也就是说,过滤提交字符串可以有效抵御注入攻击。