mirror of
https://github.com/gelusus/wxvl.git
synced 2026-10-27 19:10:56 +00:00
正在获取URL...
chainreactors: 5 个URL BruceFeIix: 14 个URL Doonsec: 40 个URL 总共去重后: 54 个URL 路径遍历漏洞:一个下载接口引发的系统文件泄露、16岁研究员发现微软身份验证漏洞,导致17.3万亿条记录泄露、
This commit is contained in:
1 parent
b047ebf5ba
commit
e6f4555893
3 files changed
+199
-1
No files matched your search
@@ -27242,5 +27242,7 @@
|
||||
"https://mp.weixin.qq.com/s/BuobyZqHMxVvsBL7XUepBg": "CNNVD | 人工智能重要漏洞通报(2026年第十四期)",
|
||||
"https://mp.weixin.qq.com/s/DiDJKzTMpC9q2cqxpz4oCA": "【安全圈】MCP官方SDK高危漏洞:恶意服务可盗取OAuth凭证",
|
||||
"https://mp.weixin.qq.com/s/XLId0bCdiNJaRoTSMN0c1A": "【漏洞预警】Citrix NetScaler 命令注入漏洞",
|
||||
"https://mp.weixin.qq.com/s/_Z38qSHvDhI-X5NwN9SnAg": "(10分) CVE-2026-102240:Netcore AP未认证命令注入,一条GET拿root"
|
||||
"https://mp.weixin.qq.com/s/_Z38qSHvDhI-X5NwN9SnAg": "(10分) CVE-2026-102240:Netcore AP未认证命令注入,一条GET拿root",
|
||||
"https://mp.weixin.qq.com/s/-ps4Hty70QFXHX1bRSjpeg": "路径遍历漏洞:一个下载接口引发的系统文件泄露",
|
||||
"https://mp.weixin.qq.com/s/JyXkDWmGtCn2rYsY9iEoMQ": "16岁研究员发现微软身份验证漏洞,导致17.3万亿条记录泄露"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
# 16岁研究员发现微软身份验证漏洞,导致17.3万亿条记录泄露
|
||||
原创 ZM
|
||||
ZM 暗镜 2026-09-29 22:00
|
||||
|
||||
一位名叫 Faav 的 16 岁安全研究员发现了微软内部 Titan 分析服务中的一个重大身份验证漏洞。
|
||||
|
||||
该漏洞可能允许攻击者冒充管理员并运行未经授权的 SQL 查询。研究人员估计,存在漏洞的环境包含 17 个相互连接的分析数据库中存储的 17.3 万亿行数据。
|
||||
|
||||
然而,这个数字代表的是潜在可访问的数据量,并不代表实际访问的记录数量、泄露的数据量或涉及的独立个体数量。
|
||||
|
||||
该问题源于对JSON Web Tokens (JWT)的验证不当。据报道,Titan 检查了令牌声明,例如租户 ID、受众、应用程序 ID 和用户身份。
|
||||
|
||||
然而,它并未对 JWT 签名进行加密验证。因此,攻击者可以在保持签名无效或缺失的情况下修改身份声明,从而破坏旨在证明令牌来自可信身份提供商的关键安全控制措施。
|
||||
|
||||
研究人员利用人工智能辅助侦察技术识别出了 Titan,这是微软的一项内部分析服务,其网页界面受到“需要 VPN”页面的保护。然而,一个独立的 API 端点却可以公开访问。该端点暴露了一个 Swagger 文档,其中列出了多个路由,包括 /v2/Query,该路由接受原始 SQL 查询。
|
||||
|
||||
初始未经身份验证的请求返回HTTP 401 错误,表明 API 需要授权令牌。随后,Faav 使用来自外部 Entra 租户的令牌测试了该服务如何处理 JWT 声明。
|
||||
|
||||
研究人员通过修改令牌字段发现,即使原始签名保持不变,Titan 也能处理已更改的租户、受众和应用程序值。这强烈表明该服务在未验证其完整性的情况下就信任了声明。
|
||||
|
||||
研究人员使用数据库元数据而非批量数据提取,估算出总共存储了 17,333,335,124,315 行数据。该估算值可能包含历史记录、副本、重复条目和衍生数据集;不应将其解释为 17.3 万亿条客户记录或 17.3 万亿个受影响个体。
|
||||
|
||||
对元数据的有限访问暴露了大约 25,000 条帐户和电子邮件记录、17,990 条员工电子邮件记录、15,001 条员工组织记录、仪表板定义、数据集元数据和数据库配置。
|
||||
|
||||
研究人员还对 Bing 分析数据运行了两个单行查询,但表示没有访问任何客户个人身份信息 (PII),没有识别任何用户,也没有执行任何跨服务关联。
|
||||
|
||||
Faav 于 2026 年 9 月 5 日向微软安全响应中心报告了该问题,案件编号为 144051。微软于 9 月 9 日限制了对暴露的 API 端点的访问,并于 9 月 17 日向该研究人员奖励了 5000 美元。微软表示,此次协调披露有助于加强其服务并更好地保护客户。目前尚无公开证据表明该漏洞在修复前曾被恶意利用。该事件凸显了 JWT 的一个基本安全要求:应用程序必须拒绝未签名的令牌,强制执行显式签名算法,根据受信任的密钥验证令牌签名,然后才能处理与颁发者、受众、租户和用户身份相关的声明。
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
# 路径遍历漏洞:一个下载接口引发的系统文件泄露
|
||||
原创 钟智强
|
||||
钟智强 哪吒网络安全 2026-09-29 17:38
|
||||
|
||||
只改了几个字符,服务器就把整个系统文件交了出来
|
||||
|
||||
路径遍历 | 目录穿越 | 白名单校验 | 攻防复盘
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 一、一个再普通不过的下载功能
|
||||
|
||||
那天我在看一个医疗平台的下载接口。功能很平常:页面上放一个链接,点一下,取回一份文件。这类接口在任何业务系统里都无处不在——下载报告、下载附件、下载图片。
|
||||
|
||||
我做的动作也很小:把链接里那个文件名,换成了一串“往上退”的符号。然后服务器回了我一个两百(请求成功)。接着,它把系统里最不该给人看的那份系统口令文件,一行一行、原封不动地打了出来。
|
||||
|
||||
整个过程,我没有拿到任何账号,没有绕过任何登录,没有碰任何密码。我只是改了地址栏里的几个字符。
|
||||
# 二、这个漏洞到底是怎么发生的
|
||||
|
||||
它有个正式的名字,叫路径遍历,也有人叫它目录穿越、点点斜杠、向上回溯。道理其实特别朴素。
|
||||
|
||||
一个正常的下载链接长这样:服务器把你要的文件名,拼在一个固定的目录后面,然后去硬盘上取。比如目录是“存放文件的文件夹”,你要的是“报告文件”,它就变成“存放文件的文件夹 / 报告文件”。
|
||||
|
||||
问题出在哪?那个文件名,是你传的。
|
||||
|
||||
于是你传的不是文件名,而是“往上退一层、再往上退一层……退到根目录,然后取系统口令文件”。服务器老老实实地照做了。它没有意识到自己被骗,它只是觉得你要的文件路径有点长。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
图 一 | 路径遍历攻击链:四个环节,缺一不可
|
||||
|
||||
用开放网页应用安全项目的原话说就是:通过操纵引用文件的变量,访问存放在网页根目录之外的文件与目录,包括应用源代码、配置文件和系统关键文件。
|
||||
|
||||
一句话总结:你让服务器去拿东西,却没告诉它只能在哪个柜子里拿。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
图 二 | 正常取文件 与 恶意穿越 的路径对比
|
||||
# 三、实战复现:两张截图说清整个过程
|
||||
|
||||
下面两张图,是同一次排查里的真实请求记录。目标信息已做脱敏处理。
|
||||
## 截图一:读到了系统口令文件
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
图 三 | 下载参数被改成“连续往上退四层,再取系统口令文件”。服务器返回两百(请求成功),并把系统口令文件的正文直接回显在响应里。注意响应头里那串重复出现的会话凭证字段——这同样是从这一个请求里带出来的。
|
||||
|
||||
这张图说明的第一件事:穿越真实生效了,不是理论。
|
||||
|
||||
那串重复的会话凭证字段,本身也是个信号:响应在处理“删除用户凭证”这类动作,说明这条请求链路后端还挂着别的状态逻辑,值得单独再看一眼。
|
||||
## 截图二:读到了应用自己的文件
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
图 四 | 同一个下载参数,这次指向站点自身目录下的某个脚本页面。服务器同样返回两百(请求成功),内容类型显示为网页文本,页面标题是一张“联系我们”页——说明这次穿越读到的,是应用自己的文件。
|
||||
|
||||
这张图说明的第二件事,比第一张更严重:
|
||||
|
||||
能读系统文件,意味着拿到了服务器;能读应用文件,意味着拿到了源码。
|
||||
|
||||
源码里有数据库连接方式、有接口地址、有内部逻辑、有写死的密钥。攻击者拿到源码之后,后面的每一步都会变得容易得多。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 四、为什么“过滤一下”根本没用
|
||||
|
||||
很多人第一反应是:那我过滤掉“往上退”的那几个字符不就行了?不行。原因是攻击者的花样远比过滤名单多。
|
||||
## 实际请求里见过的变形写法
|
||||
<table><tbody><tr><td data-colwidth="602" width="602" valign="top" style="background: rgb(242, 244, 247);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:Times New Roman;mso-ascii-font-family:Times New Roman;mso-fareast-font-family:思源黑体;font-variant:normal;text-transform:none;"></span></p><p><span leaf=""> </span></p><p></p></td></tr><tr><td data-colwidth="602" width="602" valign="top" style="background: rgb(242, 244, 247);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">【同一意图的多种变形写法 · 中文示意】</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:Consolas;mso-ascii-font-family:Consolas;mso-fareast-font-family:思源黑体;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span style="mso-spacerun:yes;"><span leaf=""> </span></span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">原形 :连续向上回退四层,再取系统口令文件</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">变形一 :把回退符号写成「百分号 + 数字」的形式</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">变形二 :只编码其中一部分,其余保持原样</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">变形三 :在编码之上再编码一层(服务端默认只解一层)</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">变形四 :改用另一种系统也认的分隔符写法</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">变形五 :干脆不用回退,直接报完整的绝对路径</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">变形六 :文件名后塞一个空字节,再补一个合法后缀</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:Consolas;mso-ascii-font-family:Consolas;mso-fareast-font-family:思源黑体;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span style="mso-spacerun:yes;"><span leaf=""> </span></span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">说明:上述六种写法,服务端解析后指向的是同一个目标。</span></span></p><p style="margin-tLine truncated
|
||||
|
||||
|
||||
|
||||
|
||||
代码一 | 同一意图的多种写法:过滤名单永远追不上变形速度
|
||||
## 五种绕过手法一览
|
||||
<table><tbody><tr><td data-colwidth="107" width="107" valign="top" style="background: rgb(213, 232, 240);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;font-weight:bold;mso-bidi-font-weight:bold;"><span leaf="">手法</span></span></p></td><td data-colwidth="220" width="220" valign="top" style="background: rgb(213, 232, 240);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;font-weight:bold;mso-bidi-font-weight:bold;"><span leaf="">做法</span></span></p></td><td data-colwidth="275" width="275" valign="top" style="background: rgb(213, 232, 240);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;font-weight:bold;mso-bidi-font-weight:bold;"><span leaf="">为什么过滤失效</span></span></p></td></tr><tr><td data-colwidth="107" width="107" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">编码绕过</span></span></p></td><td data-colwidth="220" width="220" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">把回退符号写成百分号加数字的形式</span></span></p></td><td data-colwidth="275" width="275" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">过滤比对的是编码后的字符串,看不出危险</span></span></p></td></tr><tr><td data-colwidth="107" width="107" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">双重编码</span></span></p></td><td data-colwidth="220" width="220" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">在编码之上再编码一层</span></span></p></td><td data-colwidth="275" width="275" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">服务端默认只解一层,过滤与系统看到的不是同一串</span></span></p></td></tr><tr><td data-colwidth="107" width="107" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">空字节截断</span></span></p></td><td data-colwidth="220" width="220" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">文件名后塞空字节再补合法后缀</span></span></p></td><td data-colwidth="275" width="275" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">应用校验的是后半段,系统打开的是前半段</span></span></p></td></tr><tr><td data-colwidth="107" width="107" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bLine truncated
|
||||
表 一 | 五种常见绕过手法与失效原因
|
||||
|
||||
所以开放网页应用安全项目给的建议非常明确:只接受已知良好的输入,做白名单,不要试图清洗坏数据。黑名单永远追不上想象力,白名单才是终点。
|
||||
# 五、正确的修法
|
||||
## 先看一段教科书级的脆弱写法
|
||||
<table><tbody><tr><td data-colwidth="602" width="602" valign="top" style="background: rgb(242, 244, 247);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:Times New Roman;mso-ascii-font-family:Times New Roman;mso-fareast-font-family:思源黑体;font-variant:normal;text-transform:none;"></span></p><p><span leaf=""> </span></p><p></p></td></tr><tr><td data-colwidth="602" width="602" valign="top" style="background: rgb(242, 244, 247);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">【危险写法示意】</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:Consolas;mso-ascii-font-family:Consolas;mso-fareast-font-family:思源黑体;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span style="mso-spacerun:yes;"><span leaf=""> </span></span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">第一步 固定目录 = 「存放文件的文件夹」(代码写死)</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">第二步 文件名 = 用户传来的内容(完全可控)</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">第三步 最终路径 = 固定目录 + 文件名</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">第四步 直接读取(最终路径)</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:Consolas;mso-ascii-font-family:Consolas;mso-fareast-font-family:思源黑体;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span style="mso-spacerun:yes;"><span leaf=""> </span></span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">问题所在:第三步把一段完全由用户控制的内容,</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf=""> 拼进了一个本该封闭的路径里。</span></span></p></td></tr></tbody></table>
|
||||
|
||||
|
||||
|
||||
|
||||
代码二 | 目录由代码写死,但文件名那段完全交给了用户
|
||||
## 改成这样就安全了
|
||||
<table><tbody><tr><td data-colwidth="602" width="602" valign="top" style="background: rgb(242, 244, 247);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:Times New Roman;mso-ascii-font-family:Times New Roman;mso-fareast-font-family:思源黑体;font-variant:normal;text-transform:none;"></span></p><p><span leaf=""> </span></p><p></p></td></tr><tr><td data-colwidth="602" width="602" valign="top" style="background: rgb(242, 244, 247);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">【正确写法示意】</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:Consolas;mso-ascii-font-family:Consolas;mso-fareast-font-family:思源黑体;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span style="mso-spacerun:yes;"><span leaf=""> </span></span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">写法一:用编号代替真实文件名</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">第一步 允许清单 = 【文件一,文件二,文件三】</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">第二步 用户提交 = 一个编号</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">第三步 取出的文件 = 允许清单 中的第 编号 项</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">第四步 最终路径 = 固定目录 + 取出的文件</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf=""> 用户从头到尾碰不到真实路径。</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:Consolas;mso-ascii-font-family:Consolas;mso-fareast-font-family:思源黑体;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span style="mso-spacerun:yes;"><span leaf=""> </span></span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">写法二:必须用用户输入时,先规范化、后判断</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Consolas;mso-bidi-font-family:Consolas;font-variant:normal;text-transform:none;"><span leaf="">第一步 基准根目录 = 规范化(允许访问的根目录)</span></span></p><p style="margin-top:0.0pt;margin-bottom:0.0pt;margin-left:6.0pt;line-height:14.0pt;mso-line-height-rule:exactly;"><span style="font-size:9.5pt;mLine truncated
|
||||
|
||||
|
||||
|
||||
|
||||
代码三 | 白名单取值 + 规范化后判断,两条路都能堵死穿越
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
图 五 | 正确的防护顺序:先规范化、后判断
|
||||
## 七条完整修法清单
|
||||
<table><tbody><tr><td data-colwidth="60" width="60" valign="top" style="background: rgb(213, 232, 240);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;font-weight:bold;mso-bidi-font-weight:bold;"><span leaf="">序号</span></span></p></td><td data-colwidth="180" width="180" valign="top" style="background: rgb(213, 232, 240);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;font-weight:bold;mso-bidi-font-weight:bold;"><span leaf="">修法</span></span></p></td><td data-colwidth="362" width="362" valign="top" style="background: rgb(213, 232, 240);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;font-weight:bold;mso-bidi-font-weight:bold;"><span leaf="">要点</span></span></p></td></tr><tr><td data-colwidth="60" width="60" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">一</span></span></p></td><td data-colwidth="180" width="180" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">文件系统调用不使用用户输入</span></span></p></td><td data-colwidth="362" width="362" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">用编号代替文件名,用户提交编号,代码映射成真实文件</span></span></p></td></tr><tr><td data-colwidth="60" width="60" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">二</span></span></p></td><td data-colwidth="180" width="180" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">路径由代码包住</span></span></p></td><td data-colwidth="362" width="362" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">用户最多只能提供文件名的一部分,目录那段写死在代码里</span></span></p></td></tr><tr><td data-colwidth="60" width="60" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">三</span></span></p></td><td data-colwidth="180" width="180" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">校验用白名单</span></span></p></td><td data-colwidth="362" width="362" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;"><span leaf="">先列允许清单,不在清单里一律拒绝,而不是去找危险字符</span></span></p></td></tr><tr><td data-colwidth="60" width="60" valign="top" style="border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normLine truncated
|
||||
表 二 | 七条修法,按优先级排列
|
||||
# 六、自查清单:三句话
|
||||
|
||||
·
|
||||
我的代码里,有没有任何一个地方,把用户传来的内容拼进了文件路径?
|
||||
|
||||
·
|
||||
如果有,我用的是“禁止什么”,还是“只允许什么”?
|
||||
|
||||
·
|
||||
如果只允许,我是在拼好路径之后判断的,还是在规范化之后判断的?
|
||||
|
||||
三句话里只要有一句答不上来,就值得现在去查一遍。
|
||||
# 七、写在最后
|
||||
|
||||
这次排查里,最让我印象深刻的不是漏洞本身有多高明,而是它有多普通。没有复杂的工具,没有高超的技巧,只是几个字符。
|
||||
|
||||
而它背后的成因,同样普通到让人无奈:一个再常见不过的功能,一次想当然的“用户不会乱填”。
|
||||
|
||||
真正的安全问题,往往不是被高明的攻击打穿的,是被“应该没事吧”这四个字打穿的。
|
||||
## 合规提醒
|
||||
|
||||
|
||||
|
||||
|
||||
<table><tbody><tr><td data-colwidth="602" width="602" valign="top" style="background: rgb(251, 243, 228);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p><span style="font-family:Times New Roman;mso-ascii-font-family:Times New Roman;mso-fareast-font-family:思源黑体;font-variant:normal;text-transform:none;"></span></p><p><span leaf=""> </span></p><p></p></td></tr><tr><td data-colwidth="602" width="602" valign="top" style="background: rgb(251, 243, 228);border-width: 1pt;border-style: solid;border-color: rgb(204, 204, 204);padding: 0pt 5.4pt;"><p style="margin-top:0.0pt;margin-bottom:0.0pt;line-height:150%;"><span style="font-size:10.5pt;line-height:150%;mso-bidi-font-size:12.0pt;font-family:思源黑体;mso-ascii-font-family:Times New Roman;mso-bidi-font-family:Times New Roman;font-variant:normal;text-transform:none;color:#8A6A20;"><span leaf="">文中目标信息已全部脱敏,截图不含可直接利用的细节。漏洞测试应在明确授权范围内进行,发现的问题请通过正规渠道及时报送责任方修复,切勿在公开渠道披露可被直接利用的细节。同一次排查中发现的其他类型隐患(例如登录入口相关的注入类问题),本文不作展开,已另行整理上报;涉及管理员凭据的内容,尤其不应出现在任何公开材料中。</span></span></p></td></tr></tbody></table>
|
||||
|
||||
|
||||
|
||||
|
||||
加入我们团队。以下是群聊二维码:
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
Reference in new issue
Block a user