Challenge Overview
Challenge Name | Category | Difficulty | Link |
---|---|---|---|
Sugar Free Candies | Crypto | Very Easy | Link to Challenge |
Description
For years, strange signals pulsed through the air on the eve of October 31st. Some said it was the voice of an ancient witch, while others believed it was a message from something far darker. A cryptic message, scattered in three parts, was intercepted by a daring group of villagers. Legend spoke of a deal made between the witch and a shadowy figure, but the true intent of their secret could only be revealed by those brave enough to decipher it before midnight, when the veil between worlds would thin.
Process
Upon downloading the assistive ZIP file, I found two files: output.txt
and source.py
.
Contents of output.txt
v1 = 4196604293528562019178729176959696479940189487937638820300425092623669070870963842968690664766177268414970591786532318240478088400508536
v2 = 11553755018372917030893247277947844502733193007054515695939193023629350385471097895533448484666684220755712537476486600303519342608532236
v3 = 14943875659428467087081841480998474044007665197104764079769879270204055794811591927815227928936527971132575961879124968229204795457570030
v4 = 6336816260107995932250378492551290960420748628
Contents of source.py
FLAG = open("flag.txt", "rb").read()
step = len(FLAG) // 3
candies = [bytes_to_long(FLAG[i:i+step]) for i in range(0, len(FLAG), step)]
cnd1, cnd2, cnd3 = candies
with open('output.txt', 'w') as f:
f.write(f'v1 = {cnd1**3 + cnd3**2 + cnd2}\n')
f.write(f'v2 = {cnd2**3 + cnd1**2 + cnd3}\n')
f.write(f'v3 = {cnd3**3 + cnd2**2 + cnd1}\n')
f.write(f'v4 = {cnd1 + cnd2 + cnd3}\n')
The source.py
script reads a file named flag.txt
, splits its content into three parts, converts them into long integers, and writes four calculated values (v1
, v2
, v3
, v4
) to output.txt
.
Breakdown of the Calculation:
- The
FLAG
(content fromflag.txt
) is divided into three equal parts. - These parts are converted to long integers (
cnd1
,cnd2
,cnd3
). - The script performs mathematical operations on these integers and writes the results to
output.txt
.
Specifically:
v1
is calculated as $cnd1^3+cnd3^2+cnd2.$v2
is calculated as $cnd2^3+cnd1^2+cnd3.$v3
is calculated as $cnd3^3+cnd2^2+cnd1.$v4
is the sum of $cnd1+cnd2+cnd3.$
Decoding the Flag
To decrypt output.txt
and retrieve the flag, I needed to reverse these mathematical operations defined in source.py. Using v4
, I know the sum of cnd1
, cnd2
, and cnd3
, so I can treat this as a system of equations and solve for cnd1
, cnd2
, and cnd3
(kind of high school math, lol).
System of Equations:
- $cnd1^3+cnd3^2+cnd2=v1$
- $cnd2^3+cnd1^2+cnd3=v2$
- $cnd3^3+cnd2^2+cnd1=v3$
- $cnd1+cnd2+cnd3=v4$
From Equation 4: $cnd3=v4−cnd1−cnd2$
Substituting into the First Equation:
Substituting the expression for cnd3
into the first equation gives: $cnd1^3+(v4−cnd1−cnd2)^2+cnd2=v1$
Expanding this results in a more complex equation. The same substitution process is applied to the other equations as well.
Implementing the Decryption
I then wrote a script to decrypt the text based on the derived equations.
from sympy import symbols, Eq, solve from Crypto.Util.number import long_to_bytes
v1 = 4196604293528562019178729176959696479940189487937638820300425092623669070870963842968690664766177268414970591786532318240478088400508536
v2 = 11553755018372917030893247277947844502733193007054515695939193023629350385471097895533448484666684220755712537476486600303519342608532236
v3 = 14943875659428467087081841480998474044007665197104764079769879270204055794811591927815227928936527971132575961879124968229204795457570030
v4 = 6336816260107995932250378492551290960420748628
eq1 = Eq(cnd1**3 + cnd3**2 + cnd2, v1)
eq2 = Eq(cnd2**3 + cnd1**2 + cnd3, v2)
eq3 = Eq(cnd3**3 + cnd2**2 + cnd1, v3)
eq4 = Eq(cnd1 + cnd2 + cnd3, v4)
solutions = solve((eq1, eq2, eq3, eq4), (cnd1, cnd2, cnd3))
cnd1_value = sol[0]
cnd2_value = sol[1]
cnd3_value = sol[2]
flag_part1 = long_to_bytes(cnd1_value)
flag_part2 = long_to_bytes(cnd2_value)
flag_part3 = long_to_bytes(cnd3_value)
flag = flag_part1 + flag_part2 + flag_part3
print(f"Decrypted flag: {flag.decode('utf-8', errors='ignore')}")`
Explanation of the Script
-
Libraries Used:
sympy
is used for symbolic mathematics to solve the equations.Crypto.Util.number
provides utilities for converting long integers to byte strings.
-
Equations Setup: The equations derived from the initial problem are set up using
Eq()
. -
Solving the Equations: The
solve()
function finds the values ofcnd1
,cnd2
, andcnd3
. -
Reconstructing the Flag: The flag parts are converted back to bytes and concatenated to reveal the full flag.
After executing the script, I successfully recovered the flag.