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

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-76071 — Netis NC63 ipFilterList 핸들러에서 무제한 sscanf 스캔셋으로 인한 인증 전 스택 버퍼 오버플로우에 대한 독창적 연구 및 PoC | Kitploit
도구/GitHubGitHub/ozcanpng/cve-2026-76071
IoT SecurityVulnerability AnalysisExploitationReverse EngineeringBinary AnalysisFirmware Analysis
GitHubozcanpng/cve-2026-76071

CVE-2026-76071

Netis NC63 ipFilterList 핸들러에서 무제한 sscanf 스캔셋으로 인한 인증 전 스택 버퍼 오버플로우에 대한 독창적 연구 및 PoC

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-76071: Netis NC63의 skk_set.cgi ipFilterList 핸들러에서 sscanf %[^,]를 통한 인증 불필요 사전 인증 스택 버퍼 오버플로

연구자: Özcan Ersan (@ozcanpng)

공개 상태

  • CVE: CVE-2026-76071
  • 공급업체: Netis Systems Co., Ltd.
  • 제품: Netis NC63 AC1200 Wireless Dual Band Gigabit MU-MIMO Router
  • 테스트된 펌웨어: NC63_V3.0.0.3327
  • 영향받는 구성 요소: /bin/netis.cgi
  • 엔드포인트: POST /cgi-bin/skk_set.cgi
  • 트리거: ipFilterList=mod
  • 동적으로 확인된 매개변수: destHost
  • 동일한 파서에 정적으로 도달하는 경로: srcHost
  • 인증: 검증된 경로에서 관찰되거나 요구되지 않음
  • 아키텍처: MIPS32r2 리틀 엔디언, o32 ABI, uClibc
  • 취약점 분류: 저장된 반환 주소 제어가 가능한 스택 기반 버퍼 오버플로
  • 검증: 격리된 QEMU 사용자 모드 런타임에서 원본 해시 프로덕션 CGI 사용
  • 준비 시점의 CVE 레코드 상태: 할당됨; CNA 레코드 세부 정보 채워지기 대기 중

요약

Netis NC63 펌웨어 V3.0.0.3327의 일반 MIB/값 파서는 ipFilterList의 destHost 필드를 두 개의 %[^,] 스캔셋으로 파싱하지만 최대 필드 폭이 없습니다. 각 변환은 16바이트 로컬 스택 버퍼에 기록합니다. 따라서 직접 HTTP 클라이언트가 쉼표 없는 긴 구성 요소를 제출하여 함수의 저장된 제어 데이터를 덮어쓸 수 있습니다.

동적으로 테스트된 두 번째 destHost 구성 요소의 경우, 저장된 ra는 로컬 버퍼로부터 정확히 112바이트 떨어져 있습니다. 원본 해시 CGI에 대한 QEMU 추적은 0x0040f7f4에서 공격자가 선택한 세 번째 항목을 확인했습니다. 별도의 관찰 전용 테스트에서는 공격자가 제어하는 요청 데이터를 정확한 MIPS a0 인수로 보존하면서 반환을 0x00423ab0의 원래 system() PLT 경로로 리디렉션했습니다. 가드된 /bin/sh는 마커를 기록했고 어떤 명령도 실행하지 않았습니다.

공개 PoC는 의도적으로 과도하게 긴 B 패턴만 포함합니다. 여기에는 비공개 제어 전환 값이나 명령 경계 구성이 포함되지 않습니다. 별도로 유지 관리되는 poc/exploit-db/의 RCE 스크립트는 Exploit-DB 제출용으로 준비되었으며, 영향받는 시스템의 승인된 테스트에만 사용하도록 의도되었습니다.

영향받는 아티팩트 무결성

193f6a5e2ce65972b1805bf076f8d3521379a8441c8aaeb5ad0ba174bbee0792  netis_NC63_V3.0.0.3327.bin
eb298774c27070dc595fefcabb4e8c12a46cb5f4fd08f91c3ca92282c3a289a2  squashfs-root/bin/netis.cgi
23faa747b7d2f067aa5431bcc227ceca97a7977cf3e7c372f715cbba57f9209b  squashfs-root/bin/boa
e3fd0ee3013014d59b14a409fb4ee5bb546e7d32413758ab3ad4fb0f0d3dcc47  squashfs-root/lib/libapmib.so

원본 프로덕션 해시

공격 표면 및 인증 상태

벤더 프론트엔드는 srcHost와 destHost를 쉼표로 구분된 세 개의 구성 요소로 만들어 ipFilterList와 함께 /cgi-bin/skk_set.cgi로 전송합니다:

param.destHost = $("#dest_host").val();
param.destHost += "," + $("#dest_ip_1").val();
param.destHost += "," + $("#dest_ip_2").val();
param.ipFilterList = $("#ip_action").val();

request({
    url: "/cgi-bin/skk_set.cgi",
    data: param
});

Vendor 프런트엔드 요청 구성

검증된 HTTP 형식의 CGI 요청에는 Cookie 또는 Authorization 헤더가 포함되어 있지 않았습니다. /tmp/boa_auth가 존재하지 않았음에도 불구하고 실행은 ipFilterList=mod 및 destHost 파서 경로로 계속 진행되었습니다. 메모리 손상 결함은 FUN_0040f7f4의 너비 없는 스캔셋(widthless scanset)이며, 더 광범위한 CGI 인증 실패는 이 권한 있는 핸들러를 인증 전에 노출시키는 조건입니다.

인증되지 않은 루트 CGI 경계

소스에서 싱크까지의 추적

Unauthenticated HTTP client
  |
  | POST /cgi-bin/skk_set.cgi
  | ipFilterList=mod
  | destHost=1,0.0.0.0,<long comma-free component>
  v
FUN_004138a0
  v
FUN_004134c8 (ipFilterList trigger row)
  v
FUN_00410898(request, "ipFilterList")
  v
FUN_0040f7f4(request, trigger, mib_table, pMib)
  |
  | get_request_param("destHost")
  v
sscanf(value, "%d,%[^,],%[^,]", ...)
  |
  | second destination: char[16]
  | no maximum scanset width
  v
saved fp overwrite -> saved ra overwrite -> controlled PC

원본 libapmib.so 메타데이터는 srcHost와 destHost를 모두 타입 0x0c로 매핑하며, 이 타입이 이 파서 케이스를 선택합니다. 동적 검증은 destHost로 수행되었으며, srcHost는 별도의 동적 주장이 아닌 동일 파서에 대한 정적 커버리지로 포함되었습니다.

핸들러 경로 및 원본 MIB 메타데이터

취약한 코드

정규화된 Ghidra 기반 의사코드:

case 0x0c:
    value = get_request_param(request, metadata_name);
    sscanf(value,
           "%d,%[^,],%[^,]",
           &selector,
           first_ip_component,   /* char[16] */
           second_ip_component); /* char[16] */

    *(char *)(destination + field_offset) = selector;
    inet_aton(first_ip_component, destination + field_offset + 1);
    inet_aton(second_ip_component, destination + field_offset + 5);
    break;

경계 없는 scanset 변환

sscanf() 자체가 본질적인 취약점은 아닙니다. 결함은 %[^,]에 최대 필드 너비가 없다는 점으로, sscanf는 각 목적지가 단 16바이트라는 사실을 알지 못합니다. 용량을 인식하는 형식이라면 %15[^,]와 같은 너비를 사용하고, 정확히 세 개의 변환이 성공했는지 확인한 뒤 파싱된 주소 값을 검증할 것입니다. 이는 예시 완화책이며 벤더 패치가 아닙니다.

스택 손상 분석

FUN_0040f7f4는 0x0040f7f4에서 시작하며 0x1d0바이트 프레임을 생성합니다:

0040f7f4  addiu sp,sp,-0x1d0
0040f7f8  sw    ra,0x1cc(sp)
0040f7fc  sw    fp,0x1c8(sp)
0040f800  sw    s0,0x1c4(sp)

0x0c 타입 목적지는 fp+0x14c와 fp+0x15c에 있습니다. 저장된 ra는 fp+0x1cc에 있으며, 두 번째 버퍼로부터의 정확한 거리는 다음과 같습니다:

0x1cc - 0x15c = 0x70 = 112 bytes

스택 레이아웃 및 저장된 ra 오프셋

동적 검증

프로그램 카운터 제어

격리된 PC 증명에서는 112바이트의 패딩 뒤에 0x0040f7f4의 하위 리틀 엔디언 3바이트를 사용했으며, sscanf 종료자가 네 번째 0바이트를 제공했습니다. QEMU는 두 번의 일반적인 파서 진입에 이어, 덮어쓴 반환 주소로 인해 발생한 세 번째 진입을 관찰했습니다:

parser_entry_hit=3 pc=0x0040f7f4
GPR28: ... s8 41414141 ra 0040f7f4
total_parser_entry_hits=3
PASS: third parser entry is the overwritten saved RA.

제어된 서드 파서 항목

관찰 전용 명령 경계

별도의 비공개 검증에서 저장된 ra=0x00423ab0, 즉 원본 바이너리의 system() PLT 경로가 형성되었다. 제어된 요청 키 접미사가 반환 시 MIPS a0에 남아 있었다. 일회용 런타임은 /bin/sh를 정적 로거로 교체했다:

argv[0]=</bin/sh>
argv[1]=<-c>
argv[2]=<NC63_IPFILTER_RCE_PROOF>
CONTROLLED_MARKER_PREFIX_REACHED
PASS: attacker-controlled request data reached system() as exact a0.
PASS: guarded /bin/sh recorded argv and executed no command.

이는 격리된 프로덕션 코드 경로에서 RCE 프리미티브를 확립합니다. 실제 라우터의 정확한 익스플로잇 신뢰성, 커널 무작위화 동작, 기본 WAN 노출은 테스트되지 않았습니다.

런타임 수용 조치 및 증거 경계

테스트된 netis.cgi는 프로덕션 아티팩트와 바이트 단위로 동일합니다. qemu-user에서는 플래시 기반 MIB 상태를 사용할 수 없기 때문에, 일회용 rootfs는 공개된 실험실 전용 libapmib.so 수용 조치를 사용하여 0으로 초기화된 MIB 상태를 할당하고 하나의 패킹된 필드 정렬을 조정했습니다. 이는 CGI, 요청 파서, 취약한 sscanf, 스택 프레임, 저장된 반환 오프셋, 에필로그 또는 system() 경로를 변경하지 않았습니다. 정적 메타데이터는 원본 벤더의 libapmib.so에서 가져왔습니다.

원본 실행 파일은 고정 베이스이며 스택 카나리와 RELRO가 없고, 실행 가능한 스택과 RWX 세그먼트를 가집니다. 이러한 속성은 익스플로잇 가능성 분석을 뒷받침하지만 동적 PC 및 가드 경계 테스트를 대체하지는 않습니다.

바이너리 하드닝 상태

안전한 공개 PoC

URL 인코딩된 본문의 드라이런 생성:

python3 poc/poc.py

승인된 일회용 대상으로의 명시적 전송:

python3 poc/poc.py --target http://192.168.1.1 --send

Exploit-DB RCE 스크립트

poc/exploit-db/CVE-2026-76071.py는 Exploit-DB용으로 준비된 RCE 스크립트입니다. 이 스크립트는 문서화된 비인증 ipFilterList 취약점을 대상으로 하며, 권한이 부여된 영향을 받는 테스트 대상에 사용할 명령 인자를 받습니다:

python3 poc/exploit-db/CVE-2026-76071.py <target> "id"

공개 스크립트는 115바이트 B 구성 요소를 사용하여 오버플로 조건을 시연합니다. 이를 전송하면 CGI 프로세스가 충돌할 수 있습니다. 여기에는 명령 문자열, 셸코드, return-to-system 주소, 리버스 셸 또는 지속성이 포함되지 않습니다.

영향

도구 다운로드