来源:伯乐在线。
一位客户让我们针对只有他们企业员工和顾客能使用的企业内网进行渗透测试。这是安全评估的一个部分,所以尽管我们之前没有使用过SQL注入来渗透网络,但对其概念也相当熟悉了。最后我们在这项任务中大获成功,现在来回顾一下这个过程的每一步,将它记录为一个案例。
“SQL注入”是一种利用未过滤/未审核用户输入的攻击方法(“缓存溢出”和这个不同),意思就是让应用运行本不应该运行的SQL代码。如果应用毫无防备地创建了SQL字符串并且运行了它们,就会造成一些出人意料的结果。
我们记录下了在多次错误的转折后经历的曲折过程,而一个更有经验的人会有这不同的—甚至更好的—方法。但事实上我们成功以后才明白,我们并没有完全被误导。
其他的SQL文章包含了更多的细节,但是这篇文章不仅展示了漏洞利用的过程,还讲述了发现漏洞的原理。
目标内网
展现在我们眼前的是一个完整定制网站,我们之前没见过这个网站,也无权查看它的源代码:这是一次“黑盒”攻击。‘刺探’结果显示这台服务器运行在微软的IIS6上,并且是ASP.NET架构。这就暗示我们数据库是微软的SQLserver:我们相信我们的技巧可以应用在任何web应用上,无论它使用的是哪种SQL服务器。
登陆页有传统的用户-密码表单,但多了一个“把我的密码邮给我”的链接;后来,这个地方被证实是整个系统陷落的关键。
当键入邮件地址时,系统假定邮件存在,就会在用户数据库里查询邮件地址,然后邮寄一些内容给这个地址。但我的邮件地址无法找到,所以它什么也不会发给我。
对于任何SQL化的表单而言,第一步测试,是输入一个带有单引号的数据:目的是看看他们是否对构造SQL的字符串进行了过滤。当把单引号作为邮件地址提交以后,我们得到了错误(服务器错误),这意味着“有害”输入实际上是被直接用于SQL语句了。就是这了!
我猜测SQL代码可能是这样:
[sql]viewplaincopy
SELECTfieldlist
FROMtable
WHEREfield=$EMAIL;
$EMAIL是用户从表单提交的地址,并且这段查询在字符串末端$EMAIL上提供了引号。我们不知道字段或表的确切名字,但是我们了解他们的本质,这有助于我们做正确的猜测。
当我们键入steve
unixwiz.net‘-注意这个末端的引号–下面是这个SQL字段的构成:[sql]viewplaincopy
SELECTfieldlist
FROMtable
WHEREfield=steve
unixwiz.net;当这段SQL开始执行,SQL解析器就会发现多余的引号然后中断执行,并给出语法错误的提示。这个错误如何清楚的表述给用户,基于应用内部的错误恢复规程,但一般来说都不会提示“邮件地址不存在”。这个错误响应成了死亡之门,它告诉别人用户输入没有被正确的处理,这就为应用破解留下了可乘之机。
这个数据呈现在WHERE的从句中,让我们以符合SQL规范的方式改变输入试试,看看会发生什么。键入anything’OR‘x’=‘x,结果如下:
[sql]viewplaincopy
SELECTfieldlistFROMtableWHEREfield=anythingORx=x;
因为应用不会思考输入–仅仅构造字符串-我们使用单引号把WHERE从句的单一组成变成了双组成,’x=‘x’从句是恒成立的,无论第一个从句是什么。(有一种更好的方式来确保“始终为真”,我们随后会接触到)。
但与每次只返回单一数据的“真实”查询不同,上面这个构造必须返回这个成员数据库的所有数据。要想知道在这种情况下应用会做什么,唯一的方法就是尝试,尝试,再尝试。我们得到了这个:
你的登录信息已经被邮寄到了random.person
example.