CAPE-parsers 0.1.49__tar.gz → 0.1.51__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.49 → cape_parsers-0.1.51}/PKG-INFO +4 -2
  2. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/AgentTesla.py +7 -1
  3. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/AuroraStealer.py +1 -1
  4. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/Stealc.py +1 -1
  5. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/AuraStealer.py +18 -11
  6. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Latrodectus.py +4 -3
  7. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/pyproject.toml +1 -1
  8. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/LICENSE +0 -0
  9. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/README.md +0 -0
  10. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/__init__.py +0 -0
  11. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/Amadey.py +0 -0
  12. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/Arkei.py +0 -0
  13. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/AsyncRAT.py +0 -0
  14. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/Carbanak.py +0 -0
  15. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/CobaltStrikeBeacon.py +0 -0
  16. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/CobaltStrikeStager.py +0 -0
  17. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/DCRat.py +0 -0
  18. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/Fareit.py +0 -0
  19. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/KoiLoader.py +0 -0
  20. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/LokiBot.py +0 -0
  21. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/Lumma.py +0 -0
  22. /cape_parsers-0.1.49/cape_parsers/CAPE/community/monsterv2.py → /cape_parsers-0.1.51/cape_parsers/CAPE/community/MonsterV2.py +0 -0
  23. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/NanoCore.py +0 -0
  24. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/Nighthawk.py +0 -0
  25. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/Njrat.py +0 -0
  26. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/PhemedroneStealer.py +0 -0
  27. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/QuasarRAT.py +0 -0
  28. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/README.md +0 -0
  29. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/Snake.py +0 -0
  30. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/SparkRAT.py +0 -0
  31. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/VenomRAT.py +0 -0
  32. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/XWorm.py +0 -0
  33. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/XenoRAT.py +0 -0
  34. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/community/__init__.py +0 -0
  35. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/AdaptixBeacon.py +0 -0
  36. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Azorult.py +0 -0
  37. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/BitPaymer.py +0 -0
  38. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/BlackDropper.py +0 -0
  39. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Blister.py +0 -0
  40. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/BruteRatel.py +0 -0
  41. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/BumbleBee.py +0 -0
  42. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/DarkGate.py +0 -0
  43. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/DoppelPaymer.py +0 -0
  44. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/DridexLoader.py +0 -0
  45. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Formbook.py +0 -0
  46. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/GuLoader.py +0 -0
  47. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/IcedID.py +0 -0
  48. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/IcedIDLoader.py +0 -0
  49. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Oyster.py +0 -0
  50. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/PikaBot.py +0 -0
  51. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/PlugX.py +0 -0
  52. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/QakBot.py +0 -0
  53. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Quickbind.py +0 -0
  54. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/README.md +0 -0
  55. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/RedLine.py +0 -0
  56. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Remcos.py +0 -0
  57. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Rhadamanthys.py +0 -0
  58. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/SmokeLoader.py +0 -0
  59. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Socks5Systemz.py +0 -0
  60. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/SquirrelWaffle.py +0 -0
  61. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Strrat.py +0 -0
  62. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/WarzoneRAT.py +0 -0
  63. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/Zloader.py +0 -0
  64. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/__init__.py +0 -0
  65. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/CAPE/core/test_cape.py +0 -0
  66. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/RATDecoders/README.md +0 -0
  67. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/RATDecoders/__init__.py +0 -0
  68. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/RATDecoders/test_rats.py +0 -0
  69. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/__init__.py +0 -0
  70. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/BackOffLoader.py +0 -0
  71. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/BackOffPOS.py +0 -0
  72. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/BlackNix.py +0 -0
  73. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/BuerLoader.py +0 -0
  74. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/ChChes.py +0 -0
  75. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/Emotet.py +0 -0
  76. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/Enfal.py +0 -0
  77. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/EvilGrab.py +0 -0
  78. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/Greame.py +0 -0
  79. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/Hancitor.py +0 -0
  80. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/HttpBrowser.py +0 -0
  81. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/JavaDropper.py +0 -0
  82. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/Nymaim.py +0 -0
  83. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/Pandora.py +0 -0
  84. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/PoisonIvy.py +0 -0
  85. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/PredatorPain.py +0 -0
  86. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/Punisher.py +0 -0
  87. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/RCSession.py +0 -0
  88. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/REvil.py +0 -0
  89. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/RedLeaf.py +0 -0
  90. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/Retefe.py +0 -0
  91. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/Rozena.py +0 -0
  92. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/SmallNet.py +0 -0
  93. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/TSCookie.py +0 -0
  94. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/TrickBot.py +0 -0
  95. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/UrsnifV3.py +0 -0
  96. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/_ShadowTech.py +0 -0
  97. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/_VirusRat.py +0 -0
  98. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/_jRat.py +0 -0
  99. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/unrecom.py +0 -0
  100. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/deprecated/xRAT.py +0 -0
  101. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/malduck/LICENSE +0 -0
  102. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/malduck/README.md +0 -0
  103. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/malduck/__init__.py +0 -0
  104. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/malduck/test_malduck.py +0 -0
  105. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/mwcp/README.md +0 -0
  106. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/mwcp/__init__.py +0 -0
  107. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/mwcp/test_mwcp.py +0 -0
  108. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/utils/__init__.py +0 -0
  109. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/utils/aplib.py +0 -0
  110. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/utils/blzpack.py +0 -0
  111. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/utils/blzpack_lib.so +0 -0
  112. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/utils/dotnet_utils.py +0 -0
  113. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/utils/lznt1.py +0 -0
  114. {cape_parsers-0.1.49 → cape_parsers-0.1.51}/cape_parsers/utils/strings.py +0 -0
@@ -1,8 +1,9 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: CAPE-parsers
3
- Version: 0.1.49
3
+ Version: 0.1.51
4
4
  Summary: CAPE: Malware Configuration Extraction
5
5
  License: MIT
6
+ License-File: LICENSE
6
7
  Keywords: cape,parsers,malware,configuration
7
8
  Author: Kevin O'Reilly
8
9
  Author-email: kev@capesandbox.com
@@ -13,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.10
13
14
  Classifier: Programming Language :: Python :: 3.11
14
15
  Classifier: Programming Language :: Python :: 3.12
15
16
  Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
16
18
  Provides-Extra: maco
17
19
  Requires-Dist: capstone (>=4.0.2)
18
20
  Requires-Dist: dncil (>=1.0.2)
@@ -9,6 +9,7 @@ except ImportError as e:
9
9
  def extract_config(data: bytes):
10
10
  config = {}
11
11
  config_dict = {}
12
+ is_c2_found = False
12
13
  with suppress(Exception):
13
14
  if data[:2] == b"MZ":
14
15
  lines = extract_strings(data=data, on_demand=True, minchars=3)
@@ -25,11 +26,13 @@ def extract_config(data: bytes):
25
26
  config_dict["Protocol"] = "Telegram"
26
27
  config["CNCs"] = lines[base + x]
27
28
  config_dict["Password"] = lines[base + x + 1]
29
+ is_c2_found = True
28
30
  break
29
31
  # Data Exfiltration via Discord
30
32
  elif "discord" in lines[base + x]:
31
33
  config_dict["Protocol"] = "Discord"
32
34
  config["CNCs"] = [lines[base + x]]
35
+ is_c2_found = True
33
36
  break
34
37
  # Data Exfiltration via FTP
35
38
  elif "ftp:" in lines[base + x]:
@@ -38,6 +41,7 @@ def extract_config(data: bytes):
38
41
  username = lines[base + x + 1]
39
42
  password = lines[base + x + 2]
40
43
  config["CNCs"] = [f"ftp://{username}:{password}@{hostname}"]
44
+ is_c2_found = True
41
45
  break
42
46
  # Data Exfiltration via SMTP
43
47
  elif "@" in lines[base + x]:
@@ -52,10 +56,12 @@ def extract_config(data: bytes):
52
56
  config_dict["Password"] = lines[base + x + 1]
53
57
  if "@" in lines[base + x + 2]:
54
58
  config_dict["EmailTo"] = lines[base + x + 2]
59
+ is_c2_found = True
55
60
  break
56
61
  # Get Persistence Payload Filename
57
62
  for x in range(2, 22):
58
- if ".exe" in lines[base + x]:
63
+ # Only extract Persistence Filename when a C2 is detected.
64
+ if ".exe" in lines[base + x] and is_c2_found:
59
65
  config_dict["Persistence_Filename"] = lines[base + x]
60
66
  break
61
67
  # Get External IP Check Services
@@ -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:
@@ -77,7 +77,7 @@ def parse_text(data):
77
77
  domain = line
78
78
  elif _is_ip(line):
79
79
  domain = line
80
- if line.startswith("/") and line[-4] == ".":
80
+ if line.startswith("/") and len(line) >= 4 and line[-4] == ".":
81
81
  uri = line
82
82
 
83
83
 
@@ -7,6 +7,14 @@ import pefile
7
7
  from Cryptodome.Cipher import AES
8
8
  from Cryptodome.Util.Padding import unpad
9
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
10
18
 
11
19
  def parse_blob(data: bytes):
12
20
  """
@@ -16,15 +24,9 @@ def parse_blob(data: bytes):
16
24
  - Next 2 DWORDs (8 bytes total) = XOR to get cipher data size
17
25
  - Remaining bytes = cipher data of that size
18
26
  """
19
- offset = 0
20
- aes_key = data[offset:offset + 32]
21
- offset += 32
22
- iv = data[offset:offset + 16]
23
- offset += 16
24
- dword1, dword2 = struct.unpack_from("<II", data, offset)
25
- cipher_size = dword1 ^ dword2
26
- offset += 8
27
- cipher_data = data[offset:offset + cipher_size]
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]
28
30
  return aes_key, iv, cipher_data
29
31
 
30
32
 
@@ -37,7 +39,8 @@ def decrypt(data: bytes) -> Tuple[bytes, bytes, bytes]:
37
39
 
38
40
  def extract_config(data: bytes) -> Dict[str, Any]:
39
41
  cfg: Dict[str, Any] = {}
40
- plaintext = ""
42
+ plaintext = b""
43
+
41
44
  pe = pefile.PE(data=data, fast_load=True)
42
45
  try:
43
46
  data_section = [s for s in pe.sections if s.Name.find(b".data") != -1][0]
@@ -63,7 +66,11 @@ def extract_config(data: bytes) -> Dict[str, Any]:
63
66
  offset -= 1
64
67
 
65
68
  if plaintext:
66
- parsed = json.loads(plaintext.decode("utf-8", errors="ignore").rstrip("\x00"))
69
+ try:
70
+ parsed = json.loads(plaintext.decode("utf-8", errors="ignore").rstrip("\x00"))
71
+ except json.JSONDecodeError:
72
+ return cfg
73
+
67
74
  conf = parsed.get("conf", {})
68
75
  build = parsed.get("build", {})
69
76
  if conf:
@@ -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.49"
3
+ version = "0.1.51"
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