Знакомство с языком программирования Perl

Тема в разделе "Софт и инструменты", создана пользователем CLAY, 17 апр 2017.

  1. CLAY

    CLAY Member

    Сообщения:
    419
    Симпатии:
    5
    Все слышали об инциденте с похищением базы со 130000 паролями пользователей социальной сети vkontakte.ru, которая сразу же попала в общий доступ? Все информационные агентства активно вставляли это грозное число в заголовки своих статей. Но нашлись люди, которые решили проверить, соответствует ли действительности такая оценка...

    На примере анализа файла с паролями читатель может ознакомиться с очень мощным и гибким языком программирования Perl и понять принцип его применения в жизни.

    130000 пользователей В контакте взломаны...

    Пароли 130000 пользователей Вконтакте появились в интернете...

    130000 паролей “ВКонтакте” оказались в свободном доступе...

    В интернете появилась база с логинами и паролями более 130 000 аккаунтов...

    Да, да — я снова о том происшествии. На этот раз хотелось бы проанализировать ситуацию не с точки зрения силы или слабости используемых паролей. Поговорим о цифрах. Журналисты, для привлечения внимания к своим средствам массовой информации частенько пытаются написать о чем-то сенсационном, даже если это не слишком соответствует действительности. Хотелось бы отметить, что называть это взломом — некорректно, так как данные были получены мошенническим путем, а не взломом.

    Итак, наиболее часто встречающаяся цифра в новостях об опубликовании конфиденциальных данных пользователей известной социальной сети это 130 000 (сто тридцать тысяч). Внушительно, не так ли? Но соответствует ли это действительности?

    Сырая база, которая и стала доступна всем представляет из себя простой текстовый файл:

    По непонятным причинам везде используется два перевода строки. Исправим это. Поможет нам скриптовый язык Perl. Напишем простой сценарий, который откроет файл и удалит строки, состоящие только из символа перевода строки:

    Открываем исходный файл file1.txt. Открываем файл file2.txt, в который будем сохранять результаты работы. Исходный файл передаем в массив @file_to_parse и для каждого элемента этого массива проверяем не состоит ли он только из символа перевода строки, который представляется как . Если не состоит, то записываем строку в файл с результатом. По окончании цикла закрываем оба файла и выводим на экран сообщение, чтобы было понятно, что работа скрипта завершена.

    После этого файл выглядит уже так:

    На скриншоте не слишком заметно, но все строки начинаются и заканчиваются пробелом. Чтобы убрать эти паразитные символы пробела используем другой скрипт:

    Начало такое же, как и в прошлый раз, только в качестве исходного файла указываем файл, с результатом работы предыдущего скрипта file2.txt.

    Тут используются простые регулярные выражения: s/^ // — модификатор s обозначает замену. Между первой и второй косыми чертами указывается что заменять — мы указываем символ ^ и пробел. Домик обозначает, что заменять нужно только пробел в начале строки. Между второй и третьей косыми чертами указываем на что заменять — нам нужно просто удалить пробелы, поэтому там ничего нет.

    s/ $// — модификатор s, как и в прошлом примере, обозначает замену. Между первой и второй косыми чертами указывается что заменять — мы указываем символ пробел и $. Доллар обозначает, что заменять нужно только пробел в конце строки.

    До изменений файл занимал 4 357 088 байт. После того, как мы убрали пробелы он несколько уменьшился и стал занимать 4 064 688 байт.

    В файле пары логинпароль разделены двоеточием, но если пользователь нажимал на фишерской странице Вход оставляя поля ввода пустыми, то, соответственно в файл добавлялось только двоеточие. Уберем строки, состоящие только из двоеточия:

    Практически идентично самому первому скрипту, но в проверке используется не просто перевод строки , а двоеточие и перевод строки — : .

    После этого файл смотрится уже совсем плотно:

    Кроме того, он уменьшился до 4 019 694 байт. На данном этапе в файле содержится 131 206 строк. Очевидно, это и было отправной точкой в статьях, заголовки которых содержали более 130 тысяч!.

    В почтовом адресе обязательно содержится символ @. Удалим строки, в которых такого символа нет:

    Как и в предыдущих регулярных выражениях мы используем символ =~, а между косыми чертами указываем нужный нам символ. Строку: if ( $line_to_parse =~ /@/ ) можно перевести на человеческий язык как-то так: если в строке $line_to_parse содержится символ @, то... и дальше в фигурных скобках указываем, что же собственно нужно делать: print OUTFILE ($line_to_parse); то есть записать в файл строку $line_to_parse.

    После этого в файле file5.txt оказалось 126 519 строк. Уже честнее. Такая цифра может использоваться в статьях с заголовками около 130 тысяч. Что ж, не будем останавливаться на достигнутом.

    Как известно, Вконтакте не позволяет использовать пароль, короче 6 символов. Поэтому долой строки, в которых после первого двоеточия меньше 6 символов. Вместе с этим отделим адреса от паролей:

    Итак, в массив @ar помещаются части строки $line_to_parse, разделенные двоеточием (заметьте, что в пароле может быть символ двоеточия, поэтому мы не гарантированно получим только два элемента — их может быть больше). Затем мы сдвигаем первый элемент массива в переменную $mail. После этого в массиве останутся один или несколько элементов. Эти элементы мы помещаем в переменную $pass. Так как $line_to_parse это строка, то заканчивается она символом перевода строки , который нам может помешать. Поэтому обрезаем его функцией chop. Дальше проверка: если длина переменной $pass больше или равна 6, то записываем в файл переменную $mail, так как это будет почтовый адрес, с корректным паролем. Так мы отсеяли еще около трех тысяч строк.

    Итак, мы получили 123 446 адресов. Но для адресов электронной почты тоже есть ряд ограничений. Так как для почтового адреса не имеет значения прописные буквы используются или строчные заменим все прописные буквы на строчные. А для отсева негодных адресов используем регулярное выражение:

    За замену больших букв на маленькие отвечает строка: $line_to_parse =~ tr/A-Z/a-z/;

    Рассмотрим по подробнее самое большое регулярное выражение:

    Данное регулярное выражение удобно рассмотреть, как состоящее из двух половинок - до @ и после @. Итак до собачки у нас могут быть буквы, цифры, точки, символы подчеркивания, знаки процента, плюсы и минусы. После собачки у нас один или несколько поддоменов, имя которых может содержать буквы, цифры и тире. А заканчиваться все должно суффиксом из двух, трех или четырех букв. Данное регулярное выражение не полное, но я пренебрегаю некоторой частью адресов, которые могли бы пройти проверку стандартом RFC822, но окажутся отсеянными этим.

    Все эти манипуляции позволили сократить базу до 122 796 строк.

    А теперь самое главное — сколько же в этих 122 796 адресах уникальных? Для ответа на это вопрос воспользуемся возможностями MySQL.

    Для подключения к базе при помощи Perl нам понадобится подключить пакет для работы с базами DBI. Затем идет подключение к базе и создание таблицы. Далее уже знакомое открытие файла. И, наконец, добавление строк в базу. При этом не забываем отрезать ненужный нам в данном случае символ переноса строки.

    Данные в базе и все, что нам нужно это выполнить запрос:

    SELECT DISTINCT mail FROM mail;

    На языке SQL это обозначает выбрать все различные данные из поля mail таблицы mail.

    В результате от сенсационных СТА ТРИДЦАТИ ТЫСЯЧ! остались скромные 40 712 записей. То есть реально злоумышленники смогли бы использовать в три раза меньше полезных данных. Зато, как эффектно выглядят заголовки...

Поделиться этой страницей