Храните свои персональные данные в сберегательной банке
реклама
Внимание! Поскольку на сайте не корректно работают спойлеры, а точнее они вообще не работают, в статье будут "портянки" текста. Как понимаете - претензии не ко мне. Я старался и потратил 6 часов, но победить кривой редактор я не смог. Заранее приношу извинения читателям.
Начнем с почты
Долго думал стоит ли публиковать статью. Тема на самом деле довольно чувствительная и много нюансов я разглашать не имею права. Разумеется начал я ей интересоваться не просто так. Дело в том, что появилась довольно интересная задача: в одной крупной не называемой организации возникла потребность проверять пароли придуманные пользователями на стойкость и «уникальность». Система не должна обращаться к внешним базам данных, а также не должна требовать какого-то супер сервера и больших баз данных. При этом, система должна признавать «плохими» не только пароли, которые есть в базе, но и похожие на них пароли.
Например, пользователь придумал себе пароль «12345». Всем известно, что это «плохой» пароль. Каждый может в этом убедиться проверив его по ссылке:
реклама
https://haveibeenpwned.com/Passwords
Но другого такого же «плохого» пароля «12345Mu», на момент проверки, в базе по ссылке не было. Таким образом, если мы хотим отсекать не только уже известные пароли, но и похожие на них, решение с базой данных не очень подходит.
реклама
Так вот, большую не называемую компанию беспокоили два важных для них момента:
1. Если заставлять людей придумывать или выдавать им очень сложные пароли — люди начинают их записывать. На бумажку, в смартфон, в записную книжку, и тому подобное. Это неприемлемо так как записанные пароли могут попасть за пределы компании.
реклама
2. Многие корпоративные политики сложности паролей порой обходятся вот таким простым способом, как описано выше — добавлением пары-тройки символов в начало или конец. Люди довольно быстро находят способы обхода политик. Начинаешь усложнять политики — получаешь пункт 1.
Многие «одмины» скажут, что надо бороться драконовскими методами: увольнять, лишать премии, закрывать доступ. Но так могут сказать только люди не умные, но самодовольные. В нормальных компаниях к сотрудникам должно быть нормальное человеческое отношение, тогда сотрудники будут платить вам тем же. Будете «закручивать гайки» в ответ получите тонны ненависти, и наплевательское отношение к работе. Но полностью списывать со счетов административные методы нельзя. Всегда нужно проводить разъяснительные лекции с персоналом, аргументированно объяснять почему стоит задумываться о безопасности, как своей, так и компании, в которой люди работают. Людей надо научить придумывать «хорошие» пароли, и они будут делать это с удовольствием. У нас конечно не коммунизм, и людям в целом наплевать как обстоят дела у дяди капиталиста. Но, увеличивая взаимную ненависть, на фоне общего снижения зарплат и падения рынка, мы ни к чему хорошему не придем. К людям всегда надо относиться по-человечески. Неважно коммунизм у нас или капитализм.
В результате оценки тех или иных решений возникла, казалось бы простая мысль: «а давайте обучим нейронку, пусть она дает нам ответ по качеству пароля». Обычно самые простые идеи имеют самую сложную реализацию. :) Но применение нейросети, несмотря на то, что имеет определенные сложности на стадии реализации, в дальнейшем окупается скоростью и низкими требованиями к железу. На этапе сбора данных и обучения решение с нейросетью потребует довольно не скромного железа, но для работы в принципе подойдет даже ноутбук. После обучения нейросети на GPU, мы сконвертируем её для работы на CPU.
Процесс создания системы, если описать его очень грубо, выглядит не замысловато:
1. Собираем данные для обучения нейросети;
2. Обрабатываем данные, чистим от мусора и приводим к нужному нам виду;
3. Переводим текст в тензорную форму. Определяемся с архитектурой нейросети, обучаем её на GPU.
4. Конвертируем нейросеть для работы на CPU;
5. Создаем несложный API или вообще локальный клиент для проверки качества пароля.
6. Профит! Нейросеть выдает нам на выходе вероятность насколько наш пароль плох, и уже на основании этой вероятности мы можем принимать решение.
Важно подчеркнуть — это решение, по моему мнению, не очень подходит для работы через обычный интернет, так как требует передачу пароля по сети в условно «открытом» виде. Разумеется это можно обойти применив симметричное шифрование. Да я знаю про HTTPS, но это и есть мое: «в открытом виде».
Сразу вынужден разочаровать. Работу с нейросетями описывать не буду — работа исследовательская и инновационная. Сосредоточусь на работе с данными. Могу только сказать, что система внедрена, показала свою высокую эффективность. Если отсекать пароли по вероятности 80%, то неподготовленный человек может и не суметь придумать «хороший» пароль. У меня как у создателя не получилось «обмануть систему». В этом прелесть нейросетей — мы ни фига не понимаем как оно работает. :)
Разумной, на основании слепого тестирования на 50 человеках, приняли вероятность 60-65%. Пока по набранным данным получается, что люди лучше запоминают пароли когда их сами придумывают, а с помощью такого ИИ «костыля» пароли получаются более безопасными. К взлому таких паролей подходить со словарями не стоит.
Как известно при обучении нейросетей чем больше данных наберешь, тем лучше. Конечно всегда есть быстрое, эффективное и не правильное решение — скачать любую доступную базу расшифрованных паролей. Таких крупных баз несколько. Но для понимания какие вообще есть данные в утечках данных, готовые расшифрованные пароли малополезны. Поэтому будем искать «сырцы». Заодно их и проанализируем.
Здесь должен сделать большое предупреждение:
Поскольку в этой работе использовалась масса чувствительных данных, то никаких «пруфов» не будет. Также не буду делиться ссылками «где скачать». Кому интересно — ищите и обрящете. Могу только предупредить, что если вам требуются данные для исследовательской работы, никакие базы покупать не надо. Всё необходимое для исследования есть в «открытом» доступе. Хотя если заказчик выделяет бюджет, то почему бы и нет. Все данные в той или иной мере способные кого-то скомпрометировать или повредить деловую репутацию будут скрыты. Поскольку «пруфов» не будет, прошу поверить на слово.
С предупреждениями разобрались, теперь надо разобраться с терминами. Я буду часто употреблять слово «база». Термин может немного меняться в зависимости от контекста. Но важно знать, что это не какая-то база данных типа Mysql или Oracle. «Сырцы» базы представляют собой кучу из разных данных:
* архивы — rar, zip, gzip, tar;
* различные SQL дампы;
* просто текстовые файлы в которых инфа храниться в виде <логин> <пароль/хэш пароля>;
* csv, xls, odt, ods, pdf и другие типы файлов.
Внутри структура каждого файла почти всегда индивидуальна.
В общем, как видно «база» - это обычная помойка куда набросано много всего разного. В моем случае, база скачанная с публичных источников, о которых не принято говорить вслух, занимала около 650Гб на диске, и содержала около 22000 (двадцать две тысячи) файлов.
Такой объем по началу меня не просто пугал, а приводил в ужас, поскольку после беглого взгляда на файлы я понял, что никакой стройной системы в них нет и все придется обрабатывать в полу-ручном режиме, файл за файлом. Такая обработка подразумевает примитивные навыки bash программирования, и владения на минимальном уровне каким ни будь языком программирования, подходящим для обработки текста. Это может быть Python, Perl, Php или любой другой которым вы более или менее владеете. Поскольку единого решения быть не может, предпочтение будем отдавать быстром наколеночным решениям — одним словом как умеем, так и делаем.
Кратко расскажу об алгоритме, который по моему мнению наиболее логичен, опробован на практике и позволяет затратить минимум времени на обработку. Для начала надо сделать копию базы и в дальнейшем работать только с копией, так как при ручной обработке всегда может случиться не поправимое — удалим или перепишем какие-то файлы. Если работаем с копией, то всегда сможем восстановить данные не скачивая базу заново. Далее надо бегло просмотреть базу на предмет типов файлов, архивов. На этом этапе можно удалять те файлы с которыми по тем или иным причинам работать невозможно. Например, это могут быть бинарные дампы, запароленные архивы, какие-то Mysql дампы из которых при всем желании не получить каких-то годных данных. Далее распаковываем все архивы, при этом надо все делать так, чтобы не переписывать файлы. Имена могут быть одинаковыми, а содержимое файлов разное.
Следующим этапом нужно найти и удалить все дубликаты файлов. Я делал это простым способом на bash:
ls | while read line; do cd $line; ls | while read mdsumm; do md5sum $mdsumm >> ../all-md5; done; cd ../; done
sort -k1 all-md5 | uniq -d -w 32 | awk '{print $2}' | while read line; do find . -name $line >> all-del-files.txt; done
cat all-del-files.txt | while read line; do rm $line; done
rm all-del-files.txt
rm all-md5
Этим скриптом я удалял в свое время дубли из своей коллекции музыки, которая формировалась еще со времен появления формата mp3, во многом стихийно. Одинаковых файлов в коллекции было много. Если «боитесь» что контрольная сумма md5 может дать коллизию, то можете заменить на sha256, например. У меня получилось сократить количество файлов примерно на 15-20%. Также важно отметить, что на этапе предварительной чистки постарайтесь сохранить оригинальную структуру базы.Далее, по желанию, надо отсортировать файлы по типу обработки. Например, SQL дампы складываем в один каталог. Файлы с записями вида логин:пароль (разделитель двоеточие) в другой каталог, логин<табуляция>пароль в третий, все что сходу не понятно как обрабатывать в четвертый.
Теперь можно просмотреть базу второй раз, и понять какая информация в ней есть, что нам конкретно понадобиться. Поскольку мой интерес кроме рабочего был еще и исследовательский, то меня интересовали следующие данные:
- логины;
- почтовые адреса;
- не хэшированные пароли;
- любая другая забавная и интересная инфа (в интернетах очень много «кричат» о персональных данных, очень хотелось посмотреть как там в реальности)
Начнем с почтовых адресов. Они содержат в себе много информации - почтовый адрес состоит из логина(имени) и имени домена. Попробуем составить рейтинги популярных логинов и популярных доменов. Таким образом мы сможем примерно понять, например, какая из почтовых служб популярна. Какие пользователи (или боты) наиболее активны в интернете.
Выковыривание почтовых адресов — это наверное самая простая задача из всех. Я предпочел Python. Этот простой скрипт выделяет в потоке данных на стандартном входе (вводе) почтовые адреса, и выводит их на стандартный вывод(выход):
#!/usr/bin/python #-*- coding: utf-8 -*- import os import re import sys import re import string for stringin in sys.stdin: text = stringin.strip() regex = re.compile(r'''([a-zA-Z0-9._%+-]+@([a-zA-Z0-9.-]+)(\.[a-zA-Z]{2,4}))''', re.VERBOSE) mo = regex.search(text) if mo is None: pass else: email = mo.group() print(email)
Корректно спрятать питоновый код под спойлер у меня не получилось. Поэтому прошу прощения, но дальше питоновые вставки под спойлер прятать не буду.
Если у кого-то есть вопрос, что такое стандартный вход и стандартный выход — search it: stdin and stdout.
Далее делаем простой «финт ушами» из корневого каталога нашей базы:
find . -type f | while read line; do cat "$line"; done | extract-emails-only.py > ../obrabotano/DB-emails-only-RAW-nonsorted.txt
Если по-русски, то находим все файлы в каталоге, выводим их на стандартный вывод, далее с помощью конвейера передаем данные нашему скрипту extract-emails-only.py, а он уже выведет все найденные адреса в файл DB-emails-only-RAW-nonsorted.txt. Если вы очень торопитесь, то можете сделать обработку в несколько потоков. У меня обработка в 4 потока уперлась в IO жесткого диска. Весь процесс занял часа 3-4. Время специально не засекал, так что говорю плюс-минус лапоть по ощущениям.
В итоге сырые данные содержали 2 990 413 376 «почтовых» адресов. На минуточку — это два миллиарда девятьсот девяносто миллионов четыреста тринадцать тысяч триста семьдесят шесть. Такое число даже вслух не удобно произносить. Размер файла составил 62Гб. Разумеется на таком объеме у нас обязательно будет какая-то доля мусора — это что-то типа того, что выглядит как почтовый адрес, но им на деле не является. Например, строка длиной 5000 символов, содержащая «@» и оканчивающаяся на «.com». Я конечно понимаю, что могут быть такие почтовые адреса, но в реальности их не будет много и на общую картину они не повлияют. Поэтому при дальнейших обработках, чтобы снизить количество мусора, будем брать строки длинной до 100 символов включительно. Пока попробуем посчитать «коэффициент уникальности» - для этого отсортируем наш файл с удалением всех дублей, а далее посчитаем насколько у нас стало меньше строк.
Сортируем с помощью вот такой не хитрой строки:
cat DB-emails-only-RAW-nonsorted.txt | LC_ALL=C sort -u --parallel=16 -T /dev/shm/ > DB-emails-only-sorted.txt
далее посчитаем количество строк:
wc -l DB-emails-only-sorted.txt
Количество строк составило 1 835 107 533. После подсчета видно, что оригинальный файл ужался на ~39%. Получается у нас повторяется 39 почтовых адресов из 100 - «коэффициент уникальности» равен 39%. Далее почистим немного от мусора, удалив все строчки длиной более 100 символов.
Для примера, строка ниже содержит 105 символов:
«ThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydog»
Поэтому думаю ограничение в 100 символов в почтовом адресе уберет мусор, но не «убьет» реальные почтовые адреса. Далее сделаем топ логинов и топ доменов. Топ почтовых адресов я тоже сделал, но по понятным причинам светить его не буду, так как там могут быть адреса реальных людей. Хотя я очень сомневаюсь, что хотя бы в топ 100 попали реальные почтовые адреса. Для самых хитрых скажу, что ТОП доменов не совпадает с ТОП логинов от слова совсем.
Сначала уберем из не сортированного файла все строки с длинной более 100 символов. Делать будем с помощью awk:
cat DB-emails-only-RAW-nonsorted.txt | awk '{if (length($0) <= 100) print $0}' > DB-emails-only-for-TOP.txt
Здесь, если по-русски, выводим файл на стандартный вывод, далее с помощью awk выводим все строчки длина которых меньше либо равна 100 в файл.
Далее с помощью awk выделим логины и домены. Логин — это то, что до символа «@», домен — после.
Выделяем логины:
awk -F "@" '{print $1}' DB-emails-only-for-TOP.txt > DB-emails-logins-only-for-TOP.txt
Выделяем домены:
awk -F "@" '{print $2}' DB-emails-only-for-TOP.txt > DB-emails-domains-only-for-TOP.txt
Если по-русски, то с помощью -F задаем разделитель полей, а далее выводим нужное поле в отдельный файл с помощью print $<номер поля>.
Теперь можно считать наши ТОПы. Процесс это длительный, поэтому лучше поставить на ночь. Если у вас в качестве процессора что-то вроде 3950Х, то можно и днем. Еще и в игрульку поиграете.
Формируем ТОП с помощью вот такой команды:
sort -S 20G DB-emails-logins-only-for-TOP.txt | uniq -c -d | sort -S 20G -r -k 1 -n > DB-emails-only-MOST-USE-sort.txt
По-русски: сначала просто сортируем файл, далее с помощью uniq считаем количество повторяющихся вхождений, далее еще раз сортируем по количеству вхождений. Для доменов аналогично, только имена файлов будут другие. Ключ -S задает значение буфера в памяти.
Вот что у меня получилось:
ТОП 50 логинов, <количество повторений> <логин>:
2396149 info
927453 gamebean
714501 -info
421592 admin
293879 mail
279140 webmaster
257705 contact
242023 mike
233400 123
233171 phongthancankhon
223874 sales
195668 john
190197 www
181149 david
179997 office
177978 123456
175416 chris
172039 myspace
170420 ian
169883 michael
153987 mark
147993 asd
132174 steve
127741 paul
126261 qq
123067 alex
120829 support
118419 me
116489 mail.ru
109470 crazyivan
109409 1
99665 peter
99021 tianzunol
98014 matt
94666 nick
94251 dave
93903 tom
90662 bob
89730 james
86351 rambler.ru
83844 -admin
82172 dan
82107 andrew
82015 a
79292 jason
79078 -mail
78379 jeff
78259 scott
77956 brian
77453 tim
Комментировать в этом топ'е особо нечего. Я бы сказал ожидаемо. Посмотрим что там в ТОП 50 доменов.
ТОП 50 доменов, <количество повторений> <домен>:
565200174 yahoo.com
427506170 gmail.com
372673569 hotmail.com
181303838 163.com
161054254 qq.com
134799665 mail.ru
92537859 aol.com
56990430 126.com
42634088 yandex.ru
31746875 hotmail.fr
27794351 game.sohu.com
26844242 rambler.ru
24836096 live.com
21356058 comcast.net
19633627 msn.com
18706015 sina.com
17887659 hotmail.co.uk
15793417 bk.ru
12935786 hotmail.it
12281161 yahoo.fr
12183068 inbox.ru
12025476 web.de
11534358 ymail.com
11528742 sbcglobal.net
10972018 list.ru
10494487 yahoo.co.uk
10368985 aim.com
10161516 sohu.com
9138014 yahoo.com.cn
8479263 gmx.de
8459018 rocketmail.com
8206512 live.fr
7013580 libero.it
7000918 yahoo.de
6864068 YAHOO.COM
6328695 att.net
5762894 hotmail.de
5650387 wp.pl
5295215 verizon.net
5265514 bellsouth.net
5043965 seznam.cz
4848416 hotmail.es
4815669 cox.net
4802871 yahoo.com.br
4777140 tianya.cn
4736202 myspace.com
4470978 outlook.com
4460304 googlemail.com
4154707 live.it
3956311 orange.fr
Здесь уже поинтересней. Первые три места — американцы, четвертое и пятое — Китай, Россия на шестом месте. Неплохо я считаю. Как ни странно, но вся ложь, которую нам рассказывали пропагандисты о том, что российский интернет занимает лидирующие позиции, оказалась правдой. Партнеры в лице немцев и хранцузов плетутся в хвосте. Странно, что Yahoo на первом месте. Всегда думал, что Гэ-майл самый популярный сервис. :)
Все что я хотел рассказать относительно почтовых адресов я сказал. Теперь у нас более сложная и муторная часть — выковырять из базы нехэшированные пароли и логины. Далее сформировать из них ТОП. Работа эта во многом ручная. Но нас спасет то, что мы в самом начале рассортировали файлы по типу обработки. В реальной жизни у меня эта сортировка заняла примерно полтора-два дня, но потом здорово сэкономила мне время.
В обработке файлов с логинами и паролями было довольно много сложностей. В частности много данных представлено в различных кодировках, поэтому часть данных приходилось смотреть глазами, перед тем, как обрабатывать. Если с латиницей почти не возникает проблем, то с кириллицей и китайскими иероглифами проблем масса. В детали, дабы не увеличивать объем статьи, вдаваться не буду. В основном все решается «по месту», с конкретным файлом. Для определения кодировки есть замечательные утилиты chardet — отображают вероятность той или иной кодировки у файла. Весь файл обрабатывать необязательно. Если видите кракозябры, то это повод использовать chardet. Обычно достаточно нескольких десятков строк.
Примерно так это выглядит в реальной жизни:
head -n 5 8.txt
"zhangqwer1@email" "zhangqwer108"
"42283372" "m4609@email" "76898256" "��������"
"42283373" "1464906394@email "198902216635" "�����WҦ��٢��аҽ����0����"
"42283374" "1311072586@email" "qaz4338081" "�����č��̨���"
"42283375" "beitangxiaosheng@email" "XIAOWU3490560888" "����ӥ��ս������С��"
Я не уверен, что ваш броузер показывает то же, что вижу я, но примерную картину составить можно. Команда head -n 5 — выводит первые 5 строк файла.
Далее делаем так:
head -n 100 8.txt | chardet
И получаем вот такой ответ:
<stdin>: GB2312 with confidence 0.63922356091
А потом так:
head -n 5 8.txt | iconv -f GB2312 -t utf8 -c
"zhangqwer1@email" "zhangqwer108"
"42283372" "m4609@email" "76898256" "狂舞霸主"
"42283373" "1464906394@email" "198902216635" "蝶舞W姚华佗【邪医生★0级】"
"42283374" "1311072586@email" "qaz4338081" "┨"
"42283375" "beitangxiaosheng@email" "XIAOWU3490560888" "【精鹰①战】北堂小生"
Латиницу китайцы презрели. И это правильно. Интернет должен говорить и работать на родном языке. Кому интересно знать культурные особенности и пристрастия в придумывании паролей, те могут обратиться к прекрасной исследовательской работе по ссылке.
Работа называется: «Comparative Analysis of Three Language Spheres: Are Linguistic and Cultural Differences Reflected in Password Selection Habits?»
Русский вольный перевод: «Языковые и культурные различия в придумывании паролей. Сравнительный анализ трех языковых и культурных групп».
От себя замечу, что авторы несколько западоцентричны, тем не менее доля истины в работе весьма велика. С их данными по анализу китайских паролей я не совсем согласен. В частности они утверждают, что китайцы «любят» цифровые пароли, хотя по моим данным это не так, однако доля цифровых паролей у китайцев действительно выше. Но это тема отдельной статьи, если я вдруг решу такую написать.
Забавным оказалось переводить китайские логины. Пока данные обрабатывались делать было нечего. Вот пример, например:
氓盲潞卢盲驴隆莽篓氓隆忙氓隆 - Blind Lu Lu Lu, Blind Donkey Rumble, Rumble Rumble
氓⒚铰 - Hinge
氓盲潞卢莽⒙久ヂ仿忙莽号氓⑩氓隆氓掳氓路 - Blind gangster Lu Mang ⒙ Jiu ヂ imitating busy mang gangster ⑩ gangster long gangster gangster road
氓陇陋茅鲁猫卤盲赂姑♀忙赂漏忙鸥忙垄娄 - Menglong Hou Maolu cat halogen blind bribery aunt
Double阿呆Plus++ - что-то типа: «двойной плюсовый дурак» :)
破hj解fjhf密码记录 — что-то типа: «попробуй взломать этот пароль»
我不是陈关系 - I'm not Chen Li
地狱小魔头 - Hell demon (Адский Димон)
僵尸的克星 - Zombie nemesis
Впрочем, если посмотреть на наши или западные форумы, то там тоже хватает похожих логинов. Распространенная китайская кодировка GB2312. Собсно какой-то другой я и не встретил.
Отдельный "геморрой" доставляет конец строки. При этом, сходу понять, что в том или ином файле не стандартный конец строки, невозможно. Консольные утилиты типа less не отображают тип конца строки в явном виде. Кроме того, в одном файле могут быть строки с разным концом строки. Только узнаёшь ты об этом когда уже отсортировал данные, увидев две одинаковые на первый взгляд строчки.
Мне встретились три типа концы строки:
\n — Unix
\r\n - Windows
\r — MAC
Надежный способ определения конца строки примерно такой:
head -n 1 <мой файл> | od -c
На выходе будет примерно следующее:
0000000 9 2 5 1 3 5 9 O w n e r \n
0000016
Здесь как видно конец строки — Unix. Хорошим вариантом будет приводить конец строки к нужному виду перед обработкой файла. Сделать это можно при помощи sed или tr.
Теперь перейдем к нашим ТОПам. Считал я их по методике описанной выше.
ТОП 50 логинов (не из почты):
1844886 And
976806 thien
826197 123456
769860 eting
726141 zara
616940 David
563177 david2500000
512929 123456789
512727 Maria
495867 Alex
436611 Anna
402734 Marco
370577 Antonio
365755 Daniel
357954 Andrea
346479 Laura
331551 Jose
315196 Michael
315106 Sandra
304003 him
302800 Ali
301248 F
291480 f
289141 none
277892 Sara
275365 wengian
269648 qwerty
249592 Robert
246693 Carlos
244908 LAM NGOC NGA
243066 ۩
242472 John
239743 Ana
231343 M
222585 Francesco
222179 Marie
220628 Sarah
218518 Inc
217501 CA
217142 Thomas
214388 m
213043 Jessica
208964 anhong
208519 Luca
206878 Marta
203905 Chris
203180 Martin
198660 Juan
198542 Mehmet
197256 ????
Выглядит весьма пёстро. С одной стороны ожидаемо много имен, с другой наличие юникодных символов меня смущает. Хотя такое встречал на некоторых сайтах.
ТОП 50 паролей:
15347574 123456
9251390 Owner
8589751 123456789
8515227 U
7301233 English
6492241 0
6446323 Mixed
5640247 Medium
5422318 ON
4742218 M
4561989 qwerty
4229087 password
4138211 12345
3960907 Single Detached Houses
3659964 QC
3582306 qwerty123
3440666 1q2w3e
3267153 DEFAULT
3187904 Large
2860813 Families
2616466 111111
2553995 French
2399313 White-Collar & Service Sector
2381911 High School/Trade
2334127 Renter
2307889 University/College
2170696 Families/Couples
2140559 Blue-Collar & Service Sector
2135532 BC
2095592 Small
1874174 Singles/Couples
1804364 12345678
1764024 123123
1699863 Oct-24
1676924 000000
1653084 AB
1587845 <6
1574485 F
1535589 Before 1960
1523563 High School
1440951 High School/Trade/College
1407905 After 1981
1389360 Couples/Families
1310663 Non-Official
1303531 18+
1254387 <15
1250221 25+
1211174 University
1198900 Service Sector & White-Collar
1120018 Before 1970
ТОП паролей меня смутил еще больше. С одной стороны все топ пароли интернета здесь присутствуют, с другой стороны меня очень смущают пароли вида: «Single Detached Houses». Признаюсь я и сам грешу длинными фразами в паролях, но тут их довольно много. Это может свидетельствовать о том, что в базу попало много мусора. Впрочем, эти данные все равно будут еще обработаны и почищены. А в «сыром» виде - как получилось, так получилось. Возможно, если все сделать по методике тех, кто периодически публикует рейтинги, будет так же как у них. Они вероятно считают пароли с пробелами не валидными и убирают их из рейтинга. Попробовал убрать все строки с пробелами и пересчитать рейтинг:
ТОП 50 паролей (предварительно убраны строки с пробелами):
9251359 Owner
8897989 123456
8514844 U
7300590 English
6449585 123456
6446314 Mixed
6377520 0
5640192 Medium
5622578 123456789
5422308 ON
4738555 M
4416047 qwerty
4011451 password
3924819 12345
3659964 QC
3499776 qwerty123
3342908 1q2w3e
3267151 DEFAULT
3187894 Large
2967173 123456789
2860782 Families
2553777 French
2334124 Renter
2307889 University/College
2170696 Families/Couples
2135517 BC
2095524 Small
1874174 Singles/Couples
1701266 111111
1699857 Oct-24
1653043 AB
1587845 <6
1573447 F
1389360 Couples/Families
1310663 Non-Official
1303531 18+
1254387 <15
1250221 25+
1248840 000000
1210953 University
1109129 123123
1026247 <18
1008180 12345678
1006660 Blue-Collar
997425 10+
997410 Couples/Singles
960243 1
950136 45
927906 44
927861 Mix
Как видно стало более похоже на «человеческий», но все равно получилось не, так как у других. :)
Что интересного заметил
«Одминам» на заметку. Не стоит аккаунту admin давать пароль вида: <имя сайта или форума> + <цифры>. Как ни странно, такое встречается даже в дампах 2017-2018 годов. В дампах 2008-2012 сплошь и рядом.
В дампах до 2012 года нехэшированные пароли обычное явление. После 2012 активно пошли хэшированные, дальше еще и с «солью». Самые свежие уже используют динамическую соль. Но по-прежнему мало кто догадывается хранить «соль» в отдельной базе. Очень рекомендую, при этом база должна быть доступна только изнутри своей сети. Если хакер утянул базу с хэшами паролей, с помощью какой ни будь уязвимости в доступной базе данных, то получить соль ему будет сложнее, так как надо лезть внутрь сети, а для этого надо разобраться в её структуре. Этим самым вы существенно осложните хакерам задачу по расшифровке, а сами сможете среагировать и оповестить своих пользователей. По моему разумению на сегодня не существует хэшей, которые невозможно дехэшировать. Вопрос только во времени. Поэтому, на случай утечки данных, необходимо сделать так, чтобы на расшифровку ушло как можно больше времени. Паролями в нехэшированном виде грешили ресурсы разных стран. От России и США до Китая. В то время это были «best practics».
Что пишут в логи дорогие хозяева ресурсов
Поскольку базы изобилуют различными логами, то могу кратко рассказать что туда пишут хозяева ресурсов. Если точнее сформулировать: какие данные я там заметил. Не буду никого обвинять и раскрывать имена. Дабы предотвратить спекуляции, сразу скажу, что нашего ресурса в базах нет.
Что встретил:
1. Номера кредиток. У кого-то номера порезаны, у кого-то полные;
2. CVV коды вводимые юзером. Хотя насколько помню такие вещи вообще сохранять нельзя;
3. IP адреса в привязке ко времени и координатам, а также к device id и номеру телефона. Забавная база. Можно много интересного из нее выколупать. По России данных там нет;
4. Приватные текстовые чаты каких-то сайтов, с полным сохранением текста. Юзер, помни! Всё что ты набил в интернете — стало общественным достоянием. Ну или рано или поздно таковым станет;
5. Данные с разных облачных хранилищ. Юзер, помни! Данные в облаке — не твои данные;
6. Данные покусанных девайсов с привязками к id устройства — в принципе бесполезны;
7. Данные избирателей одной страны;
8. Мои пароли из 2013-2016 годов. Стоит заметить, пароли 14-16 символов, не словарные слова. Два пароля созданы менеджером паролей. Хе хе, менеджеры паролей безопасны, говорили они;
9. Свои публичные почтовые адреса;
10. Логины (почтовые адреса) и пароли знакомых — 7 человек. Трое из них использовали пароли найденные в базе. Разумеется я их напугал. Срочно сменили. Другие сказали, что использовали такие пароли несколько лет назад, регистрировались на каких-то «мусорных» ресурсах;
Опять немного цифр
Я думаю многим было бы интересно количественные показатели по логинам и паролям, которые удалось вытянуть из базы.
Вот что у меня получилось:
Общее количество логинов: 2 306 631 346
Количество уникальных логинов: 1 532 895 649
Общее количество паролей: 1 620 901 764
Количество уникальных паролей: 451 871 053
Посчитаем коэффициент уникальности для логинов и паролей:
Для логинов коэффициент уникальности составил ~33,54%.
Для паролей — страшные ~72,12%.
Что означают эти цифры? А означают они то, что люди проявляют гораздо большую изобретательность при придумывании себе логинов, и совсем не изобретательны при придумывании себе паролей. Т.е чем выше коэффициент уникальности тем хуже.
Это может быть связано с несколькими причинами.
Например:
- На многих ресурсах нельзя иметь повторяющийся логин, а к паролям таких требований не предъявляют;
- Людям важна внешняя составляющая — главное казаться, а не быть. Поэтому мы изобретаем себе заковыристые логины, а на пароли тупо забиваем;
- Многие ресурсы до сих пор не предъявляют особых требований к пользовательским паролям. Однако простая проверка на уникальность пароля в локальной базе может дать очень хорошие результаты, заставив юзера немного дольше подумать над паролем.
Интересное
Самая длинная командная строка:
cat * | grep -aEi '(^|[^a-fA-F0-9])[a-fA-F0-9]{32}([^a-fA-F0-9]|$)' | iconv -f cp1254 -f utf8 -c | non-print-clear-first-step | non-print-clear | html-char-to-text | awk -F ":" '{print $1}' | sed "s/^[ \t]*//g" | sed "s/[ \t]*$//g" | sed '/^\s*$/d' >> my-file.txt
Звезды сошлись крайне не удачно. В одном файле были замешаны строки с логинами, хэшами MD5 и паролями, а также строки с классическими логином и паролем. Ну до кучи еще не привычная кодировка, непечатаемые символы и бинарные данные, а также текст закодированный в html кодировке — что-то типа такого 'Анатолий'.
Пришлось изобретать на ходу.
Утилиты non-print-clear-first-step, non-print-clear, html-char-to-text, недолго думая соорудил на Питоне. Остальное было решено стандартными средствами Линукса. Не даром говорят: «Юникс — это pipe». Конечно такие гигантские командные строки немного напрягают, но видали и подлиннее.
Кому интересно ниже скрипты.
non-print-clear-first-step:
#!/usr/bin/python import sys if __name__ == "__main__": if len(sys.argv) > 1: specedel = (sys.argv[1]) else: specedel = 0 for stringin in sys.stdin: text = stringin.replace("\t","<prd1>") output = text.decode('utf-8','ignore').encode("utf-8") text1 = output.replace("<prd1>","\t") if specedel == 0: print(text1.strip()) else: print(" ".join(text1.split()))
non-print-clear:
#!/usr/bin/python3.6m ##-*- coding: utf-8 -*- import sys if __name__ == "__main__": if len(sys.argv) > 1: specedel = (sys.argv[1]) else: specedel = 0 for stringin in sys.stdin: text = stringin.replace("\t","<prd1>") output = "".join(c for c in text if c.isprintable()) text1 = output.replace("<prd1>","\t") if len(output) > 0: if specedel == 0: print(text1.strip()) else: print(" ".join(text1.split()))
html-char-to-text:
#!/usr/bin/python #-*- coding: utf-8 -*- import os import re import string import sys; reload(sys); sys.setdefaultencoding("utf8") from HTMLParser import HTMLParser for stringin in sys.stdin: kk = stringin.encode('utf-8', errors='replace').strip() h = HTMLParser() print(h.unescape(kk))
Количество паролей содержащих кириллические символы — 808219 из 451 871 053. То есть около 0,18%. Людей приучили забивать пароли на латинице, несмотря на то, что большинство ресурсов поддерживает юникод. Если меня читают разработчики, то обязательно тестируйте свои разработки на предмет совместимости с юникодными паролями и специальными символами.
Краткие итоги
1. В процессе работы над базой пришло понимание, что простым способом подсунуть базу собранных паролей нейросети не получится. Пришлось чистить довольно основательно. Также добавил распространенные общедоступные базы. Всего получилось около 900 миллионов чистеньких уникальных паролей — размер около 14Гб. Обучение нейросети осуществлялось батчами (batch) — иными словами данные для обучения скармливались кусочками, поскольку датасет такого размера в память GPU не лезет. Обучение заняло 3 недели. Можно было и дольше, но надо ограничивать свой перфекционизм. Теоретически размер базы для обучения можно уполовинить. Уж больно «злая» нейросеть получилась.
2. Люди более изобретательны в придумывании себе логинов. И не изобретательны в придумывании себе паролей. При этом ценность логина ноль, а ценность пароля высока. Отчасти вина лежит на владельцах ресурсов. Многие никак не влияют на сложность пароля.
3. Наука информатика (если по-модному - «дата сайнс») не должна себя ограничивать только языком Python и модулем Pandas. В конце концов умение собрать данные из разрозненных источников и привести их к однообразному виду - самое главное умение специалиста в области «дата сайнс». Мой опыт показывает, что самые сложные и дорогие этапы - это собрать и разметить данные.
4. Судя по тому, что я видел в базе, можно сделать вывод, что сливают все и всё. Это уже не шокирует, но сильно печалит. В нехороших руках такие базы могут стать грозным оружием. Но я считаю, что люди обязаны знать об этом. Тогда мы сможем эффективно противостоять сбору информации о нас. Я призываю думать, прежде чем оставлять свой след в интернете. Любое слово вами написанное, любой сохраненный в облаке файл могут быть использованы против вас. Информация, что дышло: как повернешь, туда и вышло.
5. На полную обработку данных, включая подсчет ТОПов ушло около 8-ми дней.
6. Неприкасаемых нет. Воруют данные у государств, у крупных корпораций, у мелких сайтов. Обидно то, что мы узнаём об этом не всегда оперативно. Бизнес уроды и чиновники до победного конца пытаются сохранить свою репутацию и не повредить своему баблу. Вспомните крупные утечки: Гармин, Кэнон. Летом у меня Гармин лежал в течение ПЯТИ дней.
Я уверен, что стыренные данные уже есть в сети. Из свеженького: Взломали ПО которое управляет IT инфраструктурой. Клиенты получили трояна вместе с обновлением. Майкрософт тоже попала под раздачу. Адъ и Израиль! Администрация ресурса не привествует ссылки на «вражеские ресурсы», поэтому искать по фразе: «Взлом года» затронул сети Microsoft, но на клиентов заражение не перекинулось.
В общем, плакали наши данные. Поэтому включаем голову и живем так, как будто все данные о нас публичны, а то чего никому знать не положено, то и светить в интернете не надо. Мир теперь это одна большая деревня, ё-мое. :(
7. На основании п.6 я с большим ужасом представляют себе уровень распи...ва в крупных корпорациях. Они тупо знают, что им за это ничего не будет. Помните новость: Гугл заплатит пользователям за утечку данных по 5$. Только гражданам США, которые оформят заявку. Именно во столько Гугл оценивает своих хомячков. Да они заработали на них в 10 раз больше! Теперь отстегнут чуток с барского плеча. Вот меня бомбануло блин! Сорян.
8. Как обычно, хорошая мысля приходит опосля. Уже после того как закончил работу пришла в голову мысль, что подобную конструкцию можно было попробовать сделать и без нейросетей. Bloom фильтр делает почти то же самое. Не удивлюсь если в нейросети после обучения реализовался аналог Bloom фильтра. Единственное, что пока не понятно - как быть с похожими паролями. Bloom фильтр, несмотря на красоту идеи, все же немножечко «тупее» чем нейросеть.
Соблюдение Правил конференции строго обязательно!
Флуд, флейм и оффтоп преследуются по всей строгости закона!
Комментарии, содержащие оскорбления, нецензурные выражения (в т.ч. замаскированный мат), экстремистские высказывания, рекламу и спам, удаляются независимо от содержимого, а к их авторам могут применяться меры вплоть до запрета написания комментариев и, в случае написания комментария через социальные сети, жалобы в администрацию данной сети.
Комментарии Правила