Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
NanoMQ-Memory-Leak-Research — 공개 권고 및 기술 분석: CVE-2026-36590, NanoMQ v0.24.9 서비스 거부(DoS) 취약점 | Kitploit
도구/GitHubGitHub/moxie25/nanomq-memory-leak-research
Static AnalysisDynamic Analysis (Sandboxing)IoT SecurityMemory ForensicsVulnerability AnalysisExploitationPenetration Testing
GitHubmoxie25/nanomq-memory-leak-research

NanoMQ-Memory-Leak-Research

공개 권고 및 기술 분석: CVE-2026-36590, NanoMQ v0.24.9 서비스 거부(DoS) 취약점

저장소 보기
113개월 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-36590: EMQ NanoMQ v0.24.9의 서비스 거부(Denial of Service)

이 저장소는 EMQ NanoMQ v0.24.9에 영향을 미치는 서비스 거부 취약점인 CVE-2026-36590에 대한 공개 권고 및 기술 분석을 포함합니다.

검토 참고 사항

이 저장소는 CVE 검토를 위한 접근 가능한 기술 참고 자료를 제공하기 위해 공개되어 있습니다. CVE-2026-36590의 최종 분류는 CVE 팀 또는 관련 CNA가 결정합니다.

NanoMQ 팀은 이 이슈에 대해 이의를 제기했으며 이를 구성(설정) 관련 문제로 간주합니다. 이 저장소는 재현 자료, ASAN 결과, 런타임 로그, 소스 코드 분석을 포함한 기술적 증거에 초점을 맞춥니다.

권고 정보

  • CVE ID: CVE-2026-36590
  • Vendor/Project: EMQ / NanoMQ
  • Product: NanoMQ
  • Affected Version: v0.24.9
  • Vulnerability Type: 서비스 거부(Denial of Service) / 리소스 고갈(Resource Exhaustion)
  • Affected Component: /nanomq/nng/src/supplemental/mqtt/mqtt_qos_db_api.c/ nni_qos_db_set
  • CWE: CWE-772, CWE-400
  • Public Disclosure Date: 2026-06-17

요약

NanoMQ v0.24.9가 SQLite 지원 없이 빌드된 상태에서 sqlite.enable이 true로 구성된 경우, QoS 데이터베이스 포인터가 NULL로 남아 있을 수 있습니다. MQTT QoS 메시지 처리 중에 nni_qos_db_set은 복제된 메시지 참조를 해제하지 않고 조기 반환할 수 있습니다. 반복적인 QoS > 0 MQTT PUBLISH 메시지는 지속적인 메모리 소비를 유발하여 결국 서비스 거부로 이어질 수 있습니다.

이 이슈가 여전히 검토가 필요한 이유

이 이슈는 기본값이 아닌 런타임 구성에 의존하지만, 다음 사실은 왜 여전히 추가 검토가 필요한지 보여줍니다:

  1. NanoMQ는 현재 빌드에서 SQLite 지원이 불가능하다는 것을 보고하는 대신 런타임 구성을 수락하고 계속 실행됩니다.

  2. 이러한 구성 불일치는 실제로 발생할 수 있습니다. 사용자가 일반 빌드 명령으로 NanoMQ를 빌드한 후, 예제 구성 파일에서 SQLite 영속성 섹션을 복사하거나 활성화할 수 있습니다.

  3. 영향을 받는 코드 경로는 이 비일관된 상태를 완전히 검증하지 않습니다. 런타임 구성이 SQLite를 활성화된 것으로 간주하지만 데이터베이스 포인터가 NULL인 경우, nni_qos_db_set()은 전달된 메시지 객체를 해제하지 않고 조기 반환합니다.

  4. 이 구성이 수락된 후에는 원격 MQTT 트래픽에 의해 이슈가 트리거될 수 있습니다. 반복적인 QoS > 0 PUBLISH 메시지가 영향받는 경로에 진입하여 누적된 메모리 누수를 유발할 수 있습니다.

  5. 1회, 50회, 500회 재현 라운드로 수행한 ASAN 테스트는 누수된 바이트와 할당량이 트리거 시도 횟수에 따라 증가함을 보여줍니다. 이는 이 이슈가 일회성 소규모 누수가 아니라 입력 횟수에 의존적임을 시사합니다.

완화 조치

사용자는 NanoMQ 인스턴스에 대한 접근을 제한하고, 신뢰할 수 없는 클라이언트에 MQTT 서비스를 노출하지 않으며, SQLite를 지원하지 않는 빌드에서 SQLite 영속성을 활성화하지 않아야 합니다. 공급업체는 SQLite 구성에 대한 시작 시 검증을 추가하고, nni_qos_db_set의 db == NULL 분기에서 메시지 참조를 해제해야 합니다.

NanoMQ-Memory-Leak-Research

첨부 자료

  1. Analysis_Report.md: 수명주기 다이어그램 및 상세 로그 추적을 포함한 분석 전체 내역입니다.
  2. 249exploit_leak.py: 누수를 재현하는 Python PoC 스크립트.
  3. nanomq.conf: 불일치를 트리거하는 데 사용된 구성 파일.
  4. runtime_logs.log: 참조 카운트 이상을 입증하는 계측(instrumentation) 로그.
  5. Docker/: 통제된 조건에서 취약점을 안정적으로 트리거하고 검증하는 데 사용된 컨테이너화된 재현 환경입니다.
    상세 빌드 지침 및 환경 설정 절차는 다음 문서에 제공됩니다:
    Docker/Docker_Reproduction_Guide.md
  6. 249asan_log.txt: NanoMQ v0.24.9에서 캡처한 AddressSanitizer(ASAN) 런타임 로그로, 메모리 누수 및 관련 비정상 메모리 동작을 입증합니다.

기술 분석 요약

요약 이 저장소에는 NanoMQ에서 발견된 메모리 누수 취약점에 대한 PoC(Proof of Concept)와 상세 분석이 포함되어 있습니다. 이 이슈는 원격 공격자가 특정 QoS MQTT 메시지를 통해 시스템 메모리를 고갈시켜 서비스 거부(DoS)를 유발할 수 있게 합니다.

저는 NanoMQ에서 메모리 누수 현상에 대한 심층 분석을 수행했습니다. 동적 계측(dynamic instrumentation)과 코드 검토를 통해, 런타임 구성이 SQLite를 활성화(sqlite.enable=true)하지만 바이너리가 SQLite 지원 없이 컴파일된 경우(NNG_SUPP_SQLITE 미정의) 트리거되는 중요한 리소스 누수 경로를 식별했습니다.

이 이슈를 간결하게 유지하기 위해 아래에 주요 발견 사항을 요약했습니다. 전체 기술 분석(상세 ASAN 추적, 수명주기 다이어그램, 계측 로그 포함)은 첨부된 Analysis_Report.md를 참조하십시오.


분석 프로세스

1. 초기 탐지 (ASAN 분석)

AddressSanitizer를 사용하여 누수된 메모리의 출처를 tcptran_pipe_recv_cb(nng/src/sp/transport/mqtt/broker_tcp.c) 내의 nni_msg_alloc로 특정했습니다. 메모리는 할당되었지만 완전히 해제되지 않았습니다.

2. 수명주기 모델링 ("클론 3회 vs. 해제 3회" 기준선)

저는 nni_msg의 참조 카운팅 메커니즘을 분석했습니다. 정상적인 QoS 1 메시지 수명주기는 다음을 포함해야 합니다:

  • Alloc (+1): 네트워크 수신.
  • Clone 1 (+1): 애플리케이션 계층 디스패치.
  • Clone 2 (+1): 영속성/재전송 로직.
  • 총 참조: 3 -> 필요한 해제: 3.

3. 동적 추적 및 검증

GDB는 이 높은 동시성 시나리오에서 실용적이지 않았기 때문에, 특정 메모리 객체(예: 0x60e00002ffa0)의 수명주기를 추적하기 위해 동적 계측을 사용했습니다. 발견 사항: 로그는 수명주기 불일치를 확인했습니다:

  • 실제 할당: 3 (Alloc + Clone 1 + Clone 2)
  • 실제 해제: 2 (Free 1 + Free 2)
  • 결과: 참조 카운트가 1로 유지되어 누수가 발생했습니다. 누락된 해제(Free)는 nmq_pipe_send_start_v4에서 생성된 Clone 2에 해당합니다.

4. 근본 원인 식별

실행 흐름을 추적한 결과 3번째 해제(Free)가 누락된 이유가 밝혀졌습니다:

  1. 불일치: 바이너리가 -DNNG_SUPP_SQLITE 없이 컴파일되어 nano_sock_setdb의 초기화 로직이 제거되었습니다. 그러나 nanomq.conf에는 sqlite.enable = true가 설정되어 있었습니다. 이로 인해 db 포인터가 NULL로 유지되었습니다.
  2. 결함이 있는 로직 ("조기 반환"): 메시지(Ref=3)가 저장을 위해 nni_qos_db_set에 진입하면, 함수는 NULL 포인터를 확인합니다:
// File: /nanomq/nng/src/supplemental/mqtt/mqtt_qos_db_api.c
void nni_qos_db_set(..., void *db, ..., nng_msg *msg) {
    if (db == NULL) {
        // CRITICAL FLAW:
        // Early return triggers because db is NULL.
        // The function holds ownership of 'msg' (Ref++) but fails to release it.
        return; 
    }
    // ...
}

함수는 nni_msg_free(msg)를 호출하지 않고 아무런 오류 없이 반환합니다. 이로 인해 msg 포인터가 되돌릴 수 없이 유실되어 사실상 메모리 블록이 고아(orphan) 상태가 됩니다.


결론 및 영향

  • 근본 원인: nni_qos_db_set의 방어적 프로그래밍 부재. 잘못된 DB 상태로 인한 조기 반환 시 msg 포인터의 소유권을 처리하지 않습니다.
  • 영향: 이는 Silent DoS(무음 DoS)로 이어집니다. 정상 클라이언트 트래픽이든 악의적인 행위자에 의한 것이든 지속적인 QoS > 0 메시지는 시스템 메모리를 점진적으로 고갈시켜(OOM) 결국 브로커를 중단시킵니다.

권장 사항:

  1. 빠른 실패 (시작 시 검사): SQLite가 올바르게 실행되고 있는지 확인하기 위해 시스템 시작 단계(nano_sock_setdb 또는 main 함수)에 검증 로직을 추가합니다. conf->sqlite.enable == true가 감지되었지만 NNG_SUPP_SQLITE 매크로가 정의되지 않았거나 SQLite가 비정상인 경우, 시스템은 오류와 함께 종료하거나 강제로 enable을 false로 설정하고 경고를 출력해야 합니다.
  2. 리소스 안전 (Fail-Safe): nni_qos_db_set 함수의 조기 반환 분기에 리소스 해제 로직을 추가합니다. db == NULL인 경우, 참조 카운트의 균형을 맞추고 메모리 누수를 방지하기 위해 nni_msg_free(msg)를 호출해야 합니다.
도구 다운로드