CyberStudents Wordmark

Epochrypt

Category

Points

Author

Cryptography

70

q

qvipin

Solves (97)

1Profile Picture for minipifminipif12/06 3:59 pm
2Profile Picture for tudortudor12/06 4:01 pm
3Profile Picture for unpwnblunpwnbl12/06 4:07 pm
4Profile Picture for silence_silence_12/06 4:08 pm
5Profile Picture for raul_26raul_2612/06 4:20 pm
6Profile Picture for _4n3s_4n3s12/06 4:25 pm
7Profile Picture for mr_mphmr_mph12/06 4:29 pm
8Profile Picture for boomanten10boomanten1012/06 4:39 pm
9Profile Picture for zarnex__zarnex__12/06 4:42 pm
10Profile Picture for Ricker WilkesRicker Wilkes12/06 5:24 pm
11Profile Picture for ShrelicShrelic12/06 5:28 pm
12Profile Picture for batterseabattersea12/06 5:40 pm
13Profile Picture for godlyavengergodlyavenger12/06 6:15 pm
14Profile Picture for _vow__vow_12/06 8:41 pm
15Profile Picture for dailybee13.dailybee13.12/07 1:57 am
16Profile Picture for pligonsteinpligonstein12/07 4:55 am
17Profile Picture for kr4z31nkr4z31n12/07 6:16 am
18Profile Picture for heartstollerheartstoller12/07 7:47 am
19Profile Picture for dharneesh5555dharneesh555512/07 11:58 am
20Profile Picture for booklover997booklover99712/07 1:34 pm
21Profile Picture for eth007eth00712/07 10:45 pm
22Profile Picture for jokzyzjokzyz12/08 5:55 pm
23Profile Picture for peterw18peterw1812/09 7:46 am
24Profile Picture for midnightfammidnightfam12/09 9:41 am
25Profile Picture for org_benerorg_bener12/10 12:31 am
26Profile Picture for theb4tmitetheb4tmite12/11 8:12 am
27Profile Picture for mage9298mage929812/14 2:14 am
28Profile Picture for andreicatandreicat12/14 1:00 pm
29Profile Picture for nouxianouxia12/15 6:19 am
30Profile Picture for sevgillim_.sevgillim_.12/15 9:09 am
31Profile Picture for whofulwhoful12/15 1:36 pm
32Profile Picture for mostafa__1688mostafa__168812/15 6:43 pm
33Profile Picture for giangndgiangnd12/16 8:49 am
34Profile Picture for rotzkokowskirotzkokowski12/16 9:51 am
35Profile Picture for joeblack7788joeblack778812/16 9:51 am
36Profile Picture for rex_i_arex_i_a12/16 4:27 pm
37Profile Picture for colonneilcolonneil12/16 6:44 pm
38Profile Picture for _erray__erray_12/16 9:22 pm
39Profile Picture for puwanai.spuwanai.s12/16 9:22 pm
40Profile Picture for andreww4364andreww436412/17 3:30 am
41Profile Picture for .hackboredzz.hackboredzz12/17 7:01 am
42Profile Picture for neilsterrneilsterr12/17 3:28 pm
43Profile Picture for trixaitrixai12/17 4:12 pm
44Profile Picture for ryuun1cornryuun1corn12/18 1:58 am
45Profile Picture for monstermanyana_47633monstermanyana_4763312/18 3:44 am
46Profile Picture for d3dn0v4d3dn0v412/18 5:24 am
47Profile Picture for justk4l_justk4l_12/18 9:30 am
48Profile Picture for damian.28damian.2812/18 10:27 am
49Profile Picture for __landon__landon12/18 12:50 pm
50Profile Picture for dustcoversdustcovers12/18 1:19 pm
51Profile Picture for room2042.room2042.12/18 2:51 pm
52Profile Picture for fzhshzh_163fzhshzh_16312/18 8:26 pm
53Profile Picture for athawathaw12/18 9:33 pm
54Profile Picture for neilguyeverywhereneilguyeverywhere12/19 9:02 am
55Profile Picture for helius1288helius128812/19 10:21 am
56Profile Picture for saik9415saik941512/19 11:27 am
57Profile Picture for infernosalexinfernosalex12/19 1:20 pm
58Profile Picture for f00varf00var12/20 8:49 pm
59Profile Picture for vuxnx_91621vuxnx_9162112/21 3:57 am
60Profile Picture for mobyduckmobyduck12/21 1:49 pm
61Profile Picture for verbalverbalverbalverbal12/21 7:06 pm
62Profile Picture for manu7738manu773812/21 7:25 pm
63Profile Picture for abdou__ammariabdou__ammari12/22 3:59 am
64Profile Picture for mtwiss_32447mtwiss_3244712/22 10:38 am
65Profile Picture for spectre06872spectre0687212/22 11:07 am
66Profile Picture for inoginninoginn12/22 12:31 pm
67Profile Picture for captainblcaptainbl12/23 3:31 am
68Profile Picture for holygoos3holygoos312/23 8:45 am
69Profile Picture for aarondewesaarondewes12/23 11:23 am
70Profile Picture for iam_the_tea_guyiam_the_tea_guy12/23 3:39 pm
71Profile Picture for awdyan_awdyan_12/23 4:39 pm
72Profile Picture for re_tiredre_tired12/24 2:29 am
73Profile Picture for awwliveyetawwliveyet12/24 1:57 pm
74Profile Picture for v3ged4g.v3ged4g.12/25 12:59 am
75Profile Picture for concealbearconcealbear12/25 1:45 am
76Profile Picture for genseilni9593genseilni959312/25 1:59 am
77Profile Picture for predatormonarchpredatormonarch12/25 7:06 am
78Profile Picture for mattewastakenmattewastaken12/25 8:44 am
79Profile Picture for zzunaidd023zzunaidd02312/25 9:38 am
80Profile Picture for darkitydarkity12/25 10:58 am
81Profile Picture for tildenjacksontildenjackson12/25 11:49 am
82Profile Picture for 6oq.6oq.12/25 4:48 pm
83Profile Picture for hanks2151hanks215112/25 4:48 pm
84Profile Picture for m4422m442212/25 5:34 pm
85Profile Picture for lalith_sai_x7777lalith_sai_x777712/26 12:16 am
86Profile Picture for wilsonwei_cswilsonwei_cs12/26 12:32 am
87Profile Picture for kineticallyunstablekineticallyunstable12/26 12:39 am
88Profile Picture for isee9917isee991712/26 5:38 am
89Profile Picture for papa9995papa999512/26 6:38 am
90Profile Picture for _vga__vga_12/26 1:40 pm
91Profile Picture for 0x0ffset0x0ffset12/27 11:12 pm
92Profile Picture for lamentxulamentxu12/28 2:33 am
93Profile Picture for .jstr_.jstr_12/28 4:12 am
94Profile Picture for fakeaviationistfakeaviationist12/28 12:13 pm
95Profile Picture for fazectfazect12/29 6:29 am
96Profile Picture for baribal02baribal0212/29 8:49 am
97Profile Picture for darkimoo.darkimoo.12/29 10:26 pm

Description

It's time to test out Tibel Elf's new encryption method. He says once you encrypt it, you can't unencrypt it. Sureeee... Connect with nc ctf.csd.lol 3551.

Attachments

Hint

There are no penalties for viewing hints. Hints are released 12 hours and 24 hours after the challenge releases.

Submit flag

Discuss this challenge with others in #🎄丨advent-of-ctf on our Discord server.

Write-up

zarnex's write-up was selected as the best write-up submitted for this challenge.

View this write-up on GitHub

Lets look at main.py.

#!/usr/local/bin/python
import time
import base64 as b64
from pwn import xor

def epochrypt(enc):
    bits = bytes([(b + 3) % 256 for b in enc])
    based = b64.b64encode(bits)
    epc = str(int(time.time())).encode()
    final = xor(based, epc)
    print(final.hex())


def menupage():
    print("Epochrypt v1.0")
    print("\"The Dynamic Encryption Method\"")
    print("------------------------------------")
    print("1. Encrypt Text")
    print("2. View Encrypted Flag")
    print("3. Check Flag")
    print("4. Exit Program")


try:
    while True:
        menupage()
        option = input("Enter option here: ")
        if option == "1":
            textToEncrypt = input("Enter String: ")
            epochrypt(textToEncrypt.encode())
            exit(0)
        if option == "2":
            with open("/app/flag.txt", "rb") as file:
                flag = file.read()
            epochrypt(flag)
            exit(0)
        if option == "3":
            checkFlag = input("Enter flag here to check: ")
            with open("/app/flag.txt", "rb") as file:
                flag = file.read()
                if flag in (checkFlag + "\n").encode():
                    print("Correct! You got it, now go submit that thang.")
                    exit(0)
                else:
                    print("*BUZZ* That ain't it bud :(")
                    exit(0)
        if option == "4":
            print("bye bye!")
            exit(0)

except KeyboardInterrupt:
    print("CTRL + C detected, Quitting program...")

Most of this is straight forward with all the features, but the main thing we need to focus on is the epochrypt() function.

def epochrypt(enc):
    bits = bytes([(b + 3) % 256 for b in enc])
    based = b64.b64encode(bits)
    epc = str(int(time.time())).encode()
    final = xor(based, epc)
    print(final.hex())

This may be a small function but it packs a punch! Lets go over this line by line.

bits = bytes([(b + 3) % 256 for b in enc])

The first line is pretty much adding 3 to every characters ASCII values, kinda treating it like a Caeser Cipher. Using this one liner print(bytes([(b + 3) % 256 for b in b'hello'])), we see that hello becomes khoor.

based = b64.b64encode(bits)

In this line it takes the items from bits and Base64 encodes them.

epc = str(int(time.time())).encode()
final = xor(based, epc)

Now here comes the interesting part, first it takes the current Unix Epoch time and turns them into a int to strip the decimal at the end, after that it XOR's it by Based. This is probably where it gets the "The Dynamic Encryption Method" name from because it XOR's it by Epoch time (The amount of time since January 1, 1970) so it will never be the same again.

print(final.hex())

And then finally it outputs the text in Hex! Lets try it out for ourself.

$ nc ctf.csd.lol 3551
Epochrypt v1.0
"The Dynamic Encryption Method"
------------------------------------
1. Encrypt Text
2. View Encrypted Flag
3. Check Flag
4. Exit Program
Enter option here: 1
Enter String: Hello
62055b405201710d6507

$ nc ctf.csd.lol 3551
Epochrypt v1.0
"The Dynamic Encryption Method"
------------------------------------
1. Encrypt Text
2. View Encrypted Flag
3. Check Flag
4. Exit Program
Enter option here: 1
Enter String: Hello
62055b405201710d6406

Here I tried to encrypt Hello twice, notice how it is different. This is because it XOR's with the Epoch time which changes every second. Now we gotta figure out how to reverse the text. Here is what I wrote

from pwn import *
from base64 import b64decode
from time import sleep, time

I started off by importing pwntools to connect to the server and to items, then imported time to grab the epoch time and use sleep()

target = remote("ctf.csd.lol", 3551) # Connecting to the server
sleep(2) # Pausing the program
target.sendline("2") # Sending 2 to print out flag
epc = str(int(time())) # Grabbing the epoch time exactly when 2 is sent
sleep(2) # Pausing for 2 seconds

So I did write comments above on what each line does, but the general idea on what this part of the script does it to grab the epoch when it enters 2 so we have the exact epoch time to XOR with.

One thing I had noticed was that the flag when pressing option 2 always started with 6b5969 so now we can just

response = target.recv(1000).decode()  # Receive up to 1000 bytes
start_idx = response.find("6b5969")  # Find the position of "6b5969"
enc_flag = response[start_idx:].split("\n")[0].strip()  # Extract flag from marker to end of line

Now we have that extraction, all we need to do now is to write the next part of the script to reverse the encryption.

flag = bytes([(b - 3) % 256 for b in b64decode(xor(bytes.fromhex(enc_flag), epc))]) # Very Concise 1 liner that reverses the epochrypt operations
print(f"Flag: {flag.decode()}") # Decodes flag so output wouldn't be b''

So the full solution is...

from pwn import *
from base64 import b64decode
from time import sleep, time

target = remote("ctf.csd.lol", 3551)
sleep(2)
target.sendline("2")
epc = str(int(time()))
sleep(2)
response = target.recv(1000).decode()
start_idx = response.find("6b5969")
enc_flag = response[start_idx:].split("\n")[0].strip()
flag = bytes([(b - 3) % 256 for b in b64decode(xor(bytes.fromhex(enc_flag), epc))])
print(f"Flag: {flag.decode()}")

Running it...

$ /bin/python3 /home/zarnex/advent_of_ctf/epochrypt/solution.py
[+] Opening connection to ctf.csd.lol on port 3551: Done
/home/zarnex/advent_of_ctf/epochrypt/solution.py:8: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  target.sendline("2")
/home/zarnex/.local/lib/python3.12/site-packages/pwnlib/util/fiddling.py:335: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  strs = [packing.flat(s, word_size = 8, sign = False, endianness = 'little') for s in args]
Flag: csd{d3F0_M4d3_8y_4N_3lf}

Yes! But lets double check the flag...

$ nc ctf.csd.lol 3551
Epochrypt v1.0
"The Dynamic Encryption Method"
------------------------------------
1. Encrypt Text
2. View Encrypted Flag
3. Check Flag
4. Exit Program
Enter option here: 3
Enter flag here to check: csd{d3F0_M4d3_8y_4N_3lf}
Correct! You got it, now go submit that thang.

Flag: csd{d3F0_M4d3_8y_4N_3lf}

Need help with a challenge? Is a challenge broken? DM @ModMail in our Discord server.