前言

Record CS二次开发,整理一下自己的思考,系列文章的第二篇,源码篇,众所周知,CS功能十分强大,强大在于它不止内置渗透工具,还可以加载其他程序在受害者主机去运行,调用程序的形式为.NET、Powershell、DLL、BOF、这里选取.NET再加上现在非常火的免杀做本篇文章内容,故文章内容为UI调用.NET、二开免杀。

目录

0x00UI调用.NET
0x01二开免杀

0x00UI调用.NET

CS中调用.NET的程序命令为Execute-Assembly,execute-assembly 命令将一个本地的.NET可执行文件作为Beacon的后渗透任务来运行。简单点来说就是C端(client)调用.NET程序,在受控端执行。那么二开这个功能的益处在哪呢?我们能把一些常用的.NET程序,加入到CS源码中,做程序自有功能,那么在渗透过程中,就可以通过UI或者命令行的形式去直接调用该.NET程序,想想CS和MSF,CS更火的原因大概就是因为UI的存在。

源码反编译在上一篇已经有了相应的讲解,那么有了源码,我们就需要对源码做相应分析,分析哪些源码是用来调用.NET的,搜索execute-assembly去查看源码逻辑。

经过分析后,原CS程序调用.NET的源码流程图如下图右侧,下图左侧为二开CS,添加UI调用.NET的代码逻辑

首先说说原CS自带调用.NET的形式Beacon Console,Beacon Console即为Beacon控制台下输入命令的形式,输入点如下图

在Beacon Console输入help查看一下execute-assembly所需参数

由上图可看出,执行.NET程序需要execute-assembly,后带file路径+args,那么在查看源码逻辑时,就需要重点关注这三个输入

在流程图中右侧可看出,Beacon Console箭头下为BeaconConsole.java,即输入命令后,源码逻辑会进入BeaconConsole.java,通过匹配输入字符去进入不同的代码段,假设输入内容为execute-assembly,那么进入的代码段则为下图内容

具体代码如下,可看到控制台输入字符匹配execute-assembly则会执行ExecuteAssembly函数

1
2
3
4
5
6
7
8
9
10
11
else if (var3.is("execute-assembly")) {
if (var3.verify("pZ")) {
//var4 = args
var4 = var3.popString();
//var10 = file路径
var10 = var3.popString();
this.master.ExecuteAssembly(var10, var4);
} else if (var3.isMissingArguments() && var3.verify("F")) {
var4 = var3.popString();
this.master.ExecuteAssembly(var4, "");
}

追踪ExecuteAssembly函数,则进入TaskBeacon.java

对代码做简单讲解,做了两个判断,两个判断都满足的情况下,执行ExecuteAssemblyJob对象的spawn函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void ExecuteAssembly(String var1, String var2) {
//判断载入程序是否为.NET程序
PEParser var3 = PEParser.load(CommonUtils.readFile(var1));
if (!var3.isProcessAssembly()) {
//不是的情况下,直接控制台输出错误提示
this.error("File " + var1 + " is not a process assembly (.NET EXE)");
} else {
//是的话执行如下代码
for(int var4 = 0; var4 < this.bids.length; ++var4) {
BeaconEntry var5 = DataUtils.getBeacon(this.data, this.bids[var4]);
//判断.NET是否为64位
if (var5.is64()) {
//var1跟var2分别是之前传递进来的file和args
(new ExecuteAssemblyJob(this, var1, var2, "x64")).spawn(this.bids[var4]);
} else {
(new ExecuteAssemblyJob(this, var1, var2, "x86")).spawn(this.bids[var4]);
}
}
}
}

追踪ExecuteAssemblyJob对象的spawn函数,发现spawn函数在ExecuteAssemblyJob继承的JobSimple内

从控制台输入到加载执行,整个代码逻辑大致如上,想一想该如何二开该功能,用UI调用.NET呢,首先需要有个UI到功能的枢纽,可通过对话框的形式,这个对话框里面可以有个按钮,按钮直接执行.NET程序,也可以通过输入框,输入对应的.NET程序路径和args,然后点击确定执行

有了思路,那么试着去做,再看一下这张图

UI下面的第一个箭头是default.cna,default.cna存放的为sleep脚本代码,通过sleep脚本语言去设计按钮UI,简单说下sleep,底层为Java所写,语言形式跟Go相似,这个内容就不详细叙说,在后一篇文章也会做相应讲解,通俗来说,CS中的default.cna就是按钮UI设计,查看default.cna源码,可看出代码对应匹配UI

1
2
3
4
5
menu "&custom" {
item "&custom" {
customDialog($1);
}
}

以新加的custom按钮举例,前为UI按钮,后为代码实现,即点击custom -> custom按钮后,会去AggressorBrige.java去查找customDialog,AggressorBridge.java其为枢纽,该段代码为自己二开时添加

同时需要在AggressorBridge.java中添加的还有如下两行代码

1
2
import MyCustomDialogs.customDialog;
Cortana.put(var1, "&customDialog", this);

匹配customDialog后,调用customDialog对象的show1函数,显示写的Dialog

点击DotNet则会执行TaskBeacon对象的ExecuteDotNet函数

ExecuteDotNet函数如下图,为把TaskBeacon中的ExecuteAssembly函数拿来复用的函数,改了文件名,做了var1,也就是file路径的修改

file路径直接从源码包里面获取

上图中的ExecuteDotNetAssemblyJob对象Copy自ExecuteAssemblyJob对象,改了对象名

这样,UI调用.NET即修改成功,看看成果,test.exe为打印Process,回显成功

0x01二开免杀

这里需要对CS生成的木马做一个相应的介绍,CS生成的其实本质上都是shellcode,所以对CS生成的木马做免杀,等同于shellcode免杀,或者也可以在加载器上面做改变

以Payload Generator生成shellcode做例

我们需要找到生成shellcode的代码处

追踪进行,查看代码逻辑,该代码段为生成.c文件,文件内容为shellcode

参考一下TideSec写的免杀文章

把如下代码放入ToC函数,当然也可以自己对shellcode做混淆

生成.c文件后,VS生成exe,免杀效果如下,免杀前后分别为16-6

参考文章

https://www.bilibili.com/video/BV1yz411i71Z?p=8
https://github.com/TideSec/BypassAntiVirus
https://www.freebuf.com/company-information/242596.html

▼更多精彩推荐,请关注▼