x86_risc_root.c
1.8 KB
Non ricordo più in che chat ho mandato/ricevuto il link a quel talk, sulla vulnerabilità del coprocessore RISC negli Intel per scrivere in kernel space ed essere root — sta di fatto che ho trascritto il codice, l'ho ritrovato in una gif
gcc -m32 -o x86_risc_root{,.c}
journalctl -u micro
hello2.c
Niente, non riesco ad alterare le variabili d'ambiente dal modulo kernel, ogni volta da
Bad address prima di eseguire il processo — immagino sarà dovuto agli indirizzamenti diversi kernel-space / user-space, ma non ho idea di come risolvere...
journalctl -u micro
Niente, non riesco ad alterare le variabili d'ambiente dal modulo kernel, ogni volta da Bad address prima di eseguire il processo — immagino sarà dovuto agli indirizzamenti diversi kernel-space / user-space, ma non ho idea di come risolvere...
Giusto un po' di schede aperte, senza cavare un ragno dal buco
Molto triste cercare documentazione per il kernel linux — spesso e volentieri trovi codice vecchio (esempio linux 2.6) che con tutta probabilità è stato cambiato, spostato o rimosso...
Qui mancano un sacco di funzioni
https://www.kernel.org/doc/html/latest
L'unico workaround: cercare nei sorgenti indicizzati
https://elixir.bootlin.com/linux/latest/source/include/linux
Qui mancano un sacco di funzioni
https://www.kernel.org/doc/html/latest
L'unico workaround: cercare nei sorgenti indicizzati
https://elixir.bootlin.com/linux/latest/source/include/linux
Ok ecco i passaggi chiave di merda :
0. definizioni
⚠️ la nuova memoria deve essere page-aligned
10. alterare il registro con il puntatore alla memoria con l'indirizzo utente
0. definizioni
typedef unsigned long addr_t;1. recuperare la funzione
typedef unsigned char byte;
typedef const char __user *const __user *usr_str_arr;
// max size mmaped to userspace (8KB+)
#define MAX_SIZE (PAGE_SIZE * 2)
static byte *MYBUFF;
addr_t (*orig_do_mmap)(
struct file *file, addr_t addr, addr_t len,
addr_t prot, addr_t flags, //vm_flags_t vm_flags,
addr_t pgoff, addr_t *populate, struct list_head *uf
);
do_mmap (il simbolo è nascosto)orig_do_mmap = (void*)kallsyms_lookup_name("do_mmap");
2. allocare nuova memoria kernel con kmalloc (o altro, ma con passaggi diversi in seguito)⚠️ la nuova memoria deve essere page-aligned
MYBUFF = kmalloc(MAX_SIZE, GFP_USER);3. ogni chiamata ad una syscall ha associata il processo chiamante nella macro
current — recuperare tale processo e la struttura di memory managementstruct task_struct *task = current;4. wrappare le prossime modifiche alla memoria con un lock in scrittura
struct mm_struct *mm = get_task_mm(task);
mmap_write_lock_killable(mm);5. aggiungere nuovo spazio di indirizzamento (virtual memory address) al processo [extremely hard] senza mappare alcun file (anonimo)
mmap_write_unlock(mm);
addr_t populate;
addr_t vmaddr = orig_do_mmap(
0, 0, MAX_SIZE
,
PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS,
0, &populate, NULL
);
6. recuperare la struttura vma dall'indirizzo ottenutovma = vma_lookup(mm, vmaddr);7. recuperare il numero di pagina della memoria inizialmente allocata con
kmalloc
addr_t pfn = virt_to_phys((void*)kaddr) >> PAGE_SHIFT;8. mappare la pagina al processo
remap_pfn_range(vma, vma->vm_start, pfn, MAX_SIZE, vma->vm_page_prot)9. l'environment è un puntatore ad un array di stringhe [quindi array di puntatori] null-terminato — è salvato nel registro
dx della syscall — non è possibile modificarlo direttamente, perciò bisogna copiare tutto nella memoria allocata e patchare lìusr_str_arr *envp = (usr_str_arr*)®s->dx;📜 struttura custom:
MYBUFF —> {
ptr1, ptr2, NULL,
| |
"aa=1\0", "bb=2\0", NULL
}
⚠️ nonostante si possa usare MYBUFF per scrivere tutto, è necessario salvare i puntatori delle stringhe con indirizzi utente (quindi vmaddr e incrementandolo man mano)10. alterare il registro con il puntatore alla memoria con l'indirizzo utente
*envp = (usr_str_arr)vmaddr;
11. eseguire la vera syscall👍1
journalctl -u micro
hello2.c
hello2.c
12.3 KB
Full code
Dopo l'inserimento del modulo,
se un processo conterrà
si troverà la variabile d'ambiente
Dopo l'inserimento del modulo,
se un processo conterrà
"alter-me" in argv[0],si troverà la variabile d'ambiente
FUCKING_EPIC=1🚨 Repo Archlinux con pacchetti ottimizzati x86-64 [non tutti]
https://somegit.dev/ALHP/ALHP.GO
(Grazie M.)
https://somegit.dev/ALHP/ALHP.GO
(Grazie M.)
SomeGit
ALHP.GO
Go based buildbot to build official Archlinux repos with x86-64 feature levels, -O3 and LTO
Kernel Linux
>
https://elixir.bootlin.com/linux/latest/source/mm/mmap.c#L1191
Non ha senso o sbaglio?
>
unsigned long do_mmap(...)
> return -EINVAL
> (EINVAL = 22)https://elixir.bootlin.com/linux/latest/source/mm/mmap.c#L1191
Non ha senso o sbaglio?