CAPE-parsers 0.1.48__tar.gz → 0.1.50__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 (114) hide show
  1. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/PKG-INFO +1 -1
  2. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/Amadey.py +4 -9
  3. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/AuroraStealer.py +1 -1
  4. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/Stealc.py +11 -1
  5. cape_parsers-0.1.50/cape_parsers/CAPE/core/AuraStealer.py +100 -0
  6. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Latrodectus.py +4 -3
  7. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/pyproject.toml +1 -1
  8. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/LICENSE +0 -0
  9. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/README.md +0 -0
  10. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/__init__.py +0 -0
  11. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/AgentTesla.py +0 -0
  12. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/Arkei.py +0 -0
  13. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/AsyncRAT.py +0 -0
  14. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/Carbanak.py +0 -0
  15. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/CobaltStrikeBeacon.py +0 -0
  16. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/CobaltStrikeStager.py +0 -0
  17. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/DCRat.py +0 -0
  18. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/Fareit.py +0 -0
  19. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/KoiLoader.py +0 -0
  20. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/LokiBot.py +0 -0
  21. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/Lumma.py +0 -0
  22. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/NanoCore.py +0 -0
  23. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/Nighthawk.py +0 -0
  24. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/Njrat.py +0 -0
  25. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/PhemedroneStealer.py +0 -0
  26. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/QuasarRAT.py +0 -0
  27. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/README.md +0 -0
  28. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/Snake.py +0 -0
  29. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/SparkRAT.py +0 -0
  30. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/VenomRAT.py +0 -0
  31. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/XWorm.py +0 -0
  32. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/XenoRAT.py +0 -0
  33. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/__init__.py +0 -0
  34. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/community/monsterv2.py +0 -0
  35. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/AdaptixBeacon.py +0 -0
  36. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Azorult.py +0 -0
  37. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/BitPaymer.py +0 -0
  38. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/BlackDropper.py +0 -0
  39. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Blister.py +0 -0
  40. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/BruteRatel.py +0 -0
  41. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/BumbleBee.py +0 -0
  42. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/DarkGate.py +0 -0
  43. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/DoppelPaymer.py +0 -0
  44. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/DridexLoader.py +0 -0
  45. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Formbook.py +0 -0
  46. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/GuLoader.py +0 -0
  47. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/IcedID.py +0 -0
  48. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/IcedIDLoader.py +0 -0
  49. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Oyster.py +0 -0
  50. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/PikaBot.py +0 -0
  51. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/PlugX.py +0 -0
  52. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/QakBot.py +0 -0
  53. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Quickbind.py +0 -0
  54. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/README.md +0 -0
  55. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/RedLine.py +0 -0
  56. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Remcos.py +0 -0
  57. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Rhadamanthys.py +0 -0
  58. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/SmokeLoader.py +0 -0
  59. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Socks5Systemz.py +0 -0
  60. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/SquirrelWaffle.py +0 -0
  61. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Strrat.py +0 -0
  62. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/WarzoneRAT.py +0 -0
  63. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/Zloader.py +0 -0
  64. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/__init__.py +0 -0
  65. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/CAPE/core/test_cape.py +0 -0
  66. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/RATDecoders/README.md +0 -0
  67. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/RATDecoders/__init__.py +0 -0
  68. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/RATDecoders/test_rats.py +0 -0
  69. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/__init__.py +0 -0
  70. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/BackOffLoader.py +0 -0
  71. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/BackOffPOS.py +0 -0
  72. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/BlackNix.py +0 -0
  73. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/BuerLoader.py +0 -0
  74. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/ChChes.py +0 -0
  75. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/Emotet.py +0 -0
  76. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/Enfal.py +0 -0
  77. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/EvilGrab.py +0 -0
  78. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/Greame.py +0 -0
  79. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/Hancitor.py +0 -0
  80. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/HttpBrowser.py +0 -0
  81. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/JavaDropper.py +0 -0
  82. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/Nymaim.py +0 -0
  83. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/Pandora.py +0 -0
  84. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/PoisonIvy.py +0 -0
  85. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/PredatorPain.py +0 -0
  86. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/Punisher.py +0 -0
  87. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/RCSession.py +0 -0
  88. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/REvil.py +0 -0
  89. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/RedLeaf.py +0 -0
  90. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/Retefe.py +0 -0
  91. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/Rozena.py +0 -0
  92. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/SmallNet.py +0 -0
  93. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/TSCookie.py +0 -0
  94. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/TrickBot.py +0 -0
  95. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/UrsnifV3.py +0 -0
  96. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/_ShadowTech.py +0 -0
  97. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/_VirusRat.py +0 -0
  98. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/_jRat.py +0 -0
  99. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/unrecom.py +0 -0
  100. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/deprecated/xRAT.py +0 -0
  101. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/malduck/LICENSE +0 -0
  102. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/malduck/README.md +0 -0
  103. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/malduck/__init__.py +0 -0
  104. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/malduck/test_malduck.py +0 -0
  105. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/mwcp/README.md +0 -0
  106. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/mwcp/__init__.py +0 -0
  107. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/mwcp/test_mwcp.py +0 -0
  108. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/utils/__init__.py +0 -0
  109. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/utils/aplib.py +0 -0
  110. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/utils/blzpack.py +0 -0
  111. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/utils/blzpack_lib.so +0 -0
  112. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/utils/dotnet_utils.py +0 -0
  113. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/utils/lznt1.py +0 -0
  114. {cape_parsers-0.1.48 → cape_parsers-0.1.50}/cape_parsers/utils/strings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: CAPE-parsers
3
- Version: 0.1.48
3
+ Version: 0.1.50
4
4
  Summary: CAPE: Malware Configuration Extraction
5
5
  License: MIT
6
6
  Keywords: cape,parsers,malware,configuration
@@ -173,25 +173,20 @@ def extract_config(data):
173
173
  version = ""
174
174
  install_dir = ""
175
175
  install_file = ""
176
- ip_pattern = r"^(?:\d{1,3}\.){3}\d{1,3}$"
177
176
  version_pattern = r"^\d+\.\d{1,2}$"
178
177
  install_dir_pattern = r"^[0-9a-f]{10}$"
179
178
 
180
- i = 0
181
- while i < len(decoded_strings):
179
+ for i in range(len(decoded_strings)):
182
180
  s = decoded_strings[i]
183
- if re.match(ip_pattern, s):
184
- if i + 1 < len(decoded_strings):
185
- path = decoded_strings[i+1]
186
- final_config.setdefault("CNCs", []).append(f"http://{s}{path}")
187
- i += 1 # Skip next element as it has been processed
181
+ if s.endswith(".php"):
182
+ c2 = decoded_strings[i-1]
183
+ final_config.setdefault("CNCs", []).append(f"http://{c2}{s}")
188
184
  elif re.match(version_pattern, s):
189
185
  version = s
190
186
  elif re.match(install_dir_pattern, s):
191
187
  install_dir = s
192
188
  elif s.endswith(".exe"):
193
189
  install_file = s
194
- i += 1
195
190
 
196
191
  if version:
197
192
  final_config["version"] = version
@@ -32,7 +32,7 @@ def extract_config(data):
32
32
  key = item.split(":")[0].strip("{").strip('"')
33
33
  value = item.split(":")[1].strip('"')
34
34
  if key == "IP":
35
- config_dict["CNCs"] = [value]
35
+ config_dict["CNCs"] = [f"tcp://{value}"]
36
36
  elif key == "BuildID":
37
37
  config_dict["build"] = value
38
38
  else:
@@ -1,6 +1,7 @@
1
1
  import struct
2
2
  import pefile
3
3
  import yara
4
+ import ipaddress
4
5
  from contextlib import suppress
5
6
 
6
7
 
@@ -42,6 +43,13 @@ def yara_scan(raw_data):
42
43
  yield block.identifier, instance.offset
43
44
 
44
45
 
46
+ def _is_ip(ip):
47
+ try:
48
+ ipaddress.ip_address(ip)
49
+ return True
50
+ except Exception:
51
+ return False
52
+
45
53
  def xor_data(data, key):
46
54
  decoded = bytearray()
47
55
  for i in range(len(data)):
@@ -67,7 +75,9 @@ def parse_text(data):
67
75
  for line in lines:
68
76
  if line.startswith("http") and "://" in line:
69
77
  domain = line
70
- if line.startswith("/") and line[-4] == ".":
78
+ elif _is_ip(line):
79
+ domain = line
80
+ if line.startswith("/") and len(line) >= 4 and line[-4] == ".":
71
81
  uri = line
72
82
 
73
83
 
@@ -0,0 +1,100 @@
1
+ import json
2
+ import struct
3
+ from contextlib import suppress
4
+ from typing import Any, Dict, Tuple
5
+
6
+ import pefile
7
+ from Cryptodome.Cipher import AES
8
+ from Cryptodome.Util.Padding import unpad
9
+
10
+ # Define the format for the fixed-size header part.
11
+ # < : little-endian
12
+ # 32s : 32-byte string (for aes_key)
13
+ # 16s : 16-byte string (for iv)
14
+ # I : 4-byte unsigned int (for dword1)
15
+ # I : 4-byte unsigned int (for dword2)
16
+ HEADER_FORMAT = "<32s16sII"
17
+ HEADER_SIZE = struct.calcsize(HEADER_FORMAT) # This will be 32 + 16 + 4 + 4 = 56 bytes
18
+
19
+ def parse_blob(data: bytes):
20
+ """
21
+ Parse the blob according to the scheme:
22
+ - 32 bytes = AES key
23
+ - Next 16 bytes = IV
24
+ - Next 2 DWORDs (8 bytes total) = XOR to get cipher data size
25
+ - Remaining bytes = cipher data of that size
26
+ """
27
+ aes_key, iv, dword1, dword2 = struct.unpack_from(HEADER_FORMAT, data, 0)
28
+ ciphertext_size = dword1 ^ dword2
29
+ cipher_data = data[HEADER_SIZE : HEADER_SIZE + ciphertext_size]
30
+ return aes_key, iv, cipher_data
31
+
32
+
33
+ def decrypt(data: bytes) -> Tuple[bytes, bytes, bytes]:
34
+ aes_key, iv, cipher_data = parse_blob(data)
35
+ cipher = AES.new(aes_key, AES.MODE_CBC, iv)
36
+ plaintext_padded = cipher.decrypt(cipher_data)
37
+ return aes_key, iv, unpad(plaintext_padded, AES.block_size)
38
+
39
+
40
+ def extract_config(data: bytes) -> Dict[str, Any]:
41
+ cfg: Dict[str, Any] = {}
42
+ plaintext = b""
43
+
44
+ pe = pefile.PE(data=data, fast_load=True)
45
+ try:
46
+ data_section = [s for s in pe.sections if s.Name.find(b".data") != -1][0]
47
+ except IndexError:
48
+ return cfg
49
+
50
+ if not data_section:
51
+ return cfg
52
+
53
+ data = data_section.get_data()
54
+ block_size = 4096
55
+ zeros = b"\x00" * block_size
56
+ offset = data.find(zeros)
57
+ if offset == -1:
58
+ return cfg
59
+
60
+ while offset > 0:
61
+ with suppress(Exception):
62
+ aes_key, iv, plaintext = decrypt(data[offset : offset + block_size])
63
+ if plaintext and b"conf" in plaintext:
64
+ break
65
+
66
+ offset -= 1
67
+
68
+ if plaintext:
69
+ try:
70
+ parsed = json.loads(plaintext.decode("utf-8", errors="ignore").rstrip("\x00"))
71
+ except json.JSONDecodeError:
72
+ return cfg
73
+
74
+ conf = parsed.get("conf", {})
75
+ build = parsed.get("build", {})
76
+ if conf:
77
+ cfg = {
78
+ "CNCs": conf.get("hosts"),
79
+ "user_agent": conf.get("useragents"),
80
+ "version": build.get("ver"),
81
+ "build": build.get("build_id"),
82
+ "cryptokey": aes_key.hex(),
83
+ "cryptokey_type": "AES",
84
+ "raw": {
85
+ "iv": iv.hex(),
86
+ "anti_vm": conf.get("anti_vm"),
87
+ "anti_dbg": conf.get("anti_dbg"),
88
+ "self_del": conf.get("self_del"),
89
+ "run_delay": conf.get("run_delay"),
90
+ }
91
+ }
92
+
93
+ return cfg
94
+
95
+
96
+ if __name__ == "__main__":
97
+ import sys
98
+
99
+ with open(sys.argv[1], "rb") as f:
100
+ print(extract_config(f.read()))
@@ -41,7 +41,7 @@ rule Latrodectus
41
41
  $fnvhash2 = {8B 0C 24 33 C8 8B C1 89 04 24 69 04 24 93 01 00 01}
42
42
  $procchk1 = {E8 [3] FF 85 C0 74 [2] FF FF FF FF E9 [4] E8 [4] 89 44 24 ?? E8 [4] 83 F8 4B 73 ?? 83 [3] 06}
43
43
  $procchk2 = {72 [2] FF FF FF FF E9 [4] E8 [4] 83 F8 32 73 ?? 83 [3] 06}
44
- $version = {C7 44 2? ?? ?? 00 00 00 C7 44 2? ?? ?? 00 00 00 8B 05 [4] 89}
44
+ $version = {C7 44 2? ?? ?? 00 00 00 C7 44 2? ?? ?? 00 00 00 C7 44 2? ?? ?? 00 00 00 8B 05 [4] 89}
45
45
  condition:
46
46
  all of them
47
47
  }
@@ -59,7 +59,7 @@ rule Latrodectus_AES
59
59
  $key = {C6 44 2? ?? ?? [150] C6 44 2? ?? ?? B8 02}
60
60
  $aes_ctr_1 = {8B 44 24 ?? FF C8 89 44 24 ?? 83 7C 24 ?? 00 7C ?? 4? 63 44 24 ?? 4? 8B 4C 24 ?? 0F B6 84 01 F0 00 00 00 3D FF 00 00 00}
61
61
  $aes_ctr_2 = {48 03 C8 48 8B C1 0F B6 ?? 48 63 4C 24 ?? 0F B6 4C 0C ?? 33 C1 48 8B 4C 24 ?? 48 8B 54 24 ?? 48 03 D1 48 8B CA 88 01}
62
- $version = {C7 44 2? ?? ?? 00 00 00 C7 44 2? ?? ?? 00 00 00 8B 05 [4] 89}
62
+ $version = {C7 44 2? ?? ?? 00 00 00 C7 44 2? ?? ?? 00 00 00 C7 44 2? ?? ?? 00 00 00 8B 05 [4] 89}
63
63
  condition:
64
64
  all of them
65
65
  }
@@ -152,7 +152,8 @@ def extract_config(filebuf):
152
152
  data = instance.matched_data[::-1]
153
153
  major = int.from_bytes(data[10:11], byteorder="big")
154
154
  minor = int.from_bytes(data[18:19], byteorder="big")
155
- version = f"{major}.{minor}"
155
+ release = int.from_bytes(data[26:27], byteorder="big")
156
+ version = f"{major}.{minor}.{release}"
156
157
  if "$key" in item.identifier:
157
158
  key = instance.matched_data[4::5]
158
159
  try:
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "CAPE-parsers"
3
- version = "0.1.48"
3
+ version = "0.1.50"
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