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
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
419 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 escalation dei privilegi per CVE-2026-43499 (rtmutex/futex-PI UAF, "GhostLock") su GOT-W29 (HarmonyOS 4.0, kernel 4.19.157-perf+).

Conclusioni principali:

  • La primitive di scrittura della vulnerabilità è stata verificata con successo su hardware reale (riscrittura di sysctl_bootid del kernel con assistenza KPM, derivazione dello slide KASLR).
  • Ma la reale escalation dei privilegi (shell senza KPM e senza RT) non è fattibile: il percorso di ritorno di pselect nel kernel 4.19 sovrascrive deterministicamente la word lock dell'overlay, e non esiste un vettore alternativo. È un vicolo cieco determinato dalla geometria dello stack del kernel, non un difetto di implementazione (a confronto, i dispositivi smt878u/popsicle possono essere completamente compromessi, grazie a una diversa geometria dello stack).

Dispositivo

ElementoValore
ModelloHUAWEI MatePad Pro 11 GOT-W29
SoCQualcomm kona (SM8250, Snapdragon 870)
SistemaHarmonyOS 4.0 (104.0.0.136)
Kernel4.19.157-perf+
VA39-bit, pagine 4K, KASLR attivo

Vulnerabilità

remove_waiter() in kernel/locking/rtmutex.c usa current invece di waiter->task per la pulizia nel percorso di rollback di rt_mutex_start_proxy_lock(), causando un pi_blocked_on pendente (UAF dello stack). Interessa 2.6.39 ~ 7.1 (questo kernel è nel range). Commit di fix upstream 3bfdc63936dd.

Confermato su questo dispositivo: sorgente rtmutex.c:1110-1112, decompilazione di boot.elf, trigger su hardware reale tutti verificati.

Trigger

Meccanismo di trigger della vulnerabilità

Creare un ciclo PI per far sì che FUTEX_CMP_REQUEUE_PI restituisca -EDEADLK; il rollback attiva il bug di remove_waiter, lasciando un pi_blocked_on pendente (che punta al rt_waiter sullo stack del kernel del thread waiter).

Perché il vecchio trigger falliva

Il vecchio trigger faceva sì che il waiter possedesse il futex target del requeue (self-own), colpendo esattamente il controllo anticipato owner==task di task_blocks_on_rt_mutex di questo kernel (boot.elf 0x3808-0x3868), che restituisce prima di scrivere pi_blocked_on → non viene mai generato un puntatore pendente → il posizionamento dell'overlay era una diagnosi errata (nessun crash + boot_id invariato).

Trigger corretto (ciclo PI, implementato)

Ciclo PI: l'owner FUTEX_LOCK_PI(target) detiene il target del requeue; il waiter detiene il futex chain; l'owner si blocca poi sul chain (ciclo: waiter→target→owner→chain→waiter). Durante il requeue, la camminata della catena rileva rt_mutex_owner(chain)==top_task → -EDEADLK → il rollback pulisce il pi_blocked_on della persona sbagliata → il pi_blocked_on del waiter resta pendente. L'owner deve abbassare la priorità (nice=10) affinché la prio dopo il boost sia diversa da owner_waiter->prio, altrimenti rt_mutex_waiter_equal esce anticipatamente.

Risultati

Leak di KASLR (perf_event_open)

Con shell (uid 2000) e perf_event_paranoid=-1, perf_event_open(PERF_SAMPLE_IP, exclude_user=1) campiona cluster di indirizzi del testo del kernel; allineandoli agli offset dei simboli noti si ottiene lo slide.

root@kitploit:~
samples=27651 kernel_ips=1685 lo=0xffffff948728176c hi=0xffffff9488ebfc7c
KASLR slide=0x147f200000    (40/40 IP mappati nella regione di testo del kernel verificati)
runtime _stext=0xffffff9487280800

Strumento: tools/perf_kaslr.c. Prerequisito di esecuzione: shell (Shizuku rish), nessuna intercettazione seccomp.

Trigger EDEADLK

root@kitploit:~
[M] CMP_REQUEUE_PI ret=-1 errno=35 (EDEADLK!)
[W] WAIT_REQUEUE_PI ret=-1 errno=110 (ETIMEDOUT)  ← il waiter ritorna
[M] waiter_returned=1                              ← lascia pi_blocked_on pendente

Strumento: tools/edeadlk_probe.c (variante 8+2+1 = 11, oppure 27).

Meccanismo della primitive di scrittura

rt_mutex_adjust_prio_chain step[7] esegue rb_erase sul fake waiter (percorso a singolo figlio sinistro): *(tree_left) = tree_pc + scrittura incrementale __rb_change_child. Tutti gli offset in target.h sono misurati dalla decompilazione di boot.elf.

Offset completi

Vedi exploit/ghostlock-source/src/target.h. Punti chiave:

  • task_struct: cred=0x988, prio=0x184, pi_blocked_on=0xa90, usage=0x68, mm=0x728
  • rt_mutex_waiter (HW_FUTEX_PI): tree@0x0, pi_tree@0x18, task@0x30, lock@0x38, major@0x40, prio@0x48, deadline@0x50
  • PAGE_OFFSET=0xffffffc000000000, PHYS_OFFSET=0x80000000 (kona), KIMAGE_TEXT_BASE=0xffffff8008080000

Verifica su hardware reale della primitive di scrittura

Un modulo KPM scritto da me (tools/kpm-debug/rtmutex-dbg.c, KernelPatch 0.13.5 inline-hook) ricostruisce l'overlay (tree/task/lock) durante la fake walk e riscrive il parametro next_lock con empty_zero_page (KernelPatch _transit8 chiama la funzione originale con i fargs modificati), facendo sì che rt_mutex_adjust_prio_chain [3] next_lock==waiter->lock passi, [5] il trylock su lock zero abbia successo, [6] sia ownerless, [7] rt_mutex_dequeue (rb_erase a singolo figlio sinistro) venga eseguito — sysctl_bootid viene riscritto con &loggers[0][1], slide-kaslr-ok.

root@kitploit:~
REPAIR3 waiter=0xffffff801ecdbc00 lock=0xffffffa7c4950000
slide boot_id_leaked_nfulnl_logger value=ffffffa7c4612320
slide-kaslr-ok base=ffffffa7c1280000 slide=00000027b9200000

Progettazione dell'overlay

La geometria dello stack è confermata dalle dimensioni dei frame di boot.elf: in __arm64_sys_futex(0x70) + do_futex(0x60+0x1a0) rt_waiter è a sp+0xc0 → profondità 0x1b0; nel percorso pselect stack_fds[0] è a profondità 0x210, differenza 0x60 = 12 word. Quindi word_i cade in stack_fds[12+i]: le word 0-2 sono nella zona di input ex[2..4] (direttamente controllabili), le word 6-7 (task/lock) in res_in[3..4] (codificate con in[3..4] + fd POLLIN-ready), le word 3-5/8-10 restano 0. pselect ritorna immediatamente a causa del fd ready → il waiter fa busy-wait in user space (segnali disabilitati, zero syscall) finché il consumer non completa.

Perché la reale escalation dei privilegi non è fattibile

1. La word lock del vettore pselect viene sovrascritta dal percorso di ritorno

Le word task/lock dell'overlay cadono in res_in[3]/[4] (codificate da fd ready). Misurato: res_in[4] (lock) viene deterministicamente sovrascritto nel percorso di ritorno di pselect (residuo del frame rt_sigreturn), e non è mai uguale al fake_lock del payload; res_in[3] (task) è occasionalmente intatto. L'elusione in user space (operazioni FP + sched_yield) può solo ridurre il tasso di trigger di do_notify_resume a ~21%, ma la sovrascrittura del lock è quasi certa.

Altri due fatti correlati:

  • Il percorso ownerless è bloccato in 4.19: rt_mutex_adjust_pi() ha if (!owner) return 0;, quindi senza owner nel fake_lock non viene chiamato adjust_prio_chain. popsicle (6.12) non ha questo controllo. Il payload con owner è stato portato (fake_lock owner=fake_task|1), ma poiché la word lock viene sempre sovrascritta non può essere attivato in modo affidabile.
  • empty_zero_page non può essere usato come target di scrittura forzata: scriverla corrompe la pagina zero condivisa di tutto il sistema → dopo il test, tempesta di oops.

2. Il vettore alternativo (ppoll) non funziona a livello di codifica

Dalla decompilazione di boot.elf di __arm64_sys_ppoll / do_sys_poll è confermato: pollfd è una struttura di 16 byte (fd 4B + events 4B + revents 4B + pad 4B), che non può trasportare le word task/lock a 64 bit del fake waiter — il valore fd è limitato (deve essere un fd reale), events ha solo 4 byte e non è contiguo, revents è scritto dal kernel (non controllabile).

3. Differenze con altri dispositivi

smt878u / popsicle possono essere completamente compromessi: la loro geometria dello stack consente alle word di cadere nelle zone in/out/ex controllabili dall'utente (3 fd_set di pselect). La posizione del waiter su GOT-W29 (bits+0x60 → task/lock in res_in[3]/[4]) non ha questa finestra. È una differenza di geometria dello stack del kernel, non un difetto di implementazione.

4. Limitazioni del dominio app normale

Il dominio app (untrusted_app) non ha canali KASLR disponibili (perf/kallsyms/pagemap/dmesg tutti negati); CMP_REQUEUE_PI restituisce 1 (requeue riuscito) e non passa dal rollback EDEADLK; il major_only del cpuset non-root cortocircuita duramente lo step[6] della camminata della catena. L'unico ingresso per cambiare QOS, /dev/iaware_qos_ctrl, è negato da SELinux. Quindi i permessi di una normale app non possono attivare questa CVE.

Toolchain di debug

Modulo KernelPatch scritto da me (rtmutex-dbg) per l'osservazione su hardware reale del fake waiter e della primitive di scrittura, compilato sulla base degli header di LyraVoid/KernelPatch 0.13.5 (stessa origine di FolkPatch).

Set di hook

Compilazione

root@kitploit:~
cd <KernelPatch>/kpms/rtmutex-dbg
make TARGET_COMPILE=aarch64-linux-android- \
  CC=$PREFIX/bin/aarch64-linux-android-clang \
  LD=$PREFIX/bin/aarch64-linux-android-ld

Produce rtmutex_dbg.kpm. I flag di compilazione devono includere -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fno-unwind-tables (già nel Makefile): il PIC predefinito di clang produce rilocazioni GOT, e genera .eh_frame di default (R_AARCH64_PREL32), nessuno dei quali è supportato dal loader KPM → caricamento fallito -1.

Caricamento

La superkey di FolkPatch è su (non il KernelPatch predefinito di APatch). Usa lo strumento sc_kpm_load (sorgente sc_kpm_load.c):

root@kitploit:~
adb shell /data/local/tmp/sc_kpm_load su /sdcard/Download/rtmutex_dbg.kpm  # carica
adb shell /data/local/tmp/sc_kpm_load unload rtmutex-dbg su               # scarica
adb shell /data/local/tmp/sc_kpm_load ctl rtmutex-dbg counts su           # contatori

Test con un comando

run_rtmdbg_test.sh (lato dispositivo /data/local/tmp/ghostlock-test/): esegue GhostLock come shell (GOT_SLIDE_NO_RT=1 percorso reale), ciclo di sync da 0.5s per evitare perdita di log, dmesg -w su file, raccolta automatica dopo 90s (SIGSTOP per evitare soft-lock e riavvio). Prima del test:

root@kitploit:~
adb shell 'su -c "sh /sdcard/ghostlock-test/set_debug_no_reboot.sh"'  # evita il riavvio

Punti di osservazione (dmesg [RTMDBG])

  • REPAIR3: ricostruzione dell'overlay e riscrittura del parametro next_lock durante la verifica della primitive di scrittura
  • FAKEWALK skip: la fake walk coperta viene saltata (nessuna scrittura, nessun crash)
  • prio_chain[N] / prio_chain_ret: chiamate della walk e valori di ritorno (0=completata; 4294967261=-EDEADLK)
  • do_select n=320: res_in[3]/[4] lato kernel
  • futex op=13/14: CMP_REQUEUE_PI / WAIT_REQUEUE_PI

Lo stack completo di oops/panic di Huawei è registrato in /data/log/bbox/history.log.

Struttura

root@kitploit:~
tools/      strumenti di verifica (perf KASLR, sonda EDEADLK, toolchain KPM)
target/     tutti gli offset misurati
exploit/    slide.c portato (con modifiche per il trigger EDEADLK)

Ringraziamenti

  • PoC upstream: x-spy/CVE-2026-43499-popsicle, soralis0912/CVE-2026-43499-aristotle, JoinChang/ghostlock-oneplus, Wtrwx/smt878u-ionstack-poc (GPL-3.0)
  • CVE: NVD, Red Hat RHSB-2026-010
Scarica lo strumento
hookscopo
rt_mutex_adjust_piregistra le regolazioni PI; skip quando l'overlay è coperto (pulisce pi_blocked_on)
rt_mutex_adjust_prio_chainfake walk skip incondizionato; dump completo del waiter
__arm64_sys_pselect6 / __arm64_sys_ppollpulisce _TIF_WORK_MASK nel percorso di ritorno; osservazione fd_set
do_selectlettura lato kernel di res_in[3]/[4]
__arm64_sys_futextraccia WAIT_REQUEUE_PI / CMP_REQUEUE_PI
rt_mutex_dequeueconferma l'esecuzione della primitive di scrittura dello step[7] e la forma dell'albero