Categoría: programación y scripting

Web scraping de subastas del BOE en bash

Ayer domingo pude ver en Linkedin que unos científicos de datos de Deloitte (lástima no conservar el enlace) crearon un fantástico script en Python (usando Beautiful soup) para extraer los datos de las subastas publicadas en el Boletín Oficial del Estado, y pensé si podía hacer lo mismo en bash (sí, soy un romántico…).

Finalmente sí que se puede, con la relativa eficiencia del bash, pero es posible. Me resultó entretenido hacerlo, y lo comparto por si a alguien le resulta útil. Este script básicamente pide los dos primeros dígitos del código postal de la provincia que queremos extraer, y guarda todos los datos en un archivo CSV que puede visualizarse en cualquier programa de hoja de cálculos (Microsoft Excel, LibreOffice Calc, etc.).

#!/bin/bash
# Otro ejercicio de programación en bash por JCRUEDA.com
# Carácter separador de campos del CSV (por defecto, ";") :
sep=";"
# Títulos de las columnas :
encabezado="Identificador;Tipo;Inicio;Conclusión;Cantidad reclamada;Lotes;Anuncio BOE;Valor subasta;Valor tasación;Puja mínima;Tramos;Depósito;Código;Descripción;Dirección;Teléfono;Fax;E-mail;Tipo de bien;Descripción del bien;Dirección del bien;Codigo postal;Localidad del bien;Provincia;Vivienda habitual;Situación posesoria;Visitable;Pujas recibidas;Enlace;"
echo "WSB v.0.1 · Webscrapping de Subastas en Bash · jcrueda.com""\n";
echo "Datos extraídos de la Agencia Estatal del Boletín Oficial del Estado y bajo licencia:""\n""https://www.boe.es/informacion/aviso_legal""\n";
sleep 1; echo " - - -";
echo -n "[?] Primeros dos dígitos del código postal: "; read prv;
echo -n "[?] Nombre del archivo CSV de salida: "; read csvf;
echo "[i] Cargando página inicial de provincia...";
lynx --dump "https://subastas.boe.es/subastas_ava.php?campo%5B1%5D=SUBASTA.ESTADO&dato%5B1%5D=EJ&campo%5B2%5D=BIEN.TIPO&dato%5B2%5D=I&campo%5B7%5D=BIEN.COD_PROVINCIA&dato%5B7%5D="$prv"&campo%5B16%5D=SUBASTA.FECHA_INICIO_YMD&dato%5B16%5D%5B0%5D=&dato%5B16%5D%5B1%5D=&page_hits=40&sort_field%5B0%5D=SUBASTA.FECHA_FIN_YMD&sort_order%5B0%5D=desc&sort_field%5B1%5D=SUBASTA.FECHA_FIN_YMD&sort_order%5B1%5D=asc&sort_field%5B2%5D=SUBASTA.HORA_FIN&sort_order%5B2%5D=asc&accion=Buscar" > buf.fer; 
echo "[!] Extrayendo links a subastas concretas";
grep "detalleSubasta" buf.fer | tr " " "\n" | grep "https" > subastas.txt;
alguna=$(grep "accion=Mas" buf.fer | tail -1 | xargs | cut -f2 -d" ");
if [ -z "$alguna" ]; then echo "[i] Sólo hay una página de links.";
else echo "[!] Hay varias páginas. Listándolas todas...";
siguiente=$(grep "id_busqueda=" buf.fer | tail -1 | cut -f4 -d" ");
pagina=$(echo "https://subastas.boe.es/subastas_ava.php?accion=Mas&id_busqueda=`echo $siguiente | cut -f3 -d"=" | cut -f1 -d"-"`-0-5000");
rm buf.fer subastas.txt; lynx --dump "$pagina" > buf.fer; 
grep "detalleSubasta" buf.fer | tr " " "\n" | grep "https" > subastas.txt;
echo "[i] Se han extraído todos los links a subastas concretas."; fi;
echo "[i] Se han encontrado `wc -l subastas.txt | cut -f1 -d" "` subastas."; sleep 3;
echo "$encabezado" > $csvf;
for line in `cat subastas.txt`; do clear;
echo " - - - \n [!] Guardando subasta `grep -n "$line" subastas.txt | cut -f1 -d ":" | awk "NR==1"` de `wc -l subastas.txt | cut -f1 -d" "` ... \n - - -"
lynx --dump "$line" > buf.fer;
grep "Lotes" buf.fer > /dev/null | awk "NR==1" | sed s/" Lotes "// > lotes
    if grep -q "Sin lotes" lotes > /dev/null; then lotes="NO";
    else lotes="SÍ"; fi; rm lotes;
PARTE1=$(echo "`grep "Identificador " buf.fer | xargs | cut -f2 -d" "`#`grep "Tipo de subasta " buf.fer | sed s/" Tipo de subasta "//`#`grep "Fecha de inicio" buf.fer | sed s/" Fecha de inicio "// | cut -f1 -d"(" | tr " " "\n" | grep -v "CET" | xargs`#`grep "Fecha de conclusión" buf.fer | sed s/" Fecha de conclusión "// | cut -f1 -d"(" | tr " " "\n" | grep -v "CET" | xargs`#`grep "Cantidad reclamada" buf.fer | sed s/" Cantidad reclamada "//`#`echo $lotes`#`grep "Anuncio BOE" buf.fer | sed s/" Anuncio BOE "//`#`grep "Valor subasta" buf.fer | sed s/" Valor subasta "//`#`grep "Tasación " buf.fer | sed s/" Tasación "//`#`grep "Puja mínima " buf.fer | sed s/" Puja mínima "//`#`grep "Tramos entre pujas" buf.fer | sed s/" Tramos entre pujas "//`#`grep "Importe del depósito " buf.fer | sed s/" Importe del depósito "//`" | xargs);
autoridadgestora=$(grep "ver=2" buf.fer | xargs | cut -f2 -d" ");
bienes=$(grep "ver=3" buf.fer | xargs | cut -f2 -d" ");
pujas=$(grep "ver=5" buf.fer | xargs | cut -f2 -d" ");
lynx --dump "$autoridadgestora" > buf.fer; 
PARTE2=$(echo "`grep "Código" buf.fer | sed s/" Código "// | xargs`#`grep "Descripción" buf.fer | sed s/" Descripción "//`#`grep "Dirección" buf.fer | tr ";" "-" | sed s/" Dirección "//`#`grep "Teléfono" buf.fer | sed s/" Teléfono "//`#`grep "Fax" buf.fer | sed s/" Fax "//`#`grep "Correo electrónico" buf.fer | sed s/" Correo electrónico "//`" | xargs)
# TODO: Soportar varios bienes y listarlos independientemente
lynx --width 999 --dump "$bienes" > buf.fer;
PARTE3=$(echo "`grep "Bien " buf.fer | awk "NR==1" | sed s/"Bien "//`#`grep "Descripción " buf.fer | xargs | sed s/"Descripción" | tr ";" ","//`#`grep "Dirección" buf.fer | xargs | sed s/" Dirección"//`#`grep "Código Postal" buf.fer | sed s/"Código Postal"// | xargs | cut -f1 -d" "`#`grep "Localidad " buf.fer | xargs | sed s/"Localidad"// | cut -f1 -d" "`#`grep "Provincia " buf.fer | awk "NR==1" | xargs | sed s/"Provincia"//`#`grep "Vivienda habitual" buf.fer | awk "NR==1" | xargs | sed s/"Vivienda habitual"//`#`grep "Situación posesoria " buf.fer | xargs | sed s/"Situación posesoria"//`#`grep "Visitable" buf.fer | awk "NR==1" | xargs | sed s/"Visitable"//`");
PARTE4=$(lynx --width 999 --dump "$pujas" | grep "Puja máxima actual de la subasta" -A 3 | grep -v "Puja máxima actual de la subasta" | xargs )
if grep -q "ha recibido alguna" "$PARTE4"; then PARTE4="Con pujas";
else PARTE4="Sin pujas"; fi;
echo $PARTE1"#"$PARTE2"#"$PARTE3"#"$PARTE4"#"$line | tr "#" "$sep" >> $csvf
done;
rm buf.fer subastas.txt lotes; clear;
echo "[!] Finalizado! Resultados almacenados en '$csvf'"

Dependencias:

sudo apt-get install lynx curl

Radio signal identification «by ear»: Discrete Fast Fourier audio hashes comparison in Python

Most sound identification apps uses fast fourier transform to generate hashes from a sound. These hashes are stored in a huge catalog of audio fingerprints, and when a user tags a song for a few seconds, the app generates an audio fingerprint and seeks for a match on the database.

«I think that you’re listening to X«.

This clever guy created his own version of Shazam for experimental purposes. When I saw it, I thought about the posibility of use this application for SIGID.

SIGID (Signal Identification) is to search for unknown radio signals, trying to identify them through example sounds and waterfall images using software defined radio (RTLSDR, Airspy, SDRPlay, HackRF, etc.).

So first I have downloaded all audio samples from Signal Identification Wiki database and generated a SQLite database for the python script.

Listening for about 5-10 seconds, the script can now identify a lot of known signals (about 350)! In this article you can found a direct link to download my database and save potential time and problems.

Testing my database. 347 «songs» are fingerprinted. Very noisy songs, yeah.

How can I do the same?

  • Install python, pip and dependencies:
sudo apt-get install python-tk ffmpeg portaudio19-dev python-pyaudio python-pip
sudo pip install matplotlib termcolor scipy pydub PyAudio
  • Clone and set up SQLite database:
git clone https://github.com/baliksjosay/audio_recogition_system
cd audio_recognition_system
make clean reset
  • Download my generated hash database of Sigidwiki:
https://www.dropbox.com/s/9v7eslkwglzs3ys/fingerprints2.rar?dl=1
  • Unzip file in /db/ directory.
  • Test the script! Two ways:
  • Via microphone/virtual cable (5 seconds):
 python recognize-from-microphone.py -s 5
  • Vía saved audio file (Update: we are all having troubles with this option):
 python recognize-from-file.py sampleaudiofile.mp3

Enjoy it!

PS. – Doesn’t work? Think about demodulation. The same signal sounds pretty different from, i. ex. AM to FM. Some known signals (CW, FM broadcast…) may fail.

PS.2 – Update 4/2/2020. I’ve submitted my project and Rtl-sdr.com blog published a review 😀

PS.3 – Update. Some users reported problems using the «recognize-from-file.py», but no problems with «recognize-from-microphone.py». If you need to work only and exclusively with «from file» option, please contact with the author of the script (and please, share with us your conclusions!). Thank you!

PS.3 – Update 12/2/2020. Dan Maloney wrote a review on Hackaday 😀

Radio fingerprinting

Few days ago I heard about a guy that created a script for recognise spurious emissions from a list of known devices, and I wanted to do the same in a simpler way.

I do not own any downconverter for my RTL-SDR – most spurious emissions are located near to 0 MHz and my SDR device starts on 24 MHz – so I have created a very simple script using wide-range frequencies scan with rtl_power, then converted to image schema with heatmap.py, and compared with imagemagick in a probabilistic way to determine which profile is the most similar to database entries. I called it Radioprint.

Radioprint discovering nearby devices

Below you will find radioprint.sh sourcecode. Remember install all dependencies [imagemagick, rtl_power] and run the script in the same folder of heatmap.py. You must create an empty directory called «database» in the same folder in order to compare profiles before running the script.

The script reads from 24MHz to 921MHz. Maybe a narrower range would make the script more efficient, but also more innacurate. Feel free to modify it.

./RADIOPRINT.SH

rm log.html 1.png 2.png probe.csv r.txt; 
echo '<html><body bgcolor="#34495e"><font face="verdana" color="white"><h1>Radioprint</h1><br>' > log.html; 
while true; 
	do rtl_power -f 24M:921M:60k -g 50 -i 10 -e 10s probe.csv; 
	python heatmap.py probe.csv 1.png; convert 1.png -gravity Center -crop 100%x+0+26 2.png; 
	echo "<b>" >> log.html; 
	cd database; rm r.txt; 
		for line in `ls | xargs | tr " " "\n"`; 
		do convert -metric AE ../2.png $line -trim -compare -format "%[distortion]" info: >> r.txt; 
		echo -n ",$line" >> r.txt; echo " " >> r.txt; 
		done; 
	cat r.txt | sort | awk "NR==1" | cut -f2 -d"," | cut -f1 -d"." >> ../log.html; 
	cd ..; echo "</b> - " >> log.html; 
	content=$(base64 -w0 < "2.png"); 
	b64=$(echo "data:image/png;base64,$content"); 
	data=$(date +%d.%m.%y.%H.%M.%S); 
	hash=$(echo $content | base64 -d | md5sum | cut -f1 -d" "); 
	echo '<a>'$data' - '$hash':</a><br><img src="'$b64'" width=100% height=25 /><br>' >> log.html; 
done;

How it works

Run the script -without arguments- and let it work in the background. Minimize the console and open log.html with your favourite web browser in order to see real-time results – pressing F5 each 30 seconds. The script adds the scan results on this page each ~20-30 seconds.

Connect to your SDR device a small wire as antenna, about 7-8 centimeters, and let it work in a place far away from electronic devices [>1 meter]. Refresh webpage and wait until you see an appropiate spectrum representation of «normality» in «log.html», then right-click, save image as…, go to /database folder and save it [without spaces] as «normal.png». You’ve just created your first profile for nothing found.

Now put your mobile phone touching directly the small antenna. Wait for the correct profile image in «log.html», and save it in the same way we did for «normal» profile. Now save the file in /database as «smartphone.png«. Now we have two profiles: normal and smartphone.

Radioprint will start to compare distortion between saved images and the new real-time generated images. Start checking if the script detects if your smartphone is near, for example.

Update 1/10/19. RTL-SDR.com has just released a review of my script! It is a great privilege and I appreciate it very much.

rfside

rfside is a very simple bash script based on rtl_power and heatmap.py that gets info related to emission power in wide-band scan and shows it all in a gaze. The scripts perform a huge scan in just 5 minutes, from 24 MHz to 1.7 GHz [customizable] allowing us to identify active bands for a more detailed study on any SDR application. It aims to be the first step in radio signals identification.

Source code here.

Ingeniería social en iOS para obtener códigos 2FA

En el experimento que hoy presento, introduciendo un número de teléfono del atacante, se generará un archivo PDF que contiene un mensaje falso de iOS pidiendo que se guarde el archivo en la aplicación nativa «Libros» de iOS. Cuando esto se hace y se vuelve a abrir el script, se ejecuta sin consentimiento un URI tel con códigos USSD que desvían las llamadas y SMS al teléfono atacante.

Una vez hecho esto, el atacante no tiene más que acudir a la sección «¿Ha olvidado su contraseña?» de cualquier servicio para recibir en su propio móvil un código de confirmación o un link para cambiar la clave de la víctima.

Descarga el script bash aquí.

NOTA: Si vas a probarlo en tu propio móvil, teclea posteriormente el USSD #002# para desactivar los desvíos.

NOTA 2: Es un simple ejercicio de programación. El uso que se le dé a este script es asunto de cada uno, y no asumo ningún tipo de responsabilidad.

Especulando con Python: automatización de operaciones con Ethereum y la API de Coinbase

image

La casa de cambio de criptodivisas Coinbase ha puesto a disposición de desarrolladores una API especialmente útil, en tanto nos permite integrar las operaciones básicas de compra y venta en toda clase de programa o script. Python es un lenguaje especialmente estructurado, potente y sencillo, en el que los desarrolladores de Coinbase pensaron desde el primer momento – sólo hay que ver la documentación de la API -. Seguir leyendo «Especulando con Python: automatización de operaciones con Ethereum y la API de Coinbase»

Proxychains: la falta de cooperación judicial internacional como base del anonimato en Internet

Resulta ingenuo pensar que existe verdadero anonimato en Internet. Cuando entramos, inevitablemente, nuestros actos tienen reflejo en una red que ha mutado, aun mínimamente. Por ello, los neuróticos de la privacidad y los ciberdelincuentes suelen recurrir a métodos como ocultar la petición de origen bajo otra dirección IP utilizando, por ejemplo, un servidor proxy.

Una conexión del comando cUrl proxificada con proxychains, que permite encadenar proxies para tratar de dificultar la identidad de la IP de origen
Proxychains en acción, proxificando cUrl

Seguir leyendo «Proxychains: la falta de cooperación judicial internacional como base del anonimato en Internet»