Ir al contenido principal

Entorno para desarrollo y hacking del kernel Linux

Antes de empezar a desarrollar o a hacer hacking del kernel Linux es necesario preparar un entorno que nos permita hacer modificaciones en el núcleo, compilarlo y probarlo de forma que no afecte a nuestra máquina de desarrollo (no queremos que un error de programación impida que nuestra máquina vuelva a arrancar). A mí, personalmente me gusta usar una máquina virtual en Qemu, aunque hay diferentes alternativas, como preparar un entorno chroot. Aquí voy a describir como lo hago yo, que por supuesto no tiene por qué ser la mejor manera. Por último, antes de comenzar, señalar que en mi máquina de desarrollo utilizo Ubuntu, por lo que las siguientes instrucciones son directamente aplicables a este sistema operativo (aunque son fácilmente adaptables a cualquier otra distribución Linux).



Necesitamos un directorio de trabajo donde descargar el código fuente y compilarlo. Yo tengo un directorio llamado kerneldev en mi directorio home. Es decir, en /home/alberto/kerneldev.
Seguidamente vamos instalar los paquetes necesarios para poder compilar el kernel ejecutando el siguiente comando desde una consola:

sudo apt-get install fakeroot kernel-wedge build-essential makedumpfile \
kernel-package libncurses5 libncurses5-dev

Para compilar el kernel necesitaremos satisfacer algunas dependencias instalando los paquetes que nos falten, este comando hará el trabajo por nosotros:

sudo apt-get build-dep --no-install-recommends linux-image-$(uname -r)

Para descargar el código fuente, podemos recurrir directamente al repositorio oficial del kernel y descargar la última versión estable, o descargarlo usando la utilidad apt de la siguiente manera.

mkdir ~/kerneldev
mkdir ~/kerneldev/src
cd ~/kerneldev/src
apt-get source linux-image-$(uname -r)
cd linux-$(uname -r)

Podemos crear una configuración nueva o partir de la ya existente en nuestro sistema. La configuración del kernel se guarda en un archivo llamado .config. Para utilizar la misma que la de nuestra máquina de desarrollo hacemos lo siguiente:

cp -vi /boot/config-`uname -r` ~/kerneldev/src/linux-`uname -r`/.config

Si necesitamos hacer cambios en la configuración para adecuar el kernel a nuestras necesidades, podemos utilizar el siguiente comando para lanzar la utilidad de configuración del kernel.

sudo make menuconfig

También podemos usar make config si no queremos usar menús, o editar directamente el archivo .config. En nuestro caso, vamos a desactivar el módulo RTS5139, ya que hay un bug conocido que impide compilarlo correctamente en Ubuntu 12.10.

sed -i s/CONFIG_RTS5139=m/CONFIG_RTS5139=n/ .config

Por fin estamos listos para compilar. Simplemente ejecutamos el comando make. Si nuestro procesador tiene dos o más cores, podemos acelerar la compilación usando el parámetro -j4 (lanza cuatro procesos. Se suelen usar dos por core).

make -j4

Bien, ya tenemos el kernel compilado. Por ahora intacto, ya que no hemos tocado nada. Aun así, es una mala idea probar el kernel en nuestra propia máquina. Si hay algún problema dejarás tu sistema operativo inservible, así que mejor vamos a usar Qemu para virtualizar una máquina en la que probar nuestro flamante kernel.

Instalamos Qemu:

sudo apt-get install qemu kqemu-common

También necesitamos una imagen de un sistema linux ya instalado para Qemu. Vamos a descargar una imagen ya preparada de debian squeeze.

cd ~/kerneldev/
wget http://people.debian.org/~aurel32/qemu/amd64\
/debian_squeeze_amd64_standard.qcow2

Mi sistema es de 64 bits, pero si estas trabajando en 32 bits puedes descargar esta otra versión:

wget http://people.debian.org/~aurel32/qemu/i386\
/debian_squeeze_i386_standard.qcow2

Finalmente, nos resta iniciar la máquina virtual con la imagen de debian de 64 bits, pero usando nuestro nuevo kernel.

qemu-system-x86_64 -boot c -kernel \
~/kerneldev/src/linux-$(uname -r)/arch/x86_64/boot/bzImage \ 
-hda ./debian_squeeze_amd64_standard.qcow2 -append \
"root=/dev/sda1 clock=pit" -net nic,model=e1000 -net user

En caso de usar un kernel de 32 bits:

qemu-system-x86 -boot c -kernel \
~/kerneldev/src/linux-$(uname -r)/arch/i386/boot/bzImage \ 
-hda ./debian_squeeze_i386_standard.qcow2 -append \
"root=/dev/sda1 clock=pit" -net nic,model=e1000 -net user

Tened en cuenta que la password del usuario root es 'root'.

¡Enhorabuena! Hemos compilado y lanzado el kernel en la máquina virtual. Ahora queda la parte más difícil, que es empezar a "jugar" y a trastear con el kernel. Lo que los angloparlantes llaman Kernel hacking. En cualquier caso, si quieres empezar a moverte y navegar por el código fuente del kernel, necesitarás alguna ayuda para no perderte entre tantos ficheros y líneas de código.

Vamos a instalar una utilidad llamada cscope que nos ayudará bastante en nuestras andaduras con el núcleo Linux (también se puede navegar por el código fuente de Linux en http://lxr.linux.no/linux/).

sudo apt-get install cscope

Esta aplicación necesita crear una base de datos con todos los identificadores y archivos del código.

LNX=~/kerneldev/src/linux-$(uname -r)
find  $LNX                                                                \
-path "$LNX/arch/*" ! -path "$LNX/arch/i386*" -prune -o               \
-path "$LNX/include/asm-*" ! -path "$LNX/include/asm-i386*" -prune -o \
-path "$LNX/tmp*" -prune -o                                           \
-path "$LNX/Documentation*" -prune -o                                 \
-path "$LNX/scripts*" -prune -o                                       \
-path "$LNX/drivers*" -prune -o                                       \
-name "*.[chxsS]" -print > ~/kerneldev/cscope.files

cscope -b -q -k

Para entrar en la utilidad cscope ejecutamos el siguiente comando:

cscope -d

Es importante pasar el parámetro -d para que cscope no genere de nuevo la base de datos. Para moverte por los campos pulsa el tabulador y para salir usamos ctrl+d. En la pantalla se mostrará la lista de tipos de búsqueda que se pueden hacer. Son las siguientes:

Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:

Por ejemplo, si te pones en la línea
Find this C symbol:
e introduces task_struct, podrás ver dónde se define y se usa esta estructura de datos.

Ahora que tenemos listo nuestro entorno de desarrollo para el kernel podemos remangarnos y empezar a tocar sin miedo (pero con respeto). Si quieres saber como modificar el kernel, crear tus propios módulos, controladores de dispositivo, etc, yo no me perdería los próximos artículos.

Comentarios

  1. El comando cd linux-$(uname -r) no me funciona. me da un error, me dice que este directorio no existe. Alli tienes las dos lineas de orden, de envio y respuesta:

    administrador@AVM480:~/kerneldev/src$ cd linux-$(uname -r)
    bash: cd: linux-3.11.0-18-generic: No existe el archivo o el directorio

    ResponderEliminar
    Respuestas
    1. Comprueba si existe realmente el directorio linux-3.11.0-18-generic o si tiene otro nombre. Si tiene otro nombre, simplemente escribe: cd [nombre del directorio]

      Eliminar

Publicar un comentario

Entradas populares de este blog

Creando firmas de virus para ClamAV

ClamAv es un antivirus opensource y multiplataforma creado por Tomasz Kojm muy utilizado en los servidores de correo Linux. Este antivirus es desarrollado por la comunidad, y su utilidad práctica depende de que su base de datos de firmas sea lo suficientemente grande y actualizado. Para ello es necesario que voluntarios contribuyan activamente aportando firmas. El presente artículo pretende describir de manera sencilla cómo crear firmas de virus para ClamAV y contribuir con ellas a la comunidad.

Manejo de grafos con NetworkX en Python

El aprendizaje computacional es un área de investigación que en los últimos años ha tenido un auge importante, sobre todo gracias al aprendizaje profundo (Deep Learning). Pero no todo son redes neuronales. Paralelamente a estas técnicas, más bien basadas en el aprendizaje de patrones, también hay un auge de otras técnicas, digamos, más basadas en el aprendizaje simbólico. Si echamos la vista algunos años atrás, podemos considerar que quizá, la promesa de la web semántica como gran base de conocimiento ha fracasado, pero no es tan así. Ha ido transmutándose y evolucionando hacia bases de conocimiento basadas en ontologías a partir de las cuales es posible obtener nuevo conocimiento. Es lo que llamamos razonamiento automático y empresas como Google ya lo utilizan para ofrecerte información adicional sobre tus búsquedas. Ellos lo llaman Grafos de Conocimiento o Knowledge Graphs . Gracias a estos grafos de conocimiento, Google puede ofrecerte información adicional sobre tu búsqueda, ad

Scripts en NMAP

Cuando pensamos en NMAP, pensamos en el escaneo de puertos de un host objetivo al que estamos relizando una prueba de intrusión, pero gracias a las posibilidades que nos ofrecen su Scripting Engine , NMAP es mucho más que eso. Antes de continuar, un aviso: algunas de posibilidades que nos ofrecen los scripts de NMAP son bastante intrusivas, por lo que recomiendo hacerlas contra hosts propios, máquinas virtuales como las de Metasploitable, o contrato de pentesting mediante. Para este artículo voy a usar las máquinas de Metasploitable3 . No voy a entrar en los detalles sobre el uso básico de NMAP, ya que hay miles de tutoriales en Internet que hablan sobre ello. Lo cierto es que NMAP tiene algunas opciones que permiten obtener información extra, además de qué puertos están abiertos y cuales no. Por ejemplo, la opción -sV trata de obtener el servicio concreto, e incluso la versión del servicio que está corriendo en cada puerto. Otro ejemplo es la opción -O, que intenta averiguar el