Всем привет, сегодня поговорим о реверс-инжиниринге и о способах применения. (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 для пожертвований по карте, думаю будет интересно.
webad11, у меня самого уровень андроид реверса на уровне "повседневный", "посредственный", но все же попробуй. посредственный имеется в виду, что я использую андроид софт, типа апк клонера и канарейки для реверса)
пару месяцев назад реверсил debank там конечно по сложнее было wasm файл в js был (декомпилировал его в понятный текст - но он очевидно все еще был нереально большой человек не разобрался-бы), купил подписку на chatgpt (неслабо так сам попотел, GPT смог дать рабочий код после кучу попыток прочитав длинный файл) без тоны моих сил и подписки не смог бы реверснуть (ну а у тебя да самый легкий пример - искать не нужно + нет wasm, просто скинуть код на скрине GPT и сказать "перепиши на норм js" и всё)
Aisan, я еще раз повторяю: "была в разделе «статьи», но там не только авторки постятся" когда уже это ошибочное мнение пропадет у людей
Отошёл с бана, как понял многим показалась слишком лёгкая тема. Есть в предложениях сделать реверс шлюза пожертвований ЮMoney, как вам идея?