martes, 14 de septiembre de 2010

SniperlCat 0.2, detección de SYN scan's

Actualización: por algun extraño motivo se vuelve paranoico con los paquetes cuando se suspende el ordenador y se vuelve a iniciar (¿?), estoy trabajando para resolver eso.

Hoy traigo la segunda versión del SniperlCat [SniperlCat 0.2], los cambios no son muchos, pero creo que pueden resultar interesantes:

- Detecta los paquetes SYN de sockets raw (típicos de un SYN scan), aunque para esto necesita permisos de root para levantar un sniffer, básicamente se aprovecha esta [http://danielmiessler.com/study/synpackets/] idea, aunque con scanners modernos se puede hacer que no exista diferencia, unicamente avisa de paquetes con un tamaño menor de 60 bytes (suelen ser de 58) y sin el flag DF de IP activado.

- Permite llevar un log aparte de las notificaciones... no es gran cosa pero puede ser útil.

- Las alertas se reunieron en una función llamada "show_alert" para poder modificar el sistema más facilmente.

Las dependencias quedarían en "libgtk2-notify-perl" para las notificaciones, y "libnet-pcap-perl" y "libnetpacket-perl" para buscar paquetes sospechosos.

Y la sintaxis del comando sería:

Sniperlcat 0.2

sniperlcat [-h]|[-d | -v ] [-nf] [-c] [-n <red>] [-f <descriptor de red>] [-p|-np] [-dv <interfaz>][-l <log>][-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, aún 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
-dv (--device): Especifica la interfaz de red que se monitoreará
-p  (--privileged): Se asumirán que es un usuario con privilegios
-np (--no-privileged): Se asumirán que es un usuario sin privilegios
-l  (--log): Se guardarán los avisos en un archivo
-s  (--sleep): Especifica el tiempo en segundos de "descanso" entre iteraciones (por defecto 60)


Eso es todo, otro día... más.

[Referencias]
http://seclists.org/pen-test/2007/Oct/44
http://www.perlmonks.org/index.pl?node_id=170648
http://search.cpan.org/~saper/Net-Pcap-0.16/Pcap.pm

martes, 7 de septiembre de 2010

Script para hacer animaciones con CFDG

Hoy traigo un script que genera automaticamente un conjunto de imágenes con CFDG [cfanim.pl].
 Lo que hace es partir de un archivo de este programa, partiendo de un nivel de recursividad pequeño y avanzando, por ejemplo, partiendo del archivo:

startshape init

rule init{
     spiral{sat 1 b 0.8}
}

rule spiral{
     SQUARE{}
     spiral{x 1 r 1 hue 1 s 0.999}
}



Se pueden obtener las imágenes desde el primer nivel de recursividad, hasta, digamos... el 300


./cfanim.pl base.cfdg -i 1 -f 300


Nota: Es importante no partir del 0, porque se utilizaría en esa imágen el nivel de recursividad normal, no el especificado.

Con ese comando obtendríamos 300 imágenes individiales, pero si además queremos juntarlas para convertirlas en un .gif, se haría:

./cfanim.pl base.cfdg -i 1 -f 300 -m animacion.gif



La sintaxis del script es:

./cfanim.pl <archivo.cfdg> -i <figuras iniciales> -f <figuras finales> [-s <step>] [-m <output.gif> [-d <delay>]]


Por ejemplo, en el ejemplo anterior haciendo un gif de los 1000 primeros frames con 1 centésima de segundo entre cada una se haría:


./cfanim.pl base.cfdg -i 1 -f 1000 -m animacion.gif -d 1



Y eso es todo, hasta otra.

Introducción a Structure Synth (y III), el regreso

Gracias a Vishkey, descubrí hace un tiempo que las posibilidades que brinda Structure Synth van más allá de lo mencionado anteriormente, pues resulta que también soporta texturas más complejas, siempre partiendo de las mismas figuras básicas, cuales son dependen de la plantilla usada para exportar, como la plantilla "Sunflow-Ultimate-Groovelock", que como se encuentra entre las que están por defecto, servirá de ejemplo.

La sintaxis es la siguiente:

<figura base>::<textura>



Así, si queremos hacer una esfera con una textura de cristal ("glass"), haremos


sphere::glass



Este ejemplo muestra brevemente como se ven las texturas

set background black
{color white x -0.50005 s 0.001 1000 1000}box::ao // Base
{color white }sphere::glass
{color white x 10 s 0.5 1000 1000}box::shiny // Luz/techo
{ color blue y -2 }sphere::diffuse
{ color white y -4 } sphere::mirror
{color red y -6 } sphere::ao
{color black y -8 }sphere::constant
{color white y -10} sphere::phong
{color white y -12} sphere::ward



De izquierda a derecha, las texturas "glass" en blanco, "diffuse" en azul,"mirror" en blanco,"ao" en rojo,"constant" en negro,"phong" y "ward" en blanco. Además hay una caja que sirve de suelo (con una textura "ao" en blanco) y otra que ilumina la escena (con una textura "shiny" también en blanco).

Este otro ejemplo, (escrito por Vishkey) muestra más claramente las posibilidades que hay

//Autor: Vishkey

{s 2} room

esferas

rule room {
{color brown}pared
{z 20} paredLuminosa
{rx 90 z 10 y 10 color green} pared
{rx 90 z -10 y 10 color blue} pared
{ry 90 z 10 x -10 color yellow} paredEspejo
{ry 90 z -10 x -10 color white} paredEspejo
}

rule esferas {
{s 2 z 1 x 2 color white} sphere::glass
{s 2 z 1 x 1 y 1 color white} sphere::mirror
{s 2 z 1 x 1 y -1 color blue} sphere::phong
{s 2 z 1 x 2 y 2 color green} sphere::ao
{s 2 z 1 x 2 y -2 color yellow} sphere::constant
{s 2 z 1 x 1 y -3} sphere::diffuse
{s 2 z 1 x 2 y -4} sphere::shiny
{s 2 z 1 x -2 y -3 color white} box::ward
{s 2 z 1 x -3 y -2 color white} box::ao
{s 2 z 1 x -2 y -1 color white} box::phong
{s 2 z 1 x -3 color white} box::glass
}

rule pared {
{s 20 20 1} box
}

rule paredLuminosa {
{s 20 20 1} box::shiny
}

rule paredEspejo {
{s 20 20 1} box::mirror
}





Como se puede ver, el resultado es una delicia para los ojos aun con pocos elementos... aunque quizá demasiado perfecto =).
Por último añadir que la plantilla usada "Ultimate-Groovelock" añade algunas luces por su cuenta (se aprecia en algunos reflejos), en caso de querer tener un control total de la imágen estas se podrían eliminar buscando las secciones light adecuadas de la plantilla y eliminándolas o cerrando la escena con cajas... es elección de cada uno.

Hasta otra.

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 :)}