Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
Криптографическая атака на SMF |

15.08.2008, 23:54
|
|
Участник форума
Регистрация: 25.10.2006
Сообщений: 108
Провел на форуме: 495411
Репутация:
91
|
|
Криптографическая атака на SMF
Наверное не один из нас сталкивался с траблами когда его веб шелл (залитый неимоверними усилиями) на какой либо ресурс, в данном случае это форум SMF находил и удалял злой дятька АдМиН ?
Размышляя на эту тему хотел бы боделиться некоторыми соображениями, для которых необходимо иметь веб шелл на этом ресурсе ...
Сампле машин форум имеет некоторые фишки, как и большое кол во движков (не только форумы), такие как ретрив пароля ... так вот имея доступ к БД, я как то раз зделал ретрив пасса админу и подсмотрел табличку в базе под названием validation_code, формирование этого кода в смф происходит таким образом :
PHP код:
$password = substr(preg_replace('/\W/', '', md5(rand())), 0, 10);
// Set the password in the database.
db_query("
UPDATE {$db_prefix}members
SET validation_code = '" . md5($password) . "'
WHERE $searchField = '$_POST[user]'
LIMIT 1", __FILE__, __LINE__);
require_once($sourcedir . '/Subs-Post.php');
sendmail($row['emailAddress'], $txt['reminder_subject'],
sprintf($txt['sendtopic_dear'], $row['realName']) . "\n\n" .
"$txt[reminder_mail]:\n\n" .
"$scripturl?action=reminder;sa=setpassword;u=$row[ID_MEMBER];code=$password\n\n" .
"$txt[512]: $user_info[ip]\n\n" .
$txt[35] . ': ' . $row['memberName'] . "\n\n" .
$txt[130]);
Так вот, весь смысл в том, что при ретриве генерица произвольное число, шифруется MD5 и обрезается до 10 символов ...
Хочу заметить , что эта лабуда сначало пишется в базу в столбец validation_code потом ещё раз шифруется и обрезается, только после этого отправляется на почту юзера !
На первый взгляд дело дрянь ! Но когда во время моих глумленей удалили ВСЕ мои шелы (скорее всего сервер просто почистили, переустановили скрипты и бекапом вернули базу) мне так не показалось, имея на руках эти 10 символов, начал усиленно думать ...
Я понял, что шелы не вернуть, а вот validation_code наверняка остался при бекапе и зная 10 символов из целого хэша можно попробывать расшифровать и сменить пасс админу. Параметры для брута были известны, это маленькие латинские и цифры, но 10 символов, как понимаете не одна ноч расшифровки ...
Но как то я случайно вбил все маленкие символы и о чудо -) пасворд про нашол коллизию под эти 10 символов - Благо эта тузла умеет понимать не полные хэши ))
Результат получился не особо впечатляющим ( 2nq3&l7) всё портил символ &, при переходе по ссылке на ретрив пасса ( http://site.ru/forum/index.php?action=reminder;sa=setpassword;u=1;code= 2nq3&l7) этот символ как бы передавал ещё один параметр скрипту ретрива, тоесть всё что до него проходило, а после отсекалось !
Зная validation_code в СМФ можно без труда изменить пасс любому юзеру, чей код известен. И тут я решил - а что если подделать HTTP пакет и через POST запрос передать переменную code вместе с этим мать его & !
Воспользовавшись локальным прокси сервером Odysseus я так и зделал -)
Для не просвящёных одисей - это такая тузла которая при отправке каких либо данных в инет даёт вам возможность отредактировать их перед отправкой.
Ну и конечно я радовался как первокласник новому году, когда мне сказали что пасс админа успешно поменян и предложили зайти на форум -))
Через некоторое время мой хитрозамаскированный шелл снова удалили, скорее всего админ опять зделал бакуп базы и всё переустановил, но ещё при этом апгрейдил форум -) наивно , но он до сих пор не вкурил что дело не в уязвимости скрипта, а бэкдор до сих пор храниться в его базе -)
Вот таким вот образом я обеспечил себе дверь, через которую можно зайти не один раз, даже при полной чистки сервака, был бы бэкап -) ... удачи вам !
|
|
|

21.08.2008, 10:28
|
|
Banned
Регистрация: 05.12.2005
Сообщений: 982
Провел на форуме: 4839935
Репутация:
1202
|
|
Все бы хорошо, если бы не одно НО.
Видимо тебе попалась древняя версия.
Ибо в 1.1.4 validation_code состоит из 10 символов, тоесть является неполным хешем.
С точки зрения криптостойкости - это смешно, поскольку такому урезку будет соответствовать большое кол-во коллизий паролей.
Но авторы smf поставили видимо на сторону практического нахождения коллизии пароля по неполному хешу,
потому что лично мне не известен более менее приличный софт для нахождения коллизий по неполному хешу
(именно хешу, а не паролю - не спутайте с поиском по маске пароля в пассвордпро)
Щас выяснилось, что _https://hashcracking.info/index.php?1 единственный онлайн сервис, позволющий искать известный пароль по маске неполного хеша.
Пусть validation_code=d8578edf84
Тогда ищем по маске как d8578edf84%
Ну и еще одно маленькое НО: чтобы validation_code присутствовал в бд, необходимо, чтобы юзверь хоть раз запрашивал востановление пароля, до того как вы сняли дамп(и не запрашивал после, ибо тогда validation_code изменится).
smf_1-1-4
/Sources/Reminder.php
PHP код:
function RemindMail()
{
// Randomly generate a new password, with only alpha numeric characters that is a max length of 10 chars.
$password = substr(preg_replace('/\W/', '', md5(rand())), 0, 10);
// Set the password in the database.
updateMemberData($row['ID_MEMBER'], array('validation_code' => "'" . substr(md5($password), 0, 10) . "'"));
require_once($sourcedir . '/Subs-Post.php');
sendmail($row['emailAddress'], $txt['reminder_subject'],
sprintf($txt['sendtopic_dear'], $row['realName']) . "\n\n" .
"$txt[reminder_mail]:\n\n" .
"$scripturl?action=reminder;sa=setpassword;u=$row[ID_MEMBER];code=$password\n\n" .
"$txt[512]: $user_info[ip]\n\n" .
"$txt[35]: $row[memberName]\n\n" .
$txt[130]);
/Sources/Reminder.php
function setPassword2()
{
// Quit if this code is not right.
if (empty($_POST['code']) || substr($realCode, 0, 10) != substr(md5($_POST['code']), 0, 10))
fatal_error($txt['invalid_activation_code'], false);
Последний раз редактировалось Elekt; 21.08.2008 в 10:38..
|
|
|

21.08.2008, 10:58
|
|
Постоянный
Регистрация: 09.11.2006
Сообщений: 639
Провел на форуме: 1917742
Репутация:
541
|
|
validation_code наверняка остался при бекапе
как он мог остатсо при бакапе, если снесли все скрипты а базу восстановили?
|
|
|

21.08.2008, 14:18
|
|
Постоянный
Регистрация: 31.07.2002
Сообщений: 312
Провел на форуме: 1212427
Репутация:
187
|
|
Результат получился не особо впечатляющим (2nq3&l7) всё портил символ &, при переходе по ссылке на ретрив пасса (http://site.ru/forum/index.php?action=reminder;sa=setpassword;u=1;code= 2nq3&l7) этот символ как бы передавал ещё один параметр скрипту ретрива, тоесть всё что до него проходило, а после отсекалось !
Ну какбэ А так +
|
|
|

22.08.2008, 00:35
|
|
Участник форума
Регистрация: 25.10.2006
Сообщений: 108
Провел на форуме: 495411
Репутация:
91
|
|
El видимо ты не внимательно читал то, что я написАл (особенно кусок приведённого кода) ... т к я заведомо зделал ретрив пасса админу, подглядел валидатион и затих на какое то время ! незнаю с какой переодичностью он делал бэкапы, но свой старый пасс восстановил через админку на серваке ИМХО. Админ попался матёрый, поэтому он в панике не тыкал на кнопку ВСПОМНИТЬ пасс, это просто дело случая ...
А колизию нашёл пасс про за пару минут, ну это дело случая т к можно найти быстрее и полным перебором ...
Скрипту ретрива не важно что глотать, лиш бы при шифровке и обрезке получилось то что прописано в базе.
Да и ещё одно, версия была не такая уж и древняя -) 1.0.13 (это немного упрощённая версия 1.1.4) в этой версии не хватает небольших и не столь значительных кусочков кода !
LEE_ROY
При бэкапе , даже если сменить пасс не через восстановление, а просто скажем через миадмин (т к админ думал что я просто подобрал его пасс) колонка валидатион не куда не девается и так же сохраняется в бэкап в обезательном! порядке.
|
|
|

24.08.2008, 06:25
|
|
Постоянный
Регистрация: 31.07.2002
Сообщений: 312
Провел на форуме: 1212427
Репутация:
187
|
|
способ действительно действенный, и причем перебор состоит из 10 цифр и 6-ти первых букв латинского алфавита, т.е. на все про все уйдет максимум 3 дня(у меня 2-х ядерный АМД 6400+). ну это конечно если без коллизии.. )))
|
|
|

02.09.2008, 10:31
|
|
Banned
Регистрация: 05.12.2005
Сообщений: 982
Провел на форуме: 4839935
Репутация:
1202
|
|
2 n-000
Вообще, баг интересный, молодец.
Сообщение от n-000
Да и ещё одно, версия была не такая уж и древняя -) 1.0.13 (это немного упрощённая версия 1.1.4) в этой версии не хватает небольших и не столь значительных кусочков кода !
Но я не вижу на официальном сайте никакой урезанной версии, помимо обновлений разной степени "облегчённости".
Может оно и так, но пока не ясно где ты её взял.
А пока - таже история с урезком наблюдается и в smf_2-0-beta3
/Sources/Reminder.php
PHP код:
$password = substr(preg_replace('/\W/', '', md5(rand())), 0, 10);
require_once($sourcedir . '/Subs-Post.php');
$replacements = array(
'REALNAME' => $row['real_name'],
'REMINDLINK' => $scripturl . '?action=reminder;sa=setpassword;u=' . $row['id_member'] . ';code=' . $password,
'IP' => $user_info['ip'],
'MEMBERNAME' => $row['member_name'],
'OPENID' => $row['openid_uri'],
);
$emaildata = loadEmailTemplate('forgot_' . $context['account_type'], $replacements, empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']);
$context['description'] = $txt['reminder_' . (!empty($row['openid_uri']) ? 'openid_' : '') . 'sent'];
// If they were using OpenID simply email them their OpenID identity.
if (!empty($row['openid_uri']))
sendmail($row['email_address'], $emaildata['subject'], $emaildata['body']);
else
{
// Set the password in the database.
updateMemberData($row['id_member'], array('validation_code' => substr(md5($password), 0, 10)));
}
|
|
|

02.09.2008, 13:39
|
|
Участник форума
Регистрация: 25.10.2006
Сообщений: 108
Провел на форуме: 495411
Репутация:
91
|
|
El это не я её взял -) Этот форум уже был на серваке с которым я и проделывал эксперименты ...
Я долго гуглил (хотел на локал хост такой же) и в гугле вычитал что это урезок, кстате обновления этого форума происходит через админку, а на офф сайте есть раздел на который нет ссылок, ну во всяком случае я не нашёл ... возникали мысли о платной версии но он бесплатен. Если интересует могу в ПМ скинуть ссыль на такого зверька.
|
|
|

31.10.2008, 21:52
|
|
Banned
Регистрация: 05.12.2005
Сообщений: 982
Провел на форуме: 4839935
Репутация:
1202
|
|
Поговорил по поводу поддержки брута неполных хешей с автором пассвордпро - оказалось прога давно это держит.
|
|
|

02.02.2009, 09:04
|
|
Постоянный
Регистрация: 31.07.2002
Сообщений: 312
Провел на форуме: 1212427
Репутация:
187
|
|
Описание
int rand ([ int $min ], int $max )
При вызове без параметров min и max , возвращает псевдослучайное целое в диапазоне от 0 до RAND_MAX.
RAND_MAX, как посмотрел на различных Linux и FreeBSD серверах, оказывается не более 9 999 999 999, т.е. не более 10 милиардов, итого 10 знаков.
если запустить скрипт:
PHP код:
<?php
$time=time();
for($q=0;$q<10000000000;$q++){
if(($q % 1000000)==0){
echo $q." - ".date("H:i:s",time()-$time)."\r\n";
}
$t=substr(md5($q),0,10);
if(substr(md5($t),0,10)=="72dc15205d"){
echo $t;
break;
}
}
?>
то, на моей системе, 1кк перебирается за 11 секунд. Чтобы перебрать 10ккк потребуется примерно 30-34 часов, (11*10000/3600).
В то же время, если подбирать в PasswordsPro 10 символов из списка "0123456789abcdef", то для всего перебора потребуется 3 дня.
Тем более скрипт можно расположить на различных серверах и запускать там(распределенный перебор).
Последний раз редактировалось Dr.Frank; 02.02.2009 в 09:11..
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|