Imene Khanfir Kallel

24 papers Misc 10Journal 10Unranked 4
YearRankTypeTitle / Venue / Authors
2025 J jnl
Inf. Fusion
Samia Barhoumi, Imene Khanfir Kallel, Éloi Bossé, Basel Solaiman
2024 J jnl
Biomed. Signal Process. Control.
Lamia Rzouga Haddada, Faten Mekki Rmida, Wael Ouarda, Imene Khanfir Kallel, Ramzi Maalej, Saber Masmoudi, Adel M. Alimi, Najoua Essoukri Ben Amara
2024 J jnl
Expert Syst. Appl.
Mouna Medhioub, Sonda Ammar Bouhamed, Imene Khanfir Kallel, Nabil Derbel, Olfa Kanoun
2023 J jnl
Entropy
Houda Khmila, Imene Khanfir Kallel, Éloi Bossé, Basel Solaiman
2023 J jnl
Expert Syst. Appl.
Sonda Ammar Bouhamed, Imene Khanfir Kallel, Éloi Bossé, Basel Solaiman
2020 Misc conf
ATSIP
Nadia Smaoui Zghal, Imene Khanfir Kallel
2020 J jnl
Inf. Fusion
Sonda Ammar Bouhamed, Imene Khanfir Kallel, Ronald R. Yager, Éloi Bossé, Basel Solaiman
2020 Misc conf
ATSIP
Marwa Chakroun, Amal Charfi, Sonda Ammar Bouhamed, Imene Khanfir Kallel, Basel Solaiman, Houda Derbel
2020 Misc conf
ATSIP
Sonda Ammar Bouhamed, Hatem Dardouri, Imene Khanfir Kallel, Éloi Bossé, Basel Solaiman
2020 Misc conf
ATSIP
Houda Khmila, Imene Khanfir Kallel, Samia Barhoumi, Nadia Smaoui, Houda Derbel
2020 Misc conf
ATSIP
Samia Barhoumi, Imene Khanfir Kallel, Sonda Ammar Bouhamed, Éloi Bossé, Basel Solaiman
2020 J jnl
IEEE Access
Amal Charfi, Sonda Ammar Bouhamed, Éloi Bossé, Imene Khanfir Kallel, Wassim Bouchaala, Basel Solaiman, Nabil Derbel
2019 J jnl
Multim. Tools Appl.
Imene Khanfir Kallel, Shaban Almouahed, Bassem Alsahwa, Basel Solaiman
2018 J jnl
Pattern Recognit.
Imene Khanfir Kallel, Shaban Almouahed, Bassel Solaiman, Éloi Bossé
2018 Misc conf
ATSIP
Sonda Ammar Bouhamed, Marwa Chakroun, Imene Khanfir Kallel, Houda Derbel
2018 conf
SSD
Mabrouka Zemzemi, Nesrine Keskes, Rim Barioul, Sameh Fakhfakh, Imene Khanfir Kallel, Nabil Derbel, Olfa Kanoun
2017 Misc conf
ATSIP
Imene Khanfir Kallel, Sonda Ammar Bouhamed, Belhassen Akrout
2017 Misc conf
ATSIP
Imene Khanfir Kallel, Basel Solaiman
2017 conf
SDD
Sonda Ammar Bouhamed, Imene Khanfir Kallel
2015 J jnl
Pattern Recognit.
Sonda Ammar Bouhamed, Imene Khanfir Kallel, Dorra Sellami Masmoudi, Basel Solaiman
2014 Misc conf
ATSIP
Sonda Ammar Bouhamed, Imene Khanfir Kallel, Dorra Sellami Masmoudi, Basel Solaiman
2014 Misc conf
ATSIP
Wafa Damak, Issam Rebaï, Imene Khanfir Kallel
2013 conf
TSP
Sonda Ammar Bouhamed, Imene Khanfir Kallel, Dorra Sellami Masmoudi
2005 conf
SITIS
Amin Kallel, Dorra Sellami Masmoudi, Mounir Salhi, Med Amine Ben Aïcha, Imene Khanfir Kallel, Nabil Derbel
redb/extractors/apk_extractors/apk_permissions.py
← Index redb/extractors/apk_extractors/apk_permissions.py python
import inspect
from datetime import datetime, timezone
from typing import Any

from redb.extractors.enum import Tag
from redb.extractors.apk_extractor import APKExtractor
from redb.models.dataclasses import APKPermissions, APKPermission

# Known dangerous permissions (Android runtime permissions)
DANGEROUS_PERMISSIONS = {
    "android.permission.READ_CALENDAR",
    "android.permission.WRITE_CALENDAR",
    "android.permission.CAMERA",
    "android.permission.READ_CONTACTS",
    "android.permission.WRITE_CONTACTS",
    "android.permission.GET_ACCOUNTS",
    "android.permission.ACCESS_FINE_LOCATION",
    "android.permission.ACCESS_COARSE_LOCATION",
    "android.permission.ACCESS_BACKGROUND_LOCATION",
    "android.permission.RECORD_AUDIO",
    "android.permission.READ_PHONE_STATE",
    "android.permission.READ_PHONE_NUMBERS",
    "android.permission.CALL_PHONE",
    "android.permission.ANSWER_PHONE_CALLS",
    "android.permission.ADD_VOICEMAIL",
    "android.permission.USE_SIP",
    "android.permission.BODY_SENSORS",
    "android.permission.SEND_SMS",
    "android.permission.RECEIVE_SMS",
    "android.permission.READ_SMS",
    "android.permission.RECEIVE_WAP_PUSH",
    "android.permission.RECEIVE_MMS",
    "android.permission.READ_EXTERNAL_STORAGE",
    "android.permission.WRITE_EXTERNAL_STORAGE",
    "android.permission.READ_MEDIA_IMAGES",
    "android.permission.READ_MEDIA_VIDEO",
    "android.permission.READ_MEDIA_AUDIO",
    "android.permission.POST_NOTIFICATIONS",
    "android.permission.NEARBY_WIFI_DEVICES",
    "android.permission.ACTIVITY_RECOGNITION",
    "android.permission.BLUETOOTH_SCAN",
    "android.permission.BLUETOOTH_ADVERTISE",
    "android.permission.BLUETOOTH_CONNECT",
}


class APKPermissionsExtractor(APKExtractor):

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

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

    def _get_protection_level(self, perm_name):
        """Determine the protection level of a permission.

        Uses androguard's permission mappings first, falls back to the
        known dangerous list.
        """
        try:
            from androguard.core.api_specific_resources import load_permission_mappings
            target_sdk = self.apk.get_target_sdk_version()
            sdk = int(target_sdk) if target_sdk else 30
            permission_map = load_permission_mappings(sdk)
            if perm_name in permission_map:
                info = permission_map[perm_name]
                if isinstance(info, dict):
                    return info.get("protectionLevel", "unknown")
                return "unknown"
        except Exception:
            pass

        # Fallback to known dangerous set
        if perm_name in DANGEROUS_PERMISSIONS:
            return "dangerous"
        if perm_name.startswith("android.permission."):
            return "normal"
        return "unknown"

    def _compute_permhash(self):
        """Compute permhash using the permhash library."""
        try:
            from permhash.functions import permhash_apk
            return permhash_apk(self.filepath)
        except Exception as e:
            self.log.warning(f"Failed to compute permhash: {e}")
            return None

    def _safe_extract(self, field_name, func, default=None):
        """Extract a single field, logging and returning default on failure."""
        try:
            return func()
        except Exception as e:
            self.log.warning(
                f"Error extracting APK permissions field '{field_name}' for "
                f"{self.hash.sha256}: {e}"
            )
            return default

    def extract(self):
        if not self._is_valid_apk():
            self.log.error(f"Invalid APK for {self.hash.sha256}")
            return None

        requested_perms = self._safe_extract(
            "requested_permissions",
            lambda: list(self.apk.get_permissions() or []), []
        )
        custom_perms = self._safe_extract(
            "custom_permissions",
            lambda: list(self.apk.get_declared_permissions() or []), []
        )
        custom_perm_set = set(custom_perms)

        permission_details = []
        dangerous_permissions = []

        for perm in requested_perms:
            try:
                protection_level = self._get_protection_level(perm)
                is_custom = perm in custom_perm_set

                permission_details.append(APKPermission(
                    permission_name=perm,
                    protection_level=protection_level,
                    is_custom=is_custom,
                ))

                if protection_level == "dangerous":
                    dangerous_permissions.append(perm)
            except Exception as e:
                self.log.warning(
                    f"Error processing permission '{perm}' for "
                    f"{self.hash.sha256}: {e}"
                )
                permission_details.append(APKPermission(
                    permission_name=perm,
                    protection_level="unknown",
                    is_custom=perm in custom_perm_set,
                ))

        permhash_value = self._compute_permhash()

        self.permissions_data = APKPermissions(
            total_permission_count=len(requested_perms),
            dangerous_permission_count=len(dangerous_permissions),
            permissions=requested_perms,
            dangerous_permissions=dangerous_permissions,
            custom_permissions=custom_perms,
            permission_details=permission_details,
            permhash=permhash_value,
        )
        return self.permissions_data

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

            current_time = datetime.now(timezone.utc)

            # One row per permission
            data = []
            for detail in self.permissions_data.permission_details:
                data.append([
                    self.sha256,
                    detail.permission_name,
                    detail.protection_level,
                    int(detail.is_custom),
                    current_time,
                ])

            if not data:
                return None

            column_names = [
                'sha256', 'permission_name', 'protection_level',
                'is_custom', 'analysis_date',
            ]

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

            return (data, column_names, column_type_names)

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