1. 程式人生 > 其它 >攻防世界 Crypto高手進階區 3分題 streamgame1

攻防世界 Crypto高手進階區 3分題 streamgame1

技術標籤:ctfctf攻防世界crypto

前言

繼續ctf的旅程
攻防世界Crypto高手進階區的3分題
本篇是streamgame1的writeup

發現攻防世界的題目分數是動態的
就僅以做題時的分數為準了

解題過程

得到一個key檔案
和一段python

from flag import flag
assert flag.startswith("flag{")
# 作用:判斷字串是否以指定字元或子字串開頭flag{
assert flag.endswith("}")
# 作用:判斷字串是否以指定字元或子字串結尾},flag{},6個位元組
assert len
(flag)==25 # flag的長度為25位元組,25-6=19個位元組 #3<<2可以這麼算,bin(3)=0b11向左移動2位變成1100,0b1100=12(十進位制) def lfsr(R,mask): output = (R << 1) & 0xffffff #將R向左移動1位,bin(0xffffff)='0b111111111111111111111111'=0xffffff的二進位制補碼 i=(R&mask)&0xffffff #按位與運算子&:參與運算的兩個值,如果兩個相應位都為1,則該位的結果為1
,否則為0 lastbit=0 while i!=0: lastbit^=(i&1) #按位異或運算子:當兩對應的二進位相異時,結果為1 i=i>>1 output^=lastbit return (output,lastbit) R=int(flag[5:-1],2) mask = 0b1010011000100011100 f=open("key","ab") #以二進位制追加模式開啟 for i in range(12): tmp=0 for j in range
(8): (R,out)=lfsr(R,mask) tmp=(tmp << 1)^out #按位異或運算子:當兩對應的二進位相異時,結果為1 f.write(chr(tmp)) #chr() 用一個範圍在 range(256)內的(就是0255)整數作引數,返回一個對應的字元。 f.close()

也就是說

  • flag是19位的二進位制
  • 給了個加密函式
  • 對mask和R作用加密函式並生成新的R同時得到1bit資料,然後每8bit資料轉化成一個對應的ascii再寫入key檔案中

key扔進winhex
在這裡插入圖片描述
那就爆破就完事了


def check(list1, list2):
    for i in range(12):
        if list1[i] != list2[i]:
            return False
    return True
 
 
def lfsr(R ,mask):
    output = (R << 1) & 0xffffff    #將R向左移動1位,bin(0xffffff)='0b111111111111111111111111'=0xffffff的二進位制補碼
    i=(R&mask)&0xffffff             #按位與運算子&:參與運算的兩個值,如果兩個相應位都為1,則該位的結果為1,否則為0
    lastbit=0
    while i!=0:
        lastbit^=(i&1)    #按位異或運算子:當兩對應的二進位相異時,結果為1
        i=i>>1
    output^=lastbit
    return (output,lastbit)
 
 
if __name__ == '__main__':
    f = open('key','rb')
    content = f.read()
    s_list = []
    for c in content:
        s_list.append(c)
 
    print(s_list)
 
    mask = 0b1010011000100011100
 
    for i in range(1 << 19):
        print(i)
        tmp_list = []
        R = i
        for j in range(12):
            tmp = 0
            for k in range(8):
                (R, out) = lfsr(R, mask)
                tmp = (tmp << 1) ^ out  # 按位異或運算子:當兩對應的二進位相異時,結果為1
            tmp_list.append(tmp)
 
        if (check(s_list, tmp_list)):
            print(bin(i))

得到flag:flag{1110101100001101011}

結語

簡單爆破