Is Math.random() Safe? from missing rate limit to bypass 2fa and possible sqli

neroli.medium.com · kh4sh3i/bug-bounty-writeups · 22 hours ago · vulnerability
quality 7/10 · good
0 net
AI Summary

Researcher demonstrates chaining missing rate limits with Math.random() predictability via race conditions to bypass 2FA OTP validation in a Node.js-based React-Native mobile application, combined with SQL injection in the OTP endpoint affecting multiple authentication flows.

Entities
Yasser Mohammed HackerOne React-Native Math.random() Turbo Intruder Burp Suite OWASP
Is Math.random() Safe? from missing rate limit to bypass 2fa and possible sqli | by Yasser Mohammed (@n3r0li) - Freedium Milestone: 20GB Reached We’ve reached 20GB of stored data — thank you for helping us grow! Patreon Ko-fi Liberapay Close < Go to the original Is Math.random() Safe? from missing rate limit to bypass 2fa and possible sqli Hi everyone It's Yasser Again, Yasser Mohammed (@n3r0li) Follow ~4 min read · February 20, 2021 (Updated: December 31, 2021) · Free: Yes First of all i wanted to thank you all for sharing my last write-up and I got a lot of positive responses so I decided to write about another nice finding that i found lately. I was testing a mobile application which was written in React-Native for private program on HackerOne about 5 months ago, While my server-side testing I didn't found a lot of functions but as always I was working on developing a similar application as school project, and i got some problems with Synchronization, so while testing 2fa functionality I was asked to confirm the OTP which was sent to my phone number, so let's see if the back end is going to crash if we sent a lot of requests, So using the intruder i sent a lot of requests and waited for the corresponding messages to fill my phone with many OTPs and yeah I got a lot of confirmation codes, this is a missing rate limit but i never submit it if I didn't got high impact scenario from it, remembering that while I was developing my application I had to use Math.random() to generate these codes, but is it really that random ?? pseudo-randoms Let's have a closer look on how this function works, we cannot generate a pure random numbers since there is a lot of factors that could affect our randomization process which can make is so predictable, and that's what is called pseudo-random , it's so unpredictable but it's not impossible since it depends on something called seed , to understand how is it working this video is so useful as in the video the if we inserted 2 duplicate seed's into math.random we will get the same sequence, so if i was able to use this seed and send the request at the same time I will be able to guess the OTP, but this is soo hard to implement since it depends on the system clock on the server and my system clock. Synchronous vs Asynchronous the server was using asynchronous functions to handle our requests you can read this great article to understand how does js synchronous/asynchronous works, shortly synchronous means if we run this code: const second = () => { console.log('Hello there!'); }const first = () => { console.log('Hi there!'); second(); console.log('The End'); }first(); the output will be: Hi there! Hello there! The End since the call stack got to execute function first and stop until the code in the function second executed then back to execute the rest of function first in asynchronous we can execute 2 functions as above but the 2 functions will be executed in parallel with no blocking, read the above article for more details. Exploitation in this case our answer is simple , Race-Condition using turbo intruder in burp with this race condition script I will be able to send multiple requests in the same time so it will be executed on the server in the same time so we will call Math.random() many times this could give us a duplicate result in if the length of the result is not too long, here is a sample for a vulnerable code written in nodejs var http = require("http"); async function asyncCall() { var x = Math.floor(Math.random() * 1000).toString(); return x; } http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); asyncCall().then((value) =>{ console.log(value); response.end(value); }); }).listen(8081); with sample turbo intruder script: def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=30, requestsPerConnection=100, pipeline=False ) for i in range(30): engine.queue(target.req, "", gate='race1') engine.openGate('race1') engine.complete(timeout=60) def handleResponse(req, interesting): table.add(req) we will notice that we got duplicate numbers POC Notes this scenario have a lot of aspects and depends on a lot of things to apply a successful Attack Like: length of the OTP internet connection speed number of requests concurrent Connections the back-end framework this slide by OWASP is so useful to understand the attack more concurrency Vulnerabilities Life Example (Exposing the OTP and sqli) applying the above steps on the target leads to expose the OTP Generated code but the reason why we got a valid Code is that the query inserts our user_id which is the primary key in this case so we got a valid OTP SQL error And as always I was like I noticed that phone number was not being validated well which lead to sqli. this endpoint was responsible for all the OTP generation in the whole application so 2fa, number confirmation, reset password ..etc I hope u enjoyed and thanks for reading again. References Google Chrome Attack http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html https://www.veracode.com/security/race-condition https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff https://www.youtube.com/watch?v=GtOt7EBNEwQ concurrency Vulnerabilities #javascript #race-condition #2fa #bugsbounty #react-native Reporting a Problem Sometimes we have problems displaying some Medium posts. If you have a problem that some images aren't loading - try using VPN. Probably you have problem with access to Medium CDN (or fucking Cloudflare's bot detection algorithms are blocking you).