Как я «взломал» Qiwi без знаний программирования

Вступление


Снова всем привет.
На этот раз статья не будет поднимать «сурьезные» вопросы.
Это будет рассказ о том, как не зная программирования, но будучи достаточно смекалистым и внимательным, можно найти серьезную уязвимость, которая, к примеру, позволит вам списать все деньги со счета, имея лишь логин и пароль к нему (читай, обойти двухфакторную аутентификацию или же подтверждение по смс).

В данный момент Qiwi уже благополучно ее залатали, так что я буду стараться подкреплять объяснения современными скриншотами, иногда поясняя, как это выглядело 2.5 года назад.

Теперь к делу


Допустим, у вас есть логин: пароль к чужому кошельку Qiwi.
Допустим, там лежит 100к рублей.
И вы оооочень хотите завладеть ими.
Но просто так списать деньги нельзя — нужно подтверждение по СМС.
Но мы же смышленые, нас это не остановит.

Шаг 1. Логинимся в аккаунт и создаем там виртуальную карту.
Видим такую картину

acgcsqo1opxni2aprzdntxhkq14.png

Выглядит так, будто у нас очень мало информации. Всего 4 последние цифры карты и время действия карты.
Но раньше там было 6 (!) последних цифр карты. То есть были неизвестны еще 10 цифр.
А нам нужны все цифры карты. Где взять еще? Очень просто.
У всех карт есть BIN — первые 6 цифр карт определенного банка одного типа должны быть одинаковы.

Шаг 2. Лезем в браузер и гуглим «Qiwi BIN»

Сразу же узнаем, что бин — 489049.
И вот у нас уже есть 12 цифр! Осталось всего 4!

Но вот здесь наступает сложность.
Эти 4 цифры нигде не мелькают и, казалось бы, добыть их негде.
Но, конечно, если хорошо постараться, то найти можно :)

Шаг 3. Находим последние недостающие 4 цифры

Для этого нам потребуется иметь аккаунт в Qiwi с 1000р и знать, что такое Алгоритм Луна.
Давайте по порядку.
Если открыть любую операцию в Qiwi, то там показывает дату платежа и номер квитанции.
Может быть некоторые уже догадались, зачем нам 1к на счету.
Да, мы будем подставлять по порядку цифры вместо тех неизвестных 4х цифр, которые остались неизвестными и отсылать на эти номера карт по рублю!
И при одной из операций мы получим входящий 1р на тот счет, где лежат заветные 100к рублей.
Останется только сопоставить время отправки денег.
Раньше можно было сопоставить номера операций, но сейчас это скрыли. И правильно сделали.
А теперь самые внимательные скажут, что вообще-то 4 цифры — это 10к операций, а не 1к. Значит нужно 10к рублей и очень много времени, чтобы так найти нужные 4 цифры.
И это не совсем так. Представляю вам Алгоритм Луна!

Алгоритм Лу́на (англ. Luhn algorithm) — алгоритм вычисления контрольной цифры номера пластиковой карты в соответствии со стандартом ISO/IEC 7812. Не является криптографическим средством, а предназначен в первую очередь для выявления ошибок, вызванных непреднамеренным искажением данных (например, при ручном вводе номера карты, при приёме данных о номере социального страхования по телефону). Позволяет лишь с некоторой степенью достоверности судить об отсутствии ошибок в блоке цифр, но не даёт возможности нахождения и исправления обнаруженной неточности.

Если очень интересно — гуглите, а я расскажу вкратце об алгоритме и чем он нам поможет.
Этот алгоритм позволяет подтвердить, валиден ли номер карты. То есть, прогнав наши 10к вариантов через этот алгоритм, можно оставить только номера потенциально существующих карт. Догадаетесь сколько таких будет?
Верно, ровно 1к.

Конечно, это все кажется очень запарно делать вручную, но что мешает сделать простой скрипт для генерации этих самых 1к вариантов?
Вот вам примеры реализации с Википедии:

Пример Алгоритма Луна на JS
function luhnAlgorithm(digits) {
  let sum = 0;

  for (let i = 0; i < digits.length; i++) {
    let cardNum = parseInt(digits[i]);

    if ((digits.length - i) % 2 === 0) {
      cardNum = cardNum * 2;

      if (cardNum > 9) {
        cardNum = cardNum - 9;
      }
    }

    sum += cardNum;
  }

  return sum % 10 === 0;}

Пример Алгоритма Луна на PHP
function luhnAlgorithm($digit)
{
    $number = strrev(preg_replace('/[^\d]/', '', $digit));
    $sum = 0;
    for ($i = 0, $j = strlen($number); $i < $j; $i++) {
        if (($i % 2) == 0) {
            $val = $number[$i];
        } else {
            $val = $number[$i] * 2;
            if ($val > 9)  {
                $val -= 9;
            }
        }
        $sum += $val;
    }
    return (($sum % 10) === 0);
}

Теперь нам нужно перебрать эти 1к вариантов методом, который я описал выше.
И вуаля — мы получили последние 4 цифры.
Теперь у нас есть полный код карты и ее срок действия.
Конечно, у нас нет CVV кода (тот, который на обратной стороне пишут), но в некоторых местах он и не нужен.
Например Amazon!
Да, заходим на Амазон и заказываем с помощью новоиспеченных данных что угодно.
Например Steam коды на деньги или типа того. В общем что-то электронное, чтобы это быстро продать в интернете. Мы немного потеряем в деньгах, но не более 20%, скорее всего.
Вот и все! Получили +79к профита!

Не забываем, что это уже не работает!

Но если вы найдете что-то похожее — сообщайте Qiwi, они (надеюсь) исправят.
Я выложил это чтобы показать, что можно находить прикольные вещи и дыры безопасности даже не умея программировать. И для общего развития.

Всем удачи :)

© Habrahabr.ru