Wordfence, mon analyse des attaques « brute force »

Nouvel email ou plutôt SPAM n°121916 de Wordfence :

After our post on Friday discussing the increase in brute force attacks on WordPress in December, we received a lot of feedback. A few readers reached out to me personally with some additional data.
A source in Kiev, Ukraine contacted me and this morning we chatted via Skype about the political and military situation in Ukraine.
We published an update a few minutes ago that shows who is likely behind the attacks and what their motivation might be.

Maintenant il faut vérifier les faits, est-ce que je me fais attaquer par les Russes :

“Gabriele”, one of our readers, pointed out in the comments on our earlier post that the full IP block is 91.200.12.0/22. If you aren’t familiar with CIDR notation, that is an IP block that starts at 91.200.12.0 and ends at 91.200.15.255. It contains 1024 addresses (1022 usable addresses).

On va donc faire un petit grep :

grep "^91.200.1" access.log.* > 91_200_1.txt
wc -l 91_200_1.txt 
 302877 91_200_1.txt
cat 91_200_1.txt | sed 's/:/ /g' | awk '{print $2}' | sort -n | uniq -c | sort -n
 1 91.200.108.218
 1 91.200.113.142
 1 91.200.12.102
 1 91.200.12.45
 1 91.200.12.66
 1 91.200.14.182
 1 91.200.156.233
 2 91.200.110.171
 2 91.200.12.147
 2 91.200.12.20
 3 91.200.12.94
 5 91.200.12.12
 5 91.200.13.41
 6 91.200.12.69
 6 91.200.14.153
 7 91.200.12.76
 7 91.200.156.92
 8 91.200.12.75
 8 91.200.12.86
 11 91.200.12.47
 11 91.200.14.179
 12 91.200.14.88
 13 91.200.12.137
 13 91.200.13.5
 14 91.200.13.40
 15 91.200.12.1
 15 91.200.14.158
 16 91.200.12.8
 17 91.200.13.100
 18 91.200.12.26
 18 91.200.12.64
 19 91.200.12.148
 23 91.200.12.74
 25 91.200.12.70
 27 91.200.12.145
 27 91.200.13.43
 29 91.200.13.36
 29 91.200.14.157
 33 91.200.12.71
 34 91.200.12.25
 38 91.200.12.28
 39 91.200.14.62
 40 91.200.13.38
 41 91.200.14.89
 43 91.200.12.27
 49 91.200.12.63
 54 91.200.12.116
 54 91.200.12.19
 55 91.200.14.122
 59 91.200.12.128
 61 91.200.12.121
 64 91.200.12.130
 67 91.200.12.106
 70 91.200.12.143
 80 91.200.14.59
 82 91.200.12.141
 83 91.200.12.85
 87 91.200.12.136
 107 91.200.12.40
 120 91.200.12.58
 121 91.200.12.39
 133 91.200.12.139
 134 91.200.12.95
 144 91.200.12.7
 191 91.200.14.34
 207 91.200.12.50
 208 91.200.13.33
 256 91.200.12.49
 299 91.200.14.72
 306 91.200.12.97
 335 91.200.12.38
 587 91.200.12.91
 750 91.200.12.108
 750 91.200.12.24
 774 91.200.12.60
 868 91.200.12.84
 914 91.200.13.45
1017 91.200.12.5
1090 91.200.12.9
1226 91.200.12.51
1341 91.200.12.138
1506 91.200.12.93
1551 91.200.12.81
1635 91.200.12.56
1880 91.200.12.127
2015 91.200.12.14
2032 91.200.12.78
2149 91.200.12.113
2236 91.200.12.61
2276 91.200.13.64
2557 91.200.12.33
2802 91.200.12.92
2803 91.200.12.83
2850 91.200.12.155
4482 91.200.12.53
5175 91.200.12.22
5281 91.200.12.79
6341 91.200.12.134
6349 91.200.12.42
7572 91.200.12.18
7659 91.200.12.36
9031 91.200.12.55
12692 91.200.12.129
13800 91.200.12.29
30048 91.200.12.132
32258 91.200.12.4
46922 91.200.12.114
73544 91.200.12.65

En effet les Russes sont actifs sur le site, reste à voir si c’est sur la page wp-login.php.

grep wp-login.php 91_200_1.txt  | wc -l
  276624

En résumé on a eu 302877 connexions au site et 276624 de ses connexions (91%) se sont faites sur la page wp-login.php. Je crois en effet qu’il y a urgence à bannir ces IP (91.200.12.*)! Les autres connexions se font pour connaitre le login (Users Enumération) , par exemple :

91.200.12.113 - - [16/Dec/2016:14:54:27 +0100] "GET /?author=2 HTTP/1.1" 200 41393 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"

Les Russes font des attaques « Brut force » et les Américains des attaques par « SQL Injection ». Un travail d’équipe 🙂 .

Maintenant je regarde si ses attaques sont nouvelles :

cat 91_200_1.txt | awk '{print $4}' | sed 's/\// /g' | sed 's/:/ /g' | awk '{print $3}' | sort -n | uniq -c 
   1 2010
 547 2013
2927 2014
24339 2015
275063 2016

Mes logs commences en 2008, et les attaques ont commencé en 2013, et cela c’est bien intensifié depuis.

J’ai donc installé : All In One WP Security & Firewall , pour ne pas prendre la version payante de Wordfence.

Ajout des Russes dans la liste noire :

Avant de finir, je regarde les IP de connexions à wp-login afin de voir s’il n’y a que les Russes :

grep wp-login.php *.log.*  > wp-login.txt
wc -l wp-login.txt
6738752 wp-login.txt
cat wp-login.txt | sed 's/:/ /g' | awk '{print $2}' | sort -n | uniq -c | sort -n
...
73270 62.109.15.8 (Russian Federation)
73298 91.200.12.65 (Ukraine)
76085 211.125.90.135 (Japan)
76376 194.149.10.39 (Hungary)
78839 212.68.54.246 (TURKEY)
117155 178.33.61.27 (OVH ISP - France)
152925 188.165.202.149 (OVH SAS - France)
153445 174.136.35.43 (UNITED STATES)
153810 123.30.187.167 (VietNam)
155050 37.187.54.93 (OVH SAS - France)

Je pense que OVH SAS c’est WordPress.com, à  vérifier. On retrouve l’Ukraine en 9ème position … Je vous conseille donc vivement d’utiliser la liste noire suivante :

123.30.187.167
174.136.35.43
194.149.10.39
211.125.90.135
212.68.54.246
62.109.15.8
91.200.12.*
91.200.13.*
91.200.14.*
91.200.15.*
91.200.156.92

Et penser aussi à bloquer les énumérations avec All In One WP Security & Firewall:

Quand on voit le nombre d’attaque on comprends mieux pourquoi il faut faire confiance à Google Analytic pour l’analyse du trafic. Si on fait avec WebAnalyser on prend en compte une grande partie qui n’est rien d’autre que des attaques !

Wordfence, plugin de sécurité sous WordPress

Pour l’instant je suis en phase d’observation. Il est vrai que certains des conseils étaient bons, comme supprimer des fichiers de logs ou d’installation. Ensuite je trouve vraiment bien de tracer toutes les connexions à la page d’admin et d’envoyer un email à chaque connexion.

Maintenant il va falloir que j’analyse les attaques :

The Wordfence Web Application Firewall has blocked 253 attacks over the last 10 minutes. Below is a sample of these recent attacks:

décembre 14, 2016 7:22   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(vErsion(),0x27,0
décembre 14, 2016 7:22   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en99999″ union select unhex(hex(version())) — « x »= »x
décembre 14, 2016 7:22   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en99999′ union select unhex(hex(version())) — ‘x’=’x
décembre 14, 2016 7:22   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en » or (1,2)=(select*from(select name_const(CHAR(111,108,111,108,111,115,104,101,114),1),name_const(
décembre 14, 2016 7:22   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en’ or (1,2)=(select*from(select name_const(CHAR(111,108,111,108,111,115,104,101,114),1),name_const(
décembre 14, 2016 7:22   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en or (1,2)=(select*from(select name_const(CHAR(111,108,111,108,111,115,104,101,114),1),name_const(C
décembre 14, 2016 7:21   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en’ And SLeep(3) UniON SEleCT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21 #
décembre 14, 2016 7:21   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en1111111111111″ UNION SELECT CHAR(45,120,49,45,81,45),CHAR(45,120,50,45,81,45),CHAR(45,120,51,45,81
décembre 14, 2016 7:21   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en1111111111111″ UNION SELECT CHAR(45,120,49,45,81,45),CHAR(45,120,50,45,81,45),CHAR(45,120,51,45,81
décembre 14, 2016 7:21   185.5.53.22 (Lithuania)     Blocked for SQL Injection in query string: lang=en1111111111111″ UNION SELECT CHAR(45,120,49,45,81,45),CHAR(45,120,50,45,81,45),CHAR(45,120,51,45,81

Maintenant il va falloir que je regarde les logs d’Apache afin de voir si je retrouve ses attaques. Et voir aussi si ce ne sont pas des « pompiers pyromanes », c’est à dire que les attaques ne soient pas nouvelles.

A noter aussi la méthode d’attaque, on fait de l’injection à partir de la variable lang. Pas bon de mettre la variable lang en php, ou alors il faut faire un traitement simple afin de bien vérifier que la taille de la valeur n’est pas supérieure à 2.

Deux jours après l’avertissement de Wordfence, j’ai donc un nouvel avertissement (Le 16/12/2016).

[WordPress Security] Huge Increase in Brute Force Attacks in December – What to Do

During the past three weeks, we have been monitoring a steady increase in brute force attacks. The last few days have seen a rapid increase in the number of attackers.
 
This morning we have published the charts showing these changes and we identify some of the attackers. We also share data on which hosting provider networks are the largest sources of attacks.

Quand on analyse les paramètres du leur SPAM : utm_source=list&utm_campaign=121616&utm_medium=email . En gros ils ont fait 121616 emails … On se demande presque si le remède n’est pas aussi mauvais que la maladie 😉 . J’ai donc du travail pour vérifier toute ses affirmations. Je vais donc partir sur les requêtes contenant les mots « UNION SELECT » sans faire attention à la casse. J’ai 3134 fichiers de logs qui vont du 14/03/2008 à aujourd’hui.

Transposh , le plugin WordPress qui consomme toute la base de donnée !

La taille de la base de donnée est limité à 1000 Mo chez PHPNET.ORG, et je viens de voir que ce blog consomme près de 500 Mo. Après une analyse dans les tables de MySQL via la commande :

SELECT table_name AS « Tables », ROUND( (
(data_length + index_length) /1024 /1024 ) , 2) AS « Taille MB »
FROM information_schema.TABLES
WHERE table_schema = « NomDeLaBase »

Et je viens de m’apercevoir que ce sont les tables wp_translations_log et wp_translations qui occupent 50% de l’espace. Ces deux tables sont du plugin « Transposh Translation Filter » (Version 0.9.6 | Par Team Transposh) qui est désactivé … Encore un super plugin !

Je vais donc le supprimer, ce plugin n’a jamais réellement fonctionné !

La désinstallation n’a même pas supprimé les deux tables. Pour ne pas prendre de risque je les vide simplement :

  • DELETE FROM `wp_translations`;
    • 268972 lignes supprimées. (Traitement en 0.0085 sec)
  • DELETE FROM `wp_translations_log` ;
    • 520199 lignes supprimées. (Traitement en 0.0547 sec)

J’ai donc gagné 250 Mo … le module Transposh Translation Filter est à fuir !

Migration de PHP pour WordPress

La galère suite à la migration de PHP 5.2 à PHP 7.0, j’ai le site qui n’était plus accessible. Heureusement j’ai trouvé un plugin Debug (Version 1.7 | Par SoniNow Team ).

J’ai donc du faire le ménage et supprimer des plugins:

  • Polylang (Non compatible ou erreurs)
  • Ultimate TinyMCE (Non compatible ou erreurs)
  • XML Google Maps (Non compatible ou erreurs)
    • Non-static method xmlgooglemaps_dbfunctions::install() should not be called statically
  • MCE Table Buttons (Non compatible ou erreurs)
  • Simple Social Buttons (Non compatible ou erreurs)
    • Trying to get property of non-object in /wp-content/plugins/simple-social-buttons/simple-social-buttons.phpon line 409
    • Undefined variable: post in /wp-content/plugins/simple-social-buttons/simple-social-buttons.phpon line 409
  • TablePress (Non compatible ou erreurs)
  • Transposh Translation Filter  (Non compatible ou erreurs)
    • has_cap est appelé avec un argument qui est déprécié depuis la version 2.0.0 ! L’utilisation des niveaux d’utilisateur par les extensions et thèmes est désormais interdite. Utiliser les rôles et capacités à la place.
  • WordPress Database Backup  (Non compatible ou erreurs) – Heureusement PHPNET.ORG propose des sauvegardes.

Mais la bonne nouvelle c’est que ce plugin fonctionne maintenant :

  • Weather Station en version Version 3.0.5.

[live-weather-station-justgage device_id=’70:ee:50:02:df:e4′ module_id=’05:00:00:02:7e:f4′ measure_type=’rain_hour_aggregated’ design=’half-flat-thin’ color=’lgt-standard’ pointer=’external’ title=’module-type’ subtitle=’module’ unit=’unit’ size=’large’]

Il me reste encore des « Notice » (à cause de WP Super Cache ?):

  • get_currentuserinfo est déprécié depuis la version 4.5.0 ! Utilisez wp_get_current_user() à la place. in /wp-includes/functions.php on line 3783