Rada Hussein

31 papers B 2Misc 1Journal 11Unranked 17
YearRankTypeTitle / Venue / Authors
2025 J jnl
Int. J. Medical Informatics
Somayeh Abedian, Sten Hanke, Rada Hussein
2025 J jnl
Int. J. Medical Informatics
Somayeh Abedian, Sten Hanke, Rada Hussein
2025 J jnl
J. Medical Syst.
Anuradha Liyanage, Daniela Wurhofer, Mahdi Sareban, Gunnar Treff, Josef Niebauer, Rada Hussein
2025 J jnl
Frontiers Digit. Health
Somayeh Abedian, Eugene Yesakov, Stanislav Ostrovskiy, Rada Hussein
2024 conf
MIE
Somayeh Abedian, Christian Taucher, Severin Perscha, Michael Djuris, Rada Hussein, Sten Hanke
2024 conf
MIE
Florian Katsch, Rada Hussein, Georg Duftschmid
2024 J jnl
Frontiers Digit. Health
Jan David Smeddinck, Rada Hussein, Christopher Bull, Tom Foley, Mark J. van Gils
2024 conf
MIE
Prabath Jayathissa, Lukas Rohatsch, Stefan Sauermann, Rada Hussein
2024 conf
MIE
Amelie Gyrard, Philip Gribbon, Rada Hussein, Somayeh Abedian, Luis Marti Bonmati, Gibi Luisa Cabornero, George Manias, Gabriel Mihail Danciu, Stefano Dalmiani, Serge Autexier, Rick van Nuland, Mario Jendrossek, Ioannis Avramidis, Eva García Álvarez
2023 J jnl
J. Am. Medical Informatics Assoc.
Rada Hussein, Ashley C. Griffin, Adrienne Pichon, Jan Oldenburg
2023 conf
MIE
Rada Hussein, Adrienne Pichon, Jan Oldenburg, Mahdi Sareban, Josef Niebauer
2023 conf
MIE
Florian Katsch, Rada Hussein, Raffael Lukas Korntheuer, Georg Duftschmid
2023 conf
ICIMTH
Rada Hussein, Andreas Stainer-Hochgatterer, Josef Niebauer, Thomas Palfinger, Raphaela Kaisler
2023 conf
ICIMTH
Prabath Jayathissa, Mahdi Sareban, Josef Niebauer, Rada Hussein
2023 conf
EFMI-STC
Rada Hussein, Mahdi Sareban, Gunnar Treff, Josef Niebauer
2023 J jnl
Int. J. Medical Informatics
Rada Hussein, Lucas Scherdel, Frederic Nicolet, Fernando Martín-Sánchez
2023 conf
ICIMTH
Iris Falkenhein, Bianca Bernhardt, Sonja Gradwohl, Michael Brandl, Rada Hussein, Sten Hanke
2022 conf
MIE
Florian Katsch, Rada Hussein, Stefan Sabutsch, Helene Prenner, Fabian Prasser, Tanja Stamm, Georg Duftschmid
2022 conf
ICIMTH
Mohamed Khaled, Mahdi Sareban, Markus Kreuzthaler, Stefan Schulz, Rada Hussein
2021 conf
MedInfo
Rada Hussein, Daniela Wurhofer, Eva-Maria Strumegger, Andreas Stainer-Hochgatterer, Stefan Tino Kulnik, Rik Crutzen, Josef Niebauer
2021 conf
MIE
Rada Hussein, Rik Crutzen, Johanna Gutenberg, Stefan Tino Kulnik, Mahdi Sareban, Josef Niebauer
2021 conf
MedInfo
Daniela Wurhofer, Eva-Maria Strumegger, Rada Hussein, Andreas Stainer-Hochgatterer, Josef Niebauer, Stefan Tino Kulnik
2020 conf
MIE
Rada Hussein
2020 conf
EFMI-STC
Johanna Gutenberg, Stefan Tino Kulnik, Rada Hussein, Thomas Stütz, Josef Niebauer, Rik Crutzen
2017 J jnl
J. Medical Syst.
Rada Hussein
2015 J jnl
J. Medical Syst.
Rada Hussein
2015 J jnl
J. Medical Syst.
Rada Hussein
2013 Misc conf
AMIA
Ana Jimenez-Castellanos, Maximo Ramirez-Robles, Rada Hussein, Cheick Oumar Bagayoko, Caroline Perrin, Maria Zolfo, Asa Cuzin, Vincent Djientcheu, Samuel K. K. Dery, Victor Maojo
2012 B conf
CBMS
Ana Jimenez-Castellanos, Guillermo de la Calle, Raúl Alonso-Calvo, Rada Hussein, Victor Maojo
2012 J jnl
Computing
Victor Maojo, Martin Fritts, Fernando Martín-Sánchez, Diana de la Iglesia, Raul E. Cachau, Miguel García-Remesal, José Crespo, Joyce A. Mitchell, Alberto Anguita, Nathan A. Baker, José María Barreiro, Sonia E. Benitez, Guillermo de la Calle, Julio C. Facelli, Peter Ghazal, Antoine Geissbühler, Fernando D. González Nilo, Norbert M. Graf, Pierre Grangeat, Isabel Hermosilla, Rada Hussein, Josipa Kern, Sabine Koch, Yannick Legré, Victoria López-Alonso, Guillermo López-Campos, Luciano Milanesi, Vassilis Moustakis, Cristian R. Munteanu, Paula Otero, Alejandro Pazos, David Pérez-Rey, George Potamias, Ferran Sanz, Casimir A. Kulikowski
2008 B conf
CBMS
Rada Hussein, Alfred Winter
redb/extractors/js_extractors/js_suspicious_apis.py
← Index redb/extractors/js_extractors/js_suspicious_apis.py python
import inspect
from datetime import datetime, timezone
from typing import Any

from redb.extractors.enum import Tag
from redb.extractors.js_extractor import JSExtractor
from redb.extractors.js_extractors.js_patterns import CATEGORIES, PATTERNS


# Backwards-compatible export: `{category: [(raw_pattern_string, api_name), ...]}`
# in canonical PATTERNS insertion order (code_execution, network, filesystem,
# process, registry, crypto_encoding, dom_manipulation). Kept so external
# callers (notably JSDeobfuscationExtractor pre-cleanup) keep working until
# they are migrated to PATTERNS directly.
SUSPICIOUS_APIS: "dict[str, list[tuple[str, str]]]" = {}
for _name, _compiled in PATTERNS.items():
    SUSPICIOUS_APIS.setdefault(CATEGORIES[_name], []).append((_compiled.pattern, _name))


class JSSuspiciousAPIsExtractor(JSExtractor):

    def __init__(
        self, filepath, log, exporters=None, index_prefix=None,
        known_benign=False, known_malicious=False, source=None, context=None,
    ):
        super().__init__(
            filepath, log, exporters, index_prefix,
            known_benign, known_malicious, source, context=context,
        )
        self.api_findings = None
        self.log.debug(inspect.currentframe().f_code.co_name)

    def tag(self):
        return Tag.JS_SUSPICIOUS_APIS.value

    def _get_context_snippet(self, line, max_len=200):
        """Get a truncated context snippet around a match."""
        line = line.strip()
        if len(line) > max_len:
            return line[:max_len] + "..."
        return line

    def extract(self):
        src = self.js_source
        if not src:
            return None

        # Pass 1: shared per-sample scan over the raw source. The dict contains
        # entries for both PATTERNS and FEATURE_PATTERNS; the loop below only
        # consults PATTERNS keys, so feature-only entries are ignored.
        raw_scan = self._context.scan or {}
        raw_lines = self.lines

        # Pass 2: same patterns over the deobfuscated text, when the
        # deobfuscator produced something meaningfully different. APIs hidden
        # behind one obfuscation layer (Vjw0rm-style array.join + eval,
        # Dean-Edwards packers, jjencode, ...) only surface here. The scan is
        # cached on JSContext so JSDeobfuscationExtractor (which computes the
        # new_apis_found diff) reuses the same result.
        deobf_scan = self._context.scan_deobfuscated
        if deobf_scan:
            deobf_text, _ = self._context.deobfuscated
            deobf_lines = deobf_text.splitlines()
        else:
            deobf_lines = []

        findings = []
        # Iterate PATTERNS in canonical order so output is deterministic and
        # matches the historical category/pattern ordering. For each api_name,
        # raw findings take precedence; if an API is found only in the
        # deobfuscated text, we surface it as a row tagged revealed_by_deobf=1
        # with line numbers / snippets pulled from the deobfuscated source.
        for api_name in PATTERNS:
            raw_info = raw_scan.get(api_name)
            if raw_info:
                line_numbers = raw_info["lines"]
                lines_for_snippets = raw_lines
                revealed_by_deobf = 0
            else:
                deobf_info = deobf_scan.get(api_name)
                if not deobf_info:
                    continue
                line_numbers = deobf_info["lines"]
                lines_for_snippets = deobf_lines
                revealed_by_deobf = 1

            snippets = [
                self._get_context_snippet(lines_for_snippets[ln - 1])
                for ln in line_numbers[:3]
                if 0 < ln <= len(lines_for_snippets)
            ]
            findings.append({
                "api_name": api_name,
                "api_category": CATEGORIES[api_name],
                # Historical semantics: count = number of unique lines with a
                # match, not total in-source match count.
                "call_count": len(line_numbers),
                "line_numbers": line_numbers,
                "context_snippet": " | ".join(snippets),
                "revealed_by_deobf": revealed_by_deobf,
            })

        if not findings:
            return None

        self.api_findings = findings
        return findings

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ClickHouseExporter":
            if not self.api_findings:
                return None

            current_time = datetime.now(timezone.utc)
            data = []
            for f in self.api_findings:
                data.append([
                    self.sha256,
                    f['api_name'],
                    f['api_category'],
                    f['call_count'],
                    f['line_numbers'],
                    f['context_snippet'],
                    f['revealed_by_deobf'],
                    current_time,
                ])

            column_names = [
                "sha256", "api_name", "api_category",
                "call_count", "line_numbers", "context_snippet",
                "revealed_by_deobf",
                "analysis_date",
            ]

            column_type_names = [
                "FixedString(64)", "String", "LowCardinality(String)",
                "UInt32", "Array(UInt32)", "String",
                "UInt8",
                "DateTime64(3, 'UTC')",
            ]

            return (data, column_names, column_type_names)

    def get_clickhouse_table(self) -> str:
        return "redb_js_suspicious_apis"