
Tous les chiens vont au paradis, et tous les propriétaires de boutiques en ligne sur Opencart, tôt ou tard sur Opencartforum. Lorsque l'euphorie de la première installation du moteur sur l'hébergement passe et que la dure réalité commence, le propriétaire de magasin typique commence toujours à manquer quelque chose et il commence le chemin difficile de trouver des entrepreneurs qualifiés et des compléments de qualité pour son magasin.
La plus grande ressource de Runet, sur laquelle vous pouvez trouver les deux, est opencartforum.com, qui compte aujourd'hui plus de 140 000 utilisateurs enregistrés. Sur ces 140 000 inscriptions, la moitié d'entre elles sont des personnes vivant avec des boutiques en direct qui utilisent des modèles ou des modules d'une manière ou d'une autre, qui peuvent être immédiatement achetés sur le site. Et toutes ces personnes ne réalisent même pas qu’avec les modules complémentaires, elles acquièrent de merveilleuses portes dérobées et des vulnérabilités, dont n’importe quelle mère pirate ne peut que rêver.
Bien que sous une forme déclarative dans les règles de publication des modules complémentaires dans la boutique du forum, il est écrit en noir et blanc. Nous avons qadepartment, des personnes spécialement formées vérifient les extensions pour les vulnérabilités.
Et ni le forum, en tant que plate-forme qui sert d'intermédiaire entre l'auteur et l'utilisateur final du module complémentaire, ni les auteurs des modules complémentaires, comme il s'est avéré, n'assument aucune responsabilité.
Comment ça? Et donc! Apparemment, historiquement.
Modélisant pour moi-même les conséquences hypothétiques des incidents, qui seront discutées plus tard, mes cheveux sur ma tête se tiennent debout.
Imaginez. Vous êtes un propriétaire de magasin prospère, vous n'avez pas dormi la nuit depuis quelques années, écrit des textes, grignoté du noir, du blanc, du gris, des pandas combattus, de minusinsk, vous n'avez pas fini votre boisson, attiré 100000 clients, investi dans des positions. Vos enfants vont dans un bon jardin d'enfants, puis soudainement vos ventes ont diminué de moitié, tout simplement parce que votre base avec tous les contacts clients est allée chez les concurrents. Ou soudain, vous l'avez complètement perdu, car depuis un mois maintenant, votre magasin travaille sur le serveur mysql de quelqu'un d'autre, et vous n'avez même pas remarqué le changement de kofig, et toutes les sauvegardes sur l'hébergement ont mal tourné.
Ils ont présenté leurs sentiments dans une situation similaire, travaillé, travaillé pendant plusieurs années, et en un jour, tout est perdu. Vous dites que cela ne peut pas en être ainsi.
Mais cela peut être très simple. Il suffit d’acheter un module complémentaire avec une «protection» de protection non déclarée et non déclarée contre une utilisation non autorisée, et vos données peuvent rapidement devenir des étrangers!
Premier incident
Il y a six mois, une maintenance préventive superficielle d'un magasin a été effectuée lorsque le rapport du scanner Ai-Bol a montré un étrange avertissement concernant un code étrange dans le module
SeoCms (plus de 10 000 installations actives).
Nous avons commencé à regarder de plus près et il s'est avéré que cet abracadabra affiche simplement la version de l'add-on:
$text_redaeh_stpo = $text_redaeh_stpo_1.$value_tnega.$text_redaeh_stpo_2.$text_redaeh_stpo_3.$text_reda eh_stpo_4.$text_redaeh_stpo_5.$text_redaeh_stpo_6.$text_redaeh_stpo_7.$text_redaeh _stpo_8.$text_redaeh_stpo_9.$value_revres.$text_redaeh_stpo_10; if ($date_diff > 7) { $ver_content = false; $opts = array( $text_ptth => array($text_dohtem =>$text_tsop, $redaeh =>$text_redaeh_stpo, $tnetnoc => $yreuq_dliub_ptth(array($text_rdda =>$value_rdda, $text_liame => $this->data['liame'], $text_rev=>$this->data['blog_version'] )))); $context = $etaerc_txetnoc_maerts($opts); $exceptionizer = new PHP_Exceptionizer(E_ALL); try { $ver_content = $stnetnoc_teg_elif($rev_knil, FALSE , $context); } catch (E_WARNING $e) {
C'est bon sauf que:
$this->language->get('text_new_version').$ver_content. " <span style='color: #000; font-weight: normal;'>(".$date_ver_update.")</span>"
il n'est en aucun cas filtré, et si par accident un script comme celui ci-dessous arrive à la place de la version du client, obtenir un accès administrateur à n'importe quel magasin où le module est installé est une question de temps et de technique.
<script>
Les détails de la situation sont décrits
ici . Avis d'administration
ici .
Probablement la cinquième fois, après avoir modélisé ce processus très clairement pour l'administration du forum, il a été possible de transmettre la criticité de la situation.
Et l'administration, à son tour, a officiellement informé les utilisateurs de la présence de cette vulnérabilité, et il semble qu'elle ait même fait une newsletter aux clients. Mais ce n'est pas exact.
Laissons dans les coulisses les menaces et les évasions de l'auteur du module complémentaire et revenons deux mois en arrière ...
Deuxième incident
Un autre magasin vient pour inspection, dans lequel il y a des frises sauvages jusqu'à 3-4 secondes sur chaque page. Nous commençons à disséquer et à voir dans le dossier avec un cache de 20k + fichiers avec l'extension .php. Cachez les fichiers avec l'extension php Karl, ce n'est pas un hasard!
Nous examinons la structure des données de ces fichiers, et là encore des morceaux de notre beau module SEOCMS.
Et une excellente méthode:
protected function ajax_file() { $ajax_file_cached = false; $ajax_file = DIR_CACHE.base64_decode($this->db->escape($this->request->get["ajax_file"])); if (!file_exists($ajax_file)) { $ajax_file_cached = true; } else { } return $ajax_file_cached; }
Ceci est un exemple d'une vulnérabilité classique - Local File Include.
Il suffit de coder en base64 ../....../config.php et bonjour - require ($ ajax_file); Et s'il vous plaît: ici, vous avez les mots de passe de la base de données, et voici le journal des erreurs système, et si même / etc / pwd est très nécessaire, bien qu'il soit depuis longtemps hors de propos, eh bien, et si?
Et combien d'hébergeurs et de serveurs avec des paramètres par défaut brillent dans le monde de phpmyadmin? La moitié? Plus?
Nous commençons à chercher plus loin et que trouvons-nous? Magnifique code de téléchargement d'avatar:
if (!$json) { if (is_uploaded_file($this->request->files['file']['tmp_name']) && file_exists($this->request->files['file']['tmp_name'])) { $file = basename($filename) . '.' . md5(substr(sha1(uniqid(mt_rand(), true)), 0, 10)); $file_original = basename($filename);
Ce qui tombe parfaitement en erreur lors de la tentative de redimensionnement (et nous montre le chemin complet vers le fichier téléchargé), après le chargement d'une sorte de shell.php.png, puis il est également parfaitement exécuté par la méthode précédente.
Vidéo d'exploitation de la vulnérabilité (avec sortie d'erreur système php activée):
Vidéo d'exploitation de la vulnérabilité (avec sortie d'erreur du système php désactivée):
L'analyse du code a été réalisée sur la version du module 52 en avril 2019.
Étant donné que l'auteur et l'administration du forum ont été informés aux mêmes dates, suffisamment de temps s'est écoulé pour qu'ils prennent toutes les mesures possibles pour informer les acheteurs de l'élimination des vulnérabilités, nous, en toute conscience, pouvons divulguer tous les détails.
Et à ce moment, quelque chose s'est produit. Sur le serveur du développeur se trouvait son propre module. Mais la vulnérabilité n'a pas fonctionné. Elle était couverte ... Et c'est une grande bizarrerie. Très gros !!!
Et la deuxième bizarrerie de toute cette histoire est que l'opencartforum en la personne de l'administration et du service de contrôle de la qualité des suppléments n'a vu ni le premier ni le deuxième incident, et dans les deux cas, lors de la première notification, il n'a rien trouvé de critique.
Bien sûr, il n'y a rien de critique lorsque vos configurations brillent dans le monde. Il n'y a rien de critique quand une bonne moitié des commerçants ne savent pas ce qui se passe sous leur capot. Après tout, une fois, quelqu'un a mis ce module complémentaire, et sans mailing, ils ne réalisent même pas que toute l'entreprise est directement menacée.
Et s'il y a eu une réaction distincte de l'administration sur le premier incident, alors sur le second, tous les messages avec une mention sont supprimés. Et tout cela est couvert par une
offre de forum , selon laquelle, à propos des ajouts commerciaux, des commentaires peuvent être laissés comme sur les morts - bons ou rien.
L'auteur affirme également que les erreurs et les trous sont corrigés, qadepartment a manqué l'add-on à vendre, mais non, les trous ne sont pas corrigés ...
protected function ajax_file() { if (!class_exists('PHP_Exceptionizer', false)) { if (function_exists('modification')) { require_once(modification(DIR_SYSTEM . 'library/exceptionizer.php')); } else { require_once(DIR_SYSTEM . 'library/exceptionizer.php'); } } $exceptionizer = new PHP_Exceptionizer(E_ALL); try { $ajax_file_cached = false; $filename = preg_replace('/[^a-zA-Z0-9\.\-\s+]/', '', html_entity_decode(base64_decode($this->db->escape($this->request->get['ajax_file'])), ENT_QUOTES, 'UTF-8')); $ajax_file = DIR_CACHE . $filename; if (!file_exists($ajax_file)) { $ajax_file_cached = true; } else { ob_start(); require($ajax_file); $ajax_html = ob_get_contents(); ob_end_clean(); header('Content-type: text/html; charset=utf-8'); echo $ajax_html; $this->deletecache('cache.ajax'); exit(); } return $ajax_file_cached; } catch (E_WARNING $e) { } }
require () est toujours là. L'entrée est légèrement filtrée. Mais la LFI potentielle a vécu et vit. Si un peu plus, alors oui, maintenant nous ne pouvons ni charger ni exécuter le shell. Mais supposons que nous ayons essayé, fermé, cimenté l'exécution de tous les scripts sauf index.php, et même au niveau de la configuration nginx, qui n'est en aucun cas accessible. Mais quelque part ailleurs, le pirate maléfique a eu l'occasion de mettre un fichier arbitraire dans le dossier cache. Que va-t-il se passer? C'est vrai - pour exécuter du code superflu, générant un hachage dans la requête get, cela prend deux minutes. C'est-à-dire qu'en fin de compte, c'est un peu comme fermé, mais ce n'est pas comme complètement.
Eh bien, les petites choses: comment de si belles relations brillaient dans les fichiers de langue:
if ((isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) == 'on' || $_SERVER['HTTPS'] == '1')) || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') || (!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && strtolower($_SERVER['HTTP_X_FORWARDED_SSL']) == 'on'))) { $_['value_revres'] = HTTPS_SERVER; $_['value_ctlg'] = HTTPS_CATALOG; } else { $_['value_revres'] = HTTP_SERVER; $_['value_ctlg'] = HTTP_CATALOG; }
Et ils brillent ... Vous voulez connaître le chemin complet vers la racine du projet. Trouvez simplement le magasin avec l'affichage d'erreur activé et exécutez le lien directement vers le fichier de langue.
Pour étudier ce qui peut être après la mise à jour du module complémentaire en mégaoctets de lignes de code de l'auteur - il n'y a ni ressources ni désir. Il y a des personnes responsables spécialement formées pour cela.
Et la cerise sur le gâteau. Nous nous souvenons, nous avons un add-on commercial ... Et dans un add-on commercial, nous avons du texte caché sur la ressource de l'auteur:
www.google.com/search?q=%22Powered+by+SEO+CMS%22
Fait intéressant, au moins l'un des acheteurs de modules complémentaires connaît un œuf de Pâques aussi «merveilleux»?
Aujourd'hui, le supplément est à la fois vendu et vendu. Les messages contenant des appels pour faire attention à la situation sont simplement supprimés. Aucun des acheteurs n'a reçu de notifications d'avertissement concernant le deuxième incident. Peut-être que 20 à 30% des utilisateurs de modules complémentaires ont mis à jour, mais 70% - même si nous parlons des statistiques officielles de l'auteur sur l'utilisation des modules complémentaires, ce sont 7000 magasins (en fait, plus - car personne ne sait avec certitude combien de copies ont été installées par des pigistes sur les magasins clients licence étendue) sont dans une zone de risque énorme.
Pour reprendre les mots du baron Munchausen, je ne veux dire qu'une chose: messieurs mis à jour!
Pour les clients
Que faire, ceux qui se sont retrouvés dans ce sous-marin en perdition:
- Ne laissez pas de déchets sur ftp. Afficher info.php, adminer.php et toutes les autres poubelles. Vous ne devriez avoir que index.php et un point.
- Modifiez régulièrement les mots de passe, tous les mots de passe (ftp, panneau d'administration, base de données). Et assurez-vous que vous n'avez pas accidentellement de comptes étranges supplémentaires.
- Désactiver la sortie d'erreur. Toujours, si vous ne travaillez pas, désactivez la sortie d'erreur au niveau de la configuration de l'interpréteur et non dans les paramètres du magasin.
- Oui, je sais que ce n'est pas très faisable, mais vous devriez au moins vous tenir au courant de la mise à jour du code moteur lié à la sécurité, et idéalement, mettre régulièrement à jour le moteur vers des versions stables.
- Regardez régulièrement les journaux de visites, il peut y avoir beaucoup de choses intéressantes. Suivez les anomalies.
- Fermez en plus avec un mot de passe ou une restriction sur l'admin ip du magasin et diverses sections vulnérables, telles que phpmyadmin. S'il s'agit d'un partage dans lequel phpmyadmin est commun à tous, fuyez cet hébergement!
- Si vous utilisez sxd et des utilitaires similaires, renommez-les immédiatement en un jeu de caractères aléatoire.
- Lorsque vous utilisez nginx, il vaut la peine d'ajouter des règles à la configuration de l'hôte virtuel qui interdisent d'exécuter des scripts php autres que index.php dans les sections racine et admin du site.
- Ne jetez pas de déchets de votre compte. Si vous avez un magasin, que ce soit un magasin. Ne chargez pas sous un seul compte un tas de blogs wp, un seau de bugs et divers domaines de test.
- Ne stockez jamais de sauvegardes d'un site ou d'une base de données à la racine de votre hôte virtuel.
- Regardez la charge sur le serveur / l'hébergement, essayez de garder l'approvisionnement au moins x2 contre les pics de charge, et si soudainement la charge augmente soudainement sans raison, essayez de trouver la raison. Mieux vaut dépasser que de ne pas dépasser!