Всем привет, сегодня поговорим о реверс-инжиниринге и о способах применения. (WEB) Что такое реверс-инжиниринг? Для начала расскажу вам что такое реверс-инжиниринг Надеюсь с этим понятно, теперь уточним в каких случаях нам это выгодно 1. Получить доступ к закрытым данным сайта 2. Использовать функционал сайта в своих целях (пример автоматизация) 3. Поиск уязвимостей сайта Практика Теперь перейдём к самому главному, пример я буду показывать на реальном сайте ИИ для генерации фото Для начала находим жертву, в идеале для такой работы нужен сайт не требующий авторизацию (мне нужен вариант где мои запросы не будут лимитироваться) Конечно же авторизация совсем не проблема, просто в ИИ где она есть - есть лимит на запросы, нам такое не подходит. Так-же стоит учитывать что есть сайты с лимитами на запросы с одного IP, в таком случае понадобятся ******. Я нашёл себе такой вариант - тык Заходим на страницу с нужной нам функцией, в моём случае - страница для генерации фото: Вводим какой-то рандомный промпт, открываем панель разработчика в браузере (F12) Переходим во вкладку сеть, нажимаем на сайте кнопку "Generate" Сайт выполнит запрос генерации, останется лишь его найти среди лишнего мусора В моём случае оказался такой простенький запрос на: https://api.deepai.org/api/text2img С form-data: text: rain image_generator_version: standard use_old_model: false turbo: true genius_preference: classic Переходим во вкладку "отклик", видим ответ от запроса: { "id": "b98f64a8-2115-411f-8a1e-ea51a1b6306f", "output_url": "https://api.deepai.org/job-view-file/b98f64a8-2115-411f-8a1e-ea51a1b6306f/outputs/output.jpg?art-image=true", "share_url": "https://images.deepai.org/art-image/eb7ef3a779a649439a2df45f32e9321a/rain-24b213.jpg" } JS { "id": "b98f64a8-2115-411f-8a1e-ea51a1b6306f", "output_url": "https://api.deepai.org/job-view-file/b98f64a8-2115-411f-8a1e-ea51a1b6306f/outputs/output.jpg?art-image=true", "share_url": "https://images.deepai.org/art-image/eb7ef3a779a649439a2df45f32e9321a/rain-24b213.jpg" } Делаем вывод что данный запрос и отвечает за генерацию, отвечает сразу же ссылкой на изображение, очень удобно) Пытаемся повторить тот же запрос в node.js, облом, сервис требует API ключ Да, и вправду, в headers данного запроса отправляется Api_Key Казалось бы, взяли ключ, вставили и все рады, но нет. При каждом запросе API отправляет разные ключи, в чём же дело Отправляемся во вкладку "Инициатор" этого запроса Начинаем копаться в JS коде сайта, все инициаторы кликабельные, при нажатии можно увидеть функцию. Недолго покапавшись - находим замечательную функцию: Как раз она и отвечает за генерацию ключа, кстати нам разработчик оставил пасхалку в его коде) Переводим эту строку в код, подправляем под себя, в моём случае я решил на node.js const axios = require('axios'); const FormData = require('form-data'); // Generate a unique API key const generateApiKey = () => { let userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'; var myrandomstr = Math.round((Math.random() * 100000000000)) + ""; var myhashfunction = function () { for (var a = [], b = 0; 64 > b;) { a[b] = 0 | 4294967296 * Math.sin(++b % Math.PI); } return function (c) { var d, e, f, g = [d = 1732584193, e = 4023233417, ~d, ~e], h = [], l = unescape(encodeURI(c)) + "\u0080", k = l.length; c = --k / 4 + 2 | 15; for (h[--c] = 8 * k; ~k;) { h[k >> 2] |= l.charCodeAt(k) << 8 * k--; } for (b = l = 0; b < c; b += 16) { for (k = g; 64 > l; k = [f = k[3], d + ((f = k[0] + [d & e | ~d & f, f & d | ~f & e, d ^ e ^ f, e ^ (d | ~f)][k = l >> 4] + a[l] + ~~h[b | [l, 5 * l + 1, 3 * l + 5, 7 * l][k] & 15]) << (k = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21][4 * k + l++ % 4]) | f >>> -k), d, e]) { d = k[1] | 0; e = k[2]; } for (l = 4; l;) { g[--l] += k[l]; } } for (c = ""; 32 > l;) { c += (g[l >> 3] >> 4 * (1 ^ l++) & 15).toString(16); } return c.split("").reverse().join(""); } }(); return 'tryit-' + myrandomstr + '-' + myhashfunction(userAgent + myhashfunction(userAgent + myhashfunction(userAgent + myrandomstr + 'i_am_a_smelly_hacker_yes_i_am'))); }; // Function to generate image const generateImage = async (text, negativePrompt = '') => { let userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'; const apiKey = generateApiKey(); const url = 'https://api.deepai.org/api/text2img'; // Create a FormData instance const form = new FormData(); form.append('text', text); if (negativePrompt) form.append('negative_prompt', negativePrompt); form.append('image_generator_version', 'hd'); form.append('use_old_model', 'false'); // Ensure it's a string form.append('quality', 'true'); // Ensure it's a string try { const response = await axios.post(url, form, { headers: { ...form.getHeaders(), // Important: include the form headers 'api-key': apiKey, 'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Accept-Language': 'ru,en;q=0.9,en-GB;q=0.8,en-US;q=0.7', 'User-Agent': userAgent, } }); console.log('Response data:', response.data); // Return only the share_url return response.data.share_url; } catch (error) { console.error('Error:', error.response ? error.response.data : error.message); throw error; // Rethrow the error for further handling } }; // Export the module module.exports = { generateImage }; JS const axios = require('axios'); const FormData = require('form-data'); // Generate a unique API key const generateApiKey = () => { let userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'; var myrandomstr = Math.round((Math.random() * 100000000000)) + ""; var myhashfunction = function () { for (var a = [], b = 0; 64 > b;) { a[b] = 0 | 4294967296 * Math.sin(++b % Math.PI); } return function (c) { var d, e, f, g = [d = 1732584193, e = 4023233417, ~d, ~e], h = [], l = unescape(encodeURI(c)) + "\u0080", k = l.length; c = --k / 4 + 2 | 15; for (h[--c] = 8 * k; ~k;) { h[k >> 2] |= l.charCodeAt(k) << 8 * k--; } for (b = l = 0; b < c; b += 16) { for (k = g; 64 > l; k = [f = k[3], d + ((f = k[0] + [d & e | ~d & f, f & d | ~f & e, d ^ e ^ f, e ^ (d | ~f)][k = l >> 4] + a[l] + ~~h[b | [l, 5 * l + 1, 3 * l + 5, 7 * l][k] & 15]) << (k = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21][4 * k + l++ % 4]) | f >>> -k), d, e]) { d = k[1] | 0; e = k[2]; } for (l = 4; l;) { g[--l] += k[l]; } } for (c = ""; 32 > l;) { c += (g[l >> 3] >> 4 * (1 ^ l++) & 15).toString(16); } return c.split("").reverse().join(""); } }(); return 'tryit-' + myrandomstr + '-' + myhashfunction(userAgent + myhashfunction(userAgent + myhashfunction(userAgent + myrandomstr + 'i_am_a_smelly_hacker_yes_i_am'))); }; // Function to generate image const generateImage = async (text, negativePrompt = '') => { let userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'; const apiKey = generateApiKey(); const url = 'https://api.deepai.org/api/text2img'; // Create a FormData instance const form = new FormData(); form.append('text', text); if (negativePrompt) form.append('negative_prompt', negativePrompt); form.append('image_generator_version', 'hd'); form.append('use_old_model', 'false'); // Ensure it's a string form.append('quality', 'true'); // Ensure it's a string try { const response = await axios.post(url, form, { headers: { ...form.getHeaders(), // Important: include the form headers 'api-key': apiKey, 'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Accept-Language': 'ru,en;q=0.9,en-GB;q=0.8,en-US;q=0.7', 'User-Agent': userAgent, } }); console.log('Response data:', response.data); // Return only the share_url return response.data.share_url; } catch (error) { console.error('Error:', error.response ? error.response.data : error.message); throw error; // Rethrow the error for further handling } }; // Export the module module.exports = { generateImage }; Да, да, я просто взял их же код, подправил USER-AGENT, и вот у нас идеальная функция. Таким образом мы буквально за 5 минут получили доступ к их API Конечно же статья создана в учебных целях, не стоит злоупотреблять этим, но для проверки своего кода - очень хорошо подойдёт. В данной теме я старался без воды, надеюсь всем было понятно. Удачи, хакеры
Пару месяцев назад все "специалисты" гордо писали - слишком лёгкая статья, когда я выпустил реверсинг ЮMoney - специалисты пропали.
N1C1, если будут желающие люди, тоже сделаем. Там всё не так однозначно как тут, большинство не захочет углубляться. Да и эта статья не очень то пользуется популярностью.
ПИВО47, thanks, будем постепенно подниматься к сложным темам, можем зареверсить форму ЮMoney для пожертвований по карте, думаю будет интересно.
trustmeurks, хмм, достаточно интересная тема, но инструменты по типу apktool сложно будет объяснить новичкам
пару месяцев назад реверсил debank там конечно по сложнее было wasm файл в js был (декомпилировал его в понятный текст - но он очевидно все еще был нереально большой человек не разобрался-бы), купил подписку на chatgpt (неслабо так сам попотел, GPT смог дать рабочий код после кучу попыток прочитав длинный файл) без тоны моих сил и подписки не смог бы реверснуть (ну а у тебя да самый легкий пример - искать не нужно + нет wasm, просто скинуть код на скрине GPT и сказать "перепиши на норм js" и всё)
Aisan, я еще раз повторяю: "была в разделе «статьи», но там не только авторки постятся" когда уже это ошибочное мнение пропадет у людей
Отошёл с бана, как понял многим показалась слишком лёгкая тема. Есть в предложениях сделать реверс шлюза пожертвований ЮMoney, как вам идея?