我们已经知道为什么出现注入了,那么如何判断一个提交变量的数据库查询存在注入呢?
我们看到select * from admin where id=1像这样的查询语句如果我们在后面加个“”就会导致程序程序因为不匹配“”出现语法错误。
而在前台输入会由于conn.代码添加了容错语句导致不会报错而,查询语句不会查询到任何信息所以会返回“暂无记录”。
这里我们把容错语句On Error Resume Next删掉。然后刷新页面就会发现已经出现查询错误了。
虽然这样是可以判断是否出现注入的,但是并不是所有的程序加上“”出现错误都是注入漏洞的。修改sql.asp文件内容为如下代码:
<!--#include FILE='conn.asp'-->
<%
set rs=server.CreateObject('adodb.recordset')
sql='select * from admin where id='&cint(request('id'))
response.write 'sql语句为:'&sql
rs.open sql,conn,1,2
if rs.eof or rs.bof then
response.write '<br>暂无记录'
else
response.write '<br>返回信息是:'&rs('username')
end if
rs.close
set rs=nothing
set conn=nothing
%>
上面代码只在request获取内容后加了一个cint函数,cint函数的作用是强制转换表达式为数字类型,但是如果表达式不是数字类型则会出现页面错误而导致返回错误。如图:
这样就会因为错误而导致不可执行,但是我们并不能就由此判断因为cint导致变量id被过滤,所以我们还是要在conn.asp做容错处理,这样在上图的错误不会出现的情况下看sql是否被赋值。
在图中已经看到了,虽然cint错误被容错处理还会执行下面的代码,但是sql变量因为cint的错误导致赋值失败变为空值,所以就不会查询任何信息。(关于过滤会在以后的防注入章节中讲到)
所以利用“”并不能准确的判断sql注入漏洞,这时候就出现另一种方式来判断是否有sql注入漏洞,因为前面的sql查询肯定是正确的那么就利用and来连接一个判断(and是布尔运算符,只有两边同时为真时则为真,否则皆为假),这里就会利用到大家小学就会的1=1和1=2了,1=1肯定是真了,而1=2肯定为假了(所以赵大叔会说在算错的情况下1才等于2呢)。这样我们的sql语句就会变为select * from admin where id=1 and 1=1,在这里select * from admin where id=1是真而后面的1=1也为真所以整个查询语句为真,就会查询出内容。
当我们的sql查询语句变为select * from admin where id=1 and 1=2时,前面的select * from admin where id=1肯定还是为真,但是后面的的1=2为假导致整个语句为假。所以在网页中则会查询不到信息。这时就可以断定我们输入的语句已经被sql执行并且按照我们的要求来返回内容,所以存在注入漏洞。
而当添加过滤数字类型函数cint就会导致整个sql语句未被赋值而导致无法注入。(还有其他很多过滤函数和语句不通的地方会在以后的章节讲解)
------分隔线----------------------------
联系客服