Otra vez en H4CK3D, gracias a Javier Vallejos y Fabián Portantier de Securetia y a la UP
Cuesta trabajar y asistir a todo el evento, pero pude verla a Yamila Levalle (@ylevalle) exponer algo muy razonable: los SIEMs tienen que estar correctamente desarrollados y configurados, no dejan de ser aplicaciones, que fué lo que mostró en... Blackhat usa 2019 qué capa!
Tambien a Diego Bruno y Jorge Martín Vila, mostrando OSINT relacionado a lavado de dinero, les costó meter todo el tema en el tiempo asignado, jiji.
Finalmente Gerardo D'onofrio expuso la herramienta EJBCA, para certificados, muy interesante. Y ahí me tuve que ir y no pude volver.
El nerd de Schrödinger...
Con respecto a lo que yo expuse, ha sido rara la experiencia, normalmente todo el mundo siempre te dice que salió bien, nadie que mal.
Tambien suelen haber fallas técnicas y no técnicas, como una OWASP hace mucho en la que estando a punto de mostrar un ataque, no pude encontrar el archivo pese a tener la ruta escrita delante de mis ojos. Fallas técnicas que me hayan ocurrido a mi no recuerdo pero si a otras personas.
Esta vez hubo una falla técnica de origen humano. En una de las partes de SDR con gqrx iba a escuchar una radio y el audio de un canal de TV, pero no tenía audio. Esta ausencia m hizo desistir de mostrar la transmisión de radio con un adaptador USB-VGA.
Eso en realidad fue el impacto de la falla, que fue que el battery pack se apagara y que no recordara que eso podía ocurrir, la falla humana original.
Pienso que actué correctamente al no ponerme a diagnosticar la falla, que como siempre ocurre es ínfima, pese a los resultados espectaculares.
Tambien hubo otra falla leve, al intenter leer la banda magnética el lector estaba lejos de la antena y otra que en lugar de leer el controlador de la alarma de una asistente debí haber traido uno del que ya tuviera identificada la frecuencia.
Estas fallas que me persiguirán en mis pesadillas hasta el fin de los tiempos, bajaron un poco el nivel técnico pero tembien me obligaron a hacerla más entretenida. No hubo menos información, faltaron pruebas, no es lo mismo decir que esa franja naranja es el audio que escucharlo.
Me encantaría explorar la API, pero tiene baja prioridad, vuelve al cajón del futuro.
Sintonizando
Esta fue la parte sin audio, usando un receptor de DVB-T
Esta es una radio común:
Y esto el audio del canal 13:
La captura de pasar la banda magnética, no ha vuelto a dejar trazas pese a que puse la antena bien cerca.
La alarma del auto, las franjas:
Saquen sus teléfonos
Mientras me divertía un poco a costa de los asistentes, mostré un artefacto que había levantado de un volquete unos días antes cerca del trabajo. Es parte de una central inteligentísima de fines de los ochenta, HABIMAT HT-X.
http://www.aeby-tec.ch/htx/
Tiene un 68k y en el medio esa cosa roja y blanca es un eprom con ventanita montado en un adaptador, muy bueno, todo de alta calidad, las roscas de los tornillos en el plástico son de bronce, este equipo tiene como treinta años y se abrió con un soplo, mirá el destornillador que usé por que era lo que tenía a mano, normalmente busco algo con mango más grande para poder hacer fuerza.
Separada la pantalla, que es lo que más me interesa, en un primer examen no pude identificar el modelo.
Ver lo que hay en el chip o descifrar el protocolo de la pantalla son ambos muy buenos ejercicios, pero por el momento van al cajón del futuro, a menos que cambie de idea en un impulso repentino.
USB VGA
Vale poco y con este programita anda, con un delay de tres o cuatro segundos:
git clone git://git.osmocom.org/osmo-fl2k
sudo apt install libusb-1.0-0-dev mkdir build cd build/ cmake ../ -DINSTALL_UDEV_RULES=ON make -j 5 sudo make install sudo ldconfig sudo udevadm control -R sudo udevadm trigger sudo apt install sox pv
Hay que obtener el nombre de lo que se está escuchando:
pacmd list-sources | grep name | grep monitor name: <alsa_output.pci-0000_00_1f.3.analog-stereo.monitor>
Probablemente sacado de https://www.rtl-sdr.com/setting-up-and-testing-osmo-fl2k/
SDR
En general para SDR, que fué lo anterior, los componentes que usé no son muy útiles, si realmente fuera a estudiar, investigar o trabajar algo de SDR usaría algo como HackRF One. que es un poco carita, u$s 315 y mucho peor en ML, u$s 365 usado o u$s 750 nuevo.
Gracias a que la charla es para una hora, mis varios extravíos no previstos y la participación de la audiencia, esto quedó afuera, pero la idea es sencilla:
Si queremos que de un grupo de personas hagan falta al menos dos para destrabar algo que está con una clave, repartimos entre las personas puntos de una función. El sistema autenticador conoce la función pero no sabe a que altura está, la clave real es la intersección de esa función con el eje Y.
¿Querés más personas necesarias? Aumentás el grado.
Esta es la adaptación a Vivado/Nexys 4 DDR de los ejemplos del libro, escrito por Simon Monk que adquirí básicamente como introducción a Verilog tal que pudiera leer en el transporte público, pues necesito aún aprender Verilog para implementar Forzando Brutalmente MD5 Sin Computadoras en una Parallella y el ejemplo que quiero extender está en Verilog.
Como introducción a Verilog es muy liviana, termina y me digo ¿qué puedo hacer que no sea portar los ejemplos?
Son muy prácticos e interesantes, aparte de los típicos contadores y decodificadores de siete segmentos, tiene PWM, audio y vga, muy copado.
Comparando con [Free Range VHDL], se queda muy corto en los contenidos y la profundidad, pero le pasa por encima con la práctica, pues FR es agnóstico a la plataforma y no explica como sintetizar ni simular.
Los ejemplos son para tres placas que no tengo ni voy a tener, así
que me dí la tarea de adaptarlos y ejecutarlos en la que sí
tengo, una Nexys 4 DDR (Artix 7) y en lugar de
usar ISE, usar Vivado 2018.2.
En teoría lo único que tendría
que hacer es adaptar los clocks y las UCF, o sea, los archivitos que dicen a que
patitas se conectan lo que se haya programado. En la práctica, hay un poco más. Y al interactuar con hardware externo un poco de debug no viene mal.
Lo bueno de este proceso es que me sirvió para:
fijar el flujo de trabajo en Vivado.
comprender los constraints files.
asimilar Verilog, del cual no sé casi nada.
Si te interesa reproducirlo, quizás te convenga dejar de leer y tampoco mirar el código en github.
Apliqué esta práctica tambien a otros cursos online que iré publicando.
Comencé con el contador del capítulo 3. Me generó un reporte donde dice que el part name no es soportado y que los UCF (el archivo de constraints) no le sirve y que no entiende Schematics y como convertirlo a algo compatible usando ISE , que es la versión previa a Vivado.
Como me desvía mucho de mis intereses actuales, a saltear ejemplos hasta hallar Verilog.
Contador del capítulo 4
Según lo esperado, hay que adaptar el target, ajustar el XDC y darle para adelante.
[Place 30-574] Poor placement for routing between an IO pin and BUFG. If
this sub optimal condition is acceptable for this design, you may use
the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this
message to a WARNING. However, the use of this override is highly
discouraged. These examples can be used directly in the .xdc file to
override this clock rule. < set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets BTNC_IBUF] >
BTNC_IBUF_inst (IBUF.O) is locked to IOB_X0Y82 and BTNC_IBUF_BUFG_inst (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y0
Parece que no le gusta que le pongan en el reloj cosas que no son del reloj. Seguí las instrucciones (el set property...) y todo ok.
Aprender a manejarme con todo lo de los clocks, agregado a la deuda, o hacer más ancho el contador y fué más ancho, pero aún con
output reg [15:0] Q
y en el XDC:
descomentar y renombrar Q[4] a Q[7],
el problema es que con el reloj a 100 MHz, aun con un contador de 16 bits (65536), la frecuencia más baja es 1525 Hz, obviamente inapreciable sin instrumental. Luego entendí que el "Clock" estaba provisto por apretar un botoncito.
Siete segmentos del capítulo 5
Hay un prescaler que no ajusté al número apropiado tal que haga refresco a 1kHz, deber estar haciéndolo a algo bastante más alto, en otra oportunidad diagnosticaré y corregiré.
Como mi placa tiene 8 digitos contra los 3 o 4 de las del libro, para mejorar la estética, habilité todos los dígitos propagando las centenas a la izquierda, no tenía ganas de apretar mil veces el botoncito ni modificar mucho el ejemplo tal que otro botón sumara de a diez y otro de a cien. Estuve varias horas dando vueltas por que no funcionaba hasta que me di cuenta que unos wires no estaban bien por el ancho y fundamentalmente por unos warnings que decían que habían patitas sin usar.
Cuenta regresiva del capítulo 6
Como usa componentes ya modificados en el ejemplo del contador, primero hice la adaptación tal como viene y luego le apliqué el cambio, que es usar los ocho dígitos.
No pude postergar más el asunto de la frecuencia, ya que el próximo ejemplo usa este para interactuar con un componente externo.
Adelantándome un poco pero sin hacer trampa, tras adaptar el PWM a mi placa, para el servo hay que meter un pulso así:
Stefan Tauner [CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0)]
Y en el ejemplo hay cualquier cosa, ya que es de PWM en general, más considerando la disparidad de clocks
de las placas involucradas:
Elbert2 12 MHz
Papillo One 32 MHz
Mojo 50 MHz
Nexys4 DDR 100 MHz
Como siempre, te recomiendo te detengas, hagas tus pruebas y regreses.
Tablita útil para los que no estamos todo el día con esto
Hay tres caminos, uno es pensar y calcular, el otro medir y el otro mirar fijo los ejemplos y sus diferencias, tambien llamado ingeniería inversa.
Voy a tomar los tres caminos y los voy a mezclar.
Pensar y calcular
Primero hay que comprender el código:
reg [7:0] duty = 0; reg [6:0] prescaler = 0; // CLK freq / 128 / 256 = 1.5 always @(posedge CLK) begin prescaler <= prescaler + 1; // esto indica el ancho del pulso if (s_up) duty <= duty + 5; if (s_dn) duty <= duty - 5; end
pwm p(.pwm_clk (prescaler[6]), .duty (duty),...);
y el módulo pwm
reg [7:0] count = 0;
always @(posedge pwm_clk)
; // pwm_clk <= prescaler begin
count <= count + 1;
PWM_PIN <= (count < duty);
end
No lo termino de entender, así que a...
Medir
Para medir repliqué la salida del PWM del led a uno pin de un pmod y tambien el pwm_clk y de ahí al osciloscopio.
Volver a pensar y calcular
La frecuencia es 391 kHz, que es 100MHz dividido 256, si lo divido otra vez, tengo 1.527 kHz, con lo cual llego al ejemplo.
Para avanzar hacia el servo, lo que tengo no sirve pues no estoy respetando los límites y lo modifico sin mirar el siguiente ejemplo o paso al siguiente ejemplo... ok, versiono el ejemplo con valores equivalentes e intento hacer el servo y si fallo me copio.
Pensé, primero tengo que lograr un período de 20 ms, tras algunas pruebas, quedé cerca y las aproveché para aprender como parametrizar un módulo, muy útil y sencillo:
En la interfaz del módulo se define un parameter con un valor default,
y aunque el libro menciona el parameter, no explica como reemplazarlo en synthesis time.
Además puse el valor inicial de pulse_len en 1000 en lugar de 500 y está ok, salvo la falta de límites.
Si mirás bien los kdiff3s anteriores, vas a ver que cada placa no tiene parámetros distintos si no código distinto, mmh, me parece que me quedo con mi implementación, tengo dudas de si pasarle el prescaler al módulo o conservarlo afuera.
Abajo a la izquierda el servo se mueve mientras arriba al centro cambia el ancho del pulso.
Capítulo 8 WAV Player
A diferencia del ejemplo de la Nexys4DDR, el libro no usa la memoria RAM sino la memoria de la FPGA, que ahorita no recuerdo el nombre, pero ya aparecerá... block memory. Tampoco usa el audio output sino un mero GPIO.
Lo adapté tal como está, el objetivo de esta experiencia es sólo hacerlo andar, no entrar en cambios drásticos.
Usé el ejemplo de Mojo, que es la más power.
La lectura en "memoria" del audio le agrega a la síntesis cinco minutos.
NET "CLK" LOC = P89; #32MHz # Outputs NET "HS" LOC = P83; NET "VS" LOC = P85; NET "RED[0]" LOC = P61; NET "RED[1]" LOC = P58; NET "RED[2]" LOC = P54; NET "GREEN[0]" LOC = P68; NET "GREEN[1]" LOC = P66; NET "GREEN[2]" LOC = P63; NET "BLUE[0]" LOC = P78; NET "BLUE[1]" LOC = P71;
Fiel a lo que había aprendido con respecto a los nombres, adapté el XDC. Obviamente sintetizó, implementó y generó de una pero está el asunto del reloj, recuerdo haber escuchado hace muchos años a monitores VGA sometidos a resoluciones extremas y luego romperse. Tengo dos caminos:
Conectar a un monitor descartable, difícil, el que tengo no sé que tan mal anda y sería una pena romperlo.
Desde una placa de video generar la misma resolucion, medirlo y comparar.
Lo segundo sin ninguna duda es más educativo, pero tambien es más trabajo, voy a reventar primero el monitor que ya está dañado.
De un modo u otro es útil releer en el libro lo que dice de como ajustar los timings según el clock de cada placa, lo que me lleva al tercer camino:
Comprender los timings y medir el HS y VS a ver si son apropiados sin conectar el monitor.
Para ello dupliqué las señales en el PMOD, tengo un VS de 230 Hz y HS de 120KHz:
En amarillo el HS 119 kHz antes del ajuste
En cyan VS 232 Hz antes del ajuste
Empíricamente dividí el clock por cuatro a ver si me queda en 57.5 e
intuyo que HS debería ser eso por 500, un poco menos de 30 kHz,
perfecto!
En amarillo HS 30 kHz
En cyan VS 57.8 Hz
Funcionando. Si, son alfileres con cabeza los que uso para las puntas.
Lo que sigue es cuesta abajo... pero en algún momento debería sentarme a hacer bien las cuentas y usar otras resoluciones correctamente, quedará para otra entrada.
Capítulo 9 VGA memoria
Este, al igual que el del wav levanta la info de block memory, pero en lugar de tirarla al audio, va a VGA
El módulo vga.v es el mismo que el anterior, vga_mem.v tiene agregado los probes y declaré explícitamente un wire blank que no estaba.
Ufa, es una bandera inglesa, me guardo la foto.
Capítulo 9 VGA juego
Nada, más de lo mismo, sólo hay que conectar los pines y anda, más o menos, menos que más. Habría que toquetear los tiempos y centrar bien la pantalla, va a la deuda.
Resumiendo
El procedimiento para migrar los ejemplos del libro es:
Crear un nuevo proyecto
Elegir board/device
Copiar los verilogs y agregarlos al proyecto
Agregar XDC y adaptarlo mirando fijo la interfaz del top module y los .ucf
Pines
Reloj
Pelearse con lo que haya que pelear
la adaptación al clock
Run Synthesis
Volver a pelearse con lo que haya que pelear
Run Implementation
Volver a pelearse con lo que haya que pelear
Generate Bitstream
Conectar los accesorios de hardware necesarios
Hardware Manager
Auto Connect
Program Device
Es horrible el tiempo que tarda, no bien pueda voy a aprender a distribuir la carga vía red.
Estos son algunos de los temas que no resolví para no salirme del rumbo, que era sólo portar los ejemplos, en algún momento saldaré mi deuda y se reflejará en futuras entradas.
Usar distintos clockings.
Comprender y usar el audio jack.
Calibrar las medidas de VGA.
Comprender los timings de VGA para usar otras resoluciones.
Adaptación eléctrica del servo, no termina de girar los 90°.
Esta entrada es una actualización y extensión de algo que escribí hace rato. No quiero repetir lo que ya había dicho, pero como es bastante largo, haré un resumen. En el artículo original entro en mucho más detalle y agrego unas interminables reflexiones.
El tema es que en las fórmulas que suelo ver hay dimensiones como:
Impacto de Confidencialidad, Integridad y Disponibilidad (todas).
Facilidad/complejidad/costo/reproducibilidad del ataque (DREAD)
Interacción con usuarios (CVSS v3)
En particular DREAD contempla "usuarios afectados", pero en términos cuantitativos. La primera dimensión que me resultaba interesante es entonces "tipo de usuario afectado", que apunta a la calidad. No en términos de cambio de permisos, escalamiento, eso ya lo tiene de algún modo CVSS v3 con "Scope". Me refiero a que no es lo mismo comprometer a un cliente, un empleado raso, un adminstrador de sistemas, un director. Dependiendo del objetivo y el tipo de persona afectado puede producirse fuga de información, transferencias de dinero, acceso a planes estratégico.
De algún modo está en "environmental" de CVSS v3, pero no produce un texto acompañante más expresivo tipo:
"La vulnerabilidad permite tomar el control de los nodos bajo Plan 9, que es lo que usan los administradores de sistemas".
La segunda tiene que ver con la responsabilidad: es algo mío o de un tercero. ¿Es una mala configuración mía o estoy usando una librería o componente fallado? ¿Es en mi sistema o en el sistema del cliente? En el caso de XSS, quizás el navegador es tan viejo que no puedo protegerlo completamente.
Otro ejemplo es uso repetido de credenciales por parte de los usuarios en distintos sistemas. Por más que yo le pida una credencial fuerte y limite los intentos, no tengo casi control, salvo pedir regeneración periódica, que si mal no interpreto el NIST no está del todo de acuerdo. Fijate que dice:
"Do not require that memorized secrets be changed arbitrarily (e.g.,
periodically) unless there is a user request or evidence of
authenticator compromise."
La nueva
La tercera es "quién reporta" tiene que ver el tratamiento hacia quien ha efectuado y comunicado el hallazgo.
Si descubro la vulnerabilidad yo mismo, no pasa nada, no es público que yo tenga esa vulnerabilidad, no tengo que dar una respuesta por fuera del circuito o procedimiento de resolución.
Si esta vulnerabilidad figura en un boletín o en CVSS por que se trata de un componente ajeno, si es público que la tengo, pues al atacante le alcanza con saber que tengo el componente.
Si es por resultado de un Pentest y es propia, estamos entre pares. Seguimos dentro del contrato. Me tengo que ocupar sin duda pues si el Pentest la encontró en un sistema productivo, un atacante probablemente tambien lo haga.
Queda el caso de que un usuario o investigador independiente reporte, que es muy distinto y marca el máximo valor de esta dimensión, que puede tener muy importantes implicancias de impacto de imagen, daño reputacional.
Con un poco de suerte, el investigador independiente se puede manejar con Responsible Disclosure: tenés este problema, confirmalo y decime cuando lo vas a arreglar para darte tiempo antes de hacerlo público.
El usuario simplemente avisa y si no se le da respuesta quizás insista, quizás se olvide o quizás difunda en una red social "avisé y no me dieron respuesta o no lo arreglaron" y eso produce daño reputacional, aunque la vulnerabilidad haya sido un falso positivo.
Estas dimensiones o la visión que propongo quizás sea un poco menos "científicas" de algún modo, pues son menos cuantificable. Pero me parece que es un agregado más práctico, más de oficio. De todos modos no es un reemplazo, es una extensión al análisis.
Como esta es la... ya perdí la cuenta de las veces que me ha ocurrido, ha llegado el momento de compartirlo.
Tenía una duda de verilog que tenía que ver con que se estaba usando un vector como clock de un módulo y no lograba comprenderlo bien. Entonces me preparé como otras tantas veces para preguntar en el foro de embebidos:
Mi disciplina en estos casos y lo que quiero compartir es que cada vez que voy a hacer una pregunta, intento "hacer bien los deberes", esto es, evitar que alguien me conteste "hiciste esta obviedad?" o "mandá la salida de tal operación".
Para eso escribo la pregunta y voy completando todo lo que se me ocurre que alguien me reclamaría, lo cual me obliga a ir explorando muchas ramificaciones, algunas útiles y otras no tanto, de un modo u otro aprendiendo.
Asi que puse la pregunta, copié el código, quité de éste todo lo que estorbaba y esta es la primer versión del mail que no mandé, te propongo que intentés darte cuenta, si sabés algo de Verilog, claro, cuál es la respuesta:
Hola
Mirando un ejemplo que tengo de un PWM he hallado que aparentemente un posedge de un vector corresponde a su overflow o algo así, ¿es así?
Este es el código en cuestión, quitándole todo lo que me pareció superfluo.
always @(posedge CLK) begin prescaler <= prescaler + 1;
...
end
El otro módulo
module pwm(
input pwm_clk,
...
);
always @(posedge pwm_clk)
.....
Gracias y saludos
¿Listo?
Busqué "verilog posedge of a vector" y me llevó una conversación donde dice que:
A posedge on (|vec) ? Actually the standard says that [pos|neg]edge tests only the least significant bit of the vector.
Algo encaminado estoy, pero es lo contrario a los resultados, si fuera el LSB, la frecuencia sería la mitad del clock, no? ¿50 MHz en lugar de 391kHz?
Chiquito dice que la frecuencia es 391kHz
Todavía estoy intentando entender exactamente como funciona, eso lo relataré en un próximo post, pero mientras, mantengámonos en la pregunta de la relación entre posedge y un vector.
Para aclarar las cosas tanto para mí como para quien leyera, marqué con negrita el vector en los dos módulos y ahí hallé la respuesta que marco en rojo:
Se está usando el MSB del prescaler de 7 bits, encontré y entendí la respuesta a mi pregunta.
always @(posedge CLK) begin prescaler <= prescaler + 1;
....
end
------------------------
module pwm(
input pwm_clk,
...
);
always @(posedge pwm_clk)
.....
<Actualización 2022-08-04>
Al releer, me doy cuenta que nunca dije qué pasó. Quien diseño el código original lo hizo para un clock de 50Mhz, no se le pasó por la cabeza que iba a ser ejecutado con 100Mhz, el doble, necesita un bit más.
Respecto al "eso lo relataré en un próximo post", la verdad es que ya ni me acuerdo de este tema, quizás ya lo entendí y lo olvidé, lo siento.
</actualización>
Aunque estas son cosas muy personales, recomiendo este método, pues
muchas veces en el foro hay preguntas tipo "no puedo leer el
acelerómetro con la sAPI" que hacen que quien quiera contestar tenga que
empezar a escarbar para poder responder.
Está claro que quien pregunta
puede estar muy perdido, pero intentar esto, si no llevarte a la solución, puede mejorar bastante la conversación.
En alguna conversación Alejandro me dijo "Gracias Carlos, siempre me contestás a mis post, te debo tener harto". Para nada, es la misma actitud, ponerse en el lugar del otro pero para aprender.
El código completo está en github y
corresponde a la adaptación que estoy haciendo a una nexys4ddr de los ejemplos de un
libro cuyo código está en github tambien.