Сайт - get-simple.info Версия 3.3.16 - Latest Stable Version. Интернеты говорят вот так: В админке имеем возможность редактирования шаблонов - php файлы. Удаляем стопер, пишем phpinfo и у нас RCE) Осталось теперь как-то попасть в эту самую админку. Auth bypass или предсказываем значение rand() Система использует xml файлы для хранения данных, скулей не увидим. Посмотрим на то как проходит аутентификация. admin/inc/login_functions.php PHP: if ( ($userid == $USR) && ($password == $PASSWD) ) { $authenticated = true; Слабое сравнение(type jugling), но: 1) GetSimple использует sha1, брутить слишком много вариантов 2) Юзер == админ, поэтому их количество будет не большим) 3) Нужный юзер скорее всего имеет пароль отличный от необходимого нам диапозона С одной стороны вроде как и нет баги. С другой, если мы заглянем на страницу восстановления пароля, увидим, что этот процесс происходит таким образом: 1) Запрос на восстановление 2) Смена пароля 3) Отправка нового пароля на email На email не отправляется линк на смену пароля, пароль меняется и отправляется на почту. Отсюда можно решить 2 и 3 проблемы таким способом: -- отправляем на аутентификацию всегда пароль, хэш которого 0e[0-9]{38} - например aaK1STfY -- расстреливаем запросами на смену пароля Но проблема слишком большого количества вариантов мешает получить сколько-нибудь значимые результаты. Плюс ко всему, ситуация ослажняется вот этим: admin/resetpassword.php PHP: ...$randSleep = rand(250000,2000000); // random sleep for .25 to 2 seconds...usleep($randSleep);... Но раз в нашем случае мы можем поменять пароль, посмотрим что это за пароль и как он генерируется: admin/inc/template_functions.php PHP: function createRandomPassword() { $chars = "Ayz23mFGHBxPQefgnopRScdqrTU4CXYZabstuDEhijkIJKMNVWvw56789"; srand((double)microtime()*1000000); $i = 0; $pass = '' ; while ($i <= 5) { $num = rand() % 33; $tmp = substr($chars, $num, 1); $pass = $pass . $tmp; $i++; } return $pass;} Вот тут мы имеем два момента. Первый -- Что генерируется и как проверяется? Генерируется 6-символьный пароль. Имеем type jugling. Для брута sha1, учитывая время на создание нового пасса и sleep, наши 13ккк будем брутить очень долго. А вот 6 символьный вариант 0eXXXX будет попадаться в среднем на каждые 2,5кк запросов смены пароля для [a-zA-Z0-9]{6}. Все равно долго... Да и хитрые разрабы предусмотрели этот вариант - в нашем диапозоне не 62 символа, как должно быть для [a-zA-Z0-9]{6}, а 57 и нашего нолика тут как раз и не хватает)) Второй -- Как генерируется? Собсна сама бага. Функция rand() генерирует псевдослучайное число. И, если мы знаем начальное число генератора псевдослучайных чисел, мы можем узнать это псевдослучайное число. И не только его. Мы можем проследить всю цепь чисел, которые генерятся функцией rand, так как все последующие числа предсказуемы. Значит мы можем выявить все символы в новом пароле сгенеренные функцией rand. А сколько их, этих начальных чисел? На nix(php-7.3) у меня выплюнул 2kkk результатов. Т.е. два миллиарда полных вариантов пароля, а вот для win: Но разрабы решили вписать свое число. Оно устанавливается функцией srand. Что в ней происходит? Из текущей метки времени Unix с микросекундами берутся именно микросекунды и умножаются на 1кк - именно столько вариантов у нас для брута, микросекунды float 0.XXXXXX, поэтому целочисленное значение у нас никогда не будет больше одного миллиона. Для атаки на потребуется лишь один раз запросить смену пароля, а потом пробрутить наши 1 миллион паролей - дело 20 минут. Генерируем список вариантов возможных паролей: PHP: $chars = "Ayz23mFGHBxPQefgnopRScdqrTU4CXYZabstuDEhijkIJKMNVWvw56789";for($i = 0;$i <= 999999; $i++){ srand($i); $n = 0; $pass = ''; while ($n <= 5) { $num = rand() % 33; $tmp = substr($chars, $num, 1); $pass = $pass . $tmp; $n++; } echo "$pass\n"; } Тестанул - 10 из 10, Auth bypas
Предлагаю перенести этот пост в статьи, т.к. достойно, а сюда выложить сухую выжимку + приложить эксплоит. Мораль сей басни такова, что не нужно плодить свои криптовелосипеды
небольшая добавка, благодаря $num = rand() % 33; (модуло 33) имеем даже не 57 символов, а "только" 33, В этом конкретном случае правда это не играет роли...