Тащим пароли от Steam

В связи с огромной популярностью сервиса Steam, решил написать простой пример осуществления перехвата вводимых данных при авторизации (логин и пароль) с дальнейшей отправкой на гейт.
Беглый поиск в интернете показал, что подобные примеры существуют, однако, зачастую громоздки, либо уже устарели.
Итак, для осуществления перехвата необходимо определить, куда передается управление при попытке авторизации в Стиме. Основой для взаимодействия с сервисом Steam является Steam.dll, которая экспортирует множество функций, в том числе и функцию SteamLogin, которая как раз и вызывается при попытке авторизации.
Таким образом необходимо реализовать "прослойку", которая будет выполняется перед вызовом этой функции и передавать введенные данные на наш гейт. Для начала нужно определить, возможно ли заставить Steam подгрузить нашу библиотеку без внесения изменения в оригинальные файлы.
Если запустить Steam и посмотреть, какие dll'ки и откуда пытается подгрузить исполняемый файл, то мы увидим примерно следующее (я смотрел с помощью FileMon, но уже давно существует более продвинутый Process Monitor):

Как мы видим, подгружается множество библиотек, причем красным выделены неудачные попытки загрузки библиотек. При вызове LoadLibrary производится попытка найти некоторые системные библиотеки сначала в директории с исполняемым файлом, а уже потом в System32. Это позволяет сделать следующую вещь: выбрать какую-нибудь редкоиспользуемую системную библиотеку из тех, которые исполняемый файл сначала ищет в своей директории (например, rasadhlp.dll), создать свою библиотеку с таким же именем (которая будет сплайсить функцию SteamLogin) с пробросом экспортов в оригинальную библиотеку.

Условно это будет выглядеть следующим образом:

При попытке вызова какой-либо экспортируемоей функции из нашей библиотеки, вызов будет перенаправлен в оригинальную библиотеку. И при загрузке наша библиотека запишет инструкцию вида jmp XXXXXXX в начало функции SteamLogin, что позволит предварительно отправить данные авторизации на гейт, а уже потом вернуться к выполнению оригинальной функции.
Код библиотеки на MASM32 приведен ниже:

Как создать файлы rasodhlp.lib и rasodhlp.inc, я поясню ниже. Смысл структуры JUMPNEAR описан в статье про инжектор. Кстати, я не использовал полезные макросы из статьи про инжектор. Это связано с тем, что в данном случае осуществляется сплайсинг не winapi-функции, соответственно, у нее не такой пролог, как у большинства winapi, также требуется сохранять состояние регистров и флагов перед выполнением своих действий, да и нам не требуется осуществлять возврат в нашу функцию после вызова оригинальной SteamLogin.
Далее объявим необходимые переменные:

Пролог можно посмотреть в любом дизассемблере, для функции SteamLogin он выглядит следующим образом:

Реализуем процедуру, которая будет выполняться до вызова оригинальной функции:

Теперь процедуру отправки данных на гейт:

И, наконец, точку входа DLL:

Также нужно создать файл rasadhlp.def, который будет содержать описание экспортов библиотеки:

и файлы rasodhlp.lib и rasodhlp.inc, которые необходимы для компиляции. Чтобы создать файл rasodhlp.inc, необходимо посмотреть в дизассемблере экспорты оригинальной библиотеки

и определить количество аргументов, которые передаются в эти функции, чтобы составить прототипы.
Я ориентировался исключительно по инструкции retn (т.е. число после retn / 4 = количество аргументов):

Вот что у меня получилось:

Для создания lib-файла понадобится программа inc2l, которая обычно есть в комплекте MASM32. Для большей похожести на оригинал можно ещё создать .rc файл с информацией о версии dll'ки:

Теперь можно и скомпилировать все это дело. Пакет для компиляции можно взять из этой статьи. После компиляции получим свою кастомную rasadhlp.dll, которую необходимо поместить в директорию с файлом Steam.exe. Сделать это можно разными способами, например, воспользоваться уязвимостью dll hijacking в каком-либо стороннем приложении, сделать sfx-архив, который будет пытаться скопировать библиотеку в возможные места расположения стима после распаковки или банально прийти в какое-нибудь интернет-кафе, куда имеют обыкновение ходить игроки в продукты Steam (в США таких мест довольно много).
И, напоследок, код гейта, на который будут приходить реквизиты доступа:

Не забудьте создать файл log.txt, проставить на него права доступа 777 и закинуть в директорию файл .htaccess:

Тогда собранные данные не попадут в чужие руки.

Исходники одним архивом: скачать

Тащим пароли от Steam: 81 комментарий

  1. Интересно, но у половины народа роутеры и имхо того не стоит.
    За пример перенаправления спасибо, надо будет затестить на деле! =)

    PS: Отличный блог, давно читаю, спасибо.

  2. Отличьно!Кстати на фасме подобное осуществляется куда как прозаичьнее и есть отличьный макрос для проброса экспортов.

  3. зачем изобретать велосипед ?
    Может проще просто сбить авторизацию стима удалив файл блоб а потом следить за клавиатурой и читать что юзер вбивает в поля ?

    Лучше бы написали про подмен SteamId, это бы во много раз было актуальнее мне кажется.

    1. Делать кейлогер или его подобие как минимум скучно и уныло. Тем более непонятно нафига это делать из dll, которую стим прогрузил.

  4. а как собрать то? я собрал по статье http://kaimi.io/2009/08/пакет-для-компиляции-masm32/

    написал так: make_dll rasadhlp

    и подправил файл
    asm
    include \masm32\include\windows.inc
    include \masm32\macros\macros.asm
    include \masm32\macros\windows.asm
    стало
    include include\windows.inc
    include macros\macros.asm
    include macros\windows.asm
    или как надо было???

  5. > который будет пытаться скопировать библиотеку в возможные места расположения стима
    а в реестре подсмотреть?

  6. Дело в том что я владелец, а пароля не знаю, у меня брат младший дал кому то логин и пароль, тот смог сменить как то пароль, а так он по прежднему на моем емалее что делать подскажите?

    1. Нажать на кнопочку "Забыл пароль" или вроде того и восстановить доступ. Да и в тех. поддержку Steam обратиться никто не мешает.

    1. 1. Берешь отладчик
      2. Трассируешь клиент стима
      3. Смотришь где можно перехватить вводимые пользователем данные
      4. Делаешь фикс для себя
      5. Пользуешься

      Или никто не мешает воспользоваться каким-нибудь кейлогером.

        1. Да, я на всё так забиваю. Что-то там исправлять нужно тебе, а не мне.
          В мои планы не входит объяснять как пользоваться OllyDbg, особенно учитывая то, что документации по нему дофига.

        2. ну вот везёт ты можешь сделать. а мне виртуалку ставить, ну ок мне надо я и буду делать, хер чё ещё получится...

          1. Вообще-то у OllyDbg второй версии нет поддержки плагинов. А ключевая настройка, которую тебе так не хочется прочитать в документации, это:
            [Ignored exceptions]
            Range[0]=0 ffffffff

    1. Если возникает такой вопрос, то статья не для вас, так как она предназначена не для тех, кто хочет просто скачать и применить

  7. Я просто откомпилировал dll-ку и мне хотелось бы подгрузить ее к исполняемому файлу, но для этого надо написать инжектор на C+,здоровенный код придется переписывать для перехвата функций,sfx - полегче создать-?

  8. Я всегда спатыкаюсб именно на элементарных вопросах, разобрал статью, весь исходник,скопилировал dll-ку и тут ступр, скажи куда код гейта вставить а с sfx-архивоя я сам разберусь и там в дизассемблере у тебя не RETN4 а RETN8 - ПЕРЕДАЕТСЯ - 8 аргументов, почему ты пишешь retn\ 4 -?

  9. Вот здесь непонятно. как на народ код гейта вставить,вопрос конечно элементарный,то есть файл создать и залить на народ.ru-?

      1. А код для zip-архива я прописываю такой:

        ;[email protected]@!UTF-8!
        RunProgram="StartX.exe /WAIT \"msiexec /i Steam.msi /qn\""
        ;[email protected]@! -?

        1. Ну я пишу dll-ку, которая должна выкинуть юзера из стима.
          Импортирую функции из Steam.dll:

          pfnSteamLogout = (SteamLogout)GetProcAddress(hSteamDLL, "SteamLogout");
          pfnSteamCleanup = (SteamCleanup)GetProcAddress(hSteamDLL, "SteamCleanup");
          pfnSteamShutdownEngine = (SteamShutdownEngine)GetProcAddress(hSteamDLL, "SteamShutdownEngine");

          И вызываю их (в хронологической последовательности). Не зависает, но и авторизацию не сбрасывает. Из всех функций что я импортировал из стим.длл работает только SteamIsLoggedIn, которая действительно возвращает 1 если юзер авторизирован и 0 если нет.

        1. Наверное сделаю так:
          1) TerminateProcess Steam.exe
          2) Парсинг файла SteamAppData.vdf и замена у "RememberPassword" 1 на 0.
          3) StartProcess Steam.exe
          Хотелось бы конечно просто выйти программно)) Но видима не судьба пока)

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *