Impossible [CRYPTO]
Binary checker and inequalities with IF conditional statement.
📁 Challenge Description
50 points, 503 solves
Is this challenge impossible?
#!/usr/local/bin/python
def fake_psi(a, b):
return [i for i in a if i in b]
def zero_encoding(x, n):
ret = []
for i in range(n):
if (x & 1) == 0:
ret.append(x | 1)
x >>= 1
return ret
def one_encoding(x, n):
ret = []
for i in range(n):
if x & 1:
ret.append(x)
x >>= 1
return ret
print("Supply positive x and y such that x < y and x > y.")
x = int(input("x: "))
y = int(input("y: "))
if len(fake_psi(one_encoding(x, 64), zero_encoding(y, 64))) == 0 and x > y and x > 0 and y > 0:
print(open("flag.txt").read())
👀 Analysis
The conditions to read the flag are listed below:
x
must be larger thany
.x
must be positive.y
must be positive.- The length of list generated from
fake_psi(a, b)
function must be empty.
One way to solve this question is create own impossible.py
and flag.txt
in localhost for testing, and print the output x
and y
out to verify whether it satisfies the condition len(fake_psi(one_encoding(x, 64), zero_encoding(y, 64))) == 0
.
Assume we have satisfied the first 3 conditions at above, if we insert x = 2
and y = 1
, the output will be:
ret = [3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
ret = [1]
From the output given, the final list from fake_psi()
function will not be empty and it will return [1]
as 1
is the common element in both lists.
If we insert a large number x = 111111111111111111111
and y = 1
, the output will be:
ret = [13888888888888888889, 6944444444444444445, 3472222222222222223, 217013888888888889, 108506944444444445, 54253472222222223, 3390842013888889, 1695421006944445, 847710503472223, 26490953233507, 6622738308377, 3311369154189, 1655684577095, 206960572137, 103480286069, 51740143035, 12935035759, 808439735, 101054967, 12631871, 197373, 98687, 771, 193, 97, 49, 25, 13]
ret = [1]
From the output given, there is no common element in both lists. Hence, len(fake_psi(one_encoding(x, 64), zero_encoding(y, 64)))
will result in zero element. We have our solution.
It is worth noting that the last element in list
x
must be larger than the last element in listy
to get the flag which is13 > 1
in the example above. Hence,x
must be large enough to avoid bits shifting to1
.
🚩 Solution
The impossible.py was released after I had submitted the flag. Hence, this video demonstrates some possible combinations to access the flag.
#!/usr/bin/env python3
from pwn import *
context.log_level = 'critical'
x = 111111111111111111111
y = 1
io = remote('challs.actf.co', 32200)
io.recvuntil(b':')
io.sendline(str(x)).encode()
io.recvuntil(b':')
io.sendline(str(y)).encode()
print(io.recvline().decode())
io.close()
FLAG: actf{se3ms_pretty_p0ssible_t0_m3_7623fb7e33577b8a}