0x00 简介
在攻防演练中,使用云函数来隐藏 C&C 的 ip 地址已经成为了一种“标配”
在应急处置过程中,我们经常遇到 netstat -pantu | grep ip
无法找到安全设备关于红队外联的告警的情况
由于 C&C 的 ip 地址是一直变化的,所以常规的 netstat -pantu | grep ip
这种模式就可能行不通了
以目前国内厂商对云函数的支持来看,主要集中在 80, 443 这两个端口。所以如果要排查的服务器对外访问 80 和 443 不多的情况下还是可以一个一个分析的
但这终究是个麻烦事,所以有了今天的这篇文章
我们对抗云函数的方式无非就是从 DNS 解析下手
但是 Linux 默认的程序组合几乎无法实时获取到究竟是哪一个进程发起了对云函数的域名的 DNS 解析请求
所以,我们需要人工干预一下,将云函数的网站的解析地址换成我们自己的地址,之后通过筛选连接了我们指定的地址的 80 或者 443 端口的进程,获取到 pid 后再获取进程详细信息
0x01 查看 DNS 缓存记录
如果是 windows ,这件事是非常简单的,在 Linux 中就变得麻烦很多,我们需要使用下面的命令来进行获取 DNS 缓存记录
sudo killall -USR1 systemd-resolved
sudo journalctl -u systemd-resolved > ~/dns-cache.txt
cat ~/dns-cache.txt | grep tencentcs.com
如果攻击者使用了云函数,那么应该会保存 DNS 的解析记录,我们只需要将常见的云函数的网站地址作为筛选条件进行筛选即可,这里以腾讯云的云函数为例
常见云函数、CDN之类的网站地址有:
tencentcs.com
herokuapp.com
worker.dev
*.tk
假设获取到的域名为 service-123456.bj.tencentcs.com
0x02 服务器配置监控程序
当服务器对我们的监听端口发起了连接,就将发起连接的进程相关信息记录下来
此处 VPS ip 以 1.1.1.1 为例
#!/bin/bash
while true
do
sleep 0.1
pids=$(netstat -pantu | grep 1.1.1.1 | awk -F "/" '{print $1}' | awk -F " " '{print $NF}' | sort | uniq)
for one_pid in $pids
do
if [ $one_pid == "-" ]; then
continue
fi
echo "" >> $(pwd)/virus_info.txt
echo "[ lsof -p $one_pid ]" >> $(pwd)/virus_info.txt
lsof -p $one_pid >> $(pwd)/virus_info.txt
echo "" >> $(pwd)/virus_info.txt
echo "[ cat /proc/$one_pid/maps ]" >> $(pwd)/virus_info.txt
cat /proc/$one_pid/maps >> $(pwd)/virus_info.txt
echo "" >> $(pwd)/virus_info.txt
echo "[ ls -al /proc/$one_pid/exe ]" >> $(pwd)/virus_info.txt
ls -al /proc/$one_pid/exe >> $(pwd)/virus_info.txt
done
if [ -f "$(pwd)/virus_info.txt" ]; then
echo "Found it !"
exit
fi
done
0x03 修改 HOSTS 文件,建立解析记录
root 用户下执行,VPS IP 以 1.1.1.1
为例
echo "1.1.1.1 service-123456.bj.tencentcs.com" >> /etc/hosts
Linux 的 hosts 文件是不支持通配符的,也就是配置
*.tencentcs.com
是无效的所以,如果在 0x01 步骤未获取到云函数的具体域名,那就需要借助 Dnsmasq 这类程序或者外部网络设备来进行辅助,原理是一样的
0x04 在 VPS 上建立监听
mkdir listen_test
cd listen_test
python3 -m http.server 80
python3 -m http.server 443
0x05 使用 nmap 模拟对 C&C 的访问
virus_info.txt
文件内容如下
[ lsof -p 20657 ]
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nmap 20657 root cwd DIR 8,2 4096 524291 /home/join
nmap 20657 root rtd DIR 8,2 4096 2 /
nmap 20657 root txt REG 8,2 2961432 798351 /usr/bin/nmap
nmap 20657 root mem REG 8,2 47568 1581433 /lib/x86_64-linux-gnu/libnss_files-2.27.so
nmap 20657 root mem REG 8,2 97176 1581430 /lib/x86_64-linux-gnu/libnsl-2.27.so
nmap 20657 root mem REG 8,2 47576 1581435 /lib/x86_64-linux-gnu/libnss_nis-2.27.so
nmap 20657 root mem REG 8,2 39744 1581431 /lib/x86_64-linux-gnu/libnss_compat-2.27.so
nmap 20657 root mem REG 8,2 445768 798342 /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
nmap 20657 root mem REG 8,2 14560 1581426 /lib/x86_64-linux-gnu/libdl-2.27.so
nmap 20657 root mem REG 8,2 144976 1581438 /lib/x86_64-linux-gnu/libpthread-2.27.so
nmap 20657 root mem REG 8,2 2030928 1581423 /lib/x86_64-linux-gnu/libc-2.27.so
nmap 20657 root mem REG 8,2 96616 1581418 /lib/x86_64-linux-gnu/libgcc_s.so.1
nmap 20657 root mem REG 8,2 1700792 1581427 /lib/x86_64-linux-gnu/libm-2.27.so
nmap 20657 root mem REG 8,2 1594864 796948 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
nmap 20657 root mem REG 8,2 59408 798344 /usr/lib/x86_64-linux-gnu/liblinear.so.3.2.
nmap 20657 root mem REG 8,2 224048 798347 /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0
nmap 20657 root mem REG 8,2 116960 1573720 /lib/x86_64-linux-gnu/libz.so.1.2.11
nmap 20657 root mem REG 8,2 2917216 792886 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
nmap 20657 root mem REG 8,2 577312 792985 /usr/lib/x86_64-linux-gnu/libssl.so.1.1
nmap 20657 root mem REG 8,2 265344 792967 /usr/lib/x86_64-linux-gnu/libpcap.so.1.8.1
nmap 20657 root mem REG 8,2 464824 1573695 /lib/x86_64-linux-gnu/libpcre.so.3.13.3
nmap 20657 root mem REG 8,2 179152 1581419 /lib/x86_64-linux-gnu/ld-2.27.so
nmap 20657 root 0u CHR 136,1 0t0 4 /dev/pts/1
nmap 20657 root 1u CHR 136,1 0t0 4 /dev/pts/1
nmap 20657 root 2u CHR 136,1 0t0 4 /dev/pts/1
nmap 20657 root 3r CHR 5,0 0t0 13 /dev/tty
nmap 20657 root 4u IPv4 169623 0t0 TCP ubuntu:43930->service-123456.bj.tencentcs.com:domain (SYN_SENT)
[ cat /proc/20657/maps ]
55c0e5298000-55c0e53e6000 r-xp 00000000 08:02 798351 /usr/bin/nmap
55c0e55e6000-55c0e55eb000 r--p 0014e000 08:02 798351 /usr/bin/nmap
55c0e55eb000-55c0e576b000 rw-p 00153000 08:02 798351 /usr/bin/nmap
55c0e576b000-55c0e5792000 rw-p 00000000 00:00 0
55c0e66b7000-55c0e6c37000 rw-p 00000000 00:00 0 [heap]
7fe9f2ccb000-7fe9f2cd6000 r-xp 00000000 08:02 1581433 /lib/x86_64-linux-gnu/libnss_files-2.27.so
7fe9f2cd6000-7fe9f2ed5000 ---p 0000b000 08:02 1581433 /lib/x86_64-linux-gnu/libnss_files-2.27.so
...
...
7fe9f5d65000-7fe9f5d66000 rw-p 0002a000 08:02 1581419 /lib/x86_64-linux-gnu/ld-2.27.so
7fe9f5d66000-7fe9f5d67000 rw-p 00000000 00:00 0
7ffee5382000-7ffee53a3000 rw-p 00000000 00:00 0 [stack]
7ffee53a9000-7ffee53ac000 r--p 00000000 00:00 0 [vvar]
7ffee53ac000-7ffee53ae000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
[ ls -al /proc/20657/exe ]
lrwxrwxrwx 1 root root 0 Jul 2 15:03 /proc/20657/exe -> /usr/bin/nmap
我们可以获取到以下信息:
-
进程 pid 为 20657
-
启这个进程的二进制文件为 /usr/bin/nmap
-
启这个进程的时候攻击者所在的目录为 /home/join
-
启这个进程的用户为 root
Windows 也是同理,对于 CDN 的检查也可以参考这个模式
当然了,这种检测方式想绕过也非常简单,可以看看之前的文章,其中就涉及到这些知识点
0x06 往期文章
原文始发于微信公众号(NOP Team):与云函数&CDN的对抗 | 应急响应