以OrcaC2为例简单分析C2框架部分功能的实现
SpiritM0nK3y 发表于 江苏 技术文章 671浏览 · 2024-11-17 10:21

OrcaC2简介

看强网杯Master of DFIR - Phishing用的这个C2项目,简单分析一下OrcaC2的功能实现吧,项目地址:

https://github.com/Ptkatz/OrcaC2

分为四部分,Orca_Loader是导入Orca_Master生成的马用的,Orca_Master是客户端,Orca_Server是服务端,Orca_Puppet是被控端马的源码,都是用GO写的

环境搭建

先跑一下Orca_Master,发现是需要先编译好几个exe

根据install,手动编译 一下需要的东西

一些坑

在调试的时候发现一个问题,客户端和服务端之间经常断,但是心跳包是没问题的,尝试了以下方法

在server里面没找到通联相关的参数,在master里面找到了,把超时时间改长一点,还是不行,过两分钟然后就断了

之后我猜测可能心跳的问题?在server里面找到心跳相关的参数改一下,但是还是不行

再然后猜测可能是服务端获取的ip有问题?把网卡都禁用了只留一个虚拟机网卡

发现还是不行,用源码自己编译和用作者编译好的都会断,不知道为什么,不过问题不大,就是调试起来难受点

分析几个功能的实现

功能太多了,调了其中的三个看看吧

先看Orca_Master的main.go,核心在这里

跳转过去,发现这里是内置好了各种参数,和实现参数功能的源码,这里之挑选几个比较常见的看

generate/build功能

主要逻辑实现在generateCmd.go,打个断点,直接看

在这里获取stub、puppet的路径和aes的key、获取了时间戳

stub被读取为stubData,然后进入这里面

generateopt.BuildMap[fileType](stubData, host, dProtoStr, target, key, outputPath)

跟过去发现有个GenerateExe函数,传进了参数,进行了异或,生成了一个新的exe,根据前面调试看见的变量outputPath,可以认定新的exe就是loader.exe

这时候再来看看stub的源码

可以看到一开始是有默认值的

可以手动异或一下看看,发现跟Orca_Master里面type.go默认的值是一样的

GenerateExe就是把这些默认的字节替换,我们把生成的loader.exe扔进ida看看,可以验证我们的分析

然后继续看generateCmd,进入shellcode.PE2ShellCode(srcFile, dstFile, &params),后面就是上传了,所以如果把Orca_Puppet_win_x64.exe转化成.bin文件就是在这里了,步入看一下,经过了donutGen的处理

继续跟进,在这读入config和Orca_Puppet_win_x64,就生成了那个bin文件

再跟进

到这基本就可以判断是Donut混淆了,并且在引用的包里面也可以看到是(到这里如果再跟就是要分析Donut的源码了,看https://xz.aliyun.com/t/13920即可

master把Puppet.exe经过donutGen处理之后生成一个bin文件,传到server端,然后同时生成了一个loader.exe,把这个loader.exe传到被控段,运行这个loader.exe他会从server端下载那个bin文件,那怎么把这个bin运行起来的呢?初步看跟master、Puppet无关,看起来是loader.exe下载把数据保存在内存里,把内存区域标记为可执行,然后执行。所以如果想还原的话,把这个内存转储出来,应该是可行的。

解强网杯那个题的话,可以自己起个环境,生成一个loader.exe,调试改一下时间戳,或者patch一下loader.exe里面的server参数和bin文件名,把流量里的bin文件放在自己环境的服务端,就ok了

我们来尝试一下

这个loader运行后带起来一个conhost.exe,从内存里搜索数据确实可以搜索到key

但是要注意火绒剑转储出来的内存好像不全,用Windows进程管理器出来是没问题的

当然也可以直接找解混淆的项目https://github.com/volexity/donut-decryptor/

keylogger功能

先看master端,只是发送了一个请求

请求信息用aes加密了一下

server 只是起到一个类似消息转发的作用,所以直接看Orca_Puppet的源码实现,Orca_Puppet是被控端的源码,因为是要靠loader加载,不好调试,所以只静态分析,在mainapp找到keylogger

跟过去,发现是用这个gohook来获取键盘记录,对应码表是RawCodeMap

跟到RawCodeMap那边看看,是每个数字对应的按键,把hook到的数字对应的按键记录到sendCodeStr中

然后不管是正常结束了还是超时了,把sendCodeStr通过aes加密后发送回server端

dump功能

看被控端的源码,先寻找进程,然后判断权限,开个进程,然后在temp目录创建一个dmp文件

在后面是执行dumpopt.MiniDumpWriteDump,MiniDumpWriteDump函数动态加载 dbghelp.dll 库,获取 MiniDumpWriteDump函数的指针

然后就生成了转储文件

那怎么发回去的呢,dump里面没定义,那我们回来看master端源码,在这里看到发送下载请求,远端是被控端,local是master端

写lsass.dmp的进程是master端,server端并没有创建文件的行为

从源码里看好像就是master端直接在被控端下载的,所以应该不是先传到server端,然后master端再从server端下载。但是被控端没有公网ip,那是怎么传的呢?实时保存的?

可以看到是从FileSliceMsgChan中获取数据,然后写入到lsass.dmp里的,那FileSliceMsgChan是从哪来的,调试进不去,我们另辟蹊径,抓流量看看

这里因为网卡的问题,抓了两次,第一段是被控端到server端的,第二段是server端到master端的,所以并不是严格对应的。第一段可以看到数据分片从被控端传回了server端(192.168.192.1:6000)

第二段显示的是数据从server端分片传到了master端(192.168.192.34374),所以server应该只是起到流量转发功能,下载下来的文件是实时传的

file参数的源码跟dump参数中关于下载的部分的源码相同,所以也就知道了file参数是怎么下载文件的

在之前源码里可以看到所有的流量其实就是AES加密的,所以解一下流量,看见了fileDownload消息,没啥问题

0 条评论
某人
表情
可输入 255