aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorheqnx <root@heqnx.com>2025-05-25 11:51:57 +0300
committerheqnx <root@heqnx.com>2025-05-25 11:51:57 +0300
commit8fb0b275bf00c963a24c21e1dfbaa64491c4f445 (patch)
tree28e9b4bbf0d4391f092f832d8f00d84ec20fed4f
parent7c8ed923df3c02338dfbf826fd6fd9a23dac502e (diff)
downloadansible-playbooks-8fb0b275bf00c963a24c21e1dfbaa64491c4f445.tar.gz
ansible-playbooks-8fb0b275bf00c963a24c21e1dfbaa64491c4f445.zip
added role-based playbooks
-rw-r--r--ansible.cfg3
-rw-r--r--inventory.yaml27
-rw-r--r--playbook.yaml29
-rw-r--r--roles/attackbox/tasks/apt_packages.yaml5
-rw-r--r--roles/attackbox/tasks/chrome_install.yaml24
-rw-r--r--roles/attackbox/tasks/github_repos.yaml15
-rw-r--r--roles/attackbox/tasks/go_tools.yaml6
-rw-r--r--roles/attackbox/tasks/golang_install.yaml33
-rw-r--r--roles/attackbox/tasks/main.yaml5
-rw-r--r--roles/attackbox/vars/main.yaml81
-rw-r--r--roles/harden/handlers/main.yaml38
-rw-r--r--roles/harden/tasks/harden.yaml139
-rw-r--r--roles/harden/tasks/main.yaml1
-rw-r--r--roles/harden/templates/jail.local.j246
-rw-r--r--roles/sliver-c2/handlers/main.yaml70
-rw-r--r--roles/sliver-c2/tasks/apt_install.yaml5
-rw-r--r--roles/sliver-c2/tasks/golang_install.yaml33
-rw-r--r--roles/sliver-c2/tasks/main.yaml5
-rw-r--r--roles/sliver-c2/tasks/sliver_configure.yaml40
-rw-r--r--roles/sliver-c2/tasks/sliver_install.yaml35
-rw-r--r--roles/sliver-c2/tasks/sliver_systemd.yaml10
-rw-r--r--roles/sliver-c2/templates/server.json.j218
-rw-r--r--roles/sliver-c2/templates/sliver.service.j215
-rw-r--r--roles/sliver-c2/vars/main.yaml28
-rw-r--r--roles/ssh-nginx-multiplex/handlers/main.yaml25
-rw-r--r--roles/ssh-nginx-multiplex/tasks/main.yaml1
-rw-r--r--roles/ssh-nginx-multiplex/tasks/ssh_nginx_setup.yaml76
-rw-r--r--roles/ssh-nginx-multiplex/templates/index.html.j20
-rw-r--r--roles/ssh-nginx-multiplex/templates/nginx.conf.j257
-rw-r--r--roles/ssh-nginx-multiplex/templates/sslh.j23
-rw-r--r--roles/tor/handlers/main.yaml6
-rw-r--r--roles/tor/tasks/main.yaml1
-rw-r--r--roles/tor/tasks/tor_install.yaml48
-rw-r--r--roles/tor/templates/torrc.j230
34 files changed, 958 insertions, 0 deletions
diff --git a/ansible.cfg b/ansible.cfg
new file mode 100644
index 0000000..8395bb7
--- /dev/null
+++ b/ansible.cfg
@@ -0,0 +1,3 @@
+[ssh_connection]
+;scp_if_ssh = true
+transfer_method = scp
diff --git a/inventory.yaml b/inventory.yaml
new file mode 100644
index 0000000..e3d7943
--- /dev/null
+++ b/inventory.yaml
@@ -0,0 +1,27 @@
+all:
+ hosts:
+ server01:
+ ansible_host: 192.168.133.34
+ ansible_user: root
+ ansible_ssh_private_key_file: id_rsa
+ sliver_server: 127.0.0.1
+ # ssh + nginx multiplexing with sslh
+ public_sslh_port: 443
+ internal_nginx_port: 8080
+ internal_sshd_port: 22
+
+ #server02:
+ # ansible_host: 10.11.12.14
+ # ansible_user: root
+ # ansible_ssh_private_key_file: id_rsa
+ # sliver_server: 127.0.0.1
+ # # ssh + nginx multiplexing with sslh
+ # public_sslh_port: 443
+ # internal_nginx_port: 8080
+ # internal_sshd_port: 22
+
+ children:
+ servers:
+ hosts:
+ server01: {}
+ #server02: {}
diff --git a/playbook.yaml b/playbook.yaml
new file mode 100644
index 0000000..f0fbe91
--- /dev/null
+++ b/playbook.yaml
@@ -0,0 +1,29 @@
+- name: fail if system is not debian/ubuntu
+ hosts: all
+ gather_facts: true
+ tasks:
+ - name: check os family or distribution
+ ansible.builtin.assert:
+ that:
+ - "'debian' in ansible_facts.os_family.lower() or 'ubuntu' in ansible_facts.distribution.lower()"
+ fail_msg: "this playbook supports only debian-based systems"
+
+- name: setup server01
+ hosts: server01
+ become: true
+ roles:
+ - harden
+ - tor
+ - attackbox
+ - sliver-c2
+ - ssh-nginx-multiplex
+
+#- name: setup server02
+# hosts: server02
+# become: true
+# roles:
+# - harden
+# - tor
+# - attackbox
+# - sliver-c2
+# - ssh-nginx-multiplex
diff --git a/roles/attackbox/tasks/apt_packages.yaml b/roles/attackbox/tasks/apt_packages.yaml
new file mode 100644
index 0000000..4ed8331
--- /dev/null
+++ b/roles/attackbox/tasks/apt_packages.yaml
@@ -0,0 +1,5 @@
+- name: install apt packages
+ apt:
+ name: "{{ apt_packages }}"
+ state: present
+ update_cache: yes
diff --git a/roles/attackbox/tasks/chrome_install.yaml b/roles/attackbox/tasks/chrome_install.yaml
new file mode 100644
index 0000000..4b9bf4f
--- /dev/null
+++ b/roles/attackbox/tasks/chrome_install.yaml
@@ -0,0 +1,24 @@
+- name: remove old google signing key
+ file:
+ path: /etc/apt/trusted.gpg.d/google-signing-key.gpg
+ state: absent
+
+- name: download and install google signing key
+ shell: |
+ curl -sSL https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /etc/apt/trusted.gpg.d/google-signing-key.gpg
+
+- name: add google chrome repo
+ copy:
+ dest: /etc/apt/sources.list.d/google-chrome.list
+ content: |
+ deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/google-signing-key.gpg] https://dl.google.com/linux/chrome/deb stable main
+
+- name: update apt cache
+ apt:
+ update_cache: yes
+
+- name: install google chrome
+ apt:
+ name: google-chrome-stable
+ state: present
+
diff --git a/roles/attackbox/tasks/github_repos.yaml b/roles/attackbox/tasks/github_repos.yaml
new file mode 100644
index 0000000..042ea6c
--- /dev/null
+++ b/roles/attackbox/tasks/github_repos.yaml
@@ -0,0 +1,15 @@
+- name: ensure /opt/tools exists
+ ansible.builtin.file:
+ path: /opt/tools
+ state: directory
+ owner: root
+ group: root
+ mode: '0755'
+
+- name: clone github repos into /opt/tools
+ ansible.builtin.git:
+ repo: "{{ item }}"
+ dest: "/opt/tools/{{ item | basename | regex_replace('\\.git$', '') }}"
+ update: yes
+ force: yes
+ loop: "{{ github_repos }}"
diff --git a/roles/attackbox/tasks/go_tools.yaml b/roles/attackbox/tasks/go_tools.yaml
new file mode 100644
index 0000000..18c0346
--- /dev/null
+++ b/roles/attackbox/tasks/go_tools.yaml
@@ -0,0 +1,6 @@
+- name: install go tools
+ ansible.builtin.command:
+ cmd: "/usr/local/go/bin/go install -trimpath -v {{ item }}"
+ environment:
+ GOBIN: /usr/local/bin
+ loop: "{{ go_tools }}"
diff --git a/roles/attackbox/tasks/golang_install.yaml b/roles/attackbox/tasks/golang_install.yaml
new file mode 100644
index 0000000..e67d508
--- /dev/null
+++ b/roles/attackbox/tasks/golang_install.yaml
@@ -0,0 +1,33 @@
+- name: download and extract golang
+ block:
+ - name: get latest golang version
+ shell: |
+ curl -sSL https://golang.org/dl/ | awk -F '"' '/dl\/.*linux-amd64.*tar.gz/{print $(NF-1)}' | awk -F '/' '{print $3}' | head -1
+ register: latest_golang
+ changed_when: false
+
+ - name: download golang
+ get_url:
+ url: "https://golang.org/dl/{{ latest_golang.stdout }}"
+ dest: /tmp/golang.tar.gz
+
+ - name: extract golang to /usr/local
+ unarchive:
+ src: /tmp/golang.tar.gz
+ dest: /usr/local
+ remote_src: yes
+
+ - name: remove tarball
+ file:
+ path: /tmp/golang.tar.gz
+ state: absent
+
+ - name: set system-wide go environment variables
+ copy:
+ dest: /etc/profile.d/go_env.sh
+ content: |
+ export GOPATH=/root/go
+ export PATH=$PATH:/usr/local/go/bin:$GOPATH:$GOPATH/bin
+ owner: root
+ group: root
+ mode: '0644'
diff --git a/roles/attackbox/tasks/main.yaml b/roles/attackbox/tasks/main.yaml
new file mode 100644
index 0000000..3c498cd
--- /dev/null
+++ b/roles/attackbox/tasks/main.yaml
@@ -0,0 +1,5 @@
+- import_tasks: tasks/apt_packages.yaml
+- import_tasks: tasks/golang_install.yaml
+- import_tasks: tasks/chrome_install.yaml
+- import_tasks: tasks/go_tools.yaml
+- import_tasks: tasks/github_repos.yaml
diff --git a/roles/attackbox/vars/main.yaml b/roles/attackbox/vars/main.yaml
new file mode 100644
index 0000000..fc96103
--- /dev/null
+++ b/roles/attackbox/vars/main.yaml
@@ -0,0 +1,81 @@
+github_repos:
+ - https://github.com/danielmiessler/SecLists.git
+ - https://github.com/tomnomnom/gf.git
+ - https://github.com/1ndianl33t/Gf-Patterns.git
+
+go_tools:
+ - github.com/projectdiscovery/uncover/cmd/uncover@latest
+ - github.com/projectdiscovery/katana/cmd/katana@latest
+ - github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
+ - github.com/projectdiscovery/cloudlist/cmd/cloudlist@latest
+ - github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
+ - github.com/projectdiscovery/cdncheck/cmd/cdncheck@latest
+ - github.com/projectdiscovery/mapcidr/cmd/mapcidr@latest
+ - github.com/projectdiscovery/shuffledns/cmd/shuffledns@latest
+ - github.com/projectdiscovery/asnmap/cmd/asnmap@latest
+ - github.com/projectdiscovery/naabu/v2/cmd/naabu@latest
+ - github.com/projectdiscovery/chaos-client/cmd/chaos@latest
+ - github.com/projectdiscovery/tldfinder/cmd/tldfinder@latest
+ - github.com/projectdiscovery/httpx/cmd/httpx@latest
+ - github.com/projectdiscovery/tlsx/cmd/tlsx@latest
+ - github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest
+ - github.com/projectdiscovery/interactsh/cmd/interactsh-server@latest
+ - github.com/projectdiscovery/wappalyzergo/cmd/update-fingerprints@latest
+ - github.com/projectdiscovery/useragent/cmd/ua@latest
+ - github.com/projectdiscovery/notify/cmd/notify@latest
+ - github.com/projectdiscovery/tunnelx@latest
+ - github.com/projectdiscovery/urlfinder/cmd/urlfinder@latest
+ - github.com/projectdiscovery/cvemap/cmd/cvemap@latest
+ - github.com/projectdiscovery/alterx/cmd/alterx@latest
+ - github.com/projectdiscovery/proxify/cmd/proxify@latest
+ - github.com/projectdiscovery/dnsx/cmd/dnsx@latest
+ - github.com/projectdiscovery/openrisk@latest
+ - github.com/projectdiscovery/simplehttpserver/cmd/simplehttpserver@latest
+ - github.com/projectdiscovery/network-fingerprint@latest
+
+ - github.com/BishopFox/cloudfox@latest
+ - github.com/BishopFox/jsluice/cmd/jsluice@latest
+
+ - github.com/tomnomnom/gf@latest
+ - github.com/tomnomnom/waybackurls@latest
+ - github.com/tomnomnom/assetfinder@latest
+ - github.com/tomnomnom/meg@latest
+ - github.com/tomnomnom/anew@latest
+ - github.com/tomnomnom/unfurl@latest
+ - github.com/tomnomnom/qsreplace@latest
+ - github.com/tomnomnom/comb@latest
+
+ - github.com/hakluke/hakrawler@latest
+ - github.com/hakluke/hakrevdns@latest
+ - github.com/hakluke/haklistgen@latest
+ - github.com/hakluke/hakoriginfinder@latest
+ - github.com/hakluke/hakcheckurl@latest
+ - github.com/hakluke/haktrails@latest
+ - github.com/hakluke/haktldextract@latest
+ - github.com/hakluke/hakip2host@latest
+ - github.com/hakluke/hakurlencode@latest
+
+ - github.com/rverton/webanalyze/...@latest
+ - github.com/samirettali/dumpcn@latest
+ - github.com/ffuf/ffuf/v2@latest
+ - github.com/OJ/gobuster/v3@latest
+ - github.com/sensepost/gowitness@latest
+ - github.com/lc/gau/v2/cmd/gau@latest
+
+apt_packages:
+ - git
+ - gcc
+ - musl
+ - libpcap-dev
+ - musl-dev
+ - curl
+ - wget
+ - gpg
+ - openssl
+ - python3
+ - python3-pip
+ - nmap
+ - unattended-upgrades
+ - ufw
+ - tmux
+ - fail2ban
diff --git a/roles/harden/handlers/main.yaml b/roles/harden/handlers/main.yaml
new file mode 100644
index 0000000..e25c78f
--- /dev/null
+++ b/roles/harden/handlers/main.yaml
@@ -0,0 +1,38 @@
+- name: update grub
+ command: update-grub
+
+- name: reload fail2ban
+ command: fail2ban-client reload
+
+- name: enable ufw
+ ufw:
+ state: enabled
+ policy: deny
+
+- name: restart ufw
+ systemd:
+ name: ufw
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart ssh
+ systemd:
+ name: ssh
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart unattended-upgrades
+ systemd:
+ name: unattended-upgrades
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart fail2ban
+ systemd:
+ name: fail2ban
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
diff --git a/roles/harden/tasks/harden.yaml b/roles/harden/tasks/harden.yaml
new file mode 100644
index 0000000..cf60e95
--- /dev/null
+++ b/roles/harden/tasks/harden.yaml
@@ -0,0 +1,139 @@
+- name: remove snap and snapd
+ apt:
+ name:
+ - snap
+ - snapd
+ state: absent
+ purge: true
+
+- name: clean apt cache
+ apt:
+ autoclean: yes
+
+- name: clear /etc/issue and /etc/motd
+ copy:
+ content: ""
+ dest: "{{ item }}"
+ loop:
+ - /etc/issue
+ - /etc/motd
+
+- name: check if /etc/update-motd.d directory exists
+ stat:
+ path: /etc/update-motd.d
+ register: motd_dir
+
+- name: find files in /etc/update-motd.d
+ find:
+ paths: /etc/update-motd.d
+ file_type: file
+ register: motd_files
+ when: motd_dir.stat.exists
+
+- name: remove execute permissions from all files in /etc/update-motd.d
+ file:
+ path: "{{ item.path }}"
+ mode: u-x,g-x,o-x
+ loop: "{{ motd_files.files }}"
+ when: motd_dir.stat.exists
+
+- name: enforce root-only cron/at
+ file:
+ path: "{{ item }}"
+ state: touch
+ owner: root
+ group: root
+ mode: '0600'
+ loop:
+ - /etc/cron.allow
+ - /etc/at.allow
+
+- name: remove deny files for cron and at
+ file:
+ path: "{{ item }}"
+ state: absent
+ loop:
+ - /etc/cron.deny
+ - /etc/at.deny
+
+- name: backup sshd_config
+ copy:
+ src: /etc/ssh/sshd_config
+ dest: "/etc/ssh/sshd_config.bak_{{ ansible_date_time.iso8601_basic }}"
+ remote_src: yes
+
+- name: harden sshd_config
+ copy:
+ dest: /etc/ssh/sshd_config
+ content: |
+ Port 22
+ Banner /etc/issue
+ UsePAM yes
+ Protocol 2
+ Subsystem sftp /usr/lib/openssh/sftp-server
+ LogLevel verbose
+ PrintMotd no
+ AcceptEnv LANG LC_*
+ MaxSessions 5
+ StrictModes yes
+ Compression no
+ MaxAuthTries 3
+ IgnoreRhosts yes
+ PrintLastLog yes
+ AddressFamily inet
+ X11Forwarding no
+ PermitRootLogin yes
+ AllowTcpForwarding no
+ ClientAliveInterval 1200
+ AllowAgentForwarding no
+ PermitEmptyPasswords no
+ ClientAliveCountMax 0
+ GSSAPIAuthentication no
+ KerberosAuthentication no
+ IgnoreUserKnownHosts yes
+ PermitUserEnvironment no
+ ChallengeResponseAuthentication no
+ MACs hmac-sha2-512,hmac-sha2-256
+ Ciphers aes128-ctr,aes192-ctr,aes256-ctr
+
+- name: regenerate SSH host keys
+ shell: |
+ rm -f /etc/ssh/ssh_host_*key*
+ ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
+ ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
+ args:
+ creates: /etc/ssh/ssh_host_ed25519_key
+ notify: restart ssh
+
+- name: enable unattended-upgrades
+ shell: dpkg-reconfigure --priority=low unattended-upgrades
+ args:
+ creates: /etc/apt/apt.conf.d/50unattended-upgrades
+ notify: restart unattended-upgrades
+
+- name: disable ipv6 in grub
+ lineinfile:
+ path: /etc/default/grub
+ regexp: '^GRUB_CMDLINE_LINUX='
+ line: 'GRUB_CMDLINE_LINUX="ipv6.disable=1"'
+ notify: update grub
+
+- name: allow ssh port and enable ufw
+ ufw:
+ rule: allow
+ port: 22
+ proto: tcp
+ notify:
+ - enable ufw
+ - restart ufw
+
+- name: deploy custom fail2ban jail.local
+ template:
+ src: templates/jail.local.j2
+ dest: /etc/fail2ban/jail.local
+ owner: root
+ group: root
+ mode: '0644'
+ notify:
+ - restart fail2ban
+ - reload fail2ban
diff --git a/roles/harden/tasks/main.yaml b/roles/harden/tasks/main.yaml
new file mode 100644
index 0000000..95fdd29
--- /dev/null
+++ b/roles/harden/tasks/main.yaml
@@ -0,0 +1 @@
+- import_tasks: tasks/harden.yaml
diff --git a/roles/harden/templates/jail.local.j2 b/roles/harden/templates/jail.local.j2
new file mode 100644
index 0000000..dd548df
--- /dev/null
+++ b/roles/harden/templates/jail.local.j2
@@ -0,0 +1,46 @@
+[INCLUDES]
+#before = paths-distro.conf
+before = paths-debian.conf
+
+[DEFAULT]
+#ignoreself = true
+#ignoreip = 127.0.0.1/8 ::1
+ignorecommand =
+bantime = 1h
+findtime = 10m
+maxretry = 3
+maxmatches = %(maxretry)s
+backend = auto
+usedns = warn
+logencoding = auto
+enabled = false
+mode = normal
+filter = %(__name__)s[mode=%(mode)s]
+destemail = root@localhost
+sender = root@<fq-hostname>
+mta = sendmail
+protocol = tcp
+chain = <known/chain>
+port = 0:65535
+fail2ban_agent = Fail2Ban/%(fail2ban_version)s
+banaction = iptables-multiport
+banaction_allports = iptables-allports
+action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
+action_mw = %(action_)s
+ %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
+action_mwl = %(action_)s
+ %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
+action_xarf = %(action_)s
+ xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
+action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
+ %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
+action_blocklist_de = blocklist_de[email="%(sender)s", service="%(__name__)s", apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]
+action_abuseipdb = abuseipdb
+action = %(action_)s
+
+[sshd]
+mode = aggressive
+enabled = true
+port = ssh
+logpath = %(sshd_log)s
+backend = %(sshd_backend)s
diff --git a/roles/sliver-c2/handlers/main.yaml b/roles/sliver-c2/handlers/main.yaml
new file mode 100644
index 0000000..38b1dd4
--- /dev/null
+++ b/roles/sliver-c2/handlers/main.yaml
@@ -0,0 +1,70 @@
+- name: update grub
+ command: update-grub
+
+- name: reload fail2ban
+ command: fail2ban-client reload
+
+- name: enable ufw
+ ufw:
+ state: enabled
+ policy: deny
+
+- name: restart ufw
+ systemd:
+ name: ufw
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: reload systemd
+ command: systemctl daemon-reload
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart ssh
+ systemd:
+ name: ssh
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: enable unattended-upgrades service
+ systemd:
+ name: unattended-upgrades
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart ufw
+ systemd:
+ name: ufw
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart fail2ban
+ systemd:
+ name: fail2ban
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: sliver systemd handler
+ systemd:
+ name: sliver
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart nginx
+ systemd:
+ name: nginx
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart sslh
+ systemd:
+ name: sslh
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
diff --git a/roles/sliver-c2/tasks/apt_install.yaml b/roles/sliver-c2/tasks/apt_install.yaml
new file mode 100644
index 0000000..4004daf
--- /dev/null
+++ b/roles/sliver-c2/tasks/apt_install.yaml
@@ -0,0 +1,5 @@
+- name: install apt packages
+ apt:
+ name: "{{ apt_packages }}"
+ state: present
+ update_cache: yes \ No newline at end of file
diff --git a/roles/sliver-c2/tasks/golang_install.yaml b/roles/sliver-c2/tasks/golang_install.yaml
new file mode 100644
index 0000000..e67d508
--- /dev/null
+++ b/roles/sliver-c2/tasks/golang_install.yaml
@@ -0,0 +1,33 @@
+- name: download and extract golang
+ block:
+ - name: get latest golang version
+ shell: |
+ curl -sSL https://golang.org/dl/ | awk -F '"' '/dl\/.*linux-amd64.*tar.gz/{print $(NF-1)}' | awk -F '/' '{print $3}' | head -1
+ register: latest_golang
+ changed_when: false
+
+ - name: download golang
+ get_url:
+ url: "https://golang.org/dl/{{ latest_golang.stdout }}"
+ dest: /tmp/golang.tar.gz
+
+ - name: extract golang to /usr/local
+ unarchive:
+ src: /tmp/golang.tar.gz
+ dest: /usr/local
+ remote_src: yes
+
+ - name: remove tarball
+ file:
+ path: /tmp/golang.tar.gz
+ state: absent
+
+ - name: set system-wide go environment variables
+ copy:
+ dest: /etc/profile.d/go_env.sh
+ content: |
+ export GOPATH=/root/go
+ export PATH=$PATH:/usr/local/go/bin:$GOPATH:$GOPATH/bin
+ owner: root
+ group: root
+ mode: '0644'
diff --git a/roles/sliver-c2/tasks/main.yaml b/roles/sliver-c2/tasks/main.yaml
new file mode 100644
index 0000000..55e353f
--- /dev/null
+++ b/roles/sliver-c2/tasks/main.yaml
@@ -0,0 +1,5 @@
+- import_tasks: tasks/apt_install.yaml
+- import_tasks: tasks/golang_install.yaml
+- import_tasks: tasks/sliver_install.yaml
+- import_tasks: tasks/sliver_systemd.yaml
+- import_tasks: tasks/sliver_configure.yaml
diff --git a/roles/sliver-c2/tasks/sliver_configure.yaml b/roles/sliver-c2/tasks/sliver_configure.yaml
new file mode 100644
index 0000000..b90d955
--- /dev/null
+++ b/roles/sliver-c2/tasks/sliver_configure.yaml
@@ -0,0 +1,40 @@
+- name: ensure .sliver config directory exists
+ file:
+ path: "{{ install_path }}/.sliver/configs"
+ state: directory
+ owner: root
+ group: root
+ mode: '0700'
+
+- name: ensure .sliver-client config directory exists
+ file:
+ path: "/root/.sliver-client/configs"
+ state: directory
+ owner: root
+ group: root
+ mode: '0700'
+
+- name: deploy custom server.json config
+ template:
+ src: server.json.j2
+ dest: "{{ install_path }}/.sliver/configs/server.json"
+ owner: root
+ group: root
+ mode: '0600'
+ force: true
+
+- name: generate sliver operator profiles
+ loop: "{{ sliver_operators }}"
+ loop_control:
+ loop_var: operator
+ command: /opt/sliver/sliver-server operator --name {{ operator }} --lhost {{ sliver_server }} --save /root/.sliver-client/configs
+ notify: sliver systemd handler
+
+- name: fix permissions for .sliver-client directory
+ file:
+ path: /root/.sliver-client
+ state: directory
+ recurse: true
+ owner: root
+ group: root
+
diff --git a/roles/sliver-c2/tasks/sliver_install.yaml b/roles/sliver-c2/tasks/sliver_install.yaml
new file mode 100644
index 0000000..3f0e029
--- /dev/null
+++ b/roles/sliver-c2/tasks/sliver_install.yaml
@@ -0,0 +1,35 @@
+- name: import sliver gpg key
+ shell: |
+ gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 4449039C
+
+- name: get latest sliver-server binary URL
+ shell: |
+ curl -sSLf https://api.github.com/repos/BishopFox/sliver/releases/latest \
+ | grep -i browser_download_url \
+ | grep -i sliver-server_linux \
+ | grep -v sig \
+ | head -1 \
+ | cut -d '"' -f 4
+ register: sliver_url
+ changed_when: false
+
+- name: create sliver directory
+ file:
+ path: "{{ install_path }}"
+ state: directory
+ mode: '0755'
+
+- name: download sliver-server binary
+ get_url:
+ url: "{{ sliver_url.stdout }}"
+ dest: "{{ install_path }}/sliver-server"
+ mode: '0755'
+
+- name: symlink sliver binaries
+ file:
+ src: "{{ install_path }}/{{ item }}"
+ dest: "/usr/local/bin/{{ item }}"
+ state: link
+ force: true
+ loop:
+ - sliver-server
diff --git a/roles/sliver-c2/tasks/sliver_systemd.yaml b/roles/sliver-c2/tasks/sliver_systemd.yaml
new file mode 100644
index 0000000..3b29f0f
--- /dev/null
+++ b/roles/sliver-c2/tasks/sliver_systemd.yaml
@@ -0,0 +1,10 @@
+- name: copy sliver systemd service template
+ template:
+ src: sliver.service.j2
+ dest: /etc/systemd/system/sliver.service
+ owner: root
+ group: root
+ mode: '0600'
+ notify:
+ - reload systemd
+ - sliver systemd handler
diff --git a/roles/sliver-c2/templates/server.json.j2 b/roles/sliver-c2/templates/server.json.j2
new file mode 100644
index 0000000..9c59062
--- /dev/null
+++ b/roles/sliver-c2/templates/server.json.j2
@@ -0,0 +1,18 @@
+{
+ "daemon_mode": false,
+ "daemon": {
+ "host": "{{ sliver_server }}",
+ "port": 31337
+ },
+ "logs": {
+ "level": 4,
+ "grpc_unary_payloads": false,
+ "grpc_stream_payloads": false,
+ "tls_key_logger": false
+ },
+ "jobs": {
+ "multiplayer": null
+ },
+ "watch_tower": null,
+ "go_proxy": ""
+}
diff --git a/roles/sliver-c2/templates/sliver.service.j2 b/roles/sliver-c2/templates/sliver.service.j2
new file mode 100644
index 0000000..c45687d
--- /dev/null
+++ b/roles/sliver-c2/templates/sliver.service.j2
@@ -0,0 +1,15 @@
+[Unit]
+Description=Sliver
+After=network.target
+StartLimitIntervalSec=0
+
+[Service]
+Type=simple
+Restart=on-failure
+RestartSec=3
+User=root
+Environment=SLIVER_ROOT_DIR={{ install_path }}/.sliver
+ExecStart={{ install_path }}/sliver-server daemon
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/sliver-c2/vars/main.yaml b/roles/sliver-c2/vars/main.yaml
new file mode 100644
index 0000000..ba9786a
--- /dev/null
+++ b/roles/sliver-c2/vars/main.yaml
@@ -0,0 +1,28 @@
+apt_packages:
+ - binutils-mingw-w64
+ - build-essential
+ - curl
+ - fail2ban
+ - gcc
+ - git
+ - g++-mingw-w64
+ - gpg
+ - libpcap-dev
+ - mingw-w64
+ - musl
+ - musl-dev
+ - nmap
+ - openssl
+ - python3
+ - python3-pip
+ - tmux
+ - ufw
+ - unattended-upgrades
+ - wget
+install_path: /opt/sliver
+sliver_operators:
+ - operator01
+ - operator02
+ - operator03
+ - operator04
+ - operator05
diff --git a/roles/ssh-nginx-multiplex/handlers/main.yaml b/roles/ssh-nginx-multiplex/handlers/main.yaml
new file mode 100644
index 0000000..58c218b
--- /dev/null
+++ b/roles/ssh-nginx-multiplex/handlers/main.yaml
@@ -0,0 +1,25 @@
+- name: enable ufw
+ ufw:
+ state: enabled
+ policy: deny
+
+- name: restart ufw
+ systemd:
+ name: ufw
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart nginx
+ systemd:
+ name: nginx
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
+
+- name: restart sslh
+ systemd:
+ name: sslh
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
diff --git a/roles/ssh-nginx-multiplex/tasks/main.yaml b/roles/ssh-nginx-multiplex/tasks/main.yaml
new file mode 100644
index 0000000..649b41b
--- /dev/null
+++ b/roles/ssh-nginx-multiplex/tasks/main.yaml
@@ -0,0 +1 @@
+- import_tasks: tasks/ssh_nginx_setup.yaml
diff --git a/roles/ssh-nginx-multiplex/tasks/ssh_nginx_setup.yaml b/roles/ssh-nginx-multiplex/tasks/ssh_nginx_setup.yaml
new file mode 100644
index 0000000..beb0910
--- /dev/null
+++ b/roles/ssh-nginx-multiplex/tasks/ssh_nginx_setup.yaml
@@ -0,0 +1,76 @@
+- block:
+ - name: install required packages
+ apt:
+ name:
+ - openssl
+ - nginx
+ - sslh
+ - ufw
+ state: present
+ update_cache: true
+
+ - name: deploy index.html
+ template:
+ src: index.html.j2
+ dest: /var/www/html/index.html
+ owner: www-data
+ group: www-data
+ mode: '0644'
+
+ - name: ensure /var/www/html directory permissions
+ file:
+ path: /var/www/html
+ state: directory
+ owner: www-data
+ group: www-data
+ mode: '0755'
+
+ - name: generate self-signed ssl certificate
+ command: >
+ openssl req -x509 -nodes -days 365 -newkey rsa:2048
+ -keyout /etc/ssl/private/nginx-selfsigned.key
+ -out /etc/ssl/certs/nginx-selfsigned.crt
+ -subj "/CN=localhost"
+ args:
+ creates: /etc/ssl/certs/nginx-selfsigned.crt
+
+ - name: deploy nginx.conf
+ template:
+ src: nginx.conf.j2
+ dest: /etc/nginx/nginx.conf
+ owner: root
+ group: root
+ mode: '0644'
+ notify: restart nginx
+
+ - name: deploy sslh config file
+ template:
+ src: sslh.j2
+ dest: /etc/default/sslh
+ owner: root
+ group: root
+ mode: '0644'
+ notify: restart sslh
+
+ - name: allow ssh port and enable ufw
+ ufw:
+ rule: allow
+ port: "{{ internal_sshd_port }}"
+ proto: tcp
+ notify:
+ - enable ufw
+ - restart ufw
+
+ - name: allow http port and enable ufw
+ ufw:
+ rule: allow
+ port: "{{ public_sslh_port }}"
+ proto: tcp
+ notify:
+ - enable ufw
+ - restart ufw
+
+ when:
+ - public_sslh_port is defined
+ - internal_nginx_port is defined
+ - internal_sshd_port is defined
diff --git a/roles/ssh-nginx-multiplex/templates/index.html.j2 b/roles/ssh-nginx-multiplex/templates/index.html.j2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/roles/ssh-nginx-multiplex/templates/index.html.j2
diff --git a/roles/ssh-nginx-multiplex/templates/nginx.conf.j2 b/roles/ssh-nginx-multiplex/templates/nginx.conf.j2
new file mode 100644
index 0000000..a735338
--- /dev/null
+++ b/roles/ssh-nginx-multiplex/templates/nginx.conf.j2
@@ -0,0 +1,57 @@
+user www-data;
+worker_processes auto;
+pid /run/nginx.pid;
+include /etc/nginx/modules-enabled/*.conf;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ sendfile on;
+ tcp_nopush on;
+ tcp_nodelay on;
+ keepalive_timeout 65;
+ types_hash_max_size 2048;
+
+ server_tokens off;
+
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/error.log warn;
+
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_prefer_server_ciphers on;
+
+ add_header X-Content-Type-Options nosniff;
+ add_header X-Frame-Options DENY;
+ add_header X-XSS-Protection "1; mode=block";
+
+ server {
+ listen 127.0.0.1:{{ internal_nginx_port }} ssl default_server;
+ server_name _;
+
+ root /var/www/html;
+ index index.html;
+
+ ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
+ ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
+
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_prefer_server_ciphers on;
+
+ add_header X-Content-Type-Options nosniff;
+ add_header X-Frame-Options DENY;
+ add_header X-XSS-Protection "1; mode=block";
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ location ~ /\.(?!well-known) {
+ deny all;
+ }
+ }
+}
diff --git a/roles/ssh-nginx-multiplex/templates/sslh.j2 b/roles/ssh-nginx-multiplex/templates/sslh.j2
new file mode 100644
index 0000000..8820a74
--- /dev/null
+++ b/roles/ssh-nginx-multiplex/templates/sslh.j2
@@ -0,0 +1,3 @@
+RUN=yes
+DAEMON=/usr/sbin/sslh
+DAEMON_OPTS="--user sslh --listen 0.0.0.0:{{ public_sslh_port }} --ssh 127.0.0.1:{{ internal_sshd_port }} --http 127.0.0.1:{{ internal_nginx_port }}"
diff --git a/roles/tor/handlers/main.yaml b/roles/tor/handlers/main.yaml
new file mode 100644
index 0000000..8903ad6
--- /dev/null
+++ b/roles/tor/handlers/main.yaml
@@ -0,0 +1,6 @@
+- name: restart tor
+ systemd:
+ name: tor
+ state: restarted
+ enabled: true
+ when: ansible_facts['service_mgr'] == 'systemd'
diff --git a/roles/tor/tasks/main.yaml b/roles/tor/tasks/main.yaml
new file mode 100644
index 0000000..3168032
--- /dev/null
+++ b/roles/tor/tasks/main.yaml
@@ -0,0 +1 @@
+- import_tasks: tasks/tor_install.yaml
diff --git a/roles/tor/tasks/tor_install.yaml b/roles/tor/tasks/tor_install.yaml
new file mode 100644
index 0000000..e0f6d1d
--- /dev/null
+++ b/roles/tor/tasks/tor_install.yaml
@@ -0,0 +1,48 @@
+- name: install tor and required packages
+ apt:
+ name:
+ - tor
+ - tor-geoipdb
+ - torsocks
+ - proxychains
+ - curl
+ state: present
+ update_cache: yes
+
+- name: check if /etc/tor/torrc exists
+ stat:
+ path: /etc/tor/torrc
+ register: torrc_stat
+
+- name: back up /etc/tor/torrc
+ copy:
+ src: /etc/tor/torrc
+ dest: /etc/tor/torrc.bak
+ remote_src: yes
+ force: no
+ when:
+ - torrc_stat.stat.exists
+
+- name: deploy custom tor configuration
+ template:
+ src: templates/torrc.j2
+ dest: /etc/tor/torrc
+ owner: debian-tor
+ group: debian-tor
+ mode: '0644'
+ notify: restart tor
+
+- name: check if tor is routing traffic correctly
+ command: curl --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip
+ register: tor_check
+ changed_when: false
+
+- name: print tor check json response
+ debug:
+ msg: "tor check response: {{ tor_check.stdout }}"
+
+- name: verify tor is active
+ fail:
+ msg: "tor is not routing traffic correctly: istor is {{ tor_check.stdout | from_json | json_query('IsTor') }}"
+ when:
+ - tor_check.stdout | from_json | json_query('IsTor') != true
diff --git a/roles/tor/templates/torrc.j2 b/roles/tor/templates/torrc.j2
new file mode 100644
index 0000000..b12f93c
--- /dev/null
+++ b/roles/tor/templates/torrc.j2
@@ -0,0 +1,30 @@
+Log notice file /var/log/tor/notices.log
+Log info file /var/log/tor/info.log
+Log warn file /var/log/tor/warn.log
+SafeLogging 1
+
+RunAsDaemon 1
+
+DataDirectory /var/lib/tor
+
+UseEntryGuards 1
+
+ExitRelay 0
+
+ExcludeNodes {us},{gb},{ca},{nz},{au},{dk},{fr},{nl},{no},{de},{be},{it},{es},{se},{cn},{ru},{ir}
+StrictNodes 1
+
+SOCKSPort 127.0.0.1:9050
+
+DNSPort 127.0.0.1:5353
+TransPort 9040
+VirtualAddrNetworkIPv4 10.192.0.0/10
+AutomapHostsOnResolve 1
+
+HardwareAccel 1
+Sandbox 1
+NoExec 1
+KeepAlivePeriod 60
+ClientRejectInternalAddresses 1
+NewCircuitPeriod 30
+MaxCircuitDirtiness 600