Description
We intercepted a suspiciously encoded message, but it's clearly hiding a flag. No encryption, just multiple layers of obfuscation. Can you peel back the layers and reveal the truth? Download the message.txt .
Setup
Download message.txt and examine its contents.
Identify which encoding is the outermost layer.
cat message.txt
Solution
- Step 1Download and inspect the messageDownload message.txt and look at the outermost encoding. The string uses multiple stacked encodings — no encryption, just encoding transforms.cat message.txt
- Step 2Identify encoding layers and peel themEach layer is one of: binary (groups of 8 bits), octal (3-digit groups 0-7), decimal ASCII (space-separated numbers 0-127), hex (even-length hex string), URL encoding (% sequences), base32 (A-Z2-7=), base64 (A-Za-z0-9+/=), ROT13, Atbash, or Morse code (dots and dashes). Keep decoding until picoCTF{} appears.cat message.txt | base64 -d 2>/dev/nullcat message.txt | xxd -r -p 2>/dev/nullpython3 -c "import base64; print(base64.b32decode(open('message.txt').read().strip()+'====').decode())"
- Step 3Auto-peel all layers with a scriptUse this script to automatically detect and peel every encoding layer in sequence until the flag is revealed.python3 - <<'EOF' import base64, re, urllib.parse MORSE = {'.-':'A','-...':'B','-.-.':'C','-..':'D','.':'E','..-.':'F', '--.':'G','....':'H','..':'I','.---':'J','-.-':'K','.-..':'L', '--':'M','-.':'N','---':'O','.--.':'P','--.-':'Q','.-.':'R', '...':'S','-':'T','..-':'U','...-':'V','.--':'W','-..-':'X', '-.--':'Y','--..':'Z','-----':'0','.----':'1','..---':'2', '...--':'3','....-':'4','.....':'5','-....':'6','--...':'7', '---..':'8','----.':'9'} def peel(s): s = s.strip() c = re.sub(r'[\s:0x\\]', '', s) # binary cb = s.replace(' ','').replace(',','') if re.fullmatch(r'[01]+', cb) and len(cb)%8==0: try: t=''.join(chr(int(cb[i:i+8],2)) for i in range(0,len(cb),8)); return 'binary',t except: pass # morse if re.fullmatch(r'[./- \t\n]+', s) and ('.' in s or '-' in s): try: words=[' '.join(MORSE.get(l,'?') for l in w.strip().split()) for w in s.split('/')] return 'morse',' '.join(words) except: pass # octal parts=re.split(r'[\s,]+', s) if len(parts)>3 and all(re.fullmatch(r'[0-7]{1,3}',p) for p in parts): try: return 'octal',''.join(chr(int(p,8)) for p in parts) except: pass # decimal ASCII try: nums=[int(p) for p in parts] if len(nums)>3 and all(32<=n<=126 for n in nums): return 'decimal',''.join(chr(n) for n in nums) except: pass # hex if re.fullmatch(r'[0-9a-fA-F]+', c) and len(c)%2==0: try: return 'hex', bytes.fromhex(c).decode() except: pass # URL if '%' in s: t=urllib.parse.unquote(s) if t!=s: return 'url', t # base32 try: t=base64.b32decode(s.upper()+'========').decode() if t.isprintable(): return 'base32', t except: pass # base64 try: t=base64.b64decode(s+'==').decode() if t.isprintable(): return 'base64', t except: pass # rot13 t=s.translate(str.maketrans( 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm')) if 'pico' in t.lower(): return 'rot13', t return None, s data = open('message.txt').read().strip() for i in range(20): if m:=re.search(r'picoCTF[{][^}]+[}]', data): print('FLAG:', m.group()); break name, data = peel(data) if name: print(f'[{i+1}] {name}: {data[:80]}') else: print('No decoder matched'); break EOF
Flag
picoCTF{mult1c0d3_...}
Multiple stacked encoding layers (binary, octal, decimal ASCII, hex, URL, base32, base64, ROT13, Atbash, Morse). The script auto-detects and peels each layer until picoCTF{} appears.