新闻资讯 >> 文档资料 >> 网络技术 >> [资料]SQL注入一般步骤与注入常用函数
  • [资料]SQL注入一般步骤与注入常用函数

  • 刊发日期:2005-7-29 (20年前)    本文作者:网络    刊发部门:岭峰网技术部    阅读次数:14509
  • 友情提示:我们的程序已经解决了本文所说的安全问题。:)

    学习如何从数据库中获取想要获得的内容,首先,我们先看看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之间,可以用折半法加速猜解,如果写成程序测试,效率会有极大的提高。

    一、MS-SQL中的汉字猜测

    可以说MS-SQL下的汉字是不用猜测的,你只要构造的条件足够的好,可以直接让对方在报错的时候将数据内容直接显示出来。通常的做法是把你要猜的内容所在的列做上一个其它类型的运算,这样由于执行中进行了错误的类型转换,会使得查询失败并且返回错误信息,而要猜的内容正好在信息中,例如:

    select * from sysusers where [name]+1=2

    name列是nvarchar,要让他做加法运算,铁定是出错:

    Syntax error converting the nvarchar value 'public' to a column of data type int.

    我们应该可以直接从返回的错误中获得需要的信息,例如这里的public。
    所以说,MS-SQL下的汉字猜测,没有太大的必要去花大力气。

    二、ACCESS中汉字字符的猜测

    ●汉字字符的确定

    很简单,如果你发现一个网站是中文的,而且在注入的时候发现有异常的情况,你猜测的内容很有可能就是中文。通常我们这样确定:

    ... 0<>(select count(*) from admin where left(xxx,1) between char(20) and char(254)).....

    这是想只是在可见字符中进行猜测,如果这么大的范围都出了问题,可以试试看这个:

    ... 0<>(select count(*) from admin where left(xxx,1) between char(254) and char(255)).....

    如果这个条件是满足的,很不幸,你遇上中文了。

    ●间接的猜测法

    如果是中文,对于列中各条数据进行left、right等运算的时候,没有把一个汉字拆开来,也就是说如果有一条记录是“0我1”,那么:

    right(left(xxx,1),1) = 0
    right(left(xxx,2),1) = 我
    right(left(xxx,3),1) = 1

    马上有人就想到了转换成整数来猜测,然后返回去算出到底是什么汉字。这确实是可以的,而且想法很巧妙,通常的办法是构造如下的条件

    asc(right(left(xxx,N),1)) < -XXXXX

    经验上来说,小于符号后面这个数应该在-10000以下,然后通过具体注入时候得到的结果,不断的缩小范围,最后得到一个很小的负数。当确定这个负数后,可以先用计算器算出十六进制的代码,然后用编辑软件得到汉字。比如说你得到的确定的整数是-10532,用计算器转换后应该得到的是D6DC,在UltraEdit中用十六进制编辑,可以看到D6DC获得的是一个“周”字。

    ●直接的猜测法

    如同猜测非中文字符一样,中文字符也可以用between来逐步缩小范围,最后得到一个准确的汉字。这种方法的关键在于了解between作用于汉字的时候到底是怎样处理的,开始我在这方面走了一些弯路,后来多亏了小霸王(46466397),才得以彻底搞清,原来同我开始想的不一样,between对汉字的比较,是通过它们之间的unicode编码的先后顺序来的。我在网上没有搜索到unicode编码的表,在小霸王的指点下自己做了一份。
    在猜测的时候,依然是逐步的缩小范围,对于汉字的确定,用最大范围上的between可以一下子获得,例如下面这个查询查询条件,可以确定被猜测的数据一定是汉字:

    ... right(left(xxx,N),1) between '一' and '翿'

    由于unicode编码的汉字并不是按照常用的程度来排列的,事实上给猜测带来了很大的麻烦,一般我倾向于写程序来猜测,两种方法的时间复杂度一样,感觉上用第二种方法编写程序可能更为简单。

    ●适用范围

    应该说是都适用的。不过第二种方法一般要用到',有过滤的时候不通用。手工猜的话第一种方法应该很通用了,我也做了一个转换的小工具,直接由一个负整数获得对应的汉字。

    ●其它

    两种方法对于远东字符的猜测都有效,而且应该对各种非ASCII码的猜测都有效。如果有对日文/韩文等进行注入,可以简单的利用上面的方法,不同的只是编码而已。

  • 信息来源:网络
    信息提供:岭峰网技术部
    责任编辑:疾风之狼
  • 全国服务热线:0371-5501-9681    技术服务QQ:85112407    支持信箱:fuwu@wendalf.com
文章搜索: