Version
By |
Version |
Comment |
noraj |
1.0 |
Creation |
CTF
Description
I used this program to encrypt a flag. The output was:
n1s4_t1An(f1ctdb@mpl_h3)m3lp3y__Eas
file: λ.py
Solution
TL;DR : that solution is just a trick not a smart de-obfuscation.
- Here is the code of the
λ.py
:
1
| print (lambda j,m:(lambda f,t:t if len(t) <= 1 else j([f(f,x)for x in m(j,m(reversed,(lambda s:zip(*[iter(s)]*(len(s)/2)))(t+"\x01"*(len(t)%2))))]))(lambda f,t:t if len(t) <= 1 else j([f(f,x)for x in m(j,m(reversed,(lambda s: zip(*[iter(s)]*(len(s)/2)))(t+"\x01"*(len(t)%2))))]),raw_input("Plaintext:")))(''.join,map).replace("\x01","")
|
- It's clear that the code is obfuscated, but even beautified it's still a mess.
- So as I don't want my brain to blow trying to de-obfuscate this, I got around.
- I realized that, with enought iteration, we gan get back the original string. So I modified the code to "brute-force" the good combination:
1 2 3 4 5 6 7 8 9 10 11
| mixed_flag = "n1s4_t1An(f1ctdb@mpl_h3)m3lp3y__Eas"
for i in range(100): old_mixed_flag = mixed_flag mixed_flag = (lambda j, m: (lambda f, t: t if len(t) <= 1 else j([f(f, x) for x in m(j, m(reversed, (lambda s: zip( * [iter(s)] * (len(s) / 2)))(t + "\x01" * (len(t) % 2))))]))(lambda f, t: t if len(t) <= 1 else j([f(f, x) for x in m(j, m(reversed, (lambda s: zip( * [iter(s)] * (len(s) / 2)))(t + "\x01" * (len(t) % 2))))]), old_mixed_flag))(''.join, map).replace("\x01", "") print(str(i) + " " + mixed_flag)
|
- Here the non-filtered output, that's quite long:
1 2 3 4 5 6 7 8 9
| ┌─[root@parrot]─[~/CTF/CTFx/2016/50-lambda_λ-cryptography] └──╼ #python lambda_λ.py 0 c1t(fm@db4s_n1nAt1_y_p3sEah_3pll3)m 1 n_14s1tnA(tfc1bdm@lpl_3m3)p_3_yhasE 2 cf1(t@mbd41sn_An1ty_h_3Eas_l3lpp)m3 [...] 97 n_14s1tnA(tfc1bdm@lph_3m3)_l3_ypasE 98 cf1(t@mbd41sn_An1ty_pl3Eas_h3lp_)m3 99 ns_41t1An(1tcfdb@mpl_h33)mlp3y__sEa
|
- Now let's see what begins with
ctf(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ┌─[root@parrot]─[~/CTF/CTFx/2016/50-lambda_λ-cryptography] └──╼ #python lambda_λ.py | grep 'ctf(' 4 ctf(1m@db4_1nsnAt1_y_h3asElp3pl_m3) 10 ctf(1@mbd4_1nsAn1ty__p3asEh_3lplm3) 16 ctf(1m@db4_1nsnAt1_yl_3asEp_3plhm3) 22 ctf(1@mbd4_1nsAn1ty_h_3asE_l3lppm3) 28 ctf(1m@db4_1nsnAt1_ypl3asE_h3pl_m3) 34 ctf(1@mbd4_1nsAn1ty__h3asElp3lp_m3) 40 ctf(1m@db4_1nsnAt1_y_p3asEh_3pllm3) 46 ctf(1@mbd4_1nsAn1ty_l_3asEp_3lphm3) 52 ctf(1m@db4_1nsnAt1_yh_3asE_l3plpm3) 58 ctf(1@mbd4_1nsAn1ty_pl3asE_h3lp_m3) 64 ctf(1m@db4_1nsnAt1_y_h3asElp3pl_m3) 70 ctf(1@mbd4_1nsAn1ty__p3asEh_3lplm3) 76 ctf(1m@db4_1nsnAt1_yl_3asEp_3plhm3) 82 ctf(1@mbd4_1nsAn1ty_h_3asE_l3lppm3) 88 ctf(1m@db4_1nsnAt1_ypl3asE_h3pl_m3) 94 ctf(1@mbd4_1nsAn1ty__h3asElp3lp_m3)
|
- That begins to make sense, more filtering:
1 2 3 4 5 6 7 8 9 10
| ┌─[root@parrot]─[~/CTF/CTFx/2016/50-lambda_λ-cryptography] └──╼ #python lambda_λ.py | grep 'ctf(1@mbd4_1nsAn1ty_' 10 ctf(1@mbd4_1nsAn1ty__p3asEh_3lplm3) 22 ctf(1@mbd4_1nsAn1ty_h_3asE_l3lppm3) 34 ctf(1@mbd4_1nsAn1ty__h3asElp3lp_m3) 46 ctf(1@mbd4_1nsAn1ty_l_3asEp_3lphm3) 58 ctf(1@mbd4_1nsAn1ty_pl3asE_h3lp_m3) 70 ctf(1@mbd4_1nsAn1ty__p3asEh_3lplm3) 82 ctf(1@mbd4_1nsAn1ty_h_3asE_l3lppm3) 94 ctf(1@mbd4_1nsAn1ty__h3asElp3lp_m3)
|
- Not so hard:
58 ctf(1@mbd4_1nsAn1ty_pl3asE_h3lp_m3)
.