Взламываем шоп по продаже СС

Взламываем шоп по продаже СС

Темная Сторона

Думаю многим хоть раз было интересно, каким же все-таки способом люди опустошают целые шопы. На анализ был дан код магазина по продаже сс. Нужно было выяснить, каким путем были уведены из шопа деньги.

После анализа, оказалось, что способов украсть бабки достаточно много. И описывать каждый из них - дело долгое и неблагодарное. Поэтому я сделал "кратенький" отчет в достаточно упрощенной форме, который вы и имеете удовольствие читать в данный момент.


Forced Browsing & Leak info

После того, как я развернул локальную копию сайта, я собрал структуру файлов/папок и просканировал ее с помощью Burp Intruder. И практически сразу - наиудивительнейшие открытия.

При простом обращении к файлам:

  • ./core/1.php
  • ./core/3.php

Мы можем увидеть следующее:

Не так важно раскрытие пути, это практически ничего не дает (SQL-инъекций и LFI нету). На скриншоте замазано значение key из массива. Забегая вперед, для работы с сервисом, который предоставляет карты для продажи, нужно знать только API-ключ и url куда отправлять запросы. И вот key - это то самое значение API-ключа. Т.е. для человека, который знает, как делать шопы привязанные к конкретному API, достаточно знать только этот ключ, для того, чтобы слить баланс шопа.

Файл ./core/4.php позволяет делать поиск доступных городов по штатам:

Файлы: ./core/chat/show.php и ./core/chat/messages.txt отображают содержимое чата. Т.е. можно читать, о чем пишут в чатике, не заходя в магазин и даже не регистрируясь.


Активная XSS и прочие веселья в чате

Взглянем на содержимое файла ./core/chat/send.php:

<?php
require 'config.php'; 
$sender = trim($_POST['sender']);
$text = trim($_POST['message']);


PHP:

<?php
require 'config.php';
$sender = trim($_POST['sender']);
$text = trim($_POST['message']);
$date = date("H:i:s d.m.Y", time());
if($sender == 'admin'){$admin_sender = 'style="color:red";';}
$message = '<br <span style="color: #ccc">'.$date.'</span> <b '.$admin_sender.'>'.$sender.':</b> '.$text; $file = fopen($filename, 'a');
fwrite($file, $message);
fclose($file);

Мы видим, что во первых - не нужно даже быть зарегистрированным, чтобы отправить сообщение. А во вторых - нет проверки, что именно тот пользователь что указан в sender и отправил сообщение.

Достаточно отправить post-запрос с параметрами sender и message:
И мы можем увидеть в чате:

Но нам этого недостаточно. Попробуем отправить html-код.

В качестве параметров указываем:

HTML:

sender=kroba&message=hello+world!<script>alert(document.cookie)%3b</script>
Заходим в магазин:

Имеем активную XSS, которая дает нам кучу возможностей. Например, можно повесить простенький веб-сниффер. А так как по умолчанию сессионные куки не имеют флага httponly, то мы можем украсть куки любого посетителя магазина, в том числе и админа. Подставляем куки себе и заходим.


Брутфорс и подбор логинов пользователей

Немного отвлечемся и обратим наше внимание на форму логина.

Сразу можем отметить, что нет капчи - можно брутить сколько угодно.

Попробуем зайти под заведомо несуществующим пользователем abcdef1234567890

Как видите, перед тем как брутфорсить, мы можем точно определить, зарегистрирован пользователь или нет. Более того, обращаясь к файлу./core/chat/show.php можно собрать логины пользователей, не привлекая внимания.

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


Активная XSS при регистрации пользователя

Попробуем зарегистрировать пользователя:

В качестве логина указываем следующую строку:

hacker" class="btn btn-warning"><script>alert(document.cookie)</script><input type="hidden" kek="
И теперь, когда admin зайдет на страницу пользователей

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


Тикеты с XSS

Создаем тикет
Админ открывает тикет, чтобы прочитать и...

Опять таки, угоняем куки, подставляем себе и т.д.


Делаем свой аккаунт админом

Используя украденные куки админа, заходим в шоп, выбираем пункт "пользователи", выбираем заранее зарегистрированный нами аккаунт и меняем баланс на тот, который нас более устраивает:

Великолепно. Но это совсем не всё, на что мы можем влиять. Если посмотрим в html-код страницы, то можем увидеть:

Как мы видим, часть функционала убрали в комментарии. Но нам ничто не мешает просто отредактировать html с помощью firebug или другого подобного инструмента. Вдобавок, мы допишем еще один пункт в меню:

Жмем OK, заходим под пользователем l33t_hacker:

Мы не только добавили денег на баланс, но и расширили свои полномочия.

Теперь мы можем красть деньги не привлекая внимания:

  1. находим пользователей с большим балансом
  2. запоминаем баланс
  3. удаляем пользователя
  4. регистрируемся с таким же ником
  5. ставим кол-во денег, как у прошлого пользователя

И никаких подозрений - сколько занесли пользователи, столько мы и тратим. К тому же, мы можем свободно редактировать любые статьи в магазине. И можем добавить еще парочку активных xss, так сказать впрок.


Ошибка в логике: покупаем сс по своей цене

Допустим, админ редко заходит в магазин, везде пользуется noscript или поставил флаг httponly у сессионных cookie. Выходит, что у нас нет возможности стырить его куки, а вот получить пачку свежих сс и при этом заплатить как можно меньше - очень хочется. Что же делать?

Алгоритм действий простой.

Включаем burp suite. Добавляем в корзину карту, которую хотим купить. Сохраняем http-запрос добавляющий карту:

Теперь переходим в корзину и удаляем карту из корзины. Повторяем запрос, но меняем последнее значение:

Обновляем страницу с корзиной:

Такая цена нас уже устраивает. Но всегда хочется еще чего-то большего. Вместо "0.0001" поставим "-1000000":

Еще лучше, да и после покупки в плюсе остаемся!


Ошибка в логике: баланс * кол-во сессий = профит

Даже если закрыть уязвимость, связанную с изменением цены, остается возможность покупать карты, загоняя баланс в минус. Взглянем на код скрипта ./components/com_shop/shop.php, а именно, на функцию buy():

Код:

function buy(){
    if(count($_SESSION['shop']['product']) >= 1){
          
          if($_SESSION['shop']['total_sum'] > $_SESSION['user_info']['balance']){
            header("Location: /");
            exit;
        }
        //////////////////
        // пропускаем
        //////////////////
        $sql  = 'UPDATE `'.DB_PREFIX.'users` SET `balance` = `balance` - '.$_SESSION['shop']['total_sum'].' WHERE `id` = ?';           
        $user_balance = DB::prepare($sql)->execute([$_SESSION['user_info']['id']]);
        //////////////////
        // пропускаем
        //////////////////
 
      }
}

Нам разрешают покупать, если сумма покупки меньше, чем баланс пользователя. При этом и сумма покупки и баланс хранятся в сессии. Далее, после покупки баланс в БД меняет значение. Но (!) непосредственно перед покупкой нет проверки на то, сколько в данный момент в самой БД у пользователя денег.


Поэтому возможен такой трюк:

  1. Открываем 5 разных браузеров
  2. В каждом браузере заходим в один и тот же аккаунт, на котором лежит, к примеру, 100 баксов.
  3. В каждом браузере добавляем в корзину разных карт на 100$.
  4. В каждом браузере переходим на страницу с оплатой.
  5. В каждом браузере нажимаем "Buy".
  6. Получаем карт на 500$ и аккаунт, загнанный в -400$
  7. Регаем новый аккаунт, добавляем 100 баксов на счет.
  8. Повторяем пункты 1-7.

При этом кол-во браузеров может быть не 5, а 50. Или 500

В принципе, всего вышеописанного достаточно, чтобы составить общее впечатление о коде. Я не упоминал мелкие баги, типа reflected XSS, раскрытие путей и ошибки, связанные с функционалом, который был запрятан куда подальше.

Черный Рынок - название говорит само за себя. Оригинальная одежда и техника за половину стоимости.

Гражданская Оборона - самооборона от А до Я, обзоры травматического и огнестрельного оружия, самозащита в физическом и юридическом планах.

Дурман - наркотики и их медицинское употребление, увлекательные трип-репорты, виды веществ, их свойства и последствия употребления.


Report Page