Mostrando entradas con la etiqueta linux_sysadmin. Mostrar todas las entradas
Mostrando entradas con la etiqueta linux_sysadmin. Mostrar todas las entradas

2023/10/08

Un poco de history

En esta ocasión, algunas ideas y tips relativas al comando history.

Provee la funcionalidad de registrar los comandos ingresados para consulta o reejecución.

Repecto a la concurrencia, tiene la particularidad de que a medida que se van cerrando las sesiones se van guardando, cada una con su estado y sobreescribiendo las otras. En otras palabras, gana la última que escriba y eso vale para las abiertas que no tenés a la vista como accesos vía ssh o terminales en otras workspaces.

El registro está en ~/.bash_history, se puede editar.

Con el comando 

history -d N

eliminar la línea N.

Si no querés que se salve

unset HISTFILE && exit

y este que es más lindo, pero no cierra la ventana si estás en un entorno gráfico

kill -9 $$ 

y la verdad que no sé que hace en un entorno no gráfico.

Un truquito que se me ocurrió hace muchos años, incluso me lo pagaron en la revista Linux Journal, lo llamé "disposable alias", me había matado con el texto y lo redujeron a casi nada:

 

tech tip
tech tip

 

Consiste en agregar un comentario al final de los comandos que querés ejecutar varias veces pero no vale la pena hacer un script o un alias y querés recuperar con control-R:

comando ; # tag

Por ejemplo:

find . -iname "*borrar* -exec ls -l {} \;" ; # listar_a_borrar

Si pensás que con control-R borrar podés lograr el mismo efecto, considerá que cerca va a estar lleno de cosas como:

view borrar.txt

rm borrar2.txt

mkdir TRASH

mv borrar3.txt TRASH

y así...

 

La joya


Todo esto que escribí es solo para entrar en tema, ¿qué pasa si ejecutaste algo como esto?

export HTTP_PROXY=http://user:password@server:port
 
Te ha quedado en history la clave del proxy, para que la vea cualquiera que pueda acceder a tu history.
 
Tenés que hacer history | less para encontrar el número y luego history -d N.
 
Según ví en man history, hay toda una serie interminable de opciones para hacer... ni entendí bien qué, tomar un comando, reemplazarle una parte y ejecutarlo, me parece un poco bloatware.

 
Hay una manera mucho más sencilla 
 

Escondida en la documentación, hay una joyita que Mar Fer comentó en una conversación cyberciruja. Si tocás una cierta variable de la configuración, podés evitar que queden registrados los comandos de las líneas que inicies con espacios.

 

 
HISTCONTROL

A colon-separated list of values controlling how commands are saved on the history list. If the list of values includes ‘ignorespace’, lines which begin with a space character are not saved in the history list.

 

Cuando Mar Fer contó, me fijé en man history y nada dice, casi que parecía un bug, pero no, it is a feature.


Perspectiva de seguridad

 

Debido a la destrucción producto de la concurrencia, la facilidad de eliminar, editar o incluso suprimir todo, history sirve de modo muy incompleto para análisis forense. Si realmente necesitás trazabilidad, andá por el lado de auditd.

Respecto a comentar que existe lo de HISTCONTROL, un atacante que lo conozca podría en el medio de una serie de comandos normales que no llamarían la atención, ejecutar sin que quede registrado alguno malicioso en particular.

Mantener oculto lo de HISTCONTROL sólo contribuiría a una falsa sensación de seguridad mientras que el hacerlo conocido ayuda a que hayan menos datos sensibles en history, gana comentarlo.


2023/09/29

Cómo pegar texto sin portapapeles

Supongamos estos escenarios:


Tenés una VM recién instalada sin entorno gráfico y hay que ejecutar algunas instrucciones muy largas. Como no tenés portapapeles, a tipear.

Estás haciendo login en una terminal o aplicación que no soporta copiar y pegar y terminás bloqueándote porque tenés una clave tipo "1lI0OG68B".

Estás llenando un campo en una página web que por algún perverso motivo tiene

 <input  type="text" onpaste="return false" /> 

Seguro te ha ocurrido cuando te piden un mail y en la verificación no te deja pegar.

La generalización del problema es:

 

Quiero pegar texto y el portapapeles no funciona.


Entonces pensás. Si hiciste ataque del "falso pendrive" en el cual pusiste un microcontrolador que se registra como un teclado y envía texto, ¿se podría hacer algo parecido con software? ¿Un programa que envíe el texto a la ventana como si fuera el teclado?

Pues existe y si usás X11, no Wayland, se llaman xdotool.

Para saber si usás X11, ejecutás:

$ echo "$XDG_SESSION_TYPE"

o

$ env | grep -E -i 'x11|xorg|wayland'

Para instalar xdotool en Debian y derivados

$ sudo apt install xdotools

Luego, tenés que ejecutar esta secuencia:

  • Encontrar la ventana
  • Seleccionar la ventana
  • Enviar el texto

Por ejemplo:

xdotool search "Virtual" windowactivate --sync type "ls"

¿Fácil? Nada lo es. Si mirás 

$ man xdotool

verás que es una herramienta superpower, pero quedémonos con lo más básico y veamos los detalles

 

Encontrar la ventana


El search viene a ser un /.*PATTERN.*/i

Otra, hay ventanas embebidas, por ejemplo para firefox, te trae todas las solapas:

$ xdotool search "Firefox" | wc -l
Defaulting to search window name, class, and classname
94

 

Seleccionar la ventana


Es hacerla activa y el --sync es para que espere a que ocurra

 

Enviar el texto


Esto no debería tener sorpresas hasta que lo probás y el teclado de un host no corresponde con el de destino.

Se debe a que en realidad no se están enviando letras sino keycodes, que es exactamente lo mismo que pasa con el microcontrolador.

O cambiás la disposición del teclado en el destino o tenés que hacer alguna conversión del texto que vas a enviar. Un tr nunca viene mal, hasta que intentás hacerlo y te recomiendo cambiar la disposición.


Si no podés hacerlo y no hay mucho que enviar, te recomiendo que lo mandes como está y luego edites y corrijas, perdí un montón de tiempo con tr

 

Retrospectivamente, lo mejor sería escribir un programita que haga el proceso inverso, obtener el keycode de las teclas que habría que mapear y que genere el texto apropiado pero ya es todo un proyectito.


Ponele que no podés cambiar la disposición del teclado, aún queda el Plan Base64.

Primero la falla y luego con base64
Primero la falla y luego con base64

Después de haber fallado:

  1. Pasás el texto a base64
  2. Preparás el comando y ponés el cursos entre las comillas ""
  3. Enviás el texto
  4. Ejecutás falla porque el "=" no se transmite...
  5. Lo arreglás a mano y volvés a ejecutar
  6. Mostrás el contenido correcto

 

Ideas adicionales


En una terminal no X de una VM, instalando gpm se puede copiar y pegar localmente, pero aún con VboxAdditions y el portapapeles activado no pude pegar entre entornos. Igual no me maté mucho probando.

Lo de los campos a los que no se les puede pegar, que el ejemplo más básico sería una página que abrís directamente del sistema de archivos con este contenido:

<form>
  <input type="text" /><br/>
  <input type="text" /><br/>
  <input type="text" onpaste="return false" />
</form>

lo podés burlar muy fácilmente quitando lo marcado en amarillo desde el navegador con Developer Tools, ahí fué la seguridad de Client Side Validation...

Estos métodos pueden parecer rehacking pero si mirás atentamente sólo estás introduciendo texto, no hay fuga de información, cosa que sí habría en caso de funcionar el portapapeles.

Una idea para facilitar la transcripción de credenciales cuando todo lo demás falla, es  que tengan la forma ???_???_???_???, no disminuye la fortaleza y facilita la copia humana.

Finalmente, si usás estos métodos con claves, no te olvides de borrar en el historial de comandos...

Bonus: gzalo me avisó que la mayoría de los password managers tiene esta función, en el caso particular de KeePassXC es botón derecho sobre la cuenta, "Perform Auto-Type", que le envía la clave a la última ventana a la que le hayas hecho foco. Probalo con una cuenta inútil y un editor de texto hasta que lo entiendas bien.

Bonus: lo de usar un microcontrolador para almacenar claves es la idea que todos tuvimos pero solo mar fer realizó.


Dejo pegados acá los comandos:

 

xdotool search "ventana" windowactivate --sync type "txt"

 

xdotool search "ventana" windowactivate --sync type $( echo "txt" | base64 ) 

cmd=$( echo "" | base64 -d )

 

xdotool search "ventana" windowactivate --sync type $( base64 script.sh) 

echo "" | base64 -d > script.sh




2023/07/09

Aprovechando pantallas obsoletas: la implementación

 

Esto viene de una idea.

Obviamente la experiencia que transité no corresponde a lo que he dejado registrado, al ser una investigación ha habido una ida y vuelta y varias de las pruebas infructuosas no quedaron registradas

 

Implementación

Lo que terminé haciendo es VNC al Remoto, para el momento de iniciar la aplicación y hacer ssh -X al principal. Luego se puede minimizar y volver a maximizar cuando hace falta interactuar. En el caso de xwindows pelado como es con una tablet, la interacción es desde la tablet.


Los pasos del setup


Principal

sudo apt install remmina-plugin-vnc

 

Remoto linux

Como es i32, tengo un Linux Mint 19 con XFCE.

 

Autologin

sudo vi /etc/lightdm/lightdm.conf

    [Seat:*]
    autologin-session=xfce
    autologin-user=YourDesiredAutoLoginUserName
    autologin-user-timeout=0


VNC server

sudo apt install x11vnc
x11vnc -storepasswd somefile


Cuando te conectás te aparece un botón efímero en Secundario. Para evitarlo, le ponemos autenticación más que por seguridad.

Autostart de VNC

  Settings ->
    Session and startup ->
      Application autostart ->
         add x11vnc
            x11vnc -rfbauth somefile


Ver IP

sudo apt install xfce4-genmon-plugin

 
panel -> add new items -> generic monitor
armar script con este contenido y ponerlo en "command"


ip a | grep inet.*global | cut -d" " -f 6

 


Remoto android


samsung tab 3 lite sm-t110 android 4.2.2

Hay que instalar XServer-XSDL en su versión v1.20.41_apkpure de
https://sourceforge.net/projects/libsdl-android/files/apk/XServer-XSDL/

Cuando falla con "Error: X server failed to launch", hay que reiniciar y configurar seleccionar

resolución nativa
x1
device configuration ->
   mouse emulation ->
      mouse emulation mode ->
         desktop, no emulation

Cuando aparece la cuenta regresiva, tocar hasta tener display number = 3

Sacado de https://www.youtube.com/watch?v=TcgTrkA8Oj0

Me falta autostart, por ahora puedo prescindir. Estaría bueno un vnc server pero no hay, quizás lo mejor sería ver de meter un linux, no vale la pena.



Los pasos de la conexión

 

A linux

Via VNC, conectar a Secundario, la IP debe estar en el Panel

Abrir una terminal

ssh -X a Principal

Ejecutar el comando deseado, por ejemplo, "top"

 

A android

En la pantalla de la tablet debe haber instrucciones tipo:

export DISPLAY=192.168.1.105:3

export PULSE_SERVER=tcp:192.168.1.105:4713


Se invoca así:

xwindows-manager & mate-terminal -e top


o así:

mate-terminal --display=$DISPLAY -e top

 

Detalles de uso


xed 

en linux Secundario hace el render en el principal, debe ser por su integración con Mate, así que hay que usar otro, yo puse /opt/sublime_text/sublime_text


screensaving y powersaving

En todos los Secundarios hay que apagar los salvapantallas y poner al máximo o infinito los tiempos de activación de bajo cosumo.

Firefox

En linux:

firefox -P remoto https://www.google.com

En android, muy difícil de interactuar:

firefox -P remoto --display=$DISPLAY  https://www.google.com

 

En tablet 

 

teclado

Para hacer aparecer el teclado en la tablet que tengo, hay que apretar el botón del medio para elegir la xserver y ahí aparece con el teclado que luego se quita con el botón de volver.


move y resize

se puede mover, pero no conseguí cambiar el tamaño, voy a ver uno de estos días si al menos se puede setear al invocar el comando.


Evidencias


En esta imagen podemos ver en la conexión de VNC a una netbook, una terminal con ssh -X de retorno al sistema principal y una tablet con x-windows aguardando conexiones.


Conexiones abiertas
Conexiones abiertas

En esta, hemos abierto un xcalc en el principal con su render en la netbook y el top de la principal con su render en la tablet.


Programas en ejecución
Programas en ejecución


2023/07/04

Reflexiones sobre rbash

Supongamos que tenemos un linux al cual se accede por ssh. La situación normal es que a nivel de permisos tenemos root y el resto.

El usuario root puede hacer todo, listo.

Dentro de ese resto, manejando grupos y permisos podríamos más o menos manejar algún tipo de restricción. Una medida común es utilizar sudo, que habilita  una lista de acciones que podrá ejecutar quien tenga los permisos.

Pero, ponele que en lugar de estar viendo como le permitimos a los usuarios hacer algunas tareas administrativas, estamos buscando restringir lo que ya pueden hacer. Si el usuario en realidad es una cuenta para que un script pueda ejecutar algunas consultas sobre el sistema, no hay motivo para que pueda ejecutar ningún otro comando que no corresponda a lo que va a hacer.

Para este requerimiento, se puede usar rbash.

Si, si, ahí los del fondo, escuché que existe selinux y apparmor, pero esas son palabras mayores, quedémonos con lo sencillo.


Lo que hace rbash es empezar por desabilitar un montón de comportamiento provisto por bash, acá está la lista completa, lo más importante es que no permite cd ni cambiar la ruta de invocación de comandos.

Además:

The restricted shell mode is only one component of a useful restricted environment. It should be accompanied by setting PATH to a value that allows execution of only a few verified commands (commands that allow shell escapes are particularly vulnerable), changing the current directory to a non-writable directory other than $HOME after login, not allowing the restricted shell to execute shell scripts, and cleaning the environment of variables that cause some commands to modify their behavior (e.g., VISUAL or PAGER). 


Sumado a eso, en .bashrc o similar hay que setear el PATH a una carpeta con symlinks a los ejecutables permitidos, según he visto que se hace.


Luego, se debe considerar que:

When a command that is found to be a shell script is executed (see Shell Scripts), rbash turns off any restrictions in the shell spawned to execute the script.

Estoy citando pues como tengo casi nula experiencia con rbash, me siento irresponsable. Pero mi ínfima experiencia algo me ha hecho pensar.

 

Vamos ahora al escenario concreto, quiero:

  • que exista una cuenta
  • que tenga shell restringido
  • a la que sólo se pueda acceder vía ssh
    • esto implica no login por consola ni "desplazamiento lateral" tipo su o login

Este comando lo hace:

$ sudo adduser  --shell /usr/bin/rbash --disabled-login  prueba

Si estás modificando un usuario existente, editás /etc/password para que tenga el shell correcto y /etc/password para deshabilitar el login.

También se hace con 

$ sudo passwd -l prueba

Que le agrega a "!" al password existente.

De un modo u otro lo controlás con:

$ sudo grep prueba /etc/passwd /etc/shadow
/etc/passwd:prueba:x:1001:1001:,,,:/home/prueba:/usr/bin/rbash
/etc/shadow:prueba:!:19542:0:99999:7:::

Solo vía ssh, hay que habilitar la key ya que se trata de clientes script, no de personas ingresando claves, aunque con la key un usuario puede entrar.

$ ssh-keygen -f prueba.key -t ecdsa

En la carpeta del usuario prueba, hay que crear .ssh con rwx------ y el archivo authorized_keys con permisos rw------- y el contenido de prueba.key.pub.

 

rbash en acción
rbash en acción

El problema que hay acá es que si ejecutás:

$ ssh prueba@localhost -t bash

sshd ignora el shell de /etc/passwd y te da un shell irrestricto.

 

rbash bypass
rbash bypass

Se arregla de dos maneras, una global y otra específica para cada usuario.


La global es poner en sshd_config esta línea, que no la probé:

ForceCommand rbash

Tiene la ventaja de restringir a todos por si alguno se te escapa, pero si querías tener uno que haga de administrador, vas a tener que ponerle específicamente que pueda ejecutar sudo.
 
La específica para cada usuario es poner no-pty  en  .ssh/authorized_keys
a la key con la que se autentica.Queda algo asi:


no-pty ssh-ed25519 AAAAC3NzaC1....

El problema es que perdés el prompt y bash completion, algo completamente irrelevante para un script.

 
rbash con no-tty en authorized_keys
rbash con no-tty en authorized_keys

 

no login
no login

Mis reflexiones

 

Porque no password al azar

Se podría poner un password al azar, pero al ser un password existente hay una increíblemente remota posibilidad de que alguien le acierte. También que al azar sea un password en un diccionario. O que en el momento de la creación haya leak.

Es mejor poner "!" antes que usar azar pues es un indicador visual y fácil de controlar de modo automático que luego no cambie la situación.

Es mejor dejar solo "!" pues agrega que no haya ninguna posibilidad de login.


Porque no ForceCommand rbash

Si la idea es que en ese equipo no haya ningún usuario remoto sin rbash, de acuerdo con ForceCommand rbash. Pero eso implica que al menos a algún usuario hay que habilitarle que pueda ejecutar sudo, además de las reglas de sudoers.

Me parece más sencillo configurar no-pty en .ssh/authorized_keys para cada usuario a restringir.

Igual en este aspecto mi opinión no es tan fuerte como con el punto anterior. De hecho, mientras escribo esto, no puedo dejar de notar que ForceCommand rbash + sudo responde más a la política de denegar todo y luego permitir de a uno, como que cambiaría de idea muy fácil... listo, ya cambié de idea.

Igual mi instinto algo me dice a favor de no-pty, por el lado de evitar una denegación de servicio. Si vuelvo a cambiar de idea, lo registraré.

Mi posición actual es, depende del perfil de uso del equipo, si es de uso general y hay que restringir a un usuario de servicio, no-pty, si nadie debería acceder salvo ciertas tareas de mantenimiento, ForceCommand rbash + sudo.

 

Disclaimer

No tomes este post como ninguna autoridad de cómo implementar correctamente rbash, no he investigado la parte de las variables de entorno ni sometido a pruebas exhaustivas.

 

 

2023/06/18

Aprovechando pantallas obsoletas: la idea

Desde hace rato que la acumulación de netbooks de 2GB y tablets con android 4.x me viene haciendo mal y el demonio interno me dice que aproveche al menos las pantallas, asi que me puse.

Mi contexto histórico relacionado: había incursionados hace muuuuucho tiempo en utilizar dual head mediante el uso de dos placas de video cuando tenían una sola salida. También había investigado, sin éxito, el usar una misma computadora con dos placas de video, dos mouses y dos teclados como si fueran dos.

Luego, intenté nuevamente usar las pantallas peladas, pero como hablan LVDS, quedó fuera de mi alcance.

Luego, con éxito, usar varias máquinas a la vez.

Como siempre, empecé preparando un mensaje con preguntas, en este caso dirigido al chat de cybercirujas, que decía algo así como:

"Tengo un problema, aparte de la cara. El contexto es que querría usar esas notebooks pedorritas de 1 o 2gb RAM por sus pantallas, pero sin ejecutar nada más que linux base + xwindows. Por ejemplo para tener abierto en mi máquina principal un firefox con una cuenta de mail alternativa y visualizarlo en la notebook. Si además funciona el portapales, es un plus."

Como siempre, continué con la técnica de preguntar bien para aprender, escribí un montón de mensajes alternativos y seguí pistas en Internet hasta que comprendí bien el problema y algunas posibles soluciones y esto es a lo que llegué, no voy a contar toda la historia porque la verdad es que no la recuerdo.

Comencemos por la topología y mis requerimientos, habiendo un nodo principal y uno o más secundarios.

 

Topología


Principal ---> Secundarios

La idea es ejecutar en Principal una aplicación y que se visualice en Secundario, esto es porque los secundarios pueden no tener la potencia o carecer del contexto. Es un plus mantener la interacción desde Principal, pues Secundario puede estar lejos del alcance o sin dispositivos de entrada.

Con contexto me refiero a que puedo tener una VM que está conectada a una VPN, puedo mostrar el escritorio de esa VM en Secundario pero no puedo ejecutarlo ahí y menos tener la conexión a la VPN.

 

Una manera de expresar esto es:

 

Interacción -> Ejecución -> Visualización

 

Lo que deseo es:

 

Principal -> Principal -> Secundario

 

Requerimientos

 

  • Van con nombres para luego verlos en una tabla comparativa.

 

Incondicionales

 

  • Render Remoto: Usar la pantalla remota.

 

Negociables

 

  • Input en Principal: que tome el teclado y el mouse de la principal.
  • Ejecución en Principal: el contexto de ejecución debe ser en Principal
  • Visibilidad Permanente: que independientemente de lo que haya en Principal, por ejemplo al cambiar de escritorio, se siga viendo.

 

Adicionales

 

  • Modo Render Aplicación: que se visualice una ventana en particular.
  • No SSH a Principal: que no se ingresen credenciales del principal en el secundario.
  • Modo Render Total: que se muestre todo el desktop. Podría servir como un facilitador de navegación, pero si es el único modo es poco útil.
  • Integración: que haya integración con el display principal como si fuera un monitor más.

 

Transversal

 

Y existe un requerimiento adicional que es un plus:

  • Autónomo: Sin interacción física con el equipo remoto, tal que el dispositivo puede estar en un lugar de incómodo acceso o sin periféricos de entrada.


Recursos disponibles


  • navegador con http: vendría a ser el más portable, pero siempre ocupa una ventana en Principal, se parece conceptualmente a lo que hice con xzoom en el sentido que se toma algo que se está visualizando y se transmite, en el caso de xzoom a una ventana local.
  • xwindows: es el más natural, pero implica que haya xwindows en los Secundarios, cosa que a veces puede ser dificultoso.
  • vnc: permite desde una máquina ver y potencialmente interactuar con otra.
  • ssh: permite acceder de modo remoto y seguro y meter xwindows en un tunel.
  • x2x: permite con teclado y mouse saltar de un escritorio a otro remoto que tenga xwindows.

 

Un poco de análisis


Para cumplir con Principal -> Principal -> Secundario, mi sueño sería que en Principal yo lance algo, aparezca en Secundario y pueda seguir interactuando desde Principal.

 

x2x (Principal -> Secundario -> Secundario)

 

Usar x2x queda descartado pues la aplicación se ejecuta en Secundario y en mi caso en particular, como tengo tres monitores en L, el escritorio remoto sólo se puede recorrer con esa misma forma en L. Recuerdo hace un tiempo haber visto el código fuente de x2x a ver si podía darme cuenta por donde tendría que investigarlo y me superó. Pero anotemos que podría servir para la interacción.

 

VNC (Principal -> Secundario -> Secundario)

 

VNC queda descartado por la misma ejecución en Secundario. También anotemos que podría servir para la interacción.

 

Deskscreen y WEYLUS (Principal -> Principal -> Secundario)


En un video ví estas opciones. Usan el navegador del lado de Secundario.

WEYLUS es la única opción que ofrece Integración, pero sólo con chipset Intel, el cual no tengo.

Tienen como problema sólo mostrar lo que se está viendo, si te pasás a otro desktop, deja de visualizar. Se soluciona con "always on visible workspace", lo que no es ninguna solución pues el objetivo era que no ocupe pantalla en Principal. Si lo que te interesa es mostrar en Secundario, como por ejemplo para compartir con otras personas en una red local, te servirían.

https://deskreen.com/lang-en

https://github.com/H-M-H/Weylus

 

ssh -X (Principal -> Secundario -> Principal)

 

Para esto con conviene usarlo al revés, Secundario -> Principal -> Secundario, con lo cual tenemos la ejecución en Principal y visualización en Secundario, solo nos falta ver el asunto de la interacción. No me gusta porque hace falta que el Secundario se autentique frente al Principal y no es autónomo.

 

La solución

 

Esos "descartado" de antes no eran definitivos y si hacemos unas combinaciones, tenemos algo que aunque un poco complicado de poner en marcha y utilizar, cumple bastante bien.

La combinación es instalar o aprovechar el xwindows del Secundario. Desde Secundario con ssh -X abrir la aplicación y luego con x2x o VNC desde Principal interactuar. Por el bug de x2x, nos quedamos con VNC.

+----------------+        +--------------+
| Principal      +---VNC--> Secundario   |
| +------------+ |        | +----------+ |
| | Aplicación <-- ssh -X --+ Terminal | |
| |            | |        | +----------+ |
| |            | |        |  +--------+  |
| |            +--xwindows---> render |  |
| |            | |        |  +--------+  |
| +------------+ |        |              |
+----------------+        +--------------+

 

Comparativa



DeskscreenWEYLUSx2xvnc + ssh -X
render remotosisisisi
input en principalsisisisi
ejecución principalsisinosi
visibilidad permanentenonosisi
render aplicaciónsinosisi
no ssh a principalsisisino
render totalsisinono
integraciónnopotencialfalla por "L"no


Esto sigue en la implementación





2023/03/06

VirtualBox con Secure Boot

Hago esta nota más para no tener que buscar y recordar. Tomé todo de [1] y [2] y le pongo un poco de mi sabor, pues tengo mezcla con otro tema. De paso queda en spanish.


Tengo una máquina en modo dual boot con Windows 10 y bitlocker por un lado y Ubuntu 22 por el otro. En Windows 10, aparentemente por bitlocker, las virtuales con VirtualBox cada tanto le hacen tirar un BSOD. Mitiga un poco bajar en Execution Cap (de la virtual a usar, Settings -> System -> Processor -> Execution Cap) hasta el piso de lo verde, evitar hacer operaciones intensivas de disco y darle mucha memoria para que evite swappear, pero no alcanza, no puedo tener un BSOD en medio de una charla o taller.

Cuando instalé VirtualBox en Ubuntu, me encontré con un diálogo que nunca había visto, debido a que tiene activado Secure Boot.

No tomé nota bien de qué ofrecía o pedía, algo de una clave para UEFI o similar. Le dije que no, probablemente cancelé cerrando la terminal pues no me dejaba de otra manera. Luego, aun desinstalando y volviendo a instalar no volvió a ofrecerlo, así que no pude documentar.

 

Como efecto colateral me hizo reingresar la key de bitlocker al reiniciar, eso es, tras arruinarme el grub, de ahí en más, arranca directo con Windows.

Esto no es gran problema, cuando quiero arrancar con linux invoco el menú de boot del firmware que reconoce la partición UEFI Ubuntu, con eso se carga el grub y de ahí Ubuntu o si quisiera Windows.


Yendo a lo importante, al intentar ejecutar VirtualBox falla con un mensaje parecido a

 

modprobe vboxdrv failed. Please use 'dmesg' to find out why.
 

dmesg dice:

 

kernel: Lockdown: modprobe: unsigned module loading is restricted; see man kernel_lockdown.7

 

Buscando en internet llegué, tras varios artículos y respuestas diciendo "desactivá Secure Boot", que estupidéz, a uno que aunque bastante viejito es correcto.

Lo que dice es que si tenés Secure Boot, el kernel no te va a dejar insertar módulos que no estén firmados y brinda una manera de firmarlos. No voy a intentar explicar el detalle por que tengo una intuición pero no claridad.

Mi intuición es, para que un módulo esté firmado, hay que hacerlo con un secreto. Ese secreto hay que cargarlo en alguna zona protegida.

 

Esto genera el secreto:

 

$ openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=VBox Cert/"

 

Esto firma el módulo con el secreto:

 

$ sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ./MOK.priv ./MOK.der $(modinfo -n vboxdrv)

 

En mi caso la expansión es:

 

$ sudo /usr/src/linux-headers-5.15.0-48-generic/scripts/sign-file sha256 ./MOK.priv ./MOK.der /lib/modules/5.15.0-48-generic/updates/dkms/vboxdrv.ko

 

Lo mismo para hay que hacer para vboxnetflt.

Esto inicia el proceso de guardar el secreto en la zona protegida, es registrar la key con Secure Boot, te pide un secreto que establece la cadena de confianza rumbo al siguiente paso:

 

$ sudo mokutil --import MOK.der

 

Reiniciás:

 

$ shutdown -r now

 

Todo lo que sigue es la finalización del proceso de guardar el secreto.

Te aparecen unas pantallas ascii azul con un menú sencillo, en este elegís qué vas a hacer

 

Perform MOK management

+-----------------------+
|     Continue Boot     |
|      Enroll MOK       |
| Enroll key from disk  |
| Enroll hash from disk |
+-----------------------+

 

Te permite ver el secreto a registrar o continuar, continuar


[Enroll MOK]

+------------+
| View key 0 |
|  Continue  |
+------------+

 

¿Está usted seguro?

 

Enroll the key(s)?

+---+
|No |
|Yes|
+---+

 

Te pide el password que ingresaste previamente:


Enroll the key(s)?

+-------------------+
| Password:         |
+-------------------+

 

Listo

 

The system must now be rebooted

+--+
|OK|
+--+

 

Con esto se puede comprobar si está enrolado:

 

$ mokutil --test-key MOK.der
MOK.der is already enrolled
 

Con esto listás las keys:

 

$ mokutil --list-enrolled | grep -e "\[key" -e Issuer


[key 1]
        Issuer: C=GB, ST=Isle of Man, L=Douglas,
        O=Canonical Ltd.,
        CN=Canonical Ltd. Master Certificate Authority
[key 2]
        Issuer: CN=mint Secure Boot Module Signature key
[key 3]
        Issuer: CN=VBox Cert




Ese MOK.priv lo podés borrar del sistema tras resguardarlo, por ejemplo dentro del mismo keepass donde guardás las otras claves, en el campo de comentario. Al DER lo pasás antes a ascii con base64.




[1] https://askubuntu.com/questions/760671/could-not-load-vboxdrv-after-upgrade-to-ubuntu-16-04-and-i-want-to-keep-secur

[2] https://sourceware.org/systemtap/wiki/SecureBoot

2022/02/08

Rescatando un scanner de la calle

Como quizás hayas visto antes con un touchpad y un dvr, tengo una cierta compulsión por adoptar componentes obsoletos de hardware abandonados en la calle, aunque ello se cruce con mis proyectos menos inútiles y alguna vez me obligue a purgar. Hay gente que tienen algo parecido con perros y gatos. Tengo como ventaja que aunque juntan mugre mis cosas, no la generan y además sólo ocupa espacio estático. Es verdad que no les puedo hablar y si lo hiciera no lo evidenciaría por escrito.

En esta ocasión, una impresora multifunción con todos sus cables, lo que me cuenta que el motivo de su abandono probablemente esté ligado al agotamiento de sus insumos o un alto costo de reposición y bajo retorno o alguna falla. Mmh, qué brillante, ¿queda alguna otra posibilidad?. Lo normal es que algo con fuente venga sin fuente y ha venido incluso con el cable USB.

El primer impulso obviamente es conectarla a ver si anda, pero hay que tener cuidado, estamos suponiendo los motivos del abandono sin conocerlos a ciencia cierta. ¿Y si tenía una falla electrónica y al conectarla me vuela un puerto USB?

Por suerte, así como el dinero atrae al dinero y una mano ayuda a la otra, tengo en el montón de basura alguna netbook que funciona.

Como impresora impresora, no me interesa, la operación hasta ahora ha tenido como único costo enfrentar la resistencia de las personas de mi hogar a la introducción del componente ajeno. Para saber si funciona, debería comprar cartuchos y si no llega a funcionar, ese sí que sería un costo considerable sin ningún tipo de beneficio, sólo un "te lo dije".

Es interesante el scanner, aunque con poca frecuencia, algunas veces necesito digitalizar alguna superficie y aunque el celular suele alcanzar, no es muy cómodo y siempre quedan sombras y distorsiones (¡ay, qué vergüenza! acabo de escribir distorciones, eso me pasa por juntarme con electrónicos).


Debería tambien contemplar algún fallo de alimentación seguido de un corto que haga saltar la térmica y me apague esta máquina y pierda parte de lo escrito, pero voy a confiar en la zapatilla y prender una velita virtual para que todo salga bien.

Esta bueno que haya venido con la fuente pues tiene un conector loco que nunca había visto y me hubiese obligado a investigar y aprender algo que no me interesa ni sirve para nada más que ejercer mi ingenio y este artículo no hubiera ocurrido y la impresora habría quedado para la próxima purga. Queda pendiente sin embargo ver que provee esa fuente, si fuera un 5v + 12v, sería muy útil para otros usos.

Es HP Deskjet 3050 y según su hoja de datos... no me interesa. Por inspección visual veo que no tiene lo que más querría, un puerto Ethernet o WiFi... ¡ups! la acabo de prender y no sólo los tapones siguen en su lugar sino que veo un led titilante y al lado una etiqueta que dice "inalámbrico" y en el display "puerta abierta", no sé que significa, voy a tener que ver el manual. Igual no fué tan difícil, un linux mint 17 la vió instantáneamente.

Mint 17 la vió al toque
Mint 17 la vió al toque

 

Hora de conectarla a una virtual con algo más actual e investigar si se le puede usar el scanner aunque el sensor esté fallando, pues eso es lo que ocurre y aunque me dan muchas ganas de desarmarla para corregir el sensor, a menos que impida el funcionamiento del scanner, no me aporta gran cosa.

El UART/USB que tendría que usar para programar el PIC
El UART/USB que tendría que usar para programar el PIC

 

Piece of cake, simple-scan lo vió de una, casi que me dá vergüenza haber documentado esto, pero la verdad es que cuando empecé no sabía que sería tan fácil. Pudo haber sido más oportuno, hace un casi justo un año lidié con otro scanner, me pude haber ahorrado unos pesitos..


Lo útil de esta entrada es sólo tener en cuenta la metodología para interactuar con hardware en estado desconocido, primero conectar a la pieza más barata posible que determine que es seguro seguir conectando.


No prometo nada, pero podría:

  • algún día arreglar el sensor al menos para que no aparezca el mensaje, tinta tiene pero no sé si funcionará, si se ha secado.
  • acceder vía WiFi al scanner así la puedo poner más lejos y compartirla
  • ver de reemplazar el firmware, eso sí que sería algo meritorio, convertirla en un microcontrolador con WiFi y los GPIO que debe tener












2021/11/08

Perdí una máquina

Con esto de la remotidad, hemos todos tenido problemas nuevos.


El siglo pasado me ocurrió al estar operando en un servidor que lo apagué de modo remoto pero estaba en otra ubicación, por suerte era a pocas cuadras.


Lo que ocurrió esta vez es que en la oficina tengo una máquina, con la IP fijada por DHCP. ¿Qué significa esto? Que aunque en su configuración local no tiene IP fija, el servidor de DHCP recuerda la MAC Address y me asigna siempre la misma IP. Esto es vital para que la pueda encontrar en modo remoto.

Por algún motivo que desconozco, no puedo acceder pese a que me consta que está prendida y conectada pues una persona tuvo la gentileza de ir a fijarse.

¿Qué puedo hacer? Si supiera la MAC Address, avisarle a quien administra el DHCP para que restaure la regla si es que se ha ido.

También, si pudiera acceder a una máquina en la misma red, asignarle en esa máquina esa MAC Address a una IP libre arbitraria, de esta manera:

$ arp -s 192.168.1.200 14:de:39:16:a0:57

Luego, independientemente de que dirección tenga, llegaría con:

$ ssh 192.168.1.200

Si no me creés, hacés bien. Dije lo anterior pues estoy completamente seguro que había dispositivos que para conectarte por primera vez tenías que hacer eso, pero por las dudas he comprobado el procedimiento y no funciona.


El rojo representa la temperatura del horno
El rojo representa la temperatura del horno

 

Para averiguar la MAC hay varias opciones

  • fijarse en la etiqueta del gabinete.
  • averiguar el nombre del puerto en el que está conectado y pedirle a quien administra los switches que se fije.
  • entrar una vez y consultarle al sistema operativo 

Para hacerla difícil, optaré por la última. Pero si no sé la IP...

  • Puedo fijarme en otra máquina desde la que me haya conectado la firma del servidor conservada y consultar a cada máquina que tenga SSH la firma a ver cuál coincide.
  • Puedo barrer todas las IP de la red intentando entrar


Barrer y que un equipo malicioso me tome la clave, modo hacker

 

Podría alguien tener configurado que se tome nota de las credenciales ingresadas en caso de error. No es algo que se pueda hacer con PAM según dice wikipedia de PAM,  "This lack of functionality is also the reason SSH does its own authentication mechanism negotiation." pero quizás no estoy interpretando bien, pues en /var/log/auth.log hay entradas como esta:

 

auth.log:Aug 21 22:50:55 carlos-VirtualBox sshd[65233]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.190  user=carlos


o quizás sea una falsa alarma, pues luego en SSH dice que "keyboard-interactive (RFC 4256): a versatile method where the server sends one or more prompts to enter information and the client displays them and sends back responses keyed-in by the user. Used to provide one-time password authentication such as S/Key or SecurID. Used by some OpenSSH configurations when PAM is the underlying host-authentication provider to effectively provide password authentication."

 

Luego hacemos un sudo fallido:

Aug 21 23:11:55 carlos-VirtualBox sudo: pam_unix(sudo:auth): authentication failure; logname= uid=1000 euid=0 tty=/dev/pts/9 ruser=carlos rhost=  user=carlos

Vamos bien, hay que aprender un poquito de PAM a ver como ponemos nuestro propio autenticador que guarde las credenciales.

Empecemos por...

[/etc/pam.d/sshd]
# Standard Un*x authentication.
@include common-auth

Suficiente, ya me aburrí, mejor veámosle las tripas al correr, cuando ingresamos "xxxxx" como password emite esto:

$ ps ax | grep sshd: | grep -ve grep | cut -d"?" -f 1 | xargs strace -f --attach
....
[pid 65596] read(4, "\200\216\2337-)\372dz\204\20\307\214\367\16\27\276?\346\341\26,\375\f\241\17\210\2\2318\206\340"..., 8192) = 84
[pid 65596] write(5, "\0\0\0\n\f", 5)   = 5
[pid 65592] <... poll resumed>)         = 1 ([{fd=6, revents=POLLIN}])
[pid 65596] write(5, "\0\0\0\5xxxxx", 9 <unfinished ...>
[pid 65592] read(6,  <unfinished ...>
[pid 65596] <... write resumed>)        = 9
[pid 65592] <... read resumed>"\0\0\0\n", 4) = 4
[pid 65596] read(5,  <unfinished ...>
[pid 65592] read(6, "\f\0\0\0\5xxxxx", 10) = 10
[pid 65592] getuid()                    = 0
....

 

Hagamos algo mejor, asumamos que ya conocemos el $PID del sshd y usemos clave 01234567 para variar:


$ strace -f -eread --attach $PID
...
pid 65628] read(5, "\0\0\0\0", 4)      = 4
[pid 65628] read(4, "\361\376l\340\225\267\260Y\".'\301\237\353\3412\210\4\r\273'D\301\30\272\350\346\375\3544Q\""..., 8192) = 148
[pid 65627] read(6, "\0\0\0\r", 4)      = 4
[pid 65628] read(5,  <unfinished ...>
[pid 65627] read(6, "\f\0\0\0\01001234567", 13) = 13
[pid 65627] read(5, "#\n# /etc/login.defs - Configurat"..., 4096) = 4096
[pid 65627] read(5, " issuing \n# the \"mesg y\" command"..., 4096) = 4096
[pid 65627] read(5, "algorithm compatible with the on"..., 4096) = 2358
...

Mejor, pero trae demasiadas líneas, un poquito de grep

$ strace -f --attach 65570 |& fgrep 'read(6, "\'  
[pid 66019] read(6, "\0\0\0D", 4)       = 4
[pid 66019] read(6, "\6", 68)           = 1
[pid 66019] read(6, "\0\0\0\v", 4)      = 4
[pid 66019] read(6, "\0\0\0\6carlos", 10) = 10
[pid 66019] read(6, "\0\0\0\1", 4)      = 4
[pid 66019] read(6, "\0\0\0\33", 4)     = 4
[pid 66019] read(6, "\4\0\0\0\16ssh-connection\0\0\0\0\0\0\0\0", 27) = 27
[pid 66019] read(6, "\0\0\2,", 4)       = 4
[pid 66019] read(6, "\26\0\0\0\2\0\0\0\0\0\0\0\0\0\0\2\27\0\0\0\7ssh-rsa\0\0\0\3"..., 556) = 556
[pid 66019] read(6, "\0\0\1,", 4)       = 4
[pid 66019] read(6, "\26\0\0\0\2\0\0\0\0\0\0\0\0\0\0\1\27\0\0\0\7ssh-rsa\0\0\0\3"..., 300) = 300
[pid 66019] read(6, "\f\0\0\0\t987654321", 14) = 14

 

Es verdad, no es muy fácil de automatizar, quizás sea mejor tomar probablemente el código fuente de pam_unix.so, modificarlo, recompilarlo y reinstalarlo, esto fué solo una POC de por que no hay que probar contraseñas en equipos que no confiás.

 

Barrer y que un equipo malicioso me tome la clave, modo programador


Podemos instalar nuestro propio servidor ssh modificado para que registre las credenciales.

sudo apt  update
sudo apt install dh-autoreconf libz-dev libssl-dev
git clone https://github.com/openssh/openssh-portable.git
autoreconf
./configure
make ; # paciencia

 

Buscás y buscás el punto de inserción, que resulta ser

 

patch
patch

 

Luego:

$ sudo service sshd stop
$ sudo $(realpath sshd) -D

 

Intentás conectarte y tenés las claves:

sudo tail -f /var/log/auth
Nov  8 18:14:58 template sshd[1458]: User carlos Password XXXXXXXX
Nov  8 18:14:58 template sshd[1458]: Failed password for carlos from 192.168.1.100 port 49320 ssh2
Nov  8 18:15:01 template sshd[1458]: User carlos Password 12345678
Nov  8 18:15:01 template sshd[1458]: Failed password for carlos from 192.168.1.100 port 49320 ssh2
Nov  8 18:15:05 template sshd[1458]: User carlos Password mySecret
Nov  8 18:15:05 template sshd[1458]: Failed password for carlos from 192.168.1.100 port 49320 ssh2
Nov  8 18:15:05 template sshd[1458]: error: maximum authentication attempts exceeded for carlos from 192.168.1.100 port 49320 ssh2 [preauth]
Nov  8 18:15:05 template sshd[1458]: Disconnecting authenticating user carlos 192.168.1.100 port 49320: Too many authentication failures [preauth]



Ambos métodos requieren root, así que tiene que ser un equipo del atacante o que esté comprometido.


Buscar firmas

Para consultar las firmas a cada máquina, en teoría se hace así con nmap:

 

nmap
nmap


Si no tenés nmap o el servidor no te da la información como a mi me ocurre con algunas direcciones, no sé si es por alguna configuración del servidor o falla del script de nmap, usás ssh-keyscan:

 

ssh-keyscan
ssh-keyscan


Si te habías conectado antes, con ssh-keygen podés relacionar:


ssh-keygen
ssh-keygen

 

Si tuvieras la primera conexión:

 

ssh primera conexión
ssh primera conexión

 

la correlacionás con 

ssh -v
ssh -v


No he podido relacionar las firmas de ambos métodos.


Todo esto es muy complicado pero es scripteable:

START=106

STOP=110

NET=192.168.1.

TARGET=$( ssh-keygen -F 192.168.1.108 | grep -o "ecdsa.*" | cut -d" " -f 2 )

for HOST in $(seq $START $STOP); do

ssh-keyscan "$NET$HOST" | fgrep "$TARGET"

done

 

Ejecución script
Ejecución script

Si la máquina hubiera cambiado a otra IP, la encontrábamos si estaba en el rango del seq.

 

Putty


¿Qué pasa si tu conexión fué desde putty en windows? Hay que usar Regedit, buscar esta clave y ahí la IP de interés:


HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys


SSH Host Key en putty
SSH Host Key en putty

 

Para obtener el valor, le das botón derecho, modify...

 

SSH Host Key en putty
SSH Host Key en putty

Son estos dos valores:

 

0x2c41d8156e8fa6ff033b9bccde9005e7063dbbe5cff38334e336af7569bea178

0x17657a34f156c9f05ecae35749499ef23954a1b217f42c6ac946ce2a6073f8c5

 

Ahora hay que ver como se relacionan con:


AAAAC3NzaC1lZDI1NTE5AAAAIMX4c2AqzkbJaiz0F7KhVDnynklJV+PKXvDJVvE0emUX


echo -n AAAAC3NzaC1......JV+PKXvDJVvE0emUX | base64 -d | hexdump -C

00 00 00 0b 73 73 68 2d  65 64 32 35 35 31 39 00 |....ssh-ed25519.|
00 00 20 c5 f8 73 60 2a  ce 46 c9 6a 2c f4 17 b2 |.. ..s`*.F.j,...|
a1 54 39 f2 9e 49 49 57  e3 ca 5e f0 c9 56 f1 34 |.T9..IIW..^..V.4|
7a 65 17                                         |ze.|



Puede ser que no sea con la ecdsa, supongo que sabrás arreglártelas...



Conclusión

No es buena idea intentar autenticarse ante un sistema que no sabés si es el correcto.



 






2021/09/06

Cómo firmar documentos sin imprimirlos

Que quede claro que esta firma no necesariamente es legal, viene a ser como si lo imprimieras, lo firmaras y lo volvieras a digitalizar. Me imagino que como es la otra parte la que tiene que demostrar que vos firmaste, no es problema de uno.

No sé si le dá valor legal, pero si tomarás el resultado del proceso que luego expondré y le calcularas el hash, quizás sería más legal. Si además lo mandaras por mail, me parece que le suma puntos.

El proceso que voy a explicar es para el formato pdf, para word/libreoffice/similar es mucho más sencillo, sólo abrís el documento, llenás los textos y le pegás la firma elaborada según lo explicado luego.

El documento pdf se puede abrir con libreoffice writer, supongo que también con office, pero en el primer caso al menos puede haber reflujo de los textos y romperse.

Creo recordar que con Acrobat Distiller, no sé si sigue existiendo, también se puede hacer, al menos agregar texto, pero me parece que es pago y ni he buscado si hay para linux.

Lo primero y por única vez, es armarte la firma. Esta se construye a partir de una buena foto o scan sobre fondo blanco. Podrías usarla directamente así, dejando el fondo en blanco, pero necesitarías un rectángulo libre del tamaño rectangular de la firma en el documento a firmar y deberá coincidir el blanco tuyo con el del documento.

Mejor es convertir ese fondo en transparente. Se hace de modo muy sencillo con gimp, abrís la foto y:

Firma capturada
Firma capturada

 

  • select -> by color (en el fondo blanco)
  • color -> color to alpha
  • export as -> firma.png


Firma con alpha channel
Firma con alpha channel

 

Observá que el formato nativo de gimp es .xcf, no la imagen. Esto es porque gimp no sólo guarda la imagen, también puede tener un montón de información extra como layers, channels, paths y otras cosas.

Te conviene guardar esta firma, llamémosla original y derivar cada vez que firmes una con la medida apropiada, quizas ir salvando esas medidas para no hacerlo cada vez.

El siguiente paso es separar todas las páginas, pdfseparate provisto por poppler-tools es lo que yo uso.


$ pdfseparate original.pdf partes%d.pdf 

 

Luego identificar las páginas que hay que firmar. A cada una de estas páginas, abrirla con gimp y con la herramienta de texto llenar donde haya que llenar.

Finalmente, pegar la firma y overwrite.

Documento firmado
Documento firmado

Observá que el blanco de la firma no tiene conflicto con la línea de subrayado.


Finalmente, con pdfjoin volvés a armar el pdf.

$ pdfjoin parte01.pdf parte02.pdf

Esto te lo va a dejar en parte02-joined.pdf