Challenge / Web

MagicalPalindrome

Name: - Category: - Difficulty: Raw flag is stored in

Very EasyPublished 2025-09-19Sanitized local writeup

Scenario

MagicalPalindrome attack path

Name: - Category: - Difficulty: Raw proof is stored in

Objective

Challenge walkthrough focused on Web evidence, validation, and reusable operator lessons.

MagicalPalindrome sanitized attack graph

Walkthrough flow

01

Source and route audit

02

Trust boundary flaw

03

Exploit request chain

04

Admin or proof proof

Source coverage

Moderate source coverage

Status: partial. This article is generated from 4 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.

65% coverage
Evidence verdict

Moderate confidence: the page is useful for review, but it should be treated as partial because the available source material is thinner or less narrative-complete.

  • Web/MagicalPalindrome/writeup.md
  • htb-challenge/Web/MagicalPalindrome/notes.md
  • htb-challenge/Web/MagicalPalindrome/memory-summary.md
  • htb-challenge/Web/MagicalPalindrome/hypothesis-board.md

Technical Walkthrough

Writeup

Challenge

  • Name:
  • Category:
  • Difficulty:

Summary

Artifact Inventory

Analysis

Solve

Flag

Raw flag is stored in loot/flag.txt.

Lessons

Source-Backed Dossier

The sections below are merged from companion Markdown notes for the same case. They are rendered after sanitization so the article stays precise without publishing raw flags, credentials, or target-specific secrets.

Notes

Scope

  • Challenge: Magical Palindrome
  • Category: Web
  • Difficulty: Very Easy
  • Target: http://<TARGET>:30732/
  • Started: 2026-05-07

Evidence Ledger

TimestampActionFindingNext
00:00Extract zip, read sourceHono app, palindrome check, nginx 75-byte body limitAnalyze constraints
00:01Read nginx.confclient_max_body_size 75 — body must be under 75 bytesFind type confusion
00:03Tried array of 1001 strings413 — payload too largeTry gzip
00:04Tried gzip compressionPassed nginx (46 bytes) but 500 — server can't decompressType confusion
00:08Sent object with string lengthFlag returned! 52-byte payload passes all checksDone

Vulnerability

  • Type: JSON type confusion + JavaScript coercion
  • Constraint: nginx limits body to 75 bytes, palindrome needs .length >= 1000
  • Trick: Pass an object with "length": "1001" (STRING, not number)

- "1001" < 1000 → JS coerces to 1001 < 1000 → false (passes length check)

- Array("1001") creates ["1001"] (1-element array, NOT 1001-element sparse array)

- Loop runs only ONCE (index 0), needs only properties "0" and "1000"

- Payload: {"palindrome":{"length":"1001","0":"a","1000":"a"}} = 52 bytes

| 2026-05-27T23:35:17Z | backfill | challenge-state.json | Legacy workspace backfilled with deterministic state | High | Validate before further work |

Memory Summary

Metadata

  • Platform: HackTheBox Challenges
  • Category:
  • Challenge:
  • Difficulty:
  • Source workspace:

Validated Solve Chain

Concepts only. Do not include raw flags, reusable credentials, tokens, cookies, private keys, or live secrets.

1.

Reusable Lessons

-

Dead Ends

-

Tool Quirks

-

Evidence Paths

-

Ingestion Decision

  • Proposed for LightRAG: yes/no
  • Requires user approval before ingestion: yes

Hypothesis Board

RankPathEvidenceMissing ProofCheapest ValidationConfidenceStatus

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit Condition

Technical analogy

How to remember this solve

Think of the web app like a building with signs on every door. The solve usually comes from reading the map carefully, finding the door the app forgot to hide, then sending the exact request that proves you understand the route.

For MagicalPalindrome, keep the mental model simple: identify the trusted assumption, prove it with the smallest safe test, then automate or repeat only the part that directly leads to the flag.