好友
阅读权限 10
听众
最后登录 1970-1-1
本帖最后由 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表示如下:[Python] 纯文本查看 复制代码
def process(a): # total 8*5 = 40 char
if a[4]!='#' or a[9]!='#' or a[14]!='#' or a[19]!='#' or a[24]!='#' or a[29]!='#' or a[34]!='#':
print 'Format error'
exit(0)
a = ['']*8
a[0] = serial[0:4]
a[1] = serial[5:9]
a[2] = serial[10:14]
a[3] = serial[15:19]
a[4] = serial[20:24]
a[5] = serial[25:29]
a[6] = serial[30:34]
a[7] = serial[35:39]
for i in a:
for j in i:
if j not in '0123456789ABCDEF':
print 'Format error'
exit(0)
target = [0]*5
target[0] = ord(a[0][0])*ord(a[1][0])<<16
target[0] += ord(a[0][1])^ord(a[2][1])
target[0] += ord(a[0][2])%(ord(a[3][2])+1)+1
target[0] += ord(a[0][3])/(ord(a[4][3])+1)
target[1] = (ord(a[1][0])^ord(a[5][0]))<<16
target[1] += ord(a[1][1])%(ord(a[6][1])+3)
target[1] += ord(a[1][2])/(ord(a[7][2])+1)+5
target[1] += ord(a[1][3])+ord(a[0][3])
target[2] = (ord(a[2][0])/(ord(a[1][0])+3)) << 16
target[2] ^= ord(a[2][1])%ord(a[3][1])
target[2] += ord(a[2][2])+12+ord(a[5][2])
target[2] += ord(a[2][3])+ord(a[7][3])
target[3] = ord(a[2][3])^ord(a[0][1])
target[3] *= ord(a[1][3])+ord(a[3][1])
target[3] &= ord(a[4][2])&ord(a[5][2])
target[3] *= ord(a[7][3])
target[3] += target[1]
target[3] *= ord(a[6][0])
target[3] *= target[0]
tmp = target[3]
tmp -= target[1]
tmp %= 2*target[0]
target[3] -= tmp
target[4] = (ord(a[3][0])^ord(a[4][0])) << 16
target[4] *= ord(a[3][1])%(ord(a[4][1])+2)
target[4] += ord(a[3][2])%(ord(a[4][2])+5) + 7
target[4] += ord(a[3][3])*ord(a[4][3])
return target
将得到的5个64位数据与base64解密后的前三个DWORD进行比较,比较公式如下:
将上式求解得到如下公式:[Python] 纯文本查看 复制代码
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的函数或数据均为加密时使用,未标注的为解密时使用)[Python] 纯文本查看 复制代码
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字节出发生了交换。变换后的密钥加函数如下:[Python] 纯文本查看 复制代码
def Key_xor(res,a2):
result = list(res)
for i in xrange(4):
result[i] = chr(ord(result[i])^ord(a2[4*i]))
result[4+i] = chr(ord(result[4+i])^ord(a2[4*i+1]))
result[8+i] = chr(ord(result[8+i])^ord(a2[4*i+3]))
result[12+i] = chr(ord(result[12+i])^ord(a2[4*i+2]))
return ''.join(result)
在进行字节代换时,代换表也发生了变化,代换表如下:
可运算得到逆代换表如下
在进行行变换时由原本的行变换变成了列变换。代码如下:[Python] 纯文本查看 复制代码
def Inv_RowShift(res):
result = list(res)
result[1],result[5],result[9],result[13] = result[13],result[1],result[5],result[9]
result[2],result[6],result[10],result[14] = result[10],result[14],result[2],result[6]
result[3],result[7],result[11],result[15] = result[7],result[11],result[15],result[3]
return ''.join(result)
其列混淆则为列混淆的逆变换,直接使用即可,此处不给出。 根据分析结果对应的写出逆变换得到解密函数即可。
0x03 结果
任给一组用户名:0000#A222#2222#2222#44F4#55D5#C666#7AB7
求得注册码:Ou979Wh4Udz8ky9Y9ga#QSAssV&pf2rBBSv@5ou7BS+=
结果:
免费评分
查看全部评分
发帖前要善用【论坛搜索 】 功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。