Hay muchos aspectos de la seguridad en los sistemas Linux, desde configurar cuentas hasta garantizar que los usuarios legítimos no tengan más privilegios de los que necesitan para hacer su trabajo. En este post os muestro algunos de los comandos Linux básicos de ciberseguridad  para el trabajo diario.

SUDO

Ejecutar comandos privilegiados con sudo, en lugar de cambiar al usuario a root, es una buena práctica esencial, ya que ayuda a garantizar que solo se usan privilegios de root cuando es necesario y limita el impacto de los errores. El acceso al comando sudo depende de la configuración en los archivos /etc/sudoers y /etc/group.

$ sudo adduser pepe
Adding user `pepe' ...
Adding new group `pepe' (1007) ...
Adding new user `pepe' (1007) with group `pepe' ...
Creating home directory `/home/pepe' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for shark
Enter the new value, or press ENTER for the default
        Full Name []: Pepe
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n] Y

Si ejecutamos sudo y preguntamos al sistema quién somos, recibiremos la confirmación de que se está ejecutando el comando como root.

$ sudo whoami
root

VISUDO

El comando visudo nos permite realizar cambios en el archivo /etc/sudoers abriendo el archivo en un editor de texto y verificando la sintaxis de sus cambios. Ejecuta el comando con "sudo visudo" y asegúrate de comprender la sintaxis. Los privilegios pueden ser asignados por usuario o por grupo. En la mayoría de los sistemas Linux, el archivo /etc/sudoers ya estará configurado con grupos como los que se muestran a continuación que permiten asignar los privilegios a los grupos configurados en el archivo /etc/group. En esos casos, no necesitamos usar el comando visudo en absoluto: solo debemos familiarizarnos con los grupos que otorgan privilegios de root de esta manera y realizar las actualizaciones en el archivo /etc/group.

%admin ALL=(ALL) ALL
%sudo ALL=(ALL:ALL) ALL
%wheel ALL=(ALL:ALL) ALL

Ten en cuenta que los nombres de los grupos están precedidos por el signo %.

Probablemente podremos ver los grupos que proporcionan acceso a sudo en el archivo /etc/group , probablemente sea uno de estos:

$ egrep "admin|sudo|wheel" /etc/group
sudo:x:27:pepe,ruben.ramiro

La forma más fácil de otorgar a alguien el privilegio de sudo es agregarlo al grupo habilitado en /etc/group. Sin embargo, eso significa que pueden ejecutar cualquier comando como root. Si deseamos que algunos usuarios tengan autoridad de raíz para un conjunto limitado de comandos (por ejemplo, agregar y eliminar cuentas), podemos definir los comandos que deseamos que puedan ejecutar a través de un alias de comando como este:

Cmnd_Alias ACCT_CMDS = /usr/sbin/adduser, /usr/sbin/deluser

Luego, daremos al usuario o grupo la capacidad de ejecutar estos comandos usando sudo con un comando como uno de estos:

ruben.ramiro ALL=(ALL) ACCT_CMDS
%ciberseguridad  ALL=(ALL:ALL) ACCT_CMDS

La primera línea permite al usuario "ruben.ramiro" ejecutar los dos comandos (adduser y deluser, definidos en el alias) con sudo mientras que la segunda asigna los mismos privilegios a cualquiera en el grupo "ciberseguridad" en el archivo /etc/group.

Podemos usar el comando "sudo update-alternative - config editor" si no nos gusta el editor predeterminado que se activa cuando ejecutamos el comando visudo. Ofrecerá una serie de editores como opciones y podremos cambiar la configuración.

WHO y W

Los comandos who y w muestran quién ha iniciado sesión en el sistema, aunque w muestra más información, como el lugar desde el que iniciaron sesión, cuándo iniciaron sesión y cuánto tiempo han estado inactivos.

$ w
 18:03:35 up 9 days, 22:48,  2 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
ruben.ramiro      tty2     /dev/tty2        27Apr18  9days  7:34   0.09s /usr/lib/x86_64-linux
pepe      pts/1    192.168.0.15     09:50    7.00s  0.28s  0.00s w

LAST

Este comando muestra los inicios de sesión recientes de los usuarios y, a menudo, es útil cuando se intenta rastrear cambios u otra actividad.

$ last ruben.ramiro
ruben.ramiro  pts/1   192.168.1.32   Wed May  2 07:01 - 08:29  (01:27)
wtmp begins Tue May  1 10:21:35 2018

ruben.ramiro no ha iniciado sesión desde hace tiempo. Podría estar de vacaciones o podria haber dejado la compañia recientemente. Este tipo de información puede ser útil para decidir si necesitaríamos hacer un seguimiento del usuario.

FIND

El comando find se usa para hacer muchos tipos de búsquedas. Cuando se trata de seguridad, es posible que nos encontremos buscando archivos que no tengan propietarios (sin cuentas correspondientes) o que sean de escritura para todos , ademas de ejecutables. Los comandos de búsqueda son fáciles de componer, pero requieren cierta familiaridad con sus muchas opciones para definir lo que necesitamos en la busqueda. En el primero de estos dos comandos encontraremos archivos sin propietarios definidos, en el segundo encontraremos archivos que probablemente cualquiera puede ejecutar y modificar.

$ sudo find /home -nouser
$ sudo find / -perm -o=wx

Tener en cuenta que -o en el segundo comando se refiere al grupo "otro", no al propietario ni al grupo asociado con los archivos.

FILE

El comando examina un archivo y determina qué tipo de archivo se basa en su contenido, no en su nombre. Muchos archivos (como los archivos jpeg) contienen identificadores cerca del comienzo de los archivos que los identifican. El archivo ".jpg" en el ejemplo a continuación claramente no es el verdadero archivo jpeg sino un ejecutable, a pesar de su nombre.

ruben.ramiro@pc:~$ ls -l
total 24
-rw-r--r-- 1 root root     0 Apr 13 09:59 empty
-rwxr-xr-x 1 ruben.ramiro group 18840 May 10 17:39 foto.jpg
-rwx------ 1 ruben.ramiro group    24 May  2 07:06 trythis
ruben.ramiro@pc:~$ file foto.jpg
foto.jpg: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=5d19f7a492405ea9b022a9aa8151f6fb4143633d, stripped

WHICH

El comando which identifica el ejecutable que se ejecutará cuando se escriba su nombre. Esto no siempre será lo que creemos. Si se ha insertado un troyano en el sistema de archivos en una ubicación que aparece en su ruta de búsqueda antes de la legítima, se ejecutará en su lugar. Esto es una buena razón para asegurarnos de que la ruta de búsqueda incluya directorios como /usr/bin antes de agregar menos ubicaciones estándar y especialmente antes de "." (El directorio actual).

$ which date
/usr/local/bin/date <=== probablemente no es lo que queríamos

Podemos verificar la ruta de búsqueda de un usuario cambiando al usuario y haciéndole "eco":

luis@pc:~$ sudo su - ruben.ramiro
ruben.ramiro@pc:~$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin

Incluso si las rutas de búsqueda de los usuarios están configuradas en un archivo del sistema como /etc/profile o /etc/bash.bashrc, pueden haber sido modificadas por la configuración local.

SS

El comando ss es una herramienta para investigar sockets y nos permite hacer cosas como mostrar puertos de escucha y conexiones activas. Sin agregar algunas restricciones, ss mostrará mucha más información de la que probablemente queremos ver. Muchas partes del sistema operativo se comunican a través de sockets. Si deseamos generar una lista de conexiones establecidas o puertos de escucha (es decir, servicios disponibles para sistemas externos), los comandos como estos serán muy útiles.

Conexiones establecidas:

$ ss -t
State   Recv-Q Send-Q Local Address:Port     Peer Address:Port   
ESTAB   0      224    192.168.0.20:ssh      192.168.0.15:56647

$ ss | grep ESTAB | grep tcp
tcp    ESTAB   0    64   192.168.0.20:ssh   192.168.0.15:64885

Puertos de escucha:

$ ss -ltn
State   Recv-Q Send-Q Local Address:Port     Peer Address:Port     
LISTEN  0      128          *:22             *:*
LISTEN  0      5      127.0.0.1:631          *:*                 
LISTEN  0      50           *:445            *:*
LISTEN  0      50           *:139            *:*
LISTEN  0      128          *:5355           *:*
LISTEN  0      128         :::22             :::*
LISTEN  0      5          ::1:631            :::*
LISTEN  0      50         :::445             :::*
LISTEN  0      128        :::5355            :::*
LISTEN  0      50         :::139             :::*

Observamos que el puerto 631 (CUPS) solo está escuchando en la interfaz de bucle invertido (127.0.0.1).

UFW

Si estamos ejecutando un firewall en el sistema Linux, un paso importante para controlar el acceso al sistema, los comandos utilizados para iniciar/detener, habilitar/deshabilitar, modificar y mostrar el estado o las reglas activas es crítico. Aquí algunos comandos de muestra  que podemos encontrar en sistemas Ubuntu:

$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22                         ALLOW IN    192.168.0.0/24

Este firewall está activo y permite que solo se conecten conexiones de la red local y por el puerto 22.

Los siguientes comandos deberían 1) configurar la regla que se muestra arriba y 2) desactivar el firewall.

$ sudo ufw allow from 192.168.0.0/24 to any port 22
$ sudo ufw disable

IPTABLES

También es importante saber cómo enumerar las reglas de firewall para iptables. Estos comandos le proporcionarán una lista completa de las reglas de netfilter:

sudo iptables -vL -t filter
sudo iptables -vL -t nat
sudo iptables -vL -t mangle
sudo iptables -vL -t raw
sudo iptables -vL -t security

IP

El comando ip permite mostrar información de las interfaces de red. En el siguiente ejemplo, vemos el loopback y la interfaz pública.

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp0s25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:1e:4f:c8:43:fc brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.20/24 brd 192.168.0.255 scope global dynamic enp0s25
       valid_lft 59794sec preferred_lft 59794sec
    inet6 fe80::f233:4f72:4556:14c2/64 scope link
       valid_lft forever preferred_lft forever

IP ROUTE

El comando ip route muestra la tabla de enrutamiento:

$ ip route
default via 192.168.0.1 dev enp0s25 proto static metric 100
169.254.0.0/16 dev enp0s25 scope link metric 1000
192.168.0.0/24 dev enp0s25 proto kernel scope link src 192.168.0.20 metric 100

KILL - PKILL - KILLALL

Como sabras, hay más de una forma de matar un proceso de Unix, los sistemas Unix y Linux ofrecen una conveniente selección de comandos para finalizar procesos. Podremos matar por ID de proceso o por nombre. Podremos matarlos individualmente o en grupo a la vez. En cualquier caso, los diversos comandos kill están a nuestra disposición y debemos estar listo para usarlos según sea necesario.

$ kill 1234
$ pkill bad
$ killall badproc

PASSWD

El comando passwd es probablemente obvio cuando se trata de la seguridad del sistema, no debe omitirse de ninguna lista de elementos esenciales de seguridad. Es importante tener una política madura para los cambios de contraseña, especialmente cuando los usuarios son cambiantes.

Sin embargo, el comando passwd no solo se usa para cambiar las contraseñas. También podemos usarlo con sudo para cambiar las contraseñas de otros usuarios, bloquear/desbloquear o caducar cuentas, verificar el estado de la cuenta y cambiar la configuración que determina cuándo caduca una contraseña o cuándo debe avisar del cambio de la misma.

Podemos consultar la página del manual (man passwd) para obtener detalles y usar comandos como estos:

$ sudo passwd ruben.ramiro <== cambiar contraseña a ruben.ramiro
$ sudo passwd -e andres   <== Caducar la contrasela de dory (forzar reseteo)
$ sudo passwd -i luis  <== Desabilitar cuenta

PWCK

El comando pwck realiza una especie de comprobación de cordura en sus archivos /etc/passwd y /etc/shadow, asegurándonos de que los campos obligatorios estan presentes, existan archivos y directorios, etc.

$ sudo pwck
user 'squash': directory '/home/squash' does not exist
user 'squash': program '/bin/bsh' does not exist

SETFACL - GETFACL

No permitas que la fácil visualización de los permisos de tipo rwxr-x --- te hagan creer que esto es todo lo que hay para archivar permisos en sistemas Linux. Con los comandos setfacl y getfacl, puedes dar acceso a un archivo a alguien que no sea el propietario de un archivo y que no sea miembro del grupo asociado ( Por que no queremos que lo sean). Supongamos que deseamos que Usuario1 tenga acceso de lectura a un archivo que describe las  instrucciones de configuración de ufw, pero nada más. Usamos un comando como este para modificar la lista de control de acceso (ACL) para el propio archivo:

$ setfacl -m u:Usuario1:r ufw-setup

El comando getfacl mostrará que se realizó el cambio:

$ getfacl ufw-setup
# file: ufw-setup
# owner: shs
# group: shs
user::rwx
user:Usuario1:r--        <===
group::rw-                      
mask::r--
other::---

SESTATUS - APPARMOR

Los comandos sestatus y apparmor pueden mostrar el estado de las herramientas SELinux y apparmor que proporcionan aislamiento entre las aplicaciones que utilizan el control de acceso obligatorio. Si estamos utilizando estas herramientas, debemos saber cómo mostrar su estado.

sestatus:

$ sudo sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

apparmor:

$ sudo apparmor_status
apparmor module is loaded.
18 profiles are loaded.
18 profiles are in enforce mode.
   /sbin/dhclient
   /usr/bin/evince
   /usr/bin/evince-previewer
   /usr/bin/evince-previewer//sanitized_helper
   /usr/bin/evince-thumbnailer
   /usr/bin/evince-thumbnailer//sanitized_helper
   /usr/bin/evince//sanitized_helper
   /usr/lib/NetworkManager/nm-dhcp-client.action
   /usr/lib/NetworkManager/nm-dhcp-helper
   /usr/lib/connman/scripts/dhclient-script
   /usr/lib/cups/backend/cups-pdf
   /usr/lib/snapd/snap-confine
   /usr/lib/snapd/snap-confine//mount-namespace-capture-helper
   /usr/sbin/cups-browsed
   /usr/sbin/cupsd
   /usr/sbin/cupsd//third_party
   /usr/sbin/ippusbxd
   /usr/sbin/tcpdump
0 profiles are in complain mode.
3 processes have profiles defined.
3 processes are in enforce mode.
   /sbin/dhclient (705)
   /usr/sbin/cups-browsed (30173)
   /usr/sbin/cupsd (26828)
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

Debemos saber cómo iniciar y detener estas herramientas.

$ sudo /etc/init.d/apparmor start
$ sudo /etc/init.d/apparmor stop
$ sudo /etc/init.d/apparmor restart

para SELinux, qué representan los distintos modos:

enforcing -- La política de seguridad de SELinux está aplicada
permissive -- SELinux imprime advertencias
disabled -- SELinux está totalmente desabilitado

Muchos comandos en sistemas Linux pueden ayudarnos a administrar nuestra ciberseguridad. Aprende a usarlos, familiarizate con ellos y bastiona tus sistemas teniendo en cuenta los mismos, como se indica en las guias de ciberseguridad CIS.