def test_trial_beacon_x86(self):
     path = os.path.join(
         os.path.dirname(__file__),
         "samples",
         "4d1d732125e4d1a3ba0571e0cd892cf8e0dce854387ee405f75df4dcfb0f616b.zip",
     )
     f = decrypt_sample(path)
     parser = cobaltstrikeConfig(f)
     conf = parser.parse_config()
     self.assertIn('header "CGGGGG"', conf.get("HttpGet_Metadata").get("Metadata"))
 def test_encrypted_x86(self):
     path = os.path.join(
         os.path.dirname(__file__),
         "samples",
         "7773169ca4ea81203a550dfebe53f091a8c57a3a5b12386e51c5a05194fef3ff.zip",
     )
     f = decrypt_sample(path)
     parser = cobaltstrikeConfig(f)
     conf = parser.parse_encrypted_config()
     self.assertEqual(conf.get("PublicKey_MD5"), "8ac540617dddcdf575f6dc207abb7344")
 def test_encrypted_x86_64(self):
     path = os.path.join(
         os.path.dirname(__file__),
         "samples",
         "10fd211ba97ddf12aecb1e7931d92c3ba37421c362cb1490e0203c1bd88ec141.zip",
     )
     f = decrypt_sample(path)
     parser = cobaltstrikeConfig(f)
     conf = parser.parse_encrypted_config()
     self.assertEqual(conf.get("PublicKey_MD5"), "d2c8ec15d925e2514714d619022f7cdf")
 def test_non_pe_x86(self):
     path = os.path.join(
         os.path.dirname(__file__),
         "samples",
         "13e954be0b0c022c392c956e9a800201a75dab7e288230b835bcdd4a9d68253d.zip",
     )
     f = decrypt_sample(path)
     parser = cobaltstrikeConfig(f)
     conf = parser.parse_encrypted_config()
     self.assertEqual(conf.get("HttpPostUri"), "/submit.php")
def get_beacon_data(url, arch):
    full_url = urljoin(url, URL_PATHS[arch])
    try:
        resp = requests.get(full_url,
                            timeout=30,
                            headers=EMPTY_UA_HEADERS,
                            verify=False)
    except requests.exceptions.RequestException as e:
        print('[-] Connection error: ', e)
        return

    if resp.status_code != 200:
        print('[-] Failed with HTTP status code: ', resp.status_code)
        return

    buf = resp.content

    # Check if it's a Trial beacon, therefore not xor encoded (not tested)
    eicar_offset = buf.find(b'EICAR-STANDARD-ANTIVIRUS-TEST-FILE')
    if eicar_offset != -1:
        return cobaltstrikeConfig(BytesIO(buf)).parse_config()

    offset = buf.find(b'\xff\xff\xff')
    if offset == -1:
        print('[-] Unexpected buffer received')
        return
    offset += 3
    key = struct.unpack_from('<I', buf, offset)[0]
    size = struct.unpack_from('<I', buf, offset + 4)[0] ^ key
    head_enc = struct.unpack_from('<I', buf, offset + 8)[0] ^ key
    head = head_enc & 0xffff

    # Taken directly from L8_get_beacon.py
    if head == 0x5a4d or head == 0x9090:
        decoded_data = b''
        for i in range(2 + offset // 4, len(buf) // 4 - 4):
            a = struct.unpack_from('<I', buf, i * 4)[0]
            b = struct.unpack_from('<I', buf, i * 4 + 4)[0]
            с = a ^ b
            decoded_data += struct.pack('<I', с)

        return cobaltstrikeConfig(BytesIO(decoded_data)).parse_config()
 def test_beacon_45_x86_64(self):
     path = os.path.join(
         os.path.dirname(__file__),
         "samples",
         "320a5f715aa5724c21013fc14bfe0a10893ce9723ebc25d9ae9f06f5517795d4.zip",
     )
     f = decrypt_sample(path)
     parser = cobaltstrikeConfig(f)
     conf = parser.parse_config()
     self.assertEqual(conf.get("Watermark_Hash"), "xi1knfb/QiftN2EAhdtcyw==")
     self.assertEqual(conf.get("Retry_Max_Attempts"), 0)
     self.assertEqual(conf.get("Retry_Increase_Attempts"), 0)
     self.assertEqual(conf.get("Retry_Duration"), 0)