Randomstudy
第一層,和服務器同步時間種子就可以了。
第二層,分析 SDK的 Random 函數。


隨機數是以 seed0x5deece66d + 0xb &((1<<48)-1) 循環的形式生成偽隨機數的,只需要爆破得到低16位即可 就是 0-0xffff。
寫腳本即可爆破,后來因為python 加了一個0xfffffff和腳本有點出入 可能有概率出不了解。懶得修改直接上。
import java.io.PrintStream;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
public class test
{
public static long nextSeed(long seed){
return ((seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)) ;
}
public static int getNextInt(long seed, long bits ){
return (int)(seed >>> (48 - bits));
}
public static void main(String[] paramArrayOfString)
{
long t1 = Long.parseLong(paramArrayOfString[0]);
long t2 = Long.parseLong(paramArrayOfString[1]);
for(int i=0; i< 0x10000; i++){
if( t2 == getNextInt(nextSeed((t1 << 16) + i), 32)){
// System.out.println("find:");
// System.out.println(getNextInt(nextSeed((t1 << 16) + i), 32));
System.out.println(getNextInt(nextSeed(nextSeed((t1 << 16) + i)),32));
}
}
}
}
第三層 套用randcrack即可
import hashlib
import random
import time
import subprocess
from randcrack import RandCrack
from pwn import *
def proof(skr, skr_sha256):
for c1 in range(0x100):
for c2 in range(0x100):
for c3 in range(0x100):
shr = skr + chr(c1)+ chr(c2)+ chr(c3)
# print hashlib.sha256(shr).hexdigest()
if hashlib.sha256(shr).hexdigest() == skr_sha256.strip().lower():
print shr.encode("hex")
return shr.encode("hex")
def one(p, t):
random.seed(t)
randintdata = str(random.randint(0,2**64))
print "Try: ", randintdata
p.sendline(randintdata)
i = -10
time_num = 1
data = p.recvline()
print data
while "fail" in data:
time_num += 1
random.seed(t + i)
for x in range(time_num):
randintdata = str(random.randint(0,2**64))
print "Try: ", randintdata
p.sendline(randintdata)
i += 1
data = p.recvline()
if i == 8:
print "attack fail!"
exit()
def second(p, x1, x2):
x1 = x1.strip()
x2 = x2.strip()
print x1,x2
o = subprocess.check_output(["/usr/lib/jvm/jdk-12.0.1/bin/java", "test", x1, x2])
while len(o.split('\n')) == 1:
p.sendline("1")
p.recv()
print p.recvuntil("[-]")
data1 = p.recvuntil("\n").strip()
p.recvuntil("[-]")
data2 = p.recvuntil("\n").strip()
o = subprocess.check_output(["/usr/lib/jvm/jdk-12.0.1/bin/java", "test", data1, data2])
print "output:", o.split('\n')
p.sendline(o.split('\n')[0])
p.recv()
def third(p):
rc = RandCrack()
for i in range(624):
p.sendline("1")
oneline = p.recvline()
print i, int(oneline[10:-1])
this_num = int(oneline[10:-1])
rc.submit(this_num)
p.recvuntil('[-]')
this_num = rc.predict_randrange(0, 4294967295)
p.sendline(str(this_num))
print p.recv()
print p.recv()
print p.recv()
def attack():
p = remote("119.3.245.36", 23456)
p.recvuntil("hexdigest()=")
skr_sha256 = p.recvuntil("\n")
p.recvuntil("('hex')=")
shr5 = p.recvuntil("\n").strip().decode("hex")
p.recv()
p.sendline(proof(shr5, skr_sha256))
p.recv()
p.sendline("bfdccbebf86687951f6d37b3e5a35fe1")
p.recv()
p.recv()
one(p, int(time.time()))
# print p.recvuntil("[-]")
print p.recvuntil("[-]")
data1 = p.recvuntil("\n")
p.recvuntil("[-]")
data2 = p.recvuntil("\n")
second(p, data1, data2)
print p.recv()
p.recv()
third(p)
attack()
2019強網杯-Writeup