Пароли WordPress на md5. Как их взламывают

Многие специалисты по ИБ говорят, что: «Хеширование паролей WordPress небезопасно», аргументируя это так: «… потому что основано на md5».

Верно это или нет, но надежное хеширование паролей имеет решающее значение для такой большой экосистемы, как WordPress, которая всегда была привлекательной целью для хакеров. Итак, я решил поближе познакомиться с системой хеширования и попытаться взломать хеши WordPress с нуля!

Понимание хэшей паролей WordPress

Поиск в Google не выдал ничего полезного,  большая часть информации носит общий характер и только сбивает с толку. Много ссылок на используемые библиотеки PHP (переносимый хеш из phpass), но ничего конкретного.

Я решил использовать другой подход, отталкиваясь от следующей мысли:

хеширование — это односторонний процесс, но WordPress каким-то образом может аутентифицировать пользователей, сопоставляя их ввод пароля с хешем, хранящимся в базе данных.

Оттуда я начал проверять код и нашел первую интересную функцию: wp_check_password($password,$hash)которая сравнивает простой текстовый пароль с хешем и возвращает true, если они совпадают.

				
					// Предположим, новый стиль phpass Portable hash.
if ( empty( $wp_hasher ) ) {
    require_once ABSPATH . WPINC . '/class-phpass.php';
    // По умолчанию используем Portable Hash из phpass.
    $wp_hasher = new PasswordHash( 8, true );
}
$check = $wp_hasher->CheckPassword( $password, $hash );
/** фильтр wp-includes/pluggable.php */
return apply_filters( 'check_password', $check, $password, $hash, $user_id );
				
			

Проходя через код в три этапа: CheckPasswordcrypt_privateи в encode64

Короче говоря, crypt_private($password, $stored_hash)повторно хеширует пароль, прежде чем его сравнивают с сохраненным хешем. Если они совпадают, пароль правильный и аутентификация продолжается. Это означает, что злоумышленники также могут использовать эту функцию для взлома хэша.

Анатомия хеша

Так выглядит хэш WordPress:

				
					$P$BnPVO4gP9JUMSAM1WlLTHPdH6EDj4e1
				
			

Для простоты предположим, что сайт использует PHP >5 и новейший переносимый хэш phpass, который является наиболее распространенной настройкой.

Первые 3 символа $P$– это идентификатор, сообщающий системе, какой у нас хэш.

Четвертый символ (отсчет от 0) используется для определения того, сколько раз md5 () должен обработать входную строку.

Символы от 5 до 12 nPVO4gP9– это соль, которая представляет собой случайную строку, добавляемую к паролю перед хешированием , чтобы придать ему больше случайности. Например, если ваш пароль admin , он преобразуется в nPVO4gP9admin, а затем хешируется.

Оставшаяся часть хэша JUMSAM1WlLTHPdH6EDj4e1– это реальная случайность, сгенерированная солью+паролем, переданным в недокументированной encode64функции, которая выполняет некоторые побитовые операции с входной строкой и возвращает 22 символа на выходе.

Пока не понятно? Копаем дальше.

Пока что мы знаем:

  • первая часть хеша – это фиксированный идентификатор
  • второй – один символ, используемый как счетчик
  • третья – соль, привязанная к паролю
  • последняя часть —  случайный, сгенерированные ‘salt + pass’, обработанный функцией encode64
				
					[$P$] [B] [nPVO4gP9] [JUMSAM1WlLTHPdH6EDj4e1]
				
			

Таким образом, мы можем подытожить — соль + пароль хешируется X раз и передается в encode64 — для выполнения атаки по словарю или брутфорс атаки необходим перебор «последней части» хеш-кода, для успешного взлома хэша!

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

Перезапись encode64 с использованием golang

Я решил использовать golang, потому что он очень быстрый, и нам нужна вся эта скорость для вычисления больших словарей паролей.

Как и в процедуре шифрования WordPress, сценарий берет хеш и изолирует соль, затем он составляет пароль (соль + пароль), пытаясь использовать каждый пароль в словаре и md5-хеширование X раз.

				
					itoa64 := "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
hashloop := 1 << strings.Index(itoa64, string(hash[3])); // char n. 4 in the hash
				
			

Сделав это, он выполняет серию побитовых операций с байтами, полученными с помощью ord () в PHP, которые нам не нужны в golang, поскольку у нас уже есть значения байтов.

				
					itoa64[hashedpass[0] &  0x3f]
				
			

На этом этапе понято, что нам даже не нужно искать всю строку. Достаточно сопоставить несколько символов, чтобы соответствовать всему паролю и сделать скрипт более производительным! Итак, из-за характера процесса хеширования, если char n. 0/4/8… соответствует, введенный пароль правильный.

И БУМ, хэш декодирован:

				
					wphashcrash '$P$BnPVO4gP9JUMSAM1WlLTHPdH6EDj4e1' Dev/wphashcrash/dict.txt
$P$BnPVO4gP9JUMSAM1WlLTHPdH6EDj4e1 admin
2020/05/30 12:44:15 Executed in 0.000221
				
			

Весь код на GitHub – https://github.com/francescocarlucci/wphashcrash – и на данный момент скрипт является POC и получает только один хэш пароля в качестве входных данных и путь к словарю паролей.

Если вы действительно хотите попробовать взломать список хэшей, вы можете выполнить его форк или просто заключить скрипт в цикл bash for.

Соображения безопасности

На данный момент, я думаю, достаточно ясно, что если злоумышленник получит доступ к базе данных на сайте WordPress, он / она сможет взломать любой слабый пароль.

Это досадно, особенно потому, что:

  • SQL-инъекция – не такая уж редкость в плагинах WordPress
  • RCE также, скорее всего, предоставит доступ к БД
  • Экосистема WordPress – огромная территория для работы фрилансеров, и очень часто можно найти старые / неиспользуемые учетные записи wp-admin и FTP, созданные для временных нужд.

Вдобавок ко всему , на многих веб-сайтах не используются надежные пароли, чтобы не навредить пользовательскому опыту.

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

Возможное решение

Известно, что Bcrypt является более сильным методом хеширования по сравнению с md5, и существует существующий плагин, который использует bcrypt и заменяет все основные функции, необходимые для обработки паролей:

  • wp_check_password ()
  • wp_hash_password ()
  • wp_set_password ()

Заключение

Существует множество инструментов для взлома хэшей, таких как Hashcat и John The Ripper, которые могут быть даже более производительными, но, опять же, цель этого исследования – понять структуру хешей WordPress и взломать ее с нуля .

Данная статья предназначена для изучения и проверки собственной инфраструктуры безопасности. 

Рекомендованные статьи

Определение и методы социальной инженерии

Не всегда кибермошенники для получения доступа к необходимой информации используют уязвимости в электронных ресурсах. Один из самых надежным и относительно простых способов получить необходимые данные…

Комментарии