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代替注释#和--+,如果没问题剩下的套路都一样