Full Disclosure mailing list archives

Legends of IdleOn - I Reject Your RNG And Substitute My Own


From: Soatok Dreamseeker <soatok.dhole () gmail com>
Date: Tue, 16 Jan 2024 16:29:25 -0500

Hello Full Disclosure mailing list!

Legends of IdleOn is a popular free-to-play game on Android, iOS, Steam,
and Web. While playing around with it last year, I got curious and noticed
a trivial way to manipulate the random number generator.

After six months of radio silence from the developer, including asking the
Discord moderators for help getting the developer's attention, I've decided
to publish this publicly:

https://gist.github.com/soatok/3cbf09501d1fd9e67e552c7165b0e81a

Disclosure Timeline

Note: All dates are in YYYY-MM-DD format (as per ISO 8601 and other
standards).
*Date* *Action*
2023-07-06 Emailed lava at lavaflame2 dot com with these details and a
recommended fix.
2023-08-06 A month later, I follow up just asking if Lava has received my
messages.
2023-11-15 Additional follow-up email
2023-11-15 Mentioned knowing an exploit in Discord, passed details onto
moderator (*Hotair*)
2023-11-15 Additional follow-up email (as I cannot DM lava)
2024-01-16 Given a lack of repsonse after more than 6 months, public
disclosure.

Screenshots are also available <https://imgur.com/gallery/aMrpl5y> for some
of my outreach attempts.
<https://gist.github.com/soatok/3cbf09501d1fd9e67e552c7165b0e81a#exploit>
Exploit

This is easiest to do in the browser version of the game. You can use a
Google Account for both Steam and Web in order to load an existing account
in the web mode. Easy peasy.

Press F12 to open your developer tools. Run the following code:

// Make a native copy of your browser's Math.random
functionMath.originalRandom = Math.random
// Now replace itMath.random = () => Math.originalRandom() / 100000000000;

Open the Arcade. Press Launch. Notice all of the balls always fall to the
right. You can score unlimited jackpots.

There are some other use cases where you want high numbers. There are yet
others where you want to pingpong between high and low numbers for the
desired effect.

Math.originalRandom = Math.random;Math.lowRandom = function() {
    return Math.originalRandom() / 100000000000;}
Math.highRandom = function() {
    return 1 - Math.lowRandom();}

let breakCycle = false;function luckyCycle() {
  return setTimeout(function() {
    if (breakCycle) return;
    // console.log('rng on');
    Math.random = Math.lowRandom;
    return setTimeout(function() {
      //console.log('rng off');
      Math.random = Math.highRandom;
      return setTimeout(luckyCycle, 30000);
    }, 30000);
  });}

Then you can just Math.random = /* desired other function, such as
Math.lowRandom */ your way to winning big.
<https://gist.github.com/soatok/3cbf09501d1fd9e67e552c7165b0e81a#impact>
Impact

   - Millions of Gems <https://imgur.com/gallery/xR4Ie9o>
   - See https://soatok.idleonefficiency.com for what controlling RNG
   outputs looks like on an account

<https://gist.github.com/soatok/3cbf09501d1fd9e67e552c7165b0e81a#mitigation>
Mitigation

Lava could mitigate this risk with one line of code, followed by a search
and replace:

+ const LavaMath = Object.freeze(Math)

And then replace any calls to Math.random with LavaMath.random, and then
this would no longer be possible.

(Yes, I included this one-liner in my email to Lava in July 2023.)
<https://gist.github.com/soatok/3cbf09501d1fd9e67e552c7165b0e81a#advanced-exploit>Advanced
Exploit

Compile Chromium with a custom RNG that returns a low value (less than
0.000001) 9/10 times, then defers to the normal LCG the rest of the time.
You'll win most luck-based things (Arcade Balls, Gaming Plants, etc.).

The mitigation I suggest doesn't defend against this, but using a secure
RNG instead of Math.random would likely generate farier numers *anyway*.
<https://gist.github.com/soatok/3cbf09501d1fd9e67e552c7165b0e81a#update>
Update

The /r/idleon mods censored the link to this Gist from their subreddit
<https://old.reddit.com/r/idleon/comments/197ypyv/legends_of_idleon_rng_manipulation/ki3xind/?context=4>
(Archive
<https://web.archive.org/web/20240116112102/https://old.reddit.com/r/idleon/comments/197ypyv/legends_of_idleon_rng_manipulation/>
).

The actual exploit code that makes this an easy win is not included in this
disclosure, but a clever mind can concoct their own with minimal iteration.

After this disclosure, their community response has been limited to:

   1. Censoring my post from Reddit
   2. Falsely flagging my Steam Community post as an advertisement
   3. Angry Discord PMs from people who think my goal is to "enable
   cheating"

That does not include:

   1. Mitigating the issue
   2. Acknowledging the receipt of any of my attempts to disclose privately
   3. Any communication whatsoever

They have not succeeded in censoring my GitHub Gist, nor my review on the
Steam store that links to my Gist, but that may be in the works.

Thus, I thought I'd share it with Full Disclosure (with additional
context). All URLs are also archived on archive.org and archive.today,
should they attempt to invoke the Streisand Effect.

Happy hacking,
Soatok
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/


Current thread: