1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
| from Crypto.Util.number import long_to_bytes,bytes_to_long,inverse from pwn import * context.log_level = 'debug' def gcd(a, b): while b: a, b = b, a%b return a
def crack_unknown_increment(states, modulus, multiplier): """ 利用伪随机序列s,模数n,乘数m,恢复增数c states:伪随机数序列s modulus:模数n, multiplier:乘数m increment:增量c return:根据n,m,s0,s1恢复c,并返回 """ increment = (states[1] - states[0]*multiplier) % modulus return modulus, multiplier, increment
def crack_unknown_multiplier(states, modulus): """ 利用伪随机序列s和模数n,恢复乘数m states:伪随机数序列s modulus:模数n, multiplier:乘数m return:根据n,s0,s1,s2恢复m,然后利用crack_unknown_increment恢复c """ multiplier = (states[2] - states[1]) * inverse(states[1] - states[0], modulus) % modulus return crack_unknown_increment(states, modulus, multiplier)
def crack_unknown_modulus(states): """ 利用初值和随后LCG产生的连续的几个值,恢复模数n modulus:模数n states:伪随机数序列s diffs:相邻随机数s的差值:t序列 zeroes:与t系列有关的差值,zeroes = t2*t0 - t1*t1,t0,t1,t2相邻 return:根据n,s0,s1,s2恢复m,然后利用crack_unknown_increment恢复c """ diffs = [s1 - s0 for s0, s1 in zip(states, states[1:])] zeroes = [t2*t0 - t1*t1 for t0, t1, t2 in zip(diffs, diffs[1:], diffs[2:])] modulus = abs(reduce(gcd, zeroes)) return crack_unknown_multiplier(states, modulus)
def lcg(seed,params): """ LCG算法 params:(multiplier,increment,modulus) seed:伪随机序列中第一个值s0 return:返回一个迭代器,其中的值是私钥序列 """ (m,c,n)=params x = seed % n yield int(x) while True: x = (m * x + c) % n yield int(x)
def decode(pri,pub,c,p): """ ElGamal解密算法 pri:一方私钥 pub:另一方公钥 sharekey:双方协商密钥 c:密文 p:模数 m:明文 return:返回明文字符 """ sharekey = pow(pub,pri,p) m=long_to_bytes(c*inverse(sharekey,p)%p) return m
class Game: def __init__(self, n, key, r, b): self.n = n self.key = key self.r = r & (2 ** self.n - 1) self.b = b def out(self): o = self.r & 1 p = self.r & self.key q = 0 while p: q = q + p & 1 p = p >> 1 q = q & 1 t = q << (self.n - 2) & (2 ** self.n - 1) self.r = t | (self.r >> 1) & (2 ** self.n - 1) return o
def next(self): res = 0 for i in range(self.b): o = self.out() res |= o << (self.b - 1 - i) return res
def getr(s): r = '' for i in s: b = bin(i)[2:].rjust(8,'0') for each in b: r = each+r print int(r,2) return int(r,2)
def getk(s): k="" for i in s: b = bin(i)[2:].rjust(8,'0') for each in b: k += each return k sh = remote('59.110.243.101','5123') sh.recvuntil("Your choice:\n") sh.sendline("2") sh.recvuntil("Baby:") Baby = sh.recvuntil("\n")[:-1] sh.recvuntil("Easy:") Easy = sh.recvuntil("\n")[:-1] sh.recvuntil("Normal:") Normal = sh.recvuntil("\n")[:-1] sh.recvuntil("Hard:") Hard = sh.recvuntil("\n")[:-1] sh.recvuntil("Master:") Master = sh.recvuntil("\n")[:-1] sh.recvuntil("Crazy:") Crazy = sh.recvuntil("\n")[:-1]
pri=[Baby,Easy,Normal,Hard,Master,Crazy]
(n,m,c)=crack_unknown_modulus([int(each) for each in pri])
x=int(pri[0])
key = lcg(x,(m,c,n)) for _ in range(6): next(key) choice = next(key) sh.recvuntil("Input the level code:\n")
sh.sendline(str(choice)) sh.recvuntil("Your choice:\n") sh.sendline("1")
s=[] F = 0 for _ in range(9): sh.recvuntil("Input your answer:\n") sh.sendline("0") ans = sh.recvuntil("The answer is ") if 'Right' in ans: F = 1 print("NICE") s.append(int(sh.recvuntil("!")[:-1]))
if F == 1: sh.recvuntil("Input your answer:\n") sh.sendline("0") ans = sh.recvuntil("The answer is ") s.append(int(sh.recvuntil("!")[:-1])) r = getr(s[:5]) output = getk(s[:]) print "r:"+str(r) print "output:"+ output print s k = input("k:") game = Game(40,k,r,8) for _ in range(10): next(game)
for _ in range(500): sh.recvuntil("Input your answer:\n") sh.sendline(str(next(game)))
sh.interactive()
[DEBUG] Received 0x3f bytes: 'Your coin: 500\n' 'You Win!\n' 'flag{12727f129b72e685388c6a67538ee9b0}\n'
|