Jae Hun Bang

24 papers C 1Journal 16Unranked 7
YearRankTypeTitle / Venue / Authors
2020 J jnl
Computing
Usman Akhtar, Anita Sant'Anna, Chang-Ho Jihn, Muhammad Asif Razzaq, Jae Hun Bang, Sungyoung Lee
2020 J jnl
J. Inf. Sci.
Jamil Hussain, Fahad Ahmed Satti, Muhammad Afzal, Wajahat Ali Khan, Hafiz Syed Muhammad Bilal, Muhammad Zaki Ansaar, Hafiz Farooq Ahmad, Tae Ho Hur, Jae Hun Bang, Jee-In Kim, Gwang Hoon Park, Hyonwoo Seung, Sungyoung Lee
2020 conf
ICOIN
Muhammad Zaki Ansaar, Jamil Hussain, Jae Hun Bang, Sungyoung Lee, Kim Young Shin, Kim Young Woo
2020 conf
ICOIN
Muhammad Asif Razzaq, Jae Hun Bang, Sunmoo Svenna Kang, Sungyoung Lee
2019 J jnl
Int. J. Medical Informatics
Cam-Hao Hua, Thien Huynh-The, Kiyoung Kim, Seung-Young Yu, Thuong Le-Tien, Gwang Hoon Park, Jae Hun Bang, Wajahat Ali Khan, Sung-Ho Bae, Sungyoung Lee
2019 J jnl
Int. J. Medical Informatics
Shujaat Hussain, Maqbool Hussain, Muhammad Afzal, Jamil Hussain, Jae Hun Bang, Hyonwoo Seung, Sungyoung Lee
2018 J jnl
IEEE Access
Maqbool Ali, Rahman Ali, Wajahat Ali Khan, Soyeon Caren Han, Jae Hun Bang, Tae Ho Hur, Dohyeong Kim, Sungyoung Lee, Byeong Ho Kang
2018 J jnl
Sensors
Jamil Hussain, Wajahat Ali Khan, Tae Ho Hur, Hafiz Syed Muhammad Bilal, Jae Hun Bang, Anees Ul Hassan, Muhammad Afzal, Sungyoung Lee
2018 J jnl
Sensors
Jae Hun Bang, Tae Ho Hur, Dohyeong Kim, Thien Huynh-The, Jongwon Lee, Yongkoo Han, Oresti Banos, Jee-In Kim, Sungyoung Lee
2018 J jnl
Inf. Sci.
Thien Huynh-The, Cam-Hao Hua, Nguyen Anh Tu, Tae Ho Hur, Jae Hun Bang, Dohyeong Kim, Muhammad Bilal Amin, Byeong Ho Kang, Hyonwoo Seung, Soo-Yong Shin, Eun-Soo Kim, Sungyoung Lee
2018 J jnl
Sensors
Tae Ho Hur, Jae Hun Bang, Thien Huynh-The, Jongwon Lee, Jee-In Kim, Sungyoung Lee
2018 J jnl
J. Multimodal User Interfaces
Jamil Hussain, Anees Ul Hassan, Hafiz Syed Muhammad Bilal, Rahman Ali, Muhammad Afzal, Shujaat Hussain, Jae Hun Bang, Oresti Banos, Sungyoung Lee
2018 J jnl
Inf. Sci.
Thien Huynh-The, Cam-Hao Hua, Nguyen Anh Tu, Tae Ho Hur, Jae Hun Bang, Dohyeong Kim, Muhammad Bilal Amin, Byeong Ho Kang, Hyonwoo Seung, Sungyoung Lee
2017 J jnl
Sensors
Tae Ho Hur, Jae Hun Bang, Dohyeong Kim, Oresti Banos, Sungyoung Lee
2017 J jnl
Sensors
Muhammad Asif Razzaq, Claudia Villalonga, Sungyoung Lee, Usman Akhtar, Maqbool Ali, Eun-Soo Kim, Asad Masood Khattak, Hyonwoo Seung, Tae Ho Hur, Jae Hun Bang, Dohyeong Kim, Wajahat Ali Khan
2016 J jnl
Sensors
Oresti Baños, Claudia Villalonga, Jae Hun Bang, Tae Ho Hur, Dong Uk Kang, Sang Beom Park, Thien Huynh-The, Le-Ba Vui, Muhammad Bilal Amin, Muhammad Asif Razzaq, Wajahat Ali Khan, Choong Seon Hong, Sungyoung Lee
2015 conf
IWBBIO (2)
Oresti Banos, Muhammad Bilal Amin, Wajahat Ali Khan, Muhammad Afzal, Mahmood Ahmad, Maqbool Ali, Taqdir Ali, Rahman Ali, Hafiz Syed Muhammad Bilal, Manhyung Han, Jamil Hussain, Maqbool Hussain, Shujaat Hussain, Tae Ho Hur, Jae Hun Bang, Thien Huynh-The, Muhammad Idris, Dong Wook Kang, Sang Beom Park, Hameed Siddiqui, Le-Ba Vui, Muhammad Fahim, Asad Masood Khattak, Byeong Ho Kang, Sungyoung Lee
2015 conf
UbiComp/ISWC Adjunct
Oresti Baños, Jae Hun Bang, Dong Uk Kang, Choong Seon Hong, Sungyoung Lee, José Antonio Moral-Muñoz, Miguel Damas, Ignacio Diaz Reyes, Héctor Pomares, Ignacio Rojas, Claudia Villalonga, Manuel Arroyo Morales
2015 conf
EMBC
Oresti Baños, Jae Hun Bang, Tae Ho Hur, Muhammad Hameed Siddiqi, Huynh-The Thien, Le-Ba Vui, Wajahat Ali Khan, Taqdir Ali, Claudia Villalonga, Sungyoung Lee
2014 J jnl
Sensors
Manhyung Han, Jae Hun Bang, Chris D. Nugent, Sally I. McClean, Sungyoung Lee
2014 J jnl
Sensors
Shujaat Hussain, Jae Hun Bang, Manhyung Han, Muhammad Idris, Muhammad Bilal Amin, Sungyoung Lee, Chris D. Nugent, Sally I. McClean, Bryan W. Scotney, Gerard Parr
2013 C conf
Healthcom
Shujaat Hussain, Muhammad Bilal Amin, Jae Hun Bang, Manhyung Han, Sungyoung Lee, Chris D. Nugent, Sally I. McClean, Bryan W. Scotney, Gerard P. Parr
2013 conf
UCAmI
Manhyung Han, Jae Hun Bang, Chris D. Nugent, Sally I. McClean, Sungyoung Lee
2013 conf
SoICT
Ba-Vui Le, Jae Hun Bang, Sungyoung Lee
redb/extractors/malcontent.py
← Index redb/extractors/malcontent.py python
import inspect
import json
import subprocess
from typing import Any
from datetime import datetime, timezone

from redb.extractors.enum import Tag
from redb.models.dataclasses import Malcontent
from redb.extractors.extractor import Extractor
from dotenv import load_dotenv
import os

load_dotenv(override=True)


class MalcontentExtractor(Extractor):
    """
    Extractor for malcontent tool from chainguard-dev/malcontent.

    Malcontent discovers supply-chain compromises through context, differential
    analysis, and 14,000+ YARA rules. It analyzes binaries and code to detect
    malicious content and suspicious behavioral patterns.

    Binary can be extracted from Docker image:
        docker cp $(docker create cgr.dev/chainguard/malcontent:latest):/usr/bin/mal /usr/local/bin/mal

    Stores full JSON output for materialized view extraction.
    """

    # Cache version at class level to avoid repeated subprocess calls
    _cached_version = None

    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        elastic_index=None,
        known_benign=False,
        known_malicious=False,
    ):
        super().__init__(
            filepath,
            log,
            exporters,
            index_prefix,
            elastic_index,
            known_benign,
            known_malicious
        )
        self.malcontent = None

    @classmethod
    def _get_malcontent_version(cls, log) -> str:
        """Get malcontent version, cached at class level."""
        if cls._cached_version is not None:
            return cls._cached_version

        malcontent_path = os.getenv("MALCONTENT_PATH", "/usr/local/bin/mal")
        try:
            result = subprocess.run(
                [malcontent_path, "--version"],
                capture_output=True,
                text=True,
                timeout=10
            )
            version_output = result.stdout.strip()
            if result.returncode == 0 and version_output:
                # Parse "malcontent version v1.21.5" -> "1.21.5"
                if version_output.startswith("malcontent version v"):
                    version_output = version_output[len("malcontent version v"):]
                elif version_output.startswith("malcontent version "):
                    version_output = version_output[len("malcontent version "):]
                cls._cached_version = version_output
            else:
                cls._cached_version = "unknown"
        except Exception as e:
            log.warning(f"Could not get malcontent version: {e}")
            cls._cached_version = "unknown"

        return cls._cached_version

    def _extract_malcontent(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        TIMEOUT = int(os.getenv("MALCONTENT_TIMEOUT", "300"))
        malcontent_path = os.getenv("MALCONTENT_PATH", "/usr/local/bin/mal")

        malcontent_command = [malcontent_path, "analyze", "--format=json", self.filepath]

        import signal

        try:
            process = subprocess.Popen(
                malcontent_command,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                preexec_fn=os.setsid
            )

            try:
                stdout, stderr = process.communicate(timeout=TIMEOUT)
                if process.returncode != 0:
                    self.log.error(f"Error running malcontent, return code: {process.returncode}, stderr: {stderr}")
                    return {}
            except subprocess.TimeoutExpired:
                self.log.warning(f"The malcontent command timed out after {TIMEOUT} seconds, terminating process group")
                try:
                    os.killpg(process.pid, signal.SIGTERM)
                    try:
                        process.wait(timeout=3)
                    except subprocess.TimeoutExpired:
                        self.log.warning("Process didn't terminate with SIGTERM, sending SIGKILL")
                        os.killpg(process.pid, signal.SIGKILL)
                    process.wait()
                except (ProcessLookupError, OSError) as e:
                    self.log.warning(f"Error while killing process: {e}")
                return {}

            try:
                malcontent_output = json.loads(stdout)
            except json.JSONDecodeError as e:
                self.log.error(f"Error parsing malcontent output: {e}")
                return {}

            # Unwrap the Files/<path> structure to get the inner content
            # Structure is: {"Files": {"/path/to/file": {<actual content>}}}
            files_dict = malcontent_output.get("Files", {})
            if not files_dict:
                self.log.warning("Malcontent output has no 'Files' key")
                return {}

            # Get the first (and only) file's content
            file_content = next(iter(files_dict.values()), {})
            if not file_content:
                self.log.warning("Malcontent output has empty file content")
                return {}

            # Extract risk score and level from the unwrapped content
            risk_score = file_content.get("RiskScore", 0)
            risk_level = file_content.get("RiskLevel", "")

            version = self._get_malcontent_version(self.log)

            self.malcontent = Malcontent(
                malcontent_dump=json.dumps(file_content),
                version=version,
                risk_score=risk_score,
                risk_level=risk_level
            )
            self.log.debug(f"Malcontent analysis complete, version={version}, risk={risk_level}({risk_score})")

        except Exception as e:
            self.log.error(f"Unexpected error in malcontent extraction: {str(e)}")
            if 'process' in locals() and process.poll() is None:
                try:
                    os.killpg(process.pid, signal.SIGKILL)
                    process.wait()
                except:
                    pass
            return {}

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ClickHouseExporter":
            current_time = datetime.now(timezone.utc)

            data = [[
                self.sha256,
                current_time,
                self.malcontent.version,
                self.malcontent.risk_score,
                self.malcontent.risk_level,
                self.malcontent.malcontent_dump
            ]]

            column_names = [
                'sha256', 'analysis_date',
                'malcontent_version', 'malcontent_risk_score', 'malcontent_risk_level',
                'malcontent_json'
            ]

            column_type_names = [
                'FixedString(64)',
                'DateTime64(3, \'UTC\')',
                'LowCardinality(String)', 'UInt8', 'LowCardinality(String)',
                'JSON'
            ]

            return (data, column_names, column_type_names)

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

    def extract(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            self._extract_malcontent()
            return self.malcontent
        except Exception as e:
            self.log.error(f"Error extracting malcontent: {e}")
            return None

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