Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions lib/cuckoo/common/demux.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@
"Microsoft OOXML",
]

MS_EXCLUDE = [
"MSI Installer",
"Microsoft Cabinet archive"
]


IGNORABLE_PATTERNS = (
re.compile(br"msvcp\d+\.dll$", re.IGNORECASE),
Expand Down Expand Up @@ -487,15 +492,18 @@ def demux_sample(
magic = File(filename).get_type() or ""

# --- 3. Handle Password-Protected Office Files ---
is_office = ("Microsoft" in magic or any(x in magic for x in OFFICE_TYPES)) and "MSI Installer" not in magic
is_office = ("Microsoft" in magic or any(x in magic for x in OFFICE_TYPES)) and not any(x in magic for x in MS_EXCLUDE)
if is_office and use_sflock:
password = options2passwd(options)
if HAS_SFLOCK and password:
if use_sflock and password:
retlist = demux_office(filename, password, platform)
return retlist, error_list
# elif use_sflock:
# retlist = demux_office(filename, "", platform)
# return retlist, error_list
else:
log.error("Detected password protected office file, but no sflock is installed.")
return [], [{os.path.basename(filename).decode(errors='ignore'): "Detected password protected office file, but no sflock is installed"}]
log.error("Detected password protected office file, but no sflock is installed. Magic: %s, Password:%s", magic, str(password))
return [], [{os.path.basename(filename).decode(errors='ignore'): f"Detected password protected office file, but no sflock is installed. Magic: {magic}. Password: {password}"}]

# --- 4. Skip Extraction for specific types ---
ignored_signatures = [
Expand Down
6 changes: 5 additions & 1 deletion utils/dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def node_get_report_nfs(task_id, worker_name, main_task_id) -> bool:
path_mkdir(analyses_path, mode=0o755, exist_ok=False)

try:
shutil.copytree(worker_path, analyses_path, ignore=dist_ignore_patterns, ignore_dangling_symlinks=True, dirs_exist_ok=True)
shutil.copytree(worker_path, analyses_path, symlinks=True, ignore=dist_ignore_patterns, ignore_dangling_symlinks=True, dirs_exist_ok=True)
except shutil.Error:
log.error("Files doens't exist on worker")
except Exception as e:
Expand Down Expand Up @@ -2268,6 +2268,10 @@ def main():
if args.enable_clean:
cron_cleaner(args.clean_hours)

if args.clean_workers:
cron_cleaner(args.clean_hours)
sys.exit()

if args.force_reported:
with main_db.session.begin():
main_db.set_status(args.force_reported, TASK_DISTRIBUTED_COMPLETED)
Expand Down
76 changes: 76 additions & 0 deletions utils/gcp_pubsub_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,85 @@ def process_message(self, message: Any):
self.processing_ids.discard(msg_id)
log.info("[%s] Total processing time: %.2f seconds", correlation_id, time.time() - start_time)

def _diagnostic_loop(self):
"""Periodically log status and queue depth (if monitoring is available)."""
import time
from lib.cuckoo.common.gcp import gcp_cfg

monitoring_client = None
try:
from google.cloud import monitoring_v3
auth_by = gcp_cfg.gcp.get("auth_by", "vm")
service_account_path = gcp_cfg.gcp.get("service_account_path")

if auth_by == "json" and service_account_path:
if not os.path.isabs(service_account_path):
from lib.cuckoo.common.constants import CUCKOO_ROOT
service_account_path = os.path.join(CUCKOO_ROOT, service_account_path)
if os.path.exists(service_account_path):
monitoring_client = monitoring_v3.MetricServiceClient.from_service_account_json(service_account_path)
else:
monitoring_client = monitoring_v3.MetricServiceClient()
except ImportError:
log.debug("google-cloud-monitoring not installed. Install via `pip install google-cloud-monitoring` for precise queue counts.")
except Exception as e:
log.debug("Failed to initialize monitoring client: %s", e)

# Wait briefly before first check
time.sleep(5)

while True:
queue_size_str = "unknown (install google-cloud-monitoring)"
if monitoring_client:
try:
from google.cloud.monitoring_v3 import types
project_name = f"projects/{self.project_id}"
now = time.time()
interval = types.TimeInterval(
{
"end_time": {"seconds": int(now)},
"start_time": {"seconds": int(now - 600)},
}
)

results = monitoring_client.list_time_series(
request={
"name": project_name,
"filter": f'metric.type = "pubsub.googleapis.com/subscription/num_undelivered_messages" AND resource.labels.subscription_id = "{self.subscription_id}"',
"interval": interval,
}
)

latest_val = None
for result in results:
for point in result.points:
latest_val = point.value.int64_value
break
if latest_val is not None:
break

if latest_val is not None:
queue_size_str = str(latest_val)
else:
queue_size_str = "0"
except Exception as e:
log.debug("Error fetching queue size metric: %s", e)
queue_size_str = "error (permission or API issue)"

with self.ids_lock:
active = len(self.processing_ids)

log.info("[HEARTBEAT] Subscriber is healthy. Actively processing: %d Tasks. Undelivered queue size: %s.", active, queue_size_str)
time.sleep(300)

def start(self):
log.info("Starting GCP Pub/Sub subscriber on %s", self.subscription_path)

# Start a background diagnostic thread so the app doesn't seem 'hung' when idle
import threading
diag_thread = threading.Thread(target=self._diagnostic_loop, daemon=True)
diag_thread.start()

from lib.cuckoo.common.gcp import gcp_cfg
max_messages = 5
lease_duration = 1800
Expand Down
2 changes: 1 addition & 1 deletion web/analysis/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4510,7 +4510,7 @@ def on_demand(request, service: str, task_id: str, category: str, sha256):

if not path_exists(path):
extractedfile = False
if category == "static":
if category in ("static", "target.file"):
path = os.path.join(ANALYSIS_BASE_PATH, "analyses", task_id, "binary")
category = "target.file"
elif category == "dropped":
Expand Down
Loading