http://www.wechall.net/challenge/training/mysql/auth_bypass2/index.php
这又是一道SQL注入题。只不过这道题比 MySQL I 要难一点的是username和password要分开验证了。
可以看看题目提供的代码。
它的逻辑是:先查一下username,如果这一行存在的话,就把这一行的password与用户输入的password进行对比,如果正确则通过。这样分开验证的意思是password是一定要有的,不能再通过 MySQL I 的伎俩去掉password验证的环节了。
但是留下的漏洞仍然是很明显存在的,也就是程序没有对用户输入的字符串进行检查和过滤。
既然没有,那么这一定是一个注入点。
思路就在于SQL语法中,SELECT后面是可以直接跟一行的值,也就是一个记录的。
什么意思?SELECT 1,2,3 是可以出来一行 1,2,3 的。
还有另一个思路就是SQL的合并操作符UNION。
所以总体的思路就是——空集union一个自己编的一个记录。
但是呢,UNION有一点东西要注意的:UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。
上面的要求对我们自己编的记录做出了限制,我们不能瞎来,那我们怎么知道该怎么编呢?
不愧是很好的教育网站,这都有写。可以看看提供的代码最前面的注释。
同之前的bypass1要求一样,我们都要以admin的身份login。因此我们可以构造这样的一个记录:
1, admin, md5(‘admin’)
那么SQL的注入语句可以这样构造:
1 |
SELECT * FROM users WHERE username='' union select 1,'admin', md5('admin') #' |
别忘了最后加一个#注释掉最后的引号,因为前面已经闭合掉了。
这样做之后,数据库查询到的记录就是我们自己编的那一个。所以password我们只要输入admin就可以通过验证了。