Наверное не один из нас сталкивался с траблами когда его веб шелл (залитый неимоверними усилиями) на какой либо ресурс, в данном случае это форум 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 я так и зделал -) Для не просвящёных одисей - это такая тузла которая при отправке каких либо данных в инет даёт вам возможность отредактировать их перед отправкой. Ну и конечно я радовался как первокласник новому году, когда мне сказали что пасс админа успешно поменян и предложили зайти на форум -)) Через некоторое время мой хитрозамаскированный шелл снова удалили, скорее всего админ опять зделал бакуп базы и всё переустановил, но ещё при этом апгрейдил форум -) наивно , но он до сих пор не вкурил что дело не в уязвимости скрипта, а бэкдор до сих пор храниться в его базе -) Вот таким вот образом я обеспечил себе дверь, через которую можно зайти не один раз, даже при полной чистки сервака, был бы бэкап -) ... удачи вам !
Все бы хорошо, если бы не одно НО. Видимо тебе попалась древняя версия. Ибо в 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);
El видимо ты не внимательно читал то, что я написАл (особенно кусок приведённого кода) ... т к я заведомо зделал ретрив пасса админу, подглядел валидатион и затих на какое то время ! незнаю с какой переодичностью он делал бэкапы, но свой старый пасс восстановил через админку на серваке ИМХО. Админ попался матёрый, поэтому он в панике не тыкал на кнопку ВСПОМНИТЬ пасс, это просто дело случая ... А колизию нашёл пасс про за пару минут, ну это дело случая т к можно найти быстрее и полным перебором ... Скрипту ретрива не важно что глотать, лиш бы при шифровке и обрезке получилось то что прописано в базе. Да и ещё одно, версия была не такая уж и древняя -) 1.0.13 (это немного упрощённая версия 1.1.4) в этой версии не хватает небольших и не столь значительных кусочков кода ! LEE_ROY При бэкапе , даже если сменить пасс не через восстановление, а просто скажем через миадмин (т к админ думал что я просто подобрал его пасс) колонка валидатион не куда не девается и так же сохраняется в бэкап в обезательном! порядке.
способ действительно действенный, и причем перебор состоит из 10 цифр и 6-ти первых букв латинского алфавита, т.е. на все про все уйдет максимум 3 дня(у меня 2-х ядерный АМД 6400+). ну это конечно если без коллизии.. )))
2 n-000 Вообще, баг интересный, молодец. Но я не вижу на официальном сайте никакой урезанной версии, помимо обновлений разной степени "облегчённости". Может оно и так, но пока не ясно где ты её взял. А пока - таже история с урезком наблюдается и в 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))); }
El это не я её взял -) Этот форум уже был на серваке с которым я и проделывал эксперименты ... Я долго гуглил (хотел на локал хост такой же) и в гугле вычитал что это урезок, кстате обновления этого форума происходит через админку, а на офф сайте есть раздел на который нет ссылок, ну во всяком случае я не нашёл ... возникали мысли о платной версии но он бесплатен. Если интересует могу в ПМ скинуть ссыль на такого зверька.
Поговорил по поводу поддержки брута неполных хешей с автором пассвордпро - оказалось прога давно это держит.
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 дня. Тем более скрипт можно расположить на различных серверах и запускать там(распределенный перебор).