domingo, 28 de febrero de 2010

Peligros en el e-Mail

Hoy vamos a ver uno de los "peligros" del correo electronico, y no, no me refiero a el malware, ni al spam ni a nada asi (aunque lleva tanto tiempo ahi como ellos, o aun mas) , sino a algo que incluso se utiliza en correos legitimos (o al menos eso parecen)

Esto es, los correos con HTML

En un principio se podria pensar que esto no tiene nada de malo, se usa HTML en paginas web y no hay ningun problema, ¿verdad?... el problema esta en que se puede utilizar para obtener informacion que no suele ser bueno hacer publica, como la direccion IP utilizada

Veamos como funciona:

Mandamos un correo electronico a una direccion... usuario@example.org , cuando se abra el correo se mostrara el contenido en HTML (a menos que se configure el cliente de correo para que no lo haga) y al mostrar una imagen (por ejemplo), el cliente se conecta al servidor donde esta la imagen, que puede capturar informacion interesante del cliente como la IP, el navegador/cliente utilizado, etc...

Vamos alla, para esto usamos dos archivos, uno PHP (o lo que se utilize en el servidor web que se va a utilizar) y una imagen (o cualquier cosa que haga que el cliente se comunique con nuestro servidor, la imagen es lo mas sencillo y encaja perfectamente en un correo)

El archivo PHP solo tiene que hacer una cosa, guardar los datos del cliente y mandarle la imagen, un ejemplo seria:

<?php
$fname="log.txt"; // archivo donde se guardan los logs

$f=fopen("$fname","a"); // Abrimos el archivo y lo preparamos
// para seguir escribiendo
fwrite($f,"IP: ".$_SERVER['REMOTE_ADDR']."\n"); // Guardamos la IP del cliente
fwrite($f,"Navegador: ".$_SERVER['HTTP_USER_AGENT']."\n"); // y tambien la
//informacion del cliente
fwrite($f,"---------------------\n"); // Para hacer el archivo mas facil de leer
fclose($f);
// Imagen a mostrar
$img="esfera.png";
// Redireccionamos al cliente a la imagen
header("Location: $img");
?>
Como se puede ver, el codigo es bastante simple, abrir un archivo, escribir un par de variables interesantes (en este caso, la IP y el cliente), y redireccionar el cliente a la imagen, se podria hacer que lea la imagen y la envie al cliente, que seria una solucion mas fiable (si alguien sigue la direccion de la imagen se dara cuenta del truco)

Y ya esta, le enviamos el correo a alguien y...

El primero es abriendolo con el Thunderbird (como se puede ver en Navegador), y la segunda con un webmail (el navegador es Firefox)
Y ya tenemos la IP de a quien se le envio el correo

La siguiente vuelta de tuerca es hacer que en los logs tambien aparezcan las direcciones asociadas a cada IP, solo hay que añadir otra variable

<?php
$fname="log.txt"; // archivo donde se guardan los logs

$f=fopen("$fname","a"); // Abrimos el archivo y lo preparamos
// para seguir escribiendo
fwrite($f,"Direccion: ".$_REQUEST['mail']."\n");
fwrite($f,"IP: ".$_SERVER['REMOTE_ADDR']."\n"); // Guardamos la IP del cliente
fwrite($f,"Navegador: ".$_SERVER['HTTP_USER_AGENT']."\n"); // y tambien la
//informacion del cliente
fwrite($f,"---------------------\n"); // Para hacer el archivo mas facil de leer
fclose($f);
// Imagen a mostrar
$img="esfera.png";
// Redireccionamos al cliente a la imagen
header("Location: $img");
?>

Ahora ademas no se puede simplemente usar la imagen como antes (simplemente indicando su URL) ahora ademas hay que añadir ?mail=usuario@correo.aaa, por ejemplo, para mandarselo a "joe@gmail.com", utilizando la imagen http://aaa.com/imagen.php, habria que indicar http://aaa.com/imagen.php?mail=joe@gmail.com en la direccion de la imagen, el resultado es este:


Y en los dos casos el email parece completamente inofensivo:

 Si, vale, no hay texto y la imagen que envie es de otro post, pero para mostrar la idea sirve

Tambien esta la opcion de incluir una imagen que solo tenga un pixel y que ademas es 100% transparente, asi que no se puede ver sin comprobar el codigo del mensaje

La solucion

La forma mas facil de evitar el problema (aparte de no abrir correos que no sean fiables) es deshabilitar el HTML en el cliente de correo (o en el webmail), Thunderbird, por ejemplo, pide confirmacion para leer HTML por defecto

Hasta otra!!

martes, 23 de febrero de 2010

Sockets multiplataforma

Un aperitivo mientras preparo algo mas interesante ;)}

Si alguien intento hacer un programa multiplataforma que hiciera uso de sockets se daria cuenta de que la unica diferencia en el manejo de estos entre Windows y los SO's basados en Unix es que el primero tiene una funcion adicional que hay que llamar para poder crear sockets, y otra para cuando se termine con su uso, y que se utilizan tipos de datos distintos (SOCKET en Windows y simplemente int en Unix).

Arreglar ese problema es sencillo, con un par de macros se soluciona el problema, aun asi, si prefieres evitar el trabajo de escribir el codigo, aqui lo tienes o descargalo de aqui [socket_wrapper] :


// -----------------------------------------------------------------
// Socket wrapper (aun que no estoy seguro de si se puede llamar asi)
#ifndef SOCKET_WRAPPER_H
  #define SOCKET_WRAPPER_H
  #ifdef _WIN32
    #include <winsock.h>
    #include <windows.h>
    #define tsocket SOCKET
    #define socket_init() WSADATA wsaData;\
                          WSAStartup(MAKEWORD(1,1),&wsaData);
    #define socket_end() WSACleanup();
  #else
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/select.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #define tsocket int
    #define socket_init()
    #define socket_end()
  #endif
#endif
// Socket wrapper end
// En windows es necesario compilarlo con -lwsock32
//  (para linkarlo a winsock)
// -----------------------------------------------------------------

Se usa como en Unix, pero el tipo de dato de los socket es tsocket y antes y despues de usar los socket hay que llamar a socket_init() y socket_end() respectivamente (en Unix no hara nada,pero en Windows llamara a las funciones necesarias).


Hasta otra

pd: No me olvide de SSHFS y las VPN

lunes, 8 de febrero de 2010

SSH: Conexiones seguras para tod@s


Seguramente muchos conozcais telnet, una forma de conseguir una consola de comandos en un ordenador remoto, igualmente muchos sabreis que es inseguro por que va "en plano" por la red (un ordenador cualquiera de la red podria ver lo que pasa en el pc remoto, secuestrar la sesion o incluso capturar las contraseñas), por eso desde hace unos años (desde el 99) se utiliza SSH (secure shell), que utiliza conexiones seguras, peroo... sabiais que ademas de utilizarlo como una consola de comandos se puede utilizar para:

  • Transferencias de archivos al estilo FTP
  • Copia de archivos en red
  • Cifrar casi cualquier tipo de conexion (todo lo que se pueda a traves de SOCKS: web, correo, mensajeria instantanea,... )
  •  Acceder a sistemas de archivos remotos como si fuesen locales (SSHFS)
  • VPN (aunque mientras se escribe esto solo es posible con el cliente y el servidor de OpenSSH)
Y todo esto sin dejar de lado la seguridad...

Para las pruebas se utilizo un servidor OpenSSH_5.3p1 y un cliente OpenSSH, el servidor puede necesitar alguna configuracion, pero la mayoria de las veces las distros/flavours ya lo traen listo para usar, ademas algunas cosas solo se pueden hacer con este servidor en concreto (OpenSSH)


Para intentar hacer todo mas claro, los comandos usaran este tipo de letra, lo que vaya etiquetado <asi> es una campo ( por ejemplo <direccion del servidor> podria ser ssh.pruebas.com o 192.168.1.17 ), por ultimo lo que va entre ´[´ y ´]´ es opcional (se usa, entre otras cosas, para activar opciones adicionales)

Empezando por lo basico:

Para abrir una consola de comandos en el servidor se utilizara el siguiente comando:

ssh [<usuario>@]<servidor> [-p <puerto>]

La parte de <usuario>@ solo es necesaria si se va a usar un usuario distinto al de la maquina local, y  -p <puerto> se usa para acceder por un puerto no estandar (que es el 22).

Este es un ejemplo posible:
Desde el pc 'vBox' el usuario 'kenkeiras' hace ssh al servidor 'sleepless' (ssh sleepless), aqui en vez de haber utilizado el nombre del servidor se puede utilizar su ip... si es la primera vez que se conecta a este servidor se pedira al usuario que confirme que el fingerprint de la clave del servidor coincida con la real (para evitar que se produzca un ataque Man-in-the-middle, por ejemplo)

Y despues la ejecucion seguiria como antes, pide la contraseña y abre la sesion del usuario.

Este comando (ssh sleepless) es el mismo que ssh $USERNAME@sleepless -p 22 ya que se presupone que el usuario va a ser el mismo en el servidor que en el pc local y que el puerto va a ser el estandar (el 22).

Manejando archivos:


Transferencia de archivos por SFTP (Secure File Transfer Protocol, Protocolo Seguro de Transferencia de Archivos) :

El uso de sftp es bastante sencillo, el comando de inicio es como el de ssh:
sftp [<usuario>@]servidor [-oPort=<puerto>]
La unica diferencia es que para especificar un puerto diferente (el estandar sigue siendo 22, todo funciona a traves de ssh) se utiliza -oPort , en vez de -p

Se utliza como un cliente ftp normal, pero siempre se usa binary para las transferencias (para los que no lo entiendan, esto ultimo da igual)

Por ejemplo:

Los comandos basicos son:

  • cd <directorio>: Cambia al directorio especificado
  • put <archivo local> [<archivo remoto>]: Envia un archivo 'archivo local' al servidor (si no se especifica el 'archivo remoto' se utilizara como nombre el de 'archivo local')
  • get <archivo remoto> [<archivo local>]: Envia del servidor el 'archivo remoto' al pc local (si no se especifica el 'archivo local' se utiliza como nombre el de 'archivo remoto')
  • mkdir <directorio>: Crea un directorio en el servidor
  • ls [<ruta>]: Muestra los contenidos del directorio actual (o si se especifica una ruta, de esa)
  • rm <archivo>: Elimina el archivo 'archivo'
  • rmdir <directorio>: Elimina el directorio 'directorio'
  • exit: Salir
  • !: Volver a la consola del pc local (cuando se salga de la consola se volvera a el SFTP)

SCP (Secure Copy, Copia Segura):


El comando basico de scp es el siguiente scp [[<usuario>@]<servidor>:]<archivo origen> [[<usuario>@]<servidor>:]<archivo destino 1> [ [[<usuario>@]<servidor>:]<archivo destino 2> ... ]

Es decir, el comando es scp y en cada opcion se utiliza la siguiente notacion para definir un archivo:

    [[<usuario>@]<servidor>:]<archivo> Si el archivo esta (o se va a copiar) a otro pc, se escribe <servidor> :  <archivo> , si el archivo es local, solo el nombre del archivo, y si el archivo esta en otro pc, pero se accede a traves de otro usuario, <usuario> @ <servidor> : <archivo>

El primer archivo es el que se va a copiar y los demas es a donde se va a copiar, por ejemplo:
Aqui se copia un archivo ('example') del servidor 'sleepless', a el archivo local 'example'.
Las opciones son parecidas a la del programa cp de unix, por ejemplo permite copiar directiorios enteros:

Cifrando conexiones:

Si conoces el protocolo SOCKS sabras que sirve para hacer servidores proxy y clientes para cualquier protocolo que funcione sobre TCP/IP (con SOCKS5 tambien sobre UDP/IP, pero en este caso concreto no), ssh permite utilizarlo para cifrar conexiones entre el cliente y el servidor, para proteger los datos en la red que hay entre los dos (y que puede ser insegura), la idea es algo asi:


[Cliente SSH] ~~~~~~~~~> [Servidor SSH] --------------> [Destino]
                        Red insegura                       Red segura
                          (Cifrado)                            (sin cifrar)

Esto sirve por ejemplo para un portatil que esta conectado a una wifi y que tiene (ya dentro de la red con cable, protegida, ...) un servidor SSH, se tunelan los paquetes hasta el servidor (a la aplicacion lo trata como un simple proxy SOCKS), donde ya no es posible un ataque tan sencillo como usar un sniffer en una red WEP.
Para hacer esto usaremos  ssh -D [<ip de enlace>:]<puerto de enlace>   [<usuario>@]< servidor> [-p <puerto para ssh>]

Como se puede ver es igual que un comando ssh con la diferencia de que se añade -D [<ip de enlace>:]<puerto de enlace>

La opcion -D significa que el tunelado sera dinamico (hay otras opciones que usan tunelado estatico, siempre al mismo pc y en el mismo puerto), sobre SOCKS.
La ip del enlace es opcional y sirve para concretar que interfaz de red se va a utilizar para la conexion, si no se especifica (o se usa un '*') cualquier pc en la red podra utilizar el tunel (esto puede ser util o no, dependiendo de las circunstancias), si no hay motivos para dejarlo abierto recomendaria utilizar 'localhost' (o '127.0.0.1') para permitir solo las conexiones locales.
Y puerto de enlace es el puerto que se proporcionara a los programas para que se conecten al tunel

Por ejemplo:

ssh -D localhost:1234 sleepless

Abrira una conexion SSH con 'sleepless' y un tunel SSH que se puede acceder por 'localhost' y por el puerto '1234' (normalmente solo el superusuario tiene permiso para abrir puertos con un numero menor que 1024)


Y esto es todo por ahora... (proximamente el SSHFS y las VPN)

[Referencias]
http://www.openssh.org/
http://www.lucianobello.com.ar/openssh/
http://tuxpepino.wordpress.com/2007/05/11/ssh-el-dios-de-la-administracion-remota/

Hasta otra.

jueves, 28 de enero de 2010

Pasando el rato con /dev/dsp

/dev/dsp es el dispositivo que controla el audio en gnu/linux, esto permite hacer cosas bastante curiosas

(Si no encuentras el archivo dsp en la carpeta /dev, quiza este en dsp0, audio o audio0...)

Escribiendo cosas en este archivo conseguiremos que salgan como audio (lo mejor sera bajar el volumen del audio, ya vereis por que... ;)

Otra cosa... es posible que sea necesario cerrar las aplicaciones que esten utilizando el audio para que funcione todo bien, ademas esto es mejor lanzarlo en una consola de comandos (no con un "ejecutar programa") y despues pararlo con Control-C, sino es posible que siga hasta que se reinicie el pc.

Por ejemplo, haciendo  sudo cat /dev/mouse >> /dev/dsp , los altavoces produciran un sonido cada vez que el mouse se mueve.

Con sudo cat /dev/urandom >> /dev/dsp se producira un sonido aleatorio... decepcionados?, yo tambien, lo de que fuera aleatorio tenia buena pinta, pero al final es lo que se escucha cuando la radio no esta sintonizada

El resto es cuestion de imaginacion, hacer sudo cat /dev/hda >> /dev/dsp (o con sda en vez de hda si el disco es scsi)"reproducira" el disco duro, tambien se puede hacer con un archivo cualquiera, o con /dev/stdin (el teclado), /dev/mem (que es la memoria del pc)...

Tambien se puede hacer al reves, sudo cat /dev/dsp >> archivo.wav para guardar una grabacion (si el pc tiene microfono) en un archivo wav

Suerte y hasta otra

jueves, 21 de enero de 2010

Marchando una de exploits!

Ya estamos acostumbrados a que los de Microsoft hagan de las suyas, dejando bugs explotables sin parchear y con ello dejando a sus usuarios solos ante el peligro, despues pasa lo que pasa, la historia de hoy no es diferente... vamos haya:

Las malas noticias:

1. (CVE-2010-0249) El bug en IE no es algo reciente (el 14 de este mes ya estaban los de McAfee hablando sobre el) ,pero aun sigue vigente:

Bug: permite a atacantes remotos ejecutar codigo arbitrario accediendo a un puntero asociado con un objeto borrado.

Son vulnerables IE6, IE7 y IE8, con Windows 2000 SP4, Windows XP, Windows Server 2003, Windows Vista, Windows Server 2008, Windows 7 y Windows Server 2008 R2.

Simplemente navegando con uno de estos navegadores y SO's dentro de una pagina web hecha a proposito para explotar el bug permitiria acceso al sistema. (El exploit se puede conseguir a traves de Metasploit, por ejemplo)

Nota: antes se decia que con el DEP de IE, se evitaba la explotacion del bug, con el ultimo exploit esto ya no es verdad.

2. ( CVE-2010-0232 ) [Anuncio de la vulnerabilidad] El  fallo en todos los Windows de 32 bits (a partir del NT)

Un fallo en todos los Windows  debido a la forma en la que manejan las aplicaciones de 16 bits permite la explotacion para conseguir la elevacion de privilegios hasta SYSTEM (el usuario con mas privilegios de Windows).

En KiTrap0D.zip esta comprimido el exploit y el anuncio de la vulnerabilidad (en ingles)

Hay una extensa explicacion en el boletin de Hispasec: http://www.hispasec.com/unaaldia/4106/


Las buenas noticias:

Evitar los problemas es relativamente facil, para el bug de IE, puedes instalar otro navegador (como recomiendan los gobiernos Aleman y Frances): Firefox, Google Chrome, Opera  o desactivar el Javascript.

Para evitar el Bug de Windows hay que deshabilitar el soporte para aplicaciones de 16 bits (que ya no se usan), aqui hay un video que indica como hacerlo en XP:
http://www.youtube.com/watch?v=u7Y6d-BVwxk

Suerte y hasta otra

martes, 12 de enero de 2010

Diversion con los intrusos

Vuelta de navidades... hay gente que para pasar el tiempo libre se dedica a entrar en redes Wifi, veamos como sacar algo de diversion nosotros tambien :)}

Supongamos que la situacion es la siguiente: eres propietari@ de una red Wifi, red que ha sido vulnerada (maldito WEP >:(  ) y que el intruso utiliza para navegar por internet... asi que vamos a gastarle una pequeña broma

Nota: No soy abogado ni nada parecido, asi que no se si esto que se describe es totalmente legal aqui o en otro pais, las pruebas las he realizado en mi red privada, sin afectar a usuarios externos, si de verdad le vas a gastar una broma (que la cosa no pasa de eso) a alguien de tu red local, hazlo bajo tu responsabilidad.

Bien, pasemos a lo que hace falta:

- Un servidor web, para mostrarles la pagina web a los "visitantes", un Ubuntu con apache y php servira perfectamente
- La suite dsniff (concretamente la herramienta dnsspoof), en un entorno Ubuntu/Debian se puede instalar con sudo apt-get install dsniff

Lo primero es preparar la pagina que va a ver el "visitante", una o dos cosas apovechando la variable $_SERVER  haran la pagina mas interesante, esta es bastante simple, todo es cuestion de hecharle imaginacion:



El codigo que muestra informacion sobre el "visitante" es casi igual que el de la imagen que muestra ip, navegador...

Por ultimo redireccionar a los visitantes de otro servidor, el comando que se utiliza es el siguiente: sudo dnsspoof -i <interfaz> -f <archivo de hosts>
Siendo el interfaz el dispositivo utilizado para conectarse a la red (como eth0 ,en Gnu/Linux, *BSD,etc se puede averiguar con ifconfig )

Y el archivo de hosts uno como el de /usr/share/dsniff/dnsspoof.hosts, siguiendo el formato clasico hay un dominio en cada linea, lo primero es la IP a la que se asigna el dominio, que va despues de la IP separado por una tabulacion (las lineas que empiezan por # son comentarios).

Lo que se consigue con esto es (por decirlo de una forma) que cuando el navegador pregunte en que IP esta alguno de los dominios de la lista, el dnsspoof se adelante al servidor DNS (aprovechando que la red local suele ser mas rapida) y le diga la IP que aparece en el archivo de hosts


 Para que el dnsspoof funcione tiene que poder snifar las peticiones DNS, asi que dependiendo de la red quiza sea necesario poner en marcha un man-in-the-middle, para esto se utilizara otra herramienta de la suite dsniff, arpspoof, el comando es este: sudo arpspoof -i <interfaz> -t <ip de pasarela> <"visitante" >

Suerte y hasta otra

lunes, 21 de diciembre de 2009

pyCrawler 0.1 (Crawler en Python)

Esto es un ejemplo de como hacer un crawler (un script que va siguiendo los enlaces de las paginas web) escrito en python.

El proposito original del script era hacer mas sencillo el trabajo de moderacion de un sitio web, filtrando las imagenes (por url), textos, enlaces y titulos, a traves de una blacklist (nota: estas no traen por defecto ningun elemento, asi que hay que añadirlos a mano, en las lineas 170 y 171,implementadas como listas).

Lo que se hace al encontrar algo en la lista negra se define en la funcion Aviso (linea 16).

Como el proposito original era la moderacion, el script esta programado para no seguir ningun enlace fuera de ese sitio web (pero esto se puede cambiar facilmente).

Link: pyCrawler

Suerte y hasta otra.

jueves, 10 de diciembre de 2009

Jugando a Core Wars [2° Parte/2]

Sigamos con el Core Wars...
Resumiendo, lo que vimos hasta ahora fue:

    ;Comentarios
    ;name nombre del programa
    ;author autor
    MOV A,B ;Copia A en B
    ADD A,B  ;Añade A a B
    JMP A     ;Se salta la instruccion A
    DAT A,B ;Un espacio para datos

Formas de indicar una direccion:

-Inmediata, por de la posicion donde esta el valor, se indica con un '#'
-Directa, por la posicion actual, se representa con '$' (o sin nada)
-Indirecta, por el valor de la posicion indicada, se indica con un '*' si es el primer campo (A), o con '@' si es el segundo campo (B)

Pero hay mas formas de indicar una direccion de forma indirecta:

- La del campo A, restandole 1 antes, '{'
- La del campo B, restandole 1 antes, '<'
- La del campo A, sumandole 1 despues, '}'
- La del campo B, sumandole 1 despues, '>'

Por ejemplo, se podria modificar el programa "dwarf"

            ;name Dwarf
            ;author A. K. Dewdney
dwarf  ADD #4, bomb
           MOV   bomb, @bomb
           JMP    dwarf

bomb  DAT #0


Haciendo que llene todos los espacios de memoria 1 a 1, en vez de cuatro en cuatro, y de paso eliminamos una instruccion (con lo que el programa es mas rapido)


dwarf  MOV   bomb, >bomb
          JMP    dwarf

bomb  DAT #1


Veamos las diferencias, la primera es que ya no esta la instruccion ADD por que lo que hacia (cambiar el valor de "bomb" para evitar estar siempre "golpeando la misma zona")ahora lo hace el MOV.
La segunda es el campo B de la instruccion MOV incrementa el valor del campo B de "bomb" uno de cada vez (por el '>').
La ultima es que el valor al que apunta "bomb" al principio es el siguiente ('#1'), ya que al no haber ADD y a que el incremento es posterior, si fuera el mismo ('#0'), se sobreescribiria, algo totalmente inutil.

Ahora algo mas complejo... aunque no por ello util:

      SUB #7,inst ;Para reajustar el puntero de instruccion
      SUB #6,pos ; Esto tambien
      MOV >inst,>pos
      SEQ inst,inst+1 ;Aqui esta el problema XD
      JMP -2
      JMP -14 ;Al proximo paso
pos  DAT #-9
inst  DAT #0 ;Los valores que quedaran despues de copiarse a si mismos
       DAT #2

Como se puede ver aqui hay instrucciones nuevas:
-La primera es SUB (de substract, restar ), funciona igual que el ADD, pero en vez de sumar, resta (logicamente es igual que hacer ADD de un numero negativo)
-La otra es SEQ (skip if equal, saltar si es igual), compara las dos instucciones y si son iguales se salta la siguiente instruccion

Veamos que hace el codigo entonces :
El DAT con la etiqueta pos, indica la posicion a donde se va a copiar, y el de la etiqueta inst, la instruccion que se va a copiar.
El DAT siguiente al de inst tiene siempre el valor #2, esto servira para comprobar si se acabo de copiar todo el codigo.

-Resta 7 al DAT que indica la instruccion a copiar (para que apunte al principio del codigo)    [ SUB #7,inst ]
-Resta 6 al DAT que indica donde se copiara la instruccion (para que apunte a la proxima seccion donde se copiara) [ SUB #6,pos ]
-Copia la instruccion a la que apunta inst a la posicion que indica pos, y incrementa en 1 los dos (para que apunten al siguiente) [ MOV >inst,>pos ]
-Si inst es igual a lo que hay en la siguiente posicions, se salta la siguiente posicion [ SEQ inst,inst+1 ]
-Vuelve atras 2 instrucciones [ JMP -2 ]
-Vuelve atras 14 instrucciones (pasa al bucle siguiente) [ JMP -14 ]

Es decir, que se copia todo hacia atras, hasta que acaba y salta hacia atras, para continuar copiandose.La utilidad que tiene esto es poca, con un minimo cambio en cualquier parte del codigo que se este ejecutando, el programa falla.

Las opciones para cambiar el flujo del programa son:

-SEQ (explicado anteriormente)
-SNE (funciona al reves que SEQ) (Skip if Not Equal, saltar si no es igual)
-SLT (se salta la siguiente instruccion si el campo A es menor que el campo B) (Skip if Less Than, saltar si es menos de)

-JNZ, si el valor del campo A es distinto de 0, se salta a la posicion que indica el campo B (Jump if Not Zero, saltar si no es cero)
-JZ, como JZN, pero si el valor de A es 0 (Jump if Zero, saltar si es cero)
-DJN, como JNZ, pero decrementa previamente el valor de A (Decrement & Jump if Not zero, decrementar y saltar si no es cero)

-SPL, se crea un segundo proceso que empieza en la posicion indicada (Split, separar)

La unica que introduce algo nuevo es SPL, veamos un ejemplo:

    SPL 0
    MOV 0,1

- SPL 0, crea un proceso mas, que seguira en la misma instruccion (si, asi continuamente)- MOV 0,1 ... un clasico imp (como el primero de todo)

Lo que hace es generar muchos procesos, ejecutando todos el codigo del imp
Si lo ejecutamos veremos que aunque al principio el conjunto de imps avanzan relativamente rapido, poco a poco van mas lentos, esto es por la forma que hay de repartir el tiempo entre los procesos:

Durante el turno de cada programa se ejecuta un proceso suyo y este no se volvera a ejecutar hasta que lo hayan hecho el resto

Esto significa que cuantos mas procesos haya para el programa, mas habra que esperar para que se repita el mismo proceso (por esto y por otras cosas suele haber un limite de procesos por programa)

Ya no se me ocurre nada mas que pueda hacer falta para escribir un programa de Core Wars, asi que eso es todo por ahora.

Quien no tenga problemas con el ingles tiene un buen tutorial en [ http://vyznev.net/corewar/guide.html ]

Actualizacion: Uno mas ( este no lo explicare :)}, es bastante sencillo )

    ;name Code Runner
    ;author Kenkeiras

    ADD #4,3
    SPL >2
    JMP -2
    DAT #1,#1

Suerte

domingo, 6 de diciembre de 2009

Jugando a Core Wars [1° Parte/2]

Aqui veremos como funciona el juego Core wars, en el que hay que escribir un programa que intente eliminar a sus oponentes (para esto hay varios metodos... hacer que dividan por cero, que intenten ejecutar algo que no sea codigo,etc )

No voy a explicar como instalarlo, ya que hay muchos programas que sirven para jugar, puedes encontrar muchos aqui: http://homepages.paradise.net.nz/~anton/cw/corewar-faq.html#CoreWarSystems
En los repositorios de Ubuntu/Debian hay un paquete llamado corewars [ sudo apt-get install corewars ] que sirve perfectamente, pero es posible que despues no este en el menu, si es asi tendras que abrir un terminal y lanzar corewars

El lenguaje que se usa (llamado Redcode) es bastante parecido al Ensamblador, asi que aunque quien maneje este tendra mucho trabajo adelantado (se usan ADD's, MOV's, JMP's...), para est@s ultim@s hay que destacar que la sintaxis es mas parecida a la de AT&T que a la de Intel (por ejemplo en el ADD el primer argumento es la cantidad a añadir y la segunda donde se añadira), se explicara todo como si no se tuviera ninguna nocion de ensamblador.

Nota: desde ya mismo perdon por algunas licencias que me tomare para intentar hacer mas sencillo todo (como llamar "bytes" a las posiciones de memoria)

Como primer ejemplo utilizaremos el programa mas sencillo, llamado imp (de impulso):

    ;name Imp
    ;author Walter Hofmann

    mov 0,1

Si lo ejecutamos veremos que va llenando la memoria byte a byte (si se le puede llamar asi), uno de cada vez.

Veamos como es el codigo... lo que va despues de un ';' es un comentario (no tiene relevancia en el juego), algunos MARS (las maquinas virtuales donde suceden los "combates") buscan cierta informacion en los comentarios, por ejemplo los que despues de el ';' llevan la palabra "name", especifican el nombre del programa, y los que despues del ';' llevan "author", muestran el nombre del autor del programa.

Hasta ahora no paso nada que afectase a la "maquina" que ejecuta el programa, ahora viene lo divertido,el codigo MOV 0,1 copia la instruccion (MOV) que esta en la posicion 0 desde el codigo (el propio codigo) hasta la posicion 1 desde el codigo, la posicion de memoria siguiente, con lo que la instruccion se copia a la siguiente posicion y despues se ejecuta lo que haya en la siguiente posicion ( si, el mismo codigo otra vez ).

Para entenderlo mejor veamos rapidamente como funciona la maquina:

La memoria de la maquina es circular (no hay punto inicial ni final), es lineal (solo se puede ir hacia adelante o hacia atras) y es relativa (solo se puede especificar una posicion a partir de la actual, no se puede decir por ejemplo, la posicion 74).

El procesador de la maquina ejecuta una instruccion ( que siempre ocupan 1 "byte" ) y a menos que la instruccion implique un cambio en el flujo del programa (JMP, JNZ... ya se explicaran despues) a continuacion se ejecuta la siguiente, si no hay ninguna o la operacion no esta permitida (como una division por 0), el proceso "muere".

Entonces nustro ejemplo pasaria algo asi:

t=0

 ...
 ---------------
 | ???          |
 ---------------
 | MOV 0,1  | <- (Se va a ejecutar esto)
 ---------------
 | ???          |
 ---------------
 | ???          |
 ---------------

...


t=1 (despues de ejecutar la primera instruccion)


 ...

 --------------
 | ???         |
 --------------
 | MOV 0,1 |
 --------------
 | MOV 0,1 | <- (Se va a ejecutar esto)
 --------------
 | ???         |
 --------------
...


t=2 (despues de la segunda instruccion)


 ...

 --------------
 | ???         |
 --------------
 | MOV 0,1 |
 --------------
 | MOV 0,1 |
 --------------
 | MOV 0,1 | <- (Se va a ejecutar esto)
 --------------
 | ???         |
 --------------
 ...


Asi el programa va "haciendo el camino" y sigue hasta que algo lo detenga.

Ahora veamos algo un poco mas complejo.

            ;name Dwarf
            ;author A. K. Dewdney
dwarf  ADD #4, bomb
           MOV   bomb, @bomb
           JMP    dwarf

bomb  DAT #0

Aqui se introducen muchas mas posibilidades, empezando por esta:

bomb   DAT #0

Esto significa, hay un "byte" que no contiene ninguna instruccion, sino datos, y a esta posicion tiene la etiqueta "bomb" (para no tener que ver donde seria su direccion con cada nueva instruccion), su uso es bastante simple, si alguien intenta ejecutarlo el proceso falla, y se puede utilizar para almacenar datos (de ahi su nombre, DAT).

La segunda es:

dwarf  ADD #4, bomb

Un "byte" con la etiqueta "dwarf" y con la instruccion ADD, que añade el valor del primer argumento (en este caso 4), a lo que este en la segunda posicion (en este caso a lo que tiene la etiqueta "bomb" ).

Despues tenemos:

    MOV   bomb, @bomb

Como ya vimos en el primer ejemplo, la instruccion MOV copia lo que haya en el primer valor, en el segundo,pero en este caso el segundo valor se utiliza para indicar donde se va a copiar...me explico:

Hay tres grupos de formas de indicar una direccion, inmediata, directa e indirecta.

La inmediata es la que se toma partiendo de la posicion de donde se toma el valor, se indica con un '#' antes del valor (por ejemplo, el DAT o el primer valor del ADD).

La directa es la que se calcula partiendo de la posicion actual, se indica con un '$' o no añadiendo nada (por ejemplo, en el primer valor del MOV o en el JMP).

La indirecta, es la que se calcula partiendo de la posicion que indique el "byte" que se indique, dependiendo de si es el que indica el primero (campo A) o el segundo argumento (campo B) del "byte" se indican con un '*' o '@' respectivamente (se pueden hacer mas cosas, pero ya me estoy extendiendo demasiado por ahora)

Entonces     MOV   bomb, @bomb     copia lo que haya en la posicion "bomb" a donde apunte el campo B de "bomb".
Por ultimo...

          JMP  dwarf

La instruccion JMP salta a la posicion que se indique, en este caso la posicion con la etiqueta dwarf (el principio del codigo).
En resumen, lo que hace el codigo es:

- Añade 4 a la posicion que apunta "bomb"  (MOV #4,bomb)
- Copia "bomb" a la posicion que apunta (MOV bomb,@bomb)
- Vuelve al principio (JMP dwarf)

Asi que va llenando la memoria de DAT's, (si algun programa los intenta ejecutar falla), por ejemplo, contra un imp, podria ocurrir esto.

t=0
...
 ---------------
 | MOV 0,1  |
 ---------------
 | MOV 0,1  | <- (Se va a ejecutar esto)
 ---------------
 | ???          |
 ---------------
 | ???          |
 ---------------
...

t=1 (cuando el imp se copia a la siguiente posicion, y en el mismo "turno" el "bomb" del programa anterior se copia a la misma posicion)

...                                                          ...
 ---------------                                       ----------------
 | MOV 0,1  |                                        | MOV 0,1  |
 ---------------                                       ----------------
 | MOV 0,1  |                                        | MOV 0,1  |
 ---------------                          =>         -----------------
 | MOV 0,1  | <-  (Se va a ejecutar)    | DAT         | <-
 ---------------                                       ------------------ 
 | ???          |                                        | ???          |
 ---------------                                       -----------------
...                                                        ...

Esto es todo por ahora... hay una guia bastante completa en [http://vyznev.net/corewar/guide.html]

Suerte

jueves, 3 de diciembre de 2009

Manifiesto en defensa de los derechos fundamentales en internet

Ante la inclusión en el Anteproyecto de Ley de Economía sostenible de modificaciones legislativas que afectan al libre ejercicio de las libertades de expresión, información y el derecho de acceso a la cultura a través de Internet, los periodistas, bloggers, usuarios, profesionales y creadores de internet manifestamos nuestra firme oposición al proyecto, y declaramos que...
1.- Los derechos de autor no pueden situarse por encima de los derechos fundamentales de los ciudadanos, como el derecho a la privacidad, a la seguridad, a la presunción de inocencia, a la tutela judicial efectiva y a la libertad de expresión. 2.- La suspensión de derechos fundamentales es y debe seguir siendo competencia exclusiva del poder judicial. Ni un cierre sin sentencia. Este anteproyecto, en contra de lo establecido en el artículo 20.5 de la Constitución, pone en manos de un órgano no judicial -un organismo dependiente del ministerio de Cultura-, la potestad de impedir a los ciudadanos españoles el acceso a cualquier página web.
3.- La nueva legislación creará inseguridad jurídica en todo el sector tecnológico español, perjudicando uno de los pocos campos de desarrollo y futuro de nuestra economía, entorpeciendo la creación de empresas, introduciendo trabas a la libre competencia y ralentizando su proyección internacional.
4.- La nueva legislación propuesta amenaza a los nuevos creadores y entorpece la creación cultural. Con Internet y los sucesivos avances tecnológicos se ha democratizado extraordinariamente la creación y emisión de contenidos de todo tipo, que ya no provienen prevalentemente de las industrias culturales tradicionales, sino de multitud de fuentes diferentes.
5.- Los autores, como todos los trabajadores, tienen derecho a vivir de su trabajo con nuevas ideas creativas, modelos de negocio y actividades asociadas a sus creaciones. Intentar sostener con cambios legislativos a una industria obsoleta que no sabe adaptarse a este nuevo entorno no es ni justo ni realista. Si su modelo de negocio se basaba en el control de las copias de las obras y en Internet no es posible sin vulnerar derechos fundamentales, deberían buscar otro modelo.
6.- Consideramos que las industrias culturales necesitan para sobrevivir alternativas modernas, eficaces, creíbles y asequibles y que se adecuen a los nuevos usos sociales, en lugar de limitaciones tan desproporcionadas como ineficaces para el fin que dicen perseguir.
7.- Internet debe funcionar de forma libre y sin interferencias políticas auspiciadas por sectores que pretenden perpetuar obsoletos modelos de negocio e imposibilitar que el saber humano siga siendo libre.
8.- Exigimos que el Gobierno garantice por ley la neutralidad de la Red en España, ante cualquier presión que pueda producirse, como marco para el desarrollo de una economía sostenible y realista de cara al futuro.
9.- Proponemos una verdadera reforma del derecho de propiedad intelectual orientada a su fin: devolver a la sociedad el conocimiento, promover el dominio público y limitar los abusos de las entidades gestoras.
10.- En democracia las leyes y sus modificaciones deben aprobarse tras el oportuno debate público y habiendo consultado previamente a todas las partes implicadas. No es de recibo que se realicen cambios legislativos que afectan a derechos fundamentales en una ley no orgánica y que versa sobre otra materia.

Este manifiesto es obra de muchas manos, y propiedad de todos. Si te gusta, cópialo, pásalo, publícalo en tu weblog o haz lo que quieras con él.