Skip to content

Latest commit

 

History

History

rnggods

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Praise our RNG Gods

Points: 436

Solves: 58


In this we were given chall.txt which contains the bytecodes of a python program.

Running file on the file really threw me of because, well...

file chall.txt 
chall.txt: Dyalog APL transfer 

Eventually I didn't see any connection between this and Dyalog, and went to GPT, who told me that it was python bytecode and reconstructed it

Now it didn't reconstruct it properly, and it was a pretty bad idea to rely on it anyway. In the future, it's not very hard to reconstruct it by hand. Here are some resources to help you

and something I found really useful was

The specific place where GPT was stumbling was

 0 LOAD_GLOBAL 1 (NULL + random)
 2 LOAD_ATTR 2 (getrandbits)
 4 LOAD_CONST 1 (32)
 6 CALL 1
 8 load_fast 0 (i)
10 load_const 2 (195894762)
12 binary_op 12 (^)
14 LOAD_CONST 3 (322420958)
16 BINARY_OP 12 (^)
18 BINARY_OP 5 ()
20 LOAD_CONST 4 (2969596945L)
22 BINARY_OP 5 ()
24 STORE_FAST 1 (password)

It reconstructed this as

return (random.getrandbits(32) ^ 195894762 ^ 322420958) % 2969596945

Which clearly is wrong. What actually is happening is that

 0 LOAD_GLOBAL 1 (NULL + random)
 2 LOAD_ATTR 2 (getrandbits)
 4 LOAD_CONST 1 (32)
 6 CALL 1

is getting a 32-bit random number.

 8 load_fast 0 (i)
10 load_const 2 (195894762)
12 binary_op 12 (^)
14 LOAD_CONST 3 (322420958)
16 BINARY_OP 12 (^)

is just doing i ^ 195894762 and then XORING that with 322420958

Now a tricky part was BINARY_OP 5. Apparently this is multiplication (*). Till python v3.10 the bytecodes were BINARY_MULTIPLICATION etc, but in v3.11 they were changed to BINARY_OP x. I had to visit some forum threads to realise this, and then I confirmed this with Dis This. Which gives us the final math expression as

return (random.getrandbits(32) * ((i ^ 195894762) ^ 322420958) * 2969596945)

Now lets get to the actual exploit. What the challenge is basically an exploit of python's random module. random uses the Mersenne Twister Pseudo Random Number Generator ("Praise our RNG gods"), which is predictable if you have information of 624 contiguous outputs.

The python randcrack module helps us execute this exploit. We have been given essentially an infinite sequence of numbers generated by random that we pass into randcrack then. Finally once we confirm randcrack is able to predict the numbers, we sent a predicted number to the challenge to get the flag :)


server is now down so I can't get the flag :(
sorry I was so slow