• Fuentes

 #444116  por NvK
 26 May 2014, 01:39
Saludos, hoy vengo con una pequeña demostración de un hook en ring0
que acabo de terminar, el cual servirá para hacer todos los procesos
en ring3 inmortales.


Desde las versiones 2.6 del kernel se quitaron
los permisos de escritura quedando los de solo lectura y
la tabla de syscall no puede ser exportada.
Por lo que debemos encontrar otro método de hookear dicha
tabla, uno de ellos es mirando en "boot/System.map" donde
pueden encontrarse las direcciones a las syscalls(en mi caso System.map-3.2.6)

El standar __NR_kill para hookear kill_pid pero si se desea otra
función tan solo basta mirar la syscall_table y buscar el NR correcto.

Para poder permitir lectura/escritura y hacer
un hook exitoso necesitamos desactivar momentáneamente el bit CR0(control register)
el cual es el encargado de proteger secciones de memoria
contra escritura.
CR0 tiene 2 estados:
0x0000 = modo lectura/escritura.
0x0001 = modo escritura.

Las 2 funciones que usare para ello son native_read_cr0 y native_write_cr0
el cual nos permitirá alterar sus estados.

en mi caso el archivo System.map-3.2.6 contenia el puntero
a la syscall table y kill pid en las siguientes direcciones:
25940 - c1562120 R sys_call_table
2169 - c105bb80 T kill_pid


Por lo que en sus sistemas tal vez no funcione, por esto mencionaba
más arriba el mirar el archivo System.map si lo prueban por su cuenta...

Una vez instalado el driver, se intenta matar un proceso cualquiera y esto
es lo que pasa...

Imagen

Ya desinstalado los procesos pueden matarse normalmente:
Imagen

Código:
/*
	Author: NvK
	Agradecimientos: http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/ por la explicacion.
	Descripción: Hace todos los proceso en ring3 inmortales
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/highmem.h>

#include <asm/cacheflush.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>

#define ELF_INITED 		".text.data"
#define ELF_BEGIN		".text.text"

static unsigned long kill_calls= 0;
// Puntero a la tabla
unsigned long *sys_call_table= (unsigned long*)0xc1562120;
// Función restaurada...
asmlinkage int (*original_kill)(pid_t, int);

int call_x86_hook_kill(pid_t pid, int sig)
{
	printk(KERN_ALERT "\n[+] x86 kill Hooked %ld", kill_calls++);
	return (*original_kill)(pid, sig);
}

static int __section(.init.text)__attribute__((cold)) notrace INIT_KERNEL(void)
{
	// desactivar bit de control
	native_write_cr0(native_read_cr0()&(~0x10000));
	
	original_kill= (void *)sys_call_table[__NR_kill];
	sys_call_table[__NR_kill]= call_x86_hook_kill;
	
	// activar bit de control(volver a su estado normal)
	native_write_cr0(native_read_cr0() | 0x10000);
  
  return 0;
}

static void __section(.exit.data) EXIT_KERNEL(void)
{
	native_write_cr0(native_read_cr0()&(~0x10000));
	sys_call_table[__NR_kill]= original_kill;
	native_write_cr0(native_read_cr0() | 0x10000);
	
	return;
}

module_init(INIT_KERNEL);
module_exit(EXIT_KERNEL);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Nvk");
MODULE_DESCRIPTION("ring0 x86 hook - [kill poc]");
 #444176  por NvK
 26 May 2014, 14:07
me olvide de avisar que si lo que quieren es solo saber cuantas veces el sistema a hecho
la syscall cambien
esta linea:
int call_x86_hook_kill(pid_t pid, int sig)
por ésta otra:
asmlinkage call_x86_hook_kill(pid_t pid, int sig)
Enrealidad no afecta las señales entre procesos...