SQL手工注入基础详解---- Access篇

作者:DragonEgg
信息来源: 噩靈戰隊[Evil-Soul Security Team]  http://bbs.x-xox-x.com/
       复习了一下以前学习手工注入时做的笔记,想起以前苦学技术的日子真是感慨万千—别人在背英语句子时,而我在背数据库语句,同样都是英文,可谓煞咱的英语还是不及格呢?言归正传,虽然现在各种SQL注入工具层出不穷,但既然是工具就有出错的时候,并且有的工具并不适用于所有的数据库,有时我们也需要工具目标的情况来灵活的注入,所以学会手工注入是十分重要的,再次便将我的“手工注入学习笔记”分享与大家,老鸟可以飞过,如果有什么不正确的地方欢迎大家批评指正。
                                                      原理篇
    动态脚本语言(如:asp、php、aspx、jsp等)在执行过程中,总要和数据库进行关联,根据带入的变量,来查询指定的数据,然后在用户的浏览器上显示出来,这当中就进行了一次数据库的查询行为,如图1所示即为查询所带入的变量。

当这种对于数据库的行为被我们所控制时,就形成了SQL注入攻击。例如,这是一个正常的URL:“ http://www.hacker.cn/index.asp?ID=8 ”,将这个URL进行提交,并假设服务器将进行类似:select * from news where id="&ID 的查询(news是表名,ID是提交的参数,本例即8),如果客户提交的是:“ http://www.hacker.cn/index.asp?ID=8  and user>0”,如果没有对我们提交的参数进行过滤,服务器就会执行:select * from news where id=8 and user>0 这样的查询,这样的语句肯定是执行不了的,就会报错,显示出错误的原因,即user的内容,如图2。

    用通俗些的例子讲。你是皇帝的传令官,天天都要传达皇帝的命令,有一次皇帝要你去问:今年的国库还有多少金子?(正常URL),你找到相关人员(数据库)问:“今年的国库还有多少金子,国库的密码是不是还在纪晓岚那里?(构造的URL)”相关人员很热心,给你指出错误:“国库的密码不在纪晓岚那里,在和珅那里。”你又跑去问和珅:“国库的密码是不是123?”和珅也很热心,给你指出错误:“不是,是321。(得到敏感数据)”然后你就可以去国库随便拿东西了。
    由此可以看出,注入攻击和数据库的关联要大于和脚本语言的关系。也就是例子中的对什么样的“相关人员”说什么话,对广东的就说广东话,对东北的就说东北话,提交的命令要让数据库能够看懂、执行。常用的数据库有以下几种:Acess、MSSQL、MySQL等,下面将分别进行讲解。(后记1) 
                                                       Access篇 
一:注入点的判断 
    注入的原理前面已经讲过了,我们现在来实战。在判断一个带有参数的URL是不是一个注入点时,可以在URL的最后加一个单引号,即“'”,若是注入点,程序就会把“'”带入查询语句中执行,而语句中并没有另一个“'”与其闭合,程序就会报错,根据报错返回的信息,我们就可以判断数据库的类型,如图3,

返回的信息里面有“Microsoft JET Database Engine”的字样,入侵者依靠它来判断目标数据库为ACCESS数据库。我们也可以在URL后加一个分号:“;”或“--”来使目标报错,分号“;”是MSSQL数据库中用来分离两个语句的符号,“--”是MSSQL数据库中用来注释后面的语句的符号,而access遇到“;”或“--”时,因为语言不通,都会报错。如图4。注意:单引号“'”,分号“;”以及“--”都是在英文状态下输入的。

    以上是特殊符号判断法,还有经典的语句检测法:“ and 1=1”和“ and 1=2”。如果没有对我们提交的参数进行过滤,“ and 1=1”就会带入SQL查询语句中执行,“and”是逻辑语言中“和”的意思。即当and前后两个语句都是正确的话,则为真,程序返回正常;只要有一个语句为假,程序就会报错,对比图5和图6返回的信息。
  
    我们上面所说的都是针对数字型的注入点,但有时我们还会遇到类似id=hacker这样的参数,因为hacker是一个字符,遮掩的注入类型我们称之为字符型注入。当遇到这种情况,我们按以上的语句检测法是没有效果的,因为字符窜类型不想数字型那样直接取值,它需要用单引号包含起来,这样成为一个整体。因此,相应的,我们进行判断时应该改为:“' and '1'='1”或“' and '1'='2”。例如:“ http://www.hacker.cn/index.asp?ID=8'  and '1'='1”和“ http://www.hacker.cn/index.asp?ID=8' and '1'='2”来判断(后记2)。在进行注入时,按照这种格式就行:“' and 语句 and '1'='1”,如图2就是一个字符型的注入点。关于注入点的判断我们就介绍到这里,接下来继续基于Access数据库的注入攻击。 
二:数据的猜解 
    但遇到是Access数据库的目标时,是很郁闷的,因为对于Access数据库来说,我们能做的很少,大多数情况下只能用猜的方式来猜解数据(后记3)。这是一个要拼RP的体力活,要是在RP差的话,就生成个字典去暴力吧。 
    数据在数据库中是以表的形式存在的,一个数据库中有多个表,每个表中还有多个列(字段)。也可以将一个表比作一张课程表,列名就相当于“星期”,至于一天上几节课,就是这个列中有几条(行)数据。 
    言归正传,猜解表要用到如下语句,假如我们要猜解数据库中有没有admin这个表,可以提交“http://www.****.cn/new.asp?id=1&aid=1 and exists (select * from admin)”如果返回正常(还正常访问时显示的一样),就说明存在admin这个表,如图7:

如果不存在admin这个表,就依然会报错,返回和图6一样的信息。这是不是很麻烦?要是猜不到表的话,接下来的操作就无法进行了,所以大家平时一定要注意多搜集一些表名和列名,以备后用。 
    为了让大家更明白的了解每句注入语句的含义,我会详细的解释下每句的意思。exists ()的作用是:()里若是返回结果集,就为真。*是通配符,可代指一个字母或一个单词,代表任意,即存在数据。select * from admin的意思是:在admin这个表中是否存在数据,若存在数据,exists ()就为真,and前后两个语句都为真,程序返回正常;若admin表不存在,就是为空集,exists ()为假,程序报错。因此通过替换“admin”就可以判断替换的表是否存在。 
    我们继续,判断出了表以后,我们接下来就是获取表里面的列名了,提交语句:“http://www.****.cn/new.asp?id=1&aid=1 and exists (select count(username) from admin)”,username是我们猜解的列名,count()的作用是:返回指定条件的行数,count(username)意思是:返回“username”有几行,存在的话返回“1”(列名不能有重复),exists ()就为真,程序返回正常,若不存在的话,返回“0”,即为空集,exists ()就为假,程序报错,改变“username”即可判断输入的列名是否存在,如图8,

存在username这个列,通过以上的尝试,我们确定了admin这个表存在username,password,id这三个列。
    猜解到了列之后我们接下来就是猜解列里的内容了,我们那admin表中的username里的内容演示如何猜解里面的内容。要猜解它的内容,就要先知道它里面内容的长度,要是内容很长的话,就要做好挑灯夜战的准备了,我们提交:
    http://www.****.cn/new.asp?id=1&aid=1 and (select top 1 len(username)from admin)>6
返回的信息如图9,

说明内容长度是不大于6的,即小于等于6,其中len()函数是判断输入的列名的内容的长度,而top 1表示username这个列的第一行内容。
    我们再提交:“http://www.****.cn/new.asp?id=1&aid=1 and (select top 1 len(username)from admin)>3”,返回正常的信息,如图10。

说明内容的长度是大于3的,在4和6之间,最后判断出第一条数据的长度为5。若要猜解第二条数据的长度,可以在top后面的“1”改成“2”来猜解,其他的依此类推。然后将username改成password进行猜解长度,猜出来的长度是16。
    接下来就是判断具体的内容了,一般情况下,我们是用Mid(列名,N,1)来截取列名的第N位字符,再用ASC()函数将截取到的的字符转换为ASCII码:ASCII码又叫美国信息标准码,可以将字母或符号转换为数字,如a的十进制ASCII码为97,我们猜解出来的是ASCII码的值,还需要对其进行转换。为了加快猜解速度,我们可以使用折半法进行猜解。
    我们提交:“http://www.****.cn/new.asp?id=1&aid=1 and (select top 1 asc(mid(username,1,1)) from admin)>97”,返回错误,如图11,

说明username第一位的ASCII码不大于97。我们来继续猜解,再来看看是不是大于60,返回正确,如图12。

最后猜解出大于96又不大于97,说明username第一位的ASCII码为97,即是“a”。我们可以使用“ASCII及进制转换工具”进行转换,如图13。

然后继续猜解第二位,提交:“http://www.****.cn/new.asp?id=1&aid=1 and (select top 1 asc(mid(username,2,1)) from admin)>97”。
    通过千辛万苦的猜解和转换,我们猜解出username第一行的内容为“admin”,然后将username改成password进行猜解,最后就得到了目标的管理员的用户名和密码,而又是密码是经过加密的,我们无法直接使用。最常用的就是md5加密,md5加密算法是不可逆的,若猜解出的密码是16位或32位的数字和字母组成的话,八九成就是md5加密了,如图14。

也有可能是管理员的密码本来就是16位或32位的数字和字母组成的,那就无语了。我们可以在下面几个网站将其解密:
         www.cmd5.com
         http://www.md5.com.cn/
         http://www.md5.org.cn/
    将密文输入,点击解密即可解出原文,如图15,

若解不出,提示NOT FOUND,就只能用工具暴力破解了,如图16就是一款不错的md5破解工具。

    在知道了用户名和密码后,我们可以查找网站的后台,获取webshell,进行提权,也可以进行其它操作。

                                                   后记
1:其它的数据库还有:DB2、Orcale等;
2:因为主要是基础的手工注入文章,便没有提及“文本框搜索型注入”、“cookie注入”和“http头注入”(其实是最近很忙,粗略地找了下注入点,没有找到,惭愧……)。数据的提交类型有:get、post以及cookies。每一种提交方式都可以形成注入攻击,有兴趣的可以查一下相关资料。
3:有时也可以用UNION联合查询来暴,也是最近才听说,还在学习中不怎么熟悉,就不献丑了,来张图证明吧,如图17。

下面有些资料大家可以看看,感谢好友U#0h4x0r提供的资料: http://msdn.microsoft.com/zh-cn/library/bb208962(en-us,office.12).aspx  
其他:文章中的方法名字虽然是我编的(如有雷同,纯属万幸),但方法是别人想出来的。

你可能感兴趣的:(数据库安全,数据库)