echo579 发表于 2018-4-27 12:37

资格赛进阶版题解

本帖最后由 echo579 于 2018-4-27 12:50 编辑

第一次发帖,搞不动格式,贴上word吧

--------------------------------------------------
0x00 概述
    程序接受了用户输入的用户名和注册码,要求用户名长度为39,格式为xxxx#xxxx#xxxx#xxxx#xxxx#xxxx#xxxx#xxxx,注册码则为变形AES加密后再用变形base64编码后的数据,要求解密后长度为32,最后一个DWORD为0,倒数第二个DWORD为0x32303138。
0x01 校验
    将格式化的用户名按照计算规则生成5个64位数据,计算过程用python表示如下:
用户名计算
def process(a):      # total 8*5 = 40 char
      if a!='#' or a!='#' or a!='#' or a!='#' or a!='#' or a!='#' or a!='#':
                print 'Format error'
                exit(0)
      a = ['']*8
      a = serial
      a = serial
      a = serial
      a = serial
      a = serial
      a = serial
      a = serial
      a = serial

      for i in a:
                for j in i:
                        if j not in '0123456789ABCDEF':
                              print 'Format error'
                              exit(0)

      target = *5

      target = ord(a)*ord(a)<<16
      target += ord(a)^ord(a)
      target += ord(a)%(ord(a)+1)+1
      target += ord(a)/(ord(a)+1)

      target = (ord(a)^ord(a))<<16
      target += ord(a)%(ord(a)+3)
      target += ord(a)/(ord(a)+1)+5
      target += ord(a)+ord(a)

      target = (ord(a)/(ord(a)+3)) << 16
      target ^= ord(a)%ord(a)
      target += ord(a)+12+ord(a)
      target += ord(a)+ord(a)

      target = ord(a)^ord(a)
      target *= ord(a)+ord(a)
      target &= ord(a)&ord(a)
      target *= ord(a)
      target += target
      target *= ord(a)
      target *= target

      tmp = target
      tmp -= target
      tmp %= 2*target
      target -= tmp


      target = (ord(a)^ord(a)) << 16
      target *= ord(a)%(ord(a)+2)
      target += ord(a)%(ord(a)+5) + 7
      target += ord(a)*ord(a)

      return target

    将得到的5个64位数据与base64解密后的前三个DWORD进行比较,比较公式如下:
   
    将上式求解得到如下公式:
求解公式
        x = (d-b)/(2*a)
        y = (d**2+4*a*c-b**2)/(4*a)
        z = a*e**2+(b-d)*e+c

0x02 变形AES分析      
    首先AES的密钥扩展方式变了,不过无妨,可以从运行中的程序中直接提取,得到
   
      但在AES运行到2-9次密钥加时还会对2-9轮的轮密钥进行逆列混淆运算,同样,可提前计算出结果备用。计算函数如下(由于其轮密钥使用顺序以及列混淆的缘故,此处所有标为inv的函数或数据均为加密时使用,未标注的为解密时使用)
轮密钥变换

def RoundKey_mix():
      key = key_expansion('clewgemobals8102')
      real = key[:16]
      for i in range(9):
                encdata = key_trans(key[(i+1)*16:(i+2)*16])
                encdata = Inv_ColumMix(encdata)
                encdata = inv_key_trans(encdata)
                real += encdata
      real += key[-16:]
      return real



    计算结果如下
   
       密钥加在执行过程中也发生了改变,原本应对位相加的方式在第3第4字节出发生了交换。变换后的密钥加函数如下:
密钥加

def Key_xor(res,a2):
      result = list(res)
      for i in xrange(4):
                result = chr(ord(result)^ord(a2))
                result = chr(ord(result)^ord(a2))
                result = chr(ord(result)^ord(a2))
                result = chr(ord(result)^ord(a2))
      return ''.join(result)


       在进行字节代换时,代换表也发生了变化,代换表如下:
   
    可运算得到逆代换表如下
   
      在进行行变换时由原本的行变换变成了列变换。代码如下:
行变换

def Inv_RowShift(res):
      result = list(res)
      result,result,result,result = result,result,result,result
      result,result,result,result = result,result,result,result
      result,result,result,result = result,result,result,result
      return ''.join(result)


       其列混淆则为列混淆的逆变换,直接使用即可,此处不给出。       根据分析结果对应的写出逆变换得到解密函数即可。
0x03 结果
   任给一组用户名:0000#A222#2222#2222#44F4#55D5#C666#7AB7
    求得注册码:Ou979Wh4Udz8ky9Y9ga#QSAssV&pf2rBBSv@5ou7BS+=
   
    结果:
   

gunxsword 发表于 2018-4-27 22:15

历害历害,祝楼主取得好成绩!

SummerDark 发表于 2018-4-28 15:13

看到轮密钥就头疼。。

373161977 发表于 2018-5-3 18:29

过来学习进步

逄不怪 发表于 2018-5-8 19:30

加油,祝楼主技术越来越高超

wh314 发表于 2018-5-8 20:08

楼主   题目中的代码是什么语言

echo579 发表于 2018-5-9 15:26

wh314 发表于 2018-5-8 20:08
楼主   题目中的代码是什么语言

做的PC版,C写的

Lewtq 发表于 2018-5-9 19:43

我来学习一下{:301_1001:}

不善灬言辞 发表于 2018-5-11 21:33

看着密密麻麻的字符就头疼了

itaotaoba 发表于 2018-5-16 13:47

祝楼主取得好成绩!
页: [1] 2 3
查看完整版本: 资格赛进阶版题解