Latest Tweets

Una al Mes: Silicon Valley Episodio 1 CTF Write-Up

1: Obtención del archivo con las credenciales.

Descargamos una imagen del disco de Gilfoyle desde cualquiera de los dos enlaces propuestos. Rápidamente pensamos en utilizar Volatilty para analizar dicha imagen. Primero descomprimimos el archivo descargado y luego pedimos a Volatility que nos dé información sobre la imagen, para poder escoger el mejor perfil a utilizar:

 

Obtención de información sobre la imagen del disco de Gilfoyle.

Según el enunciado del reto, debemos encontrar un archivo con las credenciales (encriptadas) de acceso a la web http://34.247.69.86/siliconvalley/episodio1/login.php . Como se comenta que se ha producido un corte eléctrico, podríamos pensar que tal vez ese documento estuviera en uso en el momento del corte. Así que empezamos enumerando procesos que estuvieran en ejecución para luego filtrar aquellos que puedan ser más interesantes (navegadores web, procesadores de texto, programas de anillo de claves, etc.). Para ello usamos Volatility con el primer perfil propuesto en el comando anterior:

volatility -f GILFOYLE-HELLDD.raw –profile=Win7SP1x64 pslist

Entre todos los procesos listados, observamos que LibreOffice y Firefox estaban en ejecución:

Procesos interesantes ejecutados por el usuario.

Empezamos con LibreOffice; usamos de nuevo Volatility para listar aquellos archivos abiertos por el proceso con PID 2340 que estuvieran ubicados en el directorio del usuario (Users). El primero de la lista parece muy prometedor: info.odt:

Volcamos el archivo info.odt a disco para analizarlo con mayor detenimiento:

Volcado del archivo info.odt a disco.

Abrimos el documento con LibreOffice y observamos que, efectivamente, podría muy bien ser el documento con las credenciales cifradas.

2: Descifrando las credenciales

A priori, el contenido del documento parecer utilizar el abecedario de Base-64. Intentamos decodificarlo, pero sin éxito. Lo que sorprende es que el documento parece estar segmentado en grandes bloques de texto independientes, y se puede ver claramente una repetición de dichos bloques. En una parte del documento observamos una separación de párrafo después del carácter “:”. Justo antes y después de dicho caracter observamos lo que podría ser un par de MD5s encerrados entre corchetes:

Posibles MD5s encerrados entre corchetes.

Lo que obtenemos bien podría ser el usuario y el password generado con MD5 que estamos buscando. Probamos suerte directamente pegando estos valores en la web http://md5decrypt.net:

Rompiendo el MD5 (usuario de la web).

Rompiendo el MD5 (password de la web).

Ya tenemos las credenciales; podemos validarnos en la web y proseguir con el reto.

3: Obtención del número de la casa

Tras validarnos en la web con las credenciales Gilfoyle:Satan, obtenemos una nueva URL:

Nueva URL tras validarnos con éxito en la web.

Accedemos a la misma y obtenemos una imagen JPG:

La nueva URL nos lleva hasta una imagen JPEG.

Descargamos la imagen a disco. Antes de proceder con técnicas de stego, obtenemos toda la meta-información posible sobre la imagen. Nos da por pensar: “ey, esto parece una fotografía tomada del archivo de denuncia, tal vez tengamos suerte y tengamos la geolocalización de la cámara donde se tomó la misma…”; así que nos centramos en el campo XMP/IPTC de la imagen y buscamos la localización:

Copiamos y pegamos estas coordenadas en Google Maps. En lugar de un número de casa, Google nos devuelve un código Plus (https://plus.codes/):

Casi lo tenemos; en lugar de un número, Google nos devuelve un Plus Code.

Basta con pulsar sobre la casa que está en la calle indicada por el código Google Plus para obtener su número, el 2126:

Ya tenemos el posible número de la casa, el 2126.

Generamos el MD5 de dicho número:

echo -n “2126”|md5sum
3b92d18aa7a6176dd37d372bc2f1eb71 –

La flag es, pues: UAM{3b92d18aa7a6176dd37d372bc2f1eb71}

 

@disbauxes

Toni Castillo Girona

 

 

 

 

 

Script for NUMA systems

Preamble

On modern NUMA systems, it’s always a good thing to know the total number of physical processors (nodes), the total number of real cores per processor, and if HT is enabled, the total number of virtual cores per processor (which is, of course, twice the number of real cores per socket). At the same time, it would be great to be able to disable HT for a particular physical processor on the fly. This simple BASH script does precisely that.

Using the script

Install numactl before running the script. If numactl is not found, the script will tell you so and exit:

sudo apt-get install numactl

The script can report the real and virtual cores per socket along with the total number of physical processors installed on the system. It works perfectly well for systems that only have 1 socket, of course, so no NUMA in this case.:

cores.sh -h
Usage: /usr/bin/cores.sh [-t] [-c CPU] [-h]
		 -t, reports total number of physical processors (nodes) and quits.
		 -c CPU, reports total and real cores for physical processor CPU.
		 -r CPU, reports real cores for physical processor CPU separated with commas.
		 -d CPU, disables HT on the given CPU (requires root).
		 -h, show this help message.
  Example: /usr/bin/cores.sh -t
           /usr/bin/cores.sh -c 2
           sudo /usr/bin/cores.sh -d 0

To get the total number of cores for, say, physical processor 1 on a 4-socket system, run:

cores.sh -c 1
Total physical processors on this system: 4
Total Cores for processor 1: 1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77
Virtual Cores for processor 1:  41 45 49 53 57 61 65 69 73 77 
Real Cores for processor  1:  1 5 9 13 17 21 25 29 33 37

You can disable HT for a particular socket as well. The number of cores that will be disabled are shown in the “Virtual Cores” row. Say, you want to disable HT for CPU0 on a 1-socket system; run:

 sudo cores.sh -d 0
Total physical processors on this system: 1
Total Cores for processor 0: 0 1 2 3 4 5 6 7
Virtual Cores for processor 0:  4 5 6 7 
Real Cores for processor  0:  0 1 2 3
We are about to disable HT on physical cpu: 0
CPU cores to be disabled:  4 5 6 7 
Are you sure? [yn]

If you are completely sure, type “y” and press <ENTER>. Otherwise, type any other key and press <ENTER>.

You can run the script using the “-r” flag in order to output the real cores for a particular physical processor to pass it directly to numactl. Let’s imagine you want to run a 10-core simulation using mpirun on a 4-socket NUMA system. Each physical node has 10 real cores and 10 virtual cores due to HT. You want to run this simulation on node 3 (CPU4):

cores.sh -r 3
Total physical processors on this system: 4
Real Cores for processor  3:  3,7,11,15,19,23,27,31,35,39

Now, you can pass the string of real cores to numactl and run your simulation like this:

numactl --physcpubind=3,7,11,15,19,23,27,31,35,39 mpirun -np 10 \
> --report-bindings binary arguments

Or you can do it using this one-liner instead:

numactl --physcpubind=`cores.sh -r 3|tail -1|cut -d":" -f2|tr -d " "` \
>  mpirun -np 10 --report-bindings binary arguments

To make sure your simulation is running on the chosen cores/sockets, you can run the following command (replace PID with the proper one):

cat /proc/<PID>/status |grep Cpus_allowed_list
Cpus_allowed_list:	4-7

Get the script (cores.sh)

You can download the script from HERE.

Integrating the IHaveBeenPwned API into Linux PAM

Introduction

I was writing another 4-page article for Linux User and Developer about Public APIs when I came out with the idea of showing the readers how to leverage the IHaveBeenPwned API using a Linux PAM module. The idea was to use their new “Pwned Passwords API v2” with the K-Anonymity feature.

Writing the module

Writing a Linux PAM module is relatively easy. Doing it the right way (i.e.: avoiding common programming mistakes, adhering to good PAM-developing practises, and so on) is quite another thing altogether. There are certain things to consider; writing a buggy PAM module can easily lead to a total system lock-down or even a total system take-over. For starters, you must ensure that you overwrite any memory you have dynamically allocated before freeing it (see http://www.linux-pam.org/Linux-PAM-html/mwg-see-programming-sec.html#mwg-see-programming-sec-token). This module is used whenever a user runs the “passwd” command or some application performs a call to the putspent() function in order to change a user’s password.

This module performs the following actions:

  1. It asks for the current UNIX password to authenticate the user.
  2. If the users is authenticated, it asks for a new password.
  3. It computes its SHA1 and then generates a call to the IHaveBeenPwned API.
  4. If there is any kind of error communicating with the API, and if the option “enforceonerror” is set, the module returns an error and ends. No password is changed.
  5. If there is any kind of error communicating with the API and the “enforceonerror” option is not set, it jumps to step 8.
  6. If the call to the API succeeds, it performs a simple search for the whole hash in a local buffer.
  7. If the hash is found, it prints an error message telling the user so and returns an error. No password is changed.
  8. If the hash is not found, it tells the user so and asks for the new password again for confirmation.
  9. If both passwords match up, the password is stacked for the next module to process (pam_unix.so).

The hash is computed using OpenSSL and the API call is performed with Curl3. That’s why this module must be linked against libopenssl (-lssl) and libcurl3 (-lcurl3).

Testing the module

I released my module’s source code some days ago on GitHub. Clone, build and install the module as described in the README.md file. I have tested it on Debian Wheezy, Debian Jessie, Debian Stretch and Ubuntu 16.0.6 distros so far. Consider installing a Virtual Machine and testing the module there first. Once the module is enabled, you can run the “passwd” command to change your password the usual way. Try some well-known pwned passwords such as mariobros, princesspeach, heyjude! and so on.

My module in action with some logging.

Future work

I’m now in the process of serious code reviewing, to make sure everything is in order. There are some bits that are quite redundant, and then prone to error. So I’m trying to simplify the code as much as possible. Bear in mind that I’m a newbie when it comes to writing Linux PAM modules, so feel free to comment on my project and open issues on Github ;-).

Happy hacking!