一个字符绕过 WAF:Oracle PeopleSoft CVE-2026-35273 的排查与加固

2026-09-25 35 预计阅读时间: 1 分钟
来源: cloud.google.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:11 分钟

针对 Oracle PeopleSoft 的 CVE-2026-35273 利用活动再次扩大。UNC6240(ShinyHunters)没有更换漏洞,而是把请求路径中的 P 编码成 %50,用 /%50SEMHUB/ 绕过只匹配字面字符串 /PSEMHUB/ 的 WAF 规则。反向代理未命中规则,后端 WebLogic 却在 URL 解码后把请求正常路由到存在漏洞的 servlet。

这起事件提醒我们:边界拦截只能争取时间,不能替代补丁。已经配置 /PSEMHUB/* 阻断规则的团队,也必须重新检查日志、所有负载均衡节点和 PeopleSoft 主机,因为攻击者同时使用了落盘 Web Shell 与无文件命令执行。

为什么一条看似正确的 WAF 规则会失效

问题出在不同组件处理 URI 的顺序不一致:

  1. WAF 或反向代理在 URL 解码前匹配原始路径。
  2. 规则只寻找字面量 /PSEMHUB/。
  3. 请求使用 /%50SEMHUB/、混合大小写或其他非规范化形式。
  4. WebLogic 解码并规范化路径,将请求交给 PSEMHUB 应用。

因此,防御规则不能只列举一个编码变体。攻击者还可能编码路径中的其他字符,甚至组合大小写、重复编码和路径分隔符差异。更可靠的原则是:先按与后端一致的方式规范化 URI,再对规范化结果实施访问控制;出现非法编码、重复编码或解码歧义时直接拒绝。

即使边界设备已经正确规范化,修复优先级仍不应改变:

  • 安装 Oracle 针对 CVE-2026-35273 发布的安全更新,并保持在受支持的 PeopleTools 版本。
  • 多服务器部署中禁用不需要的 Environment Management Hub(EMHub)服务。
  • 单服务器部署中,按 Oracle 指引移除不需要的 PSEMHUB 应用。
  • 不要把管理与系统间接口暴露到公网;标准 PIA 用户会话通常不依赖这些接口。

攻击链不只包含 Web Shell

观察到的入侵通常从少量到十余次针对 /PSEMHUB/hub 编码变体的 POST 请求开始。攻击者可借此确认主机操作系统及漏洞是否可利用,而不一定立即写入文件。因此,“目录里没有陌生 JSP”不能证明系统安全。

确认目标后,攻击活动主要分为两类:

  • 落盘执行:在 PSEMHUB.war 中写入 x.jsp、u.jsp、tunnel.jsp、tunnel.jspx 或顺序编号的 JSP 文件。攻击者可能连续发送请求,以覆盖负载均衡后的每个 WebLogic 节点。
  • 无文件执行:由 WebLogic 的 Java 进程直接派生 cmd.exe、/bin/sh 或 bash,命令输出通过 HTTP 响应返回。只监控 JSP 文件创建会漏掉这种方式。

后续工具包括伪装成安装程序的 Ple64.exe、SIDEEYE 内存后门、用于 HTTP/HTTPS 隧道的 Neo-reGeorg,以及合法但被滥用的 MeshAgent。入侵者由此获得反向 Shell、代理、文件管理和凭据窃取能力,并可能进一步窃取 HR、薪资或学生数据实施勒索。

尤其需要注意:攻击命令不一定以 root 或 SYSTEM 执行。PeopleSoft 或 WebLogic 服务账号本身通常就能读取数据库连接串、Integration Broker 凭据和应用数据,危害依然很高。

可以直接执行的主机排查

下面脚本只读取文件元数据和计算哈希,不会删除或修改文件。运行前把 PS_CFG_HOME 改成实际目录;在负载均衡环境中,应对每个 WebLogic 节点执行。

#!/usr/bin/env bash
set -euo pipefail

PS_CFG_HOME="${PS_CFG_HOME:-/opt/oracle/psft/pt/8.60}"
BASE="$PS_CFG_HOME/webserv"

if [[ ! -d "$BASE" ]]; then
  echo "Directory not found: $BASE" >&2
  exit 1
fi

echo "== JSP/JSPX/EXE files under PeopleSoft web applications =="
find "$BASE" -type f \( -iname '*.jsp' -o -iname '*.jspx' -o -iname '*.exe' \) \
  -printf '%TY-%Tm-%Td %TH:%TM:%TS %s %p\n' | sort

echo
echo "== High-priority filenames =="
find "$BASE" -type f \( \
  -iname 'x.jsp' -o -iname 'u.jsp' -o -iname 'u2.jsp' -o \
  -iname 'tunnel.jsp' -o -iname 'tunnel.jspx' -o -iname 'Ple64.exe' \
\) -print

echo
echo "== SHA-256 values for discovered candidates =="
while IFS= read -r -d '' file; do
  sha256sum "$file"
done < <(find "$BASE" -type f \( \
  -iname 'x.jsp' -o -iname 'u.jsp' -o -iname 'u2.jsp' -o \
  -iname 'tunnel.jsp' -o -iname 'tunnel.jspx' -o -iname 'Ple64.exe' \
\) -print0)

echo
echo "== Possible MeshAgent artifacts =="
find /tmp "$PS_CFG_HOME" -type f \( \
  -iname 'meshagent' -o -iname 'meshagent.msh' -o -iname 'meshagent.db' \
\) -print 2>/dev/null || true

已知文件哈希可以作为辅助证据:

  • Ple64.exe: 3ba215692665513abfffd4e815c5c45f2d41e5dcc4283a2a3b740930c5c417c3
  • x.jsp: 48b4a0827da7bbfce9fb52464f8a659dea7a035189c52c506c0bfb4b1c3fe494
  • u.jsp: 2bee941fb40519d0d1ec52bd79a8f63fc65aac6455c8f2d6b668e3360dfdb5d7

不要把哈希不匹配视为安全结论。JSP 增加一个换行就会改变哈希,Neo-reGeorg 文件也会因密钥不同而变化。文件位置、创建时间、内容、父进程和访问日志需要结合判断。

用规范化方式搜索访问日志

普通 grep PSEMHUB 会漏掉 %50SEMHUB,只搜索这个变体又会漏掉其他编码。下面的 Python 脚本会从日志行中提取请求路径,最多执行三轮 URL 解码,再对规范化结果进行不区分大小写的匹配。

将代码保存为 hunt_psemhub.py,然后传入一个或多个 PIA WebLogic 访问日志:

#!/usr/bin/env python3
import re
import sys
from pathlib import Path
from urllib.parse import unquote

REQUEST = re.compile(r'"(?:GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH)\s+([^\s?]+)', re.I)


def normalize(path: str) -> str:
    current = path
    for _ in range(3):
        decoded = unquote(current, errors="replace")
        if decoded == current:
            break
        current = decoded
    current = re.sub(r"/+", "/", current)
    return current.lower()


def suspicious(line: str) -> bool:
    match = REQUEST.search(line)
    if not match:
        return False
    path = normalize(match.group(1))
    return (
        path == "/psemhub"
        or path.startswith("/psemhub/")
        or path.endswith(".jsp")
        or path.endswith(".jspx")
    )


def main() -> int:
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} ACCESS_LOG [...]", file=sys.stderr)
        return 2

    for name in sys.argv[1:]:
        path = Path(name)
        with path.open("r", encoding="utf-8", errors="replace") as handle:
            for number, line in enumerate(handle, 1):
                if suspicious(line):
                    print(f"{path}:{number}:{line.rstrip()}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

运行方式:

chmod +x hunt_psemhub.py
./hunt_psemhub.py /path/to/PIA_access.log /path/to/archived-access.log

这段脚本适合应急排查,不等同于完整的 URI 解析器。生产 WAF 或代理还应处理非法百分号编码、分号路径参数、反斜杠、双重编码及 Unicode 差异,并确认其规范化行为与 WebLogic 一致。

日志检索应重点关注:

  • 外部地址对规范化后 /PSEMHUB/hub 的 POST 请求。
  • 同一来源短时间内出现 5—15 次相似探测。
  • 对 PSEMHUB 或 PORTAL 下陌生 .jsp、.jspx 文件的访问。
  • Java/WebLogic 进程派生 Shell,特别是涉及 base64 -d、curl、/dev/tcp、tasklist 或 start /b 的命令。
  • PeopleSoft 服务账号启动 tar、zstd、rsync、sshpass 等工具。
  • 来自 PeopleSoft 主机的异常持续上传,以及 TCP 873、SSH 或大流量 HTTP POST。

可将 5.199.162.157、104.219.234.138、162.219.30.165 和 winmanage-me.network 作为调查线索,但不建议仅凭 IOC 自动定罪或封禁整个共享网络。IP 和域名可能变化,行为检测通常比静态列表更耐用。

发现异常后的处置顺序

一旦确认 Web Shell、Java 派生 Shell 或未知二进制,不要只删除文件并重启服务。应将主机视为已经失陷:

  1. 隔离受影响节点,同时保留内存、进程、网络连接、访问日志和文件时间戳等证据。
  2. 检查负载均衡后的全部节点,而不是只处理第一个告警节点。
  3. 安装补丁并禁用或移除不需要的 EMHub/PSEMHUB 组件。
  4. 从可信介质重建高风险主机;WebLogic 以 root 或 SYSTEM 运行时尤其应优先重建。
  5. 轮换 PeopleSoft 服务账号可读取的所有秘密,包括 psappsrv.cfg 中的数据库连接信息、Integration Broker 凭据和 Web 层可访问的云凭据。
  6. 检查数据库审计日志中的批量查询或导出,并搜索临时目录、Web 目录中的 .tar、.tar.gz、.zst 等归档文件。
  7. 准备数据泄露与勒索响应,包括法务、隐私、监管通知和外部沟通流程。

本次事件最重要的结论不是 %50 这个具体字符串,而是安全控制必须建立在一致的 URI 规范化语义上。短期可通过规范化后的边界阻断降低暴露面,长期仍要依靠补丁、最小权限、进程级检测和完整的事件响应闭环。


相关推荐