从第一题题目来看,感觉这次的题目都出得很灵活,主要考的是密码学这一块的东西。这道题目也不例外,由于不是科班出身,根本没有接触过密码学,那只能现学现卖,其中踩了不少坑,但是不要怕,我们可以慢慢爬出来再继续踩。初一看这道题后面的“双重保镖”很是霸气,很容易被吓跑,但是仔细认真做了之后会发现,Oh,hash碰撞也不是那么难的。好了,废话扯多了估计要被拉黑,我选择的依旧是安卓的题目,下面进入正题,我将此题分成两大部分,主要阐述这两大部分。
官方具体表演如下:
实际上第一步要找出这段算法的逆运算。程序中有一个buffer,简算过后如下:
程序将输入的16bytes(也就是128bit),记为input,buffer的大小是2048bytes,分成了128个128bit,记为x[0]到x[127],根据之前的运算,input将和x数组进行128次运算,每一次运算生成1bit,一共生成128个bit,即16字节,这16字节就是最后算出来的结果,也是需要比较的结果。
其实是一个128元1次的异或方程组,采用高数中的高斯消元法来求解,这个就算没有学过密码学也会,因为这就是高数中的内容啊,看到这个名字是不是很熟悉?对,就是矩阵化简!对于高数课逃课的同学,关于高斯消元法,给个链接:
https://en.wikipedia.org/wiki/Gaussian_elimination
这里已经非常详细
然后根据本题目的特征google一下就能搜到不少解该类方程组的模板,选取一个,代码如下:
再根据IDA中看到的信息,确认正确答案的前面7字节是"GSLab17",最后四字节是pid,编写代码如下:
再调试看看结果,自己挖了什么坑自己填填坑,即可过第一关,进入下一关。
接下来来到孪生兄弟把守的最后大关,只要越过这道防线,就可以飞向光明顶。
之所以说它是孪生兄弟,是因为它对程序进行了hash值的校验,而且是两种校验,两个校验值都必须值为0x614C5347,其实就是“GSLa”。
Hash函数H将可变长度的数据M作为输入,产生固定长度的Hash值h。
Hash函数,哈希函数,散列函数,杂凑函数它们说的都是同一个含义,后续我们都称之为Hash函数。
Hash函数H将可变长度的数据M作为输入,产生固定长度的Hash值h。
Hash函数,哈希函数,散列函数,杂凑函数它们说的都是同一个含义,后续我们都称之为Hash函数。
h=H(M)
给定输入M,通过函数H可以很容易计算出输出h;但如果给定h,则找到M在计算上不可行。
输入数据M中任何1个bit发生变化,都将导致输出M发生很大的变化。
在Hash函数中,M称之为h原像,,因为H函数是一个多对一的映射,,对于任意给定的Hash数值h,,可能会有多个原像,,如果满足如下条件, 则称之为发生了哈希碰撞,也就是哈希冲突。
x!=yandH(x)==H(y)
一个优良的Hash函数必须满足如下几个性质:
任意y,找x,使得H(x) = y,非常困难
给定x1, 找x2, 使得H(x1) == H(x2), 非常困难
找任意的x1, x2, 使得H(x1) == H(x2), 非常困难
这里感觉本题是第一条或者第二条,如果是第三条的话(可惜本题并不是),可以参考生日定理来解题,这里放个链接:
https://en.wikipedia.org/wiki/Birthday_problem
介绍完基本概念,言归正传,本题用的两个校验是crc32校验和fnvhash函数校验,这里再给两个链接:
crc32:http://blog.csdn.net/zhaodm/article/details/3711034
fnvhash:http://blog.csdn.net/taochenchang/article/details/7319739
通过分析代码可以得到:
1.crc32 校验
标准算法没改动过:
单独改crc32是没问题的.
2.fnv_hash
标准算法没改动过
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课