2019/09/22

Cambiando de grupo sin reiniciar sesión

¿Te ha pasado que acabás de instalar un programa que accede a hardware y te dice que para poder usarlo tenés que reiniciar a la windows viejo?

Algunas situaciones pueden ser VirtualBox para conectarle los USB, wireshark para acceder a las interfaces sin ser root, acceso al puerto serial y quizás al scanner.

Lo que ocurre es que necesitás pertenencia a un grupo, no es algo que se aplique así no más, hay varias maneras:

Reiniciar la sesión

Es lo que no queríamos hacer, pero si eres tan gallina, es lo tuyo.

Iniciar una nueva sesión

Artera comadreja, ok, no cerraste la sesión y te abrís una al lado con otro usuario. Te dejo de ejercicio fijarte si podés iniciar dos sesiones de XWindows del mismo usuario.

"Iniciar" una nueva sesión

¡Es la opción correcta! Una vez que estás en el grupo con, por ejemplo, addgroup, hacés su --login USER y estás adentro




Esto es para esta terminal, en las otras aplicaciones seguís afuera, pero desde esta terminal podés abrir el programa que acabás de instalar.

Unirte al grupo


Esta opción es medio rara, no la usa nadie y consiste en que a un grupo se le puede dar una clave con gpasswd, que queda en /etc/gshadow, igual que /etc/shadow, luego haces newgrp.



Ejemplo de acceso a la carpeta de USB de VirtualBox:


Esta tambien es para la terminal y te dejo como ejercicio fijarte si altera a las aplicaciones ya abiertas.

Resultado


Este es el comportamiento para acceder a USB desde VirtualBox

Primero no estás en el grupo vboxusers.


La VM arranca todo bien, pero cuando le querés conectar algo...







De cualquiera de las maneras, una vez que estás en vboxusers


Podés conectarle lo que haya en USB



Siempre...


...es mejor tomar una de estas acciones y evitar como la plaga usar sudo, pues está vez te va a funcionar, pero la próxima que hagas login, quizás te creó archivos en tu home con permisos de root y vas a tener que limpiar el desastre.

Además siempre que puedas ejecutar algo sin ser root (ni sudo) es más seguro pues tenés una defensa adicional frente a un ataque, que es que obligás a quien te ataca a escalar privilegios.

Fijate que ni mencioné la posibilidad de hacer login como root. Es de adolescentes, sentir el poder, la adrenalina. Pero una vez que aprendiste a usar *nix, madurás y sólo usás tu poder cuando hace realmente falta.


Y ya que estamos...



Como me molesta que me digan a la windows, reinicie para que los cambios sean tomados, aviso que cuando se instalan los drivers de virtualbox para poder entre otras cosas cambiar el tamaño de la pantalla, no hace falta reiniciar el sistema completo, sólo X-Windows, o sea, que con hacer logout y login alcanza, ya lo probé varias veces.

Para poder acceder a shared folders,

sudo addgroup USER vboxsf


Y más


Si quisieras crear grupos interesantes como kismet, docker y wireshark antes de instalar esos paquetes, no sé para qué, tenés que crearlos con el parámetro

--system.


2019/09/19

Juegos de cálculo seguro distribuido

En ECI 2018 hubo un curso de cripto donde mostraron varias maneras de que un grupo de adversarios puedan ejecutar cálculos con información que tienen sin compartirla, por ejemplo, empresas pueden calcular promedio de fraudes  sin que ninguna revele sus cifras.

Para mostrarlo de modo intuitivo tanto para charlas internas en el trabajo como para H4CKED 2019, he desarrollado dos juegos que paso a compartir.


En ambos casos se supone que la transmisión es completamente secreta.

Con azar

La idea es que hacemos una ronda de personas, donde la primera toma su número y le suma otro al azar, guardando ambos en secreto. El resultado se lo pasa a la siguiente participante, que le suma su número y así hasta dar la ronda completa. La primera persona le resta el número al azar a lo obtenido y tiene la sumatoria de todas las participantes, que ya puede compartir. Cualquiera divide por la cantidad de participantes y ya tenemos el promedio que queríamos.






La debilidad de este algoritmo es que cualquier par de participantes separadas por una sola persona puede atacar a esta, pues saben el valor de entrada y el de salida, cuya resta es el valor de la víctima.


Con descomposición

Una mejor versión invulnerable al ataque anterior consiste en que cada participante descompone su valor en tantos sumandos al azar como participantes hayan y envía uno a cada participantes. Cada participante toma los sumandos recibidos, los suma y comparte el resultado. Estos resultados se suman, se divide por la cantidad de participantes y nuevamente tenemos el promedio que buscábamos.








El escenario de ataque factible para este caso es que todas las participantes menos una se pongan de acuerdo para atacar a esa. Sabiendo el total, se le resta el acumulado por las atacantes y tenemos el valor de la víctima.

Multiplicación


Tambien se puede multiplicar de esta manera, con factores, salvo que si alguien tiene un cero, al menos una participante va a saberlo. Quizás habría que agregar algunas rondas de intercambio, pero para un juego ya se complica innecesariamente.

En el caso del primer juego, se puede multiplicar un cero cerca del comienzo es más identificable que al final.


Otras maneras


Hay otras maneras pero no son tan intuitivas, al menos para quienes no sabemos más que matemáticas básicas, así que no son candidatas para juegos didácticos como estos. Tampoco sé si resuelven el problema del cero en la multiplicación.

Acá tenés las tarjetas por si querés jugar







2019/09/06

Diagnostico de HTTP Headers con Polymer y Node Express dentro de TLS


El Problema

Estoy haciendo una miserable aplicacioncita con Polymer del lado del cliente y Node Express como API, siendo servidas de distintas URLs, ambas con TLS.

Al intentar agregar un Custom HTTP Header en lugar de ver un:

api_1 | { connection: 'upgrade',
api_1 |   host: 'api.techu.example',
api_1 |   'user-agent': 'Mozilla/5.0 ...Firefox/57.0',
api_1 |   accept: 'text/html,application....9,*/*;q=0.8',
api_1 |   'accept-language': 'en-US,en;q=0.5',
api_1 |   'accept-encoding': 'gzip, deflate, br',
api_1 |   'access-control-request-method': 'GET',
api_1 |   'access-control-request-headers': 'content-type',

api_1 |   'X-Practitioner-Auth': '2',
api_1 |   origin: 'https://www.techu.example' }



veo


api_1 | { connection: 'upgrade',
api_1 |   host: 'api.techu.example',
api_1 |   'user-agent': 'Mozilla/5.0 ...Firefox/57.0',
api_1 |   accept: 'text/html,application....*;q=0.8',
api_1 |   'accept-language': 'en-US,en;q=0.5',
api_1 |   'accept-encoding': 'gzip, deflate, br',
api_1 |   'access-control-request-method': 'GET',
api_1 |  'access-control-request-headers': 'content-type,x-practitioner-auth'
api_1 |   origin: 'https://www.techu.example' }



y un 

NetworkError: A network error occurred

en la consola del browser.



Como no entiendo en absoluto por qué esta ocurriendo esto, quiero descartar capas intermedias, quiero ver el tráfico de red, pero está con TLS.


No me interesa tanto mostrar la solución al problema que es CORS sino el camino seguido, centrándome en la dificultad de que haya TLS de por medio.


Alcance y consideraciones


Tengo la clave privada del servidor pues estoy en un ambiente de test y yo generé las CAs.


Tuve suerte, la ciphersuite que acordaron el servidor y el cliente es descifrable por wireshark. Según leí por ahí, hay ciertas combinaciones que lo son y otras que no. Hay maneras de forzarla.

Linux Mint 19.x.

Para variar, no sé casi nada de Polymer, Node, CORS, pero se parece a cosas que he aprendido y olvidado varias veces.


Instalar wireshark 


sudo apt install wireshark-qt

Cuando pregunta si permitir a usuarios comunes capturar en modo promiscuo, decile que si.

Luego hay que agregar el usuario al grupo y reiniciar la sesión.

sudo addgroup practitioner wireshark

Configurar el browser


Pedile al browser que deje disponibles las claves de sesión en un archivo:


SSLKEYLOGFILE=/home/practitioner/sslkeylog.log firefox


Para un launcher es parecido:


Si lo estás editando



Si lo estás creando





Una vez arrancado el browser, hay que identificar en que interfaz capturar. Podés usar ANY, pero estando con Docker mejor ser más especìfico. Sospecho que localhost es el lugar, pero comprobémoslo generando tráfico:


Tráfico en localhost y algunas interfaces de Docker


Localhost ok.


Luego hay que pedirle a wireshark que mire el archivo del browser:


(Pre)-Master-Secret log filename


y las private del sitio o sitios, yo tengo API y www, claro, si este problema se trata de algo de cross domain...



Private Keys



Mejor vaciar la cache, cerrar y volver a abrir el browser, para que no esté lleno de 304 y que agarre toda la sesión TLS.




Si tuviste éxito, vas a ver una solapita abajo que dice "Decrypted SSL"

No están de más algunos filtros como:

tcp.port == 443 && ssl.record.length > 66

La primera parte es para sacarse de encima lo que no es TLS, pero sólo si tenés la certeza que tu tráfico es sólo TLS.

Para tener esa certeza tendrías que activar en el servidor HSTS


La segunda es para eliminar los keep alives y otra información administrativa del canal. No hallé o al menos no busqué mucho como filtrar dentro del tráfico TLS, por ejemplo si quisieras sólo los GET, frame matches xxx no anda. No digo que no haya.

Con "Follow HTTP Stream" se pone mucho más amigable



Me apoyé en varias fuentes, fundamentalmente https://packetpushers.net/using-wireshark-to-decode-ssltls-packets/, donde hay más detalles relativos a las ciphersuites soportadas y como ajustarlas.

A diagnosticar

El encabezado sale "mal" desde el browser, no es problema de la API.



¿Qué estoy haciendo en el browser? Hago lo natural:


request.setRequestHeader('X-Practitioner-Auth', 'tok');

¿Qué hay de malo con eso?

Leyendo https://www.html5rocks.com/en/tutorials/cors/ inferí que el problema probablemente viene por el preflight fallido de CORS, que es ese OPTIONS sin GET posterior.

O sea que lo que puse en amarillo en realidad está ok, no me había dado cuenta que era en OPTIONS.... mejor no voy a decir nada por que no sé bien, aunque lo haya arreglado.



Supuse que la falla era tener en el middleware:


app.use(function(req,res,next) {
  res.setHeader('Access-Control-Allow-Origin','https://www.techu.example');
  res.setHeader('Access-Control-Allow-Headers','Content-Type');
  next();
});


en lugar de

app.use(function(req,res,next) {
  res.setHeader('Access-Control-Allow-Origin','https://www.techu.example');
  res.setHeader('Access-Control-Allow-Headers','Content-Type','X-Practitioner-Auth');
  next();
});



Pero no, no anda ni a palos. Despues de muchas vueltas llegué a que hay que usar CORS y listo:

npm install cors 

y en la API

const cors = require('cors');
var corsOptions = {
  origin: ['https://www.techu.example'],
  allowedHeaders: ['Content-Type', 'Autorization']
}

app.use(cors(corsOptions));


Un poco de CORS:


En resumen, en el comienzo todo era caos y promiscuidad, luego hubo SOP (Same Origin Policy) por motivos de seguridad pero eso complicaba la operativa así que hoy hay CORS (Cross Origin Resource Sharing), que es un mecanismo para que un servidor le diga a un navegador que puede ser llamado desde código provisto por otro sitio.

Que quede claro que CORS no afecta a una herramienta como Postman, en los navegadores incluso se puede deshabilitar. Dicen por ahí que con  --disable-web-security en chrome, no way firefox.

Me parece mejor implementarlo bien.


Mucho más largo, algún día...

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS