Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
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.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
GhostLock-GOT-W29 — Ricerca su CVE-2026-43499 (GhostLock) per HUAWEI MatePad Pro 11 GOT-W29 | Kitploit
Strumenti/GitHubGitHub/zzzxxxxxxxxxx/ghostlock-got-w29
Escalation di PrivilegiAnalisi delle VulnerabilitàExploitReverse EngineeringSicurezza MobileBinary Exploitation
GitHubzzzxxxxxxxxxx/ghostlock-got-w29

GhostLock-GOT-W29

Ricerca su CVE-2026-43499 (GhostLock) per HUAWEI MatePad Pro 11 GOT-W29

Vedi Repository
612918 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-43499 (GhostLock) — HUAWEI MatePad Pro 11 GOT-W29

Ricerca di privilege escalation su GOT-W29 (HarmonyOS 4.0, kernel 4.19.157-perf+) per CVE-2026-43499 (UAF dello stack rtmutex/futex-PI, "GhostLock").

Conclusione finale

  1. La vulnerabilità è reale e innescabile: un ciclo di value-holding PI fa sì che FUTEX_CMP_REQUEUE_PI restituisca -EDEADLK, il percorso di rollback attiva il bug di pulizia current != waiter->task di remove_waiter() (in questo kernel kernel/locking/rtmutex.c:1110-1112, fix upstream 3bfdc63936dd), il pi_blocked_on del waiter rimane pendente (punta al rt_waiter sul suo stack del kernel a E-0x1b0).
  2. La primitiva di scrittura è stata verificata end-to-end da puro userspace (QEMU kernel.patched, senza iniezione GDB/KPM): EDEADLK pendente → setsockopt(SOL_IP, MCAST_BLOCK_SOURCE, group_source_req 0x108) consegna un fake waiter (destinazione della copy E-0x210, waiter posizionato a buf+0x60 che copre esattamente E-0x1b0) → sched_setattr innesca il walk → rb_erase scrive sysctl_bootid, lo strumento autoverifica write_ok=1 (primi 8 byte di boot_id = 0xffffff800b412320).
  3. La precedente conclusione di "vicolo cieco nella consegna" è stata ritirata: la vecchia scansione contava il frame 0x80 di sock_setsockopt nella catena di setsockopt. Disassemblaggio + test QEMU confermano che __arm64_sys_setsockopt per level != SOL_SOCKET esegue direttamente blr ops->setsockopt, senza passare da sock_setsockopt; dopo la correzione la profondità di copia di do_ip_setsockopt = 0x210 (precedentemente stimata 0x290), la geometria combacia. Meccanismi esclusi: pselect/select, ptrace, import_iovec, ppoll, SCTP (misurato 0x158).
  4. Lavoro rimanente sul dispositivo: verifica del permesso SELinux per MCAST setsockopt (mrx su EMUI ha ottenuto la privilege escalation con lo stesso carrier come utente shell, quindi ci si aspetta che funzioni), revisione del percorso di ritorno/comportamento di park sul dispositivo reale (si può osservare W direttamente con KPM), e adattamento SELinux della catena post-exploitation (il meccanismo è già implementato, vedi --root). Differenza HKIP: nella tabella dei simboli del kernel e nell'immagine di GOT-W29 non ci sono hkip_*/ hook hypervisor, e le 97 istruzioni hvc dell'intera immagine non sono nemmeno sui percorsi cred/cap/SELinux (solo driver KVM/SMCCC/trasporto di debug), cioè quella protezione hypervisor xid di mrx su questa macchina molto probabilmente non esiste — sul dispositivo reale si può procedere direttamente con la normale procedura root.

Dispositivo

VoceValore
ModelloHUAWEI MatePad Pro 11 GOT-W29
SoCQualcomm kona (SM8250, Snapdragon 870)
SistemaHarmonyOS 4.0 (104.0.0.136)
Kernel4.19.157-perf+ (disassemblaggio boot.elf + firmware/symtab.txt)
VA39-bit, pagine 4K, KASLR on

Vulnerabilità e trigger (versione finale)

Prerequisiti del trigger

  • Privilegi shell: adb shell o Shizuku vanno bene entrambi.
  • Disabilitare i due servizi di controllo in background di Huawei, in modo che il processo shell ottenga la cpuset root (altrimenti la catena di trigger non entra nel percorso target):
pm disable-user com.huawei.powergenie
pm disable-user com.huawei.iaware

Meccanismo: creare un ciclo PI (waiter→target→owner→chain→waiter) per far sì che FUTEX_CMP_REQUEUE_PI segua il rollback EDEADLK; durante il rollback remove_waiter(lock, waiter) usa current (il thread requeue) invece di waiter->task per la pulizia: rt_mutex_dequeue rimuove il nodo waiter reale, ma il pi_blocked_on del waiter non viene azzerato (current->pi_blocked_on = NULL), diventando un puntatore pendente al rt_waiter sullo stack del kernel.

Ciclo di value-holding (ciclo probe, -EDEADLK stabile misurato):

  • waiter: FUTEX_LOCK_PI(chain) tiene chain; FUTEX_WAIT_REQUEUE_PI(wait, 0, target)
  • owner: FUTEX_LOCK_PI(target) tiene target; FUTEX_LOCK_PI(chain) si blocca
  • main: FUTEX_CMP_REQUEUE_PI(wait, 1, target) → -EDEADLK
  • dopo il ritorno per timeout del waiter (WAIT_REQUEUE_PI 2s) il pi_blocked_on pendente rimane sullo stack

Nota: il vecchio trigger "self-own" e il -EDEADLK della variant 11 di edeadlk_probe sono entrambi uscite anticipate con owner==task (rtmutex.c:1035), non producono puntatori pendenti, quindi non sono validi.

Risultati

Leak KASLR (perf_event_open, fattibile come shell)

Con perf_event_paranoid=-1, perf_event_open(PERF_SAMPLE_IP, exclude_user=1) campiona il cluster di testo del kernel; allineando agli offset dei simboli noti si ottiene lo slide:

samples=27651 kernel_ips=1685 lo=0xffffff948728176c hi=0xffffff9488ebfc7c
KASLR slide=0x147f200000    runtime _stext=0xffffff9487280800

Strumento: tools/perf_kaslr.c.

Trigger EDEADLK (creazione del puntatore pendente)

[M] CMP_REQUEUE_PI ret=-1 errno=35 (EDEADLK!)
[W] WAIT_REQUEUE_PI ret=-1 errno=110 (ETIMEDOUT)  ← il waiter ritorna, pi_blocked_on pendente

Strumento: tools/edeadlk_probe.c.

Primitiva di scrittura e catena di consegna (verifica end-to-end QEMU, senza iniezione)

Il walk di rt_mutex_adjust_prio_chain legge il fake rt_waiter nel punto pi_blocked_on pendente:

  • [3] next_lock == waiter->lock (lock = slot indipendente di empty_zero_page, vedi sotto)
  • [5] raw_spin_trylock(&lock->wait_lock) riesce con lock a zero
  • [7] rt_mutex_dequeue → percorso rb_erase con singolo figlio sinistro: *(rb_left) = rb_parent_color → valore scritto 0xffffff800b412320 (&loggers[0][1]) scritto in sysctl_bootid + 8
  • [9] ritorno pulito senza owner

Non servono pagine owner-ful / prepare_skb_payload / kernelsnitch. Il fake rt_mutex non può riutilizzare lo stesso slot tra walk diversi: al termine del walk waiters.root/leftmost rimangono nella lock puntando al waiter corrente; un secondo walk che legge il vecchio nodo dereferenzia lo stack del kernel già liberato del giro precedente, innescando il BUG_ON(w->lock != lock) di rt_mutex_top_waiter() (misurato in QEMU: il secondo test di --verify-all va direttamente in BUG). Nell'implementazione ogni attempt prende empty_zero_page + n*0x20 (128 slot in totale, SLIDE_LOCK_STRIDE/SLOTS), naturalmente tutti a zero e senza contaminarsi a vicenda.

Output di autoverifica dello strumento QEMU (kernel.patched, nokaslr, --probe-cycle --verify-all):

4.483 237 [+] slide write boot_id raw=00000000000000002023410b80ffffff lo=0 hi=ffffff800b412320 exp_lo=0 exp_hi=ffffff800b412320 ok=1
4.547 1   [+] slide write test PASSED
6.583 240 [+] slide leaf boot_id raw=00000000000000002023410b80ffffff lo=0 hi=ffffff800b412320 exp_lo=0 exp_hi=0 ok=1
6.636 1   [+] slide leaf test PASSED
8.671 243 [+] slide read boot_id raw=100000002401000030d74c0b80ffffff lo=0000012400000010 hi=ffffff800b4cd730 exp_lo=0000012400000010 exp_hi=ffffff800b4cd730 ok=1
8.724 1   [+] slide read test PASSED
10.811 1  [+] slide restore test PASSED
10.811 1  [+] slide verify all PASSED

(Per ogni attempt requeue=-1/35 trigger=0/0 wait=-1/110 carrier=-1/22 coerenti: EDEADLK, walk riuscito, timeout hrtimer, copia del carrier riuscita prima di restituire EINVAL a causa del gruppo di indirizzi fittizio.)

Nota: la verifica scrive in boot_id + 8: proc_do_uuid() rigenera l'intero UUID quando bootid[8] == 0, quindi scrivere i primi 8 byte verrebbe sovrascritto dalla lettura di verifica stessa (confermato in QEMU).

Forme della primitiva di scrittura (autotest completo --verify-all)

Scarica lo strumento