1. 程式人生 > 其它 >CTFlearn-Time to Eat

CTFlearn-Time to Eat

直接給了原始碼, 但是是經過手動混淆的…

# I wrote and debugged this code with all the convoluted "EAT" variable names.
# Was it confusing? Yes. Was debugging hard? Yes.
# Did I spend more time than I should have on this problem? Yes

EAT = int
eAT = len
EaT = print
ATE = str
EATEATEATEATEATEAT = ATE.isdigit

def
Eating(eat): return ATE(EAT(eat)*EATEATEAT) def EAt(eat, eats): print(eat, eats) eat1 = 0 eat2 = 0 eateat = 0 eAt = "" while eat1 < eAT(eat) and eat2 < eAT(eats): if eateat%EATEATEAT == EATEATEATEATEAT//EATEATEATEAT: eAt += eats[eat2] eat2 +=
1 else: eAt += eat[eat1] eat1 += 1 eateat += 1 return eAt def aten(eat): return eat[::EATEATEAT-EATEATEATEAT] def eaT(eat): return Eating(eat[:EATEATEAT]) + aten(eat) def aTE(eat): return eat#*eAT(eat) def Ate(eat): return "Eat"
+ ATE(eAT(eat)) + eat[:EATEATEAT] def Eat(eat): if eAT(eat) == 9: if EATEATEATEATEATEAT(eat[:EATEATEAT]) and\ EATEATEATEATEATEAT(eat[eAT(eat)-EATEATEAT+1:]): eateat = EAt(eaT(eat), Ate(aTE(aten(eat)))) if eateat == "E10a23t9090t9ae0140": flag = "eaten_" + eat EaT("absolutely EATEN!!! CTFlearn{",flag,"}") else: EaT("thats not the answer. you formatted it fine tho, here's what you got\n>>", eateat) else: EaT("thats not the answer. bad format :(\ \n(hint: 123abc456 is an example of good format)") else: EaT("thats not the answer. bad length :(") EaT("what's the answer") eat = input() EATEATEAT = eAT(eat)//3 EATEATEATEAT = EATEATEAT+1 EATEATEATEATEAT = EATEATEAT-1 Eat(eat)

那麼我們也手動恢復混淆程式碼
ctrl + h replace 一些eat和int, 得到

# I wrote and debugged this code with all the convoluted "int" variable names.
# Was it confusing? Yes. Was debugging hard? Yes.
# Did I spend more time than I should have on this problem? Yes

# int = int
# len = len
# print = print
# str = str
# str.isdigit = str.isdigit

def F1(eat):
    return str(int(eat)*v1)

def F2(eat, eats):
    print(eat, eats)
    eat1 = 0
    eat2 = 0
    eateat = 0
    eAt = ""
    while eat1 < len(eat) and eat2 < len(eats):
        if eateat%v1 == v3//v2:
            eAt += eats[eat2]
            eat2 += 1
        else:
            eAt += eat[eat1]
            eat1 += 1
        eateat += 1
    return eAt

def F3(eat):
    return eat[::v1-v2]

def F4(eat):
    return F1(eat[:v1]) + F3(eat)

def F5(eat):
    return eat#*len(eat)

def F6(eat):
    return "Eat" + str(len(eat)) + eat[:v1]

def Eat(eat):
    if len(eat) == 9:
        if str.isdigit(eat[:v1]) and\
            str.isdigit(eat[len(eat)-v1+1:]):
                eateat = F2(F4(eat), F6(F5(F3(eat))))
                if eateat == "E10a23t9090t9ae0140":
                    flag = "eaten_" + eat
                    print("absolutely intEN!!! CTFlearn{",flag,"}")
                else:
                    print("thats not the answer. you formatted it fine tho, here's what you got\n>>", eateat)
        else:
            print("thats not the answer. bad format :(\
            \n(hint: 123abc456 is an example of good format)")
    else:
        print("thats not the answer. bad length :(")

print("what's the answer")
eat = input()
v1 = len(eat)//3
v2 = v1+1
v3 = v1-1
Eat(eat)

有了一定可讀性後, 可以開始分析, 得知

  • 輸入的字串應該是9位長
  • 前3位和後3位應該是數字

關鍵程式碼

eateat = F2(F4(eat), F6(F5(F3(eat))))
if eateat == "E10a23t9090t9ae0140":
	flag = "eaten_" + eat
   	print("absolutely intEN!!! CTFlearn{",flag,"}")

輸入的字串eat滿足使得eateat == 'E10a23t9090t9ae0140’後, eat即為flag的後半段

進一步手改變數, 理清程式碼

def F1(eat):
    return str(int(eat)*3)

def F2(eat, eats):
    print(eat, eats)
    t1 = 0
    t2 = 0
    Td = 0
    eat_str = ""
    while t1 < len(eat) and t2 < len(eats):
        if Td%3 == 2//4:
            eat_str += eats[t2]
            t2 += 1
        else:
            eat_str += eat[t1]
            t1 += 1
        Td += 1
    return eat_str

def F3(eat):
    return eat[::3-4]

def F4(eat):
    return F1(eat[:3]) + F3(eat)

def F5(eat):
    return eat#*len(eat)

def F6(eat):
    return "Eat" + str(len(eat)) + eat[:3]

def Eat(eat):
    if len(eat) == 9:
        if str.isdigit(eat[:3]) and\
            str.isdigit(eat[len(eat)-3+1:]):
                Td = F2(F4(eat), F6(F5(F3(eat))))
                if Td == "E10a23t9090t9ae0140":
                    flag = "eaten_" + eat
                    print("absolutely intEN!!! CTFlearn{",flag,"}")
                else:
                    print("thats not the answer. you formatted it fine tho, here's what you got\n>>", Td)
        else:
            print("thats not the answer. bad format :(\
            \n(hint: 123abc456 is an example of good format)")
    else:
        print("thats not the answer. bad length :(")

print("what's the answer")
eat = input()
# 3 = len(eat)//3 # 3
# 4 = 3+1 # 4
# 2 = 3-1 # 2
Eat(eat)

逐一分析函式功能

def F2(eat, eats):
    print(eat, eats)
    t1 = 0
    t2 = 0
    Td = 0
    eat_str = ""
    while t1 < len(eat) and t2 < len(eats):
        if Td%3 == 2//4:
            eat_str += eats[t2]
            t2 += 1
        else:
            eat_str += eat[t1]
            t1 += 1
        Td += 1
    return eat_str

按模3迴圈分別將eat和eats字串的字元新增到eat_str, 然後返回


def F1(eat):
    return str(int(eat)*3)

將字串eat整數化後*3再轉字串返回


def F3(eat):
    return eat[::3-4]

翻轉字串

def F4(eat):
    return F1(eat[:3]) + F3(eat)

前3位呼叫F1函式, 拼接翻轉後的字串返回


def F5(eat):
    return eat#*len(eat)

def F6(eat):
    return "Eat" + str(len(eat)) + eat[:3]

F5 返回本身, F6返回"Eat" + 長度 + 後三位

總之就是非常繁瑣!

寫出解密指令碼

# re for F2
Td = "E10a23t9090t9ae0140"
print(len(Td))
s1, s2 = '', ''
for i in range(len(Td)):
    if i % 3 == 0: s2 += Td[i]
    else: s1 += Td[i]
print(s1, ' ', s2)
print(len(s1), ' ', len(s2))
# 1023900tae14   Eat9900
# 12 7

其實按照s1的結果就已經能分析出eat字串
為341eat009, 之所以末尾缺少3, 是因為F2函式存在資訊丟失, 有部分字元沒加入返回的字串中
驗證, 執行源程式即可
在這裡插入圖片描述

CTFlearn{ eaten_341eat009 }

總結

  • 這題並不需要完全分析出所有函式的功能, 只需要F2, F4, F1, F3即可
  • 還有一種解法, 已知前3位,後3位為數字, 中間3位為字母, 爆破解也行