可以肯定的是,我们能在登陆页进行密码的暴力破解,但是许多系统都针对此做了监测甚至防御。可能有的手段有操作日志,帐号锁定,或者其他能阻碍我们行动的方式,但是因为存在未过滤的输入,我们就能绕过更多的保护措施。
我们在构造的字符串里包含进邮箱名和密码来进行密码测试。在我们的例子中,我们用了受害者bob@example.com 并尝试了多组密码。
SELECT email, passwd, login_id, full_name FROM members WHERE email = '<a href="https://www.linuxidc.com/mailto:bob@example.com">bob@example.com</a>' AND passwd = 'hello123';这是一条很好使的SQL语句,我们不会得到服务器错误的提示,只要我们得到“your password has been mailed to you”的提示信息,就证明我们已经得到密码了。这时候受害人可能会警觉起来,但谁关心他呢,我们已经得到密码了。
这个过程可以使用perl脚本自动完成,然而,我们在写脚本的过程中,发现了另一种方法来破解系统。
数据库不是只读的迄今为止,我们没做查询数据库之外的事,尽管SELECT是只读的,但不代表SQL只能这样。SQL使用分号表示结束,如果输入没有正确过滤,就没有什么能阻止我们在字符串后构造与查询无关的指令。
The most drastic example is:
这剂猛药是这样的:
SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x'; DROP TABLE members; --'; -- Boom!第一部分我们准备了一个伪造的email地址——‘X’——我们不关心查询结果返回什么:我们想要得到的只是我们自己构造的SQL指令。这次攻击删除了整个members表,这就不太好玩了。
这表明我们不仅仅可以切分SQL指令,而且也可以修改数据库。这是被允许的。
添加新用户我们已经了解了members表的局部结构,添加一条新纪录到表里视乎是一个可行的方法:如果这成功了,我们就能简单的用我们新插入的身份登陆到系统了。
不要太惊讶,这条SQL有点长,我们把它分行显示以便于理解,但它依然是一条语句:
SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x'; INSERT INTO members ('email','passwd','login_id','full_name') VALUES ('steve@unixwiz.net','hello','steve','Steve Friedl');--';即使我们得到了正确的字段名和表名,但在成功攻击之前我们还有几件事需要了解:
在web表单里,我们可能没有足够的空间键入这么多文本(尽管可以用脚本解决,但并不容易)。
web应用可能没有members表的INSERT权限。
母庸置疑,members表里肯定还有其他字段,有一些可能需要初始值,否则会引起INSERT失败。
即使我们插入了一条新纪录,应用也可能不正常运行,因为我们无法提供值的字段名会自动插入NULL。
一个正确的“member”可能额不仅仅只需要members表里的一条纪录,而还要结合其他表的信息(如,访问权限),因此只添加一个表可能不够。
在这个案例里,我们遇到了问题#4或#5,我们无法确定到底是哪个—— 因为用构造好的用户名登陆进去的时候,返回了服务器错误的提示。尽管这就暗示了我们那些没有构造的字段是必须的,但我们没有办法正确处理。
一个可行的办法是猜测其他字段,但这是一个劳力费神的过程:尽管我们可以猜测其他“显而易见”的字段,但要想得到整个应用的组织结构图太难了。
我们最后尝试了其他方式。
把密码邮给我我们意识到虽然我们无法添加新纪录到members数据库里,但我们可以修改已经存在的,这被证明是可行的。
从上一步得知 bob@example.com 账户在这个系统里,我们用SQL注入把数据库中的这条记录改成我们自己的email地址:
SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x'; UPDATE members SET email = <a href="mailto:'steve@unixwiz.net">'steve@unixwiz.net</a>' WHERE email = <a href="mailto:'bob@example.com">'bob@example.com</a>';运行之后,我们自然得到了“we didn’t know your email address”的提示,但这在预料之中,毕竟我们用了假的email地址。UPDATE操作不会通知应用,因此它悄然执行了。
之后,我们使用了“I lost my password”的功能,用我们刚刚更新的email地址,一分钟后,我们收到了这封邮件:
From: <a href="https://www.linuxidc.com/mailto:system@example.com">system@example.com</a> To: <a href="https://www.linuxidc.com/mailto:steve@unixwiz.net">steve@unixwiz.net</a> Subject: Intranet login This email is in response to your request for your Intranet log in information. Your User ID is: bob Your password is: hello现在,我们要做的就是跟随标准的登录流程进入系统,这是一个高等级职员,有高级权限,比我们INSERT的用户要好。