首页
社区
课程
招聘
[原创]CS 4.4 二开笔记:beacon 指令分析篇
2024-2-21 10:24 4452

[原创]CS 4.4 二开笔记:beacon 指令分析篇

2024-2-21 10:24
4452

CS 二开系列

CS 4.4 二开笔记:基础篇
CS 4.4 二开笔记:增强篇
CS 4.4 二开笔记:beacon 指令分析篇

前言

之前看了鸡哥针对beacon进行逆向,了解了beacon指令号的含义。还有WBG对beacon协议的分析,写得也很详细。因此重复的部分我就不过多赘述了。本文是从cs的源码出发进行分析,得到了更为详尽的信息,我在这里补全beacon的全部指令含义,希望能对大家有所帮助。

基础运行流程

aggressor 运行后启动本地web服务,输入与teamserver相同的账号密码后进入主界面。
teamserver 等待 aggressor 发送的加密指令,解密后进行处理。
teamserver 设置监听器(例如beacon_name https 443端口),将指令号放至端口等待beacon取(根据beacon的元数据来区别beacon)。
beacon 取回后设置 jobs,任务轮流执行。
图片描述
此处以jquery.profile中的get为例:
图片描述
get:
图片描述
跟get的流程一样,post在profile中也可进行设置:
图片描述
密钥解密 https://the-x.cn/cryptography/Rsa.aspx
元数据使用RSA加密,任务回传数据使用的是AES加密,其中AES的密钥是协商进行传递的。
图片描述

cna脚本注册源码事件流程

我是通过cna脚本事件来追踪指令号发送的流程的,在这里举例两个追踪流程的原理,第二个举例则为指令追踪的原理。

举例一

内置的cna脚本对接源码的原理如下:
图片描述
图片描述

举例二

default.cna默认Access选项中的openElevateDialog:(用于提权)
图片描述
对应在BeaconBridge.java中:
先是脚本注册:

1
2
3
4
5
public void scriptLoaded(ScriptInstance var1) {
...
Cortana.put(var1, "&openElevateDialog", this);
...
}

脚本触发函数:
图片描述
对应进入ElevateDialog界面(ElevateDialog.java):
可以看到下发指令号的类依靠的是TaskBeacon,
图片描述
针对代码进行进一步分析:

  • this.client:AggressorClient 的一个实例,是一个客户端对象。
  • this.bids:一个字符串数组,是当前 TaskBeacon 实例将要操作的信标(beacons)的ID。
  • var5.input("elevate " + var3 + " " + var4); // 调用 input 方法,发送 "elevate" 命令和两个参数(var3 和 var4)
  • var5.Elevate(var3, var4); // 调用 var5 实例的 Elevate 方法,传递之前获取的 "exploit" 和 "listener" 字符串。

进入TaskBeacon.java,可以看到Elevate函数:
图片描述
这个函数调用了ServiceEXE.java类(注意:不是BeaconExploits.java中的Elevate函数):
图片描述
可以看到此处主要使用的是TaskBeacon.PsExec函数:
从这里开始进行下发指令号,下发顺序为:10 -> 56
对应执行的操作是upload file和delete file。
图片描述
Elevate操作涉及到的指令号为 10 -> 100 -> 56,其中100指令号的实现是通过beacon/PostExInlineObject.java类实现的:
图片描述
在这里涉及到100指令号的操作有两个,通过debug发现是属于PostExInlineObject.java类中的go函数。
图片描述
可以看到go函数在PsExec中进行了调用:
图片描述
go函数的作用是用来发送一个BOF进行执行:
图片描述
运行原理如下:

  1. 获取远程beacon的架构(32位或64位)
  2. getObjectFile 方法获取与beacon架构相对应的对象文件的字节码。
  3. 如果对象文件为空,则报告错误。
  4. 使用 OBJExecutable 类解析对象文件。
  5. 如果对象文件解析出现错误,则报告错误。
  6. 检查对象文件的目标架构与beacon的架构是否一致,如果不一致,则报告错误。
  7. 从 OBJExecutable 实例中获取代码段、数据段以及重定位信息。
  8. 使用 CommandBuilder 构建命令,设置命令号(可能是用于BOF任务的特定命令号),并添加入口点、代码、数据和重定位段。
  9. 如果有链接错误,则报告错误。
  10. 如果一切正常,则使用 this.client.getConnection().call 方法将构建完成的命令发送到beacon。

我们自己重构beacon需要掌握如何发送beacon指令号,teamserver端调用指令号只需要实现下面的代码就可以了:

1
2
CommandBuilder var = new CommandBuilder();
var.setCommand(100);

beacon 指令号说明

此处结合鸡哥之前提供的指令号进行扩充,如有问题欢迎补充:

指令号 功能
1 spawn派生会话,原理是挂起线程rundll32线程注入dll
2 执行shell功能时进行调用
3 Exit退出功能,修改dwMilliseconds时间为0,如果为0就退出程序
4 Sleep设置beacon睡眠时间,接收数据包,取得修改的时间并进行修改dwMilliseconds
5 切换目录,使用SetCurrentDirectory切换当前进程的当前工作目录
6 Jitter设置
7 不存在
8 不存在
9 指定已打开进程来注入会话,原理就是远程线程注入,dllinject、shinject之类也会走这个case
10 upload上传文件
11 download 下载文件,先分割数据包获得需要下载的文件名,然后打开文件,不断读取文件内容,然后加密返回给teamserver
12 execute 执行程序,但不回显
13 spawnto,设置Beacon派生会话时使用的程序,当再执行spawn时,会判断启用哪个程序进行注入,而不是再注入默认的rundll32.exe
14 不存在
15 没有命令参数,是与rportfwd端口转发相关的case,首先接收到访问目标机器的请求信息,然后发送给目标机器,然后中转机通过select模型等待信息返回,最后把rportfwd端口转发的信息返回
16 没有命令参数,是与rportfwd端口转发相关的case,首先接收到访问目标机器的请求信息,然后发送给目标机器,然后中转机通过select模型等待信息返回,最后把rportfwd端口转发的信息返回
17 不存在
18 desktop VNC远程桌面,x86 desktop VNC远程桌面(不注入进程),需要由vnc的dll,不建议用有点卡
19 download_cancel,取消相关下载文件
20 不存在
21 不存在
22 没有相关命令行,负责中转子beacon的传输数据
23 调用shutdow()断开与子Beacon的连接
24 beacon进程回调函数解密
25 不存在
26 不存在
27 获取当前令牌关联的用户ID
28 恢复Beacon原始令牌
29 修改文件时间戳
30 不存在
31 从目标进程中窃取访问令牌
32 PS,显示进程列表
33 结束指定进程
34 不存在
35 不存在
36 不存在
37 导入Powershell脚本以便后续调用
38 以其他用户权限执行程序,调用CreateProcessWithLogonW()函数,以某用户身份执行指定程序
39 显示当前所在目录
40 Job执行后数据的回传,当job执行后产生数据会用管道回传给beacon
41 查看Beacon中的所有任务,在list读取后台进行中的任务
42 jobkill命令,用于停止指定的已运行任务
43 Inject(x64) 指定已打开进程来注入会话,原理就是远程线程注入,dllinject、shinject之类也会走这个case ,流程与case 9 一样。
44 0原理也是挂起线程rundll32线程注入dll,流程都是一样的,只是在不同文件夹在rundll32.exe
45 VNC (x64) desktop VNC远程桌面(注入进程),需要由vnc的dll
46 VNC (x86) desktop VNC远程桌面(注入进程),需要由vnc的dll
47 暂停指定job
48 不存在
49 创建令牌
50 端口转发数据
51 暂停端口转发
52 开启stageTCP服务
53 TaskBeacon回调函数
54 mkdir,创建目录
55 drives,GetLogicalDrivers()列出目标机上所有的磁盘盘符
56 删除文件,先用GetFileAttributesA()获取到文件属性,进行判断是文件还是文件夹,如果是文件夹就遍历删除里面文件再删文件夹,如果是文件则直接删
57 开启stage管道服务
58 不存在
59 One-liner:启服务器,执行相应的ps命令,返回一个会话
60 PassTheHash
61 mimikatz的执行
62 Mimikatz Job执行后数据的回传
63 不存在
64 不存在
65 不存在
66 不存在
67 UploadRaw,上传raw
68 link通过管道连接SMB形式的Beacon
69 Spawnto (x64) 设置Beacon派生会话时使用的程序,执行流程与任务号13 spawnto x86一样
70 内存执行C#的可执行文件,首先传输invokeassembly.dll并注入到rundll32.exe,实现了在其内存中创建CLR环境,然后通过管道再将C#可执行文件读取到内存中,最后执行。
https://github.com/b4rtik/metasploit-execute-assembly/
71 流程与任务号70一样,区别只是传输dll的版本是x64的
72 putenv()设置环境变量
73 调用CopyFileA()复制文件
74 调用MoveFileA()移动文件
75 伪造子进程(jobs)的父进程为指定进程,jobs是指portscan等操作,不是派生会话操作
76 父进程欺骗,即指定所创建程序的父进程pid值,并执行该进程
77 getprivs,启用当前访问令牌所拥有的特权
78 在目标上执行程序(输出回显)
79 powershell任务getImportCradle
80 不存在
81 不存在
82 当在Pivoting->Listener(Reserve TCP Beacon)或oneliner,创建完成后再执行一条命令rportfwd 4444 windows/beacon_reverse_tcp,会调用此任务号,原理与rportfwd一致
83 进程参数欺骗:增加欺骗的参数
84 进程参数欺骗:删除欺骗的参数
85 进程参数欺骗:查询设置了哪些参数
86 Connect连接bind形式的TCP Beacon
87 流程与任务号70一样,作用也是内存执行C#的可执行文件,流程一样:首先传输invokeassembly.dll并注入到rundll32.exe,实现了在其内存中创建CLR环境,然后通过管道再将C#可执行文件读取到内存中,最后调用执行。区别是,不使用ImpersonateLoggedOnUser()当前线程模拟登陆用户进行操作,TokenHandle要在pth后才会生成并保存
88 流程与任务号71一样,区别是不使用ImpersonateLoggedOnUser()当前线程模拟登陆用户进行操作,TokenHandle要在pth后才会生成并保存
89 spawn 派生会话,跟指令号1对应,区别在于是否忽略token
90 Spawn (x64) 派生会话,跟指令号44对应,区别在于是否忽略token
91 ReflectiveDLL,patchDOSHeader
92 不存在
93 不存在
94 不存在
95 获取system权限
96 不存在
97 不存在
98 不存在
99 不存在
100 BOF内存执行
101 Screenshot

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2024-2-21 10:42 被bwner编辑 ,原因:
收藏
免费 4
打赏
分享
最新回复 (1)
雪    币: 1648
活跃值: (1095)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
非白即黑 2024-2-21 12:18
2
1
感谢分享
游客
登录 | 注册 方可回帖
返回