Radhika Nagpal

91 papers A* 21A 23C 1Misc 2Journal 23Unranked 19
YearRankTypeTitle / Venue / Authors
2026 J jnl
Sci. Robotics
Merihan Alhafnawi, Jad Bendarkawi, Yenet Tafesse, Lucia Stein-Montalvo, Azariah Jones, Vicky Chow, Sigrid Adriaenssens, Radhika Nagpal
2025 A conf
IROS
Irene Sha, Daniel B. Quinn, Radhika Nagpal
2024 conf
ANTS
Thiemen Siemensma, Darren Chiu, Sneha Ramshanker, Radhika Nagpal, Bahar Haghighat
2024 J jnl
CoRR
Thiemen Siemensma, Darren Chiu, Sneha Ramshanker, Radhika Nagpal, Bahar Haghighat
2024 J jnl
CoRR
Di Ni, Hungtang Ko, Radhika Nagpal
2024 A* conf
ICRA
Darren Chiu, Radhika Nagpal, Bahar Haghighat
2024 J jnl
CoRR
Sneha Ramshanker, Hungtang Ko, Radhika Nagpal
2023 J jnl
CoRR
Darren Chiu, Radhika Nagpal, Bahar Haghighat
2022 A conf
IROS
Julia T. Ebert, Florian Berlinger, Bahar Haghighat, Radhika Nagpal
2022 conf
ANTS Conference
Bahar Haghighat, Johannes Boghaert, Zev Minsky-Primus, Julia T. Ebert, Fangzheng Liu, Martin Nisser, Ariel Ekblaw, Radhika Nagpal
2022 A conf
IROS
Florian Berlinger, Julia T. Ebert, Radhika Nagpal
2022 A conf
AAMAS
Everardo Gonzalez, Lucie Houel, Radhika Nagpal, Melinda J. D. Malley
2021 J jnl
Sci. Robotics
Florian Berlinger, Melvin Gauci, Radhika Nagpal
2021 A* conf
ICRA
Florian Berlinger, Paula Wulkop, Radhika Nagpal
2021 J jnl
Frontiers Robotics AI
Nicole Carey, Paul Bardunias, Radhika Nagpal, Justin Werfel
2020 A* conf
ICRA
Julia T. Ebert, Melvin Gauci, Frederik Mallmann-Trenn, Radhika Nagpal
2020 A* conf
ICRA
Melinda J. D. Malley, Bahar Haghighat, Lucie Houel, Radhika Nagpal
2020 J jnl
IEEE Robotics Autom. Lett.
Mihai Duduta, Florian Berlinger, Radhika Nagpal, David R. Clarke, Robert J. Wood, Fatma Zeynep Temel
2018 A* conf
ICRA
Florian Berlinger, Mihai Duduta, Hudson Gloria, David R. Clarke, Radhika Nagpal, Robert J. Wood
2018 A conf
AAMAS
Julia T. Ebert, Melvin Gauci, Radhika Nagpal
2018 J jnl
IEEE Robotics Autom. Lett.
Florian Berlinger, Jeff Dusek, Melvin Gauci, Radhika Nagpal
2017 J jnl
PLoS Comput. Biol.
Tsvetomira Radeva, Anna R. Dornhaus, Nancy A. Lynch, Radhika Nagpal, Hsin-Hao Su
2017 A conf
AAMAS
Melvin Gauci, Monica E. Ortiz, Michael Rubenstein, Radhika Nagpal
2017 A conf
WACV
Nicole Carey, Justin Werfel, Radhika Nagpal
2017 A conf
IROS
Melinda J. D. Malley, Michael Rubenstein, Radhika Nagpal
2017 conf
SSCI
Elizabeth E. Esterly, Helen McCreery, Radhika Nagpal
2017 A* conf
HRI
Serena Booth, James Tompkin, Hanspeter Pfister, Jim Waldo, Krzysztof Gajos, Radhika Nagpal
2016 conf
DARS
Melvin Gauci, Radhika Nagpal, Michael Rubenstein
2015 A* conf
ICRA
Michael Rubenstein, Bo Cimino, Radhika Nagpal, Justin Werfel
2015 A* conf
ICRA
Lucian Cucu, Michael Rubenstein, Radhika Nagpal
2014 A* conf
ICRA
Richard J. D. Moore, Karthik Dantu, Geoffrey L. Barrows, Radhika Nagpal
2014 C conf
WAFR
Alejandro Cornejo, Radhika Nagpal
2014 J jnl
Robotica
Nils Napp, Radhika Nagpal
2014 J jnl
Robotics Auton. Syst.
Michael Rubenstein, Christian Ahler, Nick Hoff, Adrian Cabrera, Radhika Nagpal
2014 J jnl
Robotics Auton. Syst.
Robert Fitch, Kasper Støy, Serge Kernbach, Radhika Nagpal, Wei-Min Shen
2014 A* conf
ICRA
Nils Napp, Radhika Nagpal
2014 A* conf
ICRA
Nils Napp, Brandon Araki, Michael Thomas Tolley, Radhika Nagpal, Robert J. Wood
2014 A conf
DISC
Alejandro Cornejo, Anna R. Dornhaus, Nancy A. Lynch, Radhika Nagpal
2013 A conf
AAMAS
Michael Rubenstein, Adrian Cabrera, Justin Werfel, Golnaz Habibi, James McLurkin, Radhika Nagpal
2013 J jnl
CoRR
Alejandro Cornejo, Radhika Nagpal
2013 Misc conf
ICNC
Yong-Lae Park, Diana Young, Bor-rong Chen, Robert J. Wood, Radhika Nagpal, Eugene Goldfield
2012 A conf
IROS
Karthik Dantu, Spring Berman, Bryan Kate, Radhika Nagpal
2012 A conf
IROS
Yong-Lae Park, Bor-rong Chen, Carmel Majidi, Robert J. Wood, Radhika Nagpal, Eugene Goldfield
2012 conf
DARS
Nils Napp, Radhika Nagpal
2012 A* conf
ICRA
Michael Rubenstein, Christian Ahler, Radhika Nagpal
2012 A conf
IROS
Nils Napp, Olive R. Rappoli, Jessica M. Wu, Radhika Nagpal
2012 J jnl
Tiny Trans. Comput. Sci.
Nils Napp, Radhika Nagpal
2011 J jnl
Int. J. Robotics Res.
Chih-Han Yu, Radhika Nagpal
2011 A conf
IROS
Yong-Lae Park, Bor-rong Chen, Diana Young, Leia Stirling, Robert J. Wood, Eugene Goldfield, Radhika Nagpal
2011 A* conf
ICRA
Spring Berman, Vijay Kumar, Radhika Nagpal
2011 A conf
IROS
Nicholas Hoff, Robert J. Wood, Radhika Nagpal
2011 A conf
IROS
Spring Berman, Radhika Nagpal, Ádám M. Halász
2011 conf
Robotics: Science and Systems
Kirstin Petersen, Radhika Nagpal, Justin Werfel
2010 A* conf
AAAI
Chih-Han Yu, Radhika Nagpal
2010 A conf
AAMAS
Chih-Han Yu, Justin Werfel, Radhika Nagpal
2010 A* conf
ICRA
Chih-Han Yu, Justin Werfel, Radhika Nagpal
2010 conf
DARS
Nicholas Hoff, Robert J. Wood, Radhika Nagpal
2010 conf
ANTS Conference
Peter Bailis, Radhika Nagpal, Justin Werfel
2010 conf
ROBIO
Nicholas Hoff, Amelia Sagoff, Robert J. Wood, Radhika Nagpal
2009 A conf
IROS
Chih-Han Yu, Radhika Nagpal
2009 J jnl
PLoS Comput. Biol.
Ankit Patel, William T. Gibson, Matthew C. Gibson, Radhika Nagpal
2009 A* conf
ICRA
Chih-Han Yu, Radhika Nagpal
2008 conf
AAMAS (2)
Daniel Yamins, Radhika Nagpal
2008 conf
AAMAS (Demos)
Radhika Nagpal, Chih-Han Yu, Daniel Yamins
2008 A conf
IROS
Chih-Han Yu, Kristina Haller, Donald E. Ingber, Radhika Nagpal
2008 conf
AAMAS (1)
Chih-Han Yu, Radhika Nagpal
2008 J jnl
Int. J. Robotics Res.
Justin Werfel, Radhika Nagpal
2008 conf
SASO
Julius Degesys, Radhika Nagpal
2007 A conf
IROS
Justin Werfel, Donald E. Ingber, Radhika Nagpal
2007 conf
IPSN
Julius Degesys, Ian Rose, Ankit Patel, Radhika Nagpal
2007 conf
SASO
Ankit Patel, Julius Degesys, Radhika Nagpal
2007 A* conf
PerCom
Marco Mamei, Radhika Nagpal
2007 A conf
IROS
Chih-Han Yu, François-Xavier Willems, Donald E. Ingber, Radhika Nagpal
2007 conf
BIOWIRE
Julius Degesys, Ian Rose, Ankit Patel, Radhika Nagpal
2006 A* conf
AAAI
Crystal Schuil, Matthew Valente, Justin Werfel, Radhika Nagpal
2006 A* conf
ICRA
Justin Werfel, Yaneer Bar-Yam, Daniela Rus, Radhika Nagpal
2006 J jnl
IEEE Intell. Syst.
Justin Werfel, Radhika Nagpal
2006 J jnl
IEEE Intell. Syst.
Radhika Nagpal, Franco Zambonelli, Emin Gün Sirer, Hakima Chaouchi, Mikhail I. Smirnov
2005 A* conf
IJCAI
Justin Werfel, Yaneer Bar-Yam, Radhika Nagpal
2005 ed.
Engineering Self-Organising Systems
Sven Brueckner, Giovanna Di Marzo Serugendo, Anthony Karageorgos, Radhika Nagpal
2005 Misc conf
SenSys
Geoffrey Werner-Allen, Geetika Tewari, Ankit Patel, Matt Welsh, Radhika Nagpal
2005 J jnl
Genet. Program. Evolvable Mach.
Radhika Nagpal
2005 A* conf
AAAI
Jimming Cheng, Winston Cheng, Radhika Nagpal
2004 J jnl
Telecommun. Syst.
Jonathan Bachrach, Radhika Nagpal, Michael Salib, Howard E. Shrobe
2004 conf
DARS
Kasper Støy, Radhika Nagpal
2004 A conf
IROS
Kasper Støy, Radhika Nagpal
2003 conf
Engineering Self-Organising Systems
Radhika Nagpal
2003 conf
IPSN
Radhika Nagpal, Howard E. Shrobe, Jonathan Bachrach
2002 A conf
AAMAS
Radhika Nagpal
2001
Radhika Nagpal
2000 J jnl
Commun. ACM
Harold Abelson, Don Allen, Daniel Coore, Chris Hanson, George Homsy, Thomas F. Knight Jr., Radhika Nagpal, Erik Rauch, Gerald J. Sussman, Ron Weiss
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