漏洞与定级:CVE、CVSS,和”该不该今晚修”
这一章回答你两个最实际的问题:CVE / 组件到底怎么定级,以及 RCE、SSRF 这些名词到底在说什么。
先拿开篇的四要素给它们定位:
- 漏洞(CVE)属于「脆弱性」——它是”你哪里漏了”。
- 定级属于「脆弱性 × 威胁 × 影响」的综合判断——它回答的不是”这个洞几分”,是”这个洞打不打得中我、打中了我疼不疼”。
这两件事是两回事,很多人混着讲,就乱了。
一、先分清楚四个字母,别再说混了
安全圈最讨厌的地方,是四个长得像、天天被一起念的名词,其实各管各的。而且你会发现,它们正好落在四要素的不同格子上:
| 缩写 | 全称 | 它是啥 | 落在四要素哪一格 |
|---|---|---|---|
| CVE | Common Vulnerabilities and Exposures | 漏洞的身份证号 | 脆弱性(这个具体的洞) |
| CWE | Common Weakness Enumeration | 漏洞的类型/基因 | 脆弱性(这是哪一类的洞) |
| CVSS | Common Vulnerability Scoring System | 漏洞的评分尺子 | 给脆弱性打分,但分数里揉了威胁和影响 |
| EPSS | Exploit Prediction Scoring System | 漏洞的被利用概率预测 | 威胁(这个洞真会被打的概率) |
重点理解 CVE 和 CWE 的关系:
- CVE 是实例,CWE 是类。
CVE-2021-44228(Log4j 那个)是一个具体的洞;它的类型是CWE-502(不安全的反序列化)等。- 就像”张三”是一个具体的人(CVE),“人类”是张三的类别(CWE)。
- CVE 本身不带严重度分数。CVE 记录只告诉你”这里有个洞、影响什么、是谁报告的”。严重度是 CVSS 算出来的,别把两者绑死。
再看 CVSS 和 EPSS 的区别,这是你定级时最容易踩的坑:
| CVSS | EPSS | |
|---|---|---|
| 回答什么问题 | 这个洞严重不严重(技术上) | 这个洞会不会真的被利用 |
| 落在四要素 | 脆弱性 × 影响 | 威胁 |
| 输出 | 0~10 分,分低/中/高/严重 | 0~1 的概率(未来 30 天内被利用) |
| 类比 | 「这把刀有多锋利」 | 「这把刀最近会不会有人拿去捅人」 |
这是全章最值钱的一句话:CVSS 高分 ≠ 你会被打。 一个 9.8 分的洞,如果需要物理接触设备、需要管理员权限、需要用户点一个链接,那它实际几乎打不到你。反过来,一个 5.3 分的洞,如果已经在野被大规模利用、PoC 满天飞,那它反而要你今晚就修。
为什么?因为 CVSS 只描述了”脆弱性”和”影响”,它不知道”威胁”(EPSS/在野)和”资产”(你的上下文)。而真正决定”你会不会被打”的,是后两者。
二、CVSS 怎么算:它其实已经在用四要素了
CVSS 3.1 的 Base Score(基础分)由 8 个指标算出来,分成两组。你现在不用背公式,但要懂每个指标在问什么——因为这两组指标,正好对应四要素里的”威胁”和”影响”。
第一组:可利用性(Exploitability)—— 这是「威胁」维度,问”好不好打”
| 指标 | 全称 | 取值 | 它在问什么 |
|---|---|---|---|
| AV | Attack Vector 攻击向量 | N网络 / A相邻 / L本地 / P物理 | 攻击者离你多远 |
| AC | Attack Complexity 攻击复杂度 | L低 / H高 | 攻击条件苛不苛刻 |
| PR | Privileges Required 权限要求 | N无 / L低 / H高 | 攻击者需要什么身份 |
| UI | User Interaction 用户交互 | N无 / R需要 | 要不要受害者配合 |
第二组:影响(Impact)—— 这是「影响」维度,问”打中了多疼”
| 指标 | 全称 | 取值 | 它在问什么 |
|---|---|---|---|
| C | Confidentiality 机密性 | H高 / L低 / N无 | 数据会不会被偷看 |
| I | Integrity 完整性 | H高 / L低 / N无 | 数据会不会被篡改 |
| A | Availability 可用性 | H高 / L低 / N无 | 服务会不会被打瘫 |
这 C / I / A 三个字母,就是”影响”要素的三种形态(机密性 Confidentiality、完整性 Integrity、可用性 Availability,合称 CIA)。所有漏洞的”危害”,最终都落在这三个词上——不是偷看,就是篡改,要么就是打瘫。
现在把 CVSS 和四要素对上,你会豁然开朗:
CVSS Base Score = 可利用性组(威胁:好不好打) + 影响组(影响:多疼)
↓
它描述的对象是「脆弱性」(某个具体的洞)
它唯一没包含的是「资产」(你的上下文)
这就是 CVSS 高分 ≠ 你会被打的数学根源:CVSS 只装下了”脆弱性 × 威胁(理论好不好打)× 影响”,没装下”资产”。而”这个组件到底在不在你们公司、公网还是内网、背后是核心支付还是边缘 wiki”——这些”资产”信息,才是定级的临门一脚。
三、为什么 RCE 是核武器级:用向量读一个真实分数
现在看一个具体例子,体会”向量”怎么读。
Log4j 的 CVE-2021-44228,CVSS 3.1 向量长这样:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
翻译成人话:
- AV:N —— 通过网络就能打,攻击者不用碰你的机器(威胁:最危险)
- AC:L —— 攻击复杂度低,几乎没条件(威胁:最危险)
- PR:N —— 不需要任何账号权限(威胁:最危险)
- UI:N —— 不需要受害者点任何东西(威胁:最危险)
- C:H / I:H / A:H —— 偷看、篡改、打瘫,三样全占,且都是”高”(影响:全打满)
所以你看到没:RCE(远程代码执行)之所以是”核武器级”,是因为它把”威胁”维度的四个指标全打成了最危险值,同时把”影响”维度的 CIA 三件套全打满。
这就是”远程代码执行”这个概念恐怖的地方:它意味着攻击者能在你的机器上跑任意代码。一旦能跑代码,什么机密性、完整性、可用性,全都不再属于你——因为代码能偷数据、能改数据、能删数据、能装后门。RCE 是”脆弱性”的危害天花板,因为它直接绕过了所有上层防护,拿到了最底层的控制权。
顺带解释两个你一定会遇到的”兄弟概念”:
- RCE(Remote Code Execution,远程代码执行):攻击者通过网络让你的服务器执行代码。Log4j、Struts2、反序列化漏洞,多是奔着 RCE 去。
- LCE / 任意代码执行(Arbitrary Code Execution):更宽的说法,不强调”远程”。本地提权后执行代码也算。安全圈日常说”getshell”(拿到 shell),本质就是拿到了 RCE 或代码执行。
四、漏洞概念速查:它们各自从哪个角度打你
你要的”RCE 等等的概念”,我给你一张速查表。每个漏洞类型,本质是一个”脆弱性在哪(攻击面) + 一个影响方向”。 按攻击面(脆弱性打的是哪一层)归类,你会记得更牢。
脆弱性在「代码执行」这条命脉上的(最高危)
| 漏洞 | 脆弱性在哪(攻击面) | 一句话影响 |
|---|---|---|
| 命令注入 | 拼进 shell 的不可信输入 | 直接执行系统命令,一步 getshell |
| 代码注入 / 表达式注入 | 拼进代码/模板引擎的输入(Struts2 OGNL、EL 表达式) | 执行任意代码,RCE |
| 反序列化 | 把不可信数据还原成对象 | 还原过程触发恶意代码,RCE(Java/Python 重灾区) |
| LFI / RFI(本地/远程文件包含) | 文件包含函数的路径参数 | 读任意文件 / 包含恶意文件执行代码 |
脆弱性在「数据」这条命脉上的
| 漏洞 | 脆弱性在哪(攻击面) | 一句话影响 |
|---|---|---|
| SQL 注入(SQLi) | 拼进 SQL 的输入 | 读库、改库、写文件、最终 getshell |
| XXE(XML 外部实体) | XML 解析器处理外部实体 | 读文件、SSRF、打瘫服务 |
| 路径穿越 | 文件路径参数里的 ../ | 读服务器上任意文件 |
| 越权 / IDOR | 对象 ID 没做授权校验 | 直接访问别人的数据(业务系统第一高发) |
脆弱性在「浏览器 / 用户」这条命脉上的
| 漏洞 | 脆弱性在哪(攻击面) | 一句话影响 |
|---|---|---|
| XSS(跨站脚本) | 网页里注入 JS | 盗 cookie、钓鱼、控制受害者浏览器 |
| CSRF(跨站请求伪造) | 借受害者的”已登录身份”发请求 | 冒用身份执行操作 |
| 开放重定向 | 跳转参数没校验 | 钓鱼跳转,盗取凭证 |
脆弱性在「服务器当跳板」这条命脉上的(近几年大火)
| 漏洞 | 脆弱性在哪(攻击面) | 一句话影响 |
|---|---|---|
| SSRF(服务端请求伪造) | 让服务器替你去请求内网 | 打内网、读云厂商元数据(云上核心威胁) |
不属于技术漏洞、但占比最高的
| 问题 | 本质 | 一句话影响 |
|---|---|---|
| 逻辑漏洞 | 业务逻辑本身有缺陷 | 支付金额篡改、优惠券复用、绕过流程 |
| 弱口令 / 认证绕过 | 口令或认证逻辑薄弱 | 直接进系统,一切防护形同虚设 |
记这张表的窍门,还是四要素:每一个漏洞,问一句”脆弱性在哪(代码/数据/浏览器/内网)“,就是认清”漏在哪”;问一句”打中了影响什么(C/I/A 哪个受损)“,就是认清”疼多大”。 认清脆弱性和评估影响,两步分开,别一次想全。
五、组件定级:从一条 CVE 到”该不该今晚修”
这是你干应用安全最日常的一件事。给你一条 CVE,你要产出的是一个决策:修不修?多急?
记住,你定的不是 CVE 的级,你定的是”这个 CVE 在你们公司环境里的实际风险级”。 两者天差地别。NVD 给 Log4j 定 10 分,是给全世界的;但如果你某个系统里根本没用到 Log4j,它对你们公司就是 0 风险。
用四要素翻译这句话:定级 = 脆弱性 × 威胁 × 影响,全都要落到”资产”上。 决策链走这七步:
第 1 步:这条 CVE 是什么?(脆弱性)
查 CVE 描述、CWE 类型、CVSS 分数。先建立一个”客观基准”,但别急着信这个分数,它只是起点。
第 2 步:我们在用吗?(资产)
命中判断。这个组件、这个版本,你们到底有没有、用在哪。这一步靠 SCA(软件成分分析)——它扫你的依赖树,告诉你哪个系统用了哪个版本的什么库。没有 SCA,组件定级就是盲人摸象,你连”我们用了 Log4j 吗、用在哪几个系统”都答不上来。这本质是盘点资产——你看不见的东西,就守不住。
第 3 步:可达吗?(脆弱性 × 资产,关键一步)
漏洞代码路径,在不在你们实际调用的路径上?
- 一个组件的某个函数有洞,但你们的业务代码根本不会走到那个函数——那这个洞对你们”不可达”,风险大幅下降。
- 这一步叫可达性分析(reachability analysis)。它把”组件里有洞”和”洞真能被打到”区分开。
第 4 步:暴露吗?(威胁 × 资产)
受影响组件在不在攻击面上?
- 公网直接可达的服务:威胁最高。
- 只在内网:中等。
- 根本没部署、或者组件在但服务没开:低。
一个内网系统的 Log4j,和一个公网门户的 Log4j,风险不是一个量级。“可达”和”暴露”两个词,是你定级时最该刻进脑子的两个词——它们衡量的是”威胁够不够得着你的资产”。
第 5 步:可利用吗?(威胁)
有没有现成的攻击工具?外面真的有人在打吗?
- 有公开 PoC(验证脚本) / Exploit(完整攻击代码):威胁↑
- 进了 CISA KEV(已知被利用漏洞目录):说明在野已经有人在打了,威胁↑↑
- EPSS 分高:被利用概率高,威胁↑↑
第 6 步:影响什么资产?(影响)
打穿了之后,能碰到什么?
- 是能直接拿数据库、拿核心业务?还是只碰到一个边缘静态页?
- 这决定”影响”这一格的高低。同样的洞,落在核心支付系统 vs 落在一个内部 wiki 上,定级完全不同。
第 7 步:综合定级 + 定 SLA(四要素合拢)
把”脆弱性 × 威胁 × 影响”合起来,落到一个优先级和一个修复时限:
| 严重度 | 定义(示例) | 修复 SLA |
|---|---|---|
| 严重 Critical | 公网可达 + 无权限即可 RCE + 有在野利用 | 24 小时内 |
| 高 High | 公网可达 + 需一定条件 + 有 PoC | 7 天内 |
| 中 Medium | 内网可达 / 需高权限 / 无公开 PoC | 30 天内 |
| 低 Low | 不可达 / 影响极小 / 理论性漏洞 | 随迭代 |
六、一张图收尾:定级的本质是”乘法”
把上面七步浓缩成一句话,就是:
实际风险 = 脆弱性(CVSS) × 威胁(EPSS/可达/暴露/在野) × 影响(资产价值)
三个因子,缺一个都定不准。只看 CVSS 的人,会把一个内网不可达的 9.8 分洞当成灾难;只看到”我们有在用”的人,会忽略真正暴露的那个系统。
你要练的,就是每次拿到 CVE,脑子里自动走这七步,最后落成一个”修不修、多急”的决策。
思考题(先想,再看答案)
题目一: 两个漏洞同时出现:漏洞 A 是 CVSS 9.8 的 RCE,但只在你们一个内网测试环境里用到这个组件;漏洞 B 是 CVSS 5.3 的 SSRF,出在你们公网门户上,且已经有公开 PoC。按这一章的决策链,你应该先修哪个?为什么?
题目二: 为什么说”只有 SCA(组件分析)没有可达性分析,定级会大量误报”?试着用一个具体场景说明:什么情况下一个 9.8 分的组件漏洞,对你们实际是”低风险”。
题目三(概念辨析): 有人说”CVE 越多越危险”。用四要素反驳他:CVE 数量多,到底意味着什么?它跟”实际风险高”之间缺了什么?
参考答案
题目一: 先修 B。因为 B 虽然 CVSS 只有 5.3,但它公网可达(威胁够得着)+ 有 PoC(威胁真实存在)+ 打在门户(影响核心对外业务),三个因子全踩在”威胁 × 影响”的高位。而 A 虽然 9.8,但只在内网测试环境(威胁够不着,暴露面极小),攻击者根本碰不到它。这就是”CVSS 高分 ≠ 你会被打”最典型的体现——定级是”环境相关”的,不是”漏洞相关”的。
题目二: 因为 SCA 只回答”你们用了这个组件”(资产),不回答”你们用到了这个有洞的函数”(脆弱性是否可达)。举例:Log4j 的 JNDI lookup 洞需要代码里实际用 logger.info(用户可控字符串) 且触发了 ${...} 解析;如果一个系统用了 Log4j,但只把静态字符串打日志、且配置里 lookups 是关闭的,那这个 10 分洞对它是不可达的,实际低风险。反过来,没有可达性分析,SCA 会把所有”用了 Log4j”的系统全标成 Critical,产生海量误报,最后你连真该修的也淹没在噪音里了。
题目三: CVE 数量多,只说明”这个组件的脆弱性(已知漏洞)个数多”,是个”存量”指标,它不等于”你们实际风险高”。中间缺了至少三个因子:你们用没用这个组件(资产)、漏洞是否暴露在攻击面(威胁)、漏洞是否在野被利用(威胁)。一个没人用、或不可达、或没 PoC 的 CVE 数量再多,对你们的实际风险也是零。反过来,一个只有一条 CVE、但正在被大规模利用的组件,才是真正的定时炸弹。所以”组件 CVE 数”本身不能用来定级,它是噪音信号,不是风险信号。