🐙EASM for Dummies

EASM for dummies aims to be a GitOps Workflow environment that relies on Github Actions and Kubernetes to run CyberSecurity tools.

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 but could potentially be expanded in the future to add new ones.

TL;DR

By using Github Actions within the Kubernetes controller Github made named 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.

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.

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 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 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 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

How to install ARC at a k8s cluster

GitHub have all this pretty much covered from their quick start guide for ARC 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. Once we have the token issued we are ready to apply ARC with this helm commands.

Install ARC
NAMESPACE="arc-systems"
helm install arc \
    --namespace "${NAMESPACE}" \
    --create-namespace \
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
Install ARC Runner Set
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

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.

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:

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.

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:

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.

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.

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.

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.

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.

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 * * *"}]

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.

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

Last updated