Прорыв в неведомое. #1
Joe Pesci"Нам свойственно бояться неведомого потому, что с тем что нам известно мы уже научились справляться." (Джулиана Вильсон)
Ты работаешь в 21 веке. Тебе не обязательно знать все о своём ремесле, но ты постоянно должен узнавать о новых возможностях, которые когда-то помогут тебе решить неизвестно-сложную задачу довольно быстро и достаточно легко.
Приступил писать проект, но вдруг понял, что не знаешь как в запросе появляется тот или иной параметр? Начал искать, но нашел только непонятную JS-функцию, которую х*й знает как присрать в свой проект на С# (в лучшем случае)? Эти рекламные предложения можно продолжать сколь угодно долго, но суть ты уловил и теперь мы можем приступить к делу.
Хотя нет, давай еще раз определимся для чего будет все то, о чем пойдет речь ниже по тексту. В наше время главное быстрый тест (хотя бы на начальной стадии) и вряд ли в твои планы входит недельный реверс-инжиниринг очередной функции js или выплата МРОТ'а (100$) очередному проггеру с Kwork'a, который сделает всю работу по реверсу за тебя.
Я предлагаю тебе решение, которое поможет сделать быстрый тест, понять стоит ли тебе работать с сайтом/приложением дальше, улучшать свой код/подход и т.д.
Начнем.
JS - браузерный язык (в основном), поэтому все, что хешируется/криптуется/кодируется на клиенте (в браузере) будет сделано именно через него.
Определим подопытного, пусть это будет - OutLook
В запросе на регистрацию мы видим значение - "CipherValue".
Объяснять буду на примере его получения.
Нажимаем Ctrl+F в Fiddler и пытаемся найти, встречается ли это значение где-то еще в нашей сессии снифа и в итоге находим js файл - https://acctcdn.msauth.net/lightweightsignuppackage_RXoxV9mfeGuGCvJNsxsgXg2.js?v=1 (с течением времени эта ссылка может поменяться, главное - понять механику поиска таких значений).
Тут мы видим, что CipherValue получает значения из другой функции Encrypt
на вход которой подаются некоторые переменные, пока еще не известные нам. Давайте разбираться.
Находим функцию Encrypt и понимаем, что в нее мы передали два значения на позиции переменных n и а (Encrypt("", "", x, r.password) - с предыдущего скрина).
Просматривая данную функцию можно понять, что n - переменная, на основе которой работает switch (switch - оператор выбора). Оператор switch работает со своим другом - case, то есть, логика такая - на основе переменной n код выбирает, какую дальнейшую логику выполнять функции.
Переменная а скорее всего хранит значение введенного пользователем пароля при регистрации, но мы еще проверим, на самом деле это так или нет.
Круг сузился, нам нужно явно понять, что за ребята эти n и a.
Заходим обратно в консоль разработчика и ставим точку останова на функцию Encrypt. Обратите внимание, что на панели справа точка останова должна отобразиться! Когда вы убедились, что все сделали верно - перезагружаем страничку и начинаем ручной процесс регистрации аккаунта в браузере, вводим желаемый логин для почты, пароль, дату рождения, имя и фамилию, в общем все, что от вас требуется.
Опачки! Точка останова отработала:)
Мы видим, что в функцию пришли два непустых значения - "newpwd" (что является switch для функции) и "JoeAtWork!" (что является моим паролем).
Круг снова сузился и теперь мы понимаем, что при регистрации мы попадаем в данный case, но, однако - на этом дело не заканчивается. Пароль пользователя передается в следующую функцию PackageNewPwdOnly - смотрим что там.
Что именно происходит в этой функции - нам пока неинтересно, да и вряд ли станет.
Теперь давайте по порядку.
Мы знаем, что мы попали в case "newpwd" и получили какое-то значение (1)
Знаем, что (2) и (3) что-то неизвестное, но то, что нам обязательно нужно.
Точно знаем, что функция Encrypt возвращает значение переменной o - в которой явно хранится CipherValue. (4)
Используя текущую точку останова посмотрим, что хранится в переменных Key и randomNum. Нажимаем на стрелочку "Step into nextfunction call" (отмечена красным кружком в правом верхнем углу).
Видим значение переменной Key (значение статичное)
А вот значение randomNum - вряд ли будет статичным.
Но, в целом, если мы также поищем эти значения в сессии снифа Fiddler'a, то поймем, что эти значения просто так лежат на странице.
<script type="text/javascript"> var Key="e=10001;m=abef72b26a0f2555...";
var randomNum="4882B0607F82D10C34430BFD404ADEB..."
var SKI="4B8F32B06B3633468A617C4D5781E6B3....";</script>
Первый этап закончен.
Мы знаем, какая функция нам нужна, а так же знаем какие данные на вход ей подавать. Работаем дальше или ты уже устал, цумбучок?
Мой канал в Telegram - https://t.me/joebackstage