1

HTTP Авторизация и безопасность

(11/07/2022 19:11:57 отредактировано VAN)

Тема: HTTP Авторизация и безопасность

Здравствуйте уважаемые форумчане и разрабы.
На досуге, изучая API, написал такой вот php скрипт авторизации и получения токена:

+ открыть спойлер
<?php
@unlink('cookie.txt');

echo '<body><center>
<h2>Скрипт авторизации в СМТ Wialon</h2>
<br><br>
<form method="POST" action="" id="auth-form" onsubmit="checkLogin(event)">
<input type="text" class="" name="login" id="login" placeholder="Пользователь" value="" autocapitalize="off" autocorrect="off" dir="auto">
<input type="password" class="" name="passw" placeholder="Пароль" autocapitalize="off" autocorrect="off" dir="auto">
<input type="submit" value="Получить"></form><br><br>';

if(!$_POST['submit']){
$login = htmlentities(htmlspecialchars($_POST['login']), ENT_QUOTES, 'UTF-8');
$passw = htmlentities(htmlspecialchars($_POST['passw']), ENT_QUOTES, 'UTF-8');
if (empty($login) OR empty($passw)) {
    echo 'Незаполнены поля логин или пароль!';
    exit;
} else {
$target_link = 'http://hosting.wialon.com/login.html';
$headers = array(
    'cache-control: max-age=0',
    'upgrade-insecure-requests: 1',
    'user-agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36',
    'sec-fetch-user: ?1',
    'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
    'x-compress: null',
    'sec-fetch-site: none',
    'sec-fetch-mode: navigate',
    'accept-encoding: deflate, br',
    'accept-language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
);

$curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $target_link);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_VERBOSE, false);
  curl_setopt($curl, CURLOPT_TIMEOUT, 10);
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($curl, CURLOPT_SSLVERSION, 3);
  curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$content = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);

if ($httpcode != 200 ) {
    echo 'Статус ответа: '.$httpcode.'<br>';
unset ($target_link, $content);
} else {
preg_match_all('#name="(.*?)" value="(.*?)"#Ui',$content, $matches);
echo 'Статус ответа: '.$httpcode.'<br>Получена сигнатура ('.$matches[1][9].'): '.$matches[2][9];
unset ($target_link, $content);

$target_link = 'https://hosting.wialon.com/oauth.html';
$postFields = array();
$postFields[$matches[1][0]] = $matches[2][0];
$postFields[$matches[1][1]] = $matches[2][1];
$postFields[$matches[1][2]] = $matches[2][2];
$postFields[$matches[1][3]] = $matches[2][3];
$postFields[$matches[1][4]] = $matches[2][4];
$postFields[$matches[1][5]] = $matches[2][5];
$postFields[$matches[1][6]] = $matches[2][6];
$postFields[$matches[1][7]] = $matches[2][7];
$postFields[$matches[1][8]] = $matches[2][8];
$postFields[$matches[1][9]] = $matches[2][9];
$postFields[$matches[1][10]] = $matches[2][10];
$postFields['login'] = $login;
$postFields['passw'] = $passw;

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $target_link);
curl_setopt($curl, CURLOPT_COOKIEFILE, __DIR__ . '/cookie.txt');
curl_setopt($curl, CURLOPT_COOKIEJAR, __DIR__ . '/cookie.txt');
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$content = curl_exec($curl);
curl_close($curl);

preg_match('#<h1 class="title">(.*?)</h1>#Ui',$content, $out1);
preg_match('#token=(.*?)&#Ui',$content, $out2);
preg_match('#svc_error=(.*?)#Ui',$content, $out3);

$res = str_replace(array("\r\n", "\r", "\n"), '',  strip_tags($out1[1]));
$token = str_replace(array("\r\n", "\r", "\n"), '',  strip_tags($out2[1]));
$error = str_replace(array("\r\n", "\r", "\n"), '',  strip_tags($out3[1]));
if ($error == 0) {
echo '<br>Результат: '.$res.'<br>Token: '.$token.')';
} else {
$errors = array(
            1 => 'Invalid session',
            2 => 'Invalid service',
            3 => 'Invalid result',
            4 => 'Invalid input',
            5 => 'Error performing request',
            6 => 'Неизвестная ошибка',
            7 => 'Доступ запрещён',
            8 => 'Неверное имя или пароль.',
            9 => 'Authorization server is unavailable, please try again later',
            1001 => 'No message for selected interval',
            1002 => 'Item with such unique property already exists',
            1003 => 'Only one request of given time is allowed at the moment',
            1006 => 'Превышен лимит попыток входа. Повторите попытку позже.'
        );
echo '<br>Результат - неудача. <br>Логин: "<b>'.$login.'</b>" или пароль: "<b>'.$passw.'</b>".<br>Ошибка: <b> '.$errors[$error].'</b> ('.$error.')';
unset ($target_link, $postFields, $errortext);
}
}
}
}
?>

Может кому пригодится.

демо версия: Проверить работу скрипта

В процессе выяснил что при множественных запросах (циклических) с положительным результатом существует ограничение по количеству авторизаций, а вот при отрицательном результате (неправильные пары логин/пароль)  ограничения нет
Что в свою очередь потенциально позволяет осуществить брут (подбор) пароля.
Циферный пароль из 6 символов подберётся за 10 - 11 дней.

Вывод:
Пользователям и Администраторам - На ответственных УЗ использовать сложные пароли не менее 8 символов.
Разрабам - может стоит как-то ограничить количество неправильно введённых учетных данных?

11010000 10010100 11010001 10000011 11010000 10111100 11010000 10110000 11010001 10000010 11010001 10001100 100000 101101 100000 11010001 10001101 11010001 10000010 11010000 10111110 100000 11010000 10111111 11010001 10000000 11010000 10111000 11010000 10111010 11010000 10111110 11010000 10111011 11010001 10001100 11010000 10111101 11010000 10111110 100001
2

HTTP Авторизация и безопасность

Re: HTTP Авторизация и безопасность

Добрый день!

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

Спасибо за уведомление и содействие. Когда будет исправлено, дополнительно здесь на форуме сообщим.

Diana Cheley
Wialon Hosting Expert
Gurtam
3

HTTP Авторизация и безопасность

Re: HTTP Авторизация и безопасность

У себя сделал через каптчу, чего и вам рекомендую smile
Примерl

11010000 10010100 11010001 10000011 11010000 10111100 11010000 10110000 11010001 10000010 11010001 10001100 100000 101101 100000 11010001 10001101 11010001 10000010 11010000 10111110 100000 11010000 10111111 11010001 10000000 11010000 10111000 11010000 10111010 11010000 10111110 11010000 10111011 11010001 10001100 11010000 10111101 11010000 10111110 100001