Mahimna Kelkar

54 papers A* 12A 1B 3Journal 29Unranked 9
YearRankTypeTitle / Venue / Authors
2025 A* conf
CCS
Mahimna Kelkar, Aadityan Ganesh, Aditi Partap, Joseph Bonneau, S. Matthew Weinberg
2025 J jnl
IACR Cryptol. ePrint Arch.
Mahimna Kelkar, Aadityan Ganesh, Aditi Partap, Joseph Bonneau, S. Matthew Weinberg
2025 A* conf
SP
James Austgen, Andrés Fábrega, Mahimna Kelkar, Dani Vilardell, Sarah Allen, Kushal Babel, Jay Yu, Ari Juels
2025 A* conf
USENIX Security Symposium
Andrés Fábrega, Amy Zhao, Jay Yu, James Austgen, Sarah Allen, Kushal Babel, Mahimna Kelkar, Ari Juels
2025 J jnl
CoRR
Andrés Fábrega, Amy Zhao, Jay Yu, James Austgen, Sarah Allen, Kushal Babel, Mahimna Kelkar, Ari Juels
2024 A* conf
CCS
Ertem Nusret Tas, István András Seres, Yinuo Zhang, Márk Melczer, Mahimna Kelkar, Joseph Bonneau, Valeria Nikolaenko
2024 J jnl
IACR Cryptol. ePrint Arch.
Ertem Nusret Tas, István András Seres, Yinuo Zhang, Márk Melczer, Mahimna Kelkar, Joseph Bonneau, Valeria Nikolaenko
2024 B conf
AFT
Mario M. Alvarez, Henry Arneson, Ben Berger, Lee Bousfield, Chris Buckland, Yafah Edelman, Edward W. Felten, Daniel Goldman, Raul Jordan, Mahimna Kelkar, Akaki Mamageishvili, Harry Ng, Aman Sanghi, Victor Shoup, Terence Tsao
2024 J jnl
CoRR
Mario M. Alvarez, Henry Arneson, Ben Berger, Lee Bousfield, Chris Buckland, Yafah Edelman, Edward W. Felten, Daniel Goldman, Raul Jordan, Mahimna Kelkar, Akaki Mamageishvili, Harry Ng, Aman Sanghi, Victor Shoup, Terence Tsao
2024 A* conf
CCS
Mahimna Kelkar, Kushal Babel, Philip Daian, James Austgen, Vitalik Buterin, Ari Juels
2024 conf
CRYPTO (8)
Amit Agarwal, Elette Boyle, Niv Gilboa, Yuval Ishai, Mahimna Kelkar, Yiping Ma
2024 A* conf
CCS
Adrià Gascón, Yuval Ishai, Mahimna Kelkar, Baiyu Li, Yiping Ma, Mariana Raykova
2024 J jnl
IACR Cryptol. ePrint Arch.
Adrià Gascón, Yuval Ishai, Mahimna Kelkar, Baiyu Li, Yiping Ma, Mariana Raykova
2024 conf
FC (2)
Deepak Maram, Mahimna Kelkar, Iddo Bentov, Ari Juels
2024 A conf
ITC
Yuval Ishai, Mahimna Kelkar, Daniel Lee, Yiping Ma
2024 J jnl
IACR Cryptol. ePrint Arch.
Yuval Ishai, Mahimna Kelkar, Daniel Lee, Yiping Ma
2024 A* conf
CCS
Deepak Maram, Mahimna Kelkar, Ittay Eyal
2024 J jnl
CoRR
James Austgen, Andrés Fábrega, Mahimna Kelkar, Dani Vilardell, Sarah Allen, Kushal Babel, Jay Yu, Ari Juels
2024 J jnl
CoRR
Kushal Babel, Nerla Jean-Louis, Yan Ji, Ujval Misra, Mahimna Kelkar, Kosala Yapa Mudiyanselage, Andrew Miller, Ari Juels
2024 J jnl
IACR Cryptol. ePrint Arch.
Kushal Babel, Nerla Jean-Louis, Yan Ji, Ujval Misra, Mahimna Kelkar, Kosala Yapa Mudiyanselage, Andrew Miller, Ari Juels
2024 A* conf
CCS
Amit Agarwal, Elette Boyle, Nishanth Chandran, Niv Gilboa, Divya Gupta, Yuval Ishai, Mahimna Kelkar, Yiping Ma
2024 J jnl
IACR Cryptol. ePrint Arch.
Mahimna Kelkar, Yunqi Li, Nerla Jean-Louis, Carolina Ortega Pérez, Kushal Babel, Andrew Miller, Ari Juels
2024 conf
FC (2)
Foteini Baldimtsi, Konstantinos Chalkias, Panagiotis Chatzigiannis, Mahimna Kelkar
2023 B conf
AFT
Akaki Mamageishvili, Mahimna Kelkar, Jan Christoph Schlegel, Edward W. Felten
2023 J jnl
CoRR
Akaki Mamageishvili, Mahimna Kelkar, Jan Christoph Schlegel, Edward W. Felten
2023 A* conf
SP
Kushal Babel, Philip Daian, Mahimna Kelkar, Ari Juels
2023 J jnl
IACR Cryptol. ePrint Arch.
Mahimna Kelkar, Kushal Babel, Philip Daian, James Austgen, Vitalik Buterin, Ari Juels
2023 J jnl
CoRR
James Austgen, Andrés Fábrega, Sarah Allen, Kushal Babel, Mahimna Kelkar, Ari Juels
2023 A* conf
CCS
Kushal Babel, Mojan Javaheripi, Yan Ji, Mahimna Kelkar, Farinaz Koushanfar, Ari Juels
2023 J jnl
IACR Cryptol. ePrint Arch.
Kushal Babel, Mojan Javaheripi, Yan Ji, Mahimna Kelkar, Farinaz Koushanfar, Ari Juels
2023 conf
CRYPTO (1)
Yuval Ishai, Mahimna Kelkar, Varun Narayanan, Liav Zafar
2023 J jnl
IACR Cryptol. ePrint Arch.
Yuval Ishai, Mahimna Kelkar, Varun Narayanan, Liav Zafar
2023 B conf
AFT
Donald Beaver, Konstantinos Chalkias, Mahimna Kelkar, Lefteris Kokoris-Kogias, Kevin Lewi, Ladi de Naurois, Valeria Nikolaenko, Arnab Roy, Alberto Sonnino
2023 A* conf
CCS
Mahimna Kelkar, Soubhik Deb, Sishan Long, Ari Juels, Sreeram Kannan
2023 conf
WPES@CCS
Mathieu Baudet, Alberto Sonnino, Mahimna Kelkar, George Danezis
2022 J jnl
IACR Cryptol. ePrint Arch.
Deepak Maram, Mahimna Kelkar, Ittay Eyal
2022 conf
APKC@AsiaCCS
Mahimna Kelkar, Soubhik Deb, Sreeram Kannan
2022 A* conf
USENIX Security Symposium
Mahimna Kelkar, Phi Hung Le, Mariana Raykova, Karn Seth
2022 J jnl
IACR Cryptol. ePrint Arch.
Foteini Baldimtsi, Konstantinos Chalkias, Panagiotis Chatzigiannis, Mahimna Kelkar
2022 J jnl
CoRR
Mathieu Baudet, Alberto Sonnino, Mahimna Kelkar, George Danezis
2022 J jnl
IACR Cryptol. ePrint Arch.
Mathieu Baudet, Alberto Sonnino, Mahimna Kelkar, George Danezis
2021 J jnl
CoRR
Kushal Babel, Philip Daian, Mahimna Kelkar, Ari Juels
2021 J jnl
IACR Cryptol. ePrint Arch.
Kushal Babel, Philip Daian, Mahimna Kelkar, Ari Juels
2021 J jnl
IACR Cryptol. ePrint Arch.
Deepak Maram, Iddo Bentov, Mahimna Kelkar, Ari Juels
2021 conf
CRYPTO (4)
Itai Dinur, Steven Goldfeder, Tzipora Halevi, Yuval Ishai, Mahimna Kelkar, Vivek Sharma, Greg Zaverucha
2021 J jnl
IACR Cryptol. ePrint Arch.
Itai Dinur, Steven Goldfeder, Tzipora Halevi, Yuval Ishai, Mahimna Kelkar, Vivek Sharma, Greg Zaverucha
2021 J jnl
IACR Cryptol. ePrint Arch.
Mahimna Kelkar, Soubhik Deb, Sreeram Kannan
2021 J jnl
IACR Cryptol. ePrint Arch.
Donald Beaver, Konstantinos Chalkias, Mahimna Kelkar, Lefteris Kokoris-Kogias, Kevin Lewi, Ladi de Naurois, Valeria Nicolaenko, Arnab Roy, Alberto Sonnino
2021 J jnl
IACR Cryptol. ePrint Arch.
Mahimna Kelkar, Phi Hung Le, Mariana Raykova, Karn Seth
2021 J jnl
IACR Cryptol. ePrint Arch.
Mahimna Kelkar, Soubhik Deb, Sishan Long, Ari Juels, Sreeram Kannan
2020 conf
CRYPTO (3)
Mahimna Kelkar, Fan Zhang, Steven Goldfeder, Ari Juels
2020 J jnl
IACR Cryptol. ePrint Arch.
Mahimna Kelkar, Fan Zhang, Steven Goldfeder, Ari Juels
2019 conf
ESORICS (1)
Duc Viet Le, Mahimna Kelkar, Aniket Kate
2018 J jnl
IACR Cryptol. ePrint Arch.
Duc Viet Le, Mahimna Kelkar, Aniket Kate
redb/extractors/apk_extractors/apk_inconsistency_tests.py
← Index redb/extractors/apk_extractors/apk_inconsistency_tests.py python
import inspect
import re
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 APKInconsistencyTests

# Emulator detection indicator strings
EMULATOR_INDICATORS = {
    "generic", "sdk", "google_sdk", "Emulator",
    "goldfish", "ranchu", "Andy", "Genymotion",
    "BlueStacks", "nox", "ttVM_Hdragon",
}

# Root detection indicator strings
ROOT_INDICATORS = {
    "/system/app/Superuser.apk",
    "/system/xbin/su",
    "/system/bin/su",
    "com.noshufou.android.su",
    "com.thirdparty.superuser",
    "eu.chainfire.supersu",
    "com.koushikdutta.superuser",
    "com.topjohnwu.magisk",
}

# Standard DEX filename pattern
STANDARD_DEX_PATTERN = re.compile(r"^classes\d*\.dex$")


class APKInconsistencyTestsExtractor(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.test_results = None
        self.log.debug(inspect.currentframe().f_code.co_name)

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

    def _test_zip_bomb(self):
        """Check if any ZIP entry has compression ratio > 100:1."""
        try:
            zf = self._get_zip_file()
            if not zf:
                return None
            with zf:
                for info in zf.infolist():
                    if info.compress_size > 0:
                        ratio = info.file_size / info.compress_size
                        if ratio > 100:
                            return True
            return False
        except Exception as e:
            self.log.warning(f"Error in zip bomb test: {e}")
            return None

    def _test_zip_duplicate_entries(self):
        """Check for duplicate filenames in ZIP directory."""
        try:
            zf = self._get_zip_file()
            if not zf:
                return None
            with zf:
                names = [info.filename for info in zf.infolist()]
                return len(names) != len(set(names))
        except Exception as e:
            self.log.warning(f"Error in duplicate entries test: {e}")
            return None

    def _test_zip_path_traversal(self):
        """Check for path traversal (../) in ZIP entry names."""
        try:
            for f in self._list_files():
                if ".." in f or f.startswith("/"):
                    return True
            return False
        except Exception as e:
            self.log.warning(f"Error in path traversal test: {e}")
            return None

    def _test_zip_suspicious_timestamps(self):
        """Check for timestamps at epoch (1980) or in the future."""
        try:
            zf = self._get_zip_file()
            if not zf:
                return None
            now = datetime.now()
            with zf:
                for info in zf.infolist():
                    try:
                        dt = datetime(*info.date_time)
                        if dt.year <= 1980 or dt > now:
                            return True
                    except (ValueError, TypeError):
                        continue
            return False
        except Exception as e:
            self.log.warning(f"Error in suspicious timestamps test: {e}")
            return None

    def _test_hidden_dex_files(self):
        """Check for DEX files not matching classes*.dex pattern."""
        try:
            for f in self._list_files():
                if f.endswith(".dex"):
                    basename = f.split("/")[-1]
                    if not STANDARD_DEX_PATTERN.match(basename):
                        return True
            return False
        except Exception as e:
            self.log.warning(f"Error in hidden DEX files test: {e}")
            return None

    def _test_manifest_component_mismatch(self):
        """Check for declared components that don't exist in DEX."""
        try:
            if not self._is_valid_apk():
                return None

            # Get all class names from DEX
            dex_classes = set()
            try:
                from androguard.core.dex import DEX
                for dex_data in (self.apk.get_all_dex() or []):
                    try:
                        d = DEX(dex_data)
                        for cls in d.get_classes():
                            name = cls.get_name()
                            if name:
                                # Convert "Lcom/example/Foo;" to "com.example.Foo"
                                dex_classes.add(
                                    name[1:-1].replace("/", ".") if name.startswith("L") else name
                                )
                    except Exception:
                        continue
            except Exception:
                return None

            if not dex_classes:
                return None

            # Check manifest components against DEX classes
            components = []
            try:
                components.extend(self.apk.get_activities() or [])
                components.extend(self.apk.get_services() or [])
                components.extend(self.apk.get_receivers() or [])
                components.extend(self.apk.get_providers() or [])
            except Exception:
                return None

            for comp in components:
                if comp and comp not in dex_classes:
                    # Component might use a shorthand; check with package prefix
                    package = self.apk.get_package() or ""
                    full_name = package + comp if comp.startswith(".") else comp
                    if full_name not in dex_classes:
                        return True

            return False
        except Exception as e:
            self.log.warning(f"Error in manifest component mismatch test: {e}")
            return None

    def _test_debuggable_release(self):
        """Check android:debuggable=true combined with a release signature."""
        try:
            if not self._is_valid_apk():
                return None

            is_debuggable = self.apk.get_attribute_value(
                "application", "debuggable"
            ) == "true"

            if not is_debuggable:
                return False

            # Check if it has a signing certificate (release builds have certs)
            try:
                certs = self.apk.get_certificates()
                if certs and len(certs) > 0:
                    return True
            except Exception:
                pass

            return False
        except Exception as e:
            self.log.warning(f"Error in debuggable release test: {e}")
            return None

    def _get_dex_strings(self):
        """Get all string constants from DEX files."""
        all_strings = set()
        try:
            from androguard.core.dex import DEX
            for dex_data in (self.apk.get_all_dex() or []):
                try:
                    d = DEX(dex_data)
                    for s in d.get_strings():
                        if s:
                            all_strings.add(s)
                except Exception:
                    continue
        except Exception:
            pass
        return all_strings

    def _test_emulator_detection_strings(self):
        """Check for emulator detection patterns in DEX strings."""
        try:
            if not self._is_valid_apk():
                return None

            dex_strings = self._get_dex_strings()
            for indicator in EMULATOR_INDICATORS:
                for s in dex_strings:
                    if indicator in s:
                        return True
            return False
        except Exception as e:
            self.log.warning(f"Error in emulator detection test: {e}")
            return None

    def _test_debugger_detection(self):
        """Check for debugger detection API calls in DEX."""
        try:
            if not self._is_valid_apk():
                return None

            dex_strings = self._get_dex_strings()
            debugger_patterns = {
                "isDebuggerConnected",
                "waitingForDebugger",
                "Debug.isDebuggerConnected",
            }
            for pattern in debugger_patterns:
                for s in dex_strings:
                    if pattern in s:
                        return True
            return False
        except Exception as e:
            self.log.warning(f"Error in debugger detection test: {e}")
            return None

    def _test_root_detection(self):
        """Check for root detection patterns in DEX."""
        try:
            if not self._is_valid_apk():
                return None

            dex_strings = self._get_dex_strings()
            for indicator in ROOT_INDICATORS:
                for s in dex_strings:
                    if indicator in s:
                        return True
            return False
        except Exception as e:
            self.log.warning(f"Error in root detection test: {e}")
            return None

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

        self.test_results = APKInconsistencyTests(
            test_zip_bomb=self._test_zip_bomb(),
            test_zip_duplicate_entries=self._test_zip_duplicate_entries(),
            test_zip_path_traversal=self._test_zip_path_traversal(),
            test_zip_suspicious_timestamps=self._test_zip_suspicious_timestamps(),
            test_hidden_dex_files=self._test_hidden_dex_files(),
            test_manifest_component_mismatch=self._test_manifest_component_mismatch(),
            test_debuggable_release=self._test_debuggable_release(),
            test_emulator_detection_strings=self._test_emulator_detection_strings(),
            test_debugger_detection=self._test_debugger_detection(),
            test_root_detection=self._test_root_detection(),
        )
        return self.test_results

    def _bool_to_nullable(self, val):
        """Convert bool/None to ClickHouse Nullable(UInt8)."""
        if val is None:
            return None
        return int(val)

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

            current_time = datetime.now(timezone.utc)
            t = self.test_results

            data = [[
                self.sha256,
                self._bool_to_nullable(t.test_zip_bomb),
                self._bool_to_nullable(t.test_zip_duplicate_entries),
                self._bool_to_nullable(t.test_zip_path_traversal),
                self._bool_to_nullable(t.test_zip_suspicious_timestamps),
                self._bool_to_nullable(t.test_hidden_dex_files),
                self._bool_to_nullable(t.test_manifest_component_mismatch),
                self._bool_to_nullable(t.test_debuggable_release),
                self._bool_to_nullable(t.test_emulator_detection_strings),
                self._bool_to_nullable(t.test_debugger_detection),
                self._bool_to_nullable(t.test_root_detection),
                current_time,
            ]]

            column_names = [
                'sha256',
                'test_zip_bomb', 'test_zip_duplicate_entries',
                'test_zip_path_traversal', 'test_zip_suspicious_timestamps',
                'test_hidden_dex_files', 'test_manifest_component_mismatch',
                'test_debuggable_release', 'test_emulator_detection_strings',
                'test_debugger_detection', 'test_root_detection',
                'analysis_date',
            ]

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

            return (data, column_names, column_type_names)

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