# EASM for Dummies

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2Fot8CHjKam606kahZCQxM%2FEASM.png?alt=media&#x26;token=88de1fe1-f894-4d9c-97ff-a623053f8d52" alt="" width="375"><figcaption><p>EASM logo</p></figcaption></figure>

## What's all this about?

The idea was to have a friendly environment where to load my Cybersecurity setup and run them autonomously to test Bug Bounty. This could suit any blue/red team that wants either to monitor their own infrastructure or to monitor the scope their might be targeting.\
\
As for now its only using the following tools from [projectdiscovery](https://projectdiscovery.io/) but could potentially be expanded in the future to add new ones.

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2F36Enl5roa7jSKUmOjCWU%2Fimage.png?alt=media&#x26;token=7e6e4344-c112-41df-9b4d-a69e20950077" alt="" width="162"><figcaption><p>tools added</p></figcaption></figure>

## TL;DR

{% embed url="<https://docs.google.com/presentation/d/1T3UV9YYFSyGqr-U0C-39FqgchR-o0vSOlxMVJIpu65w/edit#slide=id.p>" %}

By using Github Actions within the Kubernetes controller Github made named [Actions Runner Controller](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners-with-actions-runner-controller) (ARC) in a Kubernetes Kubernetes cluster we are able to adjust the workload size on demand defining custom scheduled tasks that would essentially parallelize the tools we want to run and split the input we provide and merge the results once they are done. All this in a fancy GitOps style that gives you the flexibility of having different setups depending on the environment and having notifications on new findings or even in case of an error. Moreover this setup gives the possibility to run this tools as if you were running them locally.

## Requirements & Set Up

First of all we need a somewhere to run our pipelines, due to the flexibility Github Actions give us for self-hosted runners it could be either a self-hosted VPS in a cloud provider or either our own personal computer, more info is [here](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners).

There are three options we can take if we want to run applications with Github Actions, and they are:

**Github-hosted runners** is the first one, but unfortunately discarded because scanning the internet with Github infrastructure is not allowed, more info about this in the [Github Terms of Service](https://docs.github.com/en/site-policy/github-terms).

**Self-hosted runner** is the second option, in which you will provide typically a VM or your own computer and add it as a runner to the project, the only issue about it is that runners are only allowed to run one job at a time. To add your computer as a self-hosted runner follow [this](https://docs.github.com/en/enterprise-cloud@latest/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners) guide.

**Self-hosted runner in a k8s cluster** is the one I am about to show up here in which we need to set up some things. But take it easy, it could also run in your computer without paying any extra money to a cloud provider on a local kubernetes cluster.

The very first thing we need to do is to set up a k8s cluster somewhere, it could simply be a [Minikube](https://minikube.sigs.k8s.io/) on your localhost.

### Set Up your own fork of EASM repo

You need to have the repo where you are going to manage the scans and where the runners are going to be synced and for that you can simply fork the [amocsub/EASM](https://github.com/amocsub/EASM) repository and start from that as a scratch.

At your repository **${GITHUB\_USER}/EASM** we need to enable some things first. We need to grant Github Actions Workflows **Read & Write** permissions on the repo and that can be changed at **<https://github.com/${GITHUB\\_USER}/EASM/settings/actions>**

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2FmLCkVlCtX4FM6USog9vs%2Fimage.png?alt=media&#x26;token=15315e0f-c36c-4f53-b3ff-dc4dcf1e5a01" alt=""><figcaption><p>workflow read &#x26; write permissions</p></figcaption></figure>

### How to install ARC at a k8s cluster

GitHub have all this pretty much covered from their quick start[ guide for ARC](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners-with-actions-runner-controller/quickstart-for-actions-runner-controller) but just in case I will leave here the commands I used to get everything up and fast.

First of all we need to follow the guide [authenticate ARC with a personal access token classic](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners-with-actions-runner-controller/authenticating-to-the-github-api#authenticating-arc-with-a-personal-access-token-classic). Once we have the token issued we are ready to apply ARC with this helm commands.

{% code title="Install ARC" overflow="wrap" %}

```bash
NAMESPACE="arc-systems"
helm install arc \
    --namespace "${NAMESPACE}" \
    --create-namespace \
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
```

{% endcode %}

{% code title="Install ARC Runner Set" overflow="wrap" %}

```bash
INSTALLATION_NAME="arc-runner-set"
NAMESPACE="arc-runners"
GITHUB_CONFIG_URL="https://github.com/<GITHUB_USER>/<GITHUB_REPO>" # <= REPLACE
GITHUB_PAT="<PERSONAL_ACCESS_TOKEN>" # <= REPLACE
helm install "${INSTALLATION_NAME}" \
    --namespace "${NAMESPACE}" \
    --create-namespace \
    --set maxRunners=10 \
    --set minRunners=0 \
    --set containerMode.type="dind" \
    --set githubConfigUrl="${GITHUB_CONFIG_URL}" \
    --set githubConfigSecret.github_token="${GITHUB_PAT}" \
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set
```

{% endcode %}

## Ok, enough set up. What's all this about?

At this moment you are good to create some scans. **EASM** aims to be a single point to run workflows to make some tasks easier or at least more hacky.

It's strongly recommended to leave the **^main** branch untouched and create as many branches as targets you want, for an example there are 2 branches referencing BugBounty programs taken from the [Hackerone Public directory](https://hackerone.com/directory/programs).

The actions would take the data from the branch you specify and push data back to that particular branch for each of the tasks, it should look as the following:

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2FRq7XJlJga91gtR2e91Pg%2Fimage.png?alt=media&#x26;token=58d9b413-6fba-4f0a-aa2d-aef93f993840" alt="" width="350"><figcaption></figcaption></figure>

So whenever you go to actions you can trigger manually the tools and specify several parameters for each of them, at this point **easm** aims to have several config files for each of the tools and for each of the environments.

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2FYm9LDZntQ29w4MDbowtA%2Fscreenshot.jpg?alt=media&#x26;token=a08dcbe3-2272-4ac5-8e12-0fc01bbea475" alt=""><figcaption></figcaption></figure>

The config files are organized so you can have several folders for each of the environments, by default there is a config set up as the following:

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2FBe6Qp5rF8XHFg0oeIOsB%2Fimage.png?alt=media&#x26;token=70107f2a-70c5-44fd-8480-fbe5d15910b8" alt=""><figcaption><p>tree output</p></figcaption></figure>

The folder **config/nuclei/nuclei-templates** can be updated automatically on a schedule defined in a GitHub action that would fetch changes on [projectdiscovery/nuclei-templates](https://github.com/projectdiscovery/nuclei-templates).

Custom nuclei templates are going to be automatically added on runtime for the nuclei workflow if you upload them to the folder **config/nuclei/custom-nuclei-templates.** At runtime at the nuclei action that folder is copied into **config/nuclei/nuclei-templates** so them can be accessed within the normal ones too.

#### Edit from here

Every workflow is very descriptive, and the run can split the input tasks in several pods that are dynamically created. You can update the autoscaler values **up to 256**, which is the maximum limit of a matrix to split a singular job, more info [here](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs).

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2FtZ191RzIe1PvKvbKtvO8%2Fimage.png?alt=media&#x26;token=f3754826-94f6-4433-91f1-6bce22240903" alt=""><figcaption><p>action finished</p></figcaption></figure>

As an extra you can also download the artifacts that were generated on the steps to troubleshoot them manually on your local computer if you see something went wrong or you want to do something extra with it. Have in mind that artifacts are set up to be stores for only one day so we you don't create that much files in Github.

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2Fya6UeYSeQD3jXMx6ycD6%2Fimage.png?alt=media&#x26;token=1800a1ce-c926-40e8-a282-b7b8f1c298be" alt=""><figcaption><p>action in progress</p></figcaption></figure>

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2Ftf3RbDedPW24BQIJKt2Q%2Fimage.png?alt=media&#x26;token=c041f2a4-1d94-4aab-80a7-261110ea639d" alt=""><figcaption><p>log trace of the action run</p></figcaption></figure>

## Lets analyse some use cases

There is no perfect way of setting up this tool, ideally you would like to have the programs scope you want to target all together in one Github branch. At the image below there are some examples of this cases.&#x20;

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2FZ2PtfzM5tmH7TEk3G1ty%2Fimage.png?alt=media&#x26;token=c5e2ba73-4705-4ac2-8f88-32b1c3e9dfcc" alt=""><figcaption><p>idea of a set-up</p></figcaption></figure>

And using the schedule from the actions you can set up different schedules for each of the scopes, you can do that by un-commenting the **schedule** tag from the yaml files in the actions definition.

{% code overflow="wrap" %}

```yaml
name: "nuclei"

on:
  workflow_dispatch:
    inputs:
      input_filename:
        default: "input/nuclei-input"
        description: "File name with all the urls to scan"
      output_filename:
        default: "output/nuclei-output"
        description: "Where to put the results"
      amount_of_workers:
        default: "1"
        description: "How many workers should be used, max 256 per matrix"
      config_folder:
        default: "config/nuclei/general/*"
        description: "Folder containing nuclei configurations files"
  # schedule: [{"cron": "0 0 * * *"}]
```

{% endcode %}

A simple workflow interaction can be seen in the following image, where you can see that youa are only going to be using runners on demand.

<figure><img src="https://3143345133-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRwfEQPPcB1ACLB9HVEOP%2Fuploads%2F29OdMLR7QP2AxdlgOKYw%2Fimage.png?alt=media&#x26;token=5d72d7ce-9f0d-4c65-bdbf-7e570853c988" alt=""><figcaption></figcaption></figure>

## Further Improvements or ideas...

* Notify on new findings for each of the steps
  * A new subdomain discovered
  * A new port listening on a host
  * A new vulnerability in a host
* Add extra tools...
* Adoption of Github Mobile App for interacting with the Workflows
* Adopt ways of notifying with other Github Actions
  * Telegram
  * Discord<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://amocsub.gitbook.io/blog/posts/easm-for-dummies.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
