曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4094|回复: 0
打印 上一主题 下一主题

[ASP+ACCESS] 一次注入测试

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2013-3-19 18:48:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文的目的不是要攻击一个网站,而是将此测试记录下来,以了解相关知识之目的;并且这种 ASP 注入测试早在 N 年前已经流行,而现在看起来算是很过时的东西了,但是网上存在此类漏洞的网站仍然有不少。虽然使用一些自动化的注入工具可以很轻松的达到快餐式的入侵目的,但如果不是在了解背后的细节下,这样做不但很快会乏味,而且每次都会有种意犹未尽的感觉。下面叙述此次的记录。由于本文涉及的网址链接为真实链接,因此不直接给出网址文字形式。

首先找到下面这个可供测试的站点链接:

像这样的 xxx.asp?id= 的网址片段是注入多发地段,因为 id= 的后面常会跟着一个参数,而服务器的后台 asp 处理页面会将此参数取出,并放到数据库语句里查询,最后返回相关的结果给客户,比如会有这样的 SQL 语句:select * from News where id=224 。因此,在处理这种涉及到数据库查询的语句里,若是对参数过滤不严,那么就容易产生注入的漏洞。

习惯的,我们在上面的这个网站后面加一个分号,看看网站有没有对这个最基本的小符号进行过滤:

由提示出来的错误信息我们可以知道该网站使用的数据库类型基本上就是 Access 数据库了。

使用经典的 1=1 和 1=2 测试法。

可以分别在上面的网址的后面加上 and 1=1 和 and 1=2 来测试,如果加 and 1=1 时显示的是正常页面,而加 and 1=2 显示的是错误页面,那么说明存在 SQL 注入漏洞。该漏洞的实质就是,网站后台并没有过滤网址里提交的参数中包含 SQL 查询语句,而是直接把恶意提交的查询语句作为实际查询数据库动作的一部分,因此就带来了注入问题。

下面的工作就是猜解表名了。

使用 select count() 来转换查询类型
我们可以如下提交:

从出错的信息中我们可以知道,tmp 这个表并不存在;因此我们可以通过此法不断的尝试猜解,直至得出正确的表名。当然,猜解表名也是需要靠运气或者经验的,如果表名起得比较复杂,那么我们也就很难猜解其名了。自动注入工具往往自带一个表名数据库,里面收集了常见的表名。

可能会问,我们是否可以将提交的语句直接写成 and select count(*) from tmp 而不是 and (select count(*) from tmp)>0 么?当然不行,这样会导致语法错误,因为 SQL 语法解析器会将其当成类似下面的语句形式:
select * from where id='224 and select count(*) from tmp'
显然这是不正确的;而使用后者就没有问题,它最后会演变为:
select * from where id = 224 and (select count(*) from tmp)>0
and 后面跟着一个 TRUE 或 FALSE 的条件是可以的;当该条件为 TRUE 时,网页会正常显示,否则会像上面那样提示找不到该表。

“select count(*) from 表名” 是统计指定表中的所有记录数目。如果表名存在,那么返回值必然大于等于 1 ,也就是会符合 >=0 这样的条件,也就是等价于 and 1=1 这种语句。

幸运的是,在这次测试中,网站数据库里所用的表名很简单,就是 admin 。

也可以使用下面的语句对表名进行猜解:



表名既已得出,那接下来就要猜解字段名。猜解字段名也可以使用上面的 select count() 方法,比如:

和上面猜解表名不同的是,这时 count() 函数中使用了字段名作为参数,如果字段名不存在,那么它会返回错误提示:

错误信息为:至少一个参数没有被指定值。
我们可以在电脑上打开一个 Access 数据库,并执行一段类似的查询语句(count() 中给出一个不存在的字段名),Microsofe Access 也会提示我们输入参数,比如:

这是因为,由于给出不存在的字段名,那么它就认为你没有给出有效参数。

按照此法,猜解出了存在两个重要的字段名 adminname 和 adminpass ,从名字上容易猜到,它们分别对应了管理员名和管理员密码。

在得出关键字段后,接下来就要猜解管理员名和密码了。这项工作使用 ASCII 逐字解码法。该方法猜解速度较慢,但成功率会比较高。

首先,我们来猜解管理员账号的长度,使用如下语句:

上面,top 1 表示选择第一条记录;len() 函数可以获取字段的长度。这里就是测试第 1 条记录的字段长度,首先我们看下长度是否大于 5,有返回的页面知道管理员的账号长度是小于 5 的。那我们再测试是否 > 3,这时返回正常页面,这就说明管理员的账号长度是 4 。

接下来,我们猜解用户名是什么,提交下面的语句:

这里,使用了 mid() 函数,该函数用来从文本字段中提取字符,它一共有 3 个参数。第 1 个参数是字段名,第 2 个参数是起始位置,第 3 个参数是提取的长度。因为我们每次只猜解 1 位,因此第 3 个参数恒为 1,不做改变;而第 2 个参数会依次递增。

asc() 函数是将该字符进行 ascii 码转换。因此我们可以依次判断 >10, > 20,>30 ,直到得到正确的字符。比如管理员的账号为 admin(假设还不知道),且已经知道 a 的 ASCII 码为 97,因此当我们使用上面的语句判断 >97 时必须出错,这样自然就可以知道管理员账号的第 1 个字符为 a 。又由于上面已经知道了管理员账号的长度,因此只要以此类推下去,必然可以获得正确的管理员账号。

猜解管理员密码依照同样道理,这里就不再赘述。

这就是最为普通的 SQL 注入知识。其经历有几个过程:
猜解表名 ---> 猜解字段名 ---> 猜解字段值长度 ----> 依次获取字段值中的每个字符

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-3 12:37 , Processed in 0.079422 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表