Analyse von durchgesickerten Passwörtern Gmail, Yandex und Mail.Ru

    In jüngerer Zeit wurden die Passwortdatenbanken beliebter E-Mail-Dienste öffentlich zugänglich gemacht [ 1 , 2 , 3 ]. Heute werden wir sie analysieren und eine Reihe von Fragen zur Qualität von Passwörtern und der möglichen Quelle (n) beantworten. Wir werden auch die Qualitätsmetriken einzelner Passwörter und der gesamten Stichprobe diskutieren.

    Nicht weniger interessant sind einige Anomalien und Muster von Passwortdatenbanken. Vielleicht können sie Aufschluss darüber geben, was als Datenquelle dienen könnte und wie gefährlich dieses Beispiel aus Sicht eines normalen Benutzers ist.

    Formal werden wir die folgenden Fragen berücksichtigen: Wie zuverlässig sind die Passwörter in der Datenbank und könnten sie durch einen Wörterbuchangriff gesammelt werden? Gibt es Anzeichen für Phishing-Angriffe? Könnte ein Datenleck die einzige Datenquelle sein? Könnte diese Datenbank über einen langen Zeitraum akkumuliert werden oder sind die Daten ausschließlich "frisch"?

    Artikelstruktur:

    1. Datenbeschreibung
    2. Ungültige Passwörter und Nicht-Passwörter
    3. Kennwortlängenverteilung
    4. Verteilung der Passwortstärke
    5. Wörterbuchangriff
    6. Top Passwörter
    7. Google Mail-Abruf
    8. Rambler Fetch
    9. Open Source Analyse
    10. Fazit


    Datenbeschreibung


    Daten aus allen drei Datenbanken sind eine Reihe von Adress-Passwort-Paaren, die durch einen Doppelpunkt getrennt sind. Es sind keine weiteren "Metadaten" verfügbar. Die Daten sind jedoch ziemlich verrauscht, d.h. Sie enthalten Zeichenfolgen, die weder E-Mail-Adressen noch gültige Kennwörter sind.



    Wenn wir die Merkmale der Daten untersuchen, können wir die Hypothese über den Prozess, mit dem Passwörter erhalten werden könnten, aufstellen (oder widerlegen).

    Ungültige Passwörter und Nicht-Passwörter


    Das einfachste Kriterium für die Ungültigkeit des Kennworts ist die Nichtübereinstimmung der Kennwortlänge mit den Anforderungen der E-Mail-Dienste.



    Die erhaltenen Daten besagen, dass die Passwörter aus dem Beispiel aufgrund eines „internen“ Lecks nicht erhalten werden konnten, da mehrere tausend Passwörter im Prinzip keine gültigen Passwörter sind, da die Passwortlänge auf sechs Zeichen beschränkt ist (und für moderne Google Mail-Passwörter acht Zeichen). .

    Betrachten Sie diese ungewöhnlich langen (über 60) und kurzen Passwörter (weniger als 6) im Detail.

    Beispiele

    Lange Passwörter sind HTML-Teile, ein repräsentatives Beispiel:



    Ähnliche Beispiele weisen darauf hin, dass Phishing eine der Quellen für Passwörter sein könnte. Der Eintrag in der Datenbank wurde eindeutig nicht von einer Person verifiziert und automatisch abgerufen. Phishing wird auch dadurch angezeigt, dass das Passwort HTML-Markup enthält, was für Passwortdiebstahl durch Infektion eher ungewöhnlich ist.

    Kurze Auswahl zu kurzer Passwörter:



    Ein weiterer Indikator dafür, dass Phishing eine der Ursachen sein könnte, ist das Fehlen eines Benutzernamens und eines Passworts in den Einträgen. Besonders interessant ist ein Apostroph ohne Passwort. Vielleicht hat das potenzielle Opfer das Phishing-Formular erraten und versucht, nach SQL-Injection zu suchen.

    Was kann durch verifizierte Daten eindeutig bestätigt werden? Eine automatische Datenbanküberprüfung wurde nicht durchgeführt. Höchstwahrscheinlich Hypothesen: Phishing und Virusinfektion.

    Um die Qualität der gesamten Stichprobe zu bewerten, entfernen wir offensichtlich falsche Passwörter mit einer Länge von weniger als 6 und mehr als 60 und betrachten die gesamte Verteilung als Ganzes für mehrere Parameter.

    Kennwortlängenverteilung


    Wie Sie der folgenden Grafik entnehmen können, sind die meisten Kennwörter maximal 8 Zeichen lang. Dies kann darauf hinweisen, dass eine signifikante Schicht von Passwörtern für verschiedene Arten von Brute-Force-Angriffen möglicherweise instabil ist.



    Verteilung der Passwortstärke


    Um diese Hypothese zu testen, betrachten Sie eine einfache Kennzahl für die Kennwortstärke , die auf
    dem PCI-Standard basiert .
    Lassen Sie das Passwort eine bedingte Punktzahl erhalten, um eine der folgenden Bedingungen zu erfüllen:
    • Das Passwort enthält mindestens 7 Zeichen.
    • Passwort enthält mindestens einen Kleinbuchstaben;
    • Das Passwort enthält mindestens einen Großbuchstaben.
    • Das Passwort enthält mindestens eine Ziffer.
    • Das Passwort enthält mindestens ein Sonderzeichen.

    Wenn das Passwort 4/5 erhält, nennen wir es stark (sehr zuverlässig für 5/5), wir nennen 3/5 mittel und 2/5 schwach (0 oder 1 Punkt nennen wir sehr schwach). Der R-Code ist unten angegeben.

    Zuverlässigkeitsfunktion
    library("Hmisc")
    strength <- function(password){
      # must contain at least 7 characters
      score = 0
      if (nchar(password) >= 7){
        inc(score) <- 1
      }
      # at least one digit
      if(grepl("[[:digit:]]", password)){
        inc(score) <- 1
      }
      # at least one lowercase letter 
      if(grepl("[[:lower:]]", password)){
        inc(score) <- 1
      }
      # at least one uppercase letter 
      if(grepl("[[:upper:]]", password)){
        inc(score) <- 1
      }
      # at least one special symbol
      if(grepl("[#!?^@*+&%]", password)){
        inc(score) <- 1
      }
      # 0-1 very weak
      # 2 - weak
      # 3 - medium
      # 4 - strong
      # 5 - very strong
      return(score)
    }
    


    Dann ist die Verteilung der Zuverlässigkeit:



    Wie Sie aus der Grafik sehen können, fallen die meisten Passwörter in die Kategorie der nicht zuverlässigen. Betrachten Sie als Beispiel Kennwörter mit null Sicherheit, da dies höchstwahrscheinlich ein weiteres repräsentatives Beispiel für ungültige Kennwörter ist.

    Passwörter ohne Stärke



    Wie aus den obigen Beispielen hervorgeht, sind diese Kennwörter nicht gültig (und aus Sicht einer Person sehen sie eher wie ein Eingabefehler als wie ein gültiges Kennwort aus), da Sie bei Mail-Diensten keine Mailbox registrieren können, wenn sie das Kennwort für zu einfach halten, indem Sie beispielsweise dasselbe Zeichen wiederholen sechsmal. Dies bedeutet, dass möglicherweise eine noch größere Schicht von Passwörtern gemäß den modernen Anforderungen nicht gültig ist.

    Ist es möglich, dass ein wesentlicher Teil der Datenbank über einen langen Zeitraum hinweg gesammelt wurde, als die Kennwortanforderungen geringer waren? Ansonsten ist es ziemlich schwierig, eine so große Gruppe von Passwörtern zu erklären, die nicht den Anforderungen moderner Mailsysteme entsprechen.

    Wörterbuchangriff


    Als zusätzliches Argument führen wir das folgende Experiment durch: Nehmen Sie eine Auswahl relevanter gemeinsamer Wörterbücher mit Kennwörtern vor, führen Sie mithilfe dieser Wörterbücher einen Angriff auf verfügbare Kennwörter durch und schätzen Sie den Prozentsatz der in dieser Auswahl an Wörterbüchern enthaltenen Kennwörter (der Autor ging buchstäblich nicht weiter als die ersten drei Google-Links für [Kennwortwörterbuch ]).



    Aus der obigen Tabelle ist ersichtlich, dass ein erheblicher Anteil der Kennwörter in Wörterbüchern enthalten ist, was auch darauf hinweist, dass ein Teil der Kennwörter als Ergebnis eines Wörterbuchangriffs (oder einer Art von Aufzählungsänderung) erhalten werden könnte.

    Top Passwörter


    Wir geben eine Auswahl der beliebtesten Passwörter und stellen fest, dass die meisten von ihnen derzeit keine gültigen Passwörter sind.



    Google Mail-Abruf


    Die in diesem und dem nächsten Teil beschriebenen und empfangenen Aktionen und Daten wurden von einem Freund meines Freundes ausgeführt und übertragen, der anonym bleiben wollte.

    Aufgabe: Überprüfen Sie die Gültigkeit (d. H. Dass das Passwort wirklich übereinstimmt). Aktion: Versuchen Sie in einer kleinen Stichprobe von ~ 150-200, auf die Boxen zuzugreifen. Von der gesamten Stichprobe sind im Prinzip ~ 2-3% gültig (nach mehreren Stunden öffentlich zugänglicher Daten), und tatsächlich sind alle zum Zeitpunkt der Überprüfung deaktiviert. Weniger als 1% der Kartons waren tatsächlich gültig und wurden von den Eigentümern für mindestens ein Jahr aufgegeben.

    Rambler Fetch


    Es ist leicht, in den Netzwerklisten "wirklich gültige" Adressen zu finden, die von einer Vielzahl von Stakeholdern (auch bekannt als Kulkhacker) zusammengestellt wurden.



    Interessanterweise gibt es einen ziemlich großen Prozentsatz von Rambler-Adressen unter ihnen.

    Rambler wurde einige Tage vor der Veröffentlichung gewarnt und es wurde eine Antwort erhalten, dass die notwendigen Sicherheitsmaßnahmen in naher Zukunft ergriffen werden würden.

    <humor> Interessanterweise ist der Prozentsatz gültiger Passwörter erheblich höher, und bis vor kurzem befand sich Rambler außerhalb des Medienbereichs und aktivierte keine zusätzlichen Sicherheitssysteme. Dies ermöglichte es einem unbekannten Leckanthropologen, die letzten Momente des Lebens von Postfächern zu bewerten. Trotz der Gültigkeit von Passwörtern wurden alle Postfächer für eine lange Zeit (~ 1-1,5 Jahre) verlassen und endeten mit einem der folgenden Buchstaben:







    Dies ist eine weitere Bestätigung der Phishing-Hypothese und der kumulativen Natur der Basis.

    Open Source Analyse


    Kehren wir zur Betrachtung von Open Source zurück. Eine aktive Suche nach Login-Passwörtern führte uns zu einer Reihe von Distributionen aus Spielforen:



    Es stellt sich heraus, dass ein Teil der Liste bereits in irgendeiner Form im Netzwerk gelaufen ist.

    Die Daten ermöglichen es uns daher, die Hypothese einer einzelnen Datenquelle wie eines „internen Lecks“ abzulehnen.

    Der Hauptteil des verwendeten Codes:
    Datenanalyse und Visualisierung
    source("multiplot.R")
    source("password_strength.R")
    library("ggplot2")
    print("loading yandex data")
    yandex <- read.csv("yandex.txt", header = FALSE, sep = ":", quote = "", stringsAsFactors = FALSE)
    print("loading mailru data")
    mailru <- read.csv("mail.txt",   header = FALSE, sep = ":", quote = "", stringsAsFactors = FALSE)
    print("loading gmail data")
    gmail  <- read.csv("gmail.txt",  header = FALSE, sep = ":", quote = "", stringsAsFactors = FALSE)
    ##testing if data loaded correctly
    print("testing, if loaded correctly")
    print(head(yandex))
    print(head(mailru))
    print(head(gmail))
    ##changing names
    names(yandex) <- c("email", "password")
    names(mailru) <- c("email", "password")
    names(gmail)  <- c("email", "password")
    print("computing lengths of passwords and adding to the datasets")
    yandex$pass_length   <- sapply(yandex$password, nchar)
    mailru$pass_length   <- sapply(mailru$password, nchar)
    gmail$pass_length    <- sapply(gmail$password,  nchar)
    print("number of invalid passwords by length")
    print(nrow(yandex[yandex$pass_length <  6,]))
    print(nrow(yandex[yandex$pass_length >  60,]))
    print(nrow(mailru[mailru$pass_length <  6,]))
    print(nrow(mailru[mailru$pass_length >  60,]))
    print(nrow(gmail[gmail$pass_length <  6,]))
    print(nrow(gmail[gmail$pass_length >  60,]))
    print("removing invalid passwords by length")
    yandex <- subset(yandex, pass_length >= 6 & pass_length <= 60)
    mailru <- subset(mailru, pass_length >= 6 & pass_length <= 60)
    gmail  <- subset(gmail , pass_length >= 6 & pass_length <= 60)
    #print("checking that they are removed")
    print(nrow(yandex[yandex$pass_length <  6,]))
    print(nrow(yandex[yandex$pass_length >  60,]))
    print(nrow(mailru[mailru$pass_length <  6,]))
    print(nrow(mailru[mailru$pass_length >  60,]))
    print(nrow(gmail[gmail$pass_length <  6,]))
    print(nrow(gmail[gmail$pass_length >  60,]))
    print("visualizing distribution of password lenghts by provider")
    gmailcolor  <- "deepskyblue"
    yandexcolor <- "orangered1"
    mailrucolor <- "limegreen"
     pgmail <- ggplot(data=gmail, aes(x=pass_length)) + scale_x_discrete(limits=seq(6, 20, 1), breaks=seq(6, 20, 1), drop=TRUE) + geom_histogram(colour="black", fill=gmailcolor, aes(y=..density..)) + coord_cartesian(xlim=c(5,21.5)) + xlab(expression("Длина пароля"))+ ylab(expression("Доля"))+ggtitle("Gmail")
     pyandex <- ggplot(data=yandex, aes(x=pass_length)) + scale_x_discrete(limits=seq(6, 21, 1), breaks=seq(6, 21, 1), drop=TRUE) + geom_histogram(colour="black", fill=yandexcolor, aes(y=..density..)) + coord_cartesian(xlim=c(5,21.5)) + xlab(expression("Длина пароля"))+ ylab(expression("Доля"))+ggtitle("Yandex")     
     pmailru <- ggplot(data=mailru, aes(x=pass_length)) + scale_x_discrete(limits=seq(6, 20, 1), breaks=seq(6, 20, 1), drop=TRUE) + geom_histogram(colour="black", fill=mailrucolor, aes(y=..density..)) + coord_cartesian(xlim=c(5,20.5)) + xlab(expression("Длина пароля"))+ ylab(expression("Доля"))+ggtitle("Mail.ru")     
     multiplot(pgmail, pyandex, pmailru, cols=3)
    print("computing strength of the passwords")
    yandex$strength <- sapply(yandex$password, strength)
    mailru$strength <- sapply(mailru$password, strength)
    gmail$strength  <- sapply(gmail$password,  strength)
     print(head(yandex))
     print(head(mailru))
     print(head(gmail))
    scale <- scale_x_discrete(limits=c(1,2,3,4,5), breaks=c(1,2,3,4,5), drop=TRUE, labels=c("Очень\nслабый", "Слабый", "Средний", "Надежный", "Очень\nнадежный"))
    pgmail <- ggplot(data=gmail  , aes(factor(strength))) + geom_bar(colour="black", fill=gmailcolor) + xlab(expression("Надежность"))+ coord + ylab(expression("Доля"))+ggtitle("Gmail") + scale
    pyandex <- ggplot(data=yandex, aes(factor(strength))) + geom_bar(colour="black", fill=yandexcolor, binwidth=0.5) + xlab(expression("Надежность"))+ coord + ylab(expression("Доля"))+ggtitle("Yandex") + scale
    pmailru <- ggplot(data=mailru, aes(factor(strength))) + geom_bar(colour="black", fill=mailrucolor, binwidth=0.5) + xlab(expression("Надежность"))+ coord + ylab(expression("Доля"))+ggtitle("Mail.ru") + scale    
    multiplot(pgmail, pyandex, pmailru, cols=3)
     print("Zero strength passwords")
     print("GMAIL")
     print(head(gmail[gmail$strength == 0,]))
     print("YANDEX")
     print(head(yandex[yandex$strength == 0,]))
     print("MAILRU")
     print(head(mailru[mailru$strength == 0,]))
    table_gmail  <- sort(table(gmail$password) , TRUE)
    table_yandex <- sort(table(yandex$password), TRUE)
    table_mailru <- sort(table(mailru$password), TRUE)
    print("gmail most frequent")
    print(head(table_gmail, 100))
    print("yandex most frequent")
    print(head(table_yandex,100))
    print("mailru most frequent")
    print(head(table_mailru,100))
    only_pass_gmail  <- gmail[ ,2] 
    write.csv(only_pass_gmail,  "only_pass_gmail",  row.names = FALSE)
    only_pass_yandex <- yandex[,2] 
    write.csv(only_pass_yandex, "only_pass_yandex", row.names = FALSE)
    only_pass_mailru <- mailru[,2] 
    write.csv(only_pass_mailru, "only_pass_mailru", row.names = FALSE)
    



    Vocabulary Attack Experiment Code
    #!/bin/bash
    data=sample_mailru
    dict=saved_dict_mailru
    > $dict
    j=0
    while read p; do
      ((j++))
      echo -n $j
      if grep -q "^$p$" dictionary/*; then
        echo " in "
        echo $p >> $dict
      else
        echo " out " 
      fi
      if (("$j" > 10000)); then
        break
      fi
    done <$data
    



    Fazit


    Daher scheint die Hypothese, dass es sich bei dieser Stichprobe um eine Zusammenstellung verschiedener Quellen (Phishing, Infektion, Wörterbuchangriffe, Sammlung beliebter Sammlungen) über einen langen Zeitraum handelt, am wahrscheinlichsten. Ein ausreichender Teil der Daten sind im Prinzip keine gültigen Passwörter nach formalen syntaktischen Kriterien, was auch durch experimentelle Überprüfung bestätigt wurde.

    Aus Sicht des Benutzers stellt dieses Ereignis keine signifikante Gefahr dar und sieht eher wie ein Versuch aus, einen Informationsleitfaden zu erstellen.

    UPD Ein weiterer Beweis dafür, dass die zusammengeführten Daten eine Zusammenstellung verschiedener Quellen sind, ist das Vorhandensein einer Sammlung von Google Mail-Konten mit "+" - Funktionen in der Datenbank, wenn die Adresse auf gmail.com wie Name + Domain \ Word aussieht (danke an geka für die Erinnerung an diese Funktion ).
    Топ-10 доменов из выборки (весь список тут)
    176 xtube
    132 daz
    88 filedropper
    66 daz3d
    64 eharmony
    63 friendster
    62 savage
    57 spam
    54 bioware
    52 savage2

    11 paygr
    11 comicbookdb

    Про paygr: пользователь gkond писал, что
    Нашел свой е-мейл в дампе. Пароль, которой рядом с ним указан автоматически сгенерировал мне сервис paygr.com, в далеком мае 2011 года.

    Gleichzeitig kommt "paygr" in der Google Mail-Liste "+" elf Mal vor. Vielleicht wurde auch ihre Basis kompromittiert.

    Das Wichtigste ist jedoch, dass comicbookdb erkannt hat, dass ihre Datenbank tatsächlich zusammen mit Passwörtern gestohlen wurde (danke an EnterSandman für den Link ): www.comicbookdb.com/hacked.php

    Jetzt auch beliebt: