Automating Multi-Factor Authentication: Time-Based One-Time Passwords
Two days ago marks my two years with Rapid7. It has been a fantastic adventure, and I’m quite excited to celebrate today by enabling our AppSec customers on automated time-based one-time password (TOTP) authentication. For you folks who used to wake up at 2 a.m. to Bootstrap into a scheduled scan with multi-factor authentication (MFA), we can celebrate with some shut-eye!
Multi-factor authentication
When logging onto a web application, you may be required to present a username and a password to log in to the site. This is considered “one-factor,” as this combination authenticates you to the application.
In many cases, passwords can be lost or stolen, so multi-factor authentication was developed (often called “MFA,” 2FA,” or “two-factor authentication”).
MFA adds an additional step to your login, such as presenting a hardware key, receiving a text message, or typing in a code from an app on your phone. Today, we’re going to discuss the phone app model.
Time-based one-time password
Often called TOTP, this is simply a code that you will enter after logging in. Every few seconds, the code will expire and cannot be used to login again. It uses a secret code and your system’s clock to generate this code. Only you and the website you’re logging into know this code, so nobody else can generate these codes (unless you leak them!)
Tools we’ll use today
- Rapid7’s Pen Testing Extension: A tool we use with InsightAppSec to enable recording “macros,” an extensible authentication tool used to allow scanning of your applications.
- AuthenticationTest.com: A playground of sorts for practicing automated authentication (such as MFA, drop-down fields, and so on).
- AuthenticationTest’s TOTP App: An online TOTP API that returns the code in a JSON formatted string (easy to parse!).
Our goal
We want to go to Authentication Test’s TOTP Challenge, collect our secret key, and build a macro that allows automatic population of the username, password, and the MFA code to allow us to log in.
Step 1: Create an account on your application
In the case of authenticationtest.com, you won’t need a login, but in most applications, you must create an account to get the secret code that is used to “seed” the authenticator app.
Step 2: Record a macro using the penetration testing kit
- Download and Install the Rapid7 Penetration Testing Kit Extension
- Navigate to the Authentication Test TOTP Challenge
- Either use Google Authenticator App or another app to enroll to complete the code, or simply get it wrong while recording the macro.
If you’ve never created a macro before, here’s a quick overview of the process:
- Navigate to the page you want to record (https://authenticationtest.com/totpChallenge/)
- Open the extension by clicking the silhouette
- Click “Macro Recorder”
- Click “Record Authentication Sequence”
- (A new window will pop up. Hit “OK” on the dialog, then log in as normal, clicking in each field instead of using tab)
- When done, close the window (don’t log out)
- Go back to the extension, again click Macro Recorder, and then follow Step 3 below
Step 3: Modify the macro to leverage Javascript events
Natively, most Dynamic Application Security Testing (DAST) tools will leverage simple events that playback and log in to a site. InsightAppSec, Rapid7’s DAST solution, can execute Javascript within events to authenticate.
Scroll down until you see the instruction that fills the TOTP field:
RED (SetControlData): This tells the tool to modify the text of the MFA field
YELLOW (912351): This is the code I entered while recording the macro (and would be the value we’d play back in the future)
BLUE (totpmfa): This is the ID of the field we’ll set the code to.
We’re going to change this to a javascript event by modifying some fields:
- Change the “Set Control Data” to “Javascript”
- Change the Element Path to <![CDATA[]]
- Change the Data to include this script within the CDATA field (see the screenshot below)
Here’s the javascript we’re using:
var secret = "I65VU7K5ZQL7WB4E";
var formID = "totpmfa";
const http = new XMLHttpRequest();
http.open("GET","https://authenticationtest.com/totp/?secret="+secret);
http.send();
http.onreadystatechange=(e)=>{
var retVal = JSON.parse(http.responseText);
document.getElementById(formID).value = retVal.code;
}
This javascript collects the TOTP secret (that you gathered when you signed up to your application). It also uses the ID of the element on the page.
We’ll dynamically fire off a GET request to the TOTP Authenticator App built into Authentication Test, in this case:
https://authenticationtest.com/totp/?secret=I65VU7K5ZQL7WB4E
Which will return something similar to:
{
"code": "307405"
}
Next, we’ll parse that into an object, and grab the “code” property.
Finally, we’ll take that “code” property (in this case, 307405) and enter that into the form field with the ID you specified.
But wait … there’s more!
Yeah, GET requests aren’t great for secrets, which is why you can send a POST request, too:
var secret = "I65VU7K5ZQL7WB4E";
var formID = "totpmfa";
const http = new XMLHttpRequest();
http.open("POST","https://authenticationtest.com/totp/",true);
http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
http.send("secret="+secret);
http.onreadystatechange=(e)=>{
var retVal = JSON.parse(http.responseText);
document.getElementById(formID).value = retVal.code;
}
(POST request will return the same response as GET request)
Step 4: Test the macro by playing back
Reopen the Penetration Testing Kit. After modifying the event where we send the TOTP, click “playback” and see if it logs in.
REMEMBER: The first “T” in “TOTP” is “time-based.” If you have too many delays between the time we grab this value and the time we click “login,” it may have expired. For this reason, it may make sense to do this event last, just before submitting the form. You can add the “secret” to Google Authenticator and watch the code there to see if it expires first.
Step 5: Download a trial of InsightAppSec and see how it works for your application
Checking if it works with the Penetration Testing Kit extension is great—now let’s see if you’re vulnerable. Download the 30-day free trial of InsightAppSec to find out. Want to get up and running with TOTP apps and DAST scans? Make sure you ask your Account Executive about Rapid7’s Product Security Consulting team!
Start a free trial of InsightAppSec today
Get Started