Ci sono voluti oltre dieci anni per vedere arrivare il primo kernel exploit sulla console Microsoft Xbox One. Attualmente, è stato condiviso solo un PoC (Proof of Concept) per l’esecuzione di codice nativo tramite l’app Game Script, creato dall’hacker Carrot_c4k3.
Alcune informazioni sulle notizie relative all’hacking della console Xbox One/Series stanno iniziando a essere condivise per impostare correttamente le aspettative.
the exploit consists of two pieces: a user mode part which gains native code execution in the context of a uwp store app (https://t.co/MHpULK1Toz). i've posted a proof-of-concept here which demos mapping and executing new code using this app's language https://t.co/crSTW0fUta
— emma (@carrot_c4k3) June 10, 2024
L’obiettivo è quello di rilasciare, probabilmente all’inizio del prossimo mese, un exploit per le console Xbox One/Series che consentirà la lettura/scrittura completa del kernel in SystemOS.
Tuttavia, è importante sottolineare che questo NON è un “jailbreak”. SystemOS è la macchina virtuale su cui girano le applicazioni, ed è l’ambiente su cui si ha il controllo quando si attiva la modalità dev sulla console.
Questo exploit permetterà il pieno controllo di questa macchina virtuale su cui possono essere eseguite applicazioni homebrew sulle console retail senza modalità dev, mentre NON permetterà la pirateria.
L’exploit consiste in due parti:
- Una parte in modalità utente che consente l’esecuzione di codice nativo nel contesto di un’applicazione UWP store (disponibile qui).
- Un proof-of-concept di esempio che dimostra la mappatura e l’esecuzione di nuovo codice utilizzando il linguaggio di questa applicazione.
Shellcode di esempio
Il codice definisce un piccolo segmento di shellcode:
let shellcode = [0x48,0xC7,0xC0,0x37,0x13,0x00,0x00,0xC3]
Questo shellcode esegue le seguenti istruzioni in assembly:
mov rax, 0x1337
ret
Carica il valore 0x1337
nel registro RAX
e ritorna.
Funzioni di utilità per la conversione esadecimale
Queste funzioni aiutano a convertire stringhe esadecimali in numeri e viceversa:
hex_to_num(s)
: Converte una stringa esadecimale in un numero intero.num_to_hex(num, byte_count)
: Converte un numero in una stringa esadecimale con un numero specificato di byte.
Funzioni per il dump della memoria
hex_dump(addr, count)
stampa il contenuto della memoria a partire da un indirizzo specificato per un numero specificato di byte in formato esadecimale.
Funzioni di accesso alla memoria
Queste funzioni leggono e scrivono dati di vari tipi (8, 16, 32, 64 bit) da e verso un indirizzo di memoria specificato:
write8(addr, val)
eread8(addr)
write16(addr, val)
eread16(addr)
write32(addr, val)
eread32(addr)
write64(addr, val)
eread64(addr)
Funzioni di lettura e scrittura di buffer
read_buf(addr, buf)
legge dati dalla memoria in un buffer. write_buf(addr, buf)
scrive dati da un buffer nella memoria.
Funzioni di ricerca
find_bytes(addr, max_len, pattern, buf)
cerca una sequenza di byte specificata in un intervallo di memoria.find64(addr, max_len, v)
cerca un valore a 64 bit in un intervallo di memoria.
Conversione di puntatori
ptr_to_num(p)
converte un puntatore in un numero a 64 bit.
Preparazione per l’esecuzione del codice nativo
call_native(func_ptr, rcx, rdx, r8, r9)
imposta un ambiente per eseguire una funzione nativa con i parametri specificati.
Trovare il base address dei moduli
find_module_base(addr)
trova l’indirizzo base di un modulo dato un indirizzo all’interno del modulo.
Recuperare gli export delle DLL
get_dll_exports(base_addr)
restituisce un dizionario di funzioni esportate da una DLL a partire dall’indirizzo base del modulo.
Mappatura dello shellcode
map_code(code)
alloca memoria per lo shellcode, copia il codice nella memoria allocata e modifica le protezioni della memoria per consentire l’esecuzione.
Codice principale
Il codice principale del PoC esegue i seguenti passaggi:
- Crea un oggetto
slBus
. - Trova gli indirizzi base dei moduli GameScript, ntdll e kernelbase.
- Trova gli indirizzi delle funzioni
setjmp
elongjmp
per l’esecuzione del codice nativo. - Trova un gadget ROP in ntdll per eseguire il codice.
- Recupera gli export di ntdll e kernelbase e trova gli indirizzi di
VirtualAlloc
eVirtualProtect
. - Mappa lo shellcode in memoria.
- Esegue lo shellcode e stampa il valore di ritorno.
Esecuzione
Il codice finale prepara l’ambiente, alloca memoria per lo shellcode, configura le protezioni di memoria e infine esegue lo shellcode:
var shellcode_addr = map_code(shellcode)
var shellcode_ret = call_native(shellcode_addr, 0, 0, 0, 0)
printConsole("Shellcode return value: " + num_to_hex64(shellcode_ret) + "\n")
Avviso per gli utenti che desiderano eseguire codice in SystemOS in futuro
In data 8 giugno 2024 è stato annunciato un metodo per ottenere l’esecuzione di codice a livello utente e kernel su SystemOS, è probabile che questo metodo venga corretto nel prossimo aggiornamento di sistema.
Per prepararsi, seguire i passaggi descritti di seguito:
- Assicurarsi che il tipo di accesso al proprio account Xbox Live sia configurato come “Nessuna barriera”, ovvero con accesso automatico senza richiesta di password.
- Impostare la console come “Console principale” per questo account.
- Scaricare l’app Game Script.
- Avviare l’app (per garantire che la licenza venga scaricata/memorizzata nella cache).
- Mettere la console offline! Per assicurarsi che non possa raggiungere internet, impostare un indirizzo DNS primario manuale su 127.0.0.1.
- Procurarsi un dispositivo/microcontrollore che possa simulare una tastiera (rubber ducky o simile), altrimenti bisognerà digitare molto manualmente.
Fonte: xboxoneresearch.github.io