All Collections
Quick how to's!
Authentication
How to set up Target 2FA using an alternative OTP
How to set up Target 2FA using an alternative OTP

Learn how to set up the scanner to log in to targets with Two-Factor Authentication (2FA) using an alternative One-time Password (OTP).

Jaime Vasconcelos avatar
Written by Jaime Vasconcelos
Updated over a week ago

Two-factor authentication (2FA) strengthens authentication with an additional layer of security that requires presenting an extra piece of evidence (the factor) to an authentication mechanism of a website or application. To obtain that factor, a random code is sent through a communication channel like an email or a text message. This random code is called One-time Password (OTP).

In Probely, you can scan websites or applications using 2FA by configuring the Other OTP option under the TWO-FACTOR AUTHENTICATION (2FA) section of your target settings.

Probely also allows you to set up 2FA with a Time-based One-time Password (TOPT). To learn more about it, read this article on how to set up Target 2FA with TOTP.

After setting up your target authentication with Login Form or Login Sequence, the configuration of 2FA with an alternative OTP involves three steps:

  1. Obtain information on the 2FA form of the website or application.

  2. Configure 2FA in Probely for the respective target.

  3. Communicate the OTP to Probely when requested by your 2FA.

This article describes these steps in detail.

Step 1: Obtain information on the 2FA form

The configuration of 2FA with OTP requires the CSS selectors of the 2FA form of the website or application so that Probely can use the OTP code to log in. As such, you must obtain the following information:

  • The CSS selector of the input widget of the OTP code.
    For example, .2fa-input.

  • The CSS selector of the submit button.
    For example, .2fa-submit-button

If you need to, you can read this article about how to obtain CSS selectors.

Step 2: Configure 2FA in Probely

With the information obtained in Step 1, configure 2FA with OTP in Probely as follows:

  1. Go to the target settings.

  2. Select the AUTHENTICATION tab.

  3. Go to the TWO-FACTOR AUTHENTICATION (2FA) section and select Other OTP at the top.

    This configuration is the same, regardless of whether you use authentication with a Login Form or a Login Sequence. In both cases, you'll need to provide the CSS selectors of the widgets of your 2FA login form obtained in Step 1.

Step 3: Communicate the OTP to Probely

With the 2FA configured on the target settings, you will need to implement the communication of the OTP to Probely when requesting the 2FA in your website or application. It must be done by calling an endpoint from the Probely API where you must send the OTP in the request body.

Here is an example in curl:

curl -X POST '<UNIQUE 2FA CONFIGURATION URL>' \
-H 'Content-type: application/json' \
-d '{"otp": "<OTP>"}'

Where:

  • <UNIQUE 2FA CONFIGURATION URL> is the URL provided under the UNIQUE 2FA CONFIGURATION URL of your target settings.

  • <OTP> is the OTP to send to Probely to authenticate in your 2FA.

If you send the OTP by email to the user that logs in to the target during the scan and that user has a Gmail account, we suggest using Google Script. You can create a script that polls emails from the Gmail account, extracts the OTP, and sends it to Probely (using the API endpoint) for the scan to pass your 2FA.

To do so, follow these steps:

  1. Go to https://script.google.com of the Gmail account, select My Projects, and click on CREATE APPS SCRIPT.

  2. At the top of the page, click on the project name “Untitled Project” and type a meaningful name like, for example: “Get OTPs from Emails”.

  3. Then, in the Code.gs file, replace the default myFunction function in the script with the following functions:

    function runTask() {
    // Configuration
    var API_ENDPOINT = `<UNIQUE 2FA CONFIGURATION URL>`;
    // In this example, SUBJECT_MATCH has a static email subject, but
    // it can also be a regular expression.
    var SUBJECT_MATCH = 'verification code';
    // In this example, INBOX_SEARCH_FILTER is a filter for unread
    // emails in the inbox that were received in the last hour with
    // the defined subject.
    var INBOX_SEARCH_FILTER = `is:unread newer_than:1h in:inbox subject:(${SUBJECT_MATCH})`;
    // In this example, OTP_REGEXP_MATCH has a regular expression with:
    // * A first group for parsing to where the OTP starts.
    // * A second group for parsing the OTP.
    // * A third group for parsing the rest of the email body.
    var OTP_REGEXP_MATCH = '^(.* code is: )([0-9]{6})(.*)';

    var nrUnread = GmailApp.getInboxUnreadCount();
    Logger.log(`Unread messages: ${nrUnread}`);
    if (nrUnread === 0) {
    Logger.log('No unread messages');
    return;
    }
    var threads = GmailApp.search(INBOX_SEARCH_FILTER);
    if (threads.length === 0) {
    Logger.log('No threads matching the filter');
    return;
    }
    Logger.log(`Threads matching the filter: ${threads.length}`);
    var reIsOTP = new RegExp(SUBJECT_MATCH, 'i');
    var reExtractOTP = new RegExp(OTP_REGEXP_MATCH, 'im');
    for (var i = 0; i < threads.length; i++) {
    var subject = threads[i].getFirstMessageSubject();
    if (reIsOTP.test(subject)) {
    var messages = threads[i].getMessages();
    for (var j = 0; j < messages.length; j++) {
    if (messages[j].isUnread() === false) {
    continue;
    }
    var body = messages[j].getBody();
    Logger.log(body)
    var match = body.match(reExtractOTP);
    // The following two lines of code depend on the position
    // of the OTP in the regular expression defined in
    // OTP_REGEXP_MATCH. So, review this code if you change
    // the position of the OTP in the regular expression.
    if (match && match.length > 2) {
    const extractedOTP = match[2];
    Logger.log(`Extracted OTP: ${extractedOTP}`);
    var postOptions = {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    },
    payload: JSON.stringify({
    otp: extractedOTP,
    })
    };
    var response = UrlFetchApp.fetch(API_ENDPOINT, postOptions);
    Logger.log(`API Response :: ${response}`);
    messages[j].markRead(); // Set message as read
    return;
    }
    }
    }
    }
    }

    function extractOTPFunction() {
    runTask();
    Utilities.sleep(15 * 1000);
    runTask();
    Utilities.sleep(15 * 1000);
    runTask();
    Utilities.sleep(15 * 1000);
    runTask();
    }

  4. In the runTask function, customize the following:

    1. API_ENDPOINT

      This is the API endpoint to send the OTP to Probely.

      Replace <UNIQUE 2FA CONFIGURATION URL> with the URL provided by Probely in the UNIQUE 2FA CONFIGURATION URL of your target settings, as described in step 2.

    2. SUBJECT_MATCH

      This is the string of the email subject to parse emails with the OTP.

      Customize it with a static string of the email subject. Alternatively, you can also use a regular expression (with impact on point c.).

    3. INBOX_SEARCH_FILTER

      This filter selects which emails to parse in the inbox to exclude emails with old OTPs from the list.

      If SUBJECT_MATCH was configured with a regular expression, you must remove SUBJECT_MATCH from this filter.

    4. OTP_REGEXP_MATCH

      This is the regular expression used to extract the OTP from the email body.

      Configure the regular expression that parses the content of the email body to get the OTP. If the OTP position changes in the regular expression, review the following lines in the script and adjust the index of the OTP:

              // The following two lines of code depend on the position 
      // of the OTP in the regular expression defined in
      // OTP_REGEXP_MATCH. So, review this code if you change
      // the position of the OTP in the regular expression.
      if (match && match.length > 2) {
      const extractedOTP = match[2];

  5. Save the scripts.

  6. To run the scripts regularly and parse emails, go to Triggers, and click on Add Trigger:

  7. Configure the trigger:

    Set the following values:

    1. In Choose which function to run, choose extractOTPFunction.

    2. In Select type of time based trigger, choose Minutes Timer.

    3. In Select minute interval, choose Every minute.

    4. In Failure notification settings, select Notify me immediately.

  8. Click on Save to activate the trigger.

    The trigger will execute the extractOTPFunction script every minute, which executes the runTask script four times per minute. This means emails will be checked and OTPs extracted in 15-second intervals.

With this configuration complete, Probely should be able to authenticate with 2FA and scan the target.

Read the following articles to learn more about other authentication options for your targets:

Did this answer your question?