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:
xmust be larger thany.xmust be positive.ymust 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
xmust be larger than the last element in listyto get the flag which is13 > 1in the example above. Hence,xmust 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}