[방어] 분석 — CVE-2026-13308
The CVE-2026-13308 integer underflow in Autel MaxiCharger AC Elite Home’s OCPP WebSocket parser enables unauthenticated remote code execution, and the highest‑priority immediate mitigation is to block all inbound OCPP WebSocket traffic except from trusted management servers.
📋 요약
- 심각도 high · CVSS 8.1 · EPSS 0.00567 · 악용난이도 hard
🔍 공격 기법
WebSocket 프레임의 Payload Length 필드가 검증 없이 사용되어, 공격자는 의도적으로 매우 작은(음수로 해석되는) 길이를 전송합니다. 파싱 로직이 이 값을 정수형 변수에 그대로 대입한 뒤 버퍼를 할당하면 integer underflow 가 발생하고, 할당된 버퍼가 실제 데이터보다 크게 되면서 힙 오버플로우가 일어나게 됩니다. 이어지는 메모리 그루밍 단계에서 조작된 청크가 memcpy 대상이 되어 임의 코드가 실행됩니다. 인증 절차는 전혀 요구되지 않으며, 네트워크를 통해 직접 OCPP WebSocket 엔드포인트에 접근하면 공격이 시작됩니다.
악용 가능성: 이 취약점은 네트워크를 통해 원격으로 접근할 수 있으나 AV:N 에 비해 공격 복잡도(AC:H) 가 높게 설정돼 있습니다. 이는 성공적인 악용을 위해 공격자가 OCPP 서비스의 WebSocket 메시지 구조와 정수 언더플로우 발생 조건을 정확히 이해하고, 특수하게 조작된 페이로드를 직접 설계해야 함을 의미합니다. PR:N 과 UI:N 으로 보아 인증이나 사용자 행동 없이도 시도가 가능하지만, 필요한 전제조건은 해당 충전기에 노출된 WebSocket 엔드포인트가 외부 네트워크에 공개돼 있거나 내부망에서 접근 가능해야 한다는 점입니다. 실제 EPSS 값이 0.00567 로 매우 낮고 KEV 목록에도 포함되지 않아 현재 관측된 공격 사례가 거의 없지만, 전문가 수준의 프로토콜 분석과 맞춤형 익스플로잇 개발 능력이 있다면 이론적인 위험은 여전히 존재합니다. 공격 표면은 OCPP 서비스가 수신하는 WebSocket 메시지와 그 안의 정수값을 지정하는 파라미터(예: payload‑size, buffer‑length)이며, 이러한 필드가 입력 검증 없이 직접 사용되는 것이 핵심 취약점입니다. 따라서 공격자는 해당 엔드포인트에 접근 가능한 네트워크 위치를 확보한 뒤, 정확히 조작된 정수값을 포함한 WebSocket 프레임을 전송해 버퍼 할당 오류를 유발하고 임의 코드를 실행해야 합니다. 이러한 조건들이 모두 충족될 때만 실제 악용이 가능하므로, 등급은 hard 으로 평가됩니다.
💥 영향 분석
- 원격 공격자가 충전기 내부에서 임의 코드를 실행할 수 있어, 충전 세션 제어·중단, 전력 공급 차단, 혹은 동일 네트워크 내 다른 장치로의 피벗이 가능해집니다.
- 충전 인프라 서비스 가용성이 크게 저하될 위험이 있으며, 악성 펌웨어가 설치될 경우 물리적 안전(과충전·과방전)까지 위협할 수 있습니다.
🔗 관련 취약점·체이닝
- OCPP 1.6/2.0 프로토콜을 구현하는 다른 EV 충전기에서도 WebSocket 프레임 길이 검증 부재가 보고된 바 있어, 동일한 패턴의 메모리 손상 취약점과 연계될 가능성이 있습니다.
- 성공적인 RCE 후에는 기존에 존재하던 인증 우회(예: CVE‑2025‑xxxx) 혹은 네트워크 스니핑 취약점을 이용해 추가 권한 상승이 이루어질 수 있습니다.
🔎 탐지
-
로그 지표
- 충전기 자체 syslog /
wsd프로세스 로그 –payload_length,opcode,frame_type필드. - 네트워크 IDS/IPS (Suricata, Zeek) – WebSocket 핸드쉐이크 이후 프레임 헤더를 기록하는
websocket.frame이벤트.
- 충전기 자체 syslog /
-
SIEM 쿼리 예시 (Splunk)
text1index=ws_logs sourcetype=autel_ws2| eval length=tonumber(payload_length)3| where length < 0 OR length > 65535 // 비정상 범위 탐지4| table _time, src_ip, dst_ip, payload_length, opcodeElastic (KQL)
text1ws_logs2| where tonumber(payload_length) < 0 or tonumber(payload_length) > 655353| project @timestamp, src.ip, dst.ip, payload_length, opcode -
정규식 기반 탐지 (Zeek)
bash1event websocket_frame(c: connection, is_client: bool, fin: bool,2 rsv1: bool, rsv2: bool, rsv3: bool,3 opcode: count, payload_len: count, data: string)4{5 if (payload_len < 2)6 Log::write(WebSocket::LOG, [$ts=network_time(),7 $id=c$id,8 $opcode=opcode,9 $payload_len=payload_len,10 $msg="Suspicious small payload"]);11} -
오탐 튜닝
- 정상적인
ping/pong프레임은 0~2 바이트 길이를 가질 수 있으므로,opcode == 9 or opcode == 10(Ping/Pong) 에 대해서는 경보 레벨을 낮추고, 데이터 전송(opcode == 1 or 2)에만 적용합니다. - 일부 펌웨어 업데이트 과정에서 비정상적으로 큰 프레임이 발생할 수 있으니, 평소 트래픽 평균값(예: 200~1500 바이트)보다 크게 벗어나는 경우에만 경보를 상승시킵니다.
- 정상적인
🛡️ 완화 방안
-
프록시 기반 입력 검증 – 기존 L7 프록시(Nginx, HAProxy) 앞에 배치하여 WebSocket 프레임의
Payload Length가 최소 2 바이트 이상이며, 선언된 길이와 실제 수신 데이터 크기가 일치하는지 검사합니다. 불일치 시 400 Bad Request 로 응답하고 연결을 종료합니다.- 구현 난이도: ★★★☆☆ (프록시 설정 및 정규식 적용)
- 운영 영향: 프록시 추가로 레이턴시 약간 증가, 정상적인 작은 Ping/Pong은 예외 처리 필요.
- 검증 방법: 테스트 클라이언트로 정상 OCPP 메시지와 변조된 짧은 길이 메시지를 각각 전송해 차단 여부를 확인합니다.
-
IDS/IPS 서명 배포 – 위 탐지 섹션에 제시한 SIEM/Zeek 규칙을 IDS(예: Suricata) 정책으로 적용하고,
alert websocket룰을 활성화합니다.- 구현 난이도: ★★☆☆☆ (정책 파일 추가 및 재로드)
- 운영 영향: 최소, 오탐 시 경보 빈도 조절 필요.
- 검증 방법: 공격 시뮬레이션 패킷을 전송해 알림 발생 여부 확인.
⚖️ 위험도 / 우선순위
- 조치: scheduled (이번 주 내)
- 근거: CVSS=8.1 · non-KEV · EPSS=0.00567 · exploit=hard · in_scope=None