├── DO_http_redirector ├── 000-default.conf ├── 000-default.conf-orig ├── DO-mod_rewrite-redirector-setup.sh ├── apache2.conf ├── droplet-config.tf ├── droplet-config.tf-orig ├── htaccess ├── htaccess-orig ├── init.tf └── init.tf-orig ├── DO_ssl_redirector ├── 000-default.conf ├── 000-default.conf-orig ├── DO-mod_rewrite-redirector-setup.sh ├── apache2.conf ├── droplet-config.tf ├── droplet-config.tf-orig ├── htaccess ├── htaccess-orig ├── init.tf └── init.tf-orig ├── LICENSE ├── Linode_http_redirector ├── 000-default.conf ├── 000-default.conf-orig ├── Linode-mod_rewrite-redirector-setup.sh ├── apache2.conf ├── htaccess ├── htaccess-orig ├── init.tf └── init.tf-orig ├── Linode_ssl_redirector ├── 000-default.conf ├── 000-default.conf-orig ├── Linode-mod_rewrite-redirector-setup.sh ├── apache2.conf ├── htaccess ├── htaccess-orig ├── init.tf └── init.tf-orig ├── README.md └── flow.png /DO_http_redirector/000-default.conf: -------------------------------------------------------------------------------- 1 | 2 | # The ServerName directive sets the request scheme, hostname and port that 3 | # the server uses to identify itself. This is used when creating 4 | # redirection URLs. In the context of virtual hosts, the ServerName 5 | # specifies what hostname must appear in the request's Host: header to 6 | # match this virtual host. For the default virtual host (this file) this 7 | # value is not decisive as it is used as a last resort host regardless. 8 | # However, you must set it for any further virtual host explicitly. 9 | #ServerName www.example.com 10 | 11 | DocumentRoot /var/www/html 12 | ServerName www.domainhere 13 | RewriteEngine On 14 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 15 | RewriteCond %{HTTP:Authorization} ^startofauthstring 16 | RewriteRule ^.*$ http://c2IPhere%{REQUEST_URI} [P] 17 | ProxyPassReverse / http://c2IPhere 18 | RewriteRule ^.*$ - [R=404,L] 19 | ServerAlias domainhere 20 | 21 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 22 | # error, crit, alert, emerg. 23 | # It is also possible to configure the loglevel for particular 24 | # modules, e.g. 25 | #LogLevel info ssl:warn 26 | 27 | ErrorLog ${APACHE_LOG_DIR}/error.log 28 | CustomLog ${APACHE_LOG_DIR}/access.log combined 29 | 30 | # For most configuration files from conf-available/, which are 31 | # enabled or disabled at a global level, it is possible to 32 | # include a line for only one particular virtual host. For example the 33 | # following line enables the CGI configuration for this host only 34 | # after it has been globally disabled with "a2disconf". 35 | #Include conf-available/serve-cgi-bin.conf 36 | 37 | 38 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 39 | -------------------------------------------------------------------------------- /DO_http_redirector/000-default.conf-orig: -------------------------------------------------------------------------------- 1 | 2 | # The ServerName directive sets the request scheme, hostname and port that 3 | # the server uses to identify itself. This is used when creating 4 | # redirection URLs. In the context of virtual hosts, the ServerName 5 | # specifies what hostname must appear in the request's Host: header to 6 | # match this virtual host. For the default virtual host (this file) this 7 | # value is not decisive as it is used as a last resort host regardless. 8 | # However, you must set it for any further virtual host explicitly. 9 | #ServerName www.example.com 10 | 11 | DocumentRoot /var/www/html 12 | ServerName www.domainhere 13 | RewriteEngine On 14 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 15 | RewriteCond %{HTTP:Authorization} ^startofauthstring 16 | RewriteRule ^.*$ http://c2IPhere%{REQUEST_URI} [P] 17 | ProxyPassReverse / http://c2IPhere 18 | RewriteRule ^.*$ - [R=404,L] 19 | ServerAlias domainhere 20 | 21 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 22 | # error, crit, alert, emerg. 23 | # It is also possible to configure the loglevel for particular 24 | # modules, e.g. 25 | #LogLevel info ssl:warn 26 | 27 | ErrorLog ${APACHE_LOG_DIR}/error.log 28 | CustomLog ${APACHE_LOG_DIR}/access.log combined 29 | 30 | # For most configuration files from conf-available/, which are 31 | # enabled or disabled at a global level, it is possible to 32 | # include a line for only one particular virtual host. For example the 33 | # following line enables the CGI configuration for this host only 34 | # after it has been globally disabled with "a2disconf". 35 | #Include conf-available/serve-cgi-bin.conf 36 | 37 | 38 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 39 | -------------------------------------------------------------------------------- /DO_http_redirector/DO-mod_rewrite-redirector-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "*******************************************************************" 4 | echo " Welcome to the Terraform Script Runner to Set Up Your Redirector! " 5 | echo "*******************************************************************" 6 | echo "" 7 | echo "Have you already installed terraform? (Y/N)?" 8 | read installed 9 | 10 | if [[ ("$installed" == "N") || ("$installed" == "n") ]];then 11 | ostype=$(uname) 12 | if [[ "$ostype" == "Linux" ]]; then 13 | echo "attempting to install terraform (linux install)..." 14 | curl -o ~/terraform.zip https://releases.hashicorp.com/terraform/0.13.1/terraform_0.13.1_linux_amd64.zip 15 | mkdir -p ~/opt/terraform 16 | sudo apt install unzip 17 | unzip ~/terraform.zip -d ~/opt/terraform 18 | echo "Next add terraform to your path (append export PATH=$PATH:~/opt/terraform/bin to the end)" 19 | nano ~/.bashrc 20 | . .bashrc 21 | elif [[ "$ostype" == "Darwin" ]]; then 22 | echo "Attempting to install terraform (macOS Homebrew install)..." 23 | brew tap hashicorp/tap 24 | brew install hashicorp/tap/terraform 25 | 26 | fi 27 | fi 28 | echo "=====>Enter the name you want to call your redirector droplet" 29 | read dropletName 30 | echo "=====>Enter the src IP that you will login to your redirector from (i.e., terraform will set up a firewall only allowing ssh/admin access in from this src IP)" 31 | read adminIP 32 | echo "=====>Enter the IP address of the backend C2 server that the redirector will sit in front of (only the redirector will have access to ports 443 and/or 80 on this host)" 33 | read c2IP 34 | echo "=====>Enter your Digital Ocean API key" 35 | read DOAPIKey 36 | echo "=====>Enter the name of your Digital Ocean ssh key (can be found in your admin console panel or you can create one there if you haven't already)" 37 | read keyName 38 | echo "=====>Enter the local path to the ssh private key that you use to ssh into Digital Ocean (ex: ~/.ssh/id_rsa)" 39 | read keyPath 40 | echo "=====>Enter the domain name for your redirector. AFTER THE SCRIPT RUNS, BE SURE TO SET UP DNS RECORDS TO POINT TO THIS REDIRECTOR'S IP ADDRESS" 41 | read domain 42 | echo "=====>Enter the user agent string that you want the redirector to use to allow access to your back end C2 (i.e., the unique user agent in your C2 agent)" 43 | read uAgent 44 | echo "=====>Do you have an authorization token (ex: bearer token) that you want to use for redirecting? (Y/N)" 45 | read authAns 46 | 47 | if [[ ("$authAns" == "Y") || ("$authAns" == "y") ]];then 48 | echo "=====>Enter the first few characters of the auth string that are consistent (ex: for a token with Bearer [random] you would enter Bearer here)" 49 | read authString 50 | sed -i -e "s/startofauthstring/$authString/g" 000-default.conf 51 | sed -i -e "s/startofauthstring/$authString/g" htaccess 52 | else 53 | sed -i -e '15d' 000-default.conf 54 | sed -i -e '3d' htaccess 55 | fi 56 | 57 | sed -i -e "s/myc2-1/$dropletName/g" droplet-config.tf 58 | sed -i -e "s/keyname/$keyName/g" init.tf 59 | sed -i -e "s/keyname/$keyName/g" droplet-config.tf 60 | sed -i -e "s/127.0.0.1/$adminIP/g" droplet-config.tf 61 | sed -i -e "s/10.0.0.0/$c2IP/g" droplet-config.tf 62 | 63 | sed -i -e "s/domainhere/$domain/g" init.tf 64 | sed -i -e "s/domainhere/$domain/g" 000-default.conf 65 | sed -i -e "s/domainhere/$domain/g" droplet-config.tf 66 | sed -i -e 's|useragenthere|'"$uAgent"'|g' 000-default.conf 67 | sed -i -e "s/c2IPhere/$c2IP/g" 000-default.conf 68 | sed -i -e "s/domainhere/$domain/g" htaccess 69 | sed -i -e 's|useragenthere|'"$uAgent"'|g' htaccess 70 | sed -i -e "s/c2IPhere/$c2IP/g" htaccess 71 | 72 | terraform init 73 | echo "====>Running terraform plan for the new droplet and firewall that the droplet will be added to" 74 | terraform plan -var "do_token=$DOAPIKey" -var "pvt_key=$keyPath" 75 | echo "====>Applying the terraform plan..." 76 | terraform apply -var "do_token=$DOAPIKey" -var "pvt_key=$keyPath" 77 | cp init.tf-orig init.tf 78 | cp droplet-config.tf-orig droplet-config.tf 79 | cp 000-default.conf-orig 000-default.conf 80 | cp htaccess-orig htaccess 81 | -------------------------------------------------------------------------------- /DO_http_redirector/apache2.conf: -------------------------------------------------------------------------------- 1 | # This is the main Apache server configuration file. It contains the 2 | # configuration directives that give the server its instructions. 3 | # See http://httpd.apache.org/docs/2.4/ for detailed information about 4 | # the directives and /usr/share/doc/apache2/README.Debian about Debian specific 5 | # hints. 6 | # 7 | # 8 | # Summary of how the Apache 2 configuration works in Debian: 9 | # The Apache 2 web server configuration in Debian is quite different to 10 | # upstream's suggested way to configure the web server. This is because Debian's 11 | # default Apache2 installation attempts to make adding and removing modules, 12 | # virtual hosts, and extra configuration directives as flexible as possible, in 13 | # order to make automating the changes and administering the server as easy as 14 | # possible. 15 | 16 | # It is split into several files forming the configuration hierarchy outlined 17 | # below, all located in the /etc/apache2/ directory: 18 | # 19 | # /etc/apache2/ 20 | # |-- apache2.conf 21 | # | `-- ports.conf 22 | # |-- mods-enabled 23 | # | |-- *.load 24 | # | `-- *.conf 25 | # |-- conf-enabled 26 | # | `-- *.conf 27 | # `-- sites-enabled 28 | # `-- *.conf 29 | # 30 | # 31 | # * apache2.conf is the main configuration file (this file). It puts the pieces 32 | # together by including all remaining configuration files when starting up the 33 | # web server. 34 | # 35 | # * ports.conf is always included from the main configuration file. It is 36 | # supposed to determine listening ports for incoming connections which can be 37 | # customized anytime. 38 | # 39 | # * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ 40 | # directories contain particular configuration snippets which manage modules, 41 | # global configuration fragments, or virtual host configurations, 42 | # respectively. 43 | # 44 | # They are activated by symlinking available configuration files from their 45 | # respective *-available/ counterparts. These should be managed by using our 46 | # helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See 47 | # their respective man pages for detailed information. 48 | # 49 | # * The binary is called apache2. Due to the use of environment variables, in 50 | # the default configuration, apache2 needs to be started/stopped with 51 | # /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not 52 | # work with the default configuration. 53 | 54 | 55 | # Global configuration 56 | # 57 | 58 | # 59 | # ServerRoot: The top of the directory tree under which the server's 60 | # configuration, error, and log files are kept. 61 | # 62 | # NOTE! If you intend to place this on an NFS (or otherwise network) 63 | # mounted filesystem then please read the Mutex documentation (available 64 | # at ); 65 | # you will save yourself a lot of trouble. 66 | # 67 | # Do NOT add a slash at the end of the directory path. 68 | # 69 | #ServerRoot "/etc/apache2" 70 | 71 | # 72 | # The accept serialization lock file MUST BE STORED ON A LOCAL DISK. 73 | # 74 | #Mutex file:${APACHE_LOCK_DIR} default 75 | 76 | # 77 | # The directory where shm and other runtime files will be stored. 78 | # 79 | 80 | DefaultRuntimeDir ${APACHE_RUN_DIR} 81 | 82 | # 83 | # PidFile: The file in which the server should record its process 84 | # identification number when it starts. 85 | # This needs to be set in /etc/apache2/envvars 86 | # 87 | PidFile ${APACHE_PID_FILE} 88 | 89 | # 90 | # Timeout: The number of seconds before receives and sends time out. 91 | # 92 | Timeout 300 93 | 94 | # 95 | # KeepAlive: Whether or not to allow persistent connections (more than 96 | # one request per connection). Set to "Off" to deactivate. 97 | # 98 | KeepAlive On 99 | 100 | # 101 | # MaxKeepAliveRequests: The maximum number of requests to allow 102 | # during a persistent connection. Set to 0 to allow an unlimited amount. 103 | # We recommend you leave this number high, for maximum performance. 104 | # 105 | MaxKeepAliveRequests 100 106 | 107 | # 108 | # KeepAliveTimeout: Number of seconds to wait for the next request from the 109 | # same client on the same connection. 110 | # 111 | KeepAliveTimeout 5 112 | 113 | 114 | # These need to be set in /etc/apache2/envvars 115 | User ${APACHE_RUN_USER} 116 | Group ${APACHE_RUN_GROUP} 117 | 118 | # 119 | # HostnameLookups: Log the names of clients or just their IP addresses 120 | # e.g., www.apache.org (on) or 204.62.129.132 (off). 121 | # The default is off because it'd be overall better for the net if people 122 | # had to knowingly turn this feature on, since enabling it means that 123 | # each client request will result in AT LEAST one lookup request to the 124 | # nameserver. 125 | # 126 | HostnameLookups Off 127 | 128 | # ErrorLog: The location of the error log file. 129 | # If you do not specify an ErrorLog directive within a 130 | # container, error messages relating to that virtual host will be 131 | # logged here. If you *do* define an error logfile for a 132 | # container, that host's errors will be logged there and not here. 133 | # 134 | ErrorLog ${APACHE_LOG_DIR}/error.log 135 | 136 | # 137 | # LogLevel: Control the severity of messages logged to the error_log. 138 | # Available values: trace8, ..., trace1, debug, info, notice, warn, 139 | # error, crit, alert, emerg. 140 | # It is also possible to configure the log level for particular modules, e.g. 141 | # "LogLevel info ssl:warn" 142 | # 143 | LogLevel warn 144 | 145 | # Include module configuration: 146 | IncludeOptional mods-enabled/*.load 147 | IncludeOptional mods-enabled/*.conf 148 | 149 | # Include list of ports to listen on 150 | Include ports.conf 151 | 152 | 153 | # Sets the default security model of the Apache2 HTTPD server. It does 154 | # not allow access to the root filesystem outside of /usr/share and /var/www. 155 | # The former is used by web applications packaged in Debian, 156 | # the latter may be used for local directories served by the web server. If 157 | # your system is serving content from a sub-directory in /srv you must allow 158 | # access here, or in any related virtual host. 159 | 160 | Options FollowSymLinks 161 | AllowOverride None 162 | Require all denied 163 | 164 | 165 | 166 | AllowOverride None 167 | Require all granted 168 | 169 | 170 | 171 | Options Indexes FollowSymLinks 172 | AllowOverride All 173 | Require all granted 174 | 175 | 176 | # 177 | # Options Indexes FollowSymLinks 178 | # AllowOverride None 179 | # Require all granted 180 | # 181 | 182 | 183 | 184 | 185 | # AccessFileName: The name of the file to look for in each directory 186 | # for additional configuration directives. See also the AllowOverride 187 | # directive. 188 | # 189 | AccessFileName .htaccess 190 | 191 | # 192 | # The following lines prevent .htaccess and .htpasswd files from being 193 | # viewed by Web clients. 194 | # 195 | 196 | Require all denied 197 | 198 | 199 | 200 | # 201 | # The following directives define some format nicknames for use with 202 | # a CustomLog directive. 203 | # 204 | # These deviate from the Common Log Format definitions in that they use %O 205 | # (the actual bytes sent including headers) instead of %b (the size of the 206 | # requested file), because the latter makes it impossible to detect partial 207 | # requests. 208 | # 209 | # Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. 210 | # Use mod_remoteip instead. 211 | # 212 | LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined 213 | LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined 214 | LogFormat "%h %l %u %t \"%r\" %>s %O" common 215 | LogFormat "%{Referer}i -> %U" referer 216 | LogFormat "%{User-agent}i" agent 217 | 218 | # Include of directories ignores editors' and dpkg's backup files, 219 | # see README.Debian for details. 220 | 221 | # Include generic snippets of statements 222 | IncludeOptional conf-enabled/*.conf 223 | 224 | # Include the virtual host configurations: 225 | IncludeOptional sites-enabled/*.conf 226 | 227 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 228 | -------------------------------------------------------------------------------- /DO_http_redirector/droplet-config.tf: -------------------------------------------------------------------------------- 1 | resource "digitalocean_droplet" "myc2-1" { 2 | image = "ubuntu-20-04-x64" 3 | name = "myc2-1" 4 | region = "sfo2" 5 | size = "s-1vcpu-1gb" 6 | private_networking = true 7 | ssh_keys = [ 8 | data.digitalocean_ssh_key.keyname.id 9 | ] 10 | 11 | connection { 12 | host = self.ipv4_address 13 | user = "root" 14 | type = "ssh" 15 | private_key = file(var.pvt_key) 16 | timeout = "2m" 17 | } 18 | 19 | provisioner "file" { 20 | source = "000-default.conf" 21 | destination = "/root/000-default.conf" 22 | } 23 | 24 | provisioner "file" { 25 | source = "apache2.conf" 26 | destination = "/root/apache2.conf" 27 | } 28 | 29 | provisioner "file" { 30 | source = "htaccess" 31 | destination = "/root/.htaccess" 32 | } 33 | 34 | provisioner "remote-exec" { 35 | inline = [ 36 | "sudo apt-get update -y", 37 | "sudo apt-get -y install ufw", 38 | "sudo ufw default allow outgoing", 39 | "sudo ufw allow from 127.0.0.1 to any port 22", 40 | "sudo ufw allow 80", 41 | "sudo ufw --force enable", 42 | "sudo apt-get install apache2 -y", 43 | "sudo a2enmod rewrite proxy proxy_http ssl proxy_connect", 44 | "sudo mv /root/000-default.conf /etc/apache2/sites-available/000-default.conf", 45 | "sudo mv /root/apache2.conf /etc/apache2/apache2.conf", 46 | "sudo mv /root/.htaccess /var/www/html/.htaccess", 47 | "sudo service apache2 restart", 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /DO_http_redirector/droplet-config.tf-orig: -------------------------------------------------------------------------------- 1 | resource "digitalocean_droplet" "myc2-1" { 2 | image = "ubuntu-20-04-x64" 3 | name = "myc2-1" 4 | region = "sfo2" 5 | size = "s-1vcpu-1gb" 6 | private_networking = true 7 | ssh_keys = [ 8 | data.digitalocean_ssh_key.keyname.id 9 | ] 10 | 11 | connection { 12 | host = self.ipv4_address 13 | user = "root" 14 | type = "ssh" 15 | private_key = file(var.pvt_key) 16 | timeout = "2m" 17 | } 18 | 19 | provisioner "file" { 20 | source = "000-default.conf" 21 | destination = "/root/000-default.conf" 22 | } 23 | 24 | provisioner "file" { 25 | source = "apache2.conf" 26 | destination = "/root/apache2.conf" 27 | } 28 | 29 | provisioner "file" { 30 | source = "htaccess" 31 | destination = "/root/.htaccess" 32 | } 33 | 34 | provisioner "remote-exec" { 35 | inline = [ 36 | "sudo apt-get update -y", 37 | "sudo apt-get -y install ufw", 38 | "sudo ufw default allow outgoing", 39 | "sudo ufw allow from 127.0.0.1 to any port 22", 40 | "sudo ufw allow 80", 41 | "sudo ufw --force enable", 42 | "sudo apt-get install apache2 -y", 43 | "sudo a2enmod rewrite proxy proxy_http ssl proxy_connect", 44 | "sudo mv /root/000-default.conf /etc/apache2/sites-available/000-default.conf", 45 | "sudo mv /root/apache2.conf /etc/apache2/apache2.conf", 46 | "sudo mv /root/.htaccess /var/www/html/.htaccess", 47 | "sudo service apache2 restart", 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /DO_http_redirector/htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 3 | RewriteCond %{HTTP:Authorization} ^startofauthstring 4 | RewriteRule ^.*$ http://c2IPhere%{REQUEST_URI} [P] 5 | ProxyPassReverse / http://c2IPhere 6 | RewriteRule ^.*$ - [R=404,L] 7 | -------------------------------------------------------------------------------- /DO_http_redirector/htaccess-orig: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 3 | RewriteCond %{HTTP:Authorization} ^startofauthstring 4 | RewriteRule ^.*$ http://c2IPhere%{REQUEST_URI} [P] 5 | ProxyPassReverse / http://c2IPhere 6 | RewriteRule ^.*$ - [R=404,L] 7 | -------------------------------------------------------------------------------- /DO_http_redirector/init.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | digitalocean = { 4 | source = "digitalocean/digitalocean" 5 | version = "1.22.2" 6 | } 7 | } 8 | } 9 | 10 | variable "do_token" {} 11 | variable "pvt_key" {} 12 | 13 | provider "digitalocean" { 14 | token = var.do_token 15 | } 16 | 17 | data "digitalocean_ssh_key" "keyname" { 18 | name = "keyname" 19 | } 20 | -------------------------------------------------------------------------------- /DO_http_redirector/init.tf-orig: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | digitalocean = { 4 | source = "digitalocean/digitalocean" 5 | version = "1.22.2" 6 | } 7 | } 8 | } 9 | 10 | variable "do_token" {} 11 | variable "pvt_key" {} 12 | 13 | provider "digitalocean" { 14 | token = var.do_token 15 | } 16 | 17 | data "digitalocean_ssh_key" "keyname" { 18 | name = "keyname" 19 | } 20 | -------------------------------------------------------------------------------- /DO_ssl_redirector/000-default.conf: -------------------------------------------------------------------------------- 1 | 2 | # The ServerName directive sets the request scheme, hostname and port that 3 | # the server uses to identify itself. This is used when creating 4 | # redirection URLs. In the context of virtual hosts, the ServerName 5 | # specifies what hostname must appear in the request's Host: header to 6 | # match this virtual host. For the default virtual host (this file) this 7 | # value is not decisive as it is used as a last resort host regardless. 8 | # However, you must set it for any further virtual host explicitly. 9 | #ServerName www.example.com 10 | 11 | DocumentRoot /var/www/html 12 | ServerName www.domainhere 13 | SSLEngine On 14 | SSLProxyEngine On 15 | SSLProxyVerify none 16 | SSLProxyCheckPeerCN off 17 | SSLProxyCheckPeerName off 18 | RewriteEngine On 19 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 20 | RewriteCond %{HTTP:Authorization} ^startofauthstring 21 | RewriteRule ^.*$ https://c2IPhere%{REQUEST_URI} [P] 22 | ProxyPassReverse / https://c2IPhere 23 | RewriteRule ^.*$ - [R=404,L] 24 | ServerAlias domainhere 25 | SSLCertificateFile /etc/letsencrypt/live/www.domainhere/cert.pem 26 | SSLCertificateKeyFile /etc/letsencrypt/live/www.domainhere/privkey.pem 27 | 28 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 29 | # error, crit, alert, emerg. 30 | # It is also possible to configure the loglevel for particular 31 | # modules, e.g. 32 | #LogLevel info ssl:warn 33 | 34 | ErrorLog ${APACHE_LOG_DIR}/error.log 35 | CustomLog ${APACHE_LOG_DIR}/access.log combined 36 | 37 | # For most configuration files from conf-available/, which are 38 | # enabled or disabled at a global level, it is possible to 39 | # include a line for only one particular virtual host. For example the 40 | # following line enables the CGI configuration for this host only 41 | # after it has been globally disabled with "a2disconf". 42 | #Include conf-available/serve-cgi-bin.conf 43 | 44 | 45 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 46 | -------------------------------------------------------------------------------- /DO_ssl_redirector/000-default.conf-orig: -------------------------------------------------------------------------------- 1 | 2 | # The ServerName directive sets the request scheme, hostname and port that 3 | # the server uses to identify itself. This is used when creating 4 | # redirection URLs. In the context of virtual hosts, the ServerName 5 | # specifies what hostname must appear in the request's Host: header to 6 | # match this virtual host. For the default virtual host (this file) this 7 | # value is not decisive as it is used as a last resort host regardless. 8 | # However, you must set it for any further virtual host explicitly. 9 | #ServerName www.example.com 10 | 11 | DocumentRoot /var/www/html 12 | ServerName www.domainhere 13 | SSLEngine On 14 | SSLProxyEngine On 15 | SSLProxyVerify none 16 | SSLProxyCheckPeerCN off 17 | SSLProxyCheckPeerName off 18 | RewriteEngine On 19 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 20 | RewriteCond %{HTTP:Authorization} ^startofauthstring 21 | RewriteRule ^.*$ https://c2IPhere%{REQUEST_URI} [P] 22 | ProxyPassReverse / https://c2IPhere 23 | RewriteRule ^.*$ - [R=404,L] 24 | ServerAlias domainhere 25 | SSLCertificateFile /etc/letsencrypt/live/www.domainhere/cert.pem 26 | SSLCertificateKeyFile /etc/letsencrypt/live/www.domainhere/privkey.pem 27 | 28 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 29 | # error, crit, alert, emerg. 30 | # It is also possible to configure the loglevel for particular 31 | # modules, e.g. 32 | #LogLevel info ssl:warn 33 | 34 | ErrorLog ${APACHE_LOG_DIR}/error.log 35 | CustomLog ${APACHE_LOG_DIR}/access.log combined 36 | 37 | # For most configuration files from conf-available/, which are 38 | # enabled or disabled at a global level, it is possible to 39 | # include a line for only one particular virtual host. For example the 40 | # following line enables the CGI configuration for this host only 41 | # after it has been globally disabled with "a2disconf". 42 | #Include conf-available/serve-cgi-bin.conf 43 | 44 | 45 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 46 | -------------------------------------------------------------------------------- /DO_ssl_redirector/DO-mod_rewrite-redirector-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "*******************************************************************" 4 | echo " Welcome to the Terraform Script Runner to Set Up Your Redirector! " 5 | echo "*******************************************************************" 6 | echo "" 7 | echo "Have you already installed terraform? (Y/N)?" 8 | read installed 9 | 10 | if [[ ("$installed" == "N") || ("$installed" == "n") ]];then 11 | ostype=$(uname) 12 | if [[ "$ostype" == "Linux" ]]; then 13 | echo "attempting to install terraform (linux install)..." 14 | curl -o ~/terraform.zip https://releases.hashicorp.com/terraform/0.13.1/terraform_0.13.1_linux_amd64.zip 15 | mkdir -p ~/opt/terraform 16 | sudo apt install unzip 17 | unzip ~/terraform.zip -d ~/opt/terraform 18 | echo "Next add terraform to your path (append export PATH=$PATH:~/opt/terraform/bin to the end)" 19 | nano ~/.bashrc 20 | . .bashrc 21 | elif [[ "$ostype" == "Darwin" ]]; then 22 | echo "Attempting to install terraform (macOS Homebrew install)..." 23 | brew tap hashicorp/tap 24 | brew install hashicorp/tap/terraform 25 | 26 | fi 27 | fi 28 | echo "=====>Enter the name you want to call your redirector droplet" 29 | read dropletName 30 | echo "=====>Enter the src IP that you will login to your redirector from (i.e., terraform will set up a firewall only allowing ssh/admin access in from this src IP)" 31 | read adminIP 32 | echo "=====>Enter the IP address of the backend C2 server that the redirector will sit in front of (only the redirector will have access to ports 443 and/or 80 on this host)" 33 | read c2IP 34 | echo "=====>Enter your Digital Ocean API key" 35 | read DOAPIKey 36 | echo "=====>Enter the name of your Digital Ocean ssh key (can be found in your admin console panel or you can create one there if you haven't already)" 37 | read keyName 38 | echo "=====>Enter the local path to the ssh private key that you use to ssh into Digital Ocean (ex: ~/.ssh/id_rsa)" 39 | read keyPath 40 | echo "=====>Enter the domain name for your redirector. AFTER THE SCRIPT RUNS, BE SURE TO SET UP DNS RECORDS TO POINT TO THIS REDIRECTOR'S IP ADDRESS" 41 | read domain 42 | echo "=====>Enter the user agent string that you want the redirector to use to allow access to your back end C2 (i.e., the unique user agent in your C2 agent)" 43 | read uAgent 44 | echo "=====>Do you have an authorization token (ex: bearer token) that you want to use for redirecting? (Y/N)" 45 | read authAns 46 | 47 | if [[ ("$authAns" == "Y") || ("$authAns" == "y") ]];then 48 | echo "=====>Enter the first few characters of the auth string that are consistent (ex: for a token with Bearer [random] you would enter Bearer here)" 49 | read authString 50 | sed -i -e "s/startofauthstring/$authString/g" 000-default.conf 51 | sed -i -e "s/startofauthstring/$authString/g" htaccess 52 | else 53 | sed -i -e '20d' 000-default.conf 54 | sed -i -e '10d' htaccess 55 | fi 56 | 57 | sed -i -e "s/myc2-1/$dropletName/g" droplet-config.tf 58 | sed -i -e "s/keyname/$keyName/g" init.tf 59 | sed -i -e "s/keyname/$keyName/g" droplet-config.tf 60 | sed -i -e "s/127.0.0.1/$adminIP/g" droplet-config.tf 61 | sed -i -e "s/10.0.0.0/$c2IP/g" droplet-config.tf 62 | 63 | sed -i -e "s/domainhere/$domain/g" init.tf 64 | sed -i -e "s/domainhere/$domain/g" 000-default.conf 65 | sed -i -e "s/domainhere/$domain/g" droplet-config.tf 66 | sed -i -e 's|useragenthere|'"$uAgent"'|g' 000-default.conf 67 | sed -i -e "s/c2IPhere/$c2IP/g" 000-default.conf 68 | sed -i -e "s/domainhere/$domain/g" htaccess 69 | sed -i -e 's|useragenthere|'"$uAgent"'|g' htaccess 70 | sed -i -e "s/c2IPhere/$c2IP/g" htaccess 71 | 72 | terraform init 73 | echo "====>Running terraform plan for the new droplet and firewall that the droplet will be added to" 74 | terraform plan -var "do_token=$DOAPIKey" -var "pvt_key=$keyPath" 75 | echo "====>Applying the terraform plan..." 76 | terraform apply -var "do_token=$DOAPIKey" -var "pvt_key=$keyPath" 77 | cp init.tf-orig init.tf 78 | cp droplet-config.tf-orig droplet-config.tf 79 | cp 000-default.conf-orig 000-default.conf 80 | cp htaccess-orig htaccess 81 | -------------------------------------------------------------------------------- /DO_ssl_redirector/apache2.conf: -------------------------------------------------------------------------------- 1 | # This is the main Apache server configuration file. It contains the 2 | # configuration directives that give the server its instructions. 3 | # See http://httpd.apache.org/docs/2.4/ for detailed information about 4 | # the directives and /usr/share/doc/apache2/README.Debian about Debian specific 5 | # hints. 6 | # 7 | # 8 | # Summary of how the Apache 2 configuration works in Debian: 9 | # The Apache 2 web server configuration in Debian is quite different to 10 | # upstream's suggested way to configure the web server. This is because Debian's 11 | # default Apache2 installation attempts to make adding and removing modules, 12 | # virtual hosts, and extra configuration directives as flexible as possible, in 13 | # order to make automating the changes and administering the server as easy as 14 | # possible. 15 | 16 | # It is split into several files forming the configuration hierarchy outlined 17 | # below, all located in the /etc/apache2/ directory: 18 | # 19 | # /etc/apache2/ 20 | # |-- apache2.conf 21 | # | `-- ports.conf 22 | # |-- mods-enabled 23 | # | |-- *.load 24 | # | `-- *.conf 25 | # |-- conf-enabled 26 | # | `-- *.conf 27 | # `-- sites-enabled 28 | # `-- *.conf 29 | # 30 | # 31 | # * apache2.conf is the main configuration file (this file). It puts the pieces 32 | # together by including all remaining configuration files when starting up the 33 | # web server. 34 | # 35 | # * ports.conf is always included from the main configuration file. It is 36 | # supposed to determine listening ports for incoming connections which can be 37 | # customized anytime. 38 | # 39 | # * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ 40 | # directories contain particular configuration snippets which manage modules, 41 | # global configuration fragments, or virtual host configurations, 42 | # respectively. 43 | # 44 | # They are activated by symlinking available configuration files from their 45 | # respective *-available/ counterparts. These should be managed by using our 46 | # helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See 47 | # their respective man pages for detailed information. 48 | # 49 | # * The binary is called apache2. Due to the use of environment variables, in 50 | # the default configuration, apache2 needs to be started/stopped with 51 | # /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not 52 | # work with the default configuration. 53 | 54 | 55 | # Global configuration 56 | # 57 | 58 | # 59 | # ServerRoot: The top of the directory tree under which the server's 60 | # configuration, error, and log files are kept. 61 | # 62 | # NOTE! If you intend to place this on an NFS (or otherwise network) 63 | # mounted filesystem then please read the Mutex documentation (available 64 | # at ); 65 | # you will save yourself a lot of trouble. 66 | # 67 | # Do NOT add a slash at the end of the directory path. 68 | # 69 | #ServerRoot "/etc/apache2" 70 | 71 | # 72 | # The accept serialization lock file MUST BE STORED ON A LOCAL DISK. 73 | # 74 | #Mutex file:${APACHE_LOCK_DIR} default 75 | 76 | # 77 | # The directory where shm and other runtime files will be stored. 78 | # 79 | 80 | DefaultRuntimeDir ${APACHE_RUN_DIR} 81 | 82 | # 83 | # PidFile: The file in which the server should record its process 84 | # identification number when it starts. 85 | # This needs to be set in /etc/apache2/envvars 86 | # 87 | PidFile ${APACHE_PID_FILE} 88 | 89 | # 90 | # Timeout: The number of seconds before receives and sends time out. 91 | # 92 | Timeout 300 93 | 94 | # 95 | # KeepAlive: Whether or not to allow persistent connections (more than 96 | # one request per connection). Set to "Off" to deactivate. 97 | # 98 | KeepAlive On 99 | 100 | # 101 | # MaxKeepAliveRequests: The maximum number of requests to allow 102 | # during a persistent connection. Set to 0 to allow an unlimited amount. 103 | # We recommend you leave this number high, for maximum performance. 104 | # 105 | MaxKeepAliveRequests 100 106 | 107 | # 108 | # KeepAliveTimeout: Number of seconds to wait for the next request from the 109 | # same client on the same connection. 110 | # 111 | KeepAliveTimeout 5 112 | 113 | 114 | # These need to be set in /etc/apache2/envvars 115 | User ${APACHE_RUN_USER} 116 | Group ${APACHE_RUN_GROUP} 117 | 118 | # 119 | # HostnameLookups: Log the names of clients or just their IP addresses 120 | # e.g., www.apache.org (on) or 204.62.129.132 (off). 121 | # The default is off because it'd be overall better for the net if people 122 | # had to knowingly turn this feature on, since enabling it means that 123 | # each client request will result in AT LEAST one lookup request to the 124 | # nameserver. 125 | # 126 | HostnameLookups Off 127 | 128 | # ErrorLog: The location of the error log file. 129 | # If you do not specify an ErrorLog directive within a 130 | # container, error messages relating to that virtual host will be 131 | # logged here. If you *do* define an error logfile for a 132 | # container, that host's errors will be logged there and not here. 133 | # 134 | ErrorLog ${APACHE_LOG_DIR}/error.log 135 | 136 | # 137 | # LogLevel: Control the severity of messages logged to the error_log. 138 | # Available values: trace8, ..., trace1, debug, info, notice, warn, 139 | # error, crit, alert, emerg. 140 | # It is also possible to configure the log level for particular modules, e.g. 141 | # "LogLevel info ssl:warn" 142 | # 143 | LogLevel warn 144 | 145 | # Include module configuration: 146 | IncludeOptional mods-enabled/*.load 147 | IncludeOptional mods-enabled/*.conf 148 | 149 | # Include list of ports to listen on 150 | Include ports.conf 151 | 152 | 153 | # Sets the default security model of the Apache2 HTTPD server. It does 154 | # not allow access to the root filesystem outside of /usr/share and /var/www. 155 | # The former is used by web applications packaged in Debian, 156 | # the latter may be used for local directories served by the web server. If 157 | # your system is serving content from a sub-directory in /srv you must allow 158 | # access here, or in any related virtual host. 159 | 160 | Options FollowSymLinks 161 | AllowOverride None 162 | Require all denied 163 | 164 | 165 | 166 | AllowOverride None 167 | Require all granted 168 | 169 | 170 | 171 | Options Indexes FollowSymLinks 172 | AllowOverride All 173 | Require all granted 174 | 175 | 176 | # 177 | # Options Indexes FollowSymLinks 178 | # AllowOverride None 179 | # Require all granted 180 | # 181 | 182 | 183 | 184 | 185 | # AccessFileName: The name of the file to look for in each directory 186 | # for additional configuration directives. See also the AllowOverride 187 | # directive. 188 | # 189 | AccessFileName .htaccess 190 | 191 | # 192 | # The following lines prevent .htaccess and .htpasswd files from being 193 | # viewed by Web clients. 194 | # 195 | 196 | Require all denied 197 | 198 | 199 | 200 | # 201 | # The following directives define some format nicknames for use with 202 | # a CustomLog directive. 203 | # 204 | # These deviate from the Common Log Format definitions in that they use %O 205 | # (the actual bytes sent including headers) instead of %b (the size of the 206 | # requested file), because the latter makes it impossible to detect partial 207 | # requests. 208 | # 209 | # Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. 210 | # Use mod_remoteip instead. 211 | # 212 | LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined 213 | LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined 214 | LogFormat "%h %l %u %t \"%r\" %>s %O" common 215 | LogFormat "%{Referer}i -> %U" referer 216 | LogFormat "%{User-agent}i" agent 217 | 218 | # Include of directories ignores editors' and dpkg's backup files, 219 | # see README.Debian for details. 220 | 221 | # Include generic snippets of statements 222 | IncludeOptional conf-enabled/*.conf 223 | 224 | # Include the virtual host configurations: 225 | IncludeOptional sites-enabled/*.conf 226 | 227 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 228 | -------------------------------------------------------------------------------- /DO_ssl_redirector/droplet-config.tf: -------------------------------------------------------------------------------- 1 | resource "digitalocean_droplet" "myc2-1" { 2 | image = "ubuntu-20-04-x64" 3 | name = "myc2-1" 4 | region = "sfo2" 5 | size = "s-1vcpu-1gb" 6 | private_networking = true 7 | ssh_keys = [ 8 | data.digitalocean_ssh_key.keyname.id 9 | ] 10 | 11 | connection { 12 | host = self.ipv4_address 13 | user = "root" 14 | type = "ssh" 15 | private_key = file(var.pvt_key) 16 | timeout = "2m" 17 | } 18 | 19 | provisioner "file" { 20 | source = "000-default.conf" 21 | destination = "/root/000-default.conf" 22 | } 23 | 24 | provisioner "file" { 25 | source = "apache2.conf" 26 | destination = "/root/apache2.conf" 27 | } 28 | 29 | provisioner "file" { 30 | source = "htaccess" 31 | destination = "/root/.htaccess" 32 | } 33 | 34 | provisioner "remote-exec" { 35 | inline = [ 36 | "sudo apt-get update -y", 37 | "sudo apt-get -y install ufw", 38 | "sudo ufw default allow outgoing", 39 | "sudo ufw allow from 127.0.0.1 to any port 22", 40 | "sudo ufw allow 80", 41 | "sudo ufw allow 443", 42 | "sudo ufw --force enable", 43 | "sudo apt-get install apache2 -y", 44 | "sudo a2enmod rewrite proxy proxy_http ssl proxy_connect", 45 | "sudo a2ensite default-ssl.conf", 46 | "sudo apt-get install -y software-properties-common", 47 | "sudo add-apt-repository universe", 48 | "sudo apt install -y certbot && sudo apt install -y python3-certbot-apache", 49 | "sudo certbot -n -d www.domainhere,domainhere --apache --register-unsafely-without-email --agree-tos --no-redirect", 50 | "sudo mv /root/000-default.conf /etc/apache2/sites-available/000-default.conf", 51 | "sudo mv /root/apache2.conf /etc/apache2/apache2.conf", 52 | "sudo mv /root/.htaccess /var/www/html/.htaccess", 53 | "sudo ufw deny 80", 54 | "sudo service apache2 restart", 55 | "sudo apt-get install git", 56 | ] 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /DO_ssl_redirector/droplet-config.tf-orig: -------------------------------------------------------------------------------- 1 | resource "digitalocean_droplet" "myc2-1" { 2 | image = "ubuntu-20-04-x64" 3 | name = "myc2-1" 4 | region = "sfo2" 5 | size = "s-1vcpu-1gb" 6 | private_networking = true 7 | ssh_keys = [ 8 | data.digitalocean_ssh_key.keyname.id 9 | ] 10 | 11 | connection { 12 | host = self.ipv4_address 13 | user = "root" 14 | type = "ssh" 15 | private_key = file(var.pvt_key) 16 | timeout = "2m" 17 | } 18 | 19 | provisioner "file" { 20 | source = "000-default.conf" 21 | destination = "/root/000-default.conf" 22 | } 23 | 24 | provisioner "file" { 25 | source = "apache2.conf" 26 | destination = "/root/apache2.conf" 27 | } 28 | 29 | provisioner "file" { 30 | source = "htaccess" 31 | destination = "/root/.htaccess" 32 | } 33 | 34 | provisioner "remote-exec" { 35 | inline = [ 36 | "sudo apt-get update -y", 37 | "sudo apt-get -y install ufw", 38 | "sudo ufw default allow outgoing", 39 | "sudo ufw allow from 127.0.0.1 to any port 22", 40 | "sudo ufw allow 80", 41 | "sudo ufw allow 443", 42 | "sudo ufw --force enable", 43 | "sudo apt-get install apache2 -y", 44 | "sudo a2enmod rewrite proxy proxy_http ssl proxy_connect", 45 | "sudo a2ensite default-ssl.conf", 46 | "sudo apt-get install -y software-properties-common", 47 | "sudo add-apt-repository universe", 48 | "sudo apt install -y certbot && sudo apt install -y python3-certbot-apache", 49 | "sudo certbot -n -d www.domainhere,domainhere --apache --register-unsafely-without-email --agree-tos --no-redirect", 50 | "sudo mv /root/000-default.conf /etc/apache2/sites-available/000-default.conf", 51 | "sudo mv /root/apache2.conf /etc/apache2/apache2.conf", 52 | "sudo mv /root/.htaccess /var/www/html/.htaccess", 53 | "sudo ufw deny 80", 54 | "sudo service apache2 restart", 55 | "sudo apt-get install git", 56 | ] 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /DO_ssl_redirector/htaccess: -------------------------------------------------------------------------------- 1 | SSLEngine On 2 | SSLProxyEngine On 3 | SSLProxyVerify none 4 | SSLProxyCheckPeerCN off 5 | SSLProxyCheckPeerName off 6 | SSLCertificateFile /etc/letsencrypt/live/www.domainhere/cert.pem 7 | SSLCertificateKeyFile /etc/letsencrypt/live/www.domainhere/privkey.pem 8 | RewriteEngine on 9 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 10 | RewriteCond %{HTTP:Authorization} ^startofauthstring 11 | RewriteRule ^.*$ https://c2IPhere%{REQUEST_URI} [P] 12 | ProxyPassReverse / https://c2IPhere 13 | RewriteRule ^.*$ - [R=404,L] 14 | -------------------------------------------------------------------------------- /DO_ssl_redirector/htaccess-orig: -------------------------------------------------------------------------------- 1 | SSLEngine On 2 | SSLProxyEngine On 3 | SSLProxyVerify none 4 | SSLProxyCheckPeerCN off 5 | SSLProxyCheckPeerName off 6 | SSLCertificateFile /etc/letsencrypt/live/www.domainhere/cert.pem 7 | SSLCertificateKeyFile /etc/letsencrypt/live/www.domainhere/privkey.pem 8 | RewriteEngine on 9 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 10 | RewriteCond %{HTTP:Authorization} ^startofauthstring 11 | RewriteRule ^.*$ https://c2IPhere%{REQUEST_URI} [P] 12 | ProxyPassReverse / https://c2IPhere 13 | RewriteRule ^.*$ - [R=404,L] 14 | -------------------------------------------------------------------------------- /DO_ssl_redirector/init.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | digitalocean = { 4 | source = "digitalocean/digitalocean" 5 | version = "1.22.2" 6 | } 7 | } 8 | } 9 | 10 | variable "do_token" {} 11 | variable "pvt_key" {} 12 | 13 | provider "digitalocean" { 14 | token = var.do_token 15 | } 16 | 17 | data "digitalocean_ssh_key" "keyname" { 18 | name = "keyname" 19 | } 20 | -------------------------------------------------------------------------------- /DO_ssl_redirector/init.tf-orig: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | digitalocean = { 4 | source = "digitalocean/digitalocean" 5 | version = "1.22.2" 6 | } 7 | } 8 | } 9 | 10 | variable "do_token" {} 11 | variable "pvt_key" {} 12 | 13 | provider "digitalocean" { 14 | token = var.do_token 15 | } 16 | 17 | data "digitalocean_ssh_key" "keyname" { 18 | name = "keyname" 19 | } 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, Cedric Owens 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Linode_http_redirector/000-default.conf: -------------------------------------------------------------------------------- 1 | 2 | # The ServerName directive sets the request scheme, hostname and port that 3 | # the server uses to identify itself. This is used when creating 4 | # redirection URLs. In the context of virtual hosts, the ServerName 5 | # specifies what hostname must appear in the request's Host: header to 6 | # match this virtual host. For the default virtual host (this file) this 7 | # value is not decisive as it is used as a last resort host regardless. 8 | # However, you must set it for any further virtual host explicitly. 9 | #ServerName www.example.com 10 | 11 | DocumentRoot /var/www/html 12 | ServerName www.domainhere 13 | RewriteEngine On 14 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 15 | RewriteCond %{HTTP:Authorization} ^startofauthstring 16 | RewriteRule ^.*$ http://c2IPhere%{REQUEST_URI} [P] 17 | ProxyPassReverse / http://c2IPhere 18 | RewriteRule ^.*$ - [R=404,L] 19 | ServerAlias domainhere 20 | 21 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 22 | # error, crit, alert, emerg. 23 | # It is also possible to configure the loglevel for particular 24 | # modules, e.g. 25 | #LogLevel info ssl:warn 26 | 27 | ErrorLog ${APACHE_LOG_DIR}/error.log 28 | CustomLog ${APACHE_LOG_DIR}/access.log combined 29 | 30 | # For most configuration files from conf-available/, which are 31 | # enabled or disabled at a global level, it is possible to 32 | # include a line for only one particular virtual host. For example the 33 | # following line enables the CGI configuration for this host only 34 | # after it has been globally disabled with "a2disconf". 35 | #Include conf-available/serve-cgi-bin.conf 36 | 37 | 38 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 39 | -------------------------------------------------------------------------------- /Linode_http_redirector/000-default.conf-orig: -------------------------------------------------------------------------------- 1 | 2 | # The ServerName directive sets the request scheme, hostname and port that 3 | # the server uses to identify itself. This is used when creating 4 | # redirection URLs. In the context of virtual hosts, the ServerName 5 | # specifies what hostname must appear in the request's Host: header to 6 | # match this virtual host. For the default virtual host (this file) this 7 | # value is not decisive as it is used as a last resort host regardless. 8 | # However, you must set it for any further virtual host explicitly. 9 | #ServerName www.example.com 10 | 11 | DocumentRoot /var/www/html 12 | ServerName www.domainhere 13 | RewriteEngine On 14 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 15 | RewriteCond %{HTTP:Authorization} ^startofauthstring 16 | RewriteRule ^.*$ http://c2IPhere%{REQUEST_URI} [P] 17 | ProxyPassReverse / http://c2IPhere 18 | RewriteRule ^.*$ - [R=404,L] 19 | ServerAlias domainhere 20 | 21 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 22 | # error, crit, alert, emerg. 23 | # It is also possible to configure the loglevel for particular 24 | # modules, e.g. 25 | #LogLevel info ssl:warn 26 | 27 | ErrorLog ${APACHE_LOG_DIR}/error.log 28 | CustomLog ${APACHE_LOG_DIR}/access.log combined 29 | 30 | # For most configuration files from conf-available/, which are 31 | # enabled or disabled at a global level, it is possible to 32 | # include a line for only one particular virtual host. For example the 33 | # following line enables the CGI configuration for this host only 34 | # after it has been globally disabled with "a2disconf". 35 | #Include conf-available/serve-cgi-bin.conf 36 | 37 | 38 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 39 | -------------------------------------------------------------------------------- /Linode_http_redirector/Linode-mod_rewrite-redirector-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "*******************************************************************" 4 | echo " Welcome to the Terraform Script Runner to Set Up Your Redirector! " 5 | echo "*******************************************************************" 6 | echo "" 7 | echo "Have you already installed terraform? (Y/N)?" 8 | read installed 9 | 10 | if [[ ("$installed" == "N") || ("$installed" == "n") ]];then 11 | ostype=$(uname) 12 | if [[ "$ostype" == "Linux" ]]; then 13 | echo "attempting to install terraform (linux install)..." 14 | curl -o ~/terraform.zip https://releases.hashicorp.com/terraform/0.13.1/terraform_0.13.1_linux_amd64.zip 15 | mkdir -p ~/opt/terraform 16 | sudo apt install unzip 17 | unzip ~/terraform.zip -d ~/opt/terraform 18 | echo "Next add terraform to your path (append export PATH=$PATH:~/opt/terraform/bin to the end)" 19 | nano ~/.bashrc 20 | . .bashrc 21 | elif [[ "$ostype" == "Darwin" ]]; then 22 | echo "Attempting to install terraform (macOS Homebrew install)..." 23 | brew tap hashicorp/tap 24 | brew install hashicorp/tap/terraform 25 | 26 | fi 27 | fi 28 | echo "=====>Enter the name you want to call your Linode redirector" 29 | read linodeName 30 | echo "=====>Enter the src IP that you will ssh into your redirector infra from (i.e., terraform will set up a firewall only allowing ssh/admin access in from this src IP" 31 | read adminIP 32 | echo "=====>Enter the IP address of the backend C2 server that the redirector will sit in front of (only the redirector will have access to ports 443 and/or 80 on this host)" 33 | read c2IP 34 | echo "=====>Enter your Linode Personal Access Token" 35 | read linodeToken 36 | echo "=====>Enter the local path to the ssh public key you want to load onto this host for ssh access (ex: ~/.ssh/id_rsa.pub)" 37 | read pubKey 38 | echo "=====>Enter the local path to the ssh private key that you want Terraform to use to ssh into this Linode host (ex: ~/.ssh/id_rsa)" 39 | read privKey 40 | echo "=====>Enter the domain name for your redirector. AFTER THE SCRIPT RUNS, BE SURE TO SET UP DNS RECORDS TO POINT TO THIS REDIRECTOR'S IP ADDRESS" 41 | read domain 42 | echo "=====>Enter the user agent string that you want the redirector to use to allow access to your back end C2 (i.e., the unique user agent in your C2 agent)" 43 | read uAgent 44 | echo "=====>Do you have an authorization token (ex: bearer token) that you want to use for redirecting? (Y/N)" 45 | read authAns 46 | 47 | if [[ ("$authAns" == "Y") || ("$authAns" == "y") ]];then 48 | echo "=====>Enter the first few characters of the auth string that are consistent (ex: for a token with Bearer [random] you would enter Bearer here)" 49 | read authString 50 | sed -i -e "s/startofauthstring/$authString/g" 000-default.conf 51 | sed -i -e "s/startofauthstring/$authString/g" htaccess 52 | else 53 | sed -i -e '15d' 000-default.conf 54 | sed -i -e '3d' htaccess 55 | fi 56 | 57 | sed -i -e "s/myc2-1/$linodeName/g" init.tf 58 | sed -i -e 's|publickeyhere|'"$pubKey"'|g' init.tf 59 | sed -i -e 's|privatekeyhere|'"$privKey"'|g' init.tf 60 | sed -i -e "s/127.0.0.1/$adminIP/g" init.tf 61 | sed -i -e "s/10.0.0.0/$c2IP/g" init.tf 62 | sed -i -e "s/mylinodetoken/$linodeToken/g" init.tf 63 | sed -i -e "s/domainhere/$domain/g" init.tf 64 | sed -i -e "s/domainhere/$domain/g" 000-default.conf 65 | sed -i -e 's|useragenthere|'"$uAgent"'|g' 000-default.conf 66 | sed -i -e "s/c2IPhere/$c2IP/g" 000-default.conf 67 | sed -i -e "s/domainhere/$domain/g" htaccess 68 | sed -i -e 's|useragenthere|'"$uAgent"'|g' htaccess 69 | sed -i -e "s/c2IPhere/$c2IP/g" htaccess 70 | 71 | terraform init 72 | echo "====>Running terraform plan for the new redirector..." 73 | terraform plan 74 | echo "====>Applying the terraform plan..." 75 | terraform apply 76 | cp init.tf-orig init.tf 77 | cp 000-default.conf-orig 000-default.conf 78 | cp htaccess-orig htaccess 79 | -------------------------------------------------------------------------------- /Linode_http_redirector/apache2.conf: -------------------------------------------------------------------------------- 1 | # This is the main Apache server configuration file. It contains the 2 | # configuration directives that give the server its instructions. 3 | # See http://httpd.apache.org/docs/2.4/ for detailed information about 4 | # the directives and /usr/share/doc/apache2/README.Debian about Debian specific 5 | # hints. 6 | # 7 | # 8 | # Summary of how the Apache 2 configuration works in Debian: 9 | # The Apache 2 web server configuration in Debian is quite different to 10 | # upstream's suggested way to configure the web server. This is because Debian's 11 | # default Apache2 installation attempts to make adding and removing modules, 12 | # virtual hosts, and extra configuration directives as flexible as possible, in 13 | # order to make automating the changes and administering the server as easy as 14 | # possible. 15 | 16 | # It is split into several files forming the configuration hierarchy outlined 17 | # below, all located in the /etc/apache2/ directory: 18 | # 19 | # /etc/apache2/ 20 | # |-- apache2.conf 21 | # | `-- ports.conf 22 | # |-- mods-enabled 23 | # | |-- *.load 24 | # | `-- *.conf 25 | # |-- conf-enabled 26 | # | `-- *.conf 27 | # `-- sites-enabled 28 | # `-- *.conf 29 | # 30 | # 31 | # * apache2.conf is the main configuration file (this file). It puts the pieces 32 | # together by including all remaining configuration files when starting up the 33 | # web server. 34 | # 35 | # * ports.conf is always included from the main configuration file. It is 36 | # supposed to determine listening ports for incoming connections which can be 37 | # customized anytime. 38 | # 39 | # * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ 40 | # directories contain particular configuration snippets which manage modules, 41 | # global configuration fragments, or virtual host configurations, 42 | # respectively. 43 | # 44 | # They are activated by symlinking available configuration files from their 45 | # respective *-available/ counterparts. These should be managed by using our 46 | # helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See 47 | # their respective man pages for detailed information. 48 | # 49 | # * The binary is called apache2. Due to the use of environment variables, in 50 | # the default configuration, apache2 needs to be started/stopped with 51 | # /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not 52 | # work with the default configuration. 53 | 54 | 55 | # Global configuration 56 | # 57 | 58 | # 59 | # ServerRoot: The top of the directory tree under which the server's 60 | # configuration, error, and log files are kept. 61 | # 62 | # NOTE! If you intend to place this on an NFS (or otherwise network) 63 | # mounted filesystem then please read the Mutex documentation (available 64 | # at ); 65 | # you will save yourself a lot of trouble. 66 | # 67 | # Do NOT add a slash at the end of the directory path. 68 | # 69 | #ServerRoot "/etc/apache2" 70 | 71 | # 72 | # The accept serialization lock file MUST BE STORED ON A LOCAL DISK. 73 | # 74 | #Mutex file:${APACHE_LOCK_DIR} default 75 | 76 | # 77 | # The directory where shm and other runtime files will be stored. 78 | # 79 | 80 | DefaultRuntimeDir ${APACHE_RUN_DIR} 81 | 82 | # 83 | # PidFile: The file in which the server should record its process 84 | # identification number when it starts. 85 | # This needs to be set in /etc/apache2/envvars 86 | # 87 | PidFile ${APACHE_PID_FILE} 88 | 89 | # 90 | # Timeout: The number of seconds before receives and sends time out. 91 | # 92 | Timeout 300 93 | 94 | # 95 | # KeepAlive: Whether or not to allow persistent connections (more than 96 | # one request per connection). Set to "Off" to deactivate. 97 | # 98 | KeepAlive On 99 | 100 | # 101 | # MaxKeepAliveRequests: The maximum number of requests to allow 102 | # during a persistent connection. Set to 0 to allow an unlimited amount. 103 | # We recommend you leave this number high, for maximum performance. 104 | # 105 | MaxKeepAliveRequests 100 106 | 107 | # 108 | # KeepAliveTimeout: Number of seconds to wait for the next request from the 109 | # same client on the same connection. 110 | # 111 | KeepAliveTimeout 5 112 | 113 | 114 | # These need to be set in /etc/apache2/envvars 115 | User ${APACHE_RUN_USER} 116 | Group ${APACHE_RUN_GROUP} 117 | 118 | # 119 | # HostnameLookups: Log the names of clients or just their IP addresses 120 | # e.g., www.apache.org (on) or 204.62.129.132 (off). 121 | # The default is off because it'd be overall better for the net if people 122 | # had to knowingly turn this feature on, since enabling it means that 123 | # each client request will result in AT LEAST one lookup request to the 124 | # nameserver. 125 | # 126 | HostnameLookups Off 127 | 128 | # ErrorLog: The location of the error log file. 129 | # If you do not specify an ErrorLog directive within a 130 | # container, error messages relating to that virtual host will be 131 | # logged here. If you *do* define an error logfile for a 132 | # container, that host's errors will be logged there and not here. 133 | # 134 | ErrorLog ${APACHE_LOG_DIR}/error.log 135 | 136 | # 137 | # LogLevel: Control the severity of messages logged to the error_log. 138 | # Available values: trace8, ..., trace1, debug, info, notice, warn, 139 | # error, crit, alert, emerg. 140 | # It is also possible to configure the log level for particular modules, e.g. 141 | # "LogLevel info ssl:warn" 142 | # 143 | LogLevel warn 144 | 145 | # Include module configuration: 146 | IncludeOptional mods-enabled/*.load 147 | IncludeOptional mods-enabled/*.conf 148 | 149 | # Include list of ports to listen on 150 | Include ports.conf 151 | 152 | 153 | # Sets the default security model of the Apache2 HTTPD server. It does 154 | # not allow access to the root filesystem outside of /usr/share and /var/www. 155 | # The former is used by web applications packaged in Debian, 156 | # the latter may be used for local directories served by the web server. If 157 | # your system is serving content from a sub-directory in /srv you must allow 158 | # access here, or in any related virtual host. 159 | 160 | Options FollowSymLinks 161 | AllowOverride None 162 | Require all denied 163 | 164 | 165 | 166 | AllowOverride None 167 | Require all granted 168 | 169 | 170 | 171 | Options Indexes FollowSymLinks 172 | AllowOverride All 173 | Require all granted 174 | 175 | 176 | # 177 | # Options Indexes FollowSymLinks 178 | # AllowOverride None 179 | # Require all granted 180 | # 181 | 182 | 183 | 184 | 185 | # AccessFileName: The name of the file to look for in each directory 186 | # for additional configuration directives. See also the AllowOverride 187 | # directive. 188 | # 189 | AccessFileName .htaccess 190 | 191 | # 192 | # The following lines prevent .htaccess and .htpasswd files from being 193 | # viewed by Web clients. 194 | # 195 | 196 | Require all denied 197 | 198 | 199 | 200 | # 201 | # The following directives define some format nicknames for use with 202 | # a CustomLog directive. 203 | # 204 | # These deviate from the Common Log Format definitions in that they use %O 205 | # (the actual bytes sent including headers) instead of %b (the size of the 206 | # requested file), because the latter makes it impossible to detect partial 207 | # requests. 208 | # 209 | # Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. 210 | # Use mod_remoteip instead. 211 | # 212 | LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined 213 | LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined 214 | LogFormat "%h %l %u %t \"%r\" %>s %O" common 215 | LogFormat "%{Referer}i -> %U" referer 216 | LogFormat "%{User-agent}i" agent 217 | 218 | # Include of directories ignores editors' and dpkg's backup files, 219 | # see README.Debian for details. 220 | 221 | # Include generic snippets of statements 222 | IncludeOptional conf-enabled/*.conf 223 | 224 | # Include the virtual host configurations: 225 | IncludeOptional sites-enabled/*.conf 226 | 227 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 228 | -------------------------------------------------------------------------------- /Linode_http_redirector/htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 3 | RewriteCond %{HTTP:Authorization} ^startofauthstring 4 | RewriteRule ^.*$ http://c2IPhere%{REQUEST_URI} [P] 5 | ProxyPassReverse / http://c2IPhere 6 | RewriteRule ^.*$ - [R=404,L] 7 | -------------------------------------------------------------------------------- /Linode_http_redirector/htaccess-orig: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 3 | RewriteCond %{HTTP:Authorization} ^startofauthstring 4 | RewriteRule ^.*$ http://c2IPhere%{REQUEST_URI} [P] 5 | ProxyPassReverse / http://c2IPhere 6 | RewriteRule ^.*$ - [R=404,L] 7 | -------------------------------------------------------------------------------- /Linode_http_redirector/init.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | linode = { 4 | source = "linode/linode" 5 | version = "1.14.3" 6 | } 7 | } 8 | } 9 | 10 | provider "linode" { 11 | token = "mylinodetoken" 12 | } 13 | 14 | resource "linode_instance" "myc2-1" { 15 | image = "linode/ubuntu20.04" 16 | label = "myc2-1" 17 | region = "us-west" 18 | type = "g6-nanode-1" 19 | authorized_keys = [chomp(file("publickeyhere"))] 20 | connection { 21 | host = self.ip_address 22 | user = "root" 23 | type = "ssh" 24 | private_key = chomp(file("privatekeyhere")) 25 | timeout = "2m" 26 | } 27 | 28 | provisioner "file" { 29 | source = "000-default.conf" 30 | destination = "/root/000-default.conf" 31 | } 32 | 33 | provisioner "file" { 34 | source = "apache2.conf" 35 | destination = "/root/apache2.conf" 36 | } 37 | 38 | provisioner "file" { 39 | source = "htaccess" 40 | destination = "/root/.htaccess" 41 | } 42 | 43 | provisioner "remote-exec" { 44 | inline = [ 45 | "sudo apt-get update -y && sudo apt-get upgrade -y", 46 | "sudo apt-get -y install ufw", 47 | "sudo ufw default allow outgoing", 48 | "sudo ufw allow from 127.0.0.1 to any port 22", 49 | "sudo ufw allow 80", 50 | "sudo ufw --force enable", 51 | "sudo apt-get install apache2 -y", 52 | "sudo a2enmod rewrite proxy proxy_http ssl proxy_connect", 53 | "sudo mv /root/000-default.conf /etc/apache2/sites-available/000-default.conf", 54 | "sudo mv /root/apache2.conf /etc/apache2/apache2.conf", 55 | "sudo mv /root/.htaccess /var/www/html/.htaccess", 56 | "sudo service apache2 restart", 57 | ] 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Linode_http_redirector/init.tf-orig: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | linode = { 4 | source = "linode/linode" 5 | version = "1.14.3" 6 | } 7 | } 8 | } 9 | 10 | provider "linode" { 11 | token = "mylinodetoken" 12 | } 13 | 14 | resource "linode_instance" "myc2-1" { 15 | image = "linode/ubuntu20.04" 16 | label = "myc2-1" 17 | region = "us-west" 18 | type = "g6-nanode-1" 19 | authorized_keys = [chomp(file("publickeyhere"))] 20 | connection { 21 | host = self.ip_address 22 | user = "root" 23 | type = "ssh" 24 | private_key = chomp(file("privatekeyhere")) 25 | timeout = "2m" 26 | } 27 | 28 | provisioner "file" { 29 | source = "000-default.conf" 30 | destination = "/root/000-default.conf" 31 | } 32 | 33 | provisioner "file" { 34 | source = "apache2.conf" 35 | destination = "/root/apache2.conf" 36 | } 37 | 38 | provisioner "file" { 39 | source = "htaccess" 40 | destination = "/root/.htaccess" 41 | } 42 | 43 | provisioner "remote-exec" { 44 | inline = [ 45 | "sudo apt-get update -y && sudo apt-get upgrade -y", 46 | "sudo apt-get -y install ufw", 47 | "sudo ufw default allow outgoing", 48 | "sudo ufw allow from 127.0.0.1 to any port 22", 49 | "sudo ufw allow 80", 50 | "sudo ufw --force enable", 51 | "sudo apt-get install apache2 -y", 52 | "sudo a2enmod rewrite proxy proxy_http ssl proxy_connect", 53 | "sudo mv /root/000-default.conf /etc/apache2/sites-available/000-default.conf", 54 | "sudo mv /root/apache2.conf /etc/apache2/apache2.conf", 55 | "sudo mv /root/.htaccess /var/www/html/.htaccess", 56 | "sudo service apache2 restart", 57 | ] 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Linode_ssl_redirector/000-default.conf: -------------------------------------------------------------------------------- 1 | 2 | # The ServerName directive sets the request scheme, hostname and port that 3 | # the server uses to identify itself. This is used when creating 4 | # redirection URLs. In the context of virtual hosts, the ServerName 5 | # specifies what hostname must appear in the request's Host: header to 6 | # match this virtual host. For the default virtual host (this file) this 7 | # value is not decisive as it is used as a last resort host regardless. 8 | # However, you must set it for any further virtual host explicitly. 9 | #ServerName www.example.com 10 | 11 | DocumentRoot /var/www/html 12 | ServerName www.domainhere 13 | SSLEngine On 14 | SSLProxyEngine On 15 | SSLProxyVerify none 16 | SSLProxyCheckPeerCN off 17 | SSLProxyCheckPeerName off 18 | RewriteEngine On 19 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 20 | RewriteCond %{HTTP:Authorization} ^startofauthstring 21 | RewriteRule ^.*$ https://c2IPhere%{REQUEST_URI} [P] 22 | ProxyPassReverse / https://c2IPhere 23 | RewriteRule ^.*$ - [R=404,L] 24 | ServerAlias domainhere 25 | SSLCertificateFile /etc/letsencrypt/live/www.domainhere/cert.pem 26 | SSLCertificateKeyFile /etc/letsencrypt/live/www.domainhere/privkey.pem 27 | 28 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 29 | # error, crit, alert, emerg. 30 | # It is also possible to configure the loglevel for particular 31 | # modules, e.g. 32 | #LogLevel info ssl:warn 33 | 34 | ErrorLog ${APACHE_LOG_DIR}/error.log 35 | CustomLog ${APACHE_LOG_DIR}/access.log combined 36 | 37 | # For most configuration files from conf-available/, which are 38 | # enabled or disabled at a global level, it is possible to 39 | # include a line for only one particular virtual host. For example the 40 | # following line enables the CGI configuration for this host only 41 | # after it has been globally disabled with "a2disconf". 42 | #Include conf-available/serve-cgi-bin.conf 43 | 44 | 45 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 46 | -------------------------------------------------------------------------------- /Linode_ssl_redirector/000-default.conf-orig: -------------------------------------------------------------------------------- 1 | 2 | # The ServerName directive sets the request scheme, hostname and port that 3 | # the server uses to identify itself. This is used when creating 4 | # redirection URLs. In the context of virtual hosts, the ServerName 5 | # specifies what hostname must appear in the request's Host: header to 6 | # match this virtual host. For the default virtual host (this file) this 7 | # value is not decisive as it is used as a last resort host regardless. 8 | # However, you must set it for any further virtual host explicitly. 9 | #ServerName www.example.com 10 | 11 | DocumentRoot /var/www/html 12 | ServerName www.domainhere 13 | SSLEngine On 14 | SSLProxyEngine On 15 | SSLProxyVerify none 16 | SSLProxyCheckPeerCN off 17 | SSLProxyCheckPeerName off 18 | RewriteEngine On 19 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 20 | RewriteCond %{HTTP:Authorization} ^startofauthstring 21 | RewriteRule ^.*$ https://c2IPhere%{REQUEST_URI} [P] 22 | ProxyPassReverse / https://c2IPhere 23 | RewriteRule ^.*$ - [R=404,L] 24 | ServerAlias domainhere 25 | SSLCertificateFile /etc/letsencrypt/live/www.domainhere/cert.pem 26 | SSLCertificateKeyFile /etc/letsencrypt/live/www.domainhere/privkey.pem 27 | 28 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 29 | # error, crit, alert, emerg. 30 | # It is also possible to configure the loglevel for particular 31 | # modules, e.g. 32 | #LogLevel info ssl:warn 33 | 34 | ErrorLog ${APACHE_LOG_DIR}/error.log 35 | CustomLog ${APACHE_LOG_DIR}/access.log combined 36 | 37 | # For most configuration files from conf-available/, which are 38 | # enabled or disabled at a global level, it is possible to 39 | # include a line for only one particular virtual host. For example the 40 | # following line enables the CGI configuration for this host only 41 | # after it has been globally disabled with "a2disconf". 42 | #Include conf-available/serve-cgi-bin.conf 43 | 44 | 45 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 46 | -------------------------------------------------------------------------------- /Linode_ssl_redirector/Linode-mod_rewrite-redirector-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "*******************************************************************" 4 | echo " Welcome to the Terraform Script Runner to Set Up Your Redirector! " 5 | echo "*******************************************************************" 6 | echo "" 7 | echo "Have you already installed terraform? (Y/N)?" 8 | read installed 9 | 10 | if [[ ("$installed" == "N") || ("$installed" == "n") ]];then 11 | ostype=$(uname) 12 | if [[ "$ostype" == "Linux" ]]; then 13 | echo "attempting to install terraform (linux install)..." 14 | curl -o ~/terraform.zip https://releases.hashicorp.com/terraform/0.13.1/terraform_0.13.1_linux_amd64.zip 15 | mkdir -p ~/opt/terraform 16 | sudo apt install unzip 17 | unzip ~/terraform.zip -d ~/opt/terraform 18 | echo "Next add terraform to your path (append export PATH=$PATH:~/opt/terraform/bin to the end)" 19 | nano ~/.bashrc 20 | . .bashrc 21 | elif [[ "$ostype" == "Darwin" ]]; then 22 | echo "Attempting to install terraform (macOS Homebrew install)..." 23 | brew tap hashicorp/tap 24 | brew install hashicorp/tap/terraform 25 | 26 | fi 27 | fi 28 | echo "=====>Enter the name you want to call your Linode redirector" 29 | read linodeName 30 | echo "=====>Enter the src IP that you will ssh into your redirector infra from (i.e., terraform will set up a firewall only allowing ssh/admin access in from this src IP" 31 | read adminIP 32 | echo "=====>Enter the IP address of the backend C2 server that the redirector will sit in front of (only the redirector will have access to ports 443 and/or 80 on this host)" 33 | read c2IP 34 | echo "=====>Enter your Linode Personal Access Token" 35 | read linodeToken 36 | echo "=====>Enter the local path to the ssh public key you want to load onto this host for ssh access (ex: ~/.ssh/id_rsa.pub)" 37 | read pubKey 38 | echo "=====>Enter the local path to the ssh private key that you want Terraform to use to ssh into this Linode host (ex: ~/.ssh/id_rsa)" 39 | read privKey 40 | echo "=====>Enter the domain name for your redirector. AFTER THE SCRIPT RUNS, BE SURE TO SET UP DNS RECORDS TO POINT TO THIS REDIRECTOR'S IP ADDRESS" 41 | read domain 42 | echo "=====>Enter the user agent string that you want the redirector to use to allow access to your back end C2 (i.e., the unique user agent in your C2 agent)" 43 | read uAgent 44 | echo "=====>Do you have an authorization token (ex: bearer token) that you want to use for redirecting? (Y/N)" 45 | read authAns 46 | 47 | if [[ ("$authAns" == "Y") || ("$authAns" == "y") ]];then 48 | echo "=====>Enter the first few characters of the auth string that are consistent (ex: for a token with Bearer [random] you would enter Bearer here)" 49 | read authString 50 | sed -i -e "s/startofauthstring/$authString/g" 000-default.conf 51 | sed -i -e "s/startofauthstring/$authString/g" htaccess 52 | else 53 | sed -i -e '20d' 000-default.conf 54 | sed -i -e '10d' htaccess 55 | fi 56 | 57 | sed -i -e "s/myc2-1/$linodeName/g" init.tf 58 | sed -i -e 's|publickeyhere|'"$pubKey"'|g' init.tf 59 | sed -i -e 's|privatekeyhere|'"$privKey"'|g' init.tf 60 | sed -i -e "s/127.0.0.1/$adminIP/g" init.tf 61 | sed -i -e "s/10.0.0.0/$c2IP/g" init.tf 62 | sed -i -e "s/mylinodetoken/$linodeToken/g" init.tf 63 | sed -i -e "s/domainhere/$domain/g" init.tf 64 | sed -i -e "s/domainhere/$domain/g" 000-default.conf 65 | sed -i -e 's|useragenthere|'"$uAgent"'|g' 000-default.conf 66 | sed -i -e "s/c2IPhere/$c2IP/g" 000-default.conf 67 | sed -i -e "s/domainhere/$domain/g" htaccess 68 | sed -i -e 's|useragenthere|'"$uAgent"'|g' htaccess 69 | sed -i -e "s/c2IPhere/$c2IP/g" htaccess 70 | 71 | terraform init 72 | echo "====>Running terraform plan for the new redirector..." 73 | terraform plan 74 | echo "====>Applying the terraform plan..." 75 | terraform apply 76 | cp init.tf-orig init.tf 77 | cp 000-default.conf-orig 000-default.conf 78 | cp htaccess-orig htaccess 79 | -------------------------------------------------------------------------------- /Linode_ssl_redirector/apache2.conf: -------------------------------------------------------------------------------- 1 | # This is the main Apache server configuration file. It contains the 2 | # configuration directives that give the server its instructions. 3 | # See http://httpd.apache.org/docs/2.4/ for detailed information about 4 | # the directives and /usr/share/doc/apache2/README.Debian about Debian specific 5 | # hints. 6 | # 7 | # 8 | # Summary of how the Apache 2 configuration works in Debian: 9 | # The Apache 2 web server configuration in Debian is quite different to 10 | # upstream's suggested way to configure the web server. This is because Debian's 11 | # default Apache2 installation attempts to make adding and removing modules, 12 | # virtual hosts, and extra configuration directives as flexible as possible, in 13 | # order to make automating the changes and administering the server as easy as 14 | # possible. 15 | 16 | # It is split into several files forming the configuration hierarchy outlined 17 | # below, all located in the /etc/apache2/ directory: 18 | # 19 | # /etc/apache2/ 20 | # |-- apache2.conf 21 | # | `-- ports.conf 22 | # |-- mods-enabled 23 | # | |-- *.load 24 | # | `-- *.conf 25 | # |-- conf-enabled 26 | # | `-- *.conf 27 | # `-- sites-enabled 28 | # `-- *.conf 29 | # 30 | # 31 | # * apache2.conf is the main configuration file (this file). It puts the pieces 32 | # together by including all remaining configuration files when starting up the 33 | # web server. 34 | # 35 | # * ports.conf is always included from the main configuration file. It is 36 | # supposed to determine listening ports for incoming connections which can be 37 | # customized anytime. 38 | # 39 | # * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ 40 | # directories contain particular configuration snippets which manage modules, 41 | # global configuration fragments, or virtual host configurations, 42 | # respectively. 43 | # 44 | # They are activated by symlinking available configuration files from their 45 | # respective *-available/ counterparts. These should be managed by using our 46 | # helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See 47 | # their respective man pages for detailed information. 48 | # 49 | # * The binary is called apache2. Due to the use of environment variables, in 50 | # the default configuration, apache2 needs to be started/stopped with 51 | # /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not 52 | # work with the default configuration. 53 | 54 | 55 | # Global configuration 56 | # 57 | 58 | # 59 | # ServerRoot: The top of the directory tree under which the server's 60 | # configuration, error, and log files are kept. 61 | # 62 | # NOTE! If you intend to place this on an NFS (or otherwise network) 63 | # mounted filesystem then please read the Mutex documentation (available 64 | # at ); 65 | # you will save yourself a lot of trouble. 66 | # 67 | # Do NOT add a slash at the end of the directory path. 68 | # 69 | #ServerRoot "/etc/apache2" 70 | 71 | # 72 | # The accept serialization lock file MUST BE STORED ON A LOCAL DISK. 73 | # 74 | #Mutex file:${APACHE_LOCK_DIR} default 75 | 76 | # 77 | # The directory where shm and other runtime files will be stored. 78 | # 79 | 80 | DefaultRuntimeDir ${APACHE_RUN_DIR} 81 | 82 | # 83 | # PidFile: The file in which the server should record its process 84 | # identification number when it starts. 85 | # This needs to be set in /etc/apache2/envvars 86 | # 87 | PidFile ${APACHE_PID_FILE} 88 | 89 | # 90 | # Timeout: The number of seconds before receives and sends time out. 91 | # 92 | Timeout 300 93 | 94 | # 95 | # KeepAlive: Whether or not to allow persistent connections (more than 96 | # one request per connection). Set to "Off" to deactivate. 97 | # 98 | KeepAlive On 99 | 100 | # 101 | # MaxKeepAliveRequests: The maximum number of requests to allow 102 | # during a persistent connection. Set to 0 to allow an unlimited amount. 103 | # We recommend you leave this number high, for maximum performance. 104 | # 105 | MaxKeepAliveRequests 100 106 | 107 | # 108 | # KeepAliveTimeout: Number of seconds to wait for the next request from the 109 | # same client on the same connection. 110 | # 111 | KeepAliveTimeout 5 112 | 113 | 114 | # These need to be set in /etc/apache2/envvars 115 | User ${APACHE_RUN_USER} 116 | Group ${APACHE_RUN_GROUP} 117 | 118 | # 119 | # HostnameLookups: Log the names of clients or just their IP addresses 120 | # e.g., www.apache.org (on) or 204.62.129.132 (off). 121 | # The default is off because it'd be overall better for the net if people 122 | # had to knowingly turn this feature on, since enabling it means that 123 | # each client request will result in AT LEAST one lookup request to the 124 | # nameserver. 125 | # 126 | HostnameLookups Off 127 | 128 | # ErrorLog: The location of the error log file. 129 | # If you do not specify an ErrorLog directive within a 130 | # container, error messages relating to that virtual host will be 131 | # logged here. If you *do* define an error logfile for a 132 | # container, that host's errors will be logged there and not here. 133 | # 134 | ErrorLog ${APACHE_LOG_DIR}/error.log 135 | 136 | # 137 | # LogLevel: Control the severity of messages logged to the error_log. 138 | # Available values: trace8, ..., trace1, debug, info, notice, warn, 139 | # error, crit, alert, emerg. 140 | # It is also possible to configure the log level for particular modules, e.g. 141 | # "LogLevel info ssl:warn" 142 | # 143 | LogLevel warn 144 | 145 | # Include module configuration: 146 | IncludeOptional mods-enabled/*.load 147 | IncludeOptional mods-enabled/*.conf 148 | 149 | # Include list of ports to listen on 150 | Include ports.conf 151 | 152 | 153 | # Sets the default security model of the Apache2 HTTPD server. It does 154 | # not allow access to the root filesystem outside of /usr/share and /var/www. 155 | # The former is used by web applications packaged in Debian, 156 | # the latter may be used for local directories served by the web server. If 157 | # your system is serving content from a sub-directory in /srv you must allow 158 | # access here, or in any related virtual host. 159 | 160 | Options FollowSymLinks 161 | AllowOverride None 162 | Require all denied 163 | 164 | 165 | 166 | AllowOverride None 167 | Require all granted 168 | 169 | 170 | 171 | Options Indexes FollowSymLinks 172 | AllowOverride All 173 | Require all granted 174 | 175 | 176 | # 177 | # Options Indexes FollowSymLinks 178 | # AllowOverride None 179 | # Require all granted 180 | # 181 | 182 | 183 | 184 | 185 | # AccessFileName: The name of the file to look for in each directory 186 | # for additional configuration directives. See also the AllowOverride 187 | # directive. 188 | # 189 | AccessFileName .htaccess 190 | 191 | # 192 | # The following lines prevent .htaccess and .htpasswd files from being 193 | # viewed by Web clients. 194 | # 195 | 196 | Require all denied 197 | 198 | 199 | 200 | # 201 | # The following directives define some format nicknames for use with 202 | # a CustomLog directive. 203 | # 204 | # These deviate from the Common Log Format definitions in that they use %O 205 | # (the actual bytes sent including headers) instead of %b (the size of the 206 | # requested file), because the latter makes it impossible to detect partial 207 | # requests. 208 | # 209 | # Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. 210 | # Use mod_remoteip instead. 211 | # 212 | LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined 213 | LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined 214 | LogFormat "%h %l %u %t \"%r\" %>s %O" common 215 | LogFormat "%{Referer}i -> %U" referer 216 | LogFormat "%{User-agent}i" agent 217 | 218 | # Include of directories ignores editors' and dpkg's backup files, 219 | # see README.Debian for details. 220 | 221 | # Include generic snippets of statements 222 | IncludeOptional conf-enabled/*.conf 223 | 224 | # Include the virtual host configurations: 225 | IncludeOptional sites-enabled/*.conf 226 | 227 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 228 | -------------------------------------------------------------------------------- /Linode_ssl_redirector/htaccess: -------------------------------------------------------------------------------- 1 | SSLEngine On 2 | SSLProxyEngine On 3 | SSLProxyVerify none 4 | SSLProxyCheckPeerCN off 5 | SSLProxyCheckPeerName off 6 | SSLCertificateFile /etc/letsencrypt/live/www.domainhere/cert.pem 7 | SSLCertificateKeyFile /etc/letsencrypt/live/www.domainhere/privkey.pem 8 | RewriteEngine on 9 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 10 | RewriteCond %{HTTP:Authorization} ^startofauthstring 11 | RewriteRule ^.*$ https://c2IPhere%{REQUEST_URI} [P] 12 | ProxyPassReverse / https://c2IPhere 13 | RewriteRule ^.*$ - [R=404,L] 14 | -------------------------------------------------------------------------------- /Linode_ssl_redirector/htaccess-orig: -------------------------------------------------------------------------------- 1 | SSLEngine On 2 | SSLProxyEngine On 3 | SSLProxyVerify none 4 | SSLProxyCheckPeerCN off 5 | SSLProxyCheckPeerName off 6 | SSLCertificateFile /etc/letsencrypt/live/www.domainhere/cert.pem 7 | SSLCertificateKeyFile /etc/letsencrypt/live/www.domainhere/privkey.pem 8 | RewriteEngine on 9 | RewriteCond %{HTTP_USER_AGENT} "useragenthere" [NC] 10 | RewriteCond %{HTTP:Authorization} ^startofauthstring 11 | RewriteRule ^.*$ https://c2IPhere%{REQUEST_URI} [P] 12 | ProxyPassReverse / https://c2IPhere 13 | RewriteRule ^.*$ - [R=404,L] 14 | -------------------------------------------------------------------------------- /Linode_ssl_redirector/init.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | linode = { 4 | source = "linode/linode" 5 | version = "1.14.3" 6 | } 7 | } 8 | } 9 | 10 | provider "linode" { 11 | token = "mylinodetoken" 12 | } 13 | 14 | resource "linode_instance" "myc2-1" { 15 | image = "linode/ubuntu20.04" 16 | label = "myc2-1" 17 | region = "us-west" 18 | type = "g6-nanode-1" 19 | authorized_keys = [chomp(file("publickeyhere"))] 20 | connection { 21 | host = self.ip_address 22 | user = "root" 23 | type = "ssh" 24 | private_key = chomp(file("privatekeyhere")) 25 | timeout = "2m" 26 | } 27 | 28 | provisioner "file" { 29 | source = "000-default.conf" 30 | destination = "/root/000-default.conf" 31 | } 32 | 33 | provisioner "file" { 34 | source = "apache2.conf" 35 | destination = "/root/apache2.conf" 36 | } 37 | 38 | provisioner "file" { 39 | source = "htaccess" 40 | destination = "/root/.htaccess" 41 | } 42 | 43 | provisioner "remote-exec" { 44 | inline = [ 45 | "sudo apt-get update -y && sudo apt-get upgrade -y", 46 | "sudo apt-get -y install ufw", 47 | "sudo ufw default allow outgoing", 48 | "sudo ufw allow from 127.0.0.1 to any port 22", 49 | "sudo ufw allow 80", 50 | "sudo ufw allow 443", 51 | "sudo ufw --force enable", 52 | "sudo apt-get install apache2 -y", 53 | "sudo a2enmod rewrite proxy proxy_http ssl proxy_connect", 54 | "sudo a2ensite default-ssl.conf", 55 | "sudo apt-get install -y software-properties-common", 56 | "sudo add-apt-repository universe", 57 | "sudo apt install -y certbot && sudo apt install -y python3-certbot-apache", 58 | "sudo certbot -n -d www.domainhere,domainhere --apache --register-unsafely-without-email --agree-tos --no-redirect", 59 | "sudo mv /root/000-default.conf /etc/apache2/sites-available/000-default.conf", 60 | "sudo mv /root/apache2.conf /etc/apache2/apache2.conf", 61 | "sudo mv /root/.htaccess /var/www/html/.htaccess", 62 | "sudo ufw deny 80", 63 | "sudo service apache2 restart", 64 | "sudo apt-get install git", 65 | ] 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /Linode_ssl_redirector/init.tf-orig: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | linode = { 4 | source = "linode/linode" 5 | version = "1.14.3" 6 | } 7 | } 8 | } 9 | 10 | provider "linode" { 11 | token = "mylinodetoken" 12 | } 13 | 14 | resource "linode_instance" "myc2-1" { 15 | image = "linode/ubuntu20.04" 16 | label = "myc2-1" 17 | region = "us-west" 18 | type = "g6-nanode-1" 19 | authorized_keys = [chomp(file("publickeyhere"))] 20 | connection { 21 | host = self.ip_address 22 | user = "root" 23 | type = "ssh" 24 | private_key = chomp(file("privatekeyhere")) 25 | timeout = "2m" 26 | } 27 | 28 | provisioner "file" { 29 | source = "000-default.conf" 30 | destination = "/root/000-default.conf" 31 | } 32 | 33 | provisioner "file" { 34 | source = "apache2.conf" 35 | destination = "/root/apache2.conf" 36 | } 37 | 38 | provisioner "file" { 39 | source = "htaccess" 40 | destination = "/root/.htaccess" 41 | } 42 | 43 | provisioner "remote-exec" { 44 | inline = [ 45 | "sudo apt-get update -y && sudo apt-get upgrade -y", 46 | "sudo apt-get -y install ufw", 47 | "sudo ufw default allow outgoing", 48 | "sudo ufw allow from 127.0.0.1 to any port 22", 49 | "sudo ufw allow 80", 50 | "sudo ufw allow 443", 51 | "sudo ufw --force enable", 52 | "sudo apt-get install apache2 -y", 53 | "sudo a2enmod rewrite proxy proxy_http ssl proxy_connect", 54 | "sudo a2ensite default-ssl.conf", 55 | "sudo apt-get install -y software-properties-common", 56 | "sudo add-apt-repository universe", 57 | "sudo apt install -y certbot && sudo apt install -y python3-certbot-apache", 58 | "sudo certbot -n -d www.domainhere,domainhere --apache --register-unsafely-without-email --agree-tos --no-redirect", 59 | "sudo mv /root/000-default.conf /etc/apache2/sites-available/000-default.conf", 60 | "sudo mv /root/apache2.conf /etc/apache2/apache2.conf", 61 | "sudo mv /root/.htaccess /var/www/html/.htaccess", 62 | "sudo ufw deny 80", 63 | "sudo service apache2 restart", 64 | "sudo apt-get install git", 65 | ] 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apache Mod_Rewrite Terrafrom Automation 2 | 3 | ![Image](flow.png) 4 | 5 | Bash scripts that take variables from the user and then call terraform scripts to automate standing up apache2 with mod_rewrite in front of C2 servers. Right now, this repo supports standing up redirectors in Linode or Digital Ocean, and I have different scripts for standing up http redirectors versus https redirectors. Since the mod_rewrite redirector setup scripts use a user agent value and optionally a bearer token, these redirectors are not C2 dependent and can work for any C2 that uses http or https. 6 | 7 | These bash and terraform scripts were built to be run on either Linux or macOS hosts, and first check to see if you have terraform installed. If terraform is not installed, the script will attempt to install it for you before proceeding. 8 | 9 | **NOTE: After running, terraform will start apache2 using the root user account. It is recommended that you log in, create a local user with sudo, and restart apache using that user account rather than root, since running tools as root is not recommended** 10 | 11 | ## Prerequisites 12 | 13 | - homebrew (to install terraform on macOS if you do not already have terraform installed) 14 | 15 | - You will need to generate a public/private key pair locally for use (ex: Linode will put the public key on the host you stand up and use your private key to ssh in) 16 | 17 | - For Digital Ocean, you will need to upload the public key that you plan to use to your DO to your DO account. 18 | 19 | - For standing up redirectors in Linode, you will need a Linode Personal Access Token (can be generated under the "API Tokens" link under your profile in the web console. For standing up redirectors in Digital Ocean, you will need a Digital Ocean API key (can be done via the web admin console page). 20 | 21 | - You will also need a domain name for the redirector you set up. Once the redirector is stood up you will need to login to the provider and update the DNS records to point to the newly stood up IP address. 22 | 23 | ## Instructions 24 | 25 | > cd into directory of your choice 26 | 27 | > chmod +x *.sh 28 | 29 | > ./[bash_script_you_are_running] 30 | 31 | ## Info on the types of bash scripts include 32 | 33 | ### 1. LINODE REDIRECTOR SCRIPTS: 34 | 35 | - Linode_ssl_redirector/Linode-mod_rewrite-redirector-setup.sh (stands up an ssl redirector using mod_rewrite on an Ubuntu Linode nanode 1GB host) 36 | 37 | - Linode_http_redirector/Linode-mod_rewrite-redirector-setup.sh (stands up a http (non-ssl) redirector using mod_rewrite on an Ubuntu Linode nanode 1GB host) 38 | 39 | The bash scripts above take the following inputs: 40 | 41 | - name for your Linode redirector host 42 | 43 | - source IP that you can use to ssh into your redirector (terraform will setup a ufw firewall that only allows ssh in from this source IP) 44 | 45 | - IP address of the backend C2 server that the redirector will sit in front of. Later, be sure to log into the back end C2 server and restrict http/https login only to the redirector so that your C2 server is not accessible publicly. I have some additional terraform scripts to help with this as well (https://github.com/cedowens/Linode_Terraform_Scripts, https://github.com/cedowens/Terraform_DigitalOcean_Scripts). 46 | 47 | - Your Linode personal access token 48 | 49 | - The local path to your ssh public key 50 | 51 | - The local path to your ssh private key **(note: the script currently works with ssh keys that are not password protected; I plan to update it soon to handle password protected ssh keys)** 52 | 53 | - Domain name for your redirector (this will be used in the Apache config files as well as by certbot to install ssl certificates for your domain; if using the ssl script this will also be used by letsencrypt to set up the ssl certs). As Linode spins the host up, I usually go ahead and change the IP address in my domain provider to the IP of the recently spun up redirector. The script will need records for both www.[domain] and [domain] so be sure to set DNS A records for both of those. 54 | 55 | - User Agent (This is the regex value for a user-agent string that you want to specify which will be added into the .htaccess and 000-default.conf files. I have copies of these locally with placeholder values, and the bash script replaces those placeholder values with what the user enters and later terraform remotely copies these files over to the newly stood up redirector). ***IT IS IMPORTANT TO MAKE SURE THAT YOUR REGEX WORKS HERE. I HAVE INCLUDED SOME EXAMPLES BELOW*** 56 | 57 | - For example, if you set a unique user agent string in your C2 client such as "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3; rv:10.0) Gecko/20100101 Firefox/10.0.9.1.5". You could then use a regex on the unique part of that user agent string. So in this example, when prompted for the user agent string in this script you could enter ***Firefox\/10.0.9.1.5***. Using this example, the script would then add ***Firefox\/10.0.9.1.5*** as ***RewriteCond %{HTTP_USER_AGENT} "Firefox\/10.0.9.1.5" [NC]*** in the 000-default.conf and .htaccess files. 58 | 59 | - Optional authorization token (if your C2 agent uses an Authorization token, you can include this here. Since the token would be random, you can just key in on the static portion of that header. For example if the C2 client uses a header of ***Authorization: Bearer [random value]*** then you can enter the static value of ***Bearer*** here and the script will then add ***Bearer*** as ***RewriteCond %{HTTP:Authorization} ^Bearer*** in the 000-default.conf and .htaccess files. 60 | 61 | Bash will then perform all of the variable replacements in the local init.tf, htaccess, and 000-default.conf files and then kick off a terraform plan and apply. Once you agree to the apply then terraform will stand up the Redirector in Linode. If you are using the **Linode_ssl_redirector/Linode-mod_rewrite-redirector-setup.sh** terraform will also install and run certbot to take care of letsencrypt certs for the domain you provided. Once done you can browse to your domain and everything will be up and running. 62 | 63 | ### 2. DIGITAL OCEAN REDIRECTOR SCRIPTS: 64 | - Linode_ssl_redirector/DO-mod_rewrite-redirector-setup.sh (stands up an ssl redirector using mod_rewrite on an Ubuntu DO droplet) 65 | 66 | - Linode_http_redirector/DO-mod_rewrite-redirector-setup.sh (stands up a http (non-ssl) redirector using mod_rewrite on an Ubuntu DO droplet) 67 | 68 | The bash scripts above take the following inputs: 69 | 70 | - name that you want to call your redirector DO droplet 71 | 72 | - source IP that you can use to ssh into your redirector (terraform will setup a ufw firewall that only allows ssh in from this source IP) 73 | 74 | - IP address of the backend C2 server that the redirector will sit in front of. Later, be sure to log into the back end C2 server and restrict http/https login only to the redirector so that your C2 server is not accessible publicly. I have some additional terraform scripts to help with this as well (https://github.com/cedowens/Linode_Terraform_Scripts, https://github.com/cedowens/Terraform_DigitalOcean_Scripts). 75 | 76 | - DO API key 77 | 78 | - The name of the ssh public key you have uploaded into DO (you will need to do this if you have not already done so) 79 | 80 | - The local path to your ssh private key **(note: the script currently works with ssh keys that are not password protected; I plan to update it soon to handle password protected ssh keys)** 81 | 82 | - Domain name for your redirector (this will be used in the Apache config files as well as by certbot to install ssl certificates for your domain; if using the ssl script this will also be used by letsencrypt to set up the ssl certs). As DO spins the host up, I usually go ahead and change the IP address in my domain provider to the IP of the recently spun up redirector. The script will need records for both www.[domain] and [domain] so be sure to set DNS A records for both of those. 83 | 84 | - User Agent (This is the regex value for a user-agent string that you want to specify which will be added into the .htaccess and 000-default.conf files. I have copies of these locally with placeholder values, and the bash script replaces those placeholder values with what the user enters and later terraform remotely copies these files over to the newly stood up redirector). ***IT IS IMPORTANT TO MAKE SURE THAT YOUR REGEX WORKS HERE. I HAVE INCLUDED SOME EXAMPLES BELOW***. If you stand everything up and the redirector is not working as expected, it may likely be that the regex entered may not be correct. You can then ssh into the redirector host and adjust the regex until you get it working if you have that issue. 85 | 86 | - For example, if you set a unique user agent string in your C2 client such as "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3; rv:10.0) Gecko/20100101 Firefox/10.0.9.1.5". You could then use a regex on the unique part of that user agent string. So in this example, when prompted for the user agent string in this script you could enter ***Firefox\/10.0.9.1.5***. Using this example, the script would then add ***Firefox\/10.0.9.1.5*** as ***RewriteCond %{HTTP_USER_AGENT} "Firefox\/10.0.9.1.5" [NC]*** in the 000-default.conf and .htaccess files. 87 | 88 | - Optional authorization token (if your C2 agent uses an Authorization token, you can include this here. Since the token would be random, you can just key in on the static portion of that header. For example if the C2 client uses a header of ***Authorization: Bearer [random value]*** then you can enter the static value of ***Bearer*** here and the script will then add ***Bearer*** as ***RewriteCond %{HTTP:Authorization} ^Bearer*** in the 000-default.conf and .htaccess files. If not needed, simply enter 'N' or 'n' to skip this mod_rewrite configuration. 89 | 90 | Bash will then perform all of the variable replacements in the local init.tf, htaccess, and 000-default.conf files and then kick off a terraform plan and apply. Once you agree to the apply then terraform will stand up the Redirector in DO. If you are using the **DO_ssl_redirector/DO-mod_rewrite-redirector-setup.sh** terraform will also install and run certbot to take care of letsencrypt certs for the domain you provided. Once done you can browse to your domain and everything will be up and running. 91 | -------------------------------------------------------------------------------- /flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/Mod_Rewrite_Automation/fadd4e32891c1c37c3c02e8a7a264ad4a9166a9e/flow.png --------------------------------------------------------------------------------