CAPE-parsers 0.1.55__tar.gz → 0.1.56__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/PKG-INFO +1 -1
  2. cape_parsers-0.1.56/cape_parsers/CAPE/community/Amatera.py +186 -0
  3. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/KoiLoader.py +1 -1
  4. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/NitroBunnyDownloader.py +1 -1
  5. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/pyproject.toml +1 -1
  6. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/LICENSE +0 -0
  7. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/README.md +0 -0
  8. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/__init__.py +0 -0
  9. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/AgentTesla.py +0 -0
  10. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/Amadey.py +0 -0
  11. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/Arkei.py +0 -0
  12. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/AsyncRAT.py +0 -0
  13. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/AuroraStealer.py +0 -0
  14. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/Carbanak.py +0 -0
  15. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/CobaltStrikeBeacon.py +0 -0
  16. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/CobaltStrikeStager.py +0 -0
  17. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/DCRat.py +0 -0
  18. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/Fareit.py +0 -0
  19. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/LokiBot.py +0 -0
  20. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/Lumma.py +0 -0
  21. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/MonsterV2.py +0 -0
  22. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/MyKings.py +0 -0
  23. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/NanoCore.py +0 -0
  24. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/Nighthawk.py +0 -0
  25. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/Njrat.py +0 -0
  26. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/PhemedroneStealer.py +0 -0
  27. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/QuasarRAT.py +0 -0
  28. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/README.md +0 -0
  29. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/Snake.py +0 -0
  30. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/SparkRAT.py +0 -0
  31. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/Stealc.py +0 -0
  32. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/VenomRAT.py +0 -0
  33. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/WinosStager.py +0 -0
  34. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/XWorm.py +0 -0
  35. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/XenoRAT.py +0 -0
  36. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/community/__init__.py +0 -0
  37. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/AdaptixBeacon.py +0 -0
  38. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/AuraStealer.py +0 -0
  39. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Azorult.py +0 -0
  40. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/BitPaymer.py +0 -0
  41. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/BlackDropper.py +0 -0
  42. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Blister.py +0 -0
  43. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/BruteRatel.py +0 -0
  44. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/BumbleBee.py +0 -0
  45. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/DarkGate.py +0 -0
  46. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/DoppelPaymer.py +0 -0
  47. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/DridexLoader.py +0 -0
  48. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Formbook.py +0 -0
  49. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/GuLoader.py +0 -0
  50. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/IcedID.py +0 -0
  51. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/IcedIDLoader.py +0 -0
  52. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Latrodectus.py +0 -0
  53. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Oyster.py +0 -0
  54. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/PikaBot.py +0 -0
  55. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/PlugX.py +0 -0
  56. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/QakBot.py +0 -0
  57. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Quickbind.py +0 -0
  58. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/README.md +0 -0
  59. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/RedLine.py +0 -0
  60. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Remcos.py +0 -0
  61. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Rhadamanthys.py +0 -0
  62. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/SmokeLoader.py +0 -0
  63. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Socks5Systemz.py +0 -0
  64. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/SquirrelWaffle.py +0 -0
  65. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Strrat.py +0 -0
  66. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/WarzoneRAT.py +0 -0
  67. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/Zloader.py +0 -0
  68. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/__init__.py +0 -0
  69. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/CAPE/core/test_cape.py +0 -0
  70. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/RATDecoders/README.md +0 -0
  71. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/RATDecoders/__init__.py +0 -0
  72. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/RATDecoders/test_rats.py +0 -0
  73. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/__init__.py +0 -0
  74. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/BackOffLoader.py +0 -0
  75. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/BackOffPOS.py +0 -0
  76. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/BlackNix.py +0 -0
  77. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/BuerLoader.py +0 -0
  78. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/ChChes.py +0 -0
  79. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/Emotet.py +0 -0
  80. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/Enfal.py +0 -0
  81. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/EvilGrab.py +0 -0
  82. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/Greame.py +0 -0
  83. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/Hancitor.py +0 -0
  84. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/HttpBrowser.py +0 -0
  85. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/JavaDropper.py +0 -0
  86. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/Nymaim.py +0 -0
  87. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/Pandora.py +0 -0
  88. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/PoisonIvy.py +0 -0
  89. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/PredatorPain.py +0 -0
  90. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/Punisher.py +0 -0
  91. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/RCSession.py +0 -0
  92. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/REvil.py +0 -0
  93. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/RedLeaf.py +0 -0
  94. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/Retefe.py +0 -0
  95. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/Rozena.py +0 -0
  96. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/SmallNet.py +0 -0
  97. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/TSCookie.py +0 -0
  98. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/TrickBot.py +0 -0
  99. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/UrsnifV3.py +0 -0
  100. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/_ShadowTech.py +0 -0
  101. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/_VirusRat.py +0 -0
  102. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/_jRat.py +0 -0
  103. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/unrecom.py +0 -0
  104. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/deprecated/xRAT.py +0 -0
  105. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/malduck/LICENSE +0 -0
  106. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/malduck/README.md +0 -0
  107. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/malduck/__init__.py +0 -0
  108. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/malduck/test_malduck.py +0 -0
  109. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/mwcp/README.md +0 -0
  110. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/mwcp/__init__.py +0 -0
  111. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/mwcp/test_mwcp.py +0 -0
  112. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/utils/__init__.py +0 -0
  113. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/utils/aplib.py +0 -0
  114. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/utils/blzpack.py +0 -0
  115. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/utils/blzpack_lib.so +0 -0
  116. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/utils/dotnet_utils.py +0 -0
  117. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/utils/lznt1.py +0 -0
  118. {cape_parsers-0.1.55 → cape_parsers-0.1.56}/cape_parsers/utils/strings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CAPE-parsers
3
- Version: 0.1.55
3
+ Version: 0.1.56
4
4
  Summary: CAPE: Malware Configuration Extraction
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -0,0 +1,186 @@
1
+ import base64
2
+ import json
3
+ import pefile
4
+ import yara
5
+ import struct
6
+ import re
7
+ import ipaddress
8
+ from contextlib import suppress
9
+
10
+
11
+ DESCRIPTION = "Amatera Stealer parser"
12
+ AUTHOR = "YungBinary"
13
+
14
+ RULE_SOURCE = """
15
+ rule AmateraDecrypt
16
+ {
17
+ meta:
18
+ author = "YungBinary"
19
+ description = "Find Amatera XOR key"
20
+ strings:
21
+ $decrypt = {
22
+ A1 ?? ?? ?? ?? // mov eax, dword ptr ds:szXorKey ; "852149723"
23
+ 89 45 ?? // mov dword ptr [ebp+xor_key], eax
24
+ 8B 0D ?? ?? ?? ?? // mov ecx, dword ptr ds:szXorKey+4 ; "49723"
25
+ 89 4D ?? // mov dword ptr [ebp+xor_key+4], ecx
26
+ 66 8B 15 ?? ?? ?? ?? // mov dx, word ptr ds:szXorKey+8 ; "3"
27
+ 66 89 55 ?? // mov word ptr [ebp+xor_key+8], dx
28
+ 8D 45 ?? // lea eax, [ebp+xor_key]
29
+ 50 // push eax
30
+ E8 // call
31
+ }
32
+ condition:
33
+ uint16(0) == 0x5A4D and $decrypt
34
+ }
35
+ """
36
+
37
+
38
+ RULE_SOURCE_AES_KEY = """
39
+ rule AmateraAESKey
40
+ {
41
+ meta:
42
+ author = "YungBinary"
43
+ description = "Find Amatera AES key"
44
+ strings:
45
+ $aes_key_on_stack = {
46
+ 83 EC 2C // sub esp, 2Ch
47
+ C6 45 D4 ?? // mov byte ptr [ebp-2Ch], ??
48
+ C6 45 D5 ?? // mov byte ptr [ebp-2Bh], ??
49
+ C6 45 D6 ?? // mov byte ptr [ebp-2Ah], ??
50
+ C6 45 D7 ?? // mov byte ptr [ebp-29h], ??
51
+ C6 45 D8 ?? // mov byte ptr [ebp-28h], ??
52
+ C6 45 D9 ?? // mov byte ptr [ebp-27h], ??
53
+ C6 45 DA ?? // mov byte ptr [ebp-26h], ??
54
+ C6 45 DB ?? // mov byte ptr [ebp-25h], ??
55
+ C6 45 DC ?? // mov byte ptr [ebp-24h], ??
56
+ C6 45 DD ?? // mov byte ptr [ebp-23h], ??
57
+ C6 45 DE ?? // mov byte ptr [ebp-22h], ??
58
+ C6 45 DF ?? // mov byte ptr [ebp-21h], ??
59
+ C6 45 E0 ?? // mov byte ptr [ebp-20h], ??
60
+ C6 45 E1 ?? // mov byte ptr [ebp-1Fh], ??
61
+ C6 45 E2 ?? // mov byte ptr [ebp-1Eh], ??
62
+ C6 45 E3 ?? // mov byte ptr [ebp-1Dh], ??
63
+ C6 45 E4 ?? // mov byte ptr [ebp-1Ch], ??
64
+ C6 45 E5 ?? // mov byte ptr [ebp-1Bh], ??
65
+ C6 45 E6 ?? // mov byte ptr [ebp-1Ah], ??
66
+ C6 45 E7 ?? // mov byte ptr [ebp-19h], ??
67
+ C6 45 E8 ?? // mov byte ptr [ebp-18h], ??
68
+ C6 45 E9 ?? // mov byte ptr [ebp-17h], ??
69
+ C6 45 EA ?? // mov byte ptr [ebp-16h], ??
70
+ C6 45 EB ?? // mov byte ptr [ebp-15h], ??
71
+ C6 45 EC ?? // mov byte ptr [ebp-14h], ??
72
+ C6 45 ED ?? // mov byte ptr [ebp-13h], ??
73
+ C6 45 EE ?? // mov byte ptr [ebp-12h], ??
74
+ C6 45 EF ?? // mov byte ptr [ebp-11h], ??
75
+ C6 45 F0 ?? // mov byte ptr [ebp-10h], ??
76
+ C6 45 F1 ?? // mov byte ptr [ebp-0Fh], ??
77
+ C6 45 F2 ?? // mov byte ptr [ebp-0Eh], ??
78
+ C6 45 F3 ?? // mov byte ptr [ebp-0Dh], ??
79
+ C7 45 F4 10 00 00 00 // mov dword ptr [ebp-0Ch], 10h
80
+ }
81
+ condition:
82
+ uint16(0) == 0x5A4D and $aes_key_on_stack
83
+ }
84
+ """
85
+
86
+ DOMAIN_REGEX = r'^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$'
87
+
88
+
89
+ def yara_scan(raw_data: bytes, rule_source: str):
90
+ yara_rules = yara.compile(source=rule_source)
91
+ matches = yara_rules.match(data=raw_data)
92
+
93
+ for match in matches:
94
+ for block in match.strings:
95
+ for instance in block.instances:
96
+ return instance.offset
97
+
98
+
99
+ def extract_base64_strings(data: bytes, minchars: int, maxchars: int):
100
+ """
101
+ Generator that returns ASCII formatted base64 strings
102
+ """
103
+ apat = b"([A-Za-z0-9+/=]{" + str(minchars).encode() + b"," + str(maxchars).encode() + b"})\x00"
104
+ for s in re.findall(apat, data):
105
+ yield s.decode()
106
+
107
+
108
+ def xor_data(data, key):
109
+ decoded = bytearray()
110
+ for i in range(len(data)):
111
+ decoded.append(key[i % len(key)] ^ data[i])
112
+ return decoded
113
+
114
+
115
+ def is_public_ip(ip):
116
+ try:
117
+ # This will raise a ValueError if the IP format is incorrect
118
+ ip_obj = ipaddress.ip_address(ip.decode())
119
+ if ip_obj.is_private:
120
+ return False
121
+ return True
122
+ except Exception:
123
+ return False
124
+
125
+
126
+ def is_valid_domain(data):
127
+ try:
128
+ if re.fullmatch(DOMAIN_REGEX, data.decode()):
129
+ return True
130
+ return False
131
+ except Exception:
132
+ return False
133
+
134
+
135
+ def extract_config(data):
136
+ """
137
+ Extract Amatera malware configuration.
138
+ """
139
+ config_dict = {}
140
+
141
+ with suppress(Exception):
142
+ pe = pefile.PE(data=data)
143
+ image_base = pe.OPTIONAL_HEADER.ImageBase
144
+
145
+ # Identify XOR key decryption routine and extract key
146
+ offset = yara_scan(data, RULE_SOURCE)
147
+ if not offset:
148
+ return config_dict
149
+ key_str_va = struct.unpack('i', data[offset + 1: offset + 5])[0]
150
+ key_str = pe.get_string_at_rva(key_str_va - image_base, max_length=20) + b'\x00'
151
+
152
+ # Extract AES 256 key
153
+ aes_key_offset = yara_scan(data, RULE_SOURCE_AES_KEY)
154
+ aes_key = bytearray()
155
+ if aes_key_offset:
156
+ aes_block = data[aes_key_offset : aes_key_offset + 131]
157
+ for i in range(0, len(aes_block) - 4, 4):
158
+ aes_key.append(aes_block[i+6])
159
+
160
+ # Handle each base64 string -> decode -> decrypt with XOR key
161
+ for b64_str in extract_base64_strings(data, 8, 20):
162
+ try:
163
+ decoded = base64.b64decode(b64_str, validate=True)
164
+ decrypted = xor_data(decoded, key_str)
165
+ if not is_public_ip(decrypted) and not is_valid_domain(decrypted):
166
+ continue
167
+
168
+ config_dict["CNCs"] = [f"https://{decrypted.decode()}"]
169
+
170
+ if aes_key:
171
+ config_dict["cryptokey"] = aes_key.hex()
172
+ config_dict["cryptokey_type"] = "AES"
173
+
174
+ return config_dict
175
+ except Exception:
176
+ continue
177
+
178
+ return config_dict
179
+
180
+
181
+ if __name__ == "__main__":
182
+ import sys
183
+
184
+ with open(sys.argv[1], "rb") as f:
185
+ config_json = json.dumps(extract_config(f.read()), indent=4)
186
+ print(config_json)
@@ -119,7 +119,7 @@ def extract_config(data):
119
119
  encoded_payload = remove_nulls(encoded_payload, encoded_payload_size)
120
120
  decoded_payload = xor_data(encoded_payload, xor_key)
121
121
  cncs = find_c2(decoded_payload)
122
- if cncs and list(filter(cncs, None)):
122
+ if cncs:
123
123
  config["CNCs"] = cncs
124
124
 
125
125
  return config
@@ -33,7 +33,7 @@ rule NitroBunnyDownloader
33
33
  hash = "960e59200ec0a4b5fb3b44e6da763f5fec4092997975140797d4eec491de411b"
34
34
  strings:
35
35
  $config1 = {E8 [3] 00 41 B8 ?? ?? 00 00 48 8D 15 [3] 00 48 89 C1 48 89 ?? E8 [3] 00}
36
- $config2 = {E8 [3] 00 48 8D 15 [3] 00 41 B8 ?? ?? 00 00 48 89 C1 48 89 ?? E8 [3] 00}
36
+ $config2 = {E8 [3] 00 48 8D 15 [3] 00 41 B8 ?? ?? 00 00 48 89 C1 48 89 ?? E8 [3] 00}
37
37
  $string1 = "X-Amz-User-Agent:" wide
38
38
  $string2 = "Amz-Security-Flag:" wide
39
39
  $string3 = "/cart" wide
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "CAPE-parsers"
3
- version = "0.1.55"
3
+ version = "0.1.56"
4
4
  description = "CAPE: Malware Configuration Extraction"
5
5
  authors = ["Kevin O'Reilly <kev@capesandbox.com>", "doomedraven <doomedraven@capesandbox.com>"]
6
6
  license = "MIT"
File without changes
File without changes