Verificación de los binarios de comando antes de la ejecución

13

¿Hay algún método para verificar lo que realmente está ejecutando desde un script bash?

Digamos que su escritura del golpe está llamando a varios comandos (por ejemplo: tar, mail, scp, mysqldump) y que está dispuesto para asegurarse de que tares la real, verdadera tar, que es determinable por el rootusuario sea el propietario del archivo y directorio padre y el único que tiene permiso de escritura y no algunos /tmp/surprise/tarcon www-datao apache2siendo el dueño.

Claro que sé sobre PATHel medio ambiente, tengo curiosidad por saber si esto se puede verificar adicionalmente desde un script bash en ejecución y, de ser así, ¿cómo exactamente?

Ejemplo: (pseudocódigo)

tarfile=$(which tar)
isroot=$(ls -l "$tarfile") | grep "root root"
#and so on...
Miloš Đakonović
fuente
2
Si eres tan paranoico, ¡usa tus propios binarios!
Ipor Sircer
8
Además de whichno decir correctamente qué tarhará, como respondió xhienne, lspodría ser pirateado para devolver información falsa sobre el (los) archivo (s), si corresponde. También greppodría ser pirateado para devolver información falsa; eso podría evitarse mediante el uso de la coincidencia de shell, pero luego se podría piratear shell. En typeprimer lugar, se podría piratear Shell para obtener resultados incorrectos , o reemplazarlo por completo, ya que la capacidad de reemplazo del shell fue una innovación importante de Unix en comparación con los sistemas operativos de 50 años. Ver la dirección de Turing de 1984 de Ken Thompson. Son tortugas hasta el fondo.
dave_thompson_085
2
No puedo responder esto para Linux, solo AIX, que tiene un componente llamado Trusted Execution ( TE), que tiene una base de datos con firmas (es decir, más extensa que una suma de comprobación MD5. Cuando TE está activo Y hay un archivo en la base de datos, puede elegir si el programa se ejecuta o solo advierte que no coincide con la base de datos. Además, hay otras dos configuraciones: TEP(RUTA de ejecución confiable) y TLP(RUTA LIBrary confiable). Solo se pueden ejecutar programas en TEP y las bibliotecas solo se pueden cargar con el directorio está incluido en TLP. En Linux I hay algo llamado 'AppArmor' que puede ayudarte.
Michael Felt
1
Puede tener este tipo de seguridad, pero no desde un script: cuando su script se ejecuta en un entorno no controlado, es demasiado tarde. Por lo que sabes, todo lo que puedes ver es un chroot creado por un atacante.
Charles Duffy el
2
... si desea tener un sistema que sea confiable hasta el final, debe seguir el enfoque de ChromeOS: tener su firmware firmado con una clave incrustada en su hardware; su gestor de arranque / kernel verificado por el firmware; su partición del sistema operativo raíz de solo lectura usando firmas de nivel de bloque para verificación; etc. También hay enfoques similares a los que @MichaelFelt discute disponibles (consulte la Arquitectura de medición de integridad), pero el impacto en el rendimiento es mayor y el nivel de integridad reducido (ya que verificar las firmas binarias no lo ayuda con los ataques a través de archivos no ejecutables). contenido).
Charles Duffy el

Respuestas:

24

En lugar de validar los archivos binarios que va a ejecutar, puede ejecutar los archivos binarios correctos desde el principio. Por ejemplo, si desea asegurarse de que no va a ejecutar /tmp/surprise/tar, simplemente ejecute /usr/bin/taren su secuencia de comandos. Alternativamente, establezca su $PATHvalor cuerdo antes de ejecutar cualquier cosa.

Si no confía en los archivos /usr/bin/y en otros directorios del sistema, no hay forma de recuperar la confianza. En su ejemplo, está controlando al propietario ls, pero ¿cómo sabe que puede confiar ls? El mismo argumento se aplica a otras soluciones como md5sumy strace.

Cuando se requiere una gran confianza en la integridad del sistema, se utilizan soluciones especializadas como IMA . Pero esto no es algo que pueda usar desde un script: todo el sistema debe configurarse de una manera especial, con el concepto de archivos inmutables.

Dmitry Grigoryev
fuente
Que se rompe cuando diferentes distribuciones eligen poner binarios en /binlugar de /usr/bin.
Damian Yerrick
IMA es uno de los dos enfoques de producción listos para esto; el otro es el enfoque de dm-verity adoptado por ChromeOS para realizar la validación a nivel de bloque de los rootfs.
Charles Duffy el
Comentario de @DamianYerrick Fair. Establezca $PATHambas rutas entonces, si se necesita soporte de distribución múltiple.
Dmitry Grigoryev
AIX TE (con o sin RBAC) sería un tercer núcleo integrado "listo para producción" que logrará esto, tal vez más. TE, una vez habilitado para ser más que pasivo, evitará que se abran archivos y / o se ejecuten programas. Además, el uso de aplicaciones y bibliotecas se puede configurar para que esté exclusivamente en TEP (ruta de ejecución confiable) o TLP (ruta de biblioteca confiable). Consulte ibm.com/support/knowledgecenter/en/ssw_aix_61/… para obtener información básica
Michael Felt el
6

Si un intruso ha obtenido acceso a su sistema y puede modificarlo $PATH(lo que no debe incluir /tmpbajo ninguna circunstancia), entonces es demasiado tarde para comenzar a preocuparse por la propiedad de los ejecutables.

En cambio, debería leer sobre cómo lidiar con una intrusión .

Es mejor concentrarse en evitar la intrusión por completo.

Si tiene un sistema donde este tipo de cosas son importantes, puede ser una buena idea aislar las partes que deben ser públicas de las partes que deben ser privadas, así como realizar una auditoría de los modos de comunicación. entre estos

Kusalananda
fuente
4

Es posible hasta cierto punto verificando el md5sumde un archivo. Por lo tanto, en los sistemas que usan aptadministración de paquetes, en mi caso particular, Ubuntu 16.04, existe el archivo /var/lib/dpkg/info/tar.md5sums, que almacena las sumas md5 de todos los archivos que vinieron tardurante la instalación. Por lo tanto, podría escribir una declaración if simple que verifique si la salida de md5sum /bin/tarcoincide con lo que está en ese archivo.

Eso, por supuesto, supone que el archivo en sí no ha sido alterado. Por supuesto, esto solo puede suceder cuando el atacante ha obtenido acceso root / sudo, momento en el que todas las apuestas están desactivadas.

Sergiy Kolodyazhnyy
fuente
8
¿Pero cómo se valida /usr/bin/md5sum?
Dmitry Grigoryev
Si un atacante puede reemplazar /bin/taro /usr/bin/tar, es muy probable que también pueda simplemente reemplazar md5sumo /var/lib/dpkg/info/tar.md5sums. O $SHELL.
Jonas Schäfer
1
Creo que ya mencioné en el último párrafo, que para que tal cosa ocurra, un atacante necesitaría obtener acceso raíz al sistema, y ​​en ese punto todo es posible. En los casos en que el atacante no tiene acceso de root, pero puede alterar la variable PATH para un usuario o crear un alias donde tarapunta a diferentes binarios, eso funcionará. Cuando un sistema se ve comprometido en el nivel de raíz, tiene una opción, entonces, atacarlo desde la órbita
Sergiy Kolodyazhnyy
3

Sí, hay un método: el incorporado type. Al contrario del whichcomando que solo busca en su RUTA, typele dirá si el nombre del comando es en realidad una palabra clave reservada, un nombre incorporado, un alias, una función o un archivo de disco.

$ type -t foobar || echo "Not found"
Not found

$ type -t echo
builtin

$ enable -n echo; type -t echo; type -p echo
file
/usr/bin/echo

$ echo() { printf "(echoing) %s\n" "$*"; }; type -t echo
function

$ alias echo="/bin/echo 'I say: ' "; type -t echo
alias

Además type -ale dará todos los candidatos para su comando (desde la primera hasta la última opción):

$ type -a echo
echo is aliased to `/bin/echo 'I say: ' '
echo is a function
echo () 
{ 
    printf "(echoing) %s\n" "$*"
}
echo is a shell builtin
echo is /usr/local/bin/echo
echo is /bin/echo

Finalmente, si solo le preocupan los binarios en su disco, puede usar type -Papara obtener todos los binarios en su RUTA (el mismo orden que el anterior):

$ type -Pa tar
/home/me/bin/tar                <= oh oh, is this normal?
/bin/tar

Dicho esto, typesolo no le dirá exactamente qué comando se llamará al final. Por ejemplo, si su tares un alias que llama a un binario (por ejemplo alias tar="/tmp/tar"), typele dirá que es un alias.

xhienne
fuente
type -aincluye todos los formularios (p. ej., alias y programa externo)
dave_thompson_085
Gracias @dave, es realmente interesante, he actualizado mi respuesta
xhienne
1
typele dirá lo que sabe bash, pero si estamos bajo el control de un atacante malicioso, no hay razón para creer que lo que bash cree que sabe refleja la verdad real. Por lo que sabes, hay un LD_PRELOADmódulo que intercepta todas las llamadas de la biblioteca C que realizas.
Charles Duffy el
1
@CharlesDuffy Tienes razón, por supuesto. No quería responder hacia el ángulo de seguridad. Solo estoy proponiendo una respuesta a la pregunta en la parte superior: "¿Hay algún método para verificar lo que realmente está ejecutando desde un script bash" y propuse una alternativa a which.
xhienne
Nunca he visto enableantes Utilicé el consejo de estas respuestas para correr type enablepara descubrir que es un shell incorporado y luego help enablepara ver qué hace.
Joe
3

Puede verificar qué comandos está ejecutando exactamente un script utilizando strace. Por ejemplo:

strace -f -e execve ./script.sh

Con el siguiente script:

#!/bin/bash
touch testfile.txt
echo "Hello" >> testfile.txt
cat testfile.txt
rm testfile.txt

stracele dirá la ruta exacta a los comandos ejecutados cuando se usa con el -e execveparámetro:

execve("./script.sh", ["./script.sh"], [/* 69 vars */]) = 0 
Process 8524 attached
[pid  8524] execve("/usr/bin/touch", ["touch", "testfile.txt"], [/* 68 vars */]) = 0 
[pid  8524] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8524, si_status=0, si_utime=0, si_stime=0} --- 
Process 8525 attached [pid > 8525] execve("/bin/cat", ["cat", "testfile.txt"], [/* 68 vars */]) = 0
Hello [pid  8525] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8525, si_status=0, si_utime=0, si_stime=0} --- 
Process 8526 attached [pid > 8526] execve("/bin/rm", ["rm", "testfile.txt"], [/* 68 vars */]) = 0
[pid  8526] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8526, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

Parámetros (de strace man):

-f: Rastree procesos secundarios tal como se crean mediante procesos actualmente rastreados como resultado de las llamadas al sistema fork (2), vfork (2) y clone (2). Tenga en cuenta que -p PID -fadjuntará todos los subprocesos del PID del proceso si es multiproceso, no solo el subproceso con thread_id = PID.

-e trace=file: Rastrea todas las llamadas del sistema que toman un nombre de archivo como argumento. Puede pensar en esto como una abreviatura para la -e trace=open,stat,chmod,unlink,...que es útil ver a qué archivos hace referencia el proceso. Además, el uso de la abreviatura asegurará que no olvide accidentalmente incluir una llamada como lstat en la lista.

Zumo de vidrio
fuente
3
Esto no es de ninguna manera utilizable por un script para realizar pruebas automatizadas, y no hay ninguna razón particular para creer que eso straceno se haya subvertido.
Charles Duffy el
0

El sistema operativo Linux se basa en archivos y muchos comandos ejecutados en Linux probablemente resolverán algunos cambios en los archivos ubicados en su máquina. Debido a eso, tal vez sea ​​la mejor solución para su problema. Puede probar sus comandos para cualquier cambio en el sistema de archivos antes de que se ejecute.

ingrese la descripción de la imagen aquí

Hay un comando 'strace' que descompila su comando en partes ...

ingrese la descripción de la imagen aquí

Si realmente quiere profundizar, desea verificar los descompiladores para los scripts que se ejecutarán. En otras palabras, debe verificar la interpretación del ensamblador de ese comando. Para golpear allí objdump -d. Los scripts bin de Linux se crean principalmente con Clenguaje de programación, por lo tanto, use un buen Cdescompilador.


fuente