[SWPUCTF 2021 新生赛]fakebase
flag = 'xxxxxxxxxxxxxxxxxxx' s_box = 'qwertyuiopasdfghjkzxcvb123456#$' tmp = '' for i in flag: tmp += str(bin(ord(i)))[2:].zfill(8) b1 = int(tmp,2) s = '' while b1//31 != 0: s += s_box[b1%31] b1 = b1//31 print(s) # s = u#k4ggia61egegzjuqz12jhfspfkay
取模逆运算
- 题目考查了取模的逆运算,假设
c=a%b已知,c和b,那么a可以得到算式:a=k*b+c。其中k是需要爆破的。 - 回到题目本身我们我肯可以得到
s的值,其中s的值都是s_box中取的,因此[b1%31]是可以得知的。也就是
s_box = 'qwertyuiopasdfghjkzxcvb123456#$' s = 'u#k4ggia61egegzjuqz12jhfspfkay' for i in s: s_box.index(i)
那么求b1就是
s_box = 'qwertyuiopasdfghjkzxcvb123456#$' s = 'u#k4ggia61egegzjuqz12jhfspfkay' for i in s: b1 = k*31+s_box.index(i)
但是要爆破k呢,因为b1是ASCII,最大不超过128,128/31==4因此爆破k值最大不超过5.,因为我们是从0开始爆破,因为b1是从大每次整除31,依次减小的,因此我们s选好 是需要逆序。因此:
s_box = 'qwertyuiopasdfghjkzxcvb123456#$' s = 'u#k4ggia61egegzjuqz12jhfspfkay' for k in range(5): b1=k for i in s[::-1]: b1 = b1*31+s_box.index(i)
最后直接将整数转换为字符串即可:
import libnum s_box = 'qwertyuiopasdfghjkzxcvb123456#$' s = 'u#k4ggia61egegzjuqz12jhfspfkay' for k in range(5): b1=k for i in s[::-1]: b1 = b1*31+s_box.index(i) print(libnum.n2s(int(b1)))
亦或者
import libnum s_box = 'qwertyuiopasdfghjkzxcvb123456#$' s = 'u#k4ggia61egegzjuqz12jhfspfkay' flag="" for k in range(5): b1=k for i in s[::-1]: b1 = b1*31+s_box.index(i) t = str(bin(b1)[2:]) t = str(t.zfill((len(t) // 8 + 1) * 8)) for i in range(0,len(t),8): flag = flag +chr(int(t[i:i+8],2)) print(flag)

"因为b1是ASCII,最大不超过128,128/31==4因此爆破k值最大不超过5"
这句话是为什么呢,每次除的数是31,应该已经把原有的打乱了吧