Skip to content

Instantly share code, notes, and snippets.

@wanqizhu
Last active November 13, 2015 17:46
Show Gist options
  • Save wanqizhu/419dc3f279fd1e521f97 to your computer and use it in GitHub Desktop.
Save wanqizhu/419dc3f279fd1e521f97 to your computer and use it in GitHub Desktop.

Obfuscated

The code looks scary, but in the end it just comes down to perseverance and carefully tracking your work. Try to figure out what each line does and look up unfamiliar functions. IDLE was very helpful to see what all the list indicing and map functions do. I've attached my understanding of the code, commented, below.

Once you figure out what each line does, the only catch is to keep track of the popped indices in relation with their original position in s. The flag just need to be any string passing the check, so any string of the form

Wh4/___/___0_0_0_0_M3//&&

where '/' can be ANY character, the pair && must have an XOR of 30, and among the 10 '_' we fill in 'RTHOOOO' and 'tae' (remember h already appeared and wasn't popped) in some mix so that all the uppercase letters read 'RTHOOOO' and lowercase ones read 'tae'.

An example would be WH4RTHOOO0O0t0a0eM3~~DZ

from string import ascii_uppercase as v, ascii_lowercase as k
def check_flag(s):
""" has to be a string of length 25 """
if len(s) != 0x19:
return False
s = list(s)
"""
The code basically does:
for r in [20, 17, 15, 13, 11, 2]: s.pop(r)
store the results in x
reverse x
interpret x as an int
` ` is the same as repr(), and then if we take [2::5], it does nothing (try it with IDLE)
so we just check if int(''.join(s[r] for r in [2, 11, 13, 15, 17, 20])) == 400003
We conclude that s[2] = 4, s[11], s[13], s[15], s[17] = 0, s[20] = 3
Remember that once an element is popped, the list index is different,
e.g. if you pop 10, then 12, you actually popped s[10] and s[13] in the original s,
but since we are starting from the back this doesn't play a role here.
It's important to remember though for pop requests below.
"""
if int(`[s.pop(r) for r in ([2] + [i for i in range(11, 18, 2)] + [20])[::-1]][::-1]`[2::5]) != 0x61a83: #400003
return False
""" make a list of a set of [s.pop(7), s.pop(3)]
its length, which will always be 1, must equal the first occurance of h in s
so s[1] = h
"""
if len(list(set([s.pop(r) for r in map(lambda p: int(p, 2), [("1"*5)[:2], ("1"*5)[2:]])[::-1]]))) != s.index("h"):
return False
y, z = [], []
""" repr gives "None"
pop the last 4 items of s at this point, 1st/3rd goes to y, 2nd/4th goes to z
then we are calculating len(list(set(['NoneNone', 'NoneNone']))) - 1
which is 0
"""
u = len(list(set([repr(y.append(s.pop(-1))) + repr(z.append(s.pop(-1))) for w in range(2)]))) - 1
""" Assuming s has enough characters for pop (which it will since len=25), y and z both has size 2, so the following does nothing (checks 0 == 0) """
if u != len(list(set(y))) ^ len(list(set(z))):
return False
""" XOR the first elements of y, z, and then 30
This equals 0 iff (y ^ z) == 30
only considering letters, the options are:
(D Z), (F X), (G Y), (H V), (I W), (J T), (K U), (L R), (M S), (N P), (O Q), (P N), (Q O), (R L), (S M), (T J), (U K), (V H), (W I), (X F), (Y G), (Z D), (d z), (f x), (g y), (h v), (i w), (j t), (k u), (l r), (m s), (n p), (o q), (p n), (q o), (r l), (s m), (t j), (u k), (v h), (w i), (x f), (y g), (z d)
(turns out it doesn't really matter)
"""
if (ord(y[u]) ^ ord(z[u])) ^ 0x1e != 0:
return False
""" pop the last item of s. We must have the index_of_that_letter_in_UPPERCASE XOR len(s) == 30
At this point, s has length 25 - 12 - 1 = 12
so the letter popped has to be M
so s[19] = M (remember how pop works)
"""
if v.index(s.pop()) ^ len(s) ^ 0x1e != 0:
return False
""" a contains all the UPPERCASE letters in s, i all the lowercase ones """
a, i = filter(lambda c: c in v, s), filter(lambda c: c in k, s)
""" 1st map gives [87, 82, 84, 72], to which we append [79, 79, 79, 79]
so the remaining capitalized letters of s must be WRTHOOOO
"""
if map(lambda a: a + 0x50, [7, 2, 4, -8]) + [0x4f] * 4 != map(ord, a):
return False
""" switch the 2nd and 3rd elmts
so we must have i = ['h', 't', 'a', 'e']
so the remaining lowercase letters of s must be htae
"""
i[1:3] = i[2:0:-1]
if i != list("hate"):
return False
return True
""" so we have
s = "Wh4/___/___0_0_0_0_M3//&&"
where '/' can be ANY character, the pair && must have an XOR of 30,
and among the 10 '_' we fill in 'RTHOOOO' and 'tae' (remember h already appeared and wasn't popped) in some mix
so that all the uppercase letters read 'RTHOOOO' and lowercase ones read 'tae'
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment