flag format: 0xV01D{...} giải rồi viết write up ch...

Creado el: 18 de mayo de 2026

Respondido usando GPT-5.5 Thinking por Chat01

Pregunta

challenge.txt
image.png

flag format: 0xV01D{...}
giải rồi viết write up chi tiết kèm lệnh + script đã dùng

Python

python
from pathlib import Path p=Path('/mnt/data/challenge.txt') data=p.read_bytes() len(data), data[:200], data[-200:] (6238, b'In the beginning, there was nothing.\nThen nothing whispered: let there be layers upon layers.\nSome say the answer lies within the silence between words.\nOthers believe it hides in plain sight, staring', b"n0t_qu1te_lol}\nOr perhaps it was never here at all.\nThe void speaks in whispers you cannot hear with your ears.\nListen with your tools. All of them. Every. Single. One.\nGood luck. You'll need it. \xf0\x9f\x98\x88")

Python

python
text=p.read_text('utf-8') len(text), text[:500] (2779, "In the beginning, there was nothing.\nThen nothing whispered: let there be layers upon layers.\nSome say the answer lies within the silence between words.\nOthers believe it hides in plain sight, staring back at you.\nThe number 677 means everything. Or maybe nothing. Who knows?\nDecoded message: dGhpcyBpcyBub3QgdGhlIHdheSBsb2wgdHJ5IGhhcmRlcg==\nSeek and you shall find. Or maybe you won't. HAHAHAHA.\nThe wise man once said: U NEED TO DO 677.\u200b\u200b\u200c\u200c\u200b\u200b\u200c\u200c\u200d\u200b\u200b\u200c\u200c\u200b\u200c\u200b\u200c\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200c\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200b\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200c\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200b\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200c\u200b")

Python

python
from collections import Counter cnt=Counter(text) for ch,c in cnt.items(): if ord(ch)>127 or ord(ch)<32 and ch not in '\n\t': print(hex(ord(ch)), repr(ch), c) print("newlines", cnt['\n']) # extract zero-width chars U+200B ZWSP, U+200C ZWNJ, U+200D ZWJ etc zws=''.join(ch for ch in text if ch in '\u200b\u200c\u200d\ufeff\u2060') len(zws), Counter(zws) (1728, Counter({'\u200b': 808, '\u200c': 728, '\u200d': 192}))

Python

python
seq=zws groups=seq.split('\u200d') len(groups), Counter(len(g) for g in groups), groups[:5], groups[-3:] (193, Counter({8: 192, 0: 1}), ['\u200b\u200b\u200c\u200c\u200b\u200b\u200c\u200c', '\u200b\u200b\u200c\u200c\u200b\u200c\u200b\u200c', '\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200c', '\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200b', '\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200c'], ['\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200b', '\u200b\u200c\u200c\u200b\u200c\u200c\u200c\u200c', ''])

Python

python
def decode_bits(map0): # map dict {zwsp:'0', zwnj:'1'} etc bits=[] for g in groups: if len(g)==8: bits.append(''.join(map0[ch] for ch in g)) bs=bytes(int(b,2) for b in bits) return bs for mapping in [ {'\u200b':'0','\u200c':'1'}, {'\u200b':'1','\u200c':'0'} ]: bs=decode_bits(mapping) print(mapping, bs[:100], bs) try: print(bs.decode('utf-8')) except Exception as e: print(e)

Python

python
s=decode_bits({'\u200b':'0','\u200c':'1'}).decode() len(s), s (192, '35101021a8r432431nisli89itp1304654316e1t4785939f5xr2l87h8887n1nii25630wrfujy8rlir05m57242l14l9918740y9rc9920v9e35ws39066l107907e0027493ok1g06k69y0ma7rjw8s3n82d618957r3kgit871931mfv2h7wp6m1f10o')

Python

python
import string, re, base64, binascii, codecs, math, itertools, collections alph=string.digits+string.ascii_lowercase def caesar_base36(s, shift): return ''.join(alph[(alph.index(c)-shift)%36] if c in alph else c for c in s) for sh in [677%36, -(677%36), 1, -1, 26, -26, 29, 7]: print(sh, caesar_base36(s, sh)[:100])

Python

python
for variant in ['std']: try: b=base64.b64decode(s, validate=True) print(len(b), b[:100]) print(b.decode('utf-8','replace')[:200]) except Exception as e: print("b64 err",e) # base32? base36 decode? hex? try: print(bytes.fromhex(s[:100])) except Exception as e: print("hex err", e)

Python

python
lines=text.splitlines() for i,line in enumerate(lines,1): # remove zero-width? print(i, repr(line[-20:]), "last", repr(line[-1]), hex(ord(line[-1]))) print("lines", len(lines)) print("last chars no hidden?", ''.join(line[-1] for line in lines if line)) # last visible char ignoring zero width? def last_visible(line): for ch in reversed(line): if ch not in '\u200b\u200c\u200d': return ch key=''.join(last_visible(line) for line in lines if line) key '....?=..)))))}}}...😈'

Python

python
import re, string, base64, binascii, itertools, math def rail_fence_decrypt(cipher, rails): if rails == 1: return cipher # pattern of rail indices pattern = list(range(rails)) + list(range(rails-2,0,-1)) rail_indices = [pattern[i % len(pattern)] for i in range(len(cipher))] counts = [rail_indices.count(r) for r in range(rails)] rails_str=[] idx=0 for c in counts: rails_str.append(list(cipher[idx:idx+c])); idx+=c pos=[0]*rails out=[] for r in rail_indices: out.append(rails_str[r][pos[r]]); pos[r]+=1 return ''.join(out) def rail_fence_encrypt(plain, rails): if rails==1: return plain rails_arr=['']*rails pattern=list(range(rails))+list(range(rails-2,0,-1)) for i,ch in enumerate(plain): rails_arr[pattern[i%len(pattern)]]+=ch return ''.join(rails_arr) for r in range(2,21): dec=rail_fence_decrypt(s,r) enc=rail_fence_encrypt(s,r) for name,t in [('dec',dec),('enc',enc)]: if re.search(r'0xV01D|flag|0xv01d|v01d', t, re.I): print("found", r,name,t) print("r",r, "dec", dec[:80], "enc", enc[:80])

Python

python
b=base64.b64decode(s) def score_ascii(bs): return sum(32<=x<127 or x in (9,10,13) for x in bs)/len(bs) best=[] for k in range(256): x=bytes(c^k for c in b) best.append((score_ascii(x), k, x[:100])) best=sorted(best, reverse=True)[:10] for sc,k,x in best: print(sc,k,x) print(x.decode('latin1')[:120])

Python

python
try: from Crypto.Cipher import AES from Crypto.Util.Padding import unpad print("pycryptodome ok") except Exception as e: print("no crypto", e)

Python

python
try: from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend print("cryptography ok") except Exception as e: print("no cryptography", e)

Python

python
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import padding, hashes from cryptography.hazmat.backends import default_backend from hashlib import md5, sha256, sha1 def aes_decrypt(data,key,mode='ECB',iv=None): if mode=='ECB': cipher=Cipher(algorithms.AES(key), modes.ECB()) elif mode=='CBC': cipher=Cipher(algorithms.AES(key), modes.CBC(iv or bytes(16))) dec=cipher.decryptor() return dec.update(data)+dec.finalize() def try_keys(): candidates=[] bases=[ b"677", b"676", b"0xV01D", b"0xv01d", b"0xV01D Team", b"0xV01DTeam", b"U NEED TO DO 677", b"U NEED TO DO 677 HAHAHAHA", b"HAHAHAHA", b"last character of each line", b"trust me bro", b"what you see is not what you get", b"What You See Is Not What You Get", b"nothing", b"void", b"silence", ] # strings derived last chars for ks in [ ''.join(line[-1] for line in lines if line).encode('utf-8','ignore'), ''.join(last_visible(line) for line in lines if line).encode('utf-8','ignore')]: bases.append(ks) for base in bases: variants=[base] variants.append((base*16)[:16]) variants.append((base*24)[:24]) variants.append((base*32)[:32]) variants.append(md5(base).digest()) variants.append(sha256(base).digest()) variants.append(sha1(base).digest()[:16]) variants.append(base.ljust(16,b'\0')[:16]) variants.append(base.ljust(24,b'\0')[:24]) variants.append(base.ljust(32,b'\0')[:32]) for key in variants: if len(key) in (16,24,32): for mode in ['ECB','CBC']: for iv in [bytes(16), md5(base).digest(), b'677'*5+b'6'] if mode=='CBC' else [None]: try: pt=aes_decrypt(b,key,mode,iv) sc=score_ascii(pt) if sc>0.7 or b'0xV01D' in pt or b'flag' in pt.lower(): candidates.append((sc, base, len(key), mode, iv, pt[:200])) except Exception as e: pass return sorted(candidates, reverse=True, key=lambda x:x[0]) cands=try_keys() len(cands) 0

Python

python
keys=[ ''.join(line[-1] for line in lines if line).encode('utf-8'), ''.join(last_visible(line) for line in lines if line).encode('utf-8'), b"677", b"HAHAHAHA", b"U NEED TO DO 677", b"0xV01D"] for data_name,data in [('b64bytes', b), ('hidden_ascii', s.encode())]: print('---',data_name) for key in keys: x=bytes(c ^ key[i%len(key)] for i,c in enumerate(data)) print("key",key[:40], "score", score_ascii(x), x[:120]) if b'0xV01D' in x or b'flag' in x.lower(): print("FOUND",x)

Python

python
sb=s.encode() def english_score(bs): text=''.join(chr(b) if 32<=b<127 else ' ' for b in bs).lower() common=' etaoinshrdl{}_0123456789xv' return sum(text.count(c)*w for w,c in enumerate(common[::-1],1)) - 10*sum(b<32 or b>126 for b in bs) best=[] for k in range(256): x=bytes(c^k for c in sb) if all(32<=c<127 or c in (10,13,9) for c in x): best.append((english_score(x), k, x[:200])) for score,k,x in sorted(best, reverse=True)[:20]: print(score,k,repr(x[:120]))

Python

python
from collections import Counter cnt=Counter(s) print(cnt) print(len(set(s))) for k,v in cnt.most_common(): print(k,v)

Python

python
idx=text.find('\u200b') print(idx, text[:idx][-100:], len(text[:idx])) print("byte idx", data.find('\xe2\x80\x8b'.encode() if False else b'\xe2\x80\x8b'))

Python

python
print(data.find(b'\xe2\x80\x8b'), data.find(b'\xe2\x80\x8c'), data.find(b'\xe2\x80\x8d')) print(len(text[:idx].encode()))

Python

python
print(data[430:480]) print([hex(b) for b in data[438:450]]) for ch in text[438:450]: print(hex(ord(ch)), ch.encode())

Python

python
raw=Path('/mnt/data/challenge.txt').read_bytes() print(len(raw), raw[430:480], raw.find(b'\xe2\x80\x8b')) print(text.encode('utf-8')[430:480])

Python

python
for mapping in [ {'\u200b':'0','\u200c':'1'}, {'\u200b':'1','\u200c':'0'}]: for rev in [False, True]: chars=[] for g in groups: if len(g)==8: bits=''.join(mapping[ch] for ch in g) if rev: bits=bits[::-1] chars.append(int(bits,2)) bs=bytes(chars) print(mapping, "rev",rev, bs[:80], score_ascii(bs)) try: print(bs.decode('utf-8')[:200]) except Exception as e: print("decode err")

Python

python
def shift_digits_letters(s, key): out=[] for i,c in enumerate(s): k=int(key[i%len(key)]) if c.isdigit(): out.append(str((int(c)-k)%10)) elif c.isalpha(): out.append(chr((ord(c)-97-k)%26+97)) else: out.append(c) return ''.join(out) print(shift_digits_letters(s,'677')[:200]) print(shift_digits_letters(s,'677')) # Add instead def shift_add(s, key): out=[] for i,c in enumerate(s): k=int(key[i%len(key)]) if c.isdigit(): out.append(str((int(c)+k)%10)) elif c.isalpha(): out.append(chr((ord(c)-97+k)%26+97)) else: out.append(c) return ''.join(out) print(shift_add(s,'677')[:200])

Python

python
def caesar_letters(s, shift): out=[] for c in s: if c.islower(): out.append(chr((ord(c)-97-shift)%26+97)) elif c.isupper(): out.append(chr((ord(c)-65-shift)%26+65)) else: out.append(c) return ''.join(out) for sh in [1,-1,677%26,-677%26,13,5,-5,7,-7]: print(sh, caesar_letters(s, sh)[:120])

Python

python
def caesar_printable(s, shift): out='' for c in s: o=ord(c) if 32<=o<=126: out+=chr((o-32-shift)%95+32) else: out+=c return out for sh in [677%95, -677%95, 677%36, -677%36]: print(sh, repr(caesar_printable(s,sh)[:120]))

Python

python
for w in [8,16,24,32,48,64]: print("w",w) for i in range(0,len(s),w): print(s[i:i+w]) print()

Python

python
def columns_read(s,width): rows=[s[i:i+width] for i in range(0,len(s),width)] return ''.join(''.join(row[c] for row in rows if c<len(row)) for c in range(width)) for w in range(2,50): out=columns_read(s,w) if '0x' in out or '0xv' in out.lower() or 'flag' in out.lower() or 'v01' in out.lower(): print(w,out) # inspect common widths for w in [8,12,16,24,32]: print("width",w, columns_read(s,w)[:200])

Python

python
for step in range(2,50): for off in range(step): t=s[off::step] if '0x' in t.lower() or 'v01' in t.lower() or 'flag' in t.lower() or '{' in t: print(step,off,t)

Python

python
n=int(s,36) bs=n.to_bytes((n.bit_length()+7)//8,'big') len(bs), bs[:100], score_ascii(bs) (124, b'"rK\xa7\xc7I\xd6\xbd\xe0\x8b\x9a)No\xefT`\xa9\xc2\x967`;<\xc5\x8a\x03\xda\x1eX\x8e\xbdH\x91\x0f\xc7\xa2\xae*#\xff;j\xdf\xa5I\xae\xe9\xca\xeaQ\xfcDGj\xae\x14Y\x0b\x95\xff\x053J\x1b~<"\xad\x7f\xffz\x91\x0bw\x0c\x05\x83\xd0\xe1\xe6w\x91Z4\x11.1\xbc\xa5\xc7iG\xd2~=\x9e\xa6\xc5\xbc', 0.3951612903225806)

Python

python
chars=['\u200b','\u200c','\u200d'] for perm in itertools.permutations('012'): mp=dict(zip(chars,perm)) trits=''.join(mp[ch] for ch in zws) for width in range(3,13): vals=[] ok=True for i in range(0,len(trits)-width+1,width): val=int(trits[i:i+width],3) if val>255: ok=False break vals.append(val) if ok: bs=bytes(vals) sc=score_ascii(bs) if sc>0.85 or b'0x' in bs or b'flag' in bs.lower(): print("perm",perm,"width",width,"len",len(bs),"score",sc, bs[:200])

Python

python
for perm in itertools.permutations('012'): mp=dict(zip(chars,perm)) trits=''.join(mp[ch] for ch in zws) for width in [5]: vals=[int(trits[i:i+width],3) for i in range(0,len(trits)-width+1,width)] bs=bytes(vals) sc=score_ascii(bs) if sc>0.5: print("perm",perm,"score",sc,bs[:200]) print(bs.decode('latin1')[:200])

Python

python
def rot47(text, n=47): out='' for c in text: o=ord(c) if 33 <= o <= 126: out += chr(33 + ((o-33+n) % 94)) else: out += c return out for n in [47, 677%94, -677%94, 13, 19, -19]: print(n, repr(rot47(s,n)[:120]))

Python

python
alph='0123456789abcdefghijklmnopqrstuvwxyz' def vigenere_base36(s,key,enc=False): out=[] for i,c in enumerate(s): if c in alph: k=alph.index(key[i%len(key)]) idx=alph.index(c) out.append(alph[(idx + k if enc else idx-k)%len(alph)]) else: out.append(c) return ''.join(out) for k in ['677','u','void','0xv01d','hahaha']: print(k, vigenere_base36(s,k)[:120]) print(k, vigenere_base36(s,k,enc=True)[:120])

Python

python
for step in [2,3,4,5,6,7]: print("step",step) for off in range(step): print(off, s[off::step][:100]) print()

Python

python
letters=''.join(c for c in s if c.isalpha()) digits=''.join(c for c in s if c.isdigit()) len(letters), letters, len(digits), digits[:200] (70, 'arnisliitpetfxrlhnniiwrfujyrlirmllyrcvewsleokgkymarjwsndrkgitmfvhwpmfo', 122, '35101021843243189130465431614785939528788871256308055724214991874099920935390661079070027493106690783826189573871931276110')

Python

python
letters=''.join(c for c in s if c.isalpha()) digits=''.join(c for c in s if c.isdigit()) print(letters) for sh in range(26): t=caesar_letters(letters, sh) if any(word in t for word in ['flag','the','you','try','void','this']): print("caesar",sh,t) print("rail letters") for r in range(2,15): dec=rail_fence_decrypt(letters,r) if any(w in dec for w in ['flag','the','you','try','void','this','xv']): print(r, dec) print(r, dec[:100])

Python

python
digits=''.join(c for c in s if c.isdigit()) print(len(digits), digits) # parse decimal ASCII maybe 2/3 digits pairs=[int(digits[i:i+2]) for i in range(0,len(digits)-1,2)] print(pairs[:50], bytes([x for x in pairs if x<256])[:50]) # 3-digit parse trip=[int(digits[i:i+3]) for i in range(0,len(digits)-2,3)] print(trip[:30], ''.join(chr(x) if 32<=x<127 else '?' for x in trip[:50])) # apply with ascii from possible [32-126] greedy segmentation?

Python

python
runs=re.findall(r'\d+|[a-z]+', s) [(r, len(r)) for r in runs], len(runs) ([('35101021', 8), ('a', 1), ('8', 1), ('r', 1), ('432431', 6), ('nisli', 5), ('89', 2), ('itp', 3), ('1304654316', 10), ('e', 1), ('1', 1), ('t', 1), ('4785939', 7), ('f', 1), ('5', 1), ('xr', 2), ('2', 1), ('l', 1), ('87', 2), ('h', 1), ('8887', 4), ('n', 1), ('1', 1), ('nii', 3), ('25630', 5), ('wrfujy', 6), ('8', 1), ('rlir', 4), ('05', 2), ('m', 1), ('57242', 5), ('l', 1), ('14', 2), ('l', 1), ('9918740', 7), ('y', 1), ('9', 1), ('rc', 2), ('9920', 4), ('v', 1), ('9', 1), ('e', 1), ('35', 2), ('ws', 2), ('39066', 5), ('l', 1), ('107907', 6), ('e', 1), ('0027493', 7), ('ok', 2), ('1', 1), ('g', 1), ('06', 2), ('k', 1), ('69', 2), ('y', 1), ('0', 1), ('ma', 2), ('7', 1), ('rjw', 3), ('8', 1), ('s', 1), ('3', 1), ('n', 1), ('82', 2), ('d', 1), ('618957', 6), ('r', 1), ('3', 1), ('kgit', 4), ('871931', 6), ('mfv', 3), ('2', 1), ('h', 1), ('7', 1), ('wp', 2), ('6', 1), ('m', 1), ('1', 1), ('f', 1), ('10', 2), ('o', 1)], 82)

Python

python
bb=base64.b64decode(s) print(len(bb), bb.hex()) # entropy, bytes distribution print(Counter(bb).most_common(10))

Python

python
# Generate possible key strings from line ends; test AES both modes, XOR combos line_last_variants={} for ignore_hidden in [False, True]: for include_emoji in [True, False]: chars=[] for line in lines: if not line: continue ch=last_visible(line) if ignore_hidden else line[-1] if not include_emoji and ord(ch)>127: continue chars.append(ch) name=f"lastvis{ignore_hidden}_emoji{include_emoji}" line_last_variants[name]=''.join(chars) print(name, repr(''.join(chars)), len(''.join(chars)), len(''.join(chars).encode())) # subsets for name,keystr in line_last_variants.items(): print(name, keystr.encode())

Python

python
from itertools import combinations def try_aes_with_keys(keys): outs=[] for desc,key in keys: keyb=key if isinstance(key,bytes) else key.encode() for k in set([keyb[:16], keyb[-16:], keyb[:24], keyb[-24:], keyb[:32], keyb[-32:], md5(keyb).digest(), sha256(keyb).digest(), sha1(keyb).digest()[:16]]): if len(k) not in (16,24,32): continue for mode in ['ECB','CBC']: ivs=[None] if mode=='ECB' else [bytes(16), keyb[:16].ljust(16,b'\0'), keyb[-16:].rjust(16,b'\0'), md5(keyb).digest()] for iv in ivs: try: pt=aes_decrypt(bb,k,mode,iv) # try unpad pts=[pt] try: (10, [(0.4166666666666667, 'lastvisFalse_emojiFalse', b'M\x13\xc1;\x07<b\xeb\xf8[\xbd\xb0\xa8\x1b\xba\xb3d$\x9f\xb7\x02A\x0f\x9e\x8fi\xcb\nRC\xda\xd0', 'CBC', b'!v\x19\x91Ng\xaf\xa3\x89<\xa9\x02\x8f\xe3\x95\x85', b'\xe3\x06.V\xd1\xe5Ls0\x10\xbe\xb6\xae\x13$\xbbdv\xbea|\xb9!\x13\xfa\\c\x91\xc1\x96\x9aq\xc7 I<%\xd4Q\x98\x80A\xf8\xb2\x00\xe5\xde\xe9p\xe6G\xe7g\xa0\x9f\x89Q\xfaO\xde\xad\x1b\xca{Q\x84 C\x97\x88\xa2\xce\xb96\xb4\x96g.\xaa\xbe\xe6\x1f.K2\x1eR.\xfb\xca\xe4)%~\xc4\x19"\x0f_F!\x91\xb9\xca\x05\xe2\xb3q\x1c\x86\xae\xffiCn&>%\x89\x14\x82\xd1h\xa8\x0f\x002\xc4\xe49v\x81J\x81,\x1b\x14*\x81\\\x17\x8f\x08D'), (0.4097222222222222, 'lastvisTrue_emojiFalse', b'.?=..)))))}}}...', 'CBC', b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'\xe6\xeb\xf3\xb4\xd6t.\xa8\xd2\xbe4\xfa\x0fa=\x1b\x11&\xee\xaaH\xc5\r5\xfd1dL\xde}\xa26\xdd\x07\x86h\x9e1\xc5\xb5\x8b\x124\x02\xe4\\ND\xc3\xe6\xea"\xefm\xf3\xadkl\xf2\xdf\xd8\xe2\xdbu\x1e\x94s\xf8\xeaY}\x0e\xfe\x1b>\xba6BSU\xe8eh\xcc\xc9"\r&\x00\xaba\xb5\x90R\xca\x9e\xf9\x8a\xce\x82\x91\xe7\x87\xef\x1e\x8d\x16tc\xf5\xee>bn\xcdCk\xe2\x03Yl\xb8\xa8\x8dTRyXF\x1a\x8c"9\xd4H\xbf\xb4\xf2\xa1\xcd>\xcc\x0bk'), (0.4027777777777778, 'lastvisFalse_emojiFalse', b'....?=.)))))}}}.', 'ECB', None, b"# \xf0\xe8o\xc8\xbaH\xce\x00e\xf8r\x00\x98\xdd\x870g.\xf7\x06)0\xbc\x0c\xe2\x9d}eW\xc6\x1d/\x1d\x84\xf4T\x97\x9f\x8a\x9b\xb8\\\xa7\xe3\xa2W\xc1\x05\x11\x8f)7\xff\x90\x96o\xe5[\xceIP\x04\xbbn|3\x88WY\xcd~\x8c\x01\x1a9'\xd4H^\xbd\x88\x1c_\x02\xc4\x83\x83\x87\xf4\x1eZ<YqSw\x08E\x1a\x949.\xb5\x0fD3\xfbg\xb0[\x1a\x99\xde\xfc\xdd \xe1d\x03\x99\x80\x15\xd2\x9c\x0c\xf7\x1bd\x9f\xb4g\x17\xdf<\x16j\xe3ZX[\xf8;"), (0.3680555555555556, 'lastvisTrue_emojiTrue', b'\x8b\xe7.f\x1a\xa1\xca%F\xc4\xcbYU\x89f\xf8', 'CBC', b'\xa7\x85\xf7\xf3:\x10\xedh\xbf\x89\x83+\xb2YC]', b",\xdf\xcf\x87\xc5\xee.\x88\x83;\xf9\x06\x86\x8c\xa9\x83L\xe4\x13%\xbc\xb0\xd0\x9f\x92\nN\xcb\xff+\xd0\xa6e*\x93\xd8{?\xae!n\x90\xdcC\xc4\xcf\xa6\x92A\xa2\xecp2h\x18S\xb9\xa7t\x19\x93\x8aA\x15\xd9-\xe8\x14\xad\xb6\xd4\xc2\x06\xaec&A\xd6\xb1<\xccjw~'Y]6\xbe6\x133\xd6\x84F\x9dj\xc7\xbb\xf93\xe7\xbc\x92B\x0e\x07\xb5XHZ8\x04\x9c\x90\xef\xeb\xb7^_\x84\xddh\xa4\xe2.\xdf}R4\xadK\xa7\x92\x80\xf8\x04\xb8\xb3\xf8\x19\x05{\xcf"), (0.3611111111111111, 'lastvisFalse_emojiTrue_punctstrip', b"\xe3\xb0\xc4B\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99o\xb9$'\xaeA\xe4d\x9b\x93L\xa4\x95\x99\x1bxR\xb8U", 'ECB', None, b'"Z3$Ew\xe9\x0e\x8b^D\x87\xef\xf7\xb5l~\xce.G\x18\xbd\xa2\xea\xc7\xba\x1c x\x00x\x13W\xfe\xda\xe3v`D~\xeb0\xa6\xa4\x05\x9aj\xf67j\x91k\x8e\x17\xa9\x93\xddq|\t\x86\x84\xd3\x03\x16\xael\xb7p\x03\xe9\xe3\xa46\xcf\x07=\x1a\x1b\x13\x9d\xf0Ns\xa06\xf3 \xdc\x08\xd2Q\x1d(\x97\xc7\xf0\xba\xdf\x8dk[\xff\xf9\x9f\x87\xe8X\x83\x1d\x97lu\xf0\xf9\xe7mTz\x84\xa4\xbb\x93\xf7l\xedPZo{\xae\xc4\xa2\xb0\xc3\x9c\xf2\xfb\x86\xf1T\xa5\xaf\xae')])

Python

python
bits=''.join('0' if ch=='\u200b' else '1' if ch=='\u200c' else '' for ch in zws) print(len(bits)) for width in [5,6,7,8]: for start in range(width): vals=[int(bits[i:i+width],2) for i in range(start, len(bits)-width+1, width)] # map 5-bit to a-z (0=a or 1=a), 7/8 ascii if width==5: for offset in [0,1]: txt=''.join(chr(v+ord('a')-offset) if 0+offset<=v<=25+offset else '?' for v in vals) if any(w in txt for w in ['flag','void','the','you','xv']): print("w5",start,offset,txt[:300]) else: bs=bytes(v for v in vals if 0<=v<256) sc=score_ascii(bs) if sc>0.7 or b'0x' in bs or b'flag' in bs.lower(): print("width",width,"start",start,"score",sc,bs[:200], bs.decode('latin1')[:200])

Python

python
texts5=[] for start in range(5): vals=[int(bits[i:i+5],2) for i in range(start, len(bits)-5+1, 5)] for offset in [0,1]: txt=''.join(chr(v+ord('a')-offset) if 0+offset<=v<=25+offset else '?' for v in vals) texts5.append((start,offset,txt)) print("start",start,"offset",offset,"len",len(txt),txt[:200]) # Try Caesar shifts for words for sh in range(26): ca=caesar_letters(txt.replace('?',''), sh) if 'flag' in ca or 'the' in ca or 'you' in ca or 'void' in ca: print(" caesar",sh,ca[:200])

Python

python
# Generate candidate phrases/substrings from visible text excluding hidden zero widths visible=''.join(ch for ch in text if ch not in '\u200b\u200c\u200d') # collect words and phrases tokens=re.findall(r'[A-Za-z0-9_{}xV]+', visible) cands=set() for tok in tokens: cands.add(tok) cands.add(tok.lower()) cands.add(tok.upper()) # ngrams up to 5 tokens for ngram in range(2,8): for i in range(len(tokens)-ngram+1): phrase=' '.join(tokens[i:i+ngram]) cands.add(phrase); cands.add(phrase.lower()); cands.add(phrase.upper()) phrase2='_'.join(tokens[i:i+ngram]) cands.add(phrase2); cands.add(phrase2.lower()) # exact lines/after colon for line in visible.splitlines(): cands.add(line.strip()); cands.add(line.strip().lower()) if ':' in line: cands.add(line.split(':',1)[1].strip()) # plus punctuation variants around 677 for c in ['677','0677','677.','677 HAHAHAHA','U NEED TO DO 677.','U NEED TO DO 677','U_NEED_TO_DO_677','doneedtodo677','do677','DO677','do 677','DO 677','6776776776776776','6776776776776777','HAHAHAHA','HAHAHAHA.']: cands.add(c); cands.add(c.lower()) print(len(cands)) # Try AES keys from candidates direct if len 16/24/32, md5, sha, repeats, ljust with zeros/spaces outs=[] for cand in cands: base=cand.encode() variants=set() for L in [16,24,32]: if len(base)>=L: variants.add(base[:L]); variants.add(base[-L:]) variants.add(base.ljust(L,b'\0')[:L]); variants.add(base.ljust(L,b' ')[:L]) variants.add((base*((L//len(base))+1))[:L] if len(base)>0 else b'') variants.add(md5(base).digest()) variants.add(sha256(base).digest()) variants.add(sha1(base).digest()[:16]) for key in variants: if len(key) not in (16,24,32): continue for mode in ['ECB','CBC']: ivs=[None] if mode=='ECB' else [bytes(16), md5(base).digest(), sha256(base).digest()[:16], base[:16].ljust(16,b'\0'), base[:16].ljust(16,b' ')] for iv in ivs: try: pt=aes_decrypt(bb,key,mode,iv) # unpad if possible pts=[pt] pad=pt[-1] if pad<=16 and pad>0 and pt.endswith(bytes([pad])*pad): pts.append(pt[:-pad]) for ptt in pts: sc=score_ascii(ptt) # English score stricter low=ptt.lower() if b'0xv01d' in low or b'flag' in low or b'{' in ptt or sc>0.8: outs.append((sc,cand,key,mode,iv,ptt[:300])) except Exception: pass print("outs",len(outs)) for item in sorted(outs, reverse=True, key=lambda x:x[0])[:30]: print("score",item[0],"cand",repr(item[1]),"key",item[2],"mode",item[3],"iv",item[4],"pt",item[5])

Python

python
visible=''.join(ch for ch in text if ch not in '\u200b\u200c\u200d') print(len(visible), len(text), len(zws), len(visible.encode()), len(raw)) print(Counter(ch for ch in visible if ch!='\n').most_common(20)) print(len(raw)-3*len(zws), len(raw))

Python

python
Counter(letters) Counter({'r': 8, 'i': 7, 'l': 6, 'n': 4, 'f': 4, 'w': 4, 'm': 4, 's': 3, 't': 3, 'e': 3, 'y': 3, 'k': 3, 'a': 2, 'p': 2, 'h': 2, 'j': 2, 'v': 2, 'o': 2, 'g': 2, 'x': 1, 'u': 1, 'c': 1, 'd': 1})

Python

python
def transforms_basic(x): outs=[] # original/reverse for name,t in [('orig',x),('rev',x[::-1])]: outs.append((name,t)) for r in range(2,min(30,len(x))): outs.append((name+f'_raildec{r}', rail_fence_decrypt(t,r))) outs.append((name+f'_railenc{r}', rail_fence_encrypt(t,r))) for w in range(2,len(x)): if len(x)%w==0 or w<20: outs.append((name+f'_col{w}', columns_read(t,w))) return outs matches=[] for name,t in transforms_basic(letters): for sh in range(26): ca=caesar_letters(t,sh) low=ca.lower() if any(word in low for word in ['flag','final','real','this','the','you','void']): matches.append((name,sh,ca)) len(matches) 33

Python

python
for name,sh,ca in matches[:100]: print(name, "shift", sh, ca[:200])

Python

python
import os, glob, pathlib glob.glob('/usr/share/dict/*')[:10] ['/usr/share/dict/README.select-wordlist']

Python

python
try: import wordfreq print("wordfreq ok") except Exception as e: print(e) try: import wordninja print("wordninja ok") except Exception as e: print(e)

Python

python
def take_steps(s, pattern, start=0): i=start; out='' pi=0 while 0<=i<len(s): out += s[i] i += pattern[pi%len(pattern)] pi+=1 return out for objname,obj in [('s',s),('letters',letters),('visible',visible)]: print('---',objname) for start in range(min(10,len(obj))): out=take_steps(obj,[6,7,7],start) if any(w in out.lower() for w in ['flag','0x','v01','real','you','the']): print(start,out[:200]) # print(start,out[:80])

Python

python
import math math.gcd(677,192), 677%192 (1, 101)

Python

python
def cyclic_step(s, step, start=0): n=len(s); out=[]; i=start; seen=set() for _ in range(n): out.append(s[i]) i=(i+step)%n return ''.join(out) for step in [677, 101, -677, pow(677,-1,len(s)) if math.gcd(677,len(s))==1 else None]: if step is None: continue print("step", step, "mod", step%len(s)) for start in range(0, min(len(s),20)): out=cyclic_step(s,step,start) if '0x' in out.lower() or 'v01' in out.lower() or 'flag' in out.lower() or 'the' in out.lower() or 'you' in out.lower(): print("start",start,out[:200]) print(cyclic_step(s,step,0)[:120]) print("inv", pow(677,-1,len(s)))

Python

python
for bitseq_name,bitseq in [('bits_no_sep',bits)]: n=len(bitseq) print(n, math.gcd(677,n)) for direction in [677,-677,pow(677,-1,n)]: if math.gcd(direction,n)!=1: continue for start in [0]+list(range(1,8)): perm=''.join(bitseq[(start+i*direction)%n] for i in range(n)) for revbits in [False, True]: bs=bytes(int((perm[i:i+8][::-1] if revbits else perm[i:i+8]),2) for i in range(0,n,8)) sc=score_ascii(bs) if sc>0.8 or b'0x' in bs or b'flag' in bs.lower(): print("dir",direction,"start",start,"rev",revbits,"score",sc,bs[:200]) try: print(bs.decode())

Python

python
def decode_zws_sequence(seq): gr=seq.split('\u200d') if all(len(g)==8 for g in gr if g) and len([g for g in gr if g])>0: try: return bytes(int(''.join('0' if ch=='\u200b' else '1' for ch in g),2) for g in gr if len(g)==8) except: return b'' return b'' n=len(zws) print(n, math.gcd(677,n)) for step in [677,-677, pow(677,-1,n)]: print("step",step, step%n) for start in range(9): perm=''.join(zws[(start+i*step)%n] for i in range(n)) bs=decode_zws_sequence(perm) if bs: sc=score_ascii(bs) if sc>0.8 or b'0x' in bs or b'flag' in bs.lower(): print("split", start, len(bs), sc, bs[:200])

Python

python
import random def unshuffle_from_seed(cipher, seed): n=len(cipher) perm=list(range(n)) random.Random(seed).shuffle(perm) # if c[i] = p[perm[i]] after shuffle list? Actually random.shuffle on list of plaintext yields shuffled[i]=plaintext[perm[i]] p=['']*n for i,orig_idx in enumerate(perm): p[orig_idx]=cipher[i] return ''.join(p) def shuffle_order_read(cipher, seed): n=len(cipher) perm=list(range(n)) random.Random(seed).shuffle(perm) # maybe c[perm[i]]=p[i] p=['']*n for i,idx in enumerate(perm): p[i]=cipher[idx] return ''.join(p) for objname,obj in [('s',s),('letters',letters),('bits',bits)]: for func in [unshuffle_from_seed, shuffle_order_read]: out=func(obj,677) if objname=='bits': bs=bytes(int(out[i:i+8],2) for i in range(0,len(out)-7,8)) print(objname,func.__name__, score_ascii(bs), bs[:100]) else: print(objname,func.__name__, out[:120]) if any(w in out.lower() for w in ['flag','0x','v01','you','the','real']): print("match")

Python

python
out=shuffle_order_read(s,677) for w in ['flag','0x','v01','you','the','real']: print(w, out.lower().find(w)) print(out)

Python

python
base36bs=bs # from earlier int base36 for key in [b'677', b'\x06\x07\x07', b'0xV01D', b'HAHAHAHA']: x=bytes(c^key[i%len(key)] for i,c in enumerate(base36bs)) print(key, score_ascii(x), x[:100]) try: print(x.decode('utf-8')[:200]) except: pass # single byte best best=[] for k in range(256): x=bytes(c^k for c in base36bs) if b'0x' in x or b'flag' in x.lower() or score_ascii(x)>0.75: best.append((score_ascii(x),k,x[:100])) print(best[:10], len(best))

Python

python
bin01=''.join(c for c in s if c in '01') len(bin01), bin01[:200] (32, '10101110111001100010000100111110')

Python

python
b01=bytes(int(bin01[i:i+8],2) for i in range(0,len(bin01),8)) b01, b01.decode('latin1'), b01.hex() (b'\xae\xe6!>', '®æ!>', 'aee6213e')

Python

python
for inv in [False,True]: bits2=''.join(('1' if c=='0' else '0') if inv else c for c in bin01) for rev in [False, True]: b01=bytes(int((bits2[i:i+8][::-1] if rev else bits2[i:i+8]),2) for i in range(0,len(bits2),8)) print(inv,rev,b01,b01.hex(),score_ascii(b01))

Python

python
hexchars=''.join(c for c in s if c in '0123456789abcdef') len(hexchars), hexchars[:200] (133, '35101021a8432431891304654316e14785939f52878887125630f805572421499187409c99209e3539066107907e0027493106690a78382d6189573871931f2761f10')

Python

python
for off in [0,1]: hx=hexchars[off:] if len(hx)%2: hx=hx[:-1] bs2=bytes.fromhex(hx) print(off,len(bs2),score_ascii(bs2),bs2[:100]) print(bs2.decode('latin1')[:100])

Python

python
leet_map=str.maketrans({'0':'o','1':'l','2':'z','3':'e','4':'a','5':'s','6':'g','7':'t','8':'b','9':'g'}) leet=s.translate(leet_map) print(leet[:200]) # maybe looks like english? apply rail/caesar? for name,t in [('leet',leet),('leetrev',leet[::-1])]: for r in range(2,20): dec=rail_fence_decrypt(t,r) if any(w in dec for w in ['flag','this','the','you','real','void']): print(name,r,dec[:200])

Python

python
words=['the','flag','real','this','you','found','finally','void','hidden','zero','width','not','get','see'] best=[] for base_name,base in [('s',s),('leet',leet),('letters',letters),('leet_letters',''.join(c for c in leet if c.isalpha()))]: for name,t in transforms_basic(base): for sh in range(26): ca=caesar_letters(t,sh) low=ca.lower() count=sum(low.count(w)*len(w) for w in words) if count>0: best.append((count,base_name,name,sh,ca[:300])) for item in sorted(best, reverse=True)[:50]: print(item[0], item[1], item[2], item[3], item[4])

Python

python
r5=rail_fence_decrypt(s,5) print(len(r5), r5) print("letters:", ''.join(c for c in r5 if c.isalpha())) print("digits:", ''.join(c for c in r5 if c.isdigit())) print("leet:", r5.translate(leet_map)) print("only letters leet:", ''.join(c for c in r5.translate(leet_map) if c.isalpha())) # Does r5 contain flag if digits mapped? for key in ['677']: pass

Python

python
for label,t in [('s',s),('r5dec',r5),('r5enc',rail_fence_encrypt(s,5))]: try: b64=base64.b64decode(t, validate=True) print(label, len(b64), score_ascii(b64), b64[:80], b64.hex()[:100]) # Try zlib/gzip? for name,func in []: pass except Exception as e: print(label,e)

Python

python
for tname,t in [('s',s),('rev',s[::-1])]: for r in range(2,10): for op,tt in [('dec',rail_fence_decrypt(t,r)),('enc',rail_fence_encrypt(t,r))]: # Check prefixes/contains for flag after leet map, letters, base64? le=tt.translate(leet_map) if 'flag' in le or 'flg' in tt or 'iflg' in tt or 'flag' in tt: print(tname,r,op, tt[:100], le[:100])

Python

python
for objname,obj in [('r5',r5),('r5letters',''.join(c for c in r5 if c.isalpha())),('r5leet',r5.translate(leet_map))]: print('---',objname) for step in range(2,10): for off in range(step): t=obj[off::step] if any(w in t.lower() for w in ['flag','0x','v01','the','you','real','void']): print("step",step,"off",off,t[:150])

Python

python
b_r5=base64.b64decode(r5) for key in keys+[b"677",b"HAHAHAHA"]: x=bytes(c^key[i%len(key)] for i,c in enumerate(b_r5)) sc=score_ascii(x) if sc>0.7 or b'0x' in x or b'flag' in x.lower(): print(key,sc,x[:200]) # single byte XOR best=[] for k in range(256): x=bytes(c^k for c in b_r5) sc=score_ascii(x) if sc>0.75 or b'0x' in x or b'flag' in x.lower(): best.append((sc,k,x[:100])) print("single",sorted(best, reverse=True)[:5])

Python

python
b_r5=base64.b64decode(r5) keylist=[b"677",b"HAHAHAHA",b"0xV01D",b"U NEED TO DO 677"] for keystr in line_last_variants.values(): keylist.append(keystr.encode('utf-8')) for key in keylist: x=bytes(c^key[i%len(key)] for i,c in enumerate(b_r5)) sc=score_ascii(x) if sc>0.55 or b'0x' in x or b'flag' in x.lower(): print(key,sc,x[:120]) # single byte XOR best=[] for k in range(256): x=bytes(c^k for c in b_r5) sc=score_ascii(x) if sc>0.55 or b'0x' in x or b'flag' in x.lower(): best.append((sc,k,x[:100])) print("single",sorted(best, reverse=True)[:10])

Python

python
for dataname,dat in [('s',s.encode()),('r5',r5.encode())]: print('---',dataname) for key in keylist: x=bytes(c^key[i%len(key)] for i,c in enumerate(dat)) sc=score_ascii(x) if sc>0.8 or b'0x' in x or b'flag' in x.lower(): print(key,sc,x[:200]) print(x.decode('latin1')[:200]) # single best=[] for k in range(256): x=bytes(c^k for c in dat) if all(32<=c<127 for c in x): if b'flag' in x.lower() or b'0x' in x or score_ascii(x)>0.95: best.append((score_ascii(x),k,x[:150])) print(sorted(best, reverse=True)[:5])

Python

python
xorH=bytes(c^ord('H') for c in r5.encode()).decode('latin1') print(xorH) for n in range(1,94): t=rot47(xorH,n) if 'flag' in t.lower() or '0x' in t.lower() or 'the' in t.lower() or 'you' in t.lower(): print(n,t[:200]) # Maybe Ascii85/base85 decode? import base64 for funcname,func in [('a85',base64.a85decode),('b85',base64.b85decode)]: try: out=func(xorH.encode(), adobe=False, ignorechars=b' \n\t\r\v') print(funcname,len(out),score_ascii(out),out[:100]) except Exception as e: print(funcname,e)

Python

python
try: out=base64.b85decode(xorH.encode()) print(len(out),score_ascii(out),out[:100]) except Exception as e: print(e)

Python

python
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 morse_decode(seq): # slash / separator char, spaces too toks=re.split(r'[ /]+', seq.strip()) return ''.join(MORSE.get(tok,'?') for tok in toks if tok) for dataname,dat in [('s',s.encode()),('r5',r5.encode())]: print('---',dataname) for k in range(32,127): x=bytes(c^k for c in dat).decode('latin1') mor=''.join(ch if ch in '.-/' else ' ' for ch in x) dec=morse_decode(mor) if any(w in dec.lower() for w in ['flag','the','you','void']) or '0XV01D' in dec.upper(): print("key",k,chr(k), "dec",dec[:200],"morse snippet",mor[:100]) # repeated key last chars? maybe for key in [b"HAHAHAHA", b"H", b"677"]: x=bytes(c^key[i%len(key)] for i,c in enumerate(dat)).decode('latin1') mor=''.join(ch if ch in '.-/' else ' ' for ch in x) print("repkey",key, "morse",mor[:120], "dec",morse_decode(mor)[:100])

Python

python
from collections import deque def to_bytes(x): if isinstance(x, bytes): return x return x.encode('latin1','ignore') def to_str(x): if isinstance(x, str): return x try: return x.decode('latin1') except: return x.decode('utf-8','ignore') def is_interesting(x): b=to_bytes(x) low=b.lower() return b'0xv01d' in low or b'flag' in low or b'void' in low def preview(x): s2=to_str(x) return repr(s2[:200]) keys_b=[b'H',b'HAHAHAHA',b'677',b'U NEED TO DO 677',b'0xV01D'] for keystr in line_last_variants.values(): keys_b.append(keystr.encode('utf-8')) def transforms_state(x): outs=[] data=to_bytes(x) st=to_str(x) # rail (144, 1362015)

Python

python
tmp=rail_fence_encrypt(s,5) out=rail_fence_decrypt(tmp,10) out=rail_fence_encrypt(out,4) out=rail_fence_encrypt(out,2) out=rail_fence_decrypt(out,4) print(out) print(len(out)) print(out.translate(leet_map)) print('letters', ''.join(c for c in out if c.isalpha())) print('digits', ''.join(c for c in out if c.isdigit()))

Python

python
def letters_after_digit(s, digit=None, before=False): out='' for i,c in enumerate(s): if c.isalpha(): prev=s[i-1] if i>0 else '' nxt=s[i+1] if i+1<len(s) else '' if digit is None and prev.isdigit(): out+=c elif digit is not None and prev==str(digit): out+=c return out for dataname,dat in [('s',s),('r5',r5)]: print("----",dataname) for d in range(10): t=letters_after_digit(dat,d) print(d,len(t),t) print("after any",letters_after_digit(dat,None)) # letters before digit d for d in range(10): t=''.join(c for i,c in enumerate(dat[:-1]) if c.isalpha() and

Python

python
def take_offset_by_digits(s, use_zero=False): out='' for i,c in enumerate(s): if c.isdigit(): d=int(c) if d==0 and not use_zero: continue j=i+d if j<len(s): out+=s[j] return out for dataname,dat in [('s',s),('r5',r5)]: for use_zero in [False,True]: out=take_offset_by_digits(dat,use_zero) print(dataname,use_zero,len(out),out[:200]) print('letters only', ''.join(c for c in out if c.isalpha())[:200]) if 'flag' in out.lower() or '0x' in out.lower(): print('match') # take before offset out='' for i,c in enumerate(dat): if c.isdigit(): d=int(c); j=i-d if j

Pensamiento

undefined

Python

python
import shutil, subprocess, os, sys, pkgutil, importlib.util print(shutil.which('ciphey'), shutil.which('cyberchef'), shutil.which('hashid')) mods=['ciphey','pycipher','cryptography','Crypto','z3','sympy'] for m in mods: print(m, importlib.util.find_spec(m))

Python

python
Counter(xorH).most_common() [('y', 17), ('x', 15), ('q', 15), ('{', 13), ('p', 13), ('\x7f', 12), ('z', 10), ('}', 9), ('|', 9), ('~', 9), (':', 8), ('!', 7), ('$', 6), ('.', 4), ('%', 4), ('?', 4), ('&', 4), ('<', 3), ('1', 3), ('-', 3), ('#', 3), (';', 3), ('/', 2), ('8', 2), ('"', 2), ("'", 2), (')', 2), ('>', 2), (' ', 2), ('=', 1), ('0', 1), ('+', 1), (',', 1)]

Python

python
s_xorH=bytes(c^ord('H') for c in s.encode()).decode('latin1') for r in range(2,20): for op,t in [('dec',rail_fence_decrypt(s_xorH,r)),('enc',rail_fence_encrypt(s_xorH,r))]: if any(w in t.lower() for w in ['flag','0x','v01','the','you']): print(r,op,t[:200])

Python

python
for r in [5,2,3,4,6,7,8,10]: for op,bitperm in [('dec',rail_fence_decrypt(bits,r)),('enc',rail_fence_encrypt(bits,r))]: for rev in [False, True]: bs=bytes(int((bitperm[i:i+8][::-1] if rev else bitperm[i:i+8]),2) for i in range(0,len(bitperm),8)) if score_ascii(bs)>0.8 or b'flag' in bs.lower() or b'0x' in bs: print(r,op,rev,score_ascii(bs),bs[:200]) try: print(bs.decode()) except: pass

Python

python
raw_lines=raw.splitlines() raw_last=bytes(line[-1] for line in raw_lines if line) raw_last_noemoji=bytes(line[-1] for line in raw_lines if line and line[-1]<128) print(raw_last, len(raw_last), raw_last.hex()) print(raw_last_noemoji, len(raw_last_noemoji)) key_candidates=[raw_last, raw_last_noemoji, raw_last[:16], raw_last[-16:], raw_last_noemoji[:16], raw_last_noemoji[-16:]] # test AES with direct/raw/hash for s and r5 b64 bytes def test_aes_bytes(data, key_candidates): for kb in key_candidates: variants=set() for L in [16,24,32]: if len(kb)>=L: variants.add(kb[:L]); variants.add(kb[-L:]) variants.add(kb.ljust(L,b'\0')[:L]) variants.add(md5(kb).digest()); variants.add(sha256(kb).digest()); variants.add(sha1(kb).digest()[:16]) for key in variants: if len(key) not in (16,24,32): continue for mode in ['ECB','CBC']: ivs=[None] if mode=='ECB' else [bytes(16), kb[:16].ljust(16,b'\0'), kb[-16:].rjust(16,b'\0'), md5(kb).digest()] for iv in ivs: try: pt=aes_decrypt(data,key,mode,iv) if score_ascii(pt)>0.7 or b'0x' in pt.lower() or b'flag' in pt.lower(): print("key",kb,"AES",len(key),mode,iv,"score",score_ascii(pt),pt[:200]) except Exception: pass print("s") test_aes_bytes(bb, key_candidates) print("r5") test_aes_bytes(b_r5, key_candidates)

Python

python
from pathlib import Path imgp=Path('/mnt/data/image.png') img=imgp.read_bytes() len(img), img[:20], img[-100:] (83280, b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x02h', b'aH\xf4\xd9\x00\x00\x9a\x96\x86\x9e\xaf \x97/!\x9b-BQ\x14\x0c\xcc>\xac\xd1\x10\xa3\xd1\x10\xb6ea4\x1ab4r\x95\x10B\x08!d\xdeH\xa5\xd2H\xa54\xa4Ri\xa8\x9a\xabZ*\x8dL6\x07\xc7q`\x1am\xf4{\x1d\xf4{M\x8c\xac\x81\xbc=\xe0\xffe\x88b\xba\x932\xac\xc9\x00\x00\x00\x00IEND\xaeB`\x82')

Python

python
import re, subprocess, os, textwrap, json, sys, math, statistics strings=re.findall(rb'[ -~]{5,}', img) len(strings), strings[:20], strings[-20:] (411, [b'IDATx^', b'._JC~', b'oo_dff"', b' H3Fju', b'DW)5/', b'Cj 0(', b',)nXb', b'`.(#(', b'4bbbbbb', b'\\*DQ?H(', b'5BQa!rr', b'oW;wwq`', b'OLLLL\\v', b'fgvc10', b"DZN`i'M", b"'&&&&", b'=._JC', b'?111q', b'(3UJHI', b'5\\r|I5'], [b'M+####', b'fdgg!((', b'\\^>uv', b'Ndggi>', b'`s66[c', b'>_}sss', b"]'Cl222", b'_ll,<<<p', b'^u;w.', b'//oCl222', b'sOamm', b'v_TI%', b'6~x&!', b'o@[;v', b'llKr)', b':B>v/Z._B', b':?zzzzzzzz', b'66o\\B:', b'=K6[@', b'{Czzzzzzz'])

Python

python
import struct, zlib pos=8 chunks=[] while pos<len(img): length=struct.unpack(">I", img[pos:pos+4])[0]; typ=img[pos+4:pos+8] chunks.append((typ,length,pos)) pos += 8+length+4 chunks[:10], chunks[-5:], len(chunks) ([(b'IHDR', 13, 8), (b'sRGB', 1, 33), (b'gAMA', 4, 46), (b'pHYs', 9, 62), (b'IDAT', 65445, 83), (b'IDAT', 17716, 65540), (b'IEND', 0, 83268)], [(b'gAMA', 4, 46), (b'pHYs', 9, 62), (b'IDAT', 65445, 83), (b'IDAT', 17716, 65540), (b'IEND', 0, 83268)], 7)

Python

python
def atbash(s): out='' for c in s: if c.islower(): out+=chr(ord('z')-(ord(c)-ord('a'))) elif c.isupper(): out+=chr(ord('Z')-(ord(c)-ord('A'))) elif c.isdigit(): out+=str(9-int(c)) else: out+=c return out for objname,obj in [('s',s),('r5',r5),('letters',letters),('r5letters',''.join(c for c in r5 if c.isalpha()))]: t=atbash(obj) print(objname,t[:200]) if 'flag' in t or '0x' in t: print("match") for r in range(2,10): tt=rail_fence_decrypt(t,r) if any(w in tt for w in ['flag','the','you','void']): print("r",r,tt[:200])

Python

python
r5letters=''.join(c for c in r5 if c.isalpha()) matches=[] for name,t in transforms_basic(r5letters): low=t.lower() if 'flag' in low or 'flg' in low or 'iflg' in low or 'the' in low or 'you' in low: matches.append((name,t)) for name,t in matches[:100]: print(name,t) print("count",len(matches))

Python

python
r5digits=''.join(c for c in r5 if c.isdigit()) print(len(r5digits), r5digits[:100]) # ASCII pair/3/rail etc for r in range(2,10): t=rail_fence_decrypt(r5digits,r) if '0x' in t or 'flag' in t: print('raw') # Convert pairs for off in [0,1]: hx=t[off:] if len(hx)%2: hx=hx[:-1] bs=bytes(int(hx[i:i+2]) for i in range(0,len(hx),2) if int(hx[i:i+2])<256) if score_ascii(bs)>0.7 or b'flag' in bs.lower(): print("r",r,"off",off,score_ascii(bs),bs[:100]) print(bs.decode('latin1')[:100]) # try decimal segmentation DP to printable?

Python

python
def ascii_decimal_decodings(digits, max_solutions=10): # dp score and reconstruct best printables from parsing 2 or 3 digits as 32-126 n=len(digits) dp=[(-1e9,'') for _ in range(n+1)] dp[0]=(0,'') for i in range(n): if dp[i][0]<-1e8: continue for l in [2,3]: if i+l<=n: v=int(digits[i:i+l]) if 32<=v<=126: # score common ch=chr(v) score=1 + (3 if ch.lower() in 'etaoinshrdlu' else 0) + (5 if ch in '{}_' else 0) if dp[i][0]+score>dp[i+l][0]: dp[i+l]=(dp[i][0]+score, dp[i][1]+ch) return dp[n] for name,dig in [('s',digits),('r5',r5digits)]: score,dec=ascii_decimal_decodings(dig) print(name,score,dec[:200],len(dec)) # Also allow 1 for digits as ascii? no

Python

python
for name,dig in [('s',digits),('r5',r5digits)]: n=int(dig) bsint=n.to_bytes((n.bit_length()+7)//8,'big') print(name,len(bsint),score_ascii(bsint),bsint[:100],bsint.hex()[:100]) # xor single? best=[] for k in range(256): x=bytes(c^k for c in bsint) if score_ascii(x)>0.7 or b'flag' in x.lower(): best.append((score_ascii(x),k,x[:100])) print(sorted(best, reverse=True)[:3])

Python

python
def shift_letters_by_prev_digit(s, direction=-1): out=[] cur=0 for ch in s: if ch.isdigit(): cur=int(ch) elif ch.isalpha(): out.append(chr((ord(ch)-97 + direction*cur)%26+97)) return ''.join(out) for name,dat in [('s',s),('r5',r5)]: for direction in [-1,1]: out=shift_letters_by_prev_digit(dat,direction) print(name,direction,out) if any(w in out for w in ['flag','the','you','real','void']): print("match") for r in [2,3,4,5,7]: t=rail_fence_decrypt(out,r) if any(w in t for w in ['flag','the','you','real','void']): print(" rail",r,t[:100])

Python

python
def shift_letters_by_next_digit(s, direction=-1): out=[] for i,ch in enumerate(s): if ch.isalpha(): # find next digit d=0 for j in range(i+1,len(s)): if s[j].isdigit(): d=int(s[j]); break out.append(chr((ord(ch)-97 + direction*d)%26+97)) return ''.join(out) for name,dat in [('s',s),('r5',r5)]: for direction in [-1,1]: out=shift_letters_by_next_digit(dat,direction) print(name,direction,out) if any(w in out for w in ['flag','the','you','real','void']): print("match")

Python

python
for name,dat in [('s',s),('r5',r5)]: bits_ld=''.join('1' if c.isalpha() else '0' for c in dat) print(name,len(bits_ld),bits_ld[:100]) for start in range(5): vals=[int(bits_ld[i:i+5],2) for i in range(start,len(bits_ld)-4,5)] for offset in [0,1]: txt=''.join(chr(v+ord('a')-offset) if offset<=v<=25+offset else '?' for v in vals) if any(w in txt for w in ['flag','the','you','void','real']) or True: print(start,offset,txt) print()

Python

python
for name,dat in [('s',s),('r5',r5)]: runs=re.findall(r'\d+|[a-z]+', dat) # For each digit run, convert parity bits to ascii or morse bitstr=''.join(str(int(d)%2) for d in re.findall(r'\d', dat)) print(name, "parity len",len(bitstr), bitstr[:100]) for width in [5,7,8]: for start in range(width): vals=[int(bitstr[i:i+width],2) for i in range(start,len(bitstr)-width+1,width)] if width==5: txt=''.join(chr(v+97) if v<26 else '?' for v in vals) else: txt=''.join(chr(v) if 32<=v<127 else '?' for v in vals) if any(w in txt.lower() for w in ['flag','the','you','void']): print("width

Python

python
for name,dat in [('s',s),('r5',r5),('digits',digits),('r5digits',r5digits)]: for rule_name, bits_digit in [ ('parity',''.join(str(int(c)%2) for c in dat if c.isdigit())), ('ge5',''.join('1' if int(c)>=5 else '0' for c in dat if c.isdigit())), ('prime',''.join('1' if c in '2357' else '0' for c in dat if c.isdigit())), ]: bitstr=bits_digit for width in [7,8]: for start in range(width): vals=[int(bitstr[i:i+width],2) for i in range(start,len(bitstr)-width+1,width)] bs2=bytes(vals) if score_ascii(bs2)>0.7 or b'flag' in bs2.lower() or b'0x' in bs2: print(name,rule_name,width,start,score_ascii(bs2),bs2,bs2.decode('latin1'))

Python

python
for name,dat in [('s',s),('r5',r5),('r5enc',rail_fence_encrypt(s,5))]: bits01=''.join(c for c in dat if c in '01') print(name,len(bits01),bits01) # Treat 0 dot 1 dash, split by letters/digits others maybe # Extract runs of 0/1 separated by non-01 toks=re.findall(r'[01]+', dat) for mapping in [(('0','.'),('1','-')), (('0','-'),('1','.'))]: tr={a:b for a,b in mapping} mor=' '.join(''.join(tr[ch] for ch in tok) for tok in toks) dec=morse_decode(mor) print(mapping,dec) # group bits ascii for rev in [False,True]: bs=bytes(int((bits01[i:i+8][::-1] if rev else bits01[i:i+8]),2) for i in range(0,len(bits01)-7,8)) print("ascii",rev,bs,bs.decode('latin1'))

Python

python
def xor_each_line_last(s,width, include_key=False): out=b'' for i in range(0,len(s),width): line=s[i:i+width] if not line: continue key=ord(line[-1]) part=line if include_key else line[:-1] out += bytes(ord(c)^key for c in part) return out for dataname,dat in [('s',s),('r5',r5),('r5enc',rail_fence_encrypt(s,5))]: print("----",dataname) for w in range(2,65): if len(dat)%w==0: for include in [False,True]: out=xor_each_line_last(dat,w,include) if b'0x' in out.lower() or b'flag' in out.lower() or score_ascii(out)>0.8: print("w",w,"inc",include,"score",score_ascii(out),out[:120]) if b'0x' in out.lower() or b'flag'

Python

python
for dataname,dat in [('s',s.encode()),('r5',r5.encode()),('bb',bb),('b_r5',b_r5)]: for key in [b')',b'}',b'.',b'=',b'?',b'\x8d',b'\x88']: x=bytes(c^key[0] for c in dat) if score_ascii(x)>0.8 or b'flag' in x.lower() or b'0x' in x.lower(): print(dataname,key,score_ascii(x),x[:100]) if b'flag' in x.lower() or b'0x' in x.lower(): print("match",x)

Python

python
x=bytes(c^0x88 for c in bb) for pat in [b'0x',b'flag',b'V01',b'v01']: print(pat, x.find(pat)) print(x)

Python

python
for objname,obj in [('text',text),('visible',visible),('rawlatin',raw.decode('latin1'))]: n=len(obj) print(objname,n,math.gcd(677,n)) if math.gcd(677,n)==1: for start in range(min(100,n)): out=cyclic_step(obj,677,start) # remove zero-width and nonascii outclean=''.join(ch for ch in out if ch not in '\u200b\u200c\u200d' and 32<=ord(ch)<127) if '0xV01D' in outclean or 'flag' in outclean.lower() or 'the' in outclean.lower()[:100]: print("start",start,outclean[:200]) break print(cyclic_step(obj,677,0)[:200])

Python

python
seq_vis=cyclic_step(visible,677,0) seq_vis_clean=''.join(ch for ch in seq_vis if ch!='\n') print("contains", seq_vis.find('0xV01D'), seq_vis.lower().find('flag'), seq_vis.find('{'), seq_vis.find('}')) # print around braces for i,ch in enumerate(seq_vis): if ch in '{}': print(i, seq_vis[max(0,i-100):i+100]) # maybe reverse step? seq_vis_rev=cyclic_step(visible,-677,0) for seqname,seq in [('fwd',seq_vis),('rev',seq_vis_rev)]: print(seqname, "0x", seq.find('0x'), 'V01', seq.find('V01'), 'flag', seq.lower().find('flag'), 'brace', seq.find('{'), seq.find('}')) # all substrings with braces for m in re.finditer(r'\{[^}]{0,100}\}', seq): print("brace match",m.group())

Python

python
for seqname, seq in [('vis_fwd',seq_vis),('vis_rev',seq_vis_rev),('text_fwd',cyclic_step(text,677,0)),('text_rev',cyclic_step(text,-677,0))]: clean=''.join(ch for ch in seq if ch.isalnum() or ch in '{}_') print(seqname,len(clean), clean[:500]) print("finds", clean.find('0xV01D'), clean.lower().find('flag'), clean.find('{'), clean.find('}')) for m in re.finditer(r'\{[^}]{0,100}\}', clean): print(m.group())

Python

python
def cyclic_step_bytes(data, step, start=0): n=len(data); out=bytearray(); i=start for _ in range(n): out.append(data[i]); i=(i+step)%n return bytes(out) for step in [677,-677,pow(677,-1,len(raw))]: out=cyclic_step_bytes(raw,step,0) for enc in ['latin1','utf-8']: try: txt=out.decode(enc) except: txt=out.decode(enc,'ignore') clean=''.join(ch for ch in txt if ch.isalnum() or ch in '{}_') print("step",step,"enc",enc,"len",len(clean),"0x",clean.find('0xV01D'),"flag",clean.lower().find('flag'),"brace",clean.find('{'),clean.find('}'),clean[:200]) if '0xV01D' in clean: print(clean[clean.find('0xV01D')-20:clean.find('0xV01D')+100])

Python

python
from pathlib import Path p=Path('/mnt/data/challenge.txt') text=p.read_text('utf-8') len(text), text[:500], text[-500:] (2779, "In the beginning, there was nothing.\nThen nothing whispered: let there be layers upon layers.\nSome say the answer lies within the silence between words.\nOthers believe it hides in plain sight, staring back at you.\nThe number 677 means everything. Or maybe nothing. Who knows?\nDecoded message: dGhpcyBpcyBub3QgdGhlIHdheSBsb2wgdHJ5IGhhcmRlcg==\nSeek and you shall find. Or maybe you won't. HAHAHAHA.\nThe wise man once said: U NEED TO DO 677.\u200b\u200b\u200c\u200c\u200b\u200b\u200c\u200c\u200d\u200b\u200b\u200c\u200c\u200b\u200c\u200b\u200c\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200c\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200b\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200c\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200b\u200d\u200b\u200b\u200c\u200c\u200b\u200b\u200c\u200b", "ao)\n# NOTE: RAILFENCE RAILS = 5 (source: totally reliable)\n# NOTE: MORSE is standard ITU encoding (wink wink)\n# NOTE: Base64 is used somewhere here (maybe)\nPerhaps the flag is here: 0xV01D{y0u_th0ught_lmao_try_harder_xd}\nOr maybe here: 0xV01D{s0_cl0se_yet_s0_far_hahaha_nope}\nOr here: 0xV01D{alm0st_but_n0t_qu1te_lol}\nOr perhaps it was never here at all.\nThe void speaks in whispers you cannot hear with your ears.\nListen with your tools. All of them. Every. Single. One.\nGood luck. You'll need it. 😈")

Python

python
from pathlib import Path text=Path('/mnt/data/challenge.txt').read_text('utf-8') zw_chars = ['\u200b','\u200c','\u200d','\ufeff','\u2060'] hidden=''.join(c for c in text if c in zw_chars) from collections import Counter Counter(hidden), len(hidden) (Counter({'\u200b': 808, '\u200c': 728, '\u200d': 192}), 1728)

Python

python
ZWSP,ZWNJ,ZWJ='\u200b','\u200c','\u200d' groups=hidden.split(ZWJ) lens=Counter(map(len,groups)) lens, groups[-3:], len(groups) (Counter({8: 192, 0: 1}), ['\u200b\u200b\u200c\u200c\u200b\u200b\u200b\u200b', '\u200b\u200c\u200c\u200b\u200c\u200c\u200c\u200c', ''], 193)

Python

python
payload=''.join(chr(int(''.join('0' if c==ZWSP else '1' for c in g),2)) for g in groups if g) payload, len(payload) ('35101021a8r432431nisli89itp1304654316e1t4785939f5xr2l87h8887n1nii25630wrfujy8rlir05m57242l14l9918740y9rc9920v9e35ws39066l107907e0027493ok1g06k69y0ma7rjw8s3n82d618957r3kgit871931mfv2h7wp6m1f10o', 192)

Python

python
from collections import Counter Counter(payload), ''.join(sorted(set(payload))), sum(c.isdigit() for c in payload), sum(c.isalpha() for c in payload) (Counter({'1': 17, '0': 15, '9': 15, '3': 13, '8': 13, '7': 12, '2': 10, '5': 9, '4': 9, '6': 9, 'r': 8, 'i': 7, 'l': 6, 'n': 4, 'f': 4, 'w': 4, 'm': 4, 's': 3, 't': 3, 'e': 3, 'y': 3, 'k': 3, 'a': 2, 'p': 2, 'h': 2, 'j': 2, 'v': 2, 'o': 2, 'g': 2, 'x': 1, 'u': 1, 'c': 1, 'd': 1}), '0123456789acdefghijklmnoprstuvwxy', 122, 70)

Python

python
lines=text.splitlines() [(i+1,repr(line[-10:]),repr(line[-1]) if line else '') for i,line in enumerate(lines)] [(1, "'s nothing.'", "'.'"), (2, "'on layers.'", "'.'"), (3, "'een words.'", "'.'"), (4, "'ck at you.'", "'.'"), (5, "'Who knows?'", "'?'"), (6, "'hhcmRlcg=='", "'='"), (7, "' HAHAHAHA.'", "'.'"), (8, "'\\u200d\\u200b\\u200c\\u200c\\u200b\\u200c\\u200c\\u200c\\u200c\\u200d'", "'\\u200d'"), (9, "'st me bro)'", "')'"), (10, "' CBC lmao)'", "')'"), (11, "' reliable)'", "')'"), (12, "'wink wink)'", "')'"), (13, "'re (maybe)'", "')'"), (14, "'harder_xd}'", "'}'"), (15, "'haha_nope}'", "'}'"), (16, "'qu1te_lol}'", "'}'"), (17, "'re at all.'", "'.'"), (18, "'your ears.'", "'.'"), (19, "'ngle. One.'", "'.'"), (20, "'need it. 😈'", "'😈'")]

Python

python
def caesar_letters(s,k): out='' for c in s: if 'a'<=c<='z': out+=chr((ord(c)-97+k)%26+97) else: out+=c return out for k in range(26): t=caesar_letters(s,k) # try b64 decode try: b=base64.b64decode(t+"="*((4-len(t)%4)%4), validate=True) score=sum(32<=x<127 or x in (9,10,13) for x in b)/len(b) if score>.6: print("k",k,score,b[:100]) except: pass if '0xv01d' in t or 'flag' in t: print(k,t) print("rot+1", caesar_letters(s,1)[:200]) print("rot-1", caesar_letters(s,-1)[:200])

Python

python
import base64, binascii, hashlib, itertools, re, string, math ct=base64.b64decode(s) len(ct), ct.hex() (144, 'df9d74d74db56bcaf8df6e37d678ac962f3d8ada75df4e3ae78df5e9ed6de3bf39f77f5fe71af697cee1f3cf3b9f59e28b6e7adf4c2b7ee8f2f2b962af4e66e7bdb8da5d7897df75f3be34cbdadcf7ddb4bfd7b7e70b37f74eba975d3bf74eded34dbbe3dde8935834ea4ebdcb499aeeb8f0f2cde7f3677ad7cf79eebde4822b7cef5f77d667efda1ef0a7a9b57f5d28')

Python

python
last=''.join(line[-1] for line in lines if line) repr(last), len(last), [hex(ord(c)) for c in last] ("'....?=.\\u200d)))))}}}...😈'", 20, ['0x2e', '0x2e', '0x2e', '0x2e', '0x3f', '0x3d', '0x2e', '0x200d', '0x29', '0x29', '0x29', '0x29', '0x29', '0x7d', '0x7d', '0x7d', '0x2e', '0x2e', '0x2e', '0x1f608'])

Python

python
n=int(s,36) b=n.to_bytes((n.bit_length()+7)//8,'big') len(b), b[:100], b[-100:], sum(32<=x<127 for x in b)/len(b), b.find(b'0xV') (124, b'"rK\xa7\xc7I\xd6\xbd\xe0\x8b\x9a)No\xefT`\xa9\xc2\x967`;<\xc5\x8a\x03\xda\x1eX\x8e\xbdH\x91\x0f\xc7\xa2\xae*#\xff;j\xdf\xa5I\xae\xe9\xca\xeaQ\xfcDGj\xae\x14Y\x0b\x95\xff\x053J\x1b~<"\xad\x7f\xffz\x91\x0bw\x0c\x05\x83\xd0\xe1\xe6w\x91Z4\x11.1\xbc\xa5\xc7iG\xd2~=\x9e\xa6\xc5\xbc', b'\xc5\x8a\x03\xda\x1eX\x8e\xbdH\x91\x0f\xc7\xa2\xae*#\xff;j\xdf\xa5I\xae\xe9\xca\xeaQ\xfcDGj\xae\x14Y\x0b\x95\xff\x053J\x1b~<"\xad\x7f\xffz\x91\x0bw\x0c\x05\x83\xd0\xe1\xe6w\x91Z4\x11.1\xbc\xa5\xc7iG\xd2~=\x9e\xa6\xc5\xbc p\xa3\xc5\xdc\xcc\xb5\xae\x07\x9c$~2\xccP\x1d\xc2\xe2\xdfZ\x1bI\x0b\xe8', 0.3951612903225806, -1)

Python

python
bits=''.join('0' if c==ZWSP else '1' if c==ZWNJ else '' for c in hidden) len(bits) 1536

Python

python
for off in range(8): bs=bits[off:] out=bytes(int(bs[i:i+8],2) for i in range(0,len(bs)//8*8,8)) score=sum(32<=x<127 or x in (9,10,13) for x in out)/len(out) print(off, score, out[:80])

Python

python
Counter(c for c in text if c.isspace()), [hex(ord(c)) for c in sorted(set(c for c in text if c.isspace()))] (Counter({' ': 147, '\n': 19}), ['0xa', '0x20'])

Python

python
from pathlib import Path img=Path('/mnt/data/image.png').read_bytes() len(img), img[:8], img.find(b'0xV'), img.find(b'tEXt'), img.find(b'iTXt'), img.find(b'zTXt') (83280, b'\x89PNG\r\n\x1a\n', -1, -1, -1, -1)

Python

python
import struct, zlib, binascii data=img pos=8 chunks=[] while pos < len(data): l=struct.unpack(">I",data[pos:pos+4])[0]; typ=data[pos+4:pos+8].decode('latin1') chunks.append((typ,l,pos)) pos+=8+l+4 chunks[:10], chunks[-5:], pos, len(data) ([('IHDR', 13, 8), ('sRGB', 1, 33), ('gAMA', 4, 46), ('pHYs', 9, 62), ('IDAT', 65445, 83), ('IDAT', 17716, 65540), ('IEND', 0, 83268)], [('gAMA', 4, 46), ('pHYs', 9, 62), ('IDAT', 65445, 83), ('IDAT', 17716, 65540), ('IEND', 0, 83268)], 83280, 83280)

Python

python
ascii_last=''.join(line[-1] for line in lines if line and ord(line[-1])<128) repr(ascii_last), len(ascii_last) ("'....?=.)))))}}}...'", 18)

Python

python
for i,line in enumerate(lines,1): # Remove zero width? clean=''.join(c for c in line if c not in [ZWSP,ZWNJ,ZWJ]) print(i, repr(clean[-1] if clean else ''), clean[:80])

Python

python
clean_last=''.join((''.join(c for c in line if c not in [ZWSP,ZWNJ,ZWJ])[-1] if ''.join(c for c in line if c not in [ZWSP,ZWNJ,ZWJ]) else '') for line in lines) repr(clean_last), len(clean_last), clean_last.encode('utf-8'), len(clean_last.encode('utf-8')) ("'....?=..)))))}}}...😈'", 20, b'....?=..)))))}}}...\xf0\x9f\x98\x88', 23)

Python

python
try: from Crypto.Cipher import AES print("Crypto ok") except Exception as e: print("no",e)

Python

python
try: from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes print("cryptography ok") except Exception as e: print("no",e)

Python

python
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend def aes_decrypt(key, mode, iv=None, data=ct): try: cipher=Cipher(algorithms.AES(key), modes.ECB() if mode=='ECB' else modes.CBC(iv), backend=default_backend()) return cipher.decryptor().update(data)+cipher.decryptor().finalize() except Exception as e: return None def score_bytes(b): if not b: return 0 return sum((32<=x<127) or x in (9,10,13) for x in b)/len(b) def pkcs7_unpad(b): if not b: return b pad=b[-1] if 1<=pad<=16 and b.endswith(bytes([pad])*pad): return b[:-pad] return b candidates=set() # line last variants variants=[] variants.append(last) variants.append(clean_last) variants.append(ascii_last) for v in list(variants): candidates.add(v.encode('utf-8')) candidates.add(v.encode('latin1','ignore')) for i in range(max(0,len(v)-15)): candidates.add(v[i:i+16].encode('utf-8')) be=v.encode('utf-8') for i in range(max(0,len(be)-15)): candidates.add(be[i:i+16]) # common keys common=['677','U NEED TO DO 677','U NEED TO DO 677.','u need to do 677','HAHAHAHA','HAHAHAHA.','hahahaha','void','0xV01D','0xV01D Team','What You See Is Not What You Get','this is not the way lol try harder','dGhpcyBpcyBub3QgdGhlIHdheSBsb2wgdHJ5IGhhcmRlcg==','last character of each line','trust me bro','CBC lmao','ECB','CBC','not CBC','The wise man once said: U NEED TO DO 677.'] for w in common: wb=w.encode() candidates.add(wb) candidates.add(wb[:16].ljust(16,b'\0')) candidates.add(wb[:16].ljust(16,b' ')) # repeat candidates.add((wb*((32//len(wb))+1))[:16]) candidates.add((wb*((48//len(wb))+1))[:24]) candidates.add((wb*((64//len(wb))+1))[:32]) for h in [hashlib.md5(wb).digest(),hashlib.sha1(wb).digest()[:16],hashlib.sha256(wb).digest()[:16],hashlib.sha256(wb).digest(),hashlib.sha512(wb).digest()[:32]]: candidates.add(h) # line chars maybe only not notes, etc. for start in range(len(lines)): for end in range(start+1,len(lines)+1): cl=''.join((''.join(c for c in line if c not in [ZWSP,ZWNJ,ZWJ])[-1] if ''.join(c for c in line if c not in [ZWSP,ZWNJ,ZWJ]) else '') for line in lines[start:end]) eb=cl.encode('utf-8') if len(eb) in [16,24,32]: candidates.add(eb) # ascii only ab=cl.encode('latin1','ignore') if len(ab) in [16,24,32]: candidates.add(ab) # filter keys=[k for k in candidates if len(k) in (16,24,32)] len(keys) 204

Python

python
for mode in ['ECB','CBC']: hits=[] for key in keys: ivs=[bytes(16)] # if CBC, include first 16 bytes as iv and decrypt rest? for iv in ivs: data=ct if mode=='CBC': pt=aes_decrypt(key,mode,iv,data) else: pt=aes_decrypt(key,mode,data=data) if pt: u=pkcs7_unpad(pt) sc=score_bytes(u) if b'0xV01D' in u or sc>0.7: hits.append((sc,mode,key,u[:200])) print(mode,len(hits)) for hit in sorted(hits, reverse=True)[:20]: print(hit[0],hit[1],hit[2],hit[3])

Python

python
def rail_decrypt(cipher, rails): if rails<=1: return cipher # zigzag positions pattern=list(range(rails))+list(range(rails-2,0,-1)) idx=[pattern[i%len(pattern)] for i in range(len(cipher))] counts=[idx.count(r) for r in range(rails)] rails_buf=[];p=0 for c in counts: rails_buf.append(list(cipher[p:p+c]));p+=c pos=[0]*rails;out=[] for r in idx: out.append(rails_buf[r][pos[r]]);pos[r]+=1 return ''.join(out) def rail_encrypt(plain, rails): if rails<=1: return plain rows=['']*rails r=0; d=1 for ch in plain: rows[r]+=ch if r==0: d=1 elif r==rails-1: d=-1 r+=d return ''.join(rows (0, [])

Python

python
Counter(ct).most_common(20), min(ct), max(ct), len(set(ct)) ([(223, 5), (78, 5), (231, 5), (218, 4), (247, 4), (215, 3), (151, 3), (243, 3), (242, 3), (189, 3), (93, 3), (77, 2), (181, 2), (110, 2), (55, 2), (214, 2), (120, 2), (117, 2), (227, 2), (191, 2)], 11, 248, 90)

Python

python
from math import log2 cnt=Counter(ct) ent=-sum(v/len(ct)*log2(v/len(ct)) for v in cnt.values()) ent 6.285492734523623

Python

python
letters=''.join(c for c in s if c.isalpha()) digits=''.join(c for c in s if c.isdigit()) letters, len(letters), digits, len(digits) ('arnisliitpetfxrlhnniiwrfujyrlirmllyrcvewsleokgkymarjwsndrkgitmfvhwpmfo', 70, '35101021843243189130465431614785939528788871256308055724214991874099920935390661079070027493106690783826189573871931276110', 122)

Python

python
import random, re def unshuffle_from_shuffled(shuffled, seed, method='py'): n=len(shuffled) idx=list(range(n)) random.seed(seed) random.shuffle(idx) # shuffled = [orig[i] for i in idx], so orig[i]=shuffled[j] where idx[j]=i orig=['']*n for j,i in enumerate(idx): orig[i]=shuffled[j] return ''.join(orig) for seed in [677,676,678,8203,8204,8205]: t=unshuffle_from_shuffled(s,seed) if '0x' in t or 'flag' in t.lower() or '0xv' in t.lower(): print(seed,t) print(seed,t[:100], score_bytes(t.encode()))

Python

python
for seed in range(10000): t=unshuffle_from_shuffled(s,seed) low=t.lower() if '0xv01d' in low or '0xv' in low or 'flag' in low or 'void' in low: print("seed",seed,t[:200]) break else: print("none")

Python

python
for key in [b'o', b'677', b'HAHAHAHA', ascii_last.encode(), clean_last.encode('utf-8'), last.encode('utf-8')]: for data,name in [(s.encode(),'s'),(ct,'ct')]: b=bytes(data[i]^key[i%len(key)] for i in range(len(data))) sc=score_bytes(b) if sc>.5: print(name,key,sc,b[:100])

Python

python
b=bytes(s.encode()[i]^b'HAHAHAHA'[i%8] for i in range(len(s))) print(b.decode('latin1')) print(Counter(chr(x) for x in b).most_common())

Python

python
for key in [b'H',b'A',b'HAHAHAHA',b'677',b'o', ascii_last.encode(), clean_last.encode('utf-8')[:16]]: b=bytes(ct[i]^key[i%len(key)] for i in range(len(ct))) print(key, score_bytes(b), b[:80])

Python

python
digits=''.join(c for c in s if c.isdigit()) # backtracking parse digits to printable ASCII 32-126 or maybe 0-255 solutions=[] def backtrack(pos, out): if len(solutions)>20: return if pos==len(digits): o=''.join(map(chr,out)) if '0xV' in o or 'flag' in o.lower() or len(o)>0: solutions.append(o) return for l in [2,3]: if pos+l<=len(digits): val=int(digits[pos:pos+l]) if 32<=val<=126: backtrack(pos+l,out+[val]) backtrack(0,[]) len(solutions) 0

Python

python
# all ways parse digits into 1-2 <=26 sol=[] def bt(pos, out): if len(out)>100: return if pos==len(digits): sol.append(''.join(chr(96+x) for x in out)) return for l in [1,2]: if pos+l<=len(digits): v=int(digits[pos:pos+l]) if 1<=v<=26: bt(pos+l,out+[v]) bt(0,[]) len(sol) 0

Python

python
for n in [2,3,4,5,6,8,12,16,24,32,48,64]: print("chunks",n) print(' '.join(s[i:i+n] for i in range(0,len(s),n))[:500])

Python

python
for op in ['xor','add','sub']: if op=='xor': b=bytes(x^(677%256) for x in ct) elif op=='add': b=bytes((x+677)%256 for x in ct) else: b=bytes((x-677)%256 for x in ct) print(op,score_bytes(b),b[:100], b.find(b'0xV'))

Python

python
alphs=[ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", ] for alph in alphs: for k in [677%64]+list(range(64)): trans=str.maketrans(alph, alph[k:]+alph[:k]) t=s.translate(trans) b=try_base64(t.replace('-','+').replace('_','/')) if b: sc=score_bytes(b) if sc>.65 or b'0xV' in b or b'flag' in b.lower(): print("hit", alph

Python

python
# Try base encodings using libs? base64 has b32/b85/a85 for enc,func in [('b32',base64.b32decode),('b85',base64.b85decode),('a85',base64.a85decode)]: try: b=func(s.upper() if enc=='b32' else s) print(enc,len(b),score_bytes(b),b[:100],b.find(b'0xV')) except Exception as e: print(enc,"err",e) # base58 decode implement with BTC alphabet def base_decode(s, alphabet): n=0 for ch in s: if ch not in alphabet: raise ValueError(ch) n=n*len(alphabet)+alphabet.index(ch) return n.to_bytes((n.bit_length()+7)//8,'big') alph58="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" alph62="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" for alph,name in [(alph58,'b58'),(alph62,'b62'),('0123456789abcdefghijklmnopqrstuvwxyz','b36')]: try: b=base_decode(s,alph) print(name,len(b),score_bytes(b),b[:100],b.find(b'0xV')) except Exception as e: print(name,e)

Python

python
fake_flags=re.findall(r'0xV01D\{[^}]+\}', text) fake_flags ['0xV01D{y0u_th0ught_lmao_try_harder_xd}', '0xV01D{s0_cl0se_yet_s0_far_hahaha_nope}', '0xV01D{alm0st_but_n0t_qu1te_lol}']

Python

python
fake_flags=re.findall(r'0xV01D\{[^}]+\}', text) fake_flags ['0xV01D{y0u_th0ught_lmao_try_harder_xd}', '0xV01D{s0_cl0se_yet_s0_far_hahaha_nope}', '0xV01D{alm0st_but_n0t_qu1te_lol}'] 1952

Python

python
def find_aes_hits(data, keys): res=[] # also data first block iv, rest cbc for key in keys: for mode in ['ECB']: pt=aes_decrypt(key, mode, data=data) if pt: u=pkcs7_unpad(pt); sc=score_bytes(u) if b'0xV' in u or b'flag' in u.lower() or sc>.75: res.append((sc,mode,key,u[:200])) for ivname,iv,dd in [('zero',bytes(16),data),('first',data[:16],data[16:] if len(data)>16 else data)]: if len(dd)%16==0: pt=aes_decrypt(key,'CBC',iv,dd) if pt: u=pkcs7_unpad(pt); sc=score_bytes(u) if b'0xV' in u or b'flag' in u.lower() or sc>.75: res.append((sc,'CBC_'+ivname,key,u[:200])) return res # try for raw ct, rail variants base64 decode all_aes_hits=[] for name,t in [('raw',s)] + candidates_strings[:]: b=try_base64(t) if b and len(b)%16==0: hits=find_aes_hits(b,newkeys) for h in hits: all_aes_hits.append((name,)+h) len(all_aes_hits) 11

Python

python
for hit in sorted(all_aes_hits, key=lambda x:x[1], reverse=True)[:30]: name,sc,mode,key,u=hit print("----",name,sc,mode,key[:40],len(key)) print(u)

Python

python
trits=''.join(str({ZWSP:0,ZWNJ:1,ZWJ:2}[c]) for c in hidden) for group in [3,4,5,6,8]: vals=[int(trits[i:i+group],3) for i in range(0,len(trits)//group*group,group)] b=bytes(v for v in vals if v<256) print("group",group,"nvals",len(vals),"bytes",len(b),"score",score_bytes(b), b[:100]) print(b.find(b'0xV'), b.lower().find(b'flag')) # interpret whole base3 int n=int(trits,3) b=n.to_bytes((n.bit_length()+7)//8,'big') print('whole',len(b),score_bytes(b),b[:100],b.find(b'0xV'))

Python

python
import itertools chars=[ZWSP,ZWNJ,ZWJ] for perm in itertools.permutations('012'): mp=dict(zip(chars,perm)) tri=''.join(mp[c] for c in hidden) for group in [4,5,6]: vals=[int(tri[i:i+group],3) for i in range(0,len(tri)//group*group,group)] if all(v<256 for v in vals): b=bytes(vals) else: b=bytes(v for v in vals if v<256) sc=score_bytes(b) if sc>0.75 or b"0xV" in b or b"flag" in b.lower(): print("perm",perm,"group",group,"score",sc,"len",len(b), b[:200])

Python

python
for mapping in [(str.isdigit,'0 for digit'),(str.isalpha,'0 for alpha')]: pass for digit_bit in ['0','1']: bits2=''.join(digit_bit if c.isdigit() else ('1' if digit_bit=='0' else '0') for c in s) for group in [5,6,7,8]: out=[] for i in range(0,len(bits2)//group*group,group): v=int(bits2[i:i+group],2) if group==5: # Bacon 0-25 out.append(chr(97+v) if v<26 else '?') else: out.append(chr(v)) res=''.join(out) print("digit_bit",digit_bit,"group",group,"score",sum(ch in string.printable for ch in res)/len(res),repr(res[:100])) if 'flag' in res.lower() or '0x' in res.lower(): print('HIT',res)

Python

python
for source,t in [('s',s),('r5d',rail_decrypt(s,5)),('r5e',rail_encrypt(s,5))]: for db in ['0','1']: bits2=''.join(db if c.isdigit() else ('1' if db=='0' else '0') for c in t) res=''.join(chr(97+int(bits2[i:i+5],2)) if int(bits2[i:i+5],2)<26 else '?' for i in range(0,len(bits2)//5*5,5)) print(source,db,res)

Python

python
def decode_groups(groups, z0=ZWSP,z1=ZWNJ, reverse_bits=False, reverse_groups=False): gs=[g for g in groups if g] if reverse_groups: gs=gs[::-1] out=[] for g in gs: bits=''.join('0' if c==z0 else '1' for c in g) if reverse_bits: bits=bits[::-1] out.append(chr(int(bits,2))) return ''.join(out) variants=[] for z0,z1 in [(ZWSP,ZWNJ),(ZWNJ,ZWSP)]: for rb in [False,True]: for rg in [False,True]: t=decode_groups(groups,z0,z1,rb,rg) sc=sum(c in string.printable for c in t)/len(t) variants.append((sc,z0==ZWSP,rb,rg,t)) print(sc,z0==ZWSP,rb,rg,repr(t[:100]))

Python

python
for transform in [('not', lambda b: bytes((~x)&255 for x in b)), ('minus128',lambda b: bytes((x-128)%256 for x in b)), ('stripmsb',lambda b: bytes(x&0x7f for x in b)), ('swapnib',lambda b: bytes(((x&15)<<4)|(x>>4) for x in b)), ('revbits',lambda b: bytes(int(f'{x:08b}'[::-1],2) for x in b))]: name,fn=transform b=fn(ct) print(name,score_bytes(b),b[:120],b.find(b'0xV')) # try decompress?

Python

python
strip=bytes(x&0x7f for x in ct) print(strip.decode('latin1')) for k in range(128): b=bytes(x^k for x in strip) sc=score_bytes(b) if sc>.95 and (b'flag' in b.lower() or b'0x' in b.lower() or True): # print top maybe with english score pass # rank by English frequency def english_score(b): # return score based on letters space common? text=''.join(chr(x).lower() if 32<=x<127 else ' ' for x in b) common=sum(text.count(ch) for ch in ' etaoinshrdlu') bad=sum(1 for x in b if not (32<=x<127 or x in (9,10,13))) return common - bad*5 scores=[] for k in range(128): b=bytes(x^k for x in strip) scores.append((english_score(b),k,score_bytes(b),b[:100])) for item in sorted(scores, reverse=True)[:10]: print(item)

Python

python
from PIL import Image img=Image.open('/mnt/data/image.png') img.mode, img.size ('RGBA', (616, 580))

Python

python
import numpy as np, itertools, math, re, string, base64 arr=np.array(img) # try LSB bits channels RGB/A in row-major, group bytes, both bit orders, first N def bytes_from_bits(bits): return bytes(int(''.join(map(str,bits[i:i+8])),2) for i in range(0,len(bits)//8*8,8)) channels={'r':0,'g':1,'b':2,'a':3} hits=[] for chs in ['r','g','b','a','rgb','rgba','bgr','argb']: inds=[channels[c] for c in chs] bits=[] for pix in arr.reshape(-1,4): for i in inds: bits.append(pix[i]&1) for revbit in [False,True]: b=bytes_from_bits([*bits] if not revbit else [*bits]) if revbit: b=bytes(int(''.join(str(x) for x in bits[i:i+8][::-1]),2) for i in range(0,len(bits)//8*8,8)) head=b[:100 0

Python

python
import base64, zlib, bz2, lzma, gzip, re, string, math, hashlib, itertools, collections, functools, time, random flag_re=re.compile(rb'0xV01D\{[^}]{1,100}\}', re.I) def is_interesting(b): return flag_re.search(b) or b'0xV' in b or b'flag' in b.lower() or b'v01d' in b.lower() def to_bytes(x): return x.encode() if isinstance(x,str) else x def to_str(b): try: return b.decode('latin1') except: return ''.join(chr(x) for x in b) def rot_alnum(t,k,alphabet="0123456789abcdefghijklmnopqrstuvwxyz"): trans=str.maketrans(alphabet, alphabet[k:]+alphabet[:k]) return t.translate(trans) def atbash_alnum(t,alphabet="0123456789abcdefghijklmnopqrstuvwxyz"): return t.translate(str.maketrans(alphabet, alphabet[::-1])) start

Python

python
# Recompute variables cleanly from pathlib import Path text=Path('/mnt/data/challenge.txt').read_text('utf-8') ZWSP,ZWNJ,ZWJ='\u200b','\u200c','\u200d' hidden=''.join(c for c in text if c in (ZWSP,ZWNJ,ZWJ)) groups=hidden.split(ZWJ) s=''.join(chr(int(''.join('0' if c==ZWSP else '1' for c in g),2)) for g in groups if g) bits=''.join('0' if c==ZWSP else '1' if c==ZWNJ else '' for c in hidden) letters_only=''.join(c for c in s if c.isalpha()) digits_only=''.join(c for c in s if c.isdigit()) len(s), s[:50], len(bits), len(letters_only), len(digits_only) (192, '35101021a8r432431nisli89itp1304654316e1t4785939f5x', 1536, 70, 122)

Python

python
# retry BFS broader but with seen, limited import base64, zlib, bz2, lzma, gzip, re, string, math, hashlib, itertools, collections, time flag_re=re.compile(rb'0xV01D\{[^}]{1,120}\}', re.I) def is_interesting(b): return flag_re.search(b) or b'0xV01D' in b or b'v01d' in b.lower() or b'flag' in b.lower() def rail_decrypt(cipher, rails): if rails<=1: return cipher pattern=list(range(rails))+list(range(rails-2,0,-1)) idx=[pattern[i%len(pattern)] for i in range(len(cipher))] counts=[idx.count(r) for r in range(rails)] rails_buf=[]; p=0 for c in counts: rails_buf.append(list(cipher[p:p+c])); p+=c pos=[0]*rails; out=[] for r in idx: out.append(rails_buf[r][pos[r]]); pos

Python

python
# BFS for exact 0xV/v01d only, ignoring 'flag' def is_hit(b): return flag_re.search(b) or b'0xV01D' in b or b'0xv01d' in b.lower() or b'v01d{' in b.lower() seen=set(); queue=collections.deque((name,b,0) for name,b in start_items) limit=100000 cnt=0; found=[] while queue and cnt<limit: name,b,depth=queue.popleft(); cnt+=1 if is_hit(b): found.append((name,b[:500])); print("FOUND",name,b[:500]); break if depth>=3: continue key=(hashlib.md5(b).digest(), depth) if key in seen: continue seen.add(key) outs=[] if len(b)>0 and len(b)<5000: try: t=b.decode('ascii') if all(ch in string.printable for ch in t): for label,func in [ ('b64',lambda x:base64.b64decode

Python

python
# Build transformation found t=rot_alnum(s,14) u=rail_decrypt(t,13) u, len(u), u.find('flag'), u[u.find('flag')-20:u.find('flag')+50] ('howimtgnzymu3w6ffnz8ml7mj53mmxfgeuh7km1eleicljfifhhn1mz9nkml0fgyenn5fhegeiin1znslkrnfhknshfwwtkhffjjw5mjecfft0meealegbi1ewh5jji6g0ntf9jolhe0kgf6gzkzhjcnillgev55nenlemswfmflag5khxhl2aya2kqi5v7n', 192, 170, 'cnillgev55nenlemswfmflag5khxhl2aya2kqi5v7n')

Python

python
for k in [677%36, -677%36, 677%26, -677%26]: tt=rot_alnum(s,k) if k in range(36) else caesar_letters(s,k) print(k, tt[:100]) # rail 5 decrypt/encrypt for r in [5,13,14,29]: print('r',r,rail_decrypt(tt,r)[:100]) print()

Python

python
def rot47(s,k=47): out='' for c in s: o=ord(c) if 33<=o<=126: out+=chr(33+(o-33+k)%94) else: out+=c return out for k in [47,677%94, -677%94]: t=rot47(s,k) print("k",k,t[:200]) if '0x' in t: print(t) b=try_base64(t) if b: print("b64",score_bytes(b),b[:50])

Python

python
idx=text.find(ZWSP) idx, len(text[:idx]), len(text[:idx].encode()), text[:idx][-50:] (438, 438, 438, 'AHAHAHA.\nThe wise man once said: U NEED TO DO 677.')

Python

python
len(text.encode('utf-8')), len(hidden.encode('utf-8')), len(text)-len(hidden), len(text.encode())-len(hidden.encode()) (6238, 5184, 1051, 1054)

Python

python
# Decode hidden groups starting from each delimiter/char? # For each start position in hidden run, split by ZWJ then groups of length 8 valid -> payload; look for flags/english def decode_from_sub(h): gr=h.split(ZWJ) outs=[] for g in gr: if len(g)==8 and all(c in (ZWSP,ZWNJ) for c in g): bits=''.join('0' if c==ZWSP else '1' for c in g) outs.append(chr(int(bits,2))) return ''.join(outs) for start in [0,677,676,678,8203%len(hidden), len(hidden)-677]: t=decode_from_sub(hidden[start:]) print("start",start,"len",len(t),"score",sum(c in string.printable for c in t)/max(1,len(t)),repr(t[:200]))

Python

python
for N in [677,678,676,1728-677]: t=decode_from_sub(hidden[:N]) print("N",N,"len",len(t),repr(t[:200]), "b64?", try_base64(t)[:10] if try_base64(t) else None)

Python

python
data=s.encode() cands=[] for kl in range(1,41): key=bytes(best_key_for_col(data[i::kl]) for i in range(kl)) pt=bytes(c^key[i%kl] for i,c in enumerate(data)) sc=score_text(pt)/len(pt) if sc>4 or b'0x' in pt or b'flag' in pt.lower(): cands.append((sc,kl,key,pt)) for sc,kl,key,pt in sorted(cands, reverse=True)[:20]: print('kl',kl,'score',sc,'key',key,'pt',pt[:200])

Python

python
def columnar_decrypt(cipher,key): n=len(key); L=len(cipher) # order columns by key chars stable order=sorted(range(n), key=lambda i:(key[i],i)) rows=math.ceil(L/n) # column lengths when plaintext row-wise fill full_cols=L % n col_lens=[rows if (full_cols==0 or i<full_cols) else rows-1 for i in range(n)] cols=['']*n; p=0 for i in order: l=col_lens[i]; cols[i]=cipher[p:p+l]; p+=l out=[] for r in range(rows): for c in range(n): if r<len(cols[c]): out.append(cols[c][r]) return ''.join(out) def columnar_encrypt(plain,key): n=len(key); rows=math.ceil(len(plain)/n) cols=['']*n for i,ch in enumerate(plain): cols[i%n]+=ch order=sorted(range(n), key=lambda i:(key[i],i)) return ''.join(cols[i] for i in order) for key in ['677','676','077','U NEED TO DO 677','needtodo

Python

python
u=rail_decrypt(rot_alnum(s,14),13) # Explore further one/two transforms on u for 0x/flag for k in range(36): v=rot_alnum(u,k) if '0xv' in v.lower() or 'flag' in v.lower() or 'void' in v.lower(): print("rot",k,v[:200]) for r in range(2,50): for label,func in [('rd',rail_decrypt),('re',rail_encrypt)]: v=func(u,r) if '0xv' in v.lower() or 'flag' in v.lower() or 'void' in v.lower(): print(label,r,v[:200]) # b64? b=try_base64(v) if b and (b'0xV' in b or b'flag' in b.lower() or score_bytes(b)>.65): print("b64",label,r,score_bytes(b),b[:100]) # substring around flag maybe shift chars? u 'howimtgnzymu3w6ffnz8ml7mj53mmxfgeuh7km1eleicljfifhhn1mz9nkml0fgyenn5fhegeiin1znslkrnfhknshfwwtkhffjjw5mjecfft0meealegbi1ewh5jji6g0ntf9jolhe0kgf6gzkzhjcnillgev55nenlemswfmflag5khxhl2aya2kqi5v7n'

Python

python
b=try_base64(u) len(b), score_bytes(b), b[:100], b.hex()[:100] (144, 0.3611111111111111, b'\x86\x8c"\x9a\xd8\'\xcf)\xae\xdf\x0e\x9f~|\xfc\x9a^\xe6\x8f\x9d\xe6\x9b\x17\xe0z\xe8{\x92m^\x95\xe8\x9c\x967\xe2~\x18g\xd6l\xfd\x9eI\xa5\xd1\xf82zy\xf9~\x17\xa0z(\xa7\xd79\xec\x96J\xe7~\x19\'\xb2\x17\xf0\xc2\xd9!}\xf8\xe3\xc3\x99\xa3y\xc7\xdf\xb7I\x9ey\xa9^\x81\xb8\xb5{\x08y\x8e8\xba\x83I\xed\x7f', '868c229ad827cf29aedf0e9f7e7cfc9a5ee68f9de69b17e07ae87b926d5e95e89c9637e27e1867d66cfd9e49a5d1f8327a79')

Python

python
for r in [5,13,6,7]: for label,func in [('d',rail_decrypt),('e',rail_encrypt)]: v=func(u,r) print(label,r,v[:200], 'flagpos', v.find('flag'), 'howpos', v.find('how'))

Python

python
alph="0123456789abcdefghijklmnopqrstuvwxyz" def vig_alnum(t,key,decode=True): out=[]; ki=0 shifts=[] for ch in key: if ch in alph: shifts.append(alph.index(ch)) elif ch.isdigit(): shifts.append(int(ch)) elif ch.isalpha(): shifts.append(ord(ch.lower())-97) if not shifts: return t for ch in t: if ch in alph: sh=shifts[ki%len(shifts)] if decode: sh=-sh out.append(alph[(alph.index(ch)+sh)%len(alph)]) ki+=1 else: out.append(ch) return ''.join(out) for key in ['677','676','HAHAHAHA','void','0xV01D','needtodo677','u']: for dec in [True,False]: v=vig_alnum(s,key,dec) for r in [5,6

Python

python
words=['how','flag','the','you','need','void','try','hard','lmao','close','not','what','get','see','real'] matches=[] for k in range(36): t=rot_alnum(s,k) for r in range(2,50): for label,func in [('rd',rail_decrypt),('re',rail_encrypt)]: v=func(t,r) wscore=sum(v.count(w) for w in words) if wscore: matches.append((wscore,k,label,r,v[:200])) for m in sorted(matches, reverse=True)[:50]: print(m[:4],m[4])

Python

python
u_letters=''.join(c for c in u if c.isalpha()) u_digits=''.join(c for c in u if c.isdigit()) u_letters, len(u_letters), u_digits[:100], len(u_digits) ('howimtgnzymuwffnzmlmjmmxfgeuhkmeleicljfifhhnmznkmlfgyennfhegeiinznslkrnfhknshfwwtkhffjjwmjecfftmeealegbiewhjjigntfjolhekgfgzkzhjcnillgevnenlemswfmflagkhxhlayakqivn', 163, '36875371190515015609065552257', 29)

Python

python
for k in range(26): v=caesar_letters(u_letters,k) if any(w in v for w in ['the','you','flag','how','need','void']): print(k,v[:200])

Python

python
flag_matches=[] for source_name,base in [('s',s),('rev',s[::-1])]: for k in range(36): t=rot_alnum(base,k) for r in range(2,80): for label,func in [('rd',rail_decrypt),('re',rail_encrypt)]: v=func(t,r) pos=v.find('flag') if pos!=-1: flag_matches.append((source_name,k,label,r,pos,v[max(0,pos-30):pos+60],v)) len(flag_matches) 4

Python

python
for m in flag_matches: print(m[:6])

Python

python
v=flag_matches[-1][-1] v, len(v) ('2aya2kqi5v7nfmflag5khxhlev55nenlemswgzkzhjcnillgf9jolhe0kgf6ewh5jji6g0ntt0meealegbi1ffjjw5mjecfffhknshfwwtkheiin1znslkrn0fgyenn5fhegfhhn1mz9nkmlkm1eleicljfij53mmxfgeuh73w6ffnz8ml7mhowimtgnzymu', 192)

Python

python
def atbash_letters(s): return ''.join(chr(122-(ord(c)-97)) if 'a'<=c<='z' else c for c in s) for v in [u, atbash_letters(u), atbash_alnum(u)]: print(v[:200]) print('flag',v.find('flag'),'0x',v.find('0x'), 'how', v.find('how'), 'the', v.find('the'))

Python

python
def show_trans_text(t, words=['the','you','flag','how','need']): out=[] for name,v in transpositions(t): score=sum(v.count(w) for w in words) if score: out.append((score,name,v[:200])) return sorted(out, reverse=True)[:20] show_trans_text(u_letters)[:10] [(2, 'r1c163_revrows', 'howimtgnzymuwffnzmlmjmmxfgeuhkmeleicljfifhhnmznkmlfgyennfhegeiinznslkrnfhknshfwwtkhffjjwmjecfftmeealegbiewhjjigntfjolhekgfgzkzhjcnillgevnenlemswfmflagkhxhlayakqivn'), (2, 'r1c163_fillcol_readrow', 'howimtgnzymuwffnzmlmjmmxfgeuhkmeleicljfifhhnmznkmlfgyennfhegeiinznslkrnfhknshfwwtkhffjjwmjecfftmeealegbiewhjjigntfjolhekgfgzkzhjcnillgevnenlemswfmflagkhxhlayakqivn'), (2, 'r1c163_col_revrow', 'howimtgnzymuwffnzmlmjmmxfgeuhkmeleicljfifhhnmznkmlfgyennfhegeiinznslkrnfhknshfwwtkhffjjwmjecfftmeealegbiewhjjigntfjolhekgfgzkzhjcnillgevnenlemswfmflagkhxhlayakqivn'), (2, 'r1c163_col', 'howimtgnzymuwffnzmlmjmmxfgeuhkmeleicljfifhhnmznkmlfgyennfhegeiinznslkrnfhknshfwwtkhffjjwmjecfftmeealegbiewhjjigntfjolhekgfgzkzhjcnillgevnenlemswfmflagkhxhlayakqivn'), (2, 'r163c1_rowrev', 'howimtgnzymuwffnzmlmjmmxfgeuhkmeleicljfifhhnmznkmlfgyennfhegeiinznslkrnfhknshfwwtkhffjjwmjecfftmeealegbiewhjjigntfjolhekgfgzkzhjcnillgevnenlemswfmflagkhxhlayakqivn'), (2, 'r163c1_fillcol_readrow', 'howimtgnzymuwffnzmlmjmmxfgeuhkmeleicljfifhhnmznkmlfgyennfhegeiinznslkrnfhknshfwwtkhffjjwmjecfftmeealegbiewhjjigntfjolhekgfgzkzhjcnillgevnenlemswfmflagkhxhlayakqivn'), (2, 'r163c1_col', 'howimtgnzymuwffnzmlmjmmxfgeuhkmeleicljfifhhnmznkmlfgyennfhegeiinznslkrnfhknshfwwtkhffjjwmjecfftmeealegbiewhjjigntfjolhekgfgzkzhjcnillgevnenlemswfmflagkhxhlayakqivn')]

Python

python
raw=Path('/mnt/data/challenge.txt').read_bytes() raw_lines=raw.splitlines() last_bytes=bytes(line[-1] for line in raw_lines if line) last_bytes, len(last_bytes), last_bytes[:16] (b'....?=.\x8d)))))}}}...\x88', 20, b'....?=.\x8d)))))}}}')

Python

python
# Add last_bytes variants for AES for L in [16,20]: print(L,last_bytes[:L]) cand2=set(newkeys if 'newkeys' in globals() else []) for src in [last_bytes,last_bytes[:16], last_bytes[-16:], last_bytes[1:17], last_bytes[:20]]: for L in [16,24,32]: if len(src)>=L: cand2.add(src[:L]) if len(src)<L: cand2.add(src.ljust(L,b'\0')); cand2.add(src.ljust(L,b' ')) cand2.add(hashlib.md5(src).digest()) cand2.add(hashlib.sha256(src).digest()[:L] if L<32 else hashlib.sha256(src).digest()) keys2=[k for k in cand2 if len(k) in (16,24,32)] hits=find_aes_hits(ct,keys2) len(hits), hits[:5] (0, [])

Python

python
prefix=b'0xV01D{' for kl in range(1,41): key=[None]*kl ok=True for i,pb in enumerate(prefix): pos=i%kl val=ct[i]^pb if key[pos] is not None and key[pos]!=val: ok=False;break key[pos]=val if not ok: continue # fill unknown by best scoring column key2=bytearray(kl) for j in range(kl): if key[j] is not None: key2[j]=key[j] else: key2[j]=best_key_for_col(ct[j::kl]) pt=bytes(c^key2[i%kl] for i,c in enumerate(ct)) if score_bytes(pt)>0.8 or b'0xV' in pt: print("kl",kl,"score",score_bytes(pt),'key',key2,'pt',pt[:200])

Pensamiento

Preparing a carefully phrased final writeup

I need to weigh how to phrase the final response. From the user's message, it seems I should aim to reach a solution and then explain it. I’ll try to avoid sounding like we failed and instead focus on where I’ve made progress. Adding the phrase "flag temporarily identified: unverified" seems fair. I'll make sure to back up the response with a detailed writeup, including scripts and payload.

Thought for 28m 5s

Respuesta

Mình bóc được tầng stego chắc chắn trong challenge.txt, nhưng chưa thể xác nhận flag hợp lệ từ artifact bạn gửi. File có nhiều mồi nhử: Base64 visible decode ra câu “this is not the way lol try harder”, 3 flag nhìn thấy đều được đặt trong ngữ cảnh “maybe / try harder”, và các note cũng có vẻ troll. (challenge.txt)

Kết quả chắc chắn nhất hiện tại là payload ẩn bằng zero-width characters:

text
35101021a8r432431nisli89itp1304654316e1t4785939f5xr2l87h8887n1nii25630wrfujy8rlir05m57242l14l9918740y9rc9920v9e35ws39066l107907e0027493ok1g06k69y0ma7rjw8s3n82d618957r3kgit871931mfv2h7wp6m1f10o

Mình không khuyến nghị submit các flag sau vì chúng là decoy:

text
0xV01D{y0u_th0ught_lmao_try_harder_xd} 0xV01D{s0_cl0se_yet_s0_far_hahaha_nope} 0xV01D{alm0st_but_n0t_qu1te_lol}

Write-up

1. Nhận diện hướng đi

Tên challenge là:

text
What You See Is Not What You Get

Nội dung file có hint:

text
The answer lies within the silence between words hides in plain sight Listen with your tools

=> Đây là dấu hiệu rất rõ của invisible / zero-width steganography.

2. Kiểm tra file

Lệnh dùng:

bash
file challenge.txt cat challenge.txt grep -aoE '0xV01D\{[^}]+\}' challenge.txt

Kết quả grep ra các flag nhìn thấy, nhưng đều là mồi nhử.

Decode Base64 nhìn thấy:

bash
echo 'dGhpcyBpcyBub3QgdGhlIHdheSBsb2wgdHJ5IGhhcmRlcg==' | base64 -d

Output:

text
this is not the way lol try harder

=> Base64 này cũng là decoy.

3. Extract zero-width characters

Trong file có 3 ký tự ẩn:

text
U+200B ZERO WIDTH SPACE U+200C ZERO WIDTH NON-JOINER U+200D ZERO WIDTH JOINER

Thống kê:

text
U+200B: 808 U+200C: 728 U+200D: 192 Total : 1728

Pattern rất đẹp: U+200D đóng vai trò separator, mỗi block trước nó dài đúng 8 ký tự. Vì vậy map:

text
U+200B -> 0 U+200C -> 1 U+200D -> separator

mỗi block 8 bit thành 1 byte ASCII.

4. Script đã dùng

python
#!/usr/bin/env python3 from pathlib import Path import sys import base64 from collections import Counter ZWSP = "\u200b" # zero width space ZWNJ = "\u200c" # zero width non-joiner ZWJ = "\u200d" # zero width joiner def rail_fence_decrypt(cipher: str, rails: int) -> str: if rails <= 1: return cipher pattern = list(range(rails)) + list(range(rails - 2, 0, -1)) rail_index = [pattern[i % len(pattern)] for i in range(len(cipher))] counts = [rail_index.count(r) for r in range(rails)] rails_buf = [] p = 0 for c in counts: rails_buf.append(list(cipher[p:p + c])) p += c pos = [0] * rails plain = [] for r in rail_index: plain.append(rails_buf[r][pos[r]]) pos[r] += 1 return "".join(plain) def main(path: str): text = Path(path).read_text(encoding="utf-8") hidden = "".join(c for c in text if c in (ZWSP, ZWNJ, ZWJ)) print("[+] zero-width chars:", len(hidden)) print("[+] counts:") for k, v in Counter(hidden).items(): print(f" U+{ord(k):04X}: {v}") groups = hidden.split(ZWJ) groups = [g for g in groups if g] print("[+] groups:", len(groups)) print("[+] group lengths:", sorted(set(map(len, groups)))) if not all(len(g) == 8 for g in groups): raise ValueError("Không phải tất cả group đều dài 8 bit") out = [] for g in groups: bits = "".join("0" if c == ZWSP else "1" for c in g) out.append(chr(int(bits, 2))) payload = "".join(out) print("\n[+] extracted payload:") print(payload) print("\n[+] try visible-looking Base64 decode of payload:") try: raw = base64.b64decode(payload + "=" * ((4 - len(payload) % 4) % 4)) print(" decoded length:", len(raw)) print(" hex preview:", raw[:64].hex()) except Exception as e: print(" failed:", e) print("\n[+] rail fence thử theo hint rails=5:") print(rail_fence_decrypt(payload, 5)) if __name__ == "__main__": if len(sys.argv) != 2: print(f"Usage: {sys.argv[0]} challenge.txt") sys.exit(1) main(sys.argv[1])

Chạy:

bash
python3 solve.py challenge.txt

Output quan trọng:

text
[+] zero-width chars: 1728 [+] groups: 192 [+] group lengths: [8] [+] extracted payload: 35101021a8r432431nisli89itp1304654316e1t4785939f5xr2l87h8887n1nii25630wrfujy8rlir05m57242l14l9918740y9rc9920v9e35ws39066l107907e0027493ok1g06k69y0ma7rjw8s3n82d618957r3kgit871931mfv2h7wp6m1f10o

5. Các hướng đã thử nhưng chưa ra flag xác thực

Mình đã thử các hướng sau trên payload:

text
Base64 decode Rail fence rails=5 Rail fence nhiều rails khác XOR với 677 / HAHAHAHA / last-char-of-lines AES ECB/CBC với key suy ra từ các hint Reverse / ROT / Base36 / Base85 Morse mapping từ zero-width chars

Không có output nào ra dạng xác thực:

text
0xV01D{...}

Kết luận

Với đúng file bạn gửi, mình xác định được tầng stego chính là zero-width binary, nhưng chưa tìm được flag hợp lệ. Khả năng cao còn thiếu artifact gốc từ nút “Download Challenge” hoặc file này đã được dựng để troll với payload tầng sau chưa đủ thông tin/key.

Payload cần tiếp tục xử lý là:

text
35101021a8r432431nisli89itp1304654316e1t4785939f5xr2l87h8887n1nii25630wrfujy8rlir05m57242l14l9918740y9rc9920v9e35ws39066l107907e0027493ok1g06k69y0ma7rjw8s3n82d618957r3kgit871931mfv2h7wp6m1f10o

Gửi thêm file gốc tải từ challenge, mình sẽ nối tiếp từ payload này để ra flag submit được.

Compartir este Q&A