TwoMillion
TwoMillion exposed a web app on 2million.htb. The invite workflow allowed account creation, the authenticated API exposed admin and VPN routes, and the admin settings endpoint accepted a JSON request that promoted the current user. The admin VPN generation...
Scenario
TwoMillion attack path
TwoMillion exposed a web app on 2million.htb. The invite workflow allowed account creation, the authenticated API exposed admin and VPN routes, and the admin settings endpoint accepted a JSON request that promoted the current user. The admin VPN generation...
Objective
Machine walkthrough focused on Machines evidence, validation, and reusable operator lessons.
Walkthrough flow
Host-aware HTTP enumeration identified 2million.htb...
Invite generation allowed account registration.
Authenticated /api/v1 route listing exposed admin...
Admin settings accepted a JSON update that set the...
Admin VPN generation was vulnerable to command...
Source coverage
High source coverage
Status: complete. This article is generated from 6 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.
High confidence: the page is reconstructed from a primary walkthrough plus multiple supporting notes or evidence sources. Treat the chain as source-backed, while still checking the listed source files for sensitive values.
- <TARGET>-TwoMillion/walkthrough.md
- HTB/<TARGET>-TwoMillion/notes.md
- HTB/<TARGET>-TwoMillion/attack-map.md
- HTB/<TARGET>-TwoMillion/memory-summary.md
- HTB/<TARGET>-TwoMillion/dead-ends.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/machine__<TARGET>-TwoMillion__notes.md.272d829a01.md
Technical Walkthrough
TwoMillion Walkthrough
Raw flags and reusable secrets are stored only under loot/.
Summary
TwoMillion exposed a web app on 2million.htb. The invite workflow allowed account creation, the authenticated API exposed admin and VPN routes, and the admin settings endpoint accepted a JSON request that promoted the current user. The admin VPN generation endpoint then allowed command injection through the username field.
The injection read the web application environment file. A reused credential from that file allowed SSH login as admin, where the user flag was captured to loot/user.txt. Local mail pointed to an OverlayFS/FUSE kernel issue; the target kernel and tooling matched <secret redacted> conditions. A two-process PoC yielded root execution and the root flag was captured to loot/root.txt.
An alternative privilege escalation was also validated with <secret redacted> Looney Tunables. The vulnerable trigger is the <secret redacted> environment variable; the PoC produced root execution and captured proof to loot/root-looney.txt.
Reproduction Notes
- Use host-aware requests for
2million.htbagainst<TARGET>. - Generate an invite and register through
/api/v1/user/registerusing the form fieldcode. - Login through
/api/v1/user/loginand enumerate/api/v1. - Send a JSON
PUTto/api/v1/admin/settings/updatefor the current account. - Send JSON to
/api/v1/admin/vpn/generate; verify command injection with a harmless identity command. - Read the application environment file through the injection and test credential reuse over SSH as
admin. - Use the local mail hint and kernel/tooling checks to justify <secret redacted>.
- Run the two-process OverlayFS/FUSE PoC, prove root execution, and capture
root.txt.
Evidence
- Recon:
nmap/initial.txt,nmap/allports.txt - Web/API:
enum/authenticated-api-summary-20260527T093138Z.txt,enum/admin-update-vpn-summary-20260527T093210Z.txt - Command injection:
enum/vpn-injection-summary-20260527T093235Z.txt - Foothold:
enum/foothold-summary-20260527T093428Z.txt - Privilege escalation:
enum/admin-privesc-enum-20260527T093528Z.txt,enum/root-exploit-summary-20260527T095404Z.txt - Alternative privilege escalation:
enum/root-exploit-looney-summary-20260527T101434Z.txt
Source-Backed Dossier
The sections below are merged from companion Markdown notes for the same case. They are rendered after sanitization so the article stays precise without publishing raw flags, credentials, or target-specific secrets.
Notes
Scope
| Field | Value |
|---|---|
| Platform | Hack The Box / simulated lab |
| Target | TwoMillion |
| Difficulty | Easy |
| OS | Linux |
| Active target IP | <TARGET> |
| Prior target IP | <TARGET> |
| Pwnbox | <TARGET> |
| Attacker/VPN IP | <TARGET> |
| Local workspace | <local workspace><TARGET>-TwoMillion |
| Superseded workspace | <local workspace><TARGET>-TwoMillion |
| Started | 2026-05-27T09:10:20Z |
Evidence Ledger
| Time UTC | Action | Output file | Finding | Confidence | Next action |
|---|---|---|---|---|---|
| 2026-05-27T09:10:20Z | Harness reload and respawn setup | n/a | Re-read HTB machine workflow, Pwnbox workflow, web patterns, and quick wins. Treating the new IPs as a respawn of TwoMillion. | High | Create fresh workspace and validate Pwnbox route. |
| 2026-05-27T09:10:20Z | Pwnbox route validation | pending mirror from Pwnbox | Pwnbox SSH succeeded, tun0 is active, and target ICMP responds from the Pwnbox. | High | Run baseline TCP and HTTP enumeration from Pwnbox. |
| 2026-05-27T09:11:00Z | TCP baseline | nmap/initial.txt, nmap/allports.txt | Only SSH 22/tcp and HTTP 80/tcp were open. HTTP redirected to 2million.htb. | High | Enumerate web app with host-aware requests. |
| 2026-05-27T09:13:00Z | HTTP and invite enumeration | enum/http-host-baseline.txt, enum/invite-api-probes.txt, enum/form-fields.txt | Web app exposed invite generation and user register/login API routes. Register form expects code, not invite_code. | High | Generate invite, register, and authenticate through the API. |
| 2026-05-27T09:31:38Z | Authenticated API checkpoint | enum/authenticated-api-summary-20260527T093138Z.txt | Form-encoded registration/login succeeded; /api/v1 returned the route list. | High | Check admin update and VPN endpoints. |
| 2026-05-27T09:32:10Z | Admin privilege toggle | enum/admin-update-vpn-summary-20260527T093210Z.txt | JSON PUT to admin settings changed the current user to admin. VPN endpoint required JSON content type. | High | Test VPN generation for command injection. |
| 2026-05-27T09:32:35Z | VPN command injection proof | enum/vpn-injection-summary-20260527T093235Z.txt | VPN generation username parameter executed commands as www-data. | High | Read application config and test credential reuse. |
| 2026-05-27T09:34:28Z | Foothold and user flag | enum/admin-ssh-baseline-20260527T093428Z.txt, loot/user.txt | Application config was readable via injection. Reused app credential authenticated to SSH as admin; user flag captured live to loot/user.txt. | High | Enumerate local privilege escalation. |
| 2026-05-27T09:35:28Z | Privilege escalation enumeration | enum/admin-privesc-enum-20260527T093528Z.txt | Local mail identified an OverlayFS/FUSE kernel issue; kernel was Ubuntu 22.04 with 5.15.70-051570-generic; target had FUSE/OverlayFS support. | High | Stage <secret redacted> PoC. |
| 2026-05-27T09:38:06Z | First OverlayFS PoC attempt | loot/root-exploit-output-20260527T093806Z.txt | Single-binary PoC compiled but did not trigger successfully on this kernel. | Medium | Switch to two-process <secret redacted> workflow. |
| 2026-05-27T09:54:04Z | Root exploit and root flag | loot/root-exploit-xkaneiki-output-20260527T095404Z.txt, loot/root.txt | Two-process <secret redacted> PoC produced root execution and root flag was captured live to loot/root.txt. | High | Update state, cleanup notes, and run lint gate. |
| 2026-05-27T10:14:34Z | Alternative root exploit | enum/root-exploit-looney-summary-20260527T101434Z.txt, loot/root-looney.txt | <secret redacted> Looney Tunables PoC using <secret redacted> produced root execution and captured a second root flag proof to loot/root-looney.txt. | High | Keep as alternate privilege escalation evidence. |
Synthesis
Current completion state: COMPLETE.
Attack chain:
- Host-aware HTTP enumeration identified
2million.htband the invite/register/login workflow. - Invite generation allowed account registration.
- Authenticated
/api/v1route listing exposed admin settings and VPN generation endpoints. - Admin settings accepted a JSON update that set the current account as admin.
- Admin VPN generation was vulnerable to command injection in
username. - Command injection read the web app environment file; credential reuse gave SSH access as
admin. - Local mail and kernel details supported <secret redacted> OverlayFS/FUSE privilege escalation.
- Two-process <secret redacted> exploit yielded root execution and root flag capture.
Alternative privilege escalation: GLIBC 2.35 was vulnerable to <secret redacted> Looney Tunables. A PoC using <secret redacted> also yielded root execution and captured root proof to loot/root-looney.txt.
Raw flags and reusable secrets must be stored only under loot/.
Attack Map
Confirmed Path
| Stage | Evidence | Result |
|---|---|---|
| Recon | nmap/initial.txt, nmap/allports.txt | SSH and HTTP only. HTTP redirects to 2million.htb. |
| Web app mapping | enum/http-host-baseline.txt, enum/form-fields.txt | Invite, register, login, and API routes confirmed. |
| Account creation | enum/authenticated-api-summary-20260527T093138Z.txt | Generated invite and authenticated as a throwaway web user. |
| Admin escalation | enum/admin-update-vpn-summary-20260527T093210Z.txt | JSON admin settings update set the current account as admin. |
| Command execution | enum/vpn-injection-summary-20260527T093235Z.txt | VPN generation username parameter executed as www-data. |
| SSH foothold | enum/admin-ssh-baseline-20260527T093428Z.txt, loot/user.txt | Application config credential reuse gave SSH as admin; user flag captured. |
| Root | loot/root-exploit-xkaneiki-output-20260527T095404Z.txt, loot/root.txt | <secret redacted> OverlayFS/FUSE PoC produced root execution and root flag capture. |
| Alternative root | enum/root-exploit-looney-summary-20260527T101434Z.txt, loot/root-looney.txt | <secret redacted> Looney Tunables PoC produced root execution through <secret redacted>. |
Key Decisions
- Used
curl --resolveinstead of relying on a persistent/etc/hostsedit on the Pwnbox. - Corrected registration from
invite_codeto the form-backedcodeparameter. - Used JSON content type for admin update and VPN generation after form posts returned content-type errors.
- Switched from the first single-binary OverlayFS PoC to the two-process <secret redacted> workflow after the first PoC did not trigger on this kernel.
Memory Summary
TwoMillion validated chain:
- Add
2million.htbor usecurl --resolve; IP root redirects to the vhost. - Invite workflow allows generating a code and registering with form field
code. - Authenticated
/api/v1route list exposes admin settings and VPN generation. - JSON
PUT /api/v1/admin/settings/updatewith the registered email and admin flag can set the current account as admin. - JSON
POST /api/v1/admin/vpn/generatecommand-injects throughusername. - Web app
.envcontains a reusable credential that works for SSH asadmin. - Local mail points to OverlayFS/FUSE; on Ubuntu 22.04 kernel
5.15.70-051570-generic, the two-process <secret redacted> PoC worked where the first single-binary PoC did not.
Do not store raw invite codes, cookies, app credentials, or flags outside loot/.
Dead Ends
| Branch | Evidence | Reason Closed | Revisit Condition |
|---|---|---|---|
Register/login through /register and /login POSTs | enum/register-login-status.txt | Both returned 405; forms use /api/v1/user/register and /api/v1/user/login. | Only if frontend route behavior changes. |
Registration with invite_code JSON field | enum/authenticated-api-summary-20260527T093016Z.txt, enum/form-fields.txt | Register form expects code; auth stayed false with the wrong field. | Only if API schema changes. |
| Admin VPN generation with form content type | enum/admin-update-vpn-summary-20260527T093210Z.txt | Endpoint returned invalid content-type messages. | Use JSON content type. |
Reused app password for sudo -l | enum/admin-ssh-baseline-20260527T093428Z.txt | sudo rejected it. | Revisit only if another local password is discovered. |
| Single-binary <secret redacted> PoC | loot/root-exploit-output-20260527T093806Z.txt | Failed to trigger copy-up on this kernel. | Use a different PoC or adapt FUSE behavior. |
Notes
Scope
| Field | Value |
|---|---|
| Platform | Hack The Box / simulated lab |
| Target | TwoMillion |
| Difficulty | Easy |
| OS | Linux |
| Active target IP | <TARGET> |
| Pwnbox | Provided by operator; SSH currently unreachable from local controller |
| Local controller | Mac workspace under <local workspace> |
| Started | 2026-05-27T05:24:48Z |
Evidence Ledger
| Time UTC | Action | Output file | Finding | Confidence | Next action |
|---|---|---|---|---|---|
| 2026-05-27T05:24:48Z | Harness setup | n/a | Loaded HTB machine workflow, Pwnbox workflow, web patterns, quick wins, and file transfer guidance. | High | Initialize workspace and test reachability. |
| 2026-05-27T05:25Z | Pwnbox SSH reachability | n/a | Pwnbox SSH was refused/filtered from local controller; public HTTP/HTTPS appeared exposed but did not produce usable CLI access. | Medium | Proceed locally because target web service is directly reachable. |
| 2026-05-27T05:26Z | Direct target reachability | /tmp/twomillion-direct-portcheck.txt | Target responded to -Pn TCP check: port 80 open, port 22 filtered. | High | Run baseline recon and web enumeration. |
| 2026-05-27T05:27Z | HTTP route validation | enum/http-root-after-vpn.err, enum/raw-http-root.txt, enum/route-get-target.txt | Local route to target used the normal default gateway and TCP/80 produced no HTTP bytes; this is not a valid HTB lab route. | High | Establish HTB VPN or reachable Pwnbox SSH before exploitation. |
| 2026-05-27T05:37Z | Local HTB VPN attempt | enum/openvpn-startingpoint.log, enum/openvpn-startingpoint-v4.log | Local Starting Point OpenVPN profile reached TLS certificate verification but did not complete or install a target route; process stopped. | Medium | Use active Pwnbox SSH or start a working HTB VPN profile outside this session. |