Najam Ul Hasan

43 papers B 1C 2Misc 2Journal 27Unranked 11
YearRankTypeTitle / Venue / Authors
2025 B conf
PIMRC
Muhammad Aslam Jarwar, Najam Ul Hasan, Charles Boisvert, Paul Wheway, Michael Richard Faulks
2025 conf
IOT
Chidike Vincent, Laurence Hirsch, Najam Ul Hasan, Caren Crizben Ezlin Fernandes, Adriana Crainic, Jonathan Zasada-James, James Baldwin
2024 J jnl
Int. J. Commun. Syst.
Umer Farooq, Najam Ul Hasan
2022 J jnl
J. Supercomput.
Muhammad Bilal, Muazzam Maqsood, Sadaf Yasmin, Najam Ul Hasan, Seungmin Rho
2022 J jnl
J. Supercomput.
Asma Rahim, Mehr Yahya Durrani, Saira Andleeb Gillani, Zeeshan Ali, Najam Ul Hasan, Mucheol Kim
2022 J jnl
Sensors
Imran Baig, Najam Ul Hasan, Prajoona Valsalan, Manaf Zghaibeh
2021 J jnl
Trans. Emerg. Telecommun. Technol.
Najam Ul Hasan, Waleed Ejaz, Manaf Zghaibeh, Naveed Ejaz, Bander A. Alzahrani
2020 conf
FMEC
Imran Baig, Umer Farooq, Najam Ul Hasan, Manaf Zghaibeh, Umer Mukhtar Rana, Ahthasham Sajid
2020 J jnl
IEEE Access
Manaf Zghaibeh, Umer Farooq, Najam Ul Hasan, Imran Baig
2019 C conf
CoDIT
Imran Baig, Umer Farooq, Najam Ul Hasan, Manaf Zghaibeh, Ahthasham Sajid, U. Mukhtar Rana
2019 conf
Wireless Days
Imran Baig, Umer Farooq, Najam Ul Hasan, Manaf Zghaibeh, Varun Jeoti, Muhammad Imran
2019 J jnl
Trans. Emerg. Telecommun. Technol.
Najam Ul Hasan, Waleed Ejaz, Alagan Anpalagan
2019 J jnl
EURASIP J. Wirel. Commun. Netw.
Umer Farooq, Najam Ul Hasan, Imran Baig, Muhammad Naeem Shehzad
2019 J jnl
Trans. Emerg. Telecommun. Technol.
Zeshan Qureshi, Peer Azmat Shah, Najam Ul Hasan, Sadaf Yasmin, Farhan Aadil, Muhammad Fahad Khan, Yunyoung Nam, Sehar Shahzad Farooq
2019 conf
ICC Workshops
Najam Ul Hasan, Manaf Zghaibeh, Waleed Ejaz, Adnan Shahid, Alagan Anpalagan
2019 conf
SSD
Umer Farooq, Najam Ul Hasan, Imran Baig
2018 C conf
ISNCC
Imran Baig, Umer Farooq, Najam Ul Hasan, Manaf Zghaibeh, U. Mukhtar Rana, Muhammad Imran, Muhammad Ayaz
2018 J jnl
IEEE Syst. J.
Waleed Ejaz, Najam Ul Hasan, Ghalib A. Shah, Hyung Seok Kim, Alagan Anpalagan
2017 J jnl
Int. J. Commun. Syst.
Najam Ul Hasan, Waleed Ejaz, Mahin K. Atiq, Hyung Seok Kim
2017 J jnl
Trans. Emerg. Telecommun. Technol.
Najam Ul Hasan, Waleed Ejaz, Hyung Seok Kim
2017 J jnl
EURASIP J. Wirel. Commun. Netw.
Manaf Zghaibeh, Najam Ul Hasan
2016 J jnl
Sensors
Saleem Aslam, Najam Ul Hasan, Adnan Shahid, Ju-wook Jang, Kyung-Geun Lee
2016 conf
ISTT
Shahid Qureshi, Shehzad Ahmad, Ataul Aziz Ikram, Najam Ul Hasan
2016 J jnl
IEEE Access
Najam Ul Hasan, Waleed Ejaz, Naveed Ejaz, Hyung Seok Kim, Alagan Anpalagan, Minho Jo
2016 J jnl
Sensors
Saleem Aslam, Najam Ul Hasan, Ju-wook Jang, Kyung-Geun Lee
2016 conf
ICUFN
Najam Ul Hasan, Waleed Ejaz, Imran Baig, Manaf Zghaibeh, Alagan Anpalagan
2016 conf
AECIA
Manaf Zghaibeh, Najam Ul Hasan
2015 J jnl
Trans. Emerg. Telecommun. Technol.
Waleed Ejaz, Ghalib A. Shah, Najam Ul Hasan, Hyung Seok Kim
2015 J jnl
Int. J. Commun. Syst.
Najam Ul Hasan, Wanqing Tu
2014 J jnl
EURASIP J. Wirel. Commun. Netw.
Mahin K. Atiq, Kamran Manzoor, Soomi Kim, Najam Ul Hasan, Hyung Joo Kim
2014 J jnl
Int. J. Distributed Sens. Networks
Hyung Seok Kim, Waleed Ejaz, Khalid Al-Begain, Al-Sakib Khan Pathan, Najam Ul Hasan
2013 J jnl
Comput. Commun.
Waleed Ejaz, Najam Ul Hasan, Hyung Seok Kim
2013 J jnl
EURASIP J. Wirel. Commun. Netw.
Najam Ul Hasan, Waleed Ejaz, Kamran Manzoor, Hyung Joo Kim
2013 J jnl
EURASIP J. Wirel. Commun. Netw.
Waleed Ejaz, Najam Ul Hasan, Seok Lee, Hyung Seok Kim
2013 J jnl
Entropy
Waleed Ejaz, Ghalib A. Shah, Najam Ul Hasan, Hyung Seok Kim
2012 J jnl
EURASIP J. Adv. Signal Process.
Waleed Ejaz, Najam Ul Hasan, Muhammad Awais Azam, Hyung Seok Kim
2012 J jnl
IET Commun.
Najam Ul Hasan, Waleed Ejaz, Seok Lee, Hyung Seok Kim
2012 J jnl
Sensors
Najam Ul Hasan, Naveed Ejaz, Waleed Ejaz, Hyung Seok Kim
2012 conf
NGMAST
Waleed Ejaz, Najam Ul Hasan, Hyung Seok Kim
2011 Misc conf
FIT
Waleed Ejaz, Najam Ul Hasan, Hyung Seok Kim, Muhammad Awais Azam
2011 conf
NGMAST
Waleed Ejaz, Najam Ul Hasan, Saleem Aslam, Hyung Seok Kim
2011 Misc conf
FIT
Najam Ul Hasan, Waleed Ejaz, Hyung Seok Kim, Jae-Hun Kim
2009 conf
ICWN
Waleed Ejaz, Saleem Aslam, Najam Ul Hasan, Naveed Ejaz
redb/extractors/ioc_extractor/ioc_extractor.py
← Index redb/extractors/ioc_extractor/ioc_extractor.py python
"""
IOC Extractor - Extractor class for extracting IOCs from decompilation results.

This extractor works with in-memory data from DecompileBinja, following the
standard Extractor pattern to support both ClickHouse and PrintExporter (dry-run).

Usage:
    # After DecompileBinja completes:
    ioc_extractor = IOCExtractorFromResults(
        analysis_results=decompiler.analysis_results,
        sha256=sha256,
        log=logger,
        exporters=exporters,
        index_prefix=index_prefix
    )
    ioc_extractor.export_data()
"""

import inspect
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, List, Dict, Optional

from redb.extractors.enum import Tag
from redb.extractors.database_exporters import DatabaseExporter

# Import the IOCScraper and related classes from standalone module
from redb.extractors.ioc_extractor.standalone_ioc_extractor import (
    IOCScraper,
    IOCType,
    SourceType,
    ExtractedIOC,
)
from typing import Set


class IOCExtractorFromResults:
    """
    Extracts IOCs from in-memory decompilation results.

    This follows a simplified Extractor pattern but doesn't inherit from Extractor
    since it doesn't read from a binary file - instead it takes already-processed
    analysis results from DecompileBinja.
    """

    def __init__(
        self,
        analysis_results: Dict[str, Any],
        sha256: str,
        log: Any,
        exporters: Optional[List[DatabaseExporter]] = None,
        index_prefix: Optional[str] = None,
        tld_file: Optional[Path] = None,
        suppress_types: Optional[Set[IOCType]] = None,
        js_context: bool = False,
    ):
        """
        Initialize IOC Extractor with analysis results.

        Args:
            analysis_results: Dict containing 'strings' and 'decompiled' lists from DecompileBinja
            sha256: Sample SHA256 hash
            log: Logger instance
            exporters: List of database exporters (ClickHouse, Print, etc.)
            index_prefix: Index prefix for database
            tld_file: Optional path to TLD list file
            js_context: When True, the underlying IOCScraper rejects FQDN
                candidates that match JS object-access syntax (see
                JS_FP_TLDS / JS_FP_SLDS). Set this for the JS pipeline only;
                APK suppresses FQDN entirely via suppress_types and binary
                callers leave it disabled.
        """
        self.log = log
        self.log.debug(f"Creating {self.__class__.__name__}")
        self.analysis_results = analysis_results
        self.sha256 = sha256
        self.exporters = exporters or []
        self.index_prefix = index_prefix
        self.scraper = IOCScraper(
            tld_file, suppress_types=suppress_types, js_context=js_context,
        )
        self.extracted_iocs: List[ExtractedIOC] = []

    def extract(self) -> List[ExtractedIOC]:
        """
        Extract IOCs from strings and decompiled functions in analysis_results.

        Returns:
            List of ExtractedIOC objects
        """
        self.log.debug(inspect.currentframe().f_code.co_name)
        self.extracted_iocs = []

        # Extract from strings
        strings_count = self._extract_from_strings()

        # Extract from decompiled functions
        functions_count = self._extract_from_decompiled()

        # Extract from text-based artefact surfaces (JS, PowerShell, etc.)
        text_count = self._extract_from_text()

        self.log.info(
            f"Extracted {len(self.extracted_iocs)} IOCs for {self.sha256[:16]}... "
            f"(strings: {strings_count}, functions: {functions_count}, "
            f"text: {text_count})"
        )

        return self.extracted_iocs

    def _extract_from_strings(self) -> int:
        """Extract IOCs from sample's strings."""
        count = 0
        strings = self.analysis_results.get("strings", [])

        for s in strings:
            string_value = s.get("string", "")
            string_offset = s.get("string_offset", 0)

            if isinstance(string_value, bytes):
                string_value = string_value.decode('utf-8', errors='replace')

            for ioc in self.scraper.scrape(string_value, SourceType.STRING, str(string_offset)):
                self.extracted_iocs.append(ioc)
                count += 1

        return count

    def _extract_from_decompiled(self) -> int:
        """Extract IOCs from sample's decompiled functions.

        Supports both Binja format (key: "decompiled", fields: "decompiled_function",
        "decompiled_function_hash", "function_type") and APK format (key:
        "decompiled_content", fields: "decompiled_method", "decompiled_method_hash",
        "method_type").
        """
        count = 0

        # Binja format
        decompiled = self.analysis_results.get("decompiled", [])
        for func in decompiled:
            func_type = func.get("function_type", "UNKNOWN")
            if func_type in ("LIBRARY", "THUNK"):
                continue

            func_content = func.get("decompiled_function", "")
            func_hash = func.get("decompiled_function_hash", "unknown")

            if isinstance(func_content, bytes):
                func_content = func_content.decode('utf-8', errors='replace')

            for ioc in self.scraper.scrape(func_content, SourceType.DECOMPILED_FUNCTION, func_hash):
                self.extracted_iocs.append(ioc)
                count += 1

        # APK format (decompiled_content with method-level fields)
        decompiled_content = self.analysis_results.get("decompiled_content", [])
        for func in decompiled_content:
            func_type = func.get("method_type", "UNKNOWN")
            if func_type in ("LIBRARY", "THUNK"):
                continue

            func_content = func.get("decompiled_method", "")
            func_hash = func.get("decompiled_method_hash", "unknown")

            if isinstance(func_content, bytes):
                func_content = func_content.decode('utf-8', errors='replace')

            for ioc in self.scraper.scrape(func_content, SourceType.DECOMPILED_FUNCTION, func_hash):
                self.extracted_iocs.append(ioc)
                count += 1

        return count

    def _extract_from_text(self) -> int:
        """Extract IOCs from text-based artefact surfaces.

        Walks `analysis_results["text_raw"]` and `analysis_results["text_normalized"]`,
        each a list of `{"content": str, "content_hash": str}` dicts. Each
        list is routed through its own SourceType (`TEXT_RAW` /
        `TEXT_NORMALIZED`) so analysts can distinguish IOCs that were already
        present in the raw source from those exposed only after normalisation
        (deobfuscation/beautification). Generic across text-based formats —
        used by JS today, intended for PowerShell, Python, email body,
        extracted PDF/Office text in the future.
        """
        count = 0

        for key, source_type in (
            ("text_raw", SourceType.TEXT_RAW),
            ("text_normalized", SourceType.TEXT_NORMALIZED),
        ):
            for entry in self.analysis_results.get(key, []):
                content = entry.get("content", "")
                content_hash = entry.get("content_hash", "unknown")

                if isinstance(content, bytes):
                    content = content.decode('utf-8', errors='replace')

                for ioc in self.scraper.scrape(content, source_type, content_hash):
                    self.extracted_iocs.append(ioc)
                    count += 1

        return count

    def prepare_export_data(self, exporter_type: str) -> Any:
        """
        Prepare data for specific export type.

        Returns tuple for ClickHouse or list of dicts for Print/Elasticsearch.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        if not self.extracted_iocs:
            return None

        now = datetime.now(timezone.utc)

        if exporter_type == "ClickHouseExporter":
            data = [
                [
                    self.sha256,
                    ioc.ioc_type.value,
                    ioc.ioc_value,
                    ioc.source_type.value,
                    ioc.source_identifier,
                    now,
                ]
                for ioc in self.extracted_iocs
            ]

            column_names = [
                "sha256",
                "ioc_type",
                "ioc_value",
                "source_type",
                "source_identifier",
                "extracted_at",
            ]

            column_type_names = [
                "FixedString(64)",
                "Enum8('ipv4'=1, 'ipv6'=2, 'fqdn'=3, 'url'=4, 'email'=5, 'server'=6, "
                "'hash_md5'=10, 'hash_sha1'=11, 'hash_sha256'=12, 'cve'=20, 'cwe'=21, 'cpe'=22, "
                "'crypto_btc'=30, 'crypto_eth'=31, 'crypto_xrp'=32, 'crypto_bch'=33, "
                "'crypto_ada'=34, 'crypto_substrate'=35, 'path_linux'=40, 'path_windows'=41, "
                "'registry_key'=42, 'onion'=50)",
                "String",
                "Enum8('decompiled_function'=1, 'disassembled_function'=2, 'string'=3, "
                "'text_raw'=4, 'text_normalized'=5)",
                "String",
                "DateTime64(3, 'UTC')",
            ]

            return (data, column_names, column_type_names)

        else:
            # For PrintExporter and others - return list of dicts
            return [
                {
                    "sha256": self.sha256,
                    "ioc_type": ioc.ioc_type.value,
                    "ioc_value": ioc.ioc_value,
                    "source_type": ioc.source_type.value,
                    "source_identifier": ioc.source_identifier,
                    "extracted_at": now.isoformat(),
                }
                for ioc in self.extracted_iocs
            ]

    def get_clickhouse_table(self) -> str:
        """Return the ClickHouse table name for IOCs."""
        return "redb_iocs"

    def tag(self) -> str:
        """Return the tag for this extractor."""
        return Tag.IOC.value if hasattr(Tag, 'IOC') else "ioc"

    def export_data(self) -> bool:
        """
        Export extracted IOCs to all configured exporters.

        Returns:
            True if export succeeded, False if failed, None if no data
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        # First extract the IOCs
        extracted = self.extract()

        if not extracted:
            self.log.debug("No IOCs extracted, skipping export")
            return None

        success = True

        from redb.extractors.database_exporters import PrintExporter, ClickHouseExporter

        for exporter in self.exporters:
            try:
                if isinstance(exporter, PrintExporter):
                    # For PrintExporter, pass the list of dicts
                    export_data = self.prepare_export_data("PrintExporter")
                    success &= exporter.export(export_data)

                elif isinstance(exporter, ClickHouseExporter):
                    # For ClickHouse, pass tuple with table info
                    export_data = self.prepare_export_data("ClickHouseExporter")
                    if export_data:
                        success &= exporter.export(
                            export_data,
                            table=self.get_clickhouse_table(),
                            column_names=export_data[1],
                            column_type_names=export_data[2]
                        )

            except Exception as e:
                self.log.error(f"Error exporting IOCs to {exporter.__class__.__name__}: {e}")
                success = False

        return success