首先声明,本人对神经网络一窍不通,如有表述错误请见谅。
本题构造了一个四层人工神经网络模型,原始输入变换后形成的两个浮点数为输入进入网络计算,网络输出为一个浮点数,通过输入之和与输出之间的逼近精度、输出值的范围、原始输入的格式等方式进行检验,确定唯一解。
下面是基本按着做题过程叙述的。
代码分析
程序是MinGW64编译。试运行情况如下:
搜索字符串并未发现打印信息,原来所有字串全被异或编码了,脚本解码后情况如下:
正式开始分析程序。
主流程分析
开始进行一些数值的初始化后,要求输入key。
接着检查输入key的长度为10,并进行unhex,要求输入为数字+A-F
,否则转换结果不为5字节长度,报错退出。
再接着将输入变换得到的5字节的前两字节赋值给一个64位浮点数的高位,后三字节赋值给另一个浮点数的高位,构造出两个浮点数,代入函数4015E0
进行计算,然后检查计算结果。
照主流程来看,关键的计算函数4015E0
应该就是题名说的神经网络了。
对于我这种既没有数学基础又不懂AI相关知道的人来说,太难为人了。
无法,滚去粗略学习了大约一晚上的神经网络。
计算函数分析
计算函数代码似乎比较简单,如下:
按我一晚上的学习经验来看,这是个前馈神经网络FFNN
(错了误怪),4层结构。
在第2层,18个神经元,两个输入加权求和后有一个sigmoid
激活函数;第3层只是加权求和,后面还有个线性计算,我也把这归进来了。
具体计算过程代码中已经标出。
计算最后部分还有一个校验,网络输入的一个浮点数在(1,10)之间,否则计算的输出值为10.0,就不能通过主流程的check。
check分析
这神经网络似乎是理清了些(也不管对不对),但是怎么求解呢,不知道。先详细分析下check规则吧。
计算出来后,其结果以%lf
格式覆盖原始输入。并检查第二字节为.
,即计算结果s
:
0 < s < 10
计算结果的前三个数字的平方和不小于241,如果记s1,s2,s3为前三个数字,本来式子是:
sqrt(s1**2+s2**2+s3**2) > 15.5
因为s1,s2,s3都为整数,所以即
s1**2+s2**2+s3**2 > 240.25 >= 241
而
240 /3 = 80
9*9 = 81
8*8 = 64
所以前三个数字必都为9
这是要逼近10啊。
此外还有一个校验,翻译一下,就是原始输入的第6字节为0。
下一个校验是:(记网络输入的两个浮点数为num1,num2)
abs(num1+num2-s) < 0.003
这是输出逼近输入和的意思啊,结合上面输入逼近10和网络输入值的范围,那几乎可以先假定题意设定网络输入为10或无限接近10。
整理下格式要求、主流程及计算流程的校验:
1. 输入长度为10,且字符范围是数字+A-F
2. 1<num1<10; 1<num2<10
3. num1+num2 == 10 (假定)
4. num1+num2-s < 0.003
5. input[5] == '0'
求解
这么多的条件限制,看来并不能从网络计算方法中得出结果的唯一性。开始还想从网络计算得出唯一结论,现在不管能不能就此得出,但是已经没有这个必要了。
因为,从上面的校验分析看出,实际上网络的计算过程已经不重要了,网络计算是死的,唯一变的是输入与输出,两个网络输入的浮点关系也是定的,如果定其中一个为变量,那么则可以将网络计算看来一个黑盒函数。
于是我就以第一个浮点数为变量,在输入范围内画出了墨盒函数。
下图为两段包含符合输出值要求的图:
纵轴0处为10,其上数值为相对10的偏移。
如果放大点范围,第一个浮点数的范围为:
1 < num1 < 1.125
8 < num1 < 8.2
本题还有个隐藏条件,是关于浮点数的。第一个浮点数实际上只用了输入的两个字节,第二个浮点数只用了输入的三个字节,其余字节为0。这两个数不是随便的浮点数,存储值是要符合字节格式要求的。据测试,num1其值应该是0.0625
的倍数。在脚本求解的过程中,为防止错过解,将步长又进一步放小。
求解代码如下,求解范围作了调整:
import numpy as np
import struct
import os
import matplotlib.pyplot as plt
step = 0.00005
a = [ -1.0245, 0.0848024,
-0.530959, 0.703843,
-0.120586, -0.313185,
-0.765289, 0.339469,
0.40869, 0.346429,
-0.672084, 0.703138,
0.479381, 0.145042,
-0.758163, -1.19117,
-0.716324, -0.185696,
-0.388104, -0.441494,
0.749153, -0.293723,
-0.280767, -0.660177,
-1.13947, -0.373301,
-0.371646, -0.320964,
0.227951, 0.286258,
-0.64833, 0.34251,
0.101866, -0.0669482,
-0.799297, 0.277074]
a_1 = np.array([-1.0245, -0.530959, -0.120586, -0.765289, 0.40869, -0.672084,
0.479381, -0.758163, -0.716324, -0.388104, 0.749153, -0.280767,
-1.13947, -0.371646, 0.227951, -0.64833, 0.101866, -0.799297])
a_2 = np.array([0.0848024, 0.703843, -0.313185, 0.339469, 0.346429, 0.703138,
0.145042, -1.19117, -0.185696, -0.441494, -0.293723, -0.660177,
-0.373301, -0.320964, 0.286258, 0.34251, -0.0669482, 0.277074])
w = [-0.119411,0.364227,-0.335042,-0.616251,1.03833,0.193202,
1.00183,0.443425,-0.571216,-1.36825,0.158766,-1.15323,
0.253585,-0.988879,0.611415,0.149166,0.518852,0.298557]
#1.0625 8.9375
##flag:F13FE02140
def crack():
i1 = 1
while True:
i1 = i1+step
# i1 = 1.0625
i2 = 10-i1
x = (i1-0.01+1)/(9.99-0.01+1)
y = (i2-0.03+1)/(9.99-0.03+1)
l = []
for i in range(18):
t1 = x*a[2*i]
t2 = y*a[2*i+1]
l.append(1.0/(np.exp(-1*(t1+t2))+1))
s = 0
ss = 0
for i in range(18):
s += l[i]*w[i]
ss = s*(19.32-0.26+1)+0.26-1
if ss<10 and ss>9.997 :
d1 = struct.pack('>d',round(i1,6))
d2 = struct.pack('>d',round(i2,6))
if d1[2:] == '\x00'*6 and d2[3:] == '\x00'*5:
print i1,d1.encode('hex').upper()
print i2,d2.encode('hex').upper()
print ss
if i1 >1.2:
return
def dataplot(r1,r2,step):
a1 = a_1.reshape(18,1)
a2 = a_2.reshape(18,1)
wi = np.array(w)
X=np.arange(r1,r2,step)
Y = 10-X
x = (X-0.01+1)/(9.99-0.01+1)
y = (Y-0.03+1)/(9.99-0.03+1)
t1 = x*a1
t2 = y*a2
l = 1.0/(np.exp(-1*(t1+t2))+1)
s = np.dot(l.T,wi)
ss = s*(19.32-0.26+1)+0.26-1
plt.plot(X,ss)
plt.figure(1)
plt.subplot(111)
plt.grid()
dataplot(1,9,0.0005)
plt.figure(2)
plt.subplot(211)
plt.grid()
dataplot(1,1.2,0.0005)
plt.subplot(212)
plt.grid()
dataplot(8,8.6,0.005)
plt.show()
crack()
最后flag:F13FE02140,两个浮点数为1.0625,8.9375。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-7-12 11:55
被poyoten编辑
,原因: 修改笔误