zoukankan      html  css  js  c++  java
  • JarvisOJ-[xman2019]xfz

    下载附件后,得到了一个py脚本与一个.log的文本,如下:

    fez.py:

     1 import os
     2 def xor(a,b):
     3     assert len(a)==len(b)
     4     c=""
     5     for i in range(len(a)):
     6         c+=chr(ord(a[i])^ord(b[i]))
     7     return c
     8 def round(M,K):
     9     L=M[0:27]
    10     R=M[27:54]
    11     new_l=R
    12     new_r=xor(xor(R,L),K)
    13     return new_l+new_r
    14 def fez(m,K):
    15     for i in K:
    16         m=round(m,i)
    17     return m
    18 
    19 K=[]
    20 for i in range(7):
    21     K.append(os.urandom(27))
    22 m=open("flag","rb").read()
    23 assert len(m)<54
    24 m+=os.urandom(54-len(m))
    25 
    26 test=os.urandom(54)
    27 print(test.encode("hex"))
    28 print(fez(test,K).encode("hex"))
    29 print(fez(m,K).encode("hex"))

    fez.log:

    50543fc0bca1bb4f21300f0074990f846a8009febded0b2198324c1b31d2e2563c908dcabbc461f194e70527e03a807e9a478f9a56f7
    66bbd551d9847c1a10755987b43f8b214ee9c6ec2949eef01321b0bc42cffce6bdbd604924e5cbd99b7c56cf461561186921087fa1e9
    44fc6f82bdd0dff9aca3e0e82cbb9d6683516524c245494b89c272a83d2b88452ec0bfa0a73ffb42e304fe3748896111b9bdf4171903

    简单的观察可以知道要通过已给出的三个输出,计算出原本的m(也就是flag)。这里要注意的是异或运算本身的特殊性-可逆,因此通过后面两个式子,fez(test,K),fez(m,K)计算出test与m原始数的[0:27]与[27:54],通过两者之间相互异或,两两抵消,再与给出的test的值异或,即可得到最初的m。这其中最重要的就是抵消掉k的值。

    推算结果如下:

    已知 entest enm test
    设entest的[0:27]为L,[27:54]为R
    设enm的[0:27]为ML,[27:54]为MR
    设k[]的每个值为k0,k1...k6
    则根据算法可知:(通过L和R来推)
    原始的test:(逆推)
                     L                                          R     
    ①     R^k6^L                                                L
    ②     L^k5^(R^k6^L)                                      (R^k6^L)
    ③    (R^k6^L)^k4^( L^k5^(R^k6^L) )                       L^k5^(R^k6^L) 
    简     L^k4^k5                                            R^k5^k6
    ④     L^R^k3^k4^k6                                       L^k4^k5
    ⑤     R^k2^k3^k5^k6                                      L^R^k3^k4^k6
    ⑥     L^k1^k2^k4^k5                                      R^k2^k3^k5^k6
    ⑦     L^R^k0^k1^k3^k4^k6                                 L^k1^k2^k4^k5
    原始的enm与test逆推过程一样:
    可得:
                     L                                           R     
           ML^MR^k0^k1^k3^k4^k6                            ML^k1^k2^k4^k5
    因此,根据异或运算的可逆性,可得:
    test[0:27]^m[0:27]==(L^R^k0^k1^k3^k4^k6 )^(ML^MR^k0^k1^k3^k4^k6)==L^R^ML^MR
    test[27:54]^m[27:54]==(L^k1^k2^k4^k5)^(ML^k1^k2^k4^k5)==L^ML

    写脚本得出flag:

    from libnum import n2s
    from binascii import a2b_hex
    test='50543fc0bca1bb4f21300f0074990f846a8009febded0b2198324c1b31d2e2563c908dcabbc461f194e70527e03a807e9a478f9a56f7'
    entest='66bbd551d9847c1a10755987b43f8b214ee9c6ec2949eef01321b0bc42cffce6bdbd604924e5cbd99b7c56cf461561186921087fa1e9'
    enm='44fc6f82bdd0dff9aca3e0e82cbb9d6683516524c245494b89c272a83d2b88452ec0bfa0a73ffb42e304fe3748896111b9bdf4171903'
    
    test=a2b_hex(test)
    entest=a2b_hex(entest)
    enm=a2b_hex(enm)
    R=entest[27:54]
    L=entest[0:27]
    MR=enm[27:54]
    ML=enm[0:27]
    #print(test,"
    ",entest,"
    ",enm)
    ml=''
    mr=''
    for i in range(27):
        templ=chr((R[i]^MR[i]^L[i]^ML[i]^test[i]))
        tempr=chr((L[i]^ML[i]^test[27+i]))
        ml+=templ
        mr+=tempr
    
    print(ml+mr)

    运算结果:

  • 相关阅读:
    R语言入门视频笔记--2--一些简单的命令
    Java 虚拟机内存优化
    Apollo 配置中心
    Apollo本地缓存文件
    SpringBoot 远程调试
    SpringCloud微服务架构下 部署在ECS上 403
    Nginx 常用命令
    阿里云数据库Redis版 ERR invalid password
    Apollo配置中心搭建
    Gateway 访问超时 返回504
  • 原文地址:https://www.cnblogs.com/jane315/p/13403903.html
Copyright © 2011-2022 走看看