Some random number attack scripts

Keywords: PHP socket Python Java

At the xman summer camp, the big man brought us cryptography courses. Among them, the random number part feels deeply and records several scripts.

1. Time as the Random Number of Seeds

https://www.jarvisoj.com/ [xman 2019] babyrpd

Server-side code

 1 class Unbuffered(object):
 2    def __init__(self, stream):
 3        self.stream = stream
 4    def write(self, data):
 5        self.stream.write(data)
 6        self.stream.flush()
 7    def __getattr__(self, attr):
 8        return getattr(self.stream, attr)
 9 import sys
10 sys.stdout = Unbuffered(sys.stdout)
11 import signal
12 signal.alarm(600)
13 
14 import random
15 import time
16 flag=open("/root/level0/flag","r").read()
17 
18 random.seed(int(time.time()))
19 def check():
20     recv=int(raw_input())
21     if recv==random.randint(0,2**64):
22         print flag
23         return True
24     else:
25         print "atum tql"
26         return False
27 
28 while 1:
29     if check():
30         break

Solution:

Predict time seeds, attack

 1 #coding=utf-8
 2 import socket               
 3 import random
 4 import time
 5 
 6 while True:
 7     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 8     host = '47.97.215.88'
 9     port = 20000
10     random.seed(int(time.time()+2))  #Add a delay so+2 second
11     s.connect((host, port))
12     s.send(str(random.randint(0,2**64))+'\n')
13     print s.recv(1024)

2. Random Numbers of Java

https://www.jarvisoj.com/ [xman 2019] mediumrpd

Server-side code:

 1 class Unbuffered(object):
 2    def __init__(self, stream):
 3        self.stream = stream
 4    def write(self, data):
 5        self.stream.write(data)
 6        self.stream.flush()
 7    def __getattr__(self, attr):
 8        return getattr(self.stream, attr)
 9 import sys
10 sys.stdout = Unbuffered(sys.stdout)
11 import signal
12 signal.alarm(600)
13 import os
14 os.chdir("/root/level1")
15 
16 flag=open("flag","r").read()
17 
18 import subprocess
19 o = subprocess.check_output(["java", "Main"])
20 tmp=[]
21 for i in o.split("\n")[0:3]:
22     tmp.append(int(i.strip()))
23 
24 
25 v1=tmp[0] % 0xffffffff
26 v2=tmp[1] % 0xffffffff
27 v3=tmp[2] % 0xffffffff
28 print v1
29 print v2
30 v3_get=int(raw_input())
31 if v3_get==v3:
32     print flag
1 import java.util.Random;
2 public class Main {
3     public static void main(String[] args) {
4         Random random = new Random();
5         System.out.println(random.nextInt());
6         System.out.println(random.nextInt());
7         System.out.println(random.nextInt());
8     }
9 }

Attack methods

Two random numbers V1 and V2 are obtained from the title. Through the known formula, v3 can be calculated.

 1 import socket               
 2 import random
 3 import time
 4 def liner (seed):
 5     return ((seed*25214903917+11)&0xffffffffffff)
 6 
 7 while True:
 8     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 9     host = '47.97.215.88'
10     port = 20001
11     s.connect((host, port))
12     v1=int(s.recv(1024))
13     v2=int(s.recv(1024))
14     for i in range(65536):
15         seed=v1*65536+i
16         if liner(seed)>>16==v2:
17             print seed
18             v3=liner(liner(seed))>>16
19             s.send(str(v3)+'\n')
20             print s.recv(1024)

3. python's random

Source: Mersenne Twister

The big guy said that php's mt_rand (can be attacked with php_mt_seed), ruby's rand(), python's random can be attacked, but I only got the version of python.

The title is https://www.jarvisoj.com/ [xman 2019] hardrpd

Server-side code:

 1 class Unbuffered(object):
 2    def __init__(self, stream):
 3        self.stream = stream
 4    def write(self, data):
 5        self.stream.write(data)
 6        self.stream.flush()
 7    def __getattr__(self, attr):
 8        return getattr(self.stream, attr)
 9 import sys
10 sys.stdout = Unbuffered(sys.stdout)
11 import os
12 os.chdir("/root/level2")
13 
14 from random import *
15 
16 
17 while 1:
18     a=raw_input("#")
19     target=getrandbits(32)
20     if a!=str(target):
21         print target
22     else:
23         print open("flag","rb").read()

 

Attack script: (rewritten to TokyoWestern CTF WriteUp by r3kapig )

 1 #coding=utf-8
 2 import socket               
 3 import random
 4 import time
 5 
 6 
 7 def unBitshiftRightXor (value,shift):
 8     i = 0
 9     result = 0
10     while i * shift < 32:
11          partMask = right((-1 << (32 - shift)) , (shift * i))
12          part = value & partMask
13          value ^= right(part , shift)
14          result |= part
15          i+=1
16     return result
17 def unBitshiftLeftXor(value, shift, mask):
18     i = 0;
19     result = 0;
20     while i * shift < 32:
21         partMask = right(-1 , (32 - shift)) << (shift * i)
22         part = value & partMask
23         value ^= (part << shift) & mask
24         result |= part
25         i += 1
26     return result
27 
28 def rev(nums):
29     state=[]
30     for i in nums:
31         value = i;
32         value = unBitshiftRightXor(value, 18)
33         value = unBitshiftLeftXor(value, 15, 0xefc60000)
34         value = unBitshiftLeftXor(value, 7, 0x9d2c5680)
35         state.append(unBitshiftRightXor(value, 11))
36     return state
37 
38 def sign(iv):
39     if(iv&0x80000000):
40         iv = -0x100000000 + iv
41     return iv
42 
43 def nextState(state):
44     for i in range(624):
45         y = (state[i] & 0x80000000) + (state[(i + 1) % 624] & 0x7fffffff)
46         next = right(y,1);
47         next ^= state[(i + 397) % 624]
48         if ((y & 1L) == 1L):
49             next ^= 0x9908b0df
50         state[i] = next
51 
52 def nextNumber(state):
53     currentIndex=0
54     tmp = state[currentIndex];
55     tmp ^= right(tmp , 11)
56     tmp ^= (tmp << 7) & 0x9d2c5680
57     tmp ^= (tmp << 15) & 0xefc60000
58     tmp ^= right(tmp , 18)
59     return tmp
60 
61 def right(n,bit): #python No>>>Operator, which is used as a substitute
62     x=n
63     if n<0 and bit>0:
64         n=(2147483648*2+n)>>bit
65     else:
66         n=n>>bit
67     return n
68 
69 def crack_prng(outputs_624_list):
70     state=rev(outputs_624_list)
71     stateList = state[:]
72     nextState(state)
73     r = random.Random()
74     state = (3, tuple(stateList + [624]), None)
75     r.setstate(state)
76     return r
77 '''
78 #Local test code
79 n=[random.getrandbits(32) for i in range(625)]
80 r=crack_prng(n[:-1])
81 print n[-1],r.getrandbits(32)
82 '''
83 n=[]
84 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
85 host = '47.97.215.88'
86 port = 20002  
87 s.connect((host, port))
88 for i in range(624):
89     print s.recv(1024),i,
90     s.send('\n')
91     n.append(int(s.recv(1024)))
92 r=crack_prng(n)
93 s.send(str(r.getrandbits(32))+'\n')
94 print s.recv(1024),s.recv(1024)

Posted by houssam_ballout on Tue, 08 Oct 2019 10:06:01 -0700