Essa sera uma introdução a rootkits em sistemas linux, mas é necessario o conhecimento previo de C para um entendimento mais completo
O Que é um rootkit?
Contextualizando, rootkits são softwares, geralmente maliciosos, que visam se esconder no sistema hospedeiro, normalmente desenvolvidos para esconder a existência de certos processos e/ou programas, e como ele roda em kernel space, torma sua detecção extremamente complexa.
Loadable Kernel Module (LKM) são modulos cujo tem objetivo de estender as funcionalidades do kernel sem a necessidade de recompilar ele com essa nova feature. Os LKMs são normalmente usados para adicionar suporte para novos hardwares ou para adicionar chamadas de sistema(sys calls).
Aqui está o motivo por ser aqui o “habitat natural” dos rootkits, pois os LKMs rodam como uma extensão do kernel, portanto, rodando em ring 0, assim, concedendo poderes ilimitados dentro do sistema.
LKM Rootkits são módulos de kernel que funcionam geralmente “hookando”(sequestrando) system calls e alterando seu
funcionamento normal, como por exemplo, “hookando” a sys call
getdents(get directory entries) você poderia fazer
um filtro para não ser retornado arquivos que se iniciam com secret
.
Esta técnica foi popularizada em 1999 quando o grupo The Hackers Choice(THC) publicou um artigo que ficou conhecido como LKM HACKING. Hookando syscalls um atacante pode esconder arquivos, diretórios ou processos, monitorar operações de arquivos etc, assim como citado anteriormente.
O Que são system calls?
Todos SO’s possuem funções “build in” em seu kernel, que são usadas para todas as operações nesse sistema.
As funções que o linux usa são chamadas de systemcalls.
Elas representam uma transição de niveis mais altos para kernel space, de ring’s mais altos para ring 0.
A abertura de um arquivo no kernel space, por exemplo, é representado pela syscall sys_open
.
Cada systemcall tem um número definido, que é realmente usado para fazer a chamada do sistema.
O Kernel usa a interrupção 0x80 para gerenciar todas as systemcall.
O número da systemcall e quaisquer argumentos são movidos para alguns registradores
(eax/rax para número da systemcall, por exemplo).
O número da systemcall é um índice em um array de uma estrutura do kernel chamada sys_call_table[]
.
Essa estrutura mapeia os números de chamadas do sistema para a função de serviço necessária.
Claro que não vamos escrever um rootkit nesse post, até porque isso levaria um estudo aprofundado e esse post tem a ideia de ser uma introdução, mas como uma boa introdução vamos escrever um hello world em Kernel Module
Escrevendo um hello world
// hello.c
// necessario para criar o modulo
#include <linux/module.h>
// necessario para a macro KERN_INFO
#include <linux/kernel.h>
// função de entrada, como a `main` em um programa generico em C
static int hello_init(void) {
// printk é uma função para imprimir mensagens no log do kernel
printk(KERN_INFO "Hello world!\n");
// finaliza com sucesso
return 0;
}
static void hello_exit(void) {
printk(KERN_INFO "Fechando hello world\n");
}
// Defina qual sera a função de point enter
module_init(hello_init);
/*
Similiar ao module_init, mas sera a função que sera
executada quando o modulo ser descarregado */
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("R3tr074");
MODULE_DESCRIPTION("LKM hello world");
MODULE_VERSION("1.0");
Agora que terminamos de escrever o codigo precisamos compilar ele, usaremos um Makefile para facilitar esse processo.
# Makefile
# objeto para compilar
obj-m := hello.o
# Compilador
CC = gcc -Wall
# Diretorio de build
# (uname -r é usado para selecionar as libs do kernel atual)
build := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(build) M=$(PWD) modules
clean:
$(MAKE) -C $(build) M=$(PWD) clean
Agora já temos tudo que precisamos, basta digitar make
em seu terminal
e ver a magica acontecer, vc deve ter algo parecido com isso apos o make terminar:
Não se assuste, a unica coisa que precisaremos agora é o .ko(Kernel Object), vamos carregar esse modulo para o kernel com o simples comando:
sudo insmod hello.ko
E pronto, o modulo foi carregado, para verificar você pode executar lsmod
e procurar um modulo chamado “hello” ou ir até /var/log/kern.log
e ver se acha
sua mensagem deixada pelo printk
, para descarregar o modulo, basta executar
sudo rmmod hello
.
Conclusão
Para você que gostou do assunto, prepare-se, é um assundo bem denso, porem, facinante.
Referências
https://blog.convisoappsec.com/linux-rootkits-hooking-syscalls/
http://www.ouah.org/LKM_HACKING.html
https://en.wikipedia.org/wiki/Protection_ring
Autor do post: R3tr0