专栏名称: HACK学习呀
HACK学习,专注于互联网安全与黑客精神;渗透测试,社会工程学,Python黑客编程,资源分享,Web渗透培训,电脑技巧,渗透技巧等,为广大网络安全爱好者一个交流分享学习的平台!
目录
相关文章推荐
HACK学习呀  ·  交易实战 | ... ·  2 天前  
51好读  ›  专栏  ›  HACK学习呀

魔改CobaltStrike:探究beacon里每个功能点是如何实现的

HACK学习呀  · 公众号  · 黑客  · 2021-06-05 12:26

正文


魔改CobaltStrike:命由己造(上)
1
概述

这次我们来探究 beacon 里每个功能点是如何实现的,以便日后更好地实现自定义 beacon 。因为有近百个相关功能点,所以文章就分了上下两部分。

项目地址如下:

https://github.com/mai1zhi2/CobaltstrikeSource


2
前情提要

我们从上篇协议剖析得文章中知道当 beacon 发送心跳包后, teamserver 会返回相应的任务号,并返回相应得任务信息, beacon 接收到任务信息后,会进入循环处理:

AllCase_10007F19() 里面就是 beacon 得全部命令功能,我们按反编译循环中的 case 号从低向高写, case 号与发送数据包的任务号是大同小异的。


3
功能剖析

spawn x86

case1 ,派生会话,原理是挂起方式启动 rundll32 并注入 dll

接收到的数据:

Createprocess() 以挂起方式启动 rundll32.exe

注意输入的标志 0x00000004 CREATE_SUSPENDED :

使用 VirtualAllocEx() 在目标 rundll32 进程申请内存空间:

WriteProcessMemory() 在申请的内存空间写入 dll

使用 VirtualProtectEx() 设置内存属性, PAGE_EXECUTE_READWRITE

设置 context 上下文,并恢复线程:


exit 退出

case3 Exit 退出功能,修改 dwMilliseconds 时间为 0

如果为 0 就调用 sub_10009BB0() 退出程序:


Sleep

case4 Sleep 设置 beacon 睡眠时间

接收数据包,取得修改的时间并进行修改 dwMilliseconds


Cd 切换目录

case 5 ,切换目录使用 S etCurrentDirectory 切换当前进程的当前工作目录。


Inject(x86)

case9 ,指定已打开进程来注入会话,原理就是远程线程注入, dllinject shinject 之类也会走这个 case

先用 openprocess() 打开目标进程:

目标申请空间后写入 dll 文件:

最后调用 CreateRemoteThread() 进行远程线程注入:


Upload 上传文件

case10 upload 上传文件,

首先分割 teamserver 回传的数据,得到上传的文件名,然后 wb 模式打开文件:

然后获得数据长度和内容,调用 fwrite 写入:


download 下载文件

case11 download 下载文件,先分割数据包获得需要下载的文件名,然后打开文件,不断读取文件内容,然后加密返回给 teamserver


execute 执行程序

case12 execute 执行程序,但不回显

直接使用 createprocess() 启动相应进程:


Spawnto(x86)

case13 spawnto ,设置 Beacon 派生会话时使用的程序

当再执行 spawn 时,会判断启用哪个程序进行注入,而不是再注入默认的 rundll32.exe


端口转发数据回传 ( 没有命令参数 )

case15 case16 这两个是与 rportfwd 端口转发相关的 case ,首先接收到访问目标机器的请求信息:

然后发送给目标机器,然后中转机通过 select 模型等待信息返回:

最后把 rportfwd 端口转发的信息返回:



desktopVNC 远程桌面

case18 x86 desktopVNC 远程桌面(不注入其他进程),不建议用 vnc


download_cancel 取消相关下载文件

case19 ,命令 beacon 取消相关的文件下载:


中转子 beacon 所发送的数据 ( 没有相关命令参数 )

case22 ,没有相关命令行,负责中转子 beacon 的数据传输(注意,不是端口转发的数据):



Unlink

case23 ,调用 shutdow() 断开与子 Beacon 的连接


Getuid

case27 ,获取当前令牌关联的用户 ID

使用 GetTokenInformation 检索令牌信息和 LookuoAccountSid 获取令牌 SID

最后拼接输出:


rev2self

case28 ,恢复 Beacon 原始令牌

调用 RevertToSelf() 终止当前用户标识的模拟并返回原始线程标记 :


steal_token

case31 ,从目标进程中窃取访问令牌

先打开进程,获取指定进程的句柄令牌,再用 ImpersonateLoggedOnUser 模拟一个登陆用户的访问令牌的安全上下文,最后用 DuplicateTokenEx 拷贝一个当前令牌相同权限的令牌


ps

case32 ,显示进程列表

使用 CreateToolhelp32Snapshot() Process32Next() 相关函数遍历系统进程信息,然后进行发送给服务器:


Kill

case33 ,结束指定进程

调用 TerminateProcess() 结束指定进程:


powershell-import

case37 ,导入 Powershell 脚本

导入相关的 ps 脚本(如 nishang )以便后续调用


Runas

case38 ,以其他用户权限执行程序

调用 CreateProcessWithLogonW() 函数,以某用户身份执行指定程序


Pwd

case39 ,显示当前所在目录

直接用 GetCurrentDirectoryA() 得到当前目录并返回:


Job 执行后数据的回传(没有相关命令)

case40 ,当 job(PortScan 之类的 ) 执行后产生数据会用管道回传给 beacon

Createfile() 创建管道:

SetNamedPipeHandleState() 设置管道 PIPE_READMODE_BYTE 模式:

调用 PeekNamedPipe() 读取管道内的数据:


Jobs

case41 ,查看 Beacon 中的所有任务,在 list 读取后台进行中的任务


jobkill

case42 ,结束一个在后台运行

调用 DisconnectNamedPipe() 与后台进程终止链接:


Inject(x64)

case43 ,指定已打开进程来注入会话,原理就是远程线程注入, dllinject shinject 之类也会走这个 case ,流程与 case9 一样。


Spawn(x64)

case44 ,派生会话( x64 ),原理也是挂起线程







请到「今天看啥」查看全文