Fixing routing errors from alternativaslibres faster

categoría: OpenStreetMap | tags: , , , , | sin comentarios »

alternativaslibres.org provides several .zip files with routing errors from OpenStreetMap database. This .zip files contains several .txt files with this format:

2017/01/05 03:32:50 (RouteNode): 55114001.o5m: Roundabout (http://www.openstreetmap.org/browse/way/30983372) is connected to more than one road at http://www.openstreetmap.org/?mlat=39.475536&mlon=-6.399011&zoom=17 2017/01/05 03:32:50 (RouteNode): 55114001.o5m: Roundabout (http://www.openstreetmap.org/browse/way/311363264) is connected to more than one road at http://www.openstreetmap.org/?mlat=39.475971&mlon=-6.395029&zoom=17 2017/01/05 03:33:57 (RouteNode): 55114006.o5m: Roundabout (http://www.openstreetmap.org/browse/way/174438373) is connected to more than one road at http://www.openstreetmap.org/?mlat=38.885061&mlon=-4.352789&zoom=17 2017/01/05 03:35:07 (StyledConverter): 55114015.o5m: Roundabout 463667389 direction is wrong – reversing it (see http://www.openstreetmap.org/?mlat=40.487723&mlon=-3.181809&zoom=17) 2017/01/05 03:35:07 (StyledConverter): 55114015.o5m: Roundabout 463453323 direction is wrong – reversing it (see http://www.openstreetmap.org/?mlat=40.534629&mlon=-3.299410&zoom=17)

To fix one fo this errors, you should:

  1. Copy the way ID “30983372”.
  2. Paste it in JOSM under “File->Download Object”.
  3. Fix the error.
  4. Upload the changeset.
  5. Repeat from step 1.

This workflow is slow, so I tried to improve it with a little Bash “piping” under Linux:

start_line=1; file="Roundabouts_ESP.txt"; ids=$(cat $file | sed -n 's/.*way\/\([0-9]\+\).*/w\1/p' | sort -n | uniq | tail -n +$start_line | head -n 20 | tr '\n' ','); curl "http://localhost:8111/load_object?new_layer=false&objects=${ids}"

 

To use this new and faster workflow you need to open JOSM and enable remote control, then:

  1. Set “file” variable with the one you want to fix.
  2. Run the command. JOSM will load the ways to fix.
  3. Fix one error.
  4. Upload the changeset.
  5. Repeat from step 3 until all errors are corrected.
  6. Repeat from step 2, changing variable “start_line=X” from X to X+20.

Crackear captchas sencillos

categoría: Linux, Seguridad informática | tags: , , , , | 11 comentarios »

Los captchas (Completely Automated Public Turing test to tell Computers and Humans Apart) están ampliamente extendidos hoy en día. Cualquier aplicación web con cierto nivel de seguridad que permita entrada de datos a usuarios no autentificados debería contar con un captcha para dificultar ataques de fuerza bruta. La mayoría de los captchas suelen ser visuales, en ellos se ha de escribir en un campo de texto los caracteres mostrados en una imagen. Pero el hecho de tener un captcha en una aplicación no significa que automáticamente estemos a salvo de ataques de fuerza bruta.

Un captcha visual débil resulta sencillo de romper gracias a programas de reconocimiento óptico de caracteres (OCR). Un captcha visual que resulte difícil de crackear debe contar con diferentes fuentes tipográficas, tamaños, colores, caracteres distorsionados y ruido en el fondo.

Ejemplo de un buen captcha

Ejemplo de un buen captcha

En esta entrada me gustaría mostrar lo sencillo que resulta el crackeo de un captcha débil. Para ello voy a exponer un caso real, omitiendo la dirección de la página web en cuestión. Se trata de una página que permite a sus usuarios hacer pública cierta información en forma de código. Este proceso se realiza anonimamente y sin ningún tipo de autentificación,  tan sólo cuenta con el siguiente captcha:

captcha debil que romperemos

captcha debil que romperemos

A simple vista se aprecia que el captcha no aporta gran seguridad gracias a sus caracteres perfectamente definidos.

Ejemplo práctico de crackeo de captcha débil

Para crackearlo usaremos el programa GOCR, el cual es open souce y en Linux se puede instalar desde las fuentes habituales.

Este programa requiere un “entrenamiento” previo para reconocer los caracteres, por lo que será lo que hemos de hacer en primer lugar:

mkdir ocrdb
gocr -d 2 -p ./ocrdb/ -m 256 -m 130 captcha.png

La ruta ./ocrdb/ será en dónde se guardarán los datos que genere gocr a partir de su “entrenamiento”, este directorio lo tenemos que crear manualmente. ‘captcha.png’ es el captcha que crackearemos. Al ejecutar este comando, nos encontraremos con lo siguiente:

Entrenamiento de gocr

Entrenamiento de gocr

En esta captura vemos como gocr nos pregunta por la primera letra, en este caso una “V”. La letra por la que nos pregunte en cada momento estará pintada con corchetes ‘#’, las demás con ‘O’. Al introducir la letra “V” continuará con las siguientes letras del captcha. Este proceso lo tendremos que repetir cuantas más veces mejor, hasta que gocr sea capaz de entender el captcha sin nuestra ayuda. Por lo que tendremos que ejecutar el comando bastantes veces, para agilizar el proceso podemos usar el siguiente script:

#!/bin/bash
while [ 1 ]; do
        wget -O captcha.png http:/servidor-ejemplo.com/captcha_gen.php ;
        gocr -d 2 -p ./ocrdb/ -m 256 -m 130 captcha.png ;
done

Cuando gocr sea capaz de descifrar la mayoría de captchas por si mismo pulsamos ctrl+c para detener el script. Lo siguiente sería poner a prueba el programa:

gocr -p ./ocrdb/ -m 256 -m 2 captcha.png

Este sería el método general para usar gocr, pero en el ejemplo que he propuesto es poco útil. Vamos a crear un script que se encargue del crackeo del captcha y del envío de nuestros códigos a la página con wget:

#!/bin/bash
# este será el código que se le enviará a la web
miCodigo='XPEYWZA-002'

# urls de la página. La general y la que recibe los datos por POST
url='http:/servidor-ejemplo.com'
postUrl='http:/servidor-ejemplo.com/add-code.php'

# rutas temporales de trabajo
dirActual=`pwd`
dirTrabajo='/tmp/captcha'

# si existe el directorio temporal lo borramos
if [ -d "$dirTrabajo" ]; then
        rm -Rf $dirTrabajo
fi
mkdir $dirTrabajo
cd $dirTrabajo

# hacemos una primera petición a la web guardando cookies
wget --save-cookies $dirTrabajo/cookies.txt --keep-session-cookies \
        -r $url

# renombrarmos el captcha, realizamos el OCR y eliminamos los espacios en blanco
mv captcha.php captcha.png
captchaResuelto=`gocr -p $dirActual/ocrdb/ -m 256 -m 2 captcha.png`
captchaResuelto=${captchaResuelto/ /}
echo 'CAPTCHA RESUELTO:' $captchaResuelto

# envíamos por POST el código a añadir y el resultado del captcha,
# teniendo en cuenta las cookies y datos de sesión
wget --post-data="add=$miCodigo&captcha_code=$captchaResuelto" \
                --keep-session-cookies --load-cookies $dirTrabajo/cookies.txt \
                $postUrl
cd $dirActual

Este script lo guardaremos el el mismo directorio en el que tenemos “ocrdb/”. Le podríamos añadir algunas comprobaciones de respuesta de la web, algún bucle para repetir el envío, ejecutarlo cada X tiempo vía crontab, etc. Pero eso se sale de las pretensiones de esta entrada.

Nota: Las urls de los scripts están mal formadas intencionadamente (http:/) para que el resaltador de código no las incluya como enlaces.


Distinguir una sesión local de una remota en Linux

categoría: Linux | tags: , , , | 4 comentarios »

Me he encontrado con la necesidad de programar un pequeño script en bash para el servidor Linux de un cliente. Dicho script estaba funcionando correctemente en la máquina local pero no así cuando se realizaba una conexión remota.

Ante esto era preciso encontrar alguna manera de discernir entre las conexiones locales y remontas para realizar configuraciones diferentes para cada una.

La solución, sencilla y un tanto ingeniosa, pasó por utilizar variables de entorno para hacer la distinción entre conexión local y remota:

if [[ -z "$REMOTEHOST" &&  -z  "$SSH_CLIENT"  ]]; then
echo "Cliente conectado en local";
else
echo "Cliente conectado en remoto";
fi

Se comprueba que no existan las variables de entorno $REMOTEHOST ni $SSH_CLIENT, la primera está presente en conexiones telnet y la segunda en conexiones SSH. Si no existe ninguna de ellas la conexión es local, si existe alguna de ellas la conexión es remota.