Share

Los humanos somos gente de costumbres y salvo un “efecto Meneame” que nos comimos un día, el resto de visitas al blog sigue un patron bastante simple y sin sorpresas.

Por eso el otro día mi sorpresa fue mayuscula al ver esto en las estadisticas del Observatorio de Seguridad.

AtaqueBlog-estadisticas

Obviamente algo raro esaba pasando. El modulo de estadisticas no es precisamente para hacer un forense, así que me fui directamente a los logs.

 

El resultado fue facil de localizar, pero poco gratificante.. miles de peticiones con este formato…

XX.XX.XX.XXX – – [24/Jun/2016:19:46:27 +0000] “POST /xmlrpc.php HTTP/1.0” 200 58340 “-” “-“

La problematica es que por defecto apache, siguiendo ls recomendaciones del standar, no almacena el contenido de las peticiones POST. Asi que , me toco tunear la configuracion. Para ello utilizaremos el modulo dump_io mediante el siguiente comando:

a2enmod dump_io

 

 

Luego, cambiamos la configuracion, en mi caso del ErrorLog, para utilizar el modulo. Comentamos la linea que venía y lo dejamos asi:

# LogLevel: Control the severity of messages logged to the error_log.
# Available values: trace8, …, trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the log level for particular modules, e.g.
# “LogLevel info ssl:warn”
#
#LogLevel warn
DumpIOInput On
LogLevel dumpio:trace7

 

Reiniciamos el apache y ya lo tenemos… ahora a esperar. Pasados unos dias.. otro pico en los accesos, pero ahora tenemos todos los datos, aunque hay que decir que el log queda un poco infernal

 

[Sun Jul 10 12:05:05.332861 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(103): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): POST /xmlrpc.php HTTP/1.0\r\n
[Sun Jul 10 12:05:05.332867 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(140): [client 37.59.52.170:40845] mod_dumpio: dumpio_in [getline-blocking] 0 readbytes
[Sun Jul 10 12:05:05.332868 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(63): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): 39 bytes
[Sun Jul 10 12:05:05.332870 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(103): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): Host: www.observatoriodeseguridad.com\r\n
[Sun Jul 10 12:05:05.332872 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(140): [client 37.59.52.170:40845] mod_dumpio: dumpio_in [getline-blocking] 0 readbytes
[Sun Jul 10 12:05:05.332873 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(63): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): 49 bytes
[Sun Jul 10 12:05:05.332875 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(103): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): Content-Type: application/x-www-form-urlencoded\r\n
[Sun Jul 10 12:05:05.332877 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(140): [client 37.59.52.170:40845] mod_dumpio: dumpio_in [getline-blocking] 0 readbytes[Sun Jul 10 12:05:05.332878 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(63): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): 21 bytes
[Sun Jul 10 12:05:05.332880 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(103): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): Content-Length: 101\r\n
[Sun Jul 10 12:05:05.332881 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(140): [client 37.59.52.170:40845] mod_dumpio: dumpio_in [getline-blocking] 0 readbytes
[Sun Jul 10 12:05:05.332882 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(63): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): 2 bytes
[Sun Jul 10 12:05:05.332884 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(103): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): \r\n
[Sun Jul 10 12:05:05.333222 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(140): [client 37.59.52.170:40845] mod_dumpio: dumpio_in [readbytes-blocking] 101 readbytes
[Sun Jul 10 12:05:05.333229 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(63): [client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): 101 bytes[Sun Jul 10 12:05:05.333231 2016] [dumpio:trace7] [pid 29999] mod_dumpio.c(103):
[client 37.59.52.170:40845] mod_dumpio: dumpio_in (data-HEAP): <?xml version=”
1.0″?><methodCall><methodName>demo.sayHello</methodName><params></params></metho
dCall>

 

Esta es la primera peticion que mandan, basicamente una prueba para lo que viene despues, pero ya nos hace que sea mas comodo parsearlo de alguna manera para dejar solo lo interesante:

Un poco de bash-fu y ya me encuentro un par de sorpresitas. El comando que ejecuto es:

cat error.log | cut -f8- -d’:’ | egrep -v ‘ [0-9]+ bytes$’ | grep -v ‘^$’ | cut -c2- | sed ‘s/\\r\\n//’ | less

 

Y con eso saco las peticiones mas o menos en crudo… mira que majos los chinos, estan intentando sacar el password del blog… (peticion al wp-login.php) y lo otro parece mas bien algun tipo de peticion de prueba..

POST /wp-login.php HTTP/1.1
Referer: http://65.21.1.18/wp-login.php
Accept: */*
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Host: www.observatoriodeseguridad.com
Content-Length: 21
Cache-Control: no-cachelog=admin&pwd=7654321
POST /xmlrpc.php HTTP/1.0
Host: www.observatoriodeseguridad.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 101<?xml version=”1.0″?><methodCall><methodName>demo.sayHello</methodName><params></params></methodCall>

Efectivamente.. lo serio viene despues.. miles de peticiones como esta:

POST /xmlrpc.php HTTP/1.0
Host: www.observatoriodeseguridad.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 83479<?xml version=”1.0″?><methodCall><methodName>system.multicall</methodName><params><param><value><array><data>\n<value><struct><member><name>methodName</name><value><string>wp.getCategories</string></value></member><member><name>params</name><value><array><data><value><string></string></value><value><string>observatoriodeseguridad</string></value><value><string>123456</string></value></data></array></value></member></struct></value>\n<value><struct><member><name>methodName</name><value><string>wp.getCategories</string></value></member><member><name>params</name><value><array><data><value><string></string></value><value><string>observatoriodeseguridad</string></value><value><string>password</string></value></data></array></value></member></struct></value>\n<value><struct><member><name>methodName</name><value><string>wp.getCategories</string></value></member><member><name>params</name><value><array><data><value><string></string></value><value><string>observatoriodeseguridad</string></value><value><string>12345678</string></value></data></array></value></member></struct></value>\n<value><struct><member><name>methodName</name><value><string>wp.getCategories</string></value></member><member><name>params</name><value><array><data><value><string></string></value>

No la voy a pegar aqui entera, pero creo que ya os haceis una idea. en una sola peticion web, agrupan numerosos intentos de combinaciones login/password.

Me he puesto a sacar todas las combinaciones de los logs de este ataque..

Y me salen unas 400.000!!!

Asi que mucho cuidadito con lo que poneis de password en vuestro blog 🙂

Share

Os dejo una aplicación muy chorra para obtener el estado de tus dockers a través de un bot muy simple de telegram:

 

[code language="python"]
#!/usr/bin/env python
# -*- coding: utf-8 -*-


from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
import logging
import os

# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
 level=logging.INFO)

logger = logging.getLogger(__name__)


def help(bot, update):
 bot.sendMessage(update.message.chat_id, text='Help!')


def stats(bot, update):
 bot.sendMessage(update.message.chat_id, text='ahora lo programo')
 os.system('docker stats --no-stream > /tmp/stats.tmp')

 filesize=os.path.getsize('/tmp/stats.tmp')
 if filesize > 0:
 fd = open('/tmp/stats.tmp')
 string=fd.read()
 bot.sendMessage(update.message.chat_id,text=string)
 fd.close()
 os.system('rm /tmp/stats.tmp')

def error(bot, update, error):
 logger.warn('Update "%s" caused error "%s"' % (update, error))


def main():
 # Create the EventHandler and pass it your bot's token.
 updater = Updater("740925671:tyhejsio2hustqmckopsr567a-F0k23GG9E")

 # Get the dispatcher to register handlers
 dp = updater.dispatcher




 # on different commands - answer in Telegram
 dp.add_handler(CommandHandler("stats", stats))

 # log all errors
 dp.add_error_handler(error)

 # Start the Bot
 updater.start_polling()

 # Run the bot until the you presses Ctrl-C or the process receives SIGINT,
 # SIGTERM or SIGABRT. This should be used most of the time, since
 # start_polling() is non-blocking and will stop the bot gracefully.
 updater.idle()


if __name__ == '__main__':
 main()

[/code]

 

Share

En esta entrada veremos como generar un script en python para interactuar con nuestros servidores vía Telegram:

Instalar las librerías que se necesitan:

pip install future

pip install urllib3

pip install certifi

pip install python-telegram-bot

 

El template sería algo así:

 
#
# Code to interact with your server.
#
import telegram
import sys
import logging
import os


bot = telegram.Bot("API")
#chat_id=_NUMERO_



def log_update(update):
  message = update.message.text.encode('utf-8')
  bot_chat_id = update.message.chat.id
  update_id = update.update_id
  first_name = update.message.from_user.first_name
  last_name = update.message.from_user.last_name
  from_id = update.message.from_user.id

  if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
    logging.debug('Update %d from %s %s (%d) in chat %d received:', update_id,first_name, last_name, from_id, bot_chat_id)
    logging.debug(update)
  else:
    logging.info('Update %d from %s %s (%d) in chat %d: Received "%s"', update_id,first_name, last_name, from_id, bot_chat_id, message)


try:
    LAST_UPDATE_ID = bot.getUpdates()[-1].update_id
except IndexError:
    LAST_UPDATE_ID = None

while(True):


    for update in bot.getUpdates(offset=LAST_UPDATE_ID, timeout=30):
      bot_chat_id = update.message.chat.id
      message = update.message.text.encode('utf-8')
      update_id = update.update_id
      log_update(update)
      if chat_id >= 0 and chat_id != bot_chat_id:
        logging.warning('Unauthorized chat_id %d found. Update ignored.', bot_chat_id)
        continue

#command help
      if '/help' == message:
        status = "/GetFile - Get a file.\n/ExecCommand - Exec a pre set command.\n/OtherCommands - Send a Message"
        bot.sendMessage(chat_id = bot_chat_id, text=status, parse_mode=telegram.ParseMode.MARKDOWN)

#command NewPasswordsFile

      elif '/GetFile' == message:
        fd=open('/path/to/file.txt','r')
        bot.sendDocument(chat_id=bot_chat_id, document=fd)
        fd.close()

      elif '/ExecCommand' == message:
        os.system('echo command to exec > /path/to/file')

      elif '/OtherCommands' == message:
        bot.sendMessage(chat_id=bot_chat_id,text='Ideas are welcome :P, use /Suggest idea to submit crazy features.')

      else:
        #bot.sendMessage(chat_id=bot_chat_id,text='Welcome to My bot. Accepted commands:\n\n/help - Info aobut commands.')
        os.system('echo x > /dev/null')

      LAST_UPDATE_ID = update_id + 1
   

A disfrutarlo 🙂

Share

I. Creando bot de telegram

Hay múltiples posts donde este proceso está bastante bien documentado pero creo que es útil tener todos los pasos aquí. Y como se trata de facilitar el proceso, describo el proceos yendo al grano.

I.a Desde el buscador de Telegram localizad a @BotFather, un bot para controlarlos a todos.

BotFather para gestionar Bots en Telegram

BotFather permite gestionar Bots en Telegram

I.b Comenzamos a interacturar con @BotFather con el comando /start

El comando /start te permite hablar con BotFather

El comando /start te permite hablar con BotFather

I.c Usamos el comando /newbot para crear un nuevo bot

Elige nombre para el bot y a continuación el nombre de usuario (éste último debe terminar en ‘bot’, ejemplo Scada_bot)

Si todo va bien, obtendremos nuestro token para interactuar con la API de Telegram

Obteniendo un Token para interactuar con la API HTTP de Telegram

Obteniendo un Token para interactuar con la API HTTP de Telegram

Tan sencillo como esto! Ya tienes un bot en telegran y su token para interacturar con la API HTTP.

Share

Habreis visto por todos los lados (por ejemplo http://motherboard.vice.com/read/hackers-stole-68-million-passwords-from-tumblr-new-analysis-reveals o https://www.theguardian.com/technology/2016/may/31/tumblr-emails-for-sale-darknet-65-million-hack-passwords) que se esta vendiendo en el mercado negro una lista de mas de 50 millones de usuarios sacados de Tumblr.

Parece que a parte de venderse, se ha filtrado publicamente por “ahi” asi que vamos a echarle un vistazo a ver que sacamos de ello. El archivo que se ha filtrado es un users.tar.7z que descomprimiendo y sacandolo del tar queda respectivamente asi:

-rwxrwxrwx 1 ptolomeo ptolomeo 4906136307 mar 4 02:56 users
-rwxrwxrwx 1ptolomeo ptolomeo 4906147840 may 5 00:39 users.tar
-rwxrwxrwx 1ptolomeo ptolomeo 2114725557 jun 3 23:28 users.tar.7z

 

y efectivamente el contenido parece que podria ser “legitimo”

aneilia@nyu.edu:c97c9898a5f3b0e0ef6ce428e7f3bb71cd8cf961
palmiter@gmail.com:36312fb33860a2e5d15d8b8c04ea404dbc902e2b
ddecordova@yahoo.com:3f16a0d78e90b36a03a96a88cf4d2cb41b1884e9
slicetumblr+social.seriouseats@gmail.com:8f4a69d50ab2891c27406ef63b75444dacdf2e69
leerubensteindotcom@gmail.com:9432340c1227f1c6cc6ddba47690ac5ba5276b03
achiu930@gmail.com:ce1f8c68ae23f38b5c2d14fcf315dd7f4fd7a915
demo@tumblr.com:5fb79107a970e603d05d29e0b88fe3aeca114a8

 

Si nos ponemos a contar lineas, el susto llega hasta los 73 millones

$ wc -l users
73369245 users

 

Esto con el hashcat tenia pinta de sermuy divertido ]:D…. pero no. Lo primero que podriamos pensar por la longitud de las hashes es que serian un sha-1 o algo similar, pero el estupor es absoluto al ver que aunque se procesa adecuadamente por el hashcat o por el JohnTheRipper, no da ningun resultado. 0 hits.

JohnTheRipper-bleeding-jumbo/run/john users –format:raw-sha1 -wo:password.lst –nolog
Loaded 39296504 password hashes with no different salts (Raw-SHA1 [SHA1 128/128 AVX 8x])0g 0:00:00:04 DONE  0g/s

 

El primer pensamiento es obviamente que se utilice una semilla o ‘salt’ asociado a cada usuario, y que eso se añada a la clave de alguna manera antes de pasar el proceso de hash. Si es así y no se ha incluido en el leak  el correspondiente a cada usuario, podria convertir los hashes en basicamente inservibles, dependiendo de la longitud de estos.

Pero obviamente, no estamos, en ese caso, la herramienta reconoce muchos menos hashes distintos que lineas del fichero, con lo lo que obviamente hay muchisimas lineas repetidas y no puede ser el caso. Nos quedan dos alternativas, que exista una semilla unica añadida a todas las claves (pepper), o que el algoritmo sea algo mas complejo (varias iteraciones o cosas un poco mas raro). Para probar esto ultimo, he decidido darle un repaso a los distintos subformatos que tiene el JohnTheRipper, no vaya a sonar la flauta 🙂 para ello busco los que me puedan cuadrar del comando john –list:subformats

JohnTheRipper Subformats

Pero agua de nuevo.

Solo me queda sacar ciertos datos de lo comunes o no que pueden ser esas repeticiones. Asi que las voy a contar.

cat users | cut -d: -f2 | sort | uniq -c | sort -n -r -o tumblr.hashes.counted

head tumblr.hashes.counted

210230 894b186bf79d4337c4f44140a2ec12b42d13a79f
122428 6235985022c8ead4826a4a62a5181681a3145ebe
73502 878372829572d5b96e037e3445ce5f5faeb2d031
57692 ff58efb7ded7e103174724de79fcf34a62f497ac
54220 40da18fc61674c03d9b625732562699fe1489530
50827 6dd9e2c207495c646735501466a37dfe2fc3e7b

 

WOW… 210.000 usuarios han coincidido en la clave, eso debe ser password, o tumblr  o 1234 o algo asi X”D. Pero desde luego nos estamos perdiendo algo.

 

Para que luego alguien diga, que si se filtran tus datos, esta todo perdido X”D

 

Dandole una vueltecita rapida a los usuarios, si cogemos todos los correos vemos la dura competicion entre hormail y gmail. Y si lo restringimos a los .es, hotmail arrasa, y la sorpresa es el dominio sek.es

18774947 gmail.com
18427787 hotmail.com
14487188 yahoo.com
2137398 aol.com
1540086 live.com
1536983 hotmail.co.uk
825123 ymail.com
754727 yahoo.co.uk
675643 aim.com
410127 mail.ru
 156463 hotmail.es
32568 yahoo.es
1049 terra.es
488 gmx.es
253 hotmai.es
235 wanadoo.es
160 Hotmail.es
147 alumno.sek.es
143 live.es
136 Yahoo.es

 

Y poco mas por ahora. dejare esto haciendo pruebas a ver si descubrimos que hay detras de esos hahes…

Share

En primer lugar, gracias a los que tuvieron a bien menear la noticia anterior. Hizo portada en meneame y aprendimos por las malas lo duro que puede ser eso. Ahora alguien tiene en el ToDo asegurarse de que el blog aguanta mas 🙂

En cuanto al bicho del telefono, tras inputs de varias personas(fundamentalmente @timstrazz @michalmalik  @MalwareMustDie y los propios comentarios de la entrada anterior), hemos hecho entre todos algunos avances..

El binario guarda su configuración en el archivo /system/bin/unint8int, que aunque esta en el path y con permisos de ejecucion en realidad es una base de datos SQLite.

unint8int-content

Por otro lado, estuvimos buscando como vendria eso vinculado a algun apk. en teoría parece que debiera haber algo así como un android.debugs.bin, pero no aparecio en el sistema. (Buscado a traves del comando pm list packages -f)

La gente de @MalwareMustDie hico un poco de ingenieria inversa del binario y lo colgo en un Pastebin. Ahi se referencia a otra base de datos, que pudiera indicar un apk vinculado al malware. “/data/data/com.mediatek.mobileaudioconnction/databases/audio.db” . El formato de esta BD es la misma es igual que la anterior, pero con menos datos almacenados (al menos en este momento, pero desde luego, el IMEI del telefono que aparece en ese archivo no parece tener mucho que ver con nada de audio)

En este caso si que existe un apk, MTKAudioAssistant.apk que parece estar vinculado con ello. Un decompilado rapido nos muestra que esas clasess estas presentes com.mediatek.mobileaudioconnction (siempre me va a llamar la atencion que sea connction .. sin la e)

MTKAudioAssistant

Dentro del DebugBinBroadcast (aqui os lo dejo en otro pastebin http://pastebin.com/0sgVqU6K) puede verse como el programa va adquiriendo informacion del dispositivo y la almacena en su SQLite

Debugnbinbroadcast0.java.

Debugnbinbroadcast.java

Tengo que acabar de leermelo con calma, porque desde luego tengo curiosidad por ver que mas esta haciendo, pero cuanto mas miro, mas cosas raras encuentro en el telefono 🙂

 

Share

Pues si, eso parece.. el telefono viene con bicho desde la fábrica o similar, pero empecemos por el principio…
Este año, como he debido ser malo bueno, los reyes me han regalado un movil nuevo.  Un estupendo telefono chino de esos de marca desconocida en occidente salvo para los muy frikis del tema.

Se trata concretamente de un Doogee Voyager2 D310. Se conoce que esta vez los reyes, aparte de venir de oriente lo hacen a traves de Dealextreme.

Una de las primeras cosas que queria hacer, era investigar como funciona un jueguecito, pero ya hablare de eso otro dia, el caso es que en vez de conectarlo al punto de acceso de casa, lo puse por defecto al de una raspberry pi que tengo para tal efecto. Así se que puedo pinchar todo el tráfico de red para cotillear lo que se manda.

El susto que me lleve fue ya interesante, antes de instalar nada y ya el telefono, simplemente con su android y su cuenta de google ya generaba un monton de tráfico. Alguno de ellos salto ya directamente a la primera como algo “raro”

DNS-queries

 

Definitivamente estas peticiones DNS, apestan. Un breve vistazo a lo que hay en esas máquinas en threatcrowd y confirmado, maquinas conocidas por estar sirviendo malware y unos 500 DNS distintos,

 

Asi que nada. Ya tengo tarea, encontrar que demonios esta corriendo el telefono que hace estas conexiones. Afortunadamente es un telefono que trae un “Engineer Mode ” que hace trivial ejecutar codigo como root si hace falta. Asi que la primera opcion para encontrar que programa estaba ejecutando esas conexiones fue cutre, pero eficiente.  El comando script para registrar lo que iba saliendo en pantalla, una conexion adb, y un bucle infinito…

while true; do busybox netstat -tapn ; done  

Despues simplemente a buscar cuando aparece la conexion…

netstat-debugs

Ahi esta… “debugs” que c#~@½ será eso??

Luego, ya te tiras de los pelos al ver el binario.. concretamente se encuentra en la ruta /data/debugs/debugs

debugs-perm

Estupendo!! Ahora ya se, que ademas de tener, lo que parece ser un troyano en mi movil, supone un agujero de seguridad y que cualquier otra aplicacion podria intentar escalar privilegios…

Una busqueda, mas detallada encuentra otros dos binarios, esta vez en el /bin

debugs-other-perm

Si no me fallan los calculos y lo poco que he visto por dentro, el debugsrun es que lo ejecuta, y el debugsbak es una copia del debugs que sobreescribe en la ruta original si ve que algo ha cambiado.  No es que sea un fiera del reversing… un mero “strings” ya te cuenta todo eso..

debugsrun-strings

 

Una vuelta rapida por virustotal me indica que el malware no esta inventariado, asi que os dejo por aqui los md5 de los ficheros virustotal-searchvirustotal-notfound

root@VOYAGER2_DG310:/ # md5 /data/debugs/debugs
a0061e4b77dacd1cb25b0ee0e1c7b9ce /data/debugs/debugsroot@VOYAGER2_DG310:/ # md5 /system/bin/debugsrun
3e76bc08ea812adebfaa72cd72daf5d2 /system/bin/debugsrun
root@VOYAGER2_DG310:/ # md5 /system/bin/debugsbak
a0061e4b77dacd1cb25b0ee0e1c7b9ce /system/bin/debugsbak

Tengo pendiente meterme en serio a tracear lo que hacen, tanto por reversing de los binarios como analizando mas en detalle el trafico que generan..

 

Mientras tanto, para que os hagais una idea, esta es la peticion estandar que he visto…

 

debugs-httptraffic

Os dejo aqui los ficheros.

debugs-malware.tar.gz

Si alguien tiene a bien avanzar con la investigación, subirlos para que se detecten como algo sospechoso o localizarlos en otros modelos de teléfono, please que me avise.

Share

 

Llevaba tiempo pensando en sustituir mi viejo servidor en casa. Al fin y al cabo, estaba ya mas que obsoleto y solo lo utilizaba para unas cuantas tareas programaticas y como gestor de esa información que no me hace gracia que este en la nube. Todo el resto de cosas ya las he venido subiendo a diversos VPS en los ultimos años.

 

Al final, la historieta de un amigo al que se le murio un disco duro pero pudo mantener bien los datos gracias a un RAID montado en condiciones fue el espaldarazo definitivo y me compre una QNAP-451. De eso hace aproximadamente un año. Pero el otro día repentinamente, empezo a pitar cada poco. Un pequeño vistazo al televisor al que esta enchufado y se podia ver como cada 5 minutos o asi se veia que la NAS se estaba reiniciando. Lamentablemente desde el comienzo del arranque del sistema operativo ya no se volvia a ver nada.

QNAP 451

QNAP 451

 

Asi que manos a la obra, NAS apagada y a empezar a leer a ver que se puede hacer para reflashearla y restaurar que funcione bien o como minimo poder acceder a los datos.

Lo primero que hice fue desconectar todos los discos duros, eso sí, sin sacarlos del todo del sistema para asegurarme que despues no tengo problemas al volverlos a pinchar y mantener el orden en el que estaban.

Lo siguiente, arrancar el sistema con una distribucion Live de Linux, en mi caso una Knoppix que tenia a mano directamente en un USB. Afortunadamente, el procesador del sistema es un X86 asi que paso facil y en la television se puede acceder al abios para cambiar el orden de arranque. (asegurate de que tenga ssh para conectar en remoto)

Mirando a ver a lo que nos enfrentamos…

# fdisk -l

Disk /dev/sda: 515 MB, 515899392 bytes 8 heads, 32 sectors/track, 3936 cylinders
Units = cylinders of 256 * 512 = 131072 bytes

Device Boot Start End Blocks Id System
/dev/sda1 1 41 5244 83 Linux
/dev/sda2 * 42 1922 240768 83 Linux
/dev/sda3 1923 3803 240768 83 Linux
/dev/sda4 3804 3936 17024 5 Extended
/dev/sda5 3804 3868 8304 83 Linux
/dev/sda6 3869 3936 8688 83 Linux

Parece que aparte de los discos externos este juguete viene con una especie de disco interno de 512 MB. Esto es lo que tendremos que flashear, pinta facil. QNAP ademas ofrece una imagen de recuperacion completa para descargar.

http://eu1.qnap.com/Storage/tsd/fullimage/F_TS-X51_20140916-1.2.8.img

Copiamos esta imagen al USB y la sobreescribimos en el disco

dd if=/mnt-system/F_TS-X51_20140916-1.2.8.img  of=/dev/sda

Rebotamos y voila, ya estamos de nuevo en el sistema, aunque con una version de firmware viejismo. Vamos a proceder ahora a actualizarlo a la ultima version. El mejor enlace que he encontrado para el proceso de instalacion manual es el siguiente: http://qnapsupport.net/?page_id=4672

Ahora antes de instalar hay que ir pinchando los discos de uno en uno, esperando un poco entre ellos para que el sistema los reconozca en el orden correcto. Puedes seguir la evolucion haciendo

cat /etc/enclosure_0.conf

Posteriormente lanzamos dos fases de configuracion de los dispositivos y los raid con todas las particiones raras que monta Qnap

#storage_util –sys_startup

#storage_util –sys_startup_p2

Con el primer paso debería aparecer el dispositivo md9 y montarse en /mnt/HDA_ROOT y el md13 (sin montar)

Con el segundo deberían aparecer mas dispositivos y montarse adecuadamente, pero en mi sistema eso no funciona correctamente. Las particiones como tal estan montandas sobre LVM2 y no lo reconoce bien de primeras. Vamos a indagar en esa configuracion.

#pvscan
PV /dev/md2 VG vg2 lvm2 [1.81 TiB / 0 free]
PV /dev/md1 VG vg1 lvm2 [7.26 TiB / 0 free]
Total: 2 [9.07 TiB] / in use: 2 [9.07 TiB] / in no VG: 0 [0 ]
[/mnt/tmp/vg1_lv1/MAIN] # lvscan
ACTIVE ‘/dev/vg2/lv545’ [18.54 GiB] inherit
ACTIVE ‘/dev/vg2/lv2’ [1.79 TiB] inherit
inactive ‘/dev/vg1/lv544’ [20.00 GiB] inherit
inactive ‘/dev/vg1/tp1’ [7.22 TiB] inherit
inactive ‘/dev/vg1/lv1’ [4.00 TiB] inherit

Como puede verse, el sistema detecta, dos grupos logicos distintos y muchos volumenes distintos. La verdad es que no se que es lo que hace QNAP por dentro. Estan los volumenes lv544 y lv545 de casi 20Gb que yo no he creado y no se lo que tienen. Luego esta el tp1 que es la totalidad de espacio disponible en el Raid5 que monte y lv1 que es la particion de 4 Teras que estoy usando. No recuerdo la configuracion exacta que puse en el menu de Qnap y por que en el segundo volumen no existe un equivalente al tp1 y si al lv1 de datos.  Lo unico que por algun motivo estan desactivados, para poder usarlos es necesario activar el volumen.

# vgchange -ay
2 logical volume(s) in volume group “vg2” now active
modprobe: could not parse modules.dep/sbin/modprobe failed: 1
Can’t process LV tp1: thin-pool target support missing from kernel?
Can’t process LV lv1: thick target support missing from kernel?
1 logical volume(s) in volume group “vg1” now active

Nuevo fallo. parece que el kernel no tiene soporte para alguna de las opciones de LVM2 que se estan usando. Afortunadamente la imagen si que trae los modulos, pero tenemos que insertarlos de uno en uno por orden para que se vayan resolviendo las dependencias

# insmod /lib/modules/misc/dm-bio-prison.ko
# insmod /lib/modules/misc/dm-bufio.ko
# insmod /lib/modules/misc/dm-persistent-data.ko
# insmod /lib/modules/misc/dm-thin-pool.ko
# vgchange -ay
2 logical volume(s) in volume group “vg2” now active
3 logical volume(s) in volume group “vg1” now active

 

Ahora ya podemos montar el dispositivo si todo ha ido bien.

mount -t ext4 /dev/mapper/vg1-lv1  /mnt/tmp/vg1_lv1

 

Y acceder a nuestros datos 🙂

Share

 

Me he pasado dias y dias mirando los graficos que publique en la entrada anterior y otros similares, y como no puede ser de otra forma les he sacado mil pegas.

La primera, es de formato, tanto el CSV, como esos png’s que se generan son bastante inmanejables. Archivos de 600 Mg en texto plano con los datos no es precisamente el formato más cómodo, y los png’s de 80 Mg tampoco. Ademas, con todos esos datos procesados, se podían hacer bastante mas cosas si los tuvieramos en un formato adecuado

Así que me he puesto manos a la obra, a intentar buscar otra alternativa. La primera pasar eso a un formato un poco mas manejable, a falta de una opcion mejor, he optado por volcarlo a un SQL, concretamente SQLite (al menos para empezar)

python RTL-db/rtl2sqlite.py 622M-722M-2k-20150726-17\:00\:39.csv 622M-722M-2k-20150726-17\:00\:39.sqlite3

 

Programar no es lo mio, lo reconozco, pero por ahora que funciona. Acabamos de pasar un CSV infernal a una tabla donde poder programar despues las consultas que necesitemos. E

Para que nos hagamos una idea de como afecta, vamos a utilizar como ejemplo una captura de 1h y un Megaherzio

$ ls -lah 93-94-1k-60m*
-rwxrwxrwx 1 ptolomeo ptolomeo 29M ago 1 16:11 93-94-1k-60m.csv
-rwxrwxrwx 1 ptolomeo ptolomeo 121M ago 1 16:13 93-94-1k-60m.sqlite3

Por de pronto a nivel de espacio en disco ya vemos que ocupa unas 4 veces mas. es el precio por tener las cosas un poco mas estructuradas :). Veamos un poco mas de informacion de lo que tenemos dentro

$ sqlite3 93-94-1k-60m.sqlite3
sqlite> .schema
CREATE TABLE freqdata(freq INTEGER, timestamp INTEGER, weight INTEGER,dbm REAL);
sqlite> select COUNT(freq) from freqdata;
3690000
sqlite> select COUNT(distinct(freq)) from freqdata;
1025sqlite> select MIN(freq) from freqdata;
93000000
sqlite> select MAX(freq) from freqdata;
93999997.44
sqlite> select COUNT(distinct(timestamp)) from freqdata;
3600

Es facil de resumir, 1 Mhz de analisis (entre 93M y 94M) separado en 1025 tramos y medido 3600 veces, total casi 3,7 Millones de mediciones.reduced-93-94-1k-60m

Pintandolo de la misma manera que hasta hora con el heatmap.py, nos queda algo así. Coincide como veis con unas emisiones de radio FM sencillitas y que se pueden ver bien.

La verda es que estuve mirando el codigo fuente del heatmap.py para ver si lo podia adaptar a obtener los datos del sqlite y tuve que desistir. Sinceramente, pintar unos datos bien estructurados no debía ser tan dificil.

ASí que la segunda parte del ejercicio ha consistido en precisamente eso, extraccion de los datos del SQL y representacion grafica.

Para eso vamos a tirar de nuevo de python y de una gran libreria cientifica que es el matplotlib, tiene una cantidad ingente de representaciones graficas y de posibilidades de calculo.

Contando que tenemos un array completo y sus valores, simplemente hay que alimentarlo tal cual a una de sus opciones gráficas. Tengo bastante dudas en cuanto al rendimiento viendo lo rapido que crecen los archivos,  pero por ahora el resultado parece bastante razonable.

RTLSQL-93-94-1k-60m

¿Que os parece? Tengo que ver bien como poner las etiquetas de los ejes. Ahora lo siguiente es ver si aprovechando que tenemsos los datos, podemos procesarlos de manera un poco mas seria. Pero eso ya sera en la siguiente entrega 🙂

Share

Lo confieso. Siempre he intentado ampliar mis conocimientos y dedicarme a la observacion y la investigacion. Pero a pesar de mis esfuerzos hay areas en las que estoy absolutamente pez.

Como la gente ademas conoce mi inquietud al respecto, aprovechando el lanzamiento del blog un amigo me propuso adentrarme en uno de esos oceanos inexplorados para mi y que ademas fuera contando mis aventuras aqui. De este modo, y para no postergarlo mas, alla voy, a ver lo que soy capaz de aprender y descubrir en las comnicaciones por radio y el mundo de las ondas.

Para ello, me han prometido irme facilitando algunas herramientas que me vayan permitiendo avanzar en el camino.IMG_2399_B

La primera ha sido por duplicado, un par de receptores de television USB. Conocia su existencia pero ahora me tocaba pegarme un poco con ellos. La gracia que tienen es que por un modico precio (alrededor de 20-30 €) tienes un dispositivo de recepcion con muchas mas posibilidades aparte de ver el futbol. El nombre formal creo que es SDR (Software Defined Radio) porque le puedes configurar la frecuencia que quieres sintonizar y procesar digitalmente la señal recibida. Dependiendo del modelo exacto las capacidades y el chip exacto pueden variar un poco. Vamos a ver que descubrimos de estos. Esto es lo que me suelta el dmesg con el mas pequeño de ellos.

[ 9259.272693] usb 1-1.1: Product: RTL2838UHIDIR
[ 9259.272696] usb 1-1.1: Manufacturer: Realtek

Afortunadamente a nivel de software la Kali ya viene muy preparada para jugar con estos dispositivos. Empezare por las dos piezas que me han recomendado: rtl-sdr y gqrx-sdr

Se supone que con las herramientas de lineas de comandos del pack rtl-sdr podre hacer ciertas prebas (verificar que funciona, escuchar la radio, grabar una frecuencia a un fichero, etc..) y que gqrx es la herramienta basica sencilla y visual para explorar un poco el espectro.

Lo primero es verificar que el sistema reconoce el dispositivo, y la primera respuesta es NO.

# rtl_test
Found 1 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000001Using device 0: Generic RTL2832U OEMKernel driver is active, or device is claimed by second instance of librtlsdr.
In the first case, please either detach or blacklist the kernel module
(dvb_usb_rtl28xxu), or enable automatic detaching at compile time.usb_claim_interface error -6
Failed to open rtlsdr device #0.

 

Afortunadamente Google tiene todas las respuestas, el propio kernel lo ha reconocido como un dispositivo de television y nos esta bloqueando el acceso. Asi que toca eliminar el modulo y ya tengo acceso.

~# rmmod dvb_usb_rtl28xxu
~# rtl_test
Found 1 device(s):
0: Realtek, RTL2838UHIDIR, SN: 00000001Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
Sampling at 2048000 S/s.Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.Reading samples in async mode…
^CSignal caught, exiting!User cancel, exiting…
Samples per million lost (minimum): 0

Ahora ya lo detecta adecuadamente y hemos averiguado el chipset que tiene. Lo siguiente es ver si podemos escuchar la radio con ello… Para ello me busco cual es la frecuencia en cualquier radio o web y lo pongo con el programa rtl_fm … esto nos dara los datos sintonizados, pero para convertirlo a audio y que suene hay que pasarlo por un reproduztor. Tras varias pruebas, el comando queda así:

rtl_fm -f 96.3e6 -M wbfm -s 200000 -r 48000 - | aplay -r 48k -f S16_LE

Por cierto, que al receptor he tenido que enchufarle la antena, porque si no, no sintoniza nada y aun así con bastante ruido. Me temo que este sera el primer encontronazo de muchos otros en la importancia de las antenas :/

La siguiente herramienta en pasar por mis manos en el GQRX. Es un interfaz grafico para sintonizar el dispositivo, ver la intensidad de la señal e intentar algunos ejemplos basicos de demodulacion (AM, FM, etc). Sintonizando en las misma zona de frecencia que antes, es posible nuevamente escuchar la radio y ahí si, apreciar la poca calidad de la señal que recibimos. Para hacernos una idea, aqui os dejo dos capturas, una sin antena y otra con ella. Y eso que es la cutre super sencilla que venia con el receptor.

GQRX sin Antena

GQRX sin Antena

GQRX con Antena

GQRX con Antena

Tengo que reconocer que despues me he puesto a cotillear un poco por el espectro y despues de perder unas cuantas horas he llegado a una conclusion clara… no me entero de nada. Asi que volvi a recurrir a mi amigo a ver si me daba alguna pista de donde habia alguna onda interesante y que era todo aquello que había visto. No voy a reproducir literalmente su respuesta, pero basicamente me volvi con las manos vacias dandole vueltas a que podía hacer para tener una vision global de lo que  hay en el espectro de ondas madrileño sin dejarme los ojos pegado a una pantalla avanzando de megaherzio en megaherzio.

Al final he optado por esta solucion, y la verdad es que ya os adelanto que estoy muy satisfecho. Se basa en el comando rtl-power que viene en el paquete rtl-sdr. A ese programa le podemos pasar un rango de frecuencias y unos tiempos de muestreo y total y te genera un archivo “crudo” en formato csv con las potencias de emision observadas en cada uno. Estupendo detalle pero inmanejable por si mismo. Para completarlo ya hay alguien que se ha currado una manera de visualizarlo en formato heatmap.

Para hacerlo nos tenemos que clonar el repositorio lo primero y luego alimentarlo con un fichero.

git clone https://github.com/keenerd/rtl-sdr-misc.git

El comando que estoy usando para capturar los datos es el siguiente:

rtl_power -c 0.3 -f 88M:188M:2k -e 3h captured-sample.csv

Basicamente lo que le estamos pidiendo es que durante 3 horas barra el rango de los 88 a los 188 Mhz en saltos de 2k y cada vez, descarte un 30% de las lecturas por los extremos (sin ello se veia que en esa zona la sensibilidad era mucho mas baja y salian unas estupendas bandas negras verticales). Con ello obtenemos un estupendo csv de unos 600 Mg. Este a su vez lo procesaremos con el heatmap.py que nos acabamos de bajar

python heatmap.py captured-sample.csv captured-sample.png

Que nos dara algo así pero bastante más grande. En la primera pueden verse un par de canales de FM y en la segunda algun tipo de comunicacion intermitente (ya investigare)

heatmap-sample2

Heatmap-sample1

Al final lo que he preparado un sencillo script para barrer el espectro de 100 en 100 Mghz y generar el grafiquito así como un pequeño thumbnail. Aqui os dejo unos cuantos, ojo con ellos que ocupan unos 80 Mg cada uno.

88-188Mhz resized-88M-188M-2k-20150717-20_38_10

188-288 resized-188M-288M-2k-20150718-09_10_22

288-388 resized-288M-388M-2k-20150718-13_07_41
388-488 resized-388M-488M-2k-20150718-16_07_45

488-588 resized-488M-588M-2k-20150718-19_07_49

588-688 resized-588M-688M-2k-20150718-22_07_52

688-788 resized-688M-788M-2k-20150719-01_07_58

788-888 resized-788M-888M-2k-20150719-04_08_01

888-988 resized-888M-988M-2k-20150719-07_08_04

Ahora ya puedo explorarlos a ratos e ir viendo lo que me va llamando la atencion. Ya os ire contando mis desventuras mientras sigo mis observaciones. Eso si, por de pronto se puede ver que el aparato se vuelve totalmente sordo pasadas ciertas frecuencias. A ver si puedo a ir arrojando luz sobre lo que va apareciendo ahi

¿Alguien se anima a acompañarme en mis observaciones?