Ich las Die Geschichte eines verdächtigen Angriffs aus aller Welt, sobald ich ein Blog auf meinem eigenen Server geöffnet hatte und überprüfte das Protokoll meines Servers. Es wurde bestätigt, dass der Zugang, der der gleiche Cracking-Zweck zu sein scheint, kommen würde.
Unter ihnen gab es viele Angriffe, auf die ich mich verlassen habe, ohne den Benutzernamen und das Passwort von phpMyAdmin zu erraten. Deshalb habe ich die Anzahl der Angriffe auf sie gezählt und sie eingestuft.
Ich habe das Protokoll (/ var / log / httpd / access_log) des Apache HTTP-Servers des Servers (CentOS 6.10) mit Sakura VPS beauftragt. Wenn Sie sich den Inhalt ansehen, können Sie sehen, dass der Zugriff mit einem Benutzernamen und einem Kennwort versucht wird, die nicht für phpMyAdmin gelten, wie unten gezeigt.
xxx.xxx.xxx.xxx - - [04/Oct/2018:02:57:44 +0900] "GET /phpMyAdmin/index.php?pma_username=root&pma_password=1qaz3edc5tgb&server=1 HTTP/1.1" 200 14538 "-" "Mozilla/5.0"
xxx.xxx.xxx.xxx - - [04/Oct/2018:02:57:46 +0900] "GET /phpMyAdmin/index.php?pma_username=root&pma_password=1qaz@123&server=1 HTTP/1.1" 200 14546 "-" "Mozilla/5.0"
xxx.xxx.xxx.xxx - - [04/Oct/2018:02:57:59 +0900] "GET /phpMyAdmin/index.php?pma_username=root&pma_password=1qaz@2wsx&server=1 HTTP/1.1" 200 14533 "-" "Mozilla/5.0"
xxx.xxx.xxx.xxx - - [04/Oct/2018:02:58:03 +0900] "GET /phpMyAdmin/index.php?pma_username=root&pma_password=1qaz@WSX&server=1 HTTP/1.1" 200 14543 "-" "Mozilla/5.0"
xxx.xxx.xxx.xxx - - [04/Oct/2018:02:58:06 +0900] "GET /phpMyAdmin/index.php?pma_username=root&pma_password=1qaz@WSX3edc&server=1 HTTP/1.1" 200 14538 "-" "Mozilla/5.0"
xxx.xxx.xxx.xxx - - [04/Oct/2018:02:58:09 +0900] "GET /phpMyAdmin/index.php?pma_username=root&pma_password=1qaz@wsx&server=1 HTTP/1.1" 200 14533 "-" "Mozilla/5.0"
Ich habe diese Informationen mit Python extrahiert und Histogramminformationen erstellt. Der Python-Code wird am Ende als Anhang aufgeführt.
Erwerbszeitraum: 2018/09/26 ~ 2020/01/22 Gesamtzahl der Zeilen: 658858 Zeilen Von diesen scheint der Angriff auf dem Passwort von phpMyAdmin zu beruhen, ohne zu raten: 186499 Zeile
Rangfolge | Nutzername | Anzahl |
---|---|---|
1 | root | 185504 |
2 | wordpress | 183 |
3 | admin | 138 |
4 | wp | 47 |
5 | blog | 45 |
6 | pma | 45 |
7 | shop | 43 |
8 | money | 42 |
9 | popa3d | 40 |
10 | joomla | 39 |
11 | http | 35 |
12 | ueer | 35 |
13 | project | 35 |
14 | nginx | 33 |
15 | apache | 33 |
16 | sql | 33 |
17 | db | 32 |
18 | nas | 32 |
19 | shopdb | 31 |
20 | dbs | 31 |
21 | web | 28 |
22 | backupdb | 6 |
23 | wordspress | 5 |
24 | backup | 2 |
25 | backups | 2 |
Rangfolge | Passwort | Anzahl |
---|---|---|
1 | pass | 408 |
2 | password | 372 |
3 | 361 | |
4 | admin | 359 |
5 | 123 | 347 |
6 | root | 344 |
7 | 123456 | 326 |
8 | welcome | 323 |
9 | r00t | 322 |
10 | monkey | 322 |
11 | whatever | 322 |
12 | abc123 | 321 |
13 | aa123456 | 321 |
14 | 123123 | 319 |
15 | mysql | 318 |
16 | login | 318 |
17 | 111111 | 318 |
18 | password123 | 318 |
19 | 1234567890 | 317 |
20 | access | 317 |
21 | 666666 | 316 |
22 | apache | 315 |
23 | oracle | 315 |
24 | 654321 | 315 |
25 | root123 | 315 |
26 | 123qwe | 314 |
27 | 1234567 | 314 |
28 | 12345678 | 314 |
29 | pass123 | 314 |
30 | letmein | 313 |
Rangfolge | Pfad | Anzahl |
---|---|---|
1 | /phpmyadmin/index.php | 173687 |
2 | /phpMyAdmin/index.php | 12812 |
Alle Rankings werden unter [hier] platziert (https://docs.google.com/spreadsheets/d/1sDfD5qh4LiRLQnmg5UUX8-Q93x408PQKW0RMZQu4-E/edit?usp=sharing).
Die überwiegende Mehrheit der Benutzernamen sind root-Begriffe, und andere blogbezogene Begriffe wie WordPress und Blog, datenbankbezogene Begriffe wie admin und pma sowie serverbezogene Begriffe wie apache scheinen in einer Reihe zu stehen. Im Vergleich zu Artikel zur Analyse des Angriffsprotokolls auf dem SSH-Server zielt der Angriff auf SSH auf den Namen und den Betriebssystemnamen der Person ab, während phpMyAdmin Es ist interessant, dass es subtile Unterschiede in den Trends gibt, z. B. blogbezogene Begriffe, auf die bei Angriffen abgezielt wird.
Die drei wichtigsten Passwörter waren "pass", "password" und "" (keine). Es gab nicht viele Prominente, und es schien, dass die Dinge, auf die man zielte, gleichmäßig ausgerichtet waren. Es scheint der Tendenz des "schlechtesten Passworts" zu entsprechen, wie in [hier] angegeben (https://10mtv.jp/pc/column/article.php?column_article_id=2294). Die Muster waren wie folgt.
Zusätzlich wurden die Pfade, die die Ziele des Angriffs waren, tabellarisch aufgeführt. Nur die folgenden zwei Typen wurden angegriffen.
Zielzugriffsliste, um unbefugten Zugriff zu verhindern Oder Informationen zu URLs, auf die leicht zugegriffen werden kann Der Grund, warum es im Vergleich zu dem im Artikel erwähnten Pfad nur wenige Abweichungen gibt, liegt wahrscheinlich darin, dass diesmal das Ergebnis nach dem Extrahieren der Zeile unter der Bedingung ist, dass "pma_password =" enthalten ist. Als ich mir das Protokoll mit der Extraktionsbedingung "enthält" phpMyAdmin "" ansah, stellte ich fest, dass auch versucht wurde, auf andere Pfade als die beiden diesmal aufgeführten Typen zuzugreifen.
Ich habe wenig Kenntnisse über Sicherheit, daher weiß ich nicht, wie ich sie sichern soll, aber zumindest habe ich beschlossen, den Benutzernamen und das Kennwort, die häufig in Datenbanken im Standardpfad enthalten sind, nicht mehr zu verwenden.
Das ist alles für den Text. Danke fürs Lesen. Das Folgende ist ein Anhang.
Python-Code zum Extrahieren der erforderlichen Informationen aus dem Protokoll. Diesmal wurden die folgenden Zeilen analysiert.
xxx.xxx.xxx.xxx - - [04/Oct/2018:02:58:03 +0900] "GET /phpMyAdmin/index.php?pma_username=root&pma_password=1qaz@WSX&server=1 HTTP/1.1" 200 14543 "-" "Mozilla/5.0"
Wenn "pma_password =" enthalten ist, wird dies als analysiert betrachtet. Informationen werden hier extrahiert, indem sie durch Leerzeichen, bestimmte Zeichen oder Schlüsselwörter geteilt werden. Hier finden Sie ein Beispiel für Informationen und deren Abruf. Dies kann je nach den Exporteinstellungen der Protokolldatei usw. unterschiedlich sein. Korrigieren Sie sie daher entsprechend.
Information | Wie man herausnimmt |
---|---|
IP Adresse | 0. geteilt durch Leerzeichen |
Zeitstempel | "["Wann"]"Zeichenkette eingeschlossen in |
Method (GET,POST etc.) | 6. durch Raum geteilt. Da das erste Zeichen jedoch ein doppeltes Anführungszeichen ist, löschen Sie es |
phpMyAdmin Pfad | Ab dem 7. Element durch Raum geteilt"?"Bis kurz zuvor |
Nutzername | "pma_username="Wann"&"Zeichenfolge zwischen |
Passwort | "pma_password="Wann"&"の間の文字列。(ただしこの部分のqueryでurlが終了している場合があり、そのWannきは後ろの"&"が存在しないため、スペースの直前までWannする) |
Nicht alle Zeilen können auf diese Weise extrahiert werden, aber ich ignoriere sie, da ich denke, dass einige Ausnahmen nur geringe Auswirkungen haben werden. Dieser Bereich ist angemessen. Zählen Sie nach dem Abrufen des Elements, wie oft Informationen von Interesse sind (diesmal phpMyAdmin-Pfad, Benutzername, Kennwort). Schließlich wird es in absteigender Reihenfolge sortiert und in der Standardausgabe angezeigt.
Der gesamte Quellcode sieht wie folgt aus.
from collections import defaultdict
with open('/path/to/access_log','r') as f:
logs = f.readlines()
#Extrahieren von Angriffen auf phpMyAdmin
pma_attacks = [log for log in logs if 'pma_password' in log]
#ip, time_stamp, method, path, username,Passwort extrahieren
#Schreiben Sie entsprechend dem Protokollformat neu
extracted_pma_infos = []
for pma in pma_attacks:
#Die IP-Adresse ist das durch Leerzeichen getrennte 0. Element
ip = pma.split(' ')[0]
#Der Zeitstempel ist"["Von"]"Zeichenkette bis
time_stamp = pma.split('[')[1].split(']')[0]
#Die Methode (POST, GET usw.) ist das sechste Element, das durch Leerzeichen getrennt ist, wobei das erste Zeichen entfernt wird.
method = pma.split(' ')[5][1:]
#Pfad ist das sechste Element, das durch Leerzeichen getrennt ist"?"Zeichenkette bis kurz zuvor
path = pma.split(' ')[6].split('?')[0]
#Der Benutzername ist"pma_username="Neueste"?"Zeichenkette bis
username = pma.split('pma_username=')[1].split('&')[0]
#Das Passwort ist"pma_password="Neueste"?"Zeichenkette bis
password = pma.split('pma_password=')[1].split('&')[0]
#Ausnahmebehandlung, wenn das Kennwort die letzte Abfrage ist
#Zu diesem Zeitpunkt spätestens"?"Existiert nicht und ist bis zum Ende des Protokolls enthalten, sodass dies unmittelbar vor dem Leerzeichen erfolgen kann
if ' ' in password:
password = password.split(' ')[0]
extracted_pma_infos.append([ip,time_stamp,method,path,username,password])
#Erstellen Sie ein Histogramm der angegriffenen Pfade, Benutzernamen und Kennwörter
pathlist = defaultdict(int)
unlist = defaultdict(int)
pslist = defaultdict(int)
for pma in extracted_pma_infos:
path = pma[3]
un = pma[4]
ps = pma[5]
pathlist[path]+=1
unlist[un]+=1
pslist[ps]+=1
#Argumenthistogrammdaten(dict_obj)Eine Funktion, die eine absteigende Liste analysiert und erstellt
def orderedlistFromDict(dict_obj):
count = list(set([dict_obj[v] for v in dict_obj]))
count.sort()
orderedlist = []
for c in count[::-1]:
for key in dict_obj:
if dict_obj[key] == c:
orderedlist.append((key,dict_obj[key]))
return orderedlist
#Liste der angegriffenen Pfade, Benutzernamen und Passwörter
ordered_path = orderedlistFromDict(drlist)
ordered_un = orderedlistFromDict(unlist)
ordered_ps = orderedlistFromDict(pslist)
#Pass-Ranking anzeigen
for val in ordered_path:
print(val[0],val[1],sep=',')
#Rangfolge der Benutzernamen anzeigen
for val in ordered_un:
print(val[0],val[1],sep=',')
#Kennwortrang anzeigen
for val in ordered_ps:
print(val[0],val[1],sep=',')
Recommended Posts