ReStr0
Venom战队队员 Chamd5安全团队
ReStr0-Blog

DASCTF×CBCTF july CRYPTO2_SEDSED题WriteUP

一共是两轮des

L0 R0为明文
L1=R0 R1=F(R0,K0)^L0
L2=R1 R2=F(R1,K1)^L1

L2R2是密文然后testtest已知明文

L1已知,可以算出来F(R1,K1)

然后R1=L2=F(R0,K0)^L0

都是已知,也就是知道了F(A,B)=C的A和C,求B也就是key

根据F函数直接求逆,S盒求逆无唯一解,就保存所有可行解

这样子可以解出来K0和K1的可能值

然后用z3加约束,约束是K0 K1的每6位都满足S盒求逆给出的可能输入

同时密钥轮调时候的L和R设成未知数,K0,K1是输出

用z3直接解,解出来4个可能的key

依次尝试,,找到flag

Solve.py

from My_box import *


def permutation(plain_text):
    p = ""
    for x in IP:
        p += plain_text[x - 1]
    return p


def inv_permutation(text):
    final = ""
    for x in Inv_IP:
        final += text[x - 1]
    return final


def dec_fin(p: str):  # ->left,right
    r = permutation(bin(int("0x" + p, 16))[2:].rjust(64, '0'))
    return r[:32], r[32:]


def enc_1(plain_text: str):
    plain_textb = ""
    for i in range(16):
        plain_textb += '{0:04b}'.format(int(plain_text[i], 16))
    plain_textp = permutation(plain_textb)
    left, right = plain_textp[:32], plain_textp[32:]
    return left, right





def per_func(s_output):
    s_final = ""
    for x in P:
        s_final += s_output[x - 1]
    return s_final


def Inv_per_func(s_output):
    s_final = ""
    for x in Inv_P:
        s_final += s_output[x - 1]
    return s_final


def Inv_sbox(x):
    pass

def expand(text):
    temp = ""
    for x in E:
        temp += text[x-1]
    return temp
def inv_expand(text):
    pass
def sbox(s_input):
    s_out = ""
    for i in range(8):
        row = int(s_input[6*i]+s_input[6*i+5],2)
        column = int(s_input[6*i+1:6*i+5],2)
        s_out += '{0:04b}'.format(S[i][row][column])
    return s_out
#in s 010011 110111 101011 001011 101010 101111 111110 100011
def antiF(res, src):  # res,src->key
    s1=expand(src)
    r1=Inv_per_func(res) #48s1->sbox->r1=32bit
    print("after s",r1)
    key=[]
    for i in range(8):
        tres=[]
        s_out=int(r1[4*i:4*i+4],2)
        for j in range(4):
            for k in range(16):
                if S[i][j][k]==s_out:
                    tmp1=bin(j)[2:].rjust(2,'0')
                    tres.append(tmp1[0]+bin(k)[2:].rjust(4,'0')+tmp1[1])
        key.append(tres)
    #print(key)
    #step2 xor s1
    for i in range(8):
        for j in range(4):
            key[i][j]="{0:06b}".format(int(key[i][j],2)^int(s1[i*6:i*6+6],2))
    return key
    #inv sbox(r1)=s1^key

def invF(res,key): #res,key->src
    r1=Inv_per_func(res)
    #inv sbox(r1) ^ key=src
# 10110101011011001001111101010000 11111001111011000100010000010011
# left=func(func(right,k[0]),k[1])^right,right=func(right,k[0])^left

# 71930fc0736ac560
# 1111100100010011010001000101011101001010101100010010010000110110
known = "testtest".encode().hex()
kl, kr = enc_1(known)
dl, dr = dec_fin("77a35598c47aeea6")
#f_r_k0 = '{0:032b}'.format(int(dr, 2) ^ int(kl, 2))  # f(r,k0)
#f_frk0_k1 = '{0:032b}'.format(int(dl, 2) ^ int(kr, 2))  # f(f(r,k0)^kl,k1)
#print(f_r_k0, f_frk0_k1)
#print(antiF(f_r_k0,kr))
#print(antiF(f_frk0_k1,dr))
print(dl,dr)
k0="0"*48
k1="0"*48

#or=F(r,0)^l
#ol=F(F(r,0)^l,1)^r

#func(or,k1)^ol=r
#func(r,k0)^or=l

'''
(53098363597040923252233206950, 53098363488233956254962023557, 53098363596608577688005639334, 53098363488666301819189591173)
real 11111111110111011011101101100110 00000000111111110000000001000100
ence 01110101001011011101010100000111 11011010111000110110100011100011

'''

z3s.py

from My_box import *
import claripy

# 010011 110110 110100 110101 001010 101111 110110 101011
# 010011 111110 010100101101001011100111110110101011
k0 = [['010100', '010011', '101010', '111101'], ['010001', '011010', '111001', '111110'], ['000111', '000100', '101111', '100110'], ['100010', '101111', '000000', '001101'], ['110110', '110101', '010000', '010011'], ['001010', '000111', '101000', '100101'], ['011010', '011111', '100000', '110111'], ['001010', '010111', '100110', '101001']]
k1 = [['111111', '110110', '010011', '000100'], ['111001', '110100', '001111', '011100'], ['011000', '011011', '111010', '110111'], ['000010', '011011', '110000', '111001'], ['110011', '110110', '011111', '011010'], ['011111', '001110', '111011', '101100'], ['011010', '001101', '110010', '100101'], ['000101', '011000', '101001', '100110']]

# k0=[['010100', '010011', '101010', '111101'], ['010000', '011011', '111000', '111111'], ['011000', '011011', '110000', '111001'], ['011100', '010001', '111110', '110011'], ['010110', '010101', '110000', '110011'], ['001010', '000111', '101000', '100101'], ['010010', '010111', '101000', '111111'], ['000010', '011111', '101110', '100001']]
# k1=[['000100', '001101', '101000', '111111'], ['001100', '000001', '111010', '101001'], ['000100', '000111', '100110', '101011'], ['000100', '011101', '110110', '111111'], ['011110', '011011', '110010', '110111'], ['001110', '011111', '101010', '111101'], ['000110', '010001', '101110', '111001'], ['000010', '011111', '101110', '100001']]
Ls = [claripy.BVS("a" + str(i),1) for i in range(28)]
Rs = [claripy.BVS("b" + str(i),1) for i in range(28)]


def gen_48bit(key: list):
    key_48 = []
    for x in KEY_P2:
        key_48.append(key[x - 1])
    return key_48


def circular_shift(key: list, n):
    temp = key[n:] + key[:n]
    return temp


# pp=[claripy.BoolS("p_%d"%i) for i in range(48)]
rk1 = gen_48bit(Ls + Rs)
L1 = circular_shift(Ls, 1)
R1 = circular_shift(Rs, 1)
rk2 = gen_48bit(L1 + R1)
# print(rk2)
s = claripy.Solver()


def apply_hint(key, hint):
    allc = []
    for i in range(8):
        gpp = []
        for p in range(4):
            gp = []
            for j in range(6):
                gp.append(key[i * 6 + j] == (0 if hint[i][p][j] == '0' else 1))
            gpp.append(claripy.And(*gp))
        allc.append(claripy.Or(*gpp))
    s.add(claripy.And(*allc))


apply_hint(rk1, k0)
apply_hint(rk2, k1)
fk=claripy.Concat(*rk1+rk2)
print(fk)
print(s.check_satisfiability())

print(s.eval(fk,16))

Decode.py

fuck=bin(53098363596608577688005639334)[2:].rjust(96,'0')
def dec_fin(p: str):  # ->left,right
    r = permutation(bin(int("0x" + p, 16))[2:].rjust(64, '0'))
    return r[:32], r[32:]
pay=""

def proc(enced):
    global pay
    dl,dr=dec_fin(enced)
    k0,k1=fuck[:48],fuck[48:]#"101010111001000111101111110110100101110111101001","110110111001011011011011011111011111110010100110"
    decr=bin(int(func(dr,k1),2)^int(dl,2))[2:].rjust(32,'0')
    decl=bin(int(func(decr,k0),2)^int(dr,2))[2:].rjust(32,'0')
    out=inv_permutation(decl+decr)
    for i in range(len(out)//4):
        pay+=hex(int(out[i*4:i*4+4],2))[2:]
fuckg="86721c7c1ebe2d0af8aa8e073073931b4a5ae6dcf03c784e3c70b5f8ce71cf9eb87f9b836eea0118"
for i in range(len(fuckg)//16):
    proc(fuckg[i*16:i*16+16])
print(bytes.fromhex(pay))

没有标签
首页      CRYPTO      DASCTF×CBCTF july CRYPTO2_SEDSED题WriteUP

发表评论

textsms
account_circle
email

ReStr0-Blog

DASCTF×CBCTF july CRYPTO2_SEDSED题WriteUP
一共是两轮des L0 R0为明文L1=R0 R1=F(R0,K0)^L0L2=R1 R2=F(R1,K1)^L1 L2R2是密文然后testtest已知明文 L1已知,可以算出来F(R1,K1) 然后R1=L2=F(R0,K0)^L0 都是已知,也…
扫描二维码继续阅读
2021-08-08