Tag Archives: bug bounty

yes you should use a vps for bug bounty hunting

Bug Bounty VPS Box Part 2

Yes, you need a bug bounty VPS. Why you may ask? Well here is a list of reasons why.

Bypassing Bans

The truth of the matter is that you’ll likely get banned from sites, or even whole IP blocks, for malicious scanning and/or excessive scanning (i.e. scanning too quickly). Sure, you can likely hack away just fine on a single site manually with Burp from the comfort of your personal computer. But if you’re firing up a scanner, you better think twice. Use a VPS.

Callbacks

Sure, there are a lot of tools out there for long term callbacks like interactsh or bxss, but short term, it may be just easier to use a current server you are SSHd into. You got a blind XSS and you want to load a payload from your server to show impact? Just tail your web server logs.

I’ve even went so far as to deploy my own private Burp Collaborator instance as detailed here – https://portswigger.net/burp/documentation/collaborator/server/private

POCs

If you’re behind NAT on your home network, it’s gonna be hard to connect back to a listener if you somehow got an RCE on a network.

Or maybe you have a CORS bug or Postmesssage XSS and you need to host a POC somewhere. Sure you could forward ports from your router and fiddle around all day, but trust me, it’s way easier to just fire up a $5/month box on Linode and let it run 24/7.

Vertical and Horizontal Scaling Your Bug Bounty VPS Setup

Despite what a lot of people may tell you, essentially all of the leading bug bounty hunters do some sort of mass scanning. Now, with that said, they all do it to a different degree.

Automation is especially essential if you plan on making bug bounty hunting a source of passive, steady, and significant income. But you can’t do all of that without scaling. You need to scan more things faster which requires larger instances and greater numbers of them. Eventually your lowly desktop PC cannot handle all of this work.

For this you’d want to use axiom, or similar tooling.

Experience

This is underrated. No matter if you’re a IT professional with a ‘real’ job or a beginning bug bounty hunter, experience with cloud providers is invaluable. Deploying a server on AWS, Azure, or Linode (my choice for bug hunting) is valuable experience.

So?

Yes, you need a bug bounty VPS. Just use one. They’re cheap. You can even use this link and get a $100 credit at Linode, so it’s essentially free for a while too, haha.

Deploying and Configuring a Bug Bounty Box with Terraform and Ansible

Prerequisites and Getting Started

I sometimes like to spin up a virutal machine in the cloud, do some testing, and then tear it down. It doesn’t even have to be for bug bounty hunting, but since I’ve been hunting so sporadically lately, that’s what I’ve been using this project for.

Anyway, it becomes tedious to do this repeatedly, so I decided to automate a large majority of the infrastructure creation and configuration with Terraform and Ansible.

In the following article, I’ll deploy a node on Linode, my VPS provider of choice. Use this referral link for a $100, 60-day credit. That way, you can test this project out until you’re blue in the face. The node size I deploy in this post runs $10 a month.

While Terraform and Ansible can both accomplish the same things, they both have their wheel houses. Terraform should be used for deploying infrastructure and Ansible should be used to configure that infrastructure.

In order to follow along with this article, you’ll need to install Terraform and Ansible per your Operating System’s documentation. I’m using Ubuntu 20.10.

Let’s begin b creating a directory structure for your project.

mkdir -p ./bugbounty/{/terraform/templates,ansible}

Next, you’ll need to obtain credentials from Linode. If you haven’t already, create an account, then click on your account name in the top, right-hand corner and select “API Tokens.”

Select create an access token and give it a name. Select Linodes and Read/Write, and then click “Create Token.”

Linode Read/Write Access Token

The token will be a long string of characters. Save this token for usage in a bit!

Terraform

cd into the Terraform directory you just created and create the following files:

$ touch {main.tf,output.tf,variables.tf,variables.tfvars}

The main.tf file is where the magic is done. This file will create the VM to our specifications. The variables.tf file declares variables that are used in main.tf. variables.tfvars will have the initializing values for these variables. You can also initialize the variables directly in variables.tf or even on the command line, if you’d prefer. We do it this way because it makes updating variables slightly easier and our project simpler, in a sense. output.tf defines what values will be printed to the console after we run the project.

Next, create some templates within the templates directory.

touch {./templates/ansible.tmpl,./templates/playbook.tmpl,./templates/hosts}
main.tf

Copy the following code into main.tf:

terraform {
  required_providers {
    linode = {
      source  = "linode/linode"
      version = "1.27.0"
    }
  }
}

# Configure the Linode Provider
provider "linode" {
  token = var.token
}

# Create a Linode
resource "linode_instance" "bugbountybox" {
  image     = var.image
  label     = var.label
  region    = var.region
  type      = var.type
  root_pass = var.root_pass
}

# Create an Ansible playbook from a template file
resource "local_file" "bugbountybox_setup" {
  content = templatefile("./templates/playbook.tmpl",
    {
      ip_address = linode_instance.bugbountybox.ip_address
    }
  )
  file_permission = "0640"
  filename        = "../ansible/playbook.yml"
}

# Create an Ansible config from a template file. 
resource "local_file" "ansible_config" {
  content = templatefile("./templates/ansible.tmpl",
    {
      remote_user = "root"
    }
  )
  file_permission = "0640"
  filename        = "../ansible/ansible.cfg"
}

# Create an Ansible playbook from a template file
resource "local_file" "ansible_inventory" {
  content         = linode_instance.bugbountybox.ip_address
  file_permission = "0640"
  filename        = "../ansible/hosts"
}
variables.tf

Copy the following code into variables.tf:

variable "token" {
  type        = string
  description = "Linode APIv4 token."
  sensitive   = true
}

variable "image" {
  type        = string
  description = "Image to use for your VM."
  default     = "linode/ubuntu20.04"
}

variable "label" {
  type        = string
  description = "Label to give your VM."
}

variable "region" {
  type        = string
  description = "Region where the VM will be created."
}

variable "root_pass" {
  type        = string
  description = "Password for the root account on this VM."
  sensitive   = true
}

variable "type" {
  description = "Your Linode's plan type."
  # You can initialize variables here instead of the tfvars file. 
  default = "g6-standard-1"
}
variables.tfvars

Copy the following code into variables.tfvars, and enter the values as needed:

token     = "" # put your API token here. 
image     = "linode/ubuntu20.04"
label     = "bug-bounty-box"
region    = "us-east"
root_pass = "" # put your new VM's password here. 
output.tf

Copy the following code into output.tf:

output "IP_Address" {
  value = linode_instance.bugbountybox.ip_address
}

Templates

The templates will be used by Terraform to create files that Ansible will use. We could manually create/edit these Ansible files, but why do things manually when we can automate it?

Copy the following code into ansible.tmpl:

[defaults]
host_key_checking = False
remote_user = ${ remote_user }
ask_pass      = True

Copy the following code into playbook.tmpl:

---
- name: Update/upgrade and install packages on remote server.
  hosts: ${ ip_address }
  become: true
  tasks:
    - name: Update
      apt: update_cache=yes force_apt_get=yes cache_valid_time=3600

    - name: Upgrade all packages on servers
      apt: upgrade=dist force_apt_get=yes

    - name: Install packages
      apt:
        pkg:
          - ca-certificates
          - curl
          - apt-transport-https
          - lsb-release
          - gnupg
          - software-properties-common
          - python3-pip
          - unzip
          - tar
          - tmux
          - gobuster
          - wireguard
          - wireguard-tools
          - john
          - hashcat
          - nikto
          - ruby-full
          - ruby-railties
          - hydra
          - cewl
          - whois
          - squid
          - nmap
          - git
          - python3-impacket

        update_cache: true

    - name: Install Golang
      shell: |
        wget https://go.dev/dl/go1.18.linux-amd64.tar.gz
        tar -xvf go1.18.linux-amd64.tar.gz
        chown -R root:root ./go
        mv go /usr/local
        echo "export GOPATH=$HOME/go" >> $HOME/.bashrc
        echo "export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin" >> $HOME/.bashrc
      args:
        executable: /bin/bash

    - name: Install Amass
      shell: |
        curl -s https://api.github.com/repos/OWASP/Amass/releases/latest | grep "browser_download_url.*linux_amd64.zip" | cut -d : -f 2,3 | tr -d \" | wget -i -
        unzip amass* 
        chmod +x ./amass_linux_amd64/amass 
        mv ./amass_linux_amd64/amass /usr/bin/
      args:
        executable: /bin/bash

    - name: Install Nuclei
      shell: |
        curl -s https://api.github.com/repos/projectdiscovery/nuclei/releases/latest | grep "browser_download_url.*linux_amd64.zip" | cut -d : -f 2,3 | tr -d \" | wget -i -
        unzip nuclei* nuclei
        chmod +x nuclei
        mv nuclei /usr/bin/
      args:
        executable: /bin/bash

    - name: Install FFUF
      shell: |
        curl -s https://api.github.com/repos/ffuf/ffuf/releases/latest | grep "browser_download_url.*linux_amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | wget -i -
        tar xzf ffuf* ffuf
        chmod +x ffuf
        mv ffuf /usr/bin/
      args:
        executable: /bin/bash

    - name: Install Subfinder
      shell: |
        curl -s https://api.github.com/repos/projectdiscovery/subfinder/releases/latest | grep "browser_download_url.*linux_amd64.zip" | cut -d : -f 2,3 | tr -d \" | wget -i -
        unzip subfinder* subfinder
        chmod +x subfinder
        mv subfinder /usr/bin/
      args:
        executable: /bin/bash

    - name: Install Aquatone
      shell: |
        curl -s https://api.github.com/repos/michenriksen/aquatone/releases/latest | grep "browser_download_url.*linux_amd64-*" | cut -d : -f 2,3 | tr -d \" | wget -i -
        unzip aquatone* aquatone
        chmod +x aquatone 
        mv aquatone /usr/bin
      args:
        executable: /bin/bash

    - name: Install getallurls (gau)
      shell: |
        curl -s https://api.github.com/repos/lc/gau/releases/latest | grep "browser_download_url.*linux_amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | wget -i -
        tar xzf gau* gau 
        chmod +x gau 
        mv gau /usr/bin
      args:
        executable: /bin/bash

    - name: Install CrackMapExec
      shell: |
        wget https://github.com/byt3bl33d3r/CrackMapExec/releases/download/v5.2.2/cme-ubuntu-latest.zip
        unzip cme-ubuntu-latest.zip -d "$HOME/tools/*"
        pip3 install cffi==1.14.5
      args:
        executable: /bin/bash

    - name: Reboot the box
      reboot:
        msg: "Reboot initiated by Ansible for updates"
        connect_timeout: 5
        reboot_timeout: 300
        pre_reboot_delay: 0
        post_reboot_delay: 30
        test_command: uptime

If you take a close look at these templates, you’ll see variables indicated with the following templating syntax:

${ variable_name }

These are “filled in” during the terraform apply process. We only have a single variable in each of these files, but you can use as many as you’d like depending on what you’re trying to accomplish. This is a very powerful feature. It allows you to dynamically create files to be used in other processes – in our case, Ansible.

It’s Alive!

We are ready to create our infrastructure by running the following commands within the terraform directory. Type “yes” when prompted after the apply command.

$ terraform init

$ terraform fmt

$ terraform validate

$ terraform apply -var-file="./variables.tfvars"

The terraform init command initializes the project directory. terraform fmt formats the files to the canonical style. terraform validate validates the project to ensure it will work properly. Finally, terraform apply creates your infrastructure using the tfvars file you specified.

If everything goes as planned, you should see output similar to this.

terraform apply output

As you can see, the IP address of our VM was present in the output as we specified in outputs.tf.

Ansible

During the infrastructure creation process, several files should have been created in the ansible directory. Ansible will use these files update/upgrade and install packages on our VM. From the ansible directory we run the following command to configure our new VM. At the start, you will be prompted for the SSH password that you used in your tfvars file.

$ ansible-playbook -i hosts playbook.yml

We need to specify the hosts file that Terraform created so Ansible doesn’t use the hosts file located in /etc/ansible.

This process will take a few minutes to complete, but if all went as planned, you should see something similar to this on your terminal.

Tear it Down

When you are all done playing around with your new VM, you can destroy it with the following command. Please remember to destroy it or else you will incur costs. Type “yes” when prompted.

$ terraform destroy -var-file="./variables.tfvars"

What’s Next?

Now, play around with the above project. Can you set it up to deploy multiple VMs? Can you set it up to deploy multiple VMs, install some other packages, run some commands and send the output of those commands to a database somewhere? Can you set this up on multiple clouds?

The example here is pretty basic, and doesn’t necessarily follow best practices (especially with Ansible), but it gives you the idea of what can be done with automation. Some, if not all, of the leading bug bounty hunters are at least partially automating their work. You should automate too.

Feel free to download all this code from my github and don’t forget to use my link to sign up for a Linode account.

Links

Here are some links to more information and documentation that is pertinent to this article, including a link to this code on Github.

https://www.github.com/pizza-power/bugbountyboxautomation

https://www.terraform.io/cli

https://www.linode.com/docs/guides/how-to-build-your-infrastructure-using-terraform-and-linode/

https://registry.terraform.io/providers/linode/linode/latest/docs

So you wanna bug hunt?

> All the Rage:

Bug hunting seems to be all the rage these days. I can understand that, hacking is fun. So if you can hack (legally) and get paid, why not? Let me just tell you what you’re getting yourself into.

For one, you probably aren’t going to make much money, and even if you do make some money, you’d have probably made more with a part time job, or doing whatever needs to get done at your day job to move up in the organization and make more money.

Here are a few questions to ask yourself before you bug hunt.

Can you afford $20-$40 a month for a VPS? You’ll be doing A LOT of recon and you don’t want to do it from your home IP address. You’ll get IP bans, and it will really make your household angry if they can’t get on Netflix because you spent all night hammering Akamai or whatever the case may be.

Can you afford a $400 Burp Pro subscription? Yeah, you may be able to get away without it, but IMO it isn’t worth the effort – double so if you do/are planning to work in the security industry.

> Programs:

Now, you see all those programs listed for hacking on HackerOne and and BugCrowd? Well they are all public programs that have had thousands of people picking over their programs for YEARS at this point. That’s not to say some bugs aren’t still there, they are, but they are way, way less in numbers. Not to mention, many of them have had paid pentesters hacking on them. A lot of these programs were private before they went public too, so when you see the “launched” time, it actually isn’t true – the program didn’t just launch this month.

And don’t get me started on the unpaid bounty programs. They basically are getting all this work done without having to pay anybody. But hey, you’ll get points for hacking them!!!!! Oh wow, great. Unpaid programs should not exist. It lessens the value of our work.

Let me tell you a story of me and an unpaid program. About a year ago, I got invited to this program, and I immediately realized the scope was very large – which is awesome. Within a few days, I had found a bunch of bugs. All of these bugs were medium or higher, and one was EXTREMELY critical. So naturally, I’m happy, and I’m thinking I’m going to make some good money. Wrong. That’s when I found out that this program was unpaid.

I know, I know – it is my fault for not checking first. At the time, I was under the assumption that you had to be a paid program to be a private program. I don’t know where I got that from. My point remains valid. Basically, there is a good chance I saved this company millions of dollars, and without going into details, it could have been worse that just a monetary loss for them. You know what I got in return? Points. Great. Wow.

This actually happened to me again recently. Yes, I’m stupid. But I digress, haha.

> Coding:

I see a lot of posts asking if you need to know how to code to bug hunt. It sounds like a lot of these people are trying to get away without learning how to code. Let me help you.

YOU NEED TO KNOW HOW TO CODE.

You don’t have to be a pro, but you need to be decently fluent in python and bash, and at the very least, be able to read PHP and Javascript. The more experienced you are the better.

You see those people making a lot of money bug hunting? They are probably good coders. They’ve probably automated all their recon with Python or Bash scripts. They can decompile mobile and web apps. They’re pretty good coders, generally.

> Certs:

Let’s talk about the OSCP. Is it a cool cert? Yes. Does it teach you much about bug hunting? Yes and no. You’ll need to add a lot more techniques and tools to your arsenal to be successful. The offsec AWAE does have some topics that are useful to bug hunting – web apps in particular.

Let’s talk about these techniques and tools.

You’ll need to install a lot of tools you’ve never heard of. And listen, everybody has a massive amount of bug hunting scripted. They are constantly scanning ALL the hosts in EVERY program for low hanging fruit. Again, that doesn’t mean you won’t find anything, but it greatly reduces your chances.

You still wanna bug hunt? Go for it. But don’t get discouraged when you’re in the hole $600 bucks and you’ve found two self XSS vulns after a year. Lol

> TLDR:

Don’t bug hunt, and if you do, avoid unpaid programs. Better yet, spend your time advancing your career or getting a part time job. Also, use my Linode link for your VPS 😉

You should use a VPS for bug bounty hunting

Why should you use a VPS?

For one, it’ll keep your IP address from being banned by certain providers. How would it feel to wake up one day and not being able to access certain sites because your IP has been blacklisted? If you use a VPS, this isn’t much of an issue. You can just change out the IP from the VPS provider. It may be a littler harder to change your home IP address.

For two, it makes tool installation easier and faster. On Linode, I have a lengthy script that I run when I’m starting up a new box. The script sets up everything I need for bug bounty hunting. It makes tearing down a box and bringing it up a new one simple and quick.

Another reason you may want a cloud-based box running is for server capabilities. For example if you’re testing out some sort of XSS/XXE/etc. and you need a server to host a payload, your bug bounty box can serve double duty. Additionally, some hunters maintain giant databases of scraped webpages, nmap scans, targets and their subdomains, and on and on and on. But perhaps my favorite usage of a dedicated bug-bounty box is hosting your own semi-permanent Burp Collaborator server as described here.

I use this in my day-to-day exploitation because I don’t want to host this stuff at home, which exposes my personal IP address and whatever ports I have open to the general public, which I try to avoid.

Here is a small example of a script that I run. My script is significantly larger, but this is a decent start.

See the latest version on my github page.

#!/bin/bash
# for use with Ubuntu 20.04
# some security tools to get started
# use this to setup new bug bounty box
# use at your own risk

# check if running as root
if [ "$EUID" -ne 0 ]
	then echo "Run as root, please!"
	exit
fi

mkdir sectools
cd sectools

apt update -y && apt upgrade -y

# install some packages and tools that are used regularly
apt install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common \
net-tools \
nmap \
john \
hashcat \
python3-pip \
wfuzz \
nikto \
gobuster \
masscan \
ruby-full \
ruby-railties \
wireguard \
nfs-common \
hydra \
cewl \
mlocate

# evil winrm
gem install evil-winrm

# powershell
snap install powershell --classic

# amass
curl -s https://api.github.com/repos/OWASP/Amass/releases/latest | grep "browser_download_url.*linux_amd64.zip" | cut -d : -f 2,3 | tr -d \" | wget -i -
unzip amass* 
chmod +x ./amass_linux_amd64/amass 
mv ./amass_linux_amd64/amass /usr/bin/


# nuclei
curl -s https://api.github.com/repos/projectdiscovery/nuclei/releases/latest | grep "browser_download_url.*linux_amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | wget -i -
tar xzf nuclei* nuclei
chmod +x nuclei
mv nuclei /usr/bin/

# httpx
curl -s https://api.github.com/repos/projectdiscovery/httpx/releases/latest | grep "browser_download_url.*linux_amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | wget -i -
tar xzf httpx* httpx
chmod +x httpx
mv httpx /usr/bin/

# subfinder
curl -s https://api.github.com/repos/projectdiscovery/subfinder/releases/latest | grep "browser_download_url.*linux_amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | wget -i -
tar xzf subfinder* subfinder
chmod +x subfinder
mv subfinder /usr/bin/

#aquatone setup
curl -s https://api.github.com/repos/michenriksen/aquatone/releases/latest | grep "browser_download_url.*linux_amd64-*" | cut -d : -f 2,3 | tr -d \" | wget -i -
unzip aquatone* aquatone
chmod +x aquatone && cp aquatone /usr/bin

# FFUF
curl -s https://api.github.com/repos/ffuf/ffuf/releases/latest | grep "browser_download_url.*linux_amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | wget -i -
tar xzf ffuf* ffuf
chmod +x ffuf
mv ffuf /usr/bin/

# getallurls (gau)
curl -s https://api.github.com/repos/lc/gau/releases/latest | grep "browser_download_url.*linux_amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | wget -i -
tar xzf gau* gau 
chmod +x gau 
mv gau /usr/bin

cd ..
echo "Don't forget to install metasploit, setoolkit, hexeditor, burp suite, wireshark, etc"
echo "all finished!"

You can add whatever you want to this script, and then spin up your bug bounty box with one script. I have my script set my hostname, bashrc, environment variables, download repos from git, install docker, install go, etc.

So who should you use for your VPS? I’ve used AWS, Azure, Digital Ocean, and Linode, and I find Linode to be the best. Just try them all out, and I think you’ll agree with me. AWS and Azure are both massive in size. Azure seems to take way to long to do certain tasks, so that is frustrating. The site just seems slow in general. AWS is better than Azure.

Linode is where it is at. It is quick. The interface is simpler and easier to use than all of the above, and it is cheaper than all of the above. Check it out using my referral link, if you’re interested. That link will give you a $100/60 day credit, so you don’t want to sign up without one. You can just try it out for free and see what you think.