Chatsubo [(in)Security Dark] Labs

"... A consensual hallucination experienced daily by billions of legitimate operators, in every nation, by children being taught mathematical concepts... A graphic representation of data abstracted from banks of every computer in the human system. Unthinkable complexity. Lines of light ranged in the nonspace of the mind, clusters and constellations of data. Like city lights, receding into the distance... "
--
William Gibson.

miércoles, 4 de diciembre de 2013

IOActive Labs Research: A Short Tale About executable_stack in elf_read_implies_exec() in the Linux Kernel

by Alejandro Hernández @nitr0usmx
This is a short and basic analysis I did when I was uncertain about code execution in the data memory segment. Later on, I describe what’s happening in the kernel side as well as what seems to be a small logic bug.... 

READ THE WHOLE PAPER HERE:
IOActive Labs Research: A Short Tale About executable_stack in elf_read_implies_exec() in the Linux Kernel

...
Anyway, perhaps that’s the normal behavior of the Linux kernel for some compatibility issues or something else, but isn’t it weird that making the stack executable or deleting the PT_GNU_STACK header all the memory segments are loaded with execution permissions even when the PF_EXEC flag is not set?
What do you think?

miércoles, 16 de octubre de 2013

"Binary Diffing" visual en Linux con Radare2

Binary Diffing o simplemente Bindiffing es una técnica utilizada para la visualización de código (mayormente en ensamblador) y así detectar patrones de conducta, así como también diferentes rutas de ejecución después de una modificación a un programa original, como una actualización o un parche de seguridad. Esta técnica es actualmente utilizada por muchos reverse engineers para identificar muchísimas cosas, malware, parches de seguridad mal implementados, backdoors, cambios en actualizaciones en software, cracking, y muchas cosas más.

"UNA IMAGEN DICEN MÁS QUE MIL PALABRAS"

Y bien, este blog post es básicamente una demostración básica del análisis visual para identificar diferencias entre binarios ELF en Linux utilizando Radare2. Esta es una gran herramienta para ingeniería inversa, e incluye un gran set de otras herramientas como un debugger, editor hexadecimal, etc.

Para las pruebas hice el siguiente código en C, el cual consta de simples comparaciones (if-else), un ciclo for, incremento de variables y un par de funciones de libc:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    if(strtol(argv[1], NULL, 16) == 0x41414141)
        printf("FOO\n");
    else if(strtol(argv[1], NULL, 16) == 0x42424242)
        printf("BAR\n");
    else {
        int i = 0xdead;

        for(int k = 0; k < i; k++)
            k++;

        printf("0x%x\n", i);
    }

    exit(0);
}
Compilamos con $gcc if.c -o if


Una vez descargado Radare2, es posible ver el listado convencional de código ensamblador de nuestro binario recién creado con $radare2 ./if y pdf @ sys.main dentro de Radare2:


Ahora, crearemos una copia de nuestro ejecutable con $cp if if2. Posteriormente editaremos una simple instrucción en esamblador para de allí detectar el cambio de forma visual  viendo el flujo del programa. Para este paso utilizaremos el editor HTE, en el cual una vez cargado ($ht ./if2), le damos View - ELF image, buscamos el código referente a la primer comparación contra el valor 0x41414141, y editamos cualquier jmp hacia cualquier otra etiqueta. Este es solo un ejemplo demostrativo e hice que saltara al printf("0x%x\n", i); del final, en la línea 16 del código en C, guardé el archivo y salí a la shell:


En la ejecución, lo único que cambia es lo que está en rojo, cuando se le pasa el parámtro 0x41414141. A diferencia del if normal, este imprime 0x00 ya que saltamos directo al printf() y el for anterior no se ejecutó, por lo tanto la variable que se imprime sigue siendo cero.


Ahora la parte interesante. El bindiffing más básico es ejecutar $radiff2 if if2, dando el offset y la diferencia de bytes, en este caso fue el offset de un simple jmp, así que solo cambió un byte:

Con el parámetro -C se analizan las funciones y se listan para ver si son iguales o no (notar el UNMATCH de la primer línea, correspondiente a la función main() ):


Finalmente, la opción más interesante, -g <función o dirección de memoria> para enviar la salida a formato xdot y poder visualizar las diferencias a través de un gráfico:


Con los comandos xdot ejecutados anteriormente se abrirán dos ventanas mostrando las diferencias:


A partir de aquí, lo interesante es la interpretación gráfica de los bloques de ensamblador. Este es un ejemplo bastante sencillo con pocos bloques de código y es muy fácil de identificar ciertos patrones visuales, por ejemplo:

  • Los bloques marcados en amarillo son los que cambiaron, es la diferencia binaria como tal (bindiff) ya que cambió la dirección a la que el jmp saltará.
  • A lo lejos, en la imagen de arriba, es posible ver que el path de ejecución de enmedio (el de la flecha azul vertical) en la imagen de la izquierda, simplemente se pasó a ser el path de ejecución de la derecha en la imagen de la derecha. Ese es el trozo de código que imprime "BAR". No se modificó en nada.
  •  Lo siguientes es un ciclo for. En el primer bloque de hasta arriba, el de la etiqueta loc.00400605 corresponde a la inicialización de una variable con el valor 0xdead y una variable con 0 (cero, que es el contador del for). De allí entra al bloque del for como tal, en donde se hace la comparación (instrucción cmp) para ver si continuar dentro del for o salir saltando al bloque de código que imprime el valor de la variable incrementada (flecha roja). En caso de seguir con el ciclo for, salta al pequeño bloque con dos instrucciones iguales las cuales suman 1 a la misma variable en la pila. Esta variable en nuestro código en C es k y se incrementa dos veces, en for(..;..; k++) k++;

  • La siguiente captura es la diferencia binaria, el cambio de ejecución. Nótese detenidamente  que en el primer código, del bloque amarillo se salta directamente al código de salida, con la función exit(), mientras que en el código modificado, después del código en amarillo se salta al código que imprime el valor de la variable incrementada después del ciclo for (como no se ejecutó el for, la variable tendrá un valor de cero y por eso nuestro programa en la shell imprime FOO 0x00) y posteriormente al bloque de salida (exit())
  • Por último, en la primer ejecución hay tres formas de llegar al bloque de exit() (el bloque donde dice call dword imp.exit):

mientras que en la segunda solo hay dos paths de ejecución para llegar allí:


Como es posible ver, el bindiffing es una técnica bastante útil para de forma visual identificar ciertos patrones de cambio entre dos binarios.

Espero les haya gustado este pequeño post y ojalá le encuentren provecho.

Happy Bindiffing B-) !

Alejandro.
@nitr0usmx

martes, 10 de septiembre de 2013

twitCheck.py - Identificador de amigos inactivos en Twitter por @EternalTodo

El día de ayer estuve jugando un poco con twitCheck.py que hizo un researcher que conocí apenas en el pasado Hack Cup en Las Vegas, José Miguel Esparza (@EternalTodo). En su blogpost explica la actualización de twitCheck.py a la nueva API 1.1 de Twitter y bueno, la herramienta se me hizo bastante util y fácil de configurar. 

twitCheck.py básicamente sirve para identificar a cuentas inactivas que sigues en Twitter, y después de la 1era ejecución, compara su base de datos para determinar si ganaste o perdiste followers.



Para hecharlo a andar solo se requiere:
1.- Obtener las cuatro credenciales (CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) que requiere la nueva API 1.1 de Twitter desde https://dev.twitter.com/apps/
2.- $ git clone https://github.com/abraham/twitteroauth.git 
3.- Autenticar dichas credenciales con Twitter utilizando el script en PHP en http://www.webdevdoor.com/php/authenticating-twitter-feed-timeline-oauth/. Guardar el script get-tweets1.1.php en $HOME. Luego de agregar el username de twitter y las cuatro credenciales obtenidas, ejecutar el script. La salida deben ser los últimos tweets de la cuenta:


4.- $sudo pip install tweepy
5.- $wget http://eternal-todo.com/files/scripts/twitCheck.py
6.- Editar twitCheck.py y agregar las cuatro credenciales obtenidas.
7.- Ejecutar ./twitCheck.py twitter_username

Directa o indirectamente esta herramienta podría servir para OSINT (Open Source INTelligence).
Se la recomiendo ;-).

Happy OSINT ! ;-)

martes, 16 de abril de 2013

IOActive Labs Research: Can GDB's List Source Code Be Used for Evil Purpos...

IOActive Labs Research: Can GDB's List Source Code Be Used for Evil Purpos...: By Alejandro Hernández @nitr0usmx One day while debugging an ELF executable with the GNU Debugger (GDB), I asked myself, "How...

miércoles, 27 de marzo de 2013

DotDotPwn - The Directory Traversal Fuzzer: New Contributions to DotDotPwn !

DotDotPwn - The Directory Traversal Fuzzer: New Contributions to DotDotPwn !: We're happy to announce these two great contributions to DotDotPwn - The Traversal Directory Fuzzer. The 1st one was from...

sábado, 16 de marzo de 2013

ssl_hostname_resolver.pl : CN (Common Name) grabber on X.509 Certificates over HTTPS

I had this simple idea in my previous pentest where, for some reason, I couldn't resolve some IP addresses to their corresponding hostnames, but their CN fields (SSL certs on HTTPS) had resolvable hostnames. So, I did this simple script !

For some security scanners, such as Nessus and Nikto2, it's considered a security vulnerability:
"Standard certificate validation procedures require the subject CN field of a certificate to match the actual name of the entity presenting the certificate. For example, in a certificate presented by https://www.example.com/, the CN should be www.example.com."

Source:  X.509 Certificate Subject CN Does Not Match the Entity Name
http://www.rapid7.com/vulndb/lookup/certificate-common-name-mismatch


You can download it directly at:
http://packetstormsecurity.com/files/120634/Common-Name-Grabber-Script.html

Or...

#!/usr/bin/perl
# 
# ssl_hostname_resolver.pl
# CN (Common Name) grabber on X.509 Certificates over HTTPS
#
# Copyright (c) 2013 by Alejandro Hernandez, IOActive, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# I had this simple idea in my previous pentest where, for 
# some reason, I couldn't resolve some IP addresses to their 
# corresponding hostnames, but their CN fields (SSL certs 
# on HTTPS) had resolvable hostnames. So, I did this simple script !
#
# ----------------------------------------------------------------- 
#
# For some security scanners, such as Nessus and Nikto2,
# it's considered a security vulnerability:
#
# "Standard certificate validation procedures require the subject 
# CN field of a certificate to match the actual name of the entity 
# presenting the certificate. For example, in a certificate presented 
# by https://www.example.com/, the CN should be www.example.com."
# Source:  X.509 Certificate Subject CN Does Not Match the Entity Name
# http://www.rapid7.com/vulndb/lookup/certificate-common-name-mismatch
#
#
# Alejandro Hernandez < alejandro.hernandez [at] ioactive.co.uk >
# http://twitter.com/nitr0usmx
#
# IOActive Labs Research
# http://blog.ioactive.com
# 

use Net::CIDR::Lite;
use NetAddr::IP;
use Net::SSL;

$connection_timeout = 3; # seconds
$SIG{ALRM} = sub { }; # Do nothing when the connection timeout is reached instead of die

print <
-=[ ssl_hostname_resolver.pl
-=[ by \@nitr0usmx
-=[
-=[ CN (Common Name) grabber on X.509 Certificates over HTTPS

HDR

sub usage
{
print <-=[ Usage: $0  [port to connect (443 default)]
-=[ E.g. CIDR block : $0 192.168.1.0/24
-=[      IP Range   : $0 192.168.1.1-192.168.13.37
-=[      Single IP  : $0 192.168.1.254

USG
}

my $targets = shift or (usage and die "No targets given!\n");
my $port    = shift || 443;

my $cidr_lite = Net::CIDR::Lite->new($targets);
@cidr_list = $cidr_lite->list;

print "-=[ Connecting every host on port: $port\n\n";

print "-------------------------------------------------\n";
print "      IP        =>   CN (Common Name)\n";
print "-------------------------------------------------\n";

for my $cidr( @cidr_list ){
  my $n = NetAddr::IP->new($cidr);

  for my $ip( @{ $n->splitref( $n->bits() ) } ){
    printf("%-15s =>   %s\n", $ip->addr, getCNFromX509($ip->addr));
  }
}

sub getCNFromX509
{
  my $ip = shift;

  eval{
    alarm($connection_timeout); # No. of seconds of connection timeout

    $ssl = Net::SSL->new(
          PeerAddr => $ip,
          PeerPort => $port,
          Timeout => 5 # Never reached, alarm() will be triggered before
          );
  };

  alarm(0);

  if($@){ # some error occurred 
    return "(Couldn't connect to port $port)";
  }

  $ssl->get_peer_certificate->subject_name =~ /CN=(.*)/g;

  return $1;
}

 
ch33rs !!!