You have a string wrapped in three layers. What now?
A picoCTF prompt hands you something like NzA2OTYzNkY0MzU0NDY3QjZBNzM2RjZFNUY2OTczNUY2MTZDNkY3NDVGNkY2NjVGNkY3NjY1NzI2QjY5NkM2QzVGNjg2NTZDNzA1RjdE. It is not the flag. It is base64, and inside that is hex, and inside that is ASCII. You could open three browser tabs and copy-paste between them, or you could stack the two decoders into one pipeline and read the flag in a second.
That pipeline tool lives on this site. It is called Recipe Chain, and it is the CyberChef alternative you reach for when you do not want to leave the page. It chains 80+ decoders into a single byte pipeline, has a Magic mode that auto-discovers the recipe for you, runs entirely in your browser so your input is never uploaded, and stores the whole recipe in the URL so you can bookmark or share it. This post is the field guide: when to use it, how to stack layers by hand, when to brute-force a key, and the one situation where you should close the tab and write Python instead.
Most CTF "crypto" challenges in the early rounds are not crypto at all. They are encodings stacked on encodings, and the whole puzzle is figuring out the order.
How does the pipeline actually work?
The model is the same one CyberChef popularized, and it is worth understanding because it explains every quirk you will hit. The pipeline is byte-oriented. Each operation receives the raw bytes produced by the previous step and returns new bytes. There is no "string" passed between steps; there are only bytes, and the output area decides at the end whether those bytes look like UTF-8 text or whether it should fall back to a hex view.
So a recipe is just an ordered list of operations. Your input enters at the top, flows through each step, and the bottom of the stack is your answer. If a step in the middle produces garbage, every step after it produces garbage too, which is exactly the signal you want: the first step whose output stops looking like a valid encoding is usually the wrong step or the wrong order.
INPUT: Vm0wd2QyVnRWa2RXV0doWFYwZG9WVll3... (looks like base64)step 1 From Base64 -> raw bytesstep 2 From Hex -> more bytesstep 3 ROT13 -> ascii textOUTPUT: picoCTF{the_flag_appears_here}
Because the contract between steps is "bytes in, bytes out," you can put almost anything next to anything else. From Base64 then From Hex then ROT13 is a valid recipe. So is XOR then From Base32 then a SHA-256 hash. The tool does not care whether the combination is sensible; it just runs the bytes through. That freedom is the whole point.
What is Magic mode and when should I trust it?
Pasting an unknown blob and guessing the layers by hand is slow. Magic mode is the answer. You drop the ciphertext in, switch on Magic, and the tool tries common operations against your input, scores the results by how much they look like real data (printable ratio, the presence of picoCTF{, entropy, dictionary words), and surfaces the candidate recipes that move you closest to readable text. It is the magic decoderhalf of the "decode multiple layers" problem: instead of you knowing it is base64-then-hex, the tool proposes that chain.
The honest version of how to use it: Magic is a strong first guess, not an oracle. It is excellent at the boring layers, base64, hex, the ROT family, URL encoding, and at telling you "this is clearly Base58, not Base64." It is weaker once a real key is involved, because XOR with an unknown multi-byte key or a Vigenere with an unknown keyword has too large a search space to brute in the browser instantly.
When Magic stalls and shows you nothing convincing, that is information too. It usually means the next layer is keyed (XOR, Vigenere, a substitution cipher) rather than a plain encoding. At that point jump to the classical ciphers guide or the CTF encodings reference to identify the family, then come back and add the right keyed step.
How do I chain encodings by hand?
When you already suspect the layers, building the recipe by hand is faster than Magic and teaches you to read encodings on sight. You add operations one at a time and watch the output change after each. The discipline is: add one step, look at the output, decide whether it moved you toward text or away from it, keep or remove.
Here is the canonical three-layer example. The ciphertext below is picoCTF{layers} wrapped in ROT13, then hex, then base64. You decode it by running the layers in reverse:
Ciphertext (paste into the input box):NEU3MzZINjU2RDY1NUY3MzZINjU2QzZDRecipe (add these steps top to bottom):1. From Base64 -> A736865... (hex digits appear)2. From Hex -> cvpbPGS{...} (ROT13 ciphertext)3. ROT13 -> picoCTF{...} (flag)
Notice the diagnostic value of each intermediate. After step 1 you see hex digits, so you know the next layer is From Hex. After step 2 you see text that is almost a flag but the letters are rotated, so you know the last layer is a ROT. You are not guessing blindly; each layer announces what the next one should be. This is the single most useful habit in encoding challenges: read the intermediate, let it tell you the next move.
The order matters, and getting it wrong is the most common mistake. If you put From Hex before From Base64 on the example above, step 1 sees base64 characters, tries to read them as hex, chokes on the non-hex bytes, and you get garbage. When a chain produces nonsense at a step you were confident about, the usual fix is not a different operation; it is the same two operations in the opposite order.
How do I handle a XOR layer with an unknown key?
XOR is where a lot of chains stall, because unlike base64 there is a key you do not have. Two cases cover almost everything you will see in a CTF.
Single-byte XOR. The entire ciphertext is XORed against one byte, 0 to 255. The search space is tiny, so you brute-force all 256 keys and pick the result that looks like text. The chain has a single-byte XOR step that sweeps every key and scores the outputs, surfacing the one with the highest printable ratio or the one that contains picoCTF{. This is the most common XOR in beginner challenges, and it falls in a fraction of a second.
Single-byte XOR brute force, the manual logic:for key in range(256):candidate = bytes(b ^ key for b in ciphertext)if b'picoCTF{' in candidate:print(key, candidate)The chain's XOR step does this sweep for you and ranks the hits.
Known-key (multi-byte) XOR. Sometimes the challenge tells you the key, or you recover it (a crib like the known flag prefix XORed against the ciphertext leaks the repeating key). Here you do not brute-force; you type the key in and apply it. The XOR step takes a key as text, hex, or base64, repeats it across the ciphertext, and XORs. If the key is right, text falls out immediately.
picoCTF{, XOR those 8 known bytes against the first 8 ciphertext bytes and you recover the first 8 bytes of the key. If the key is shorter and repeats, you may have the whole key already. The dedicated XOR Cipher tool has a known-plaintext mode for exactly this, then you bring the recovered key back to the chain.XOR also composes with everything else, which is why it belongs in a chain rather than a one-off tool. A realistic layered challenge is base64 on the outside, XOR in the middle, and hex on the inside. You decode the base64, brute the single-byte XOR, then From Hex, all in one stack. For the theory behind repeating-key and stream constructions, the stream ciphers in CTFs post covers why key reuse is fatal and how to exploit it.
Can I jump to a dedicated tool and come back?
Yes, and this is the feature that makes the chain practical rather than a toy. Every step in the recipe has an Open dedicated tool link. Click it on a XOR step and you land on the full XOR Cipher page with its brute-force grid, known-plaintext mode, and multi-layer view. Click it on a Morse step and you get the full Morse Decoder with timing options. Work out the hard part in the focused tool, then return to the chain to keep stacking.
The chain is the assembly line. The dedicated tools are the workbenches. You move a part to the workbench when it needs precision, then bolt it back onto the line.
This split matters because the single-purpose tools can afford a richer interface. The chain step shows you a compact XOR control; the dedicated XOR page shows you all 256 single-byte candidates in a scrollable grid with scores, frequency analysis, and a known-key recovery panel. You would not want that much UI inside every step of a five-step recipe, but you absolutely want it when one step is the whole puzzle.
When is a chain the wrong tool?
A pipeline is the right tool when the work is a fixed sequence of transforms applied once. It is the wrong tool the moment you need a loop, a branch, or a search that the built-in brute-force does not cover. Knowing where the line is saves you from fighting the UI.
Reach for Python instead of a chain when:
- You need to try thousands of keys or candidate orderings programmatically, not the small fixed sweeps the chain offers.
- The decode depends on data the chain cannot see: a network response, a file you have to parse, or a server you have to talk to with
ncorrequests. - There is real cryptography involved, RSA, AES with a derived key, an elliptic-curve problem. Those want a library, not a transform list. See the RSA attacks guide for the math-heavy cases.
- You need to integrate the decode into a larger exploit script that does more than decoding.
The tell is conditional or repeated logic. A chain is a straight line. The moment your solution has an if or a while in it, a script is cleaner. Here is the same base64-then-XOR-then-hex decode as a few lines of Python, the fallback for when you want to script it:
import base64blob = open('ciphertext.txt').read().strip()layer1 = base64.b64decode(blob) # From Base64# single-byte XOR brute forcefor key in range(256):layer2 = bytes(b ^ key for b in layer1)try:flag = bytes.fromhex(layer2.decode()) # From Hexexcept ValueError:continueif b'picoCTF{' in flag:print(key, flag)
For the broader scripting toolkit, the hex dumps post covers reading raw bytes, and the steganography post covers the cases where the data is hidden in a file rather than encoded in a string. If the flag is buried in an image or audio file, no decoder chain will find it; that is a different hunt.
Which picoCTF challenges does this crack?
Encoding and classical-cipher challenges are a staple of every picoCTF event, and the chain is built for exactly them. A few that map cleanly onto the workflow above:
- picoCTF 2024 interencdec is the poster child: nested base64 and ROT layers that you peel one step at a time. Magic mode proposes most of the stack; you finish it by hand.
- picoCTF 2019 Tapping is Morse over a netcat connection. Grab the dots and dashes, drop them in a Morse step, and read the flag. The dedicated Morse Decoder handles the timing edge cases.
- picoCTF 2024 Elements hides the flag behind a periodic-table substitution, a reminder that not every layer is a standard encoding. Identify the scheme, then a single mapping step finishes it.
- picoCTF 2021 Nice netcat delivers the flag as a stream of decimal byte values. Convert from the number list to bytes and the text appears, a one-step chain that would otherwise be tedious by hand.
For the conceptual background on every encoding you will meet, keep the CTF encodings reference and the classical ciphers guide open in another tab. The chain is the muscle; those posts are the memory.
Quick reference: common recipes
Recipes worth memorizing
Looks like base64 but decodes to more base64:From Base64 -> From Base64 -> (repeat until text)Hex digits only (0-9 a-f):From Hex -> read the textBase64 that decodes to hex:From Base64 -> From HexAlmost-a-flag but letters are shifted:ROT13 (or sweep ROT 1-25, or ROT47 for symbols)Random-looking bytes, no key given:Single-byte XOR (brute all 256) -> inspect best scoreDots and dashes:From Morse -> read the textComma- or space-separated decimal numbers:From Decimal / byte list -> read the textUnknown blob, no idea:Magic mode -> accept proposed recipe -> finish by hand
Decision order on an unknown string
- Paste it into Recipe Chain and turn on Magic.
- Accept the obvious outer layers Magic proposes (base64, hex, ROT, URL).
- Read the intermediate output; it tells you what the next layer is.
- Hit a keyed layer? Brute single-byte XOR, or recover a known key with the crib trick.
- One step is the whole puzzle? Open the dedicated tool, solve, come back.
- Found it? Bookmark the URL so the recipe is saved and shareable.
- Need a loop or a network call? Stop and write the Python.
The whole tool exists so you stop juggling browser tabs and copy-paste. It is a CyberChef alternative that keeps you on the page, never uploads your bytes, and turns a solved puzzle into a single shareable link. Open Recipe Chain, paste your blob, flip on Magic, and watch the layers fall.
If you can read the intermediate output after each step, you do not need to know the answer in advance; the chain tells you the next move one layer at a time.