CVE-2026-33439(OpenAM jato.clientSession 역직렬화를 통한 사전 인증 RCE)에 대한 최초의 공개 익스플로잇 구현.
인간의 통찰력 + AI 지원 분석 + 리버스 엔지니어링 + 권고 → 익스플로잇
CVE-2026-33439에 대한 최초의 공개 익스플로잇 구현
ForgeRock OpenAM의 인증되지 않은 Java 역직렬화 취약점으로, 조작된 JATO 세션 객체를 통해 완전한 원격 코드 실행이 가능합니다. 같은 강물이 두 번 흐릅니다. 그들은 jato.pageSession(CVE-2021-35464)을 수정하고 jato.clientSession(CVE-2026-33439)을 잊어버렸습니다. 역직렬화 가젯 체인은 자격 증명을 요구하지 않습니다.
CVE-2026-33439는 OpenIdentityPlatform OpenAM(16.0.6 이전 버전)의 사전 인증 원격 코드 실행 취약점입니다. 이 취약점은 ClientSession.deserializeAttributes() 내부에서 jato.clientSession HTTP 파라미터에 대한 안전하지 않은 Java 역직렬화로 인해 발생하며, 이는 클래스 화이트리스트가 적용되지 않은 Encoder.deserialize() → ApplicationObjectInputStream.readObject()를 호출합니다.
인증되지 않은 공격자는 <jato:form> 태그를 렌더링하는 JSP가 있는 JATO ViewBean 엔드포인트에 직렬화된 Java 객체가 포함된 조작된 HTTP GET 또는 POST 요청을 전송합니다. 서버는 요청을 수신하면 검증 없이 객체를 역직렬화하여 OpenAM WAR에 번들된 클래스만으로 구성된 가젯 체인(외부 라이브러리 불필요)을 트리거하고, 애플리케이션 프로세스 사용자 권한으로 임의의 OS 명령을 실행합니다.
CVSS 4.0 벡터: AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N → 9.3 치명적
CVSS 3.1 벡터: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H → 9.8 치명적
이 취약점은 CVE-2021-35464 이후 적용된 불완전한 수정으로 인한 직접적인 회귀입니다.
CVE-2021-35464 (ForgeRock AM / OpenAM): jato.pageSession 파라미터의 안전하지 않은 역직렬화를 통한 사전 인증 RCE. 실제 환경에서 널리 악용되었으며 CISA KEV 목록에 등재됨. 수정은 ConsoleViewBeanBase.deserializePageAttributes() 내부에 WhitelistObjectInputStream을 도입했습니다. 이는 객체를 인스턴스화하기 전에 모든 클래스 이름을 하드코딩된 약 40개의 안전한 클래스 허용 목록과 대조 확인하는 사용자 정의 ObjectInputStream 하위 클래스입니다.
CVE-2026-33439 (OpenAM ≤ 16.0.5): 수정은 jato.pageSession에만 적용되었습니다. ClientSession.deserializeAttributes()에서 완전히 별도의 코드 경로로 처리되는 jato.clientSession 파라미터는 패치된 적이 없으며, 클래스 화이트리스트 없이 ObjectInputStream.readObject()를 호출하는 필터링되지 않은 Encoder.deserialize() → ApplicationObjectInputStream을 계속 사용합니다.
공격 프리미티브는 동일합니다. 역직렬화 싱크가 다릅니다. 바뀐 것은 파라미터 이름뿐입니다.
JATO는 UI 뷰 상태를 jato.pageSession 및 jato.clientSession이라는 HTTP 파라미터로 직렬화합니다. 요청이 도착하면 OpenAM은 응답을 렌더링하기 전에 UI 상태를 복원하기 위해 이러한 파라미터를 역직렬화합니다. 두 파라미터는 완전히 다른 코드 경로를 따릅니다.
jato.pageSession에 대한 패치된 코드 경로(CVE-2021-35464 이후):```java // PATCHED - ConsoleViewBeanBase.deserializePageAttributes() ObjectInputStream ois = new WhitelistObjectInputStream(new ByteArrayInputStream(decoded)); // class whitelist enforced - gadget chains blocked Object obj = ois.readObject();
jato.clientSession에 대한 패치되지 않은 코드 경로(취약):```java
// ClientSession.java
protected ClientSession(RequestContext context) {
this.encodedSessionString =
context.getRequest().getParameter("jato.clientSession");
}
protected void deserializeAttributes() {
if (this.encodedSessionString != null
&& this.encodedSessionString.trim().length() > 0) {
this.setAttributes(
(Map) Encoder.deserialize(
// VULNERABLE - URL-safe base64 decode then plain ObjectInputStream
Encoder.decodeHttp64(this.encodedSessionString), false)
);
}
}
Encoder.deserialize() 는 클래스 필터링이 없는 ObjectInputStream 의 하위 클래스인 일반적인 ApplicationObjectInputStream 을 생성합니다. JVM 클래스패스의 모든 클래스가 인스턴스화될 수 있습니다. JSP 렌더링 중 < jato:form > 태그가 렌더링될 때마다 역직렬화가 트리거됩니다:``` getClientSession() → hasAttributes() → getEncodedString() → isValid() → ensureAttributes() → deserializeAttributes()
---
<div id="vulnerability_affected"/>
### ***영향받는 버전***
| 제품 | 취약 버전 | 수정 버전 |
|-----------------------------|-------------------------------------------------|--------|
| OpenIdentityPlatform OpenAM | ≤ 16.0.5 | 16.0.6 |
| ForgeRock AM (다운스트림) | 패치 계보에 따라 잠재적으로 영향받음 | - |
---
<div id="vulnerability_attacksurface"/>
### ***공격 표면***
JSP에 *< jato:form >* 태그를 포함하는 모든 JATO ViewBean 엔드포인트는 인증 전에 악용 가능합니다:
| Endpoint | 용도 |
|---------------------------|--------------------------------------|
| /ui/PWResetUserValidation | 비밀번호 재설정 - 사용자 ID 입력 |
| /ui/PWResetQuestion | 비밀번호 재설정 - 보안 질문 |
비밀번호 재설정 엔드포인트가 기본 대상이며, 설계상 공개적으로 접근 가능하고 *< jato:form >* 태그를 반드시 렌더링합니다.
---
---
---
<div id="gadgetchain"/>
## ***⚙️ 가젯 체인***
<div id="gadgetchain_deserialization101"/>
### ***Java 역직렬화 101***
Java가 바이트 스트림에서 객체를 역직렬화할 때, 중첩 객체를 포함하여 재구성하는 모든 클래스에서 readObject()를 호출합니다. 공격자가 바이트 스트림을 제어하고 readObject()가 코드 실행으로 이어지는 일련의 메서드 호출을 트리거하는 객체를 주입하면 가젯 체인 RCE를 얻을 수 있습니다.
CVE-2026-33439의 핵심: 가젯 체인은 외부 라이브러리가 필요 없습니다. 체인의 모든 클래스는 OpenAM WAR 자체에 포함되어 있습니다: `openam-core-16.0.5.jar, xalan-2.7.3.jar, and click-nodeps-2.3.0.jar`. <u>이로 인해 이 취약점은 기본 OpenAM 배포 어디서나 악용 가능합니다.</u>
---
<div id="gadgetchain_encoding"/>
### ***Encoder.decodeHttp64***
이것이 익스플로잇이 작동하도록 만드는 중요한 세부 사항입니다. `jato-shaded-16.0.5.jar`의 `Encoder` 클래스는 Java의 URL-safe base64 인코더/디코더를 사용합니다. 표준 base64도, 사용자 지정 문자 치환 방식도 아닙니다.
Encoder.class를 디컴파일하여 확인됨:```bash
# Extract Encoder.class from the JATO JAR
jar xf /work/jato-shaded-16.0.5.jar com/iplanet/jato/util/Encoder.class
# Decompile and inspect decodeHttp64
javap -p -c com/iplanet/jato/util/Encoder.class | grep -A10 "decodeHttp64"