# TryHackMe -  CyberHeroes Writeup

## Summary

CyberHeros is an easy-rated web challenge built on the iPortfolio Bootstrap template. The site advertises a "login page" challenge directly in its About section. Inspection of `login.html` reveals that authentication is performed entirely client-side in JavaScript, with the username hardcoded in plaintext and the password obfuscated by a trivial string-reversal function. Once the credentials are recovered from the page source, the same client script reveals the exact filename of a flag file hosted on the webserver, constructed dynamically from the submitted username and password. No exploitation of the server itself is required - the vulnerability is a client-side logic flaw combined with a predictable, credential-derived file path.

- Target: `<MACHINE_IP>`
- Category: Web
- Difficulty: Easy
- Key weakness: Client-side authentication with hardcoded/obfuscated credentials in JS, plus a predictable flag filename built from those credentials

---

## 1. Reconnaissance

Confirmed host is up and scanned open ports:

    nmap -A -Pn <MACHINE_IP> -o nmap

Results:

    22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.4
    80/tcp open  http    Apache httpd 2.4.48 (Ubuntu)

`http-title` identified the site as "CyberHeros : Index", running the iPortfolio Bootstrap template.

## 2. Initial Web Enumeration

Pulled the index page and reviewed static assets (aos.js, purecounter.js, validate.js) - all confirmed to be unmodified template vendor libraries, no custom logic there.

The index page's About section directly hints at the objective:

    We find vulnerabilities in the website legally... find the vuln on our login page and login to join us.

Nav bar links to `login.html`.

## 3. Directory Enumeration

    gobuster dir -u http://<MACHINE_IP> -w /usr/share/wordlists/dirb/common.txt -x php,txt,html,bak -t 50

Notable results:

    assets                (Status: 301)
    changelog.txt         (Status: 200) [Size: 2756]
    index.html            (Status: 200) [Size: 6568]
    login.html            (Status: 200) [Size: 5753]

No PHP backend, no admin panel, no backup files - confirming the target is static/client-side only.

## 4. Inspecting login.html

Fetched the login page source directly:

    curl http://<MACHINE_IP>/login.html

The page ships an inline `<script>` block containing the entire authentication logic:

    function authenticate() {
      a = document.getElementById('uname')
      b = document.getElementById('pass')
      const RevereString = str => [...str].reverse().join('');
      if (a.value=="h3ck3rBoi" & b.value==RevereString("54321@terceSrepuS")) {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
          if (this.readyState == 4 && this.status == 200) {
            document.getElementById("flag").innerHTML = this.responseText;
          }
        };
        xhttp.open("GET", "RandomLo0o0o0o0o0o0o0o0o0o0gpath12345_Flag_"+a.value+"_"+b.value+".txt", true);
        xhttp.send();
      }
    }

Two things fall out of this immediately:

1. The credential check happens entirely client-side, with the username hardcoded (`h3ck3rBoi`) and the password only lightly obfuscated via string reversal.
2. On a successful check, the script requests a flag file whose name is dynamically built from the raw username and password values - meaning the filename itself is fully derivable from the source, with no need to actually trigger the JS in a browser.

## 5. Recovering the Credentials

Reversing the obfuscated password string by hand:

    54321@terceSrepuS  ->  SuperSecret@12345

Recovered credentials:

    username: h3ck3rBoi
    password: SuperSecret@12345

## 6. Retrieving the Flag

Reconstructed the flag filename directly from the JS template string and requested it with curl, bypassing the browser/JS entirely:

    curl "http://<MACHINE_IP>/RandomLo0o0o0o0o0o0o0o0o0o0gpath12345_Flag_h3ck3rBoi_SuperSecret@12345.txt"

Response:

    Congrats Hacker, you made it !!
    Go ahead and nail other challenges as well :D

    flag{REDACTED}

---

## Key Vulnerabilities

| # | Vulnerability | Location | Impact |
|---|---|---|---|
| 1 | Client-side authentication logic | `login.html` inline `<script>` | Credentials and pass/fail logic fully readable in page source, no server-side verification |
| 2 | Weak obfuscation (string reversal) of password | Inline JS `RevereString()` | Trivial to reverse by hand, provides no real protection |
| 3 | Predictable, credential-derived sensitive file path | Inline JS `xhttp.open(...)` URL construction | Flag/secret file directly retrievable via curl once credentials are known, without ever executing the JS or submitting the form |

## Attack Chain

    Recon (nmap: 22, 80 open)
        |
        v
    Enumerate index.html -> hints at login.html
        |
        v
    gobuster -> confirms login.html, no backend endpoints
        |
        v
    curl login.html -> read inline <script> source
        |
        v
    Extract hardcoded username + reverse obfuscated password
        |
        v
    Derive flag filename from JS template string (no browser needed)
        |
        v
    curl flag file directly -> flag captured

## Mitigations

- Never perform authentication decisions client-side; all credential validation must happen on a trusted server, with the client only submitting credentials over an authenticated session.
- Do not rely on obfuscation (encoding, reversal, simple ciphers) as a substitute for real access control - anything shipped to the client is fully readable by the client.
- Do not derive sensitive resource paths (flags, secrets, admin files) from data that is already exposed to the client, such as hardcoded credentials in JS - this makes the resource trivially reachable without ever satisfying the intended check.
- Serve sensitive files only behind server-side, session-validated access checks, and avoid predictable or pattern-based filenames for anything not meant to be publicly enumerable.
