Victor Guerra

55 papers A* 1B 1C 2Journal 23Unranked 28
YearRankTypeTitle / Venue / Authors
2025 J jnl
IEEE Internet Things J.
Jose Martin Luna-Rivera, Carlos A. Hernández-Morales, Vicente Matus, José Rabadán, Julio Francisco Rufo Torres, Victor Guerra, Rafael Pérez Jiménez
2025 J jnl
IEEE Access
Alexander Herzog, Benoit Hamon, Paul Myland, Peter Förster, Simon Benkner, Babak Zandi, Victor Guerra, Sebastian Schöps, Willem D. van Driel, Tran Quoc Khanh
2024 J jnl
Expert Syst. Appl.
J. M. Luna-Rivera, José Rabadán, Julio Francisco Rufo Torres, Victor Guerra, Daniel Moreno, Rafael Pérez Jiménez
2024 J jnl
Sensors
Idaira Rodríguez-Yánez, Victor Guerra, José Rabadán, Rafael Pérez Jiménez
2024 conf
CSNDSP
J. M. Luna-Rivera, José Rabadán, Julio Francisco Rufo Torres, Victor Guerra, Carlos A. Gutiérrez, Rafael Pérez Jiménez
2024 conf
CSNDSP
Eleni Niarchou, Vicente Matus, Rafael Pérez Jiménez, José Rabadán, Victor Guerra
2024 conf
CSNDSP
José Rabadán, Victor Guerra, Francesco Ferrari, Rafael Pérez Jiménez, Marco Giuliani, Benoit Bataillou, Serge Nicolle
2024 J jnl
Sensors
Eleni Niarchou, Vicente Matus, José Rabadán, Victor Guerra, Rafael Pérez Jiménez
2024 J jnl
Future Gener. Comput. Syst.
Victor Guerra, Benoit Hamon, Benoit Bataillou, Adwait Inamdar, Willem D. van Driel
2023 conf
ConTEL
Eleni Niarchou, Vicente Matus, José Rabadán, Victor Guerra, Rafael Pérez Jiménez
2023 A* conf
MobiCom
Behnaz Majlesein, Callum T. Geldard, Victor Guerra, J. M. Luna-Rivera, Julio Francisco Rufo Torres, Wasiu O. Popoola, José Rabadán
2022 C conf
WFCS
Cristo Jurado-Verdu, Victor Guerra, José Rabadán, Rafael Pérez Jiménez
2022 J jnl
IEEE Access
Behnaz Majlesein, Victor Guerra, José Rabadán, Julio Francisco Rufo Torres, Rafael Pérez Jiménez
2022 conf
CSNDSP
Behnaz Majlesein, Vicente Matus, Cristo Jurado-Verdu, Victor Guerra, José Rabadán, Julio Francisco Rufo Torres
2022 conf
CSNDSP
Antonio Mederos-Barrera, Carlos Guerra-Yánez, Cristo Jurado-Verdu, Victor Guerra, José Rabadán, Rafael Pérez Jiménez, Stanislav Zvánovec
2022 C conf
IECON
Julio Francisco Rufo Torres, Victor Guerra, Jose Martin Luna-Rivera, James Farmer, Dominic C. O'Brien
2022 conf
CSNDSP
Cristo Jurado-Verdu, Victor Guerra, Carlos Guerra, José Rabadán, Stanislav Zvánovec, Rafael Pérez Jiménez
2022 conf
CSNDSP
Daniel Moreno, Victor Guerra, Julio Francisco Rufo Torres, José Rabadán, Rafael Pérez Jiménez
2022 J jnl
Sensors
Edmundo Torres-Zapata, Victor Guerra, José Rabadán, Jose Martin Luna-Rivera, Rafael Pérez Jiménez
2021 J jnl
Sensors
Antonio Mederos-Barrera, Cristo Jurado-Verdu, Victor Guerra, José Rabadán, Rafael Pérez Jiménez
2021 B conf
PIMRC
Vicente Matus, Victor Guerra, Cristo Jurado-Verdu, Stanislav Zvanovec, José Rabadán, Rafael Pérez Jiménez
2021 J jnl
Sensors
Cristo Jurado-Verdu, Victor Guerra, Vicente Matus, Carlos Almeida, José Rabadán
2021 J jnl
Sensors
Lidia Aguiar-Castillo, Victor Guerra, Julio Francisco Rufo Torres, José Rabadán, Rafael Pérez Jiménez
2021 conf
ISWCS
Edmundo Torres-Zapata, Victor Guerra, José Alberto Rabadán Borges, Jose Martin Luna-Rivera, Rafael Pérez Jiménez
2021 J jnl
Sensors
Vicente Matus, Victor Guerra, Cristo Jurado-Verdu, Stanislav Zvanovec, Rafael Pérez Jiménez
2020 conf
CSNDSP
Victor Guerra, Carlos Guerra, José Rabadán, Rafael Pérez Jiménez, Beatriz Ortega
2020 conf
CSNDSP
Cristo Jurado-Verdu, Victor Guerra, Vicente Matus, José Rabadán, Rafael Pérez Jiménez, Juan Luis Gomez-Pinchetti, Carlos Almeida
2020 conf
CSNDSP
Edmundo Torres-Zapata, Victor Guerra, José Rabadán, Rafael Pérez Jiménez, Jose Martin Luna-Rivera
2020 J jnl
Sensors
Victor Guerra, Jaime Roberto Ticay-Rivas, Victor Alonso-Eugenio, Rafael Pérez Jiménez
2020 conf
CSNDSP
Antonio Mederos-Barrera, Cristo Jurado-Verdu, Victor Guerra, José Rabadán, Rafael Pérez Jiménez
2020 conf
CSNDSP
Vicente Matus, Victor Guerra, Cristo Jurado-Verdu, Shivani Rajendra Teli, Stanislav Zvanovec, José Rabadán, Rafael Pérez Jiménez
2020 J jnl
Sensors
Francisco Alberto Delgado Rajó, Alexis Melian-Segura, Victor Guerra, Rafael Pérez Jiménez, David Sánchez-Rodríguez
2020 J jnl
Sensors
Edmundo Torres-Zapata, Victor Guerra, José Rabadán, Jose Martin Luna-Rivera, Rafael Pérez Jiménez
2020 conf
CSNDSP
Daniel Moreno, Behnaz Majlesein, Julio Francisco Rufo Torres, Victor Guerra, José Rabadán, Rafael Pérez Jiménez
2020 conf
LIOT@MOBICOM
Behnaz Majlesein, Julio Francisco Rufo Torres, Daniel Moreno, Victor Guerra, José Rabadán
2019 J jnl
Trans. Emerg. Telecommun. Technol.
A. M. Ramirez-Aguilera, J. M. Luna-Rivera, Victor Guerra, José Rabadán, Rafael Pérez Jiménez, Francisco J. Lopez-Hernandez
2019 J jnl
Trans. Emerg. Telecommun. Technol.
Edmundo Torres-Zapata, J. M. Luna-Rivera, Rafael Pérez Jiménez, Victor Guerra, José Rabadán, Julio Francisco Rufo Torres, Carlos A. Gutiérrez
2019 conf
ConTEL
Vicente Matus, Victor Guerra, Cristo Jurado-Verdu, José Rabadán, Rafael Pérez Jiménez
2019 conf
ConTEL
Victor Guerra, José Rabadán, Rafael Pérez Jiménez
2019 conf
ConTEL
Edmundo Torres-Zapata, Victor Guerra, José Rabadán, Rafael Pérez Jiménez, Jose Martin Luna-Rivera
2018 conf
LATINCOM
A. M. Ramirez-Aguilera, J. M. Luna-Rivera, Victor Guerra, José Rabadán, Rafael Pérez Jiménez, Francisco J. Lopez-Hernandez
2018 J jnl
Phys. Commun.
Daniel U. Campos-Delgado, J. M. Luna-Rivera, Rafael Pérez Jiménez, Carlos A. Gutiérrez, Victor Guerra, José Rabadán
2018 conf
CSNDSP
Patricia Chavez-Burbano, Victor Guerra, José Alberto Rabadán Borges, Cristo Jurado-Verdu, Rafael Pérez Jiménez
2018 conf
CSNDSP
Cristo Jurado-Verdu, Victor Guerra, José Rabadán, Rafael Pérez Jiménez, Patricia Chavez-Burbano
2018 conf
CSNDSP
Victor Guerra, Julio Francisco Rufo Torres, José Alberto Rabadán Borges, Rafael Pérez Jiménez
2017 J jnl
Sensors
Patricia Chavez-Burbano, Victor Guerra, José Alberto Rabadán Borges, Dionisio Rodríguez-Esparragón, Rafael Pérez Jiménez
2017 conf
IWOBI
Rafael Pérez Jiménez, José Rabadán, Victor Guerra, Lidia Aguiar, Julio Francisco Rufo Torres
2017 J jnl
Sensors
José Alberto Rabadán Borges, Victor Guerra, Rafael Rodríguez, Julio Francisco Rufo Torres, Jose Martin Luna-Rivera, Rafael Pérez Jiménez
2017 J jnl
Sensors
Ignacio Marin-Garcia, Victor Guerra, Rafael Pérez Jiménez
2016 conf
CSNDSP
Ignacio Marin-Garcia, A. M. Ramirez-Aguilera, Victor Guerra, José Alberto Rabadán Borges, Rafael Pérez Jiménez
2016 conf
CSNDSP
A. M. Ramirez-Aguilera, J. M. Luna-Rivera, Victor Guerra, José Alberto Rabadán Borges, Rafael Pérez Jiménez, Francisco J. Lopez-Hernandez
2015 conf
ICC Workshops
Victor Guerra, C. Suarez-Rodriguez, O. El-Asmar, José Alberto Rabadán Borges, Rafael Pérez Jiménez
2015 conf
ICL
Monika Andergassen, Günther Ernst, Victor Guerra, Felix Mödritscher, Markus Moser, Gustaf Neumann, Thomas Renner
2013 J jnl
Int. J. Mob. Blended Learn.
Monika Andergassen, Victor Guerra, Karl Ledermüller, Gustaf Neumann
2013 J jnl
IEEE Trans. Consumer Electron.
Crisanto Quintana Sánchez, Victor Guerra, Julio Francisco Rufo Torres, José Alberto Rabadán Borges, Rafael Pérez Jiménez
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"