直接爆破
# from flag import flag# assert flag.startswith("flag{")# assert flag.endswith("}")# assert len(flag) == 27def lfsr(R, mask):output = (R << 1) & 0xffffffi = R & mask & 0xfffffflastbit = 0while i != 0:lastbit ^= (i & 1)i = i >> 1output ^= lastbitreturn (output, lastbit)# R = int(flag[5:-1], 2)mask = 0x100002def encrypt(R):ret = ''for i in range(12):tmp = 0for j in range(8):(R, out) = lfsr(R, mask)tmp = (tmp << 1) ^ outret += chr(tmp)return retdef brute_force():with open('key', 'rb') as r:cipher = r.read()for i in range(2**20, 2**21):print iif encrypt(i) == cipher:raw_input()
flag{110111100101001101001}
解压出 classes.dex 之后使用 dex2jar + jd-gui 反编译之后可以发现核心是这样的代码:
public class a
{
private static int[] a = { 0, 146527998, 205327308, 94243885, 138810487, 408218567, 77866117, 71548549, 563255818, 559010506, 449018203, 576200653, 307283021, 467607947, 314806739, 341420795, 341420795, 469998524, 417733494, 342206934, 392460324, 382290309, 185532945, 364788505, 210058699, 198137551, 360748557, 440064477, 319861317, 676258995, 389214123, 829768461, 534844356, 427514172, 864054312 };
private static int[] b = { 13710, 46393, 49151, 36900, 59564, 35883, 3517, 52957, 1509, 61207, 63274, 27694, 20932, 37997, 22069, 8438, 33995, 53298, 16908, 30902, 64602, 64028, 29629, 26537, 12026, 31610, 48639, 19968, 45654, 51972, 64956, 45293, 64752, 37108 };
private static int[] c = { 38129, 57355, 22538, 47767, 8940, 4975, 27050, 56102, 21796, 41174, 63445, 53454, 28762, 59215, 16407, 64340, 37644, 59896, 41276, 25896, 27501, 38944, 37039, 38213, 61842, 43497, 9221, 9879, 14436, 60468, 19926, 47198,
题目给了一个图片,bmp位图格式:
看特征估计偏移有东西,stegsolve打开调下偏移看到flag:
flag:QWB{W3lc0me}
1.本题给了一个加密脚本和一个加密过后的key。
2.脚本将flag做为二进制读入,做为密钥。然后循环1024*1024次,每次循环8次nlfsr函数,将结果变换写入key中。所以可以进行爆破,每次检测key的一位,从第一位开始,如果正确在检测下一位。脚本如下:
def nlfsr(R,mask):output = (R << 1) & 0xffffffi=(R&mask)&0xfffffflastbit=0changesign=Truewhile i!=0:if changesign:lastbit &= (i & 1)changesign=Falseelse:lastbit^=(i&1)i=i>>1output^=lastbitreturn (output,lastbit)f=open("key","rb").read()mask=0b110110011011001101110flag = Falsefor x in range(0,pow(2,27-6)-1):R=xfor i in range(1024*1024): #此处可以把1024*1024改成一个较小的数tmp=0for j in range(8):(R,out)=nlfsr(R,mask)tmp=(tmp << 1)^outif f[i]!=tmp:breakelif i==1024*1024-1: #此处也要同时更改flag=Truebreakif x%100000==0:print('x =',x)if flag==True:flag=xbreakprint("flag{"+bin(x)[2:]+"}"