Naif Alajlan

113 papers C 9Journal 86Unranked 16
YearRankTypeTitle / Venue / Authors
2023 J jnl
J. Imaging
Nassim Ammour, Yakoub Bazi, Naif Alajlan
2023 J jnl
Comput. Math. Appl.
Hongwei Guo, Xiaoying Zhuang, Naif Alajlan, Timon Rabczuk
2023 conf
SPA
Saleh Alshamrani, Haikel Alhichri, Yakoub Bazi, Naif Alajlan
2022 J jnl
Eng. Comput.
Hongwei Guo, Xiaoying Zhuang, Pengwan Chen, Naif Alajlan, Timon Rabczuk
2022 J jnl
IEEE Geosci. Remote. Sens. Lett.
Nassim Ammour, Yakoub Bazi, Haikel Alhichri, Naif Alajlan
2022 J jnl
Data
Md. Saiful Islam, Haikel Alhichri, Yakoub Bazi, Nassim Ammour, Naif Alajlan, Rami Mohammad Jomaa
2022 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Mohamad Mahmoud Al Rahhal, Yakoub Bazi, Norah A. Alsharif, Laila Bashmal, Naif Alajlan, Farid Melgani
2022 C conf
IGARSS
Reham Al Dayil, Yakoub Bazi, Naif Alajlan
2022 C conf
IGARSS
Laila Bashmal, Yakoub Bazi, Naif Alajlan
2022 J jnl
Eng. Comput.
Hongwei Guo, Xiaoying Zhuang, Pengwan Chen, Naif Alajlan, Timon Rabczuk
2021 J jnl
IEEE Geosci. Remote. Sens. Lett.
Mohamad Mahmoud Al Rahhal, Yakoub Bazi, Huda Al-Hwiti, Haikel Salem Alhichri, Naif Alajlan
2021 J jnl
Comput. Biol. Medicine
Nassim Ammour, Haikel Alhichri, Yakoub Bazi, Naif Alajlan
2021 J jnl
Remote. Sens.
Tariq Lasloum, Haikel Alhichri, Yakoub Bazi, Naif Alajlan
2021 J jnl
Sensors
Soha B. Sandouka, Yakoub Bazi, Naif Alajlan
2021 J jnl
Entropy
Soha B. Sandouka, Yakoub Bazi, Haikel Salem Alhichri, Naif Alajlan
2020 J jnl
CoRR
Xiaoying Zhuang, Hongwei Guo, Naif Alajlan, Timon Rabczuk
2020 J jnl
Remote. Sens.
Reham Al Dayil, Yakoub Bazi, Haikel Salem Alhichri, Naif Alajlan
2020 J jnl
Int. J. Pattern Recognit. Artif. Intell.
Yakoub Bazi, Mohamad Mahmoud Al Rahhal, Haikel Salem Alhichri, Nassim Ammour, Naif Alajlan, Mansour Zuair
2020 J jnl
Eng. Comput.
Jorge López, Cosmin Anitescu, Navid Valizadeh, Timon Rabczuk, Naif Alajlan
2019 J jnl
IEEE Access
Aaliyah Alshehri, Yakoub Bazi, Nassim Ammour, Haidar Almubarak, Naif Alajlan
2019 J jnl
IEEE Access
Mohamad Mahmoud Al Rahhal, Yakoub Bazi, Haidar Almubarak, Naif Alajlan, Mansour Abdulaziz Al Zuair
2019 J jnl
Int. J. Intell. Syst.
Ronald R. Yager, Naif Alajlan
2019 J jnl
Remote. Sens.
Yakoub Bazi, Mohamad Mahmoud Al Rahhal, Haikel Al-Hichri, Naif Alajlan
2019 J jnl
Inf. Sci.
Ronald R. Yager, Naif Alajlan, Yakoub Bazi
2018 J jnl
Int. J. Intell. Syst.
Ronald R. Yager, Naif Alajlan, Yakoub Bazi
2018 C conf
IGARSS
Laila Bashmal, Yakoub Bazi, Haikel Salem Alhichri, Naif Alajlan
2018 conf
EIT
Haikel Salem Alhichri, Naif Alajlan, Yakoub Bazi, Timon Rabczuk
2018 J jnl
Eng. Appl. Artif. Intell.
Ronald R. Yager, Naif Alajlan
2018 J jnl
IEEE Trans. Geosci. Remote. Sens.
Salim Malek, Farid Melgani, Yakoub Bazi, Naif Alajlan
2018 J jnl
Remote. Sens.
Laila Bashmal, Yakoub Bazi, Haikel Salem Alhichri, Mohamad Mahmoud Alrahhal, Nassim Ammour, Naif Alajlan
2017 J jnl
Inf. Fusion
Ronald R. Yager, Naif Alajlan
2017 J jnl
Multim. Tools Appl.
Md. Saiful Islam, Naif Alajlan
2017 J jnl
Remote. Sens.
Nassim Ammour, Haikel Salem Alhichri, Yakoub Bazi, Bilel Benjdira, Naif Alajlan, Mansour Abdulaziz Al Zuair
2017 J jnl
IEEE Trans. Geosci. Remote. Sens.
Essam Othman, Yakoub Bazi, Farid Melgani, Haikel Al-Hichri, Naif Alajlan, Mansour Zuair
2017 J jnl
J. Vis. Commun. Image Represent.
Mohamed Lamine Mekhalfi, Farid Melgani, Yakoub Bazi, Naif Alajlan
2017 J jnl
IEEE Trans. Fuzzy Syst.
Ronald R. Yager, Naif Alajlan
2017 J jnl
IEEE Access
Md. Saiful Islam, Nassim Ammour, Naif Alajlan, Mohammad Abdullah-Al-Wadud
2016 J jnl
IEEE Trans. Inf. Forensics Secur.
Cecilia Pasquini, Giulia Boato, Naif Alajlan, Francesco G. B. De Natale
2016 J jnl
Inf. Sci.
Mohamad Mahmoud Al Rahhal, Yakoub Bazi, Haikel Salem Alhichri, Naif Alajlan, Farid Melgani, Ronald R. Yager
2016 J jnl
IEEE Trans. Cybern.
Ronald R. Yager, Naif Alajlan
2016 J jnl
Multim. Tools Appl.
Giulia Boato, Duc-Tien Dang-Nguyen, Oleg Muratov, Naif Alajlan, Francesco G. B. De Natale
2016 conf
ICIAR
Haikel Salem Alhichri, Bilel Benjdira, Yakoub Bazi, Naif Alajlan
2016 J jnl
Inf. Sci.
Ronald R. Yager, Naif Alajlan
2016 J jnl
Comput. Biol. Medicine
Md. Saiful Islam, Nassim Ammour, Naif Alajlan, Hatim Aboalsamh
2016 J jnl
Knowl. Based Syst.
Ronald R. Yager, Naif Alajlan
2016 J jnl
Int. J. Intell. Syst.
Ronald R. Yager, Naif Alajlan
2016 J jnl
IEEE Geosci. Remote. Sens. Lett.
Essam Othman, Yakoub Bazi, Naif Alajlan, Haikel Al-Hichri, Farid Melgani
2015 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Mohamed Lamine Mekhalfi, Farid Melgani, Yakoub Bazi, Naif Alajlan
2015 C conf
IGARSS
Essam Othman, Yakoub Bazi, Haikel Salem Alhichri, Naif Alajlan
2015 J jnl
Signal Image Video Process.
Nassim Ammour, Naif Alajlan
2015 C conf
IGARSS
Haikel Al-Hichri, Yakoub Bazi, Naif Alajlan, Nassim Ammour
2015 J jnl
Knowl. Based Syst.
Ronald R. Yager, Naif Alajlan
2015 J jnl
Biomed. Signal Process. Control.
Mohamad Mahmoud Al Rahhal, Yakoub Bazi, Naif Alajlan, Salim Malek, Haikel Al-Hichri, Farid Melgani, Mansour Abdulaziz Al Zuair
2015 J jnl
Knowl. Based Syst.
Ronald R. Yager, Naif Alajlan
2015 J jnl
IEEE Geosci. Remote. Sens. Lett.
Mohamed Abdelkader Bencherif, Yakoub Bazi, Abderrezak Guessoum, Naif Alajlan, Farid Melgani, Haikel Salem Alhichri
2015 conf
SCSE
Ronald R. Yager, Naif Alajlan
2015 book
Intelligent Methods for Cyber Warfare
Ronald R. Yager, Marek Z. Reformat, Naif Alajlan
2015 J jnl
IEEE Geosci. Remote. Sens. Lett.
Mohamed Lamine Mekhalfi, Farid Melgani, Yakoub Bazi, Naif Alajlan
2015 J jnl
Comput. J.
Md. Saiful Islam, Naif Alajlan
2015 J jnl
IEEE Trans. Geosci. Remote. Sens.
Thomas Moranduzzo, Farid Melgani, Mohamed Lamine Mekhalfi, Yakoub Bazi, Naif Alajlan
2015 J jnl
Int. J. Intell. Syst.
Ronald R. Yager, Naif Alajlan
2015 J jnl
Fuzzy Optim. Decis. Mak.
Ronald R. Yager, Naif Alajlan
2015 J jnl
Expert Syst. Appl.
Mohamed Lamine Mekhalfi, Farid Melgani, Yakoub Bazi, Naif Alajlan
2014 J jnl
Inf. Fusion
Ronald R. Yager, Naif Alajlan
2014 J jnl
Inf. Sci.
Ronald R. Yager, Naif Alajlan
2014 C conf
IGARSS
Yakoub Bazi, Salim Malek, Naif Alajlan, Haikel Salem Alhichri
2014 J jnl
Signal Image Video Process.
Naif Alajlan, Yakoub Bazi, Farid Melgani, Salim Malek, Mohamed Abdelkader Bencherif
2014 J jnl
IEEE Geosci. Remote. Sens. Lett.
Yakoub Bazi, Naif Alajlan, Farid Melgani, Haikel Hichri, Salim Malek, Ronald R. Yager
2014 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Salim Malek, Yakoub Bazi, Naif Alajlan, Haikel Al-Hichri, Farid Melgani
2014 J jnl
IEEE Geosci. Remote. Sens. Lett.
Naif Alajlan, Edoardo Pasolli, Farid Melgani, Andrea Franzoso
2014 J jnl
IEEE Trans. Fuzzy Syst.
Ronald R. Yager, Naif Alajlan
2014 J jnl
Fuzzy Optim. Decis. Mak.
Ronald R. Yager, Naif Alajlan
2014 J jnl
IEEE Trans. Fuzzy Syst.
Ronald R. Yager, Naif Alajlan
2014 J jnl
Knowl. Based Syst.
Ronald R. Yager, Naif Alajlan
2014 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Yakoub Bazi, Naif Alajlan, Farid Melgani, Haikel Al-Hichri, Ronald R. Yager
2013 J jnl
Biomed. Signal Process. Control.
Md. Saiful Islam, Naif Alajlan
2013 conf
ICME Workshops
Md. Saiful Islam, Naif Alajlan
2013 J jnl
Int. J. Intell. Syst.
Ronald R. Yager, Naif Alajlan
2013 conf
WHISPERS
Naif Alajlan, Yakoub Bazi, Ronald R. Yager
2013 conf
WorldCIS
Naif Alajlan, Md. Saiful Islam, Nassim Ammour
2013 J jnl
IEEE Geosci. Remote. Sens. Lett.
Haikel Hichri, Yakoub Bazi, Naif Alajlan, Salim Malek
2013 J jnl
IEEE Trans. Geosci. Remote. Sens.
Edoardo Pasolli, Farid Melgani, Naif Alajlan, Nicola Conci
2013 conf
CICSyN
Yakoub Bazi, Haikel Hichri, Naif Alajlan, Nassim Ammour
2013 J jnl
IEEE Geosci. Remote. Sens. Lett.
Abdelhamid Daamouche, Farid Melgani, Naif Alajlan, Nicola Conci
2013 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Naif Alajlan, Yakoub Bazi, Haikel Salem Alhichri, Farid Melgani, Ronald R. Yager
2012 J jnl
Biomed. Signal Process. Control.
Abdelhamid Daamouche, Latifa Hamami, Naif Alajlan, Farid Melgani
2012 J jnl
IEEE Trans. Geosci. Remote. Sens.
Edoardo Pasolli, Farid Melgani, Naif Alajlan, Yakoub Bazi
2012 J jnl
Inf. Sci.
Naif Alajlan, Yakoub Bazi, Farid Melgani, Ronald R. Yager
2012 J jnl
IEEE Trans. Inf. Technol. Biomed.
Md. Saiful Islam, Naif Alajlan, Yakoub Bazi, Haikel Hichri
2012 J jnl
IEEE Trans. Geosci. Remote. Sens.
Yakoub Bazi, Naif Alajlan, Farid Melgani
2012 C conf
IGARSS
Haikel Hichri, Yakoub Bazi, Naif Alajlan, Sayed M. Ahamad
2012 J jnl
Fuzzy Optim. Decis. Mak.
Ronald R. Yager, Naif Alajlan
2012 conf
ECCV (6)
Eslam A. Mostafa, Asem M. Ali, Naif Alajlan, Aly A. Farag
2012 C conf
IGARSS
Naif Alajlan, Yakoub Bazi, Haikel Hichri, Essam Othman
2011 C conf
IGARSS
Naif Alajlan, Nassim Ammour, Yakoub Bazi, Haikel Hichri
2011 J jnl
J. King Saud Univ. Comput. Inf. Sci.
Naif Alajlan
2011 J jnl
Int. J. Comput. Commun. Control
Marek Z. Reformat, Ronald R. Yager, Zhan Li, Naif Alajlan
2010 J jnl
J. King Saud Univ. Comput. Inf. Sci.
Naif Alajlan
2010 J jnl
Artif. Life Robotics
Naif Alajlan
2010 J jnl
Artif. Life Robotics
Mohamed Rizon, Tong-Yuen Chai, Ali S. AlMejrad, Naif Alajlan
2009 conf
IPCV
Naif Alajlan
2008 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Naif Alajlan, Mohamed S. Kamel, George H. Freeman
2007 conf
ICIAR
Naif Alajlan
2007 J jnl
Pattern Recognit.
Naif Alajlan, Ibrahim El Rube, Mohamed S. Kamel, George H. Freeman
2006 J jnl
Int. J. Image Graph.
Ibrahim El Rube, Naif Alajlan, Mohamed S. Kamel, Maher Ahmed, George H. Freeman
2006
Naif Alajlan
2006 J jnl
Signal Process. Image Commun.
Naif Alajlan, Mohamed S. Kamel, George H. Freeman
2005 conf
ICIAR
Ibrahim El Rube, Naif Alajlan, Mohamed S. Kamel, Maher Ahmed, George H. Freeman
2005 conf
ICIAR
Naif Alajlan, Ossama El Badawy, Mohamed S. Kamel, George H. Freeman
2005 conf
ICIP (1)
Ibrahim El Rube, Naif Alajlan, Mohamed Kamel, Maher Ahmed, George H. Freeman
2004 conf
ICIAR (1)
Naif Alajlan, Ed Jernigan
2004 J jnl
Signal Process. Image Commun.
Naif Alajlan, Mohamed Kamel, Ed Jernigan
2004 conf
ICIAR (1)
Naif Alajlan, Paul W. Fieguth, Mohamed Kamel
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