Saltar ó contido principal

Como monitorear un terminal desde otro [tip]

En el terminal que se quiere monitorear mkfifo tunel

script -q -f tunel

En el terminal donde se quiere mostrar ( se podría enviar a través de la red o lo que fuera ) cat tunel

Una ventaja (o un inconveniente) es que el que monitorea no puede hacer cambios en el terminal. Por otro lado, si se hace esto, el comando script no devuelve el control hasta que alguien se conecte.

ps: si solo quisieramos guardar las sesiones, sin monitorearlas, solo habría que hacer script -f

A portarse bien ;)

Blogueando en tres idiomas|Blogging in three languages|Blogueando en tres idiomas

Desde ahora intentaré escribir el blog en 3 lenguages: castellano, inglés y gallego.

El primero por que es el que vengo usando en él, y funciona bastante bien, inglés por ser la lingua franca en estos temas, y el gallego porque hecho en falta un blog sobre computación en ese idioma,.

Este post ya está en los tres lenguajes (de hecho es sobretodo una excusa para poder probar el plugin :P).

From now on, I'll try to write the blog in 3 languages: spanish, english and galician. The first one because is in which the blog was already being written, and working pretty well, english for being the lingua franca in technology, and galician because I miss a computing blog in that language.

This post is already written in the three languages(the fact is that it's above all an excuse to test the plugin :P).

Desde agora intentarei escribi-lo blogue en 3 linguaxes: castelán, inglés e galego.

O primeiro por ser o que veño usando nel, e funciona bastante ben, ingles por ser a lingua franca nestos temas, e o galego por que boto en falta un blogue sobre computación neste idioma.

Este post xa está escrito nas tres linguaxes (de feito é sobretodo unha excusa para probar o plugin :P).

Rompiendo captchas animados [post-relampago]

La historia es así, ayer un colega me "medio retó" a saltarme el_captcha_de linksave.in, con la particularidad de que es un gif animado, el detalle es que realmente esto no le confiere gran seguridad, por ejemplo este script puede eliminar eso rápidamente [ unmask.py ], he aquí unas pruebas:

Original Después de pasar el script

Se podría hacer una máscara que al final pusiese en blanco los píxeles que no se escribieron, pero creo que queda clara la idea :P

Nueva versión de GUIml, añadido Tktinter

Pues eso, que ya está listo el soporte para Tkinter en GUIml:

Desluce un poco al lado de los otros,¿verdad? 

Solo resaltar una cosa, da "X Window System error" cuando las ventanas de "About" no se cierran antes que el programa principal ( no pongais about's y todos contentos ), esto se arreglará cuando sepa que lo provoca.

Se puede descargar desde aquí: guiml02.zip

ps: está en camino una batería de nuevas versiones, stay tuned

Hasta pronto.

Escaneando un servidor FTP

Para hacer una araña que explore un servidor FTP se puede aprovechar el_ftplib de_python... solo tiene un impedimento, que cuando se pide la lista de archivos en un directorio se devuelve por stdout, lo que es bastante molesto para algo como esto.

La solución más sencilla es substituir la salida estándar ( sys.stdout ) por un objeto que almacene los datos, el único método que hace falta en el objeto es objeto.write(string) , el que se usa para mostrar strings por la pantalla, esto puede servir:

class catcher():

def clean(self):

  self.trap = ""

def readlines(self):

  return self.trap.split("\n")

def readline(self):

  l = self.readlines()

  res = l.pop(0)

  self.trap = "\n".join(l).strip()

  return res

def init(self):

  self.clean()

def write(self, s):

  self.trap += s

Después de dar el cambiazo por stdout y  de que recoja los string, este queda en catcher.trap, además se pueden utilizar los siguientes métodos:

catcher.readlines() Devuelve lo recojido como un array de strings (una por línea).

catcher.readline() Devuelve una línea de lo recojido y la elimina.

catcher.clean() Elimina lo recojido

Después hace falta convertir las líneas en algo útil, esto se puede hacer con:

import sys, re

Elimina los dobles espacios

def smash(s):

b = ""

while b != s:

   b = s

   s = s.replace("  ", " ")

return s

Convierte las líneas de ls en algo útil

def parseLs(sa, cdir = None):

d = []

cd = (cdir != None)

for s in sa: # Por cada línea

   s = smash(s.strip()) # Se elimina lo que sobra



   if (len(s) < 1): # Si aún queda algo

       continue



   o = {} # Aquí se guardarán los datos

   sld = s.split(" ") # Se separan por los espacios



   # "Si para solucionar un problema se te ocurre

   # 'esto lo puedo hacer con expresiones regulares!'

   # ...ya tienes dos problemas" -- No me acuerdo xD

   if (re.match(".{10}\ [0-9]{1,9}\ [a-z,A-Z,0-9]{1,50}\ " +

       "[a-z,A-Z,0-9]{1,50}\ [0-9]{1,1000}\ [a-z,A-Z,0-9]{3}\ " +

       "[0-9]{2}\ [0-9]{2}\:[0-9]{2}\ .{1,255}", s) != None):



       # Lee la información

       if (len(sld) < 5) or not(":" in s):

           print >>sys.stderr, "-|>", s

           continue



       o['perm' ] = sld[0]

       o['num'  ] = sld[1]

       o['user' ] = sld[2]

       o['group'] = sld[3]

       o['size' ] = sld[4]

       o['mon'  ] = sld[5]

       o['day'  ] = sld[6]

       o['hour' ] = sld[7]



       if (cd):

           o['pwd'] = cdir



       n = s.index(":")

       # Obtiene el resto y se guarda como el nombre

       o['name' ] = s[ (s[n : ].index(" ") + n + 1) : ].strip()

       d.append(o) # Se añade a la lista



   # Otra opción de formateado

   elif(re.match(".{10}\ [0-9]{1,9}\ [a-z,A-Z,0-9]{1,50}\ " +

        "[a-z,A-Z,0-9]{1,50}\ [0-9]{1,1000}\ [a-z,A-Z,0-9]{3}\ " +

        "[0-9]{2}\ [0-9]{4}\ .{1,255}",s) != None):



       # Lo mismo

       o['perm' ] = sld[0]

       l = len(sld[0])

       o['num'  ] = sld[1]

       l += len(sld[1])

       o['user' ] = sld[2]

       l += len(sld[2])

       o['group'] = sld[3]

       l += len(sld[3])

       o['size' ] = sld[4]

       l += len(sld[4])

       o['mon'  ] = sld[5]

       l += len(sld[5])

       o['year' ] = sld[6]

       l += len(sld[6])

       o['name' ] = s[ s[ 7 + l : ].index(" ") + 8 + l : ]



       if (cd):

           o['pwd'] = cdir



       d.append(o) # Se añade a la lista



   # Si falla

   else:

       print >>sys.stderr, "--->", s, "<---"

       raw_input("")

return d

Solo hay que alimentar la función parseLs con el array de líneas (desde catcher.readlines() por ejemplo) y opcionalmente con el directorio actual (solo se añade como parámetro) y devuelve un array de diccionarios con al menos las entradas 'perm' (permisos), 'num', 'user', 'group', 'size' y 'mon' (mes).

Nota: parseLs() funciona con los formateados que me he encontrado, que seguramente no sean todos.

A partir de ahí el resto es parecido a una araña normal, por ejemplo [ ftp_crawler.py ], si quieres guardar los datos en un PostgreSQL, hay que descomentar las líneas 8, 41 (aquí esta la query, el nombre de la tabla es nu, cambiala por la que quieras) a 45 y 124 (en esta se define el nombre de la base de datos). La tabla usa estas columnas: 'permisos', 'numero', 'usuario', 'grupo', 'tamanho', 'path'  (varchar y pista)

Nos vemos

[Referencia] http://docs.python.org/library/ftplib.html

Un tracker BitTorrent en un .php y una tabla MySQL

Esto lleva un rato sin actualizar, así que traigo una cosilla que puede resultar interesante, un tracker de BitTorrent que solo ocupa un archivo .php de 250 líneas y que necesita únicamente una tabla en una base de datos MySQL, además logicamente del servidor web [ announce.php ]

Para montar el tracker hay que subirlo con el nombre announce.php al directorio raíz, de forma que quede algo así: http://www.miservidor.com/announce.php y modificar estas variables:

* $dbhost: La dirección del servidor MySQL.

* $dbuser: El usuario del servidor MySQL.

* $dbpass: La contraseña del servidor MySQL.

* $dbname: La base de datos que se utilizará.
*
* $dbtable: El nombre de la tabla.
*

La estructura de la tabla es esta

* Columnas:

  • Peer_id: char(28)
  • info_hash: char(28)
  • port: smallint unsigned
  • uploaded: int(1)
  • downloaded: int(1)
  • to_go: int(1)
  • ip: varchar(15)
  • peer_key: varchar(255)
  • completed: boolean
  • last_update: int(1)
    *

* Claves:

* Peer_id

* info_hash
*

O directamente: create table peers( peer_id char(28), info_hash char(28), port smallint unsigned, uploaded int(1), downloaded int(1), to_go int(1), ip varchar(15), peer_key varchar(255), completed boolean, last_update int(1),KEY (peer_id), KEY (info_hash));

Otros parámetros que pueden ser interesantes:

* $timeout: Tiempo que se mantendrán los datos de los clientes en la base
de datos.

* $default_peer_num: Número de pares que se envían por defecto.

* $max_peer_num: Número máximo de pares que se envían en cada petición.

* $interval: Intervalo de segundos entre peticiones del cliente.
*

Una cosa, el código está pensado para IPv4, si se envían IP's con el nuevo protocolo pueden pasar cosas extrañas, pero no supone un problema de seguridad para el servidor.

Nos vemos, dadle caña y avisad si no funciona que no me fio mucho :P

[Referencias] http://wiki.theory.org/BitTorrent_Tracker_Protocol

Como funciona BitTorrent( 1 ): los archivos *.torrent

El protocolo BitTorrent parece algo muy complejo, algo fuera del alcance de los simples mortales que programamos alguna cosilla de vez en cuando, pero no es así, el protocolo básico es bastante simple, se puede comprobar leyendo la wiki_de_theory.org o leyendo estos posts, la idea de esta mini serie es explicar como funciona el protocolo en 3 secciones:
* Como funcionan los archivos *.torrent
* Como comunicarse con el tracker
* Y como comunicarse con otros clientes

Así que empezamos con los archivos, para las pruebas utilizaremos el de trisquel

Haciendo un iterador a medida en Python

Mientras no van llegando cosas que requiren más tiempo aquí va algo que puede resultar interesante, vamos a hacer nuestro propio iterador dinámico, que permita modificar su comportamiento desde el propio script, por ejemplo, si hacemos: for i in my_iterator(1,1000,"<<1"):

print i

Mostraría esto:

===============================================================================

1 2 4 8 16 32 64 128 256 512

===============================================================================

La idea es bastante simple, necesitamos una clase que sirva de iterador, necesita 2 métodos [ tipos_-_iterador ]: iter(): que devuelve un iterador ( un objeto que tenga el siguiente método ), por pura pereza, en este ejemplo se devolverá a si mismo ( self ) next(): este es el método del iterador, muestra el siguiente valor o levanta StopIteration

Si vamos escribiendo la clase, el iter y init iría así: class my_iterator:

def iter(self):

return self

def init(self, init,end,expr):

self.nextVal=init

self.end =end

self.expr=expr

Y atención que ahora viene el juego de manos!, para interpretar dinámicamente el argumento paso, utilizaremos exec() [ exec ], que se ejecuta en el entorno local, y que permite ejecutar código desde un string:     def next(self):

self.curr = self.nextVal

exec("self.nextVal = "+str(self.curr)+" "+self.expr)

if (self.curr != None)and( self.curr < self.end ):

return self.curr

else:

raise StopIteration

Mete el valor actual en self.curr (valor que se devolverá) y asigna self.nextVal al siguiente valor( en ese exec está el truco ).

Y eso es todo, saludos

Como evitar que un hilo de pyGTK bloquee a los demás [ tip ]

Si alguien ha intentado programar un script que use pyGTK lanzándolo en un hilo aparte se habrá dado cuenta de que bloquea  a todo el proceso, lo que es bastante molesto. La solución es hacer esto desde ese hilo antes de levantar la interfaz: gtk.gdk.threads_init()

Hay más sobre hilos y pyGTK ( esto en concreto no ) en: http:// unpythonic.blogspot.com/2007/08/using-threads-in-pygtk.html

Saludos

Adivinando las contraseñas de la Wifi desde Android

Después de mucho pelearse con Netbeans y Eclipse, presento la primera aplicación para móviles de este blog :D, una que a partir de la SSID ( el nombre de la red ) y la BSSID puede en algunos casos "adivinar" la clave por defecto de la red:

La aplicación aún está en pañales, no he tenido la ocasión de probarla con redes reales, de ahí que exista la opción de introducir datos manualmente ( obviamente la forma normal de hacerlo es seleccionar la red en la lista que muestra ) , para realizar pruebas, y falta por implementar el algoritmo de las redes SpeedTouch ( aunque es bastante lento, ya que hay que hacer fuerza bruta contra SHA ).

Otra cosa que queda por acabar, es la lista de redes, por ahora se marcan las que se pueden adivinar con un "[o]" al final, o con la contraseña entre '[]' si se adivinó, además los datos sobre las redes adivinadas se guardan en una Base de Datos SQLite que está desaprovechada ( quizá se podría añadir la opción de guardar todo en un TXT para guardarlo ).

El archivo de instalación se puede descargar de aquí [ DroidCrack.apk ], y el código de aquí [DroidCrack_src.zip ] y las redes que puede "adivinar" son:

  • WLAN_XXXX
  • JAZZTEL_XXX
  • DLINK-WIRELESS
  • PXXXXXXXXX

( La próxima también podrá con SpeedTouch :P )

Y no se me ocurre nada más...

ps: Si alguien sabe como hacer que al instalar no pida permiso para "Leer llamadas telefónicas", que hable ahora o que lo haga después... pero que no se lo guarde que mosquea un rato que algo que no lo necesita tenga permisos para eso, parece que es un troyano xD

Hasta otra