Last active
October 6, 2023 23:38
-
-
Save byt3bl33d3r/054e5c183a46c6c021a4bb8f1901c143 to your computer and use it in GitHub Desktop.
Caddyfile reverse proxy example for C2 platforms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
# This instructs Caddy to hit the LetsEncrypt staging endpoint, in production you should remove this. | |
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory | |
} | |
(proxy_upstream) { | |
# Enable access logging to STDOUT | |
log | |
# This is our list of naughty client User Agents that we don't want accessing our C2 | |
@ua_denylist { | |
header User-Agent curl* | |
} | |
# This is our list of naughty IPs that we want to prevent from accessing our C2 | |
@ip_denylist { | |
remote_ip 8.8.8.8/32 | |
} | |
header { | |
-Server | |
+X-Robots-Tag "noindex, nofollow, nosnippet, noarchive" | |
+X-Content-Type-Options "nosniff" | |
} | |
# Respond with a 403 if the client has a User Agent defined in our naughty list | |
# Lot more you can do with this (e.g. redirect to seperate domain), check the docs | |
respond @ua_denylist "Forbidden" 403 { | |
close | |
} | |
# Respond with a 403 if the client has an IP defined in our naughty list | |
# Lot more you can do with this (e.g. redirect to seperate domain), check the docs | |
respond @ip_denylist "Forbidden" 403 { | |
close | |
} | |
# Reverse proxy to our host "c2platform" on port 80 | |
# Caddy automatically adds a X-Forwarded-For header which is super useful for Cobalt Strike | |
reverse_proxy c2platform:80 { | |
header_up Host {upstream_hostport} | |
header_up X-Forwarded-Host {host} | |
header_up X-Forwarded-Port {port} | |
} | |
} | |
www.legitdomain.com { | |
# Use the proxy_upstream code snippet (defined above) | |
import proxy_upstream | |
} | |
legitdomain.com { | |
# Use the proxy_upstream code snippet (defined above) | |
import proxy_upstream | |
} |
Probably like this
@headers_matcher {
header “headers in c2 profile” “headers value in c2 profile”
}
reverse_proxy @headers_matcher "c2:port_bind"{
header_up Host {upstream_hostport}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Port {port}
}
redir https://www.google.com #default is redirect to google.com
I wanted to handle multiple user agents, so I decided to use a regex variant:
@ua_denylist {
header_regexp User-Agent (?i)(go-http|python|Expanse|curl|nocom|node-fetch)
}
You can also write:
www.legitdomain.com, legitdomain.com {
...
}
That way you can get rid of the import
statement.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think the best way is to reject the request which is mismatched in C2 profile, not "ua_denylist". (Similar like RedWarden)