Прорыв в неведомое. #1

Прорыв в неведомое. #1

Joe Pesci


"Нам свойственно бояться неведомого потому, что с тем что нам известно мы уже научились справляться." (Джулиана Вильсон)


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


Приступил писать проект, но вдруг понял, что не знаешь как в запросе появляется тот или иной параметр? Начал искать, но нашел только непонятную JS-функцию, которую х*й знает как присрать в свой проект на С# (в лучшем случае)? Эти рекламные предложения можно продолжать сколь угодно долго, но суть ты уловил и теперь мы можем приступить к делу.

Хотя нет, давай еще раз определимся для чего будет все то, о чем пойдет речь ниже по тексту. В наше время главное быстрый тест (хотя бы на начальной стадии) и вряд ли в твои планы входит недельный реверс-инжиниринг очередной функции js или выплата МРОТ'а (100$) очередному проггеру с Kwork'a, который сделает всю работу по реверсу за тебя.

Я предлагаю тебе решение, которое поможет сделать быстрый тест, понять стоит ли тебе работать с сайтом/приложением дальше, улучшать свой код/подход и т.д.

Начнем.
JS - браузерный язык (в основном), поэтому все, что хешируется/криптуется/кодируется на клиенте (в браузере) будет сделано именно через него.


Определим подопытного, пусть это будет - OutLook

В запросе на регистрацию мы видим значение - "CipherValue".
Объяснять буду на примере его получения.

Запрос на регистрацию в OutLook

Нажимаем Ctrl+F в Fiddler и пытаемся найти, встречается ли это значение где-то еще в нашей сессии снифа и в итоге находим js файл - https://acctcdn.msauth.net/lightweightsignuppackage_RXoxV9mfeGuGCvJNsxsgXg2.js?v=1 (с течением времени эта ссылка может поменяться, главное - понять механику поиска таких значений).

Тут мы видим, что CipherValue получает значения из другой функции Encrypt
на вход которой подаются некоторые переменные, пока еще не известные нам. Давайте разбираться.

CipherValue - начало


Находим функцию Encrypt и понимаем, что в нее мы передали два значения на позиции переменных n и а (Encrypt("", "", x, r.password) - с предыдущего скрина).

Просматривая данную функцию можно понять, что n - переменная, на основе которой работает switch (switch - оператор выбора). Оператор switch работает со своим другом - case, то есть, логика такая - на основе переменной n код выбирает, какую дальнейшую логику выполнять функции.

Переменная а скорее всего хранит значение введенного пользователем пароля при регистрации, но мы еще проверим, на самом деле это так или нет.

Круг сузился, нам нужно явно понять, что за ребята эти n и a.

Функция Encrypt


Заходим обратно в консоль разработчика и ставим точку останова на функцию Encrypt. Обратите внимание, что на панели справа точка останова должна отобразиться! Когда вы убедились, что все сделали верно - перезагружаем страничку и начинаем ручной процесс регистрации аккаунта в браузере, вводим желаемый логин для почты, пароль, дату рождения, имя и фамилию, в общем все, что от вас требуется.

Точка останова в функции Encrypt

Опачки! Точка останова отработала:)
Мы видим, что в функцию пришли два непустых значения - "newpwd" (что является switch для функции) и "JoeAtWork!" (что является моим паролем).

Получение объекта в функции Encrypt

Круг снова сузился и теперь мы понимаем, что при регистрации мы попадаем в данный case, но, однако - на этом дело не заканчивается. Пароль пользователя передается в следующую функцию PackageNewPwdOnly - смотрим что там.

Нужный нам case - newpwd
Функция PackageNewPwdOnly

Что именно происходит в этой функции - нам пока неинтересно, да и вряд ли станет.

Теперь давайте по порядку.

Мы знаем, что мы попали в case "newpwd" и получили какое-то значение (1)
Знаем, что (2) и (3) что-то неизвестное, но то, что нам обязательно нужно.
Точно знаем, что функция Encrypt возвращает значение переменной o - в которой явно хранится CipherValue. (4)

Начинаем понимать логику всего происходящего

Используя текущую точку останова посмотрим, что хранится в переменных Key и randomNum. Нажимаем на стрелочку "Step into nextfunction call" (отмечена красным кружком в правом верхнем углу).

Step into next function call

Видим значение переменной Key (значение статичное)

Значение переменной Key

А вот значение randomNum - вряд ли будет статичным.

Значение переменной 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

Report Page