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, ¶ms)
,后面就是上传了,所以如果把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消息,没啥问题