One Article Review

Accueil - L'article:
Source Blog.webp SkullSecurity
Identifiant 8300184
Date de publication 2021-03-16 16:32:50 (vue: 2023-01-11 16:56:04)
Titre BSidesSF CTF 2021 Author writeup: Hangman Battle Royale, where you defeat 1023 AI players!
Texte Hi Everybody! This is going to be a challenge-author writeup for the Hangman Battle Royale challenge from BSides San Francisco 2021. This is actually a reasonable simple challenge, overall. I got the idea of using a bad mt19937 implementation (the Mersenne Twister PRNG used by Ruby and Python) from SANS Holiday Hack Challenge 2020 (which is still online if you want to play!), and wanted to build a challenge around it. I had the idea of Battleship originally, but ended up deciding on Hangman for reasons I no longer remember, but that I'm sure made sense at the time. The game When you run the game, it prompts for the number of rounds: $ ruby ./hangman.rb Welcome to Hangman Battle Royale! ================================ MAIN MENU ================================ How many rounds do you want to play? (2 - 16) If you play at least 8 rounds, you win the special prize! When you choose a round count, it picks a bunch of CPU names to build brackets: ================================ ROUND 1! ================================ This game's match-ups are: Meirina Tresvalles -vs- Gelbert Chhangte Kebede Boehmer -vs- Karthic Cassity Mairtin Piedrahita -vs- Winston Pawlowski Brendaliz Lumbang -vs- Josipa Perlow Unusual Ballenger -vs- Carmellia Agregado Jinnie Khalif -vs- Jeegar Madela Vjeran Saltarelli -vs- Rachella Newfield And finally... YOU -vs- Patience Saravana! The vulnerability The actual code powering the list of players uses Ruby's built-in PRNG, which uses a predictable Mersenne Twister to generate random numbers. I don't love how the name-choosing code was a little bit contrived, but it can leak enough state to predict future random numbers: def get_opponents(count) return 0.upto(count-1).map do || i = rand(0xFFFFFFFF) "#{ FIRST_NAMES[i & 0xFFFF] } #{ LAST_NAMES[i >> 16] }" end end Each pair of names is a single 32-bit integer from the Mersenne Twister PRNG. It turns out, if you can leak 624 32-bit outputs, you can recover the full state! That means if you play at least 10 rounds, you end up with 210-1 names, or 1023 32-bit numbers (because you're the 1024th player). Once you've gotten the state of the PRNG, you can predict everything else that's going to happen! The exploit My exploit is super quick and dirty. It can parse the output from the game and grab the seed using mt19937predict: predictor = MT19937Predictor() for _ in range(511): (a, b) = read_names(i) predictor.setrandbits(a, 32) predictor.setrandbits(b, 32) (and yes, this is probably the first time I've ever written a Python solution!) Then does a final validation on your opponent's name to make sure the solution is working: (_, actual) = read_names(i) first_actual = FIRST_NAMES[actual & 0x0000FFFF] last_actual = LAST_NAMES[actual >> 16] final_name_actual = "%s %s" % (first_actual, last_actual) print("Validating...") print(" -> Final name (predicted):", final_name_predicted) print(" -> Final name (actual): ", final_name_actual) assert(final_name_predicted == final_name_actual) And prints out the 10 words that will be chosen: for i in range(10, 0, -1): word = predictor.getrandbits(32) print("Round %d: %s" % (10 - i + 1, WORDS[word & 0xFFFF])) # Waste RNG cycles for _ in range(1, (2**i) >> 1): predictor.getrandbits(64) To use it, I just connect to the game and tee the outpu
Envoyé Oui
Condensat /hangman /solution /tmp/hangman 0x0000ffff 0xffff 0xffffffff 1023 1024th 10: 2**i 2020 2021 210 511 624 ================================ able actual actually adedamola adrianna agregado aliecia all and another are are: around assert author avowing bad ballenger battle battleship beat because bit boehmer brackets: brendaliz bsides bsidessf build built bunch but can carleen carmellia carrick cassity challenge check chenna chhangte choose choosing chosen: christophersen code coding conclusion congratulations connect consume continue contrived copy count cpu ctf cycles deciding def defeat did dirty does don each easy else end ended enough enter ever everybody everything exploit fairly file file: final finally first flag: folks for francisco from full future game gelbert generate get getrandbits gettinger gifted going good got gotten grab graydon guess guesses hack had hangman happen hareth hemali here holiday hooray hopefully hoping how hypocoristic idea implementation including integer into janine jeegar jinnie jitlada josipa just karthic kebede khalif knowing knutsen kottwitz lancepesade last leak least let letter list little longer love luck lumbang made madela main mairtin make many map match mean means mega meirina menu mersenne misuse more mt19937 mt19937predict mt19937predict: mt19937predictor murnaghan musicalizing name names newfield not number numbers numbers: off once online opponent opponents originally others out output outputs overall pair parse paste patience pawlowski perlow picks piedrahita play player players powering predict predictable predicted predictions: predictor press print prints prize prng probably prompts pseudobranchiate python quick rachella racuya rand random range read really reasonable reasons recover remember return right rng round rounds rounds: royale ruby run saltarelli san saravana see seed sellers sense setrandbits sheneen simple single solution solution: solve solved some special start state still stroppier super sure surprised teams tee ten that the them then there thing thing: this throw time trapanned tresvalles turn turns twice twister txt type unusual ups upto use used uses using utricularia validating validation victory vjeran vulnerability wahono want wanted was waste welcome when where which whole will willyanto win window winston with without won word words working: would wow writeup writeup: written wrong yes you your
Tags Hack Prediction
Stories
Notes ★★★★
Move


L'article ne semble pas avoir été repris aprés sa publication.


L'article ne semble pas avoir été repris sur un précédent.
My email: