Sobrentendidos. 11 de febrero, Día de la Mujer y la Niña en la Ciencia

Hace algunos años, yo no creía que días como hoy fuesen necesarios: días en los que se reivindica a tantas figuras históricas no solo como científicas, sino también en tanto que mujeres. Solía defender, con el ceño fruncido y la voz herida de orgullo que «yo» no necesitaba discriminación positiva, que los méritos debían brillar por sí mismos, que los genitales de cada cual son cosa suya, que el tiempo pone las cosas en su sitio…

Es lo que tienen los instintos morales: que hunden sus raíces hasta el estómago y, solo con tiempo, información y suficiente esfuerzo, somos capaces de cambiarlos. ¿Os habéis preguntado alguna vez por qué cada vez que sale la palabra «feminismo» se monta un flame en Internet? Bien, este es el motivo. Todo el mundo conoce mujeres y todo el mundo «siente» (muy fuerte, a la altura del ombligo) cuál debe ser la actitud correcta hacia ellas; a saber, la suya propia. Rara vez 140 caracteres son suficientes para darse cuenta de que, además de sentimientos y un conocimiento parcial de ciertas mujeres, conviene tener a mano estudios e información objetiva que aclare las bases del problema. Muchos ni siquiera piensan que los datos deban ocupar un lugar en el debate.

Sin embargo, no hay nada como pillarte infraganti, víctima de tus propios sesgos, para empezar a dudar de esas intuiciones y girar la cabeza hacia los datos. En mi caso, la anécdota reveladora (o así la recuerdo yo: una especie de bisagra) vino de la mano de mi nueva carrera.

Cuando empecé el grado en Física, dio la casualidad de que tres de mis compañeros de trabajo habían empezado a estudiar por la UNED también. Ellos eran ingenieros y se habían matriculado en matemáticas. La rutina de estudios y exámenes daba para bastantes anécdotas y fomentaba el sentimiento de compañerismo, pero también… cierto grado de competición: llegaron los primeros exámenes y se descubrió que mis resultados en física eran muy buenos. Más concretamente, mis resultados en física eran mejores que los suyos en matemáticas. No en vano, soy una gran empollona, tan empollona que en 2° de carrera me dieron el premio a empollona del año de la Facultad de Ciencias de la UNED. Pero claro, ellos eran ingenieros, eran tres y, sí, eran hombres, así que algo debía de estar fallando.

La broma cuajó pronto. «Es que física es una carrera muy fácil», mucho más fácil que matemáticas, esto es. Pero lo malo no fue la broma. A fin de cuentas, era solo un comentario que nacía del juego, de la competencia sana entre pares, era eso, solo una broma. Lo malo fue el sobrentendido. Pronto, todos pensábamos que matemáticas debía de ser mucho más difícil que mis estudios. Pronto, yo misma pensaba que física no podía ser una carrera tan complicada.

Tardé todavía un año en darme cuenta de mi propio sobrentendido y algo más en asociarlo a cuestiones de género, a la imagen que yo misma tenía de “ellos” (ingenieros varones, luego más brillantes que yo) y de mi capacidad para las materias técnicas, esa capacidad que nunca hubiese puesto en duda de manera consciente. Descubrir ese sesgo misógino en mis propios ojos, como un filtro inconsciente y dirigido hacia mi propio desempeño, me hizo darme cuenta de cómo se lo aplicaba, sin quererlo, a otras mujeres. Me obligó a revisarme y a darme cuenta de que, sin datos, sin esfuerzo, sin activismo y sin días como hoy, el tiempo por sí solo nunca pondrá las cosas en su sitio.

Anatomía de una infección por malware

En informática, como en biología, los mejores virus son los mejor adaptados, son aquellos que se aprovechan de su huésped sin que este se percate… hasta que ya es demasiado tarde. También como en biología, no siempre sucede así.

—Iñaki, ¿te pillo por aquí?
—Sí, dime.
—Estoy acojonado. Algo pasa con WordPress. He llamado al hosting porque pensaba que sería problema del mismo, pero lo último que me han dicho es que el archivo “index.php” es 20 veces más grande de lo normal. ¿Es grave?

Inmediatamente le insto a descargar el fichero y a enviármelo, y a machacarlo con uno legítimo de WordPress. En una situación así, no hay tiempo que perder hasta saber a qué nos enfrentamos. Mientras tanto, conviene recabar toda la información posible, buscar más archivos modificados, comprobar la base de datos en busca de usuarios ilegítimos…

El “index.php” de una instalación de WordPress es minúsculo, de menos de 0.5 kB; por tanto 20 veces más, poco más de 8 kB, sigue siendo notablemente pequeño. El archivo que recibo es un “index.php” legítimo de WordPress con una línea (muy larga) añadida al comienzo, y tiene esta pinta:

Una larga cadena de caracteres sin ningún sentido y unas pocas operaciones debajo con menos sentido todavía. Por ahora. Es lo que se llama ofuscación de código, una técnica que tiene dos objetivos principales: por un lado, encubrir el propósito del código, o al menos dificultar su comprensión; por otro lado, dificultar su identificación. Efectivamente, una búsqueda en Google no arroja ningún resultado. Toca, pues, seguir los pasos uno por uno para descifrar el puzle.

El funcionamiento es simple, pero efectivo. El código se asemeja a una matrioska: de un conjunto de caracteres aparentemente aleatorios, se extraen unos cuantos en un orden determinado formando funciones que actúan sobre otras cadenas, que obtienen nuevos chorizos sin sentido y nuevas funciones ilegibles. En el caso que nos ocupa, la ofuscación es particularmente compleja, y me lleva hasta ocho etapas distintas hasta que logro llegar a un fragmento de código que deja de interaccionar consigo mismo y ensambla el verdadero propósito del malware. El corazón del virus tiene nombre: day212().

Esta vez, sí: una búsqueda en Google revela que existe un repositorio donde otros autores realizaron el mismo proceso que yo con otra muestra del virus. Recogen el fragmento original, el código final y detallan el proceso. ¿La fecha? Hace once meses. Lo que podemos deducir del análisis del malware es que, una vez instalado en un servidor legítimo y de una manera bastante sofisticada, inyecta código que obtiene de servidores rusos, con dominios alojados en China, en la web que recibe el usuario final. Pero esto solo es la punta del iceberg.

EITest, el negocio de la distribución de malware

Hace más de dos años, Malwarebytes publicaba una investigación en la que exponía una campaña de distribución de malware a la que apodaron EITest (por uno de los nombres de las variables del código involucrado). Desde entonces, se ha mantenido activa sin que ninguna autoridad competente haya tomado el control sobre los servidores rusos que son centrales a dicha operación. Podemos encontrar nuevos reportes de investigadores de marzo y octubre del pasado año, y ahora nos encontramos ante un nuevo repunte en sus actividades.

EITest se puede definir como una cadena de infección. Se centra en las fases de entrega, explotación de vulnerabilidades e instalación de software malicioso; es decir, su beneficio viene principalmente de la distribución de malware para otros criminales. Todo apunta a que es un negocio rentable y bien engrasado, por su evolución y su perdurabilidad, ya que sus orígenes podrían remontarse a 2011. La muestra de código con la que abríamos este artículo no es otra cosa que la puerta de entrada a esta red de distribución.

Anatomía de una infección

Todo empieza con un servidor web legítimo comprometido por alguna razón. Las posibles vías son múltiples: una instalación desactualizada, un plugin vulnerable, un servidor mal configurado… Una de las principales vías de infección conocidas fue, durante largo tiempo, una vulnerabilidad en MailPoet, un popular plugin para WordPress. No son infrecuentes tampoco los ataques distribuidos contra el panel de control de WordPress y otros gestores de contenidos (este mes precisamente ha habido un incremento que hemos notado en este blog; por eso es tan importante escoger una contraseña robusta y limitar los intentos de acceso fallidos). De una manera u otra, el código que encabeza la entrada o similar acaba en la cabecera de uno o más archivos —se han llegado a reportar cientos en un mismo servidor.

La infección está diseñada para parasitar sin perturbar demasiado al huésped y tiene unos targets muy determinados. Cuando un usuario apunta con su navegador al sitio en cuestión, está despertando a la bestia sin percatarse. El código entra en funcionamiento no sin antes comprobar cuidadosamente una serie de parámetros para asegurarse de que se encuentra ante un usuario legítimo con unas características determinadas. Pasará, por tanto, desapercibido ante bots como el de Google o Microsoft para evitar que el sitio sea identificado como portador de malware. Se ha reportado que EITest busca equipos Windows con Chrome o Internet Explorer como navegador, pero en la muestra analizada he podido comprobar que también buscan navegadores Firefox y sistemas Android.

Una vez confirmado el target, el código contacta con un tercero que será el que devuelva un regalito hecho a la medida del navegador. Parece ser que este servidor malicioso realiza más comprobaciones para asegurar que el contenido va directo a una web infectada, y además evita una misma IP durante un periodo de 24 horas [1]. Como resultado, el usuario carga la web en cuestión… y algo más. Y, de repente…

Chrome no encuentra la fuente

Cuando el cliente es Google Chrome, el usuario verá un pop-up similar al siguiente:

Da la impresión de que el navegador nos insta a descargar un pack de fuentes necesario para visualizar la página actual, pero evidentemente es un truco. De hecho, un navegador jamás necesita descargar fuentes: si no encuentra una, simplemente usa una por defecto. Pulsar ese botón desencadena otra ristra de comprobaciones, de que Chrome es en realidad Chrome, y una petición a otro servidor infectado que inicia la descarga de un archivo: “Chrome_Font.exe” o “Font_Update.exe”.

La manera en que ese archivo es servido, de nuevo para asegurarse de que la petición viene de una víctima legítima, y cómo está protegido para evitar la detección por antivirus son dignos de mención (para los curiosos, todos los detalles se encuentran en [1]). Pero sobra decir que la ejecución del archivo consuma la infección. En el caso particular de Chrome, lo que se distribuye es un virus que se dedica a lanzar múltiples instancias invisibles de Internet Explorer y a navegar autónomamente, todo apunta que para generar dinero a base de clicks fraudulentos en publicidad. Los investigadores han sido capaces de identificar 7000 sitios web infectados y 30000 IPs únicas de usuarios que han descargado el malware diseñado para Chrome [1], principalmente de Estados Unidos, durante las últimas semanas.

¿E Internet Explorer?

Peor lo tienen los usuarios de Internet Explorer —aunque todo apunta a que un Windows 10 bien actualizado mitiga las probabilidades de infección, ya que el principal sistema infectado es Windows 7—. EITest distribuye una amplia variedad de malware sin intervención del usuario utilizando como vía de entrada este navegador. En concreto, la estrategia consiste en inyectar código para descargar un ejecutable de Adobe Flash Player capaz de explotar dos vulnerabilidades diferentes. La única acción necesaria por parte del usuario es visitar la web infectada.

En ese momento, y si la versión de Flash Player es vulnerable, se inyecta un script capaz de “llamar a casa” y descargar y ejecutar cualquier tipo de malware que se provea desde los servidores de EITest: desde ransomware hasta programas capaces de convertir un PC en parte de una red de bots sin levantar las sospechas de su dueño.

El patrón es claro: de día trabajan y de noche descansan cuando el dueño apaga su computadora, ya que las víctimas principales son ordenadores personales, y se aprecia cómo el número de bots ha crecido de forma sostenida durante estas últimas semanas. Para un análisis pormenorizado, por si no me he reiterado lo suficiente todavía, lean [1].

[1] Exposing EITest campaign, Malware Traffic Analysis.

La luz: una metáfora

Lean Fotones y fotoncitos, de Joaquín Sevilla. Al principio se pone un poco técnico hablando de la dualidad onda-partícula:

La disquisición que llevó a siglos de peleas entre científicos sobre si la luz eran ondas o partículas quedó pues zanjada en un extraño empate.

Pero enseguida se le pasa. Aguanten hasta que llega la metáfora:

Una metáfora que puede ayudar a entenderlo sería suponer el haz de radiación como un chorro de partículas macroscópicas. En el extremo de los rayos gamma, los de más energía, esas partículas serían balas de rifle; los rayos X, balas de pistola; el ultravioleta lejano, piedras; el violeta, pelotas de goma; el rojo, pelotas de ping pong; y hacia abajo, cosas más sutiles, básicamente bolas de algodón.

Un balazo o una pedrada son biológicamente agresivos, potencialmente mortales. Lo son desde el primer impacto, no hay dosis inocua. En cambio con pelotas de ping pong es muy difícil matar a alguien. No es imposible, te puedes atragantar, te pueden asfixiar enterrado en una piscina de pelotas de ping pong. Pero hacen falta condiciones muy extremas y muchas pelotas (mucha intensidad) o situaciones muy exóticas.

Extensions for ‘simmer’

A new version of the Discrete-Event Simulator for R was released a few days ago on CRAN. The most interesting new feature is the implementation of the subsetting operators [ and [[ for trajectory objects. Basically, think about trajectories as lists of activities and these operators will do (almost) everything you expect.

library(simmer)

t0 <- trajectory() %>%
  seize("resource", 1) %>%
  timeout(function() rexp(1, 2)) %>%
  release("resource", 2)

t0
## trajectory: anonymous, 3 activities
## { Activity: Seize        | resource: resource | amount: 1 }
## { Activity: Timeout      | delay: 0x55ffd06c5858 }
## { Activity: Release      | resource: resource | amount: 2 }
t0[c(3, 1)]
## trajectory: anonymous, 2 activities
## { Activity: Release      | resource: resource | amount: 2 }
## { Activity: Seize        | resource: resource | amount: 1 }

After the last maintenance update (v3.5.1), which fixed several bugs and included a new interesting vignette with SimPy examples translated to ‘simmer’, this v3.6.0 comes hand in hand with the first ‘simmer’ extension released on CRAN: simmer.plot.

The primary purpose of ‘simmer.plot’ is to detach plotting capabilities from the core package, to systematise and enhance them. If you were using any of the old plot_*() functions, you will get a deprecation warning pointing to the S3 method simmer.plot::plot.simmer. This vignette will help you make the transition.

‘simmer.plot’ also implements a new plot S3 method for trajectories. It produces a diagram of a given trajectory object, which is very helpful for debugging and checking that everything conforms your simulation model. Let us consider, for instance, the following pretty complex trajectory:

t0 <- trajectory() %>%
  seize("res0", 1) %>%
  branch(function() 1, c(TRUE, FALSE),
         trajectory() %>%
           clone(2,
                 trajectory() %>%
                   seize("res1", 1) %>%
                   timeout(1) %>%
                   release("res1", 1),
                 trajectory() %>%
                   trap("signal",
                        handler=trajectory() %>%
                          timeout(1)) %>%
                   timeout(1)),
         trajectory() %>%
           set_attribute("dummy", 1) %>%
           seize("res2", function() 1) %>%
           timeout(function() rnorm(1, 20)) %>%
           release("res2", function() 1) %>%
           release("res0", 1) %>%
           rollback(11)) %>%
  synchronize() %>%
  rollback(2) %>%
  release("res0", 1)

We must ensure that:

  • Resources are seized and released as we expect.
  • Branches end (or continue) where we expect.
  • Rollbacks point back to the activity we expect.

Things are indeed much easier if you can just inspect it visually:

library(simmer.plot)

plot(t0)

Note that different resources are mapped to a qualitative color scale, so that you can quickly glance whether you placed the appropriate seizes/releases for each resource.

Other interesting ‘simmer’ extensions are already on our roadmap. Particularly, Bart has been simmering a new package (still under development) called simmer.optim, which brings parameter optimisation to ‘simmer’. While ‘simmer’, as is, can help you answer a question like the following:

If we have x amount of resources of type A, what will the average waiting time in the process be?

‘simmer.optim’ is targeted to a reformulation like this:

What amount x of resources of type A minimises the waiting time, while still maintaining a utilisation level of \rho_A?

We would be very grateful if someone with experience on DES optimisation could try it out and give us some feedback. Simply install it from GitHub using ‘devtools’

devtools::install_github("r-simmer/simmer.optim")

and start from the README, which demonstrates the current functionalities.