Криптографічні/Алгоритми стиснення

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Виявлення алгоритмів

Якщо в коді зустрічаються операції зсуву вправо й вліво, XOR та кілька арифметичних операцій, дуже ймовірно, що це реалізація криптографічного алгоритму. Тут буде показано кілька способів, як визначити, який алгоритм використовується, не розбираючи кожен крок.

API-функції

CryptDeriveKey

Якщо ця функція використовується, ви можете дізнатися, який алгоритм використовується, перевіривши значення другого параметра:

Перегляньте таблицю можливих алгоритмів та їхніх призначених значень тут: https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id

RtlCompressBuffer/RtlDecompressBuffer

Стискає та розпаковує заданий буфер даних.

CryptAcquireContext

Згідно з документацією: функція CryptAcquireContext використовується для отримання дескриптора конкретного контейнера ключів у межах певного криптографічного сервісного провайдера (CSP). Отриманий дескриптор використовується у викликах CryptoAPI, які працюють із вибраним CSP.

CryptCreateHash

Ініціює хешування потоку даних. Якщо ця функція використовується, ви можете дізнатися, який алгоритм використовується, перевіривши значення другого параметра:


Перегляньте таблицю можливих алгоритмів та їхніх призначених значень тут: https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id

Константи в коді

Інколи дуже просто ідентифікувати алгоритм завдяки використанню унікального значення або константи.

Якщо пошукати першу константу в Google, отримаєте таке:

Отже, можна припустити, що декомпільована функція — sha256 calculator.
Ви можете шукати будь-яку з інших констант і, ймовірно, отримаєте схожі результати.

Інформація про дані

Якщо в коді немає значущих констант, можливо, він завантажує інформацію з розділу .data.
Ви можете отримати ці дані, згрупувати перший dword і пошукати його в Google, як показано вище:

У цьому випадку, якщо шукати 0xA56363C6, можна знайти, що це пов’язано з таблицями алгоритму AES.

RC4 (Symmetric Crypt)

Характеристики

Складається з 3 основних частин:

  • Ініціалізаційний етап/: Створює таблицю значень від 0x00 до 0xFF (всього 256 байт, 0x100). Цю таблицю зазвичай називають Substitution Box (або SBox).
  • Етап перемішування: Буде проходити по таблиці, створеній на попередньому етапі (цикл з 0x100 ітерацій), змінюючи кожне значення за допомогою напіввипадкових байтів. Щоб отримати ці напіввипадкові байти, використовується ключ RC4. Ключі RC4 можуть мати довжину від 1 до 256 байт, однак зазвичай рекомендують довжину понад 5 байт. Часто ключі RC4 мають довжину 16 байт.
  • Етап XOR: Нарешті, plain-text або ciphertext XOR-ується зі значеннями, створеними раніше. Функція шифрування та дешифрування одна й та сама. Для цього виконується цикл по створених 256 байтах стільки разів, скільки потрібно. Це зазвичай впізнається в декомпільованому коді по використанню %256 (mod 256).

Tip

Щоб ідентифікувати RC4 у дизасемблері/декомпільованому коді, перевірте наявність 2 циклів розміром 0x100 (з використанням ключа), а потім XOR вхідних даних з 256 значеннями, створеними раніше в цих двох циклах, ймовірно з використанням %256 (mod 256)

Ініціалізаційний етап/Substitution Box: (Зверніть увагу на число 256, що використовується як лічильник, та на те, що в кожен з 256 місць записується 0)

Етап перемішування:

Етап XOR:

AES (Symmetric Crypt)

Характеристики

  • Використання Substitution Box’ів та таблиць для пошуку
  • AES можна відрізнити за використанням специфічних значень у таблицях пошуку (констант). Зверніть увагу, що константи можуть бути збережені в бінарнику або створені динамічно.
  • Ключ шифрування має бути ділимимим на 16 (зазвичай 32B) і зазвичай використовується IV розміром 16B.

SBox constants

Serpent (Symmetric Crypt)

Характеристики

  • Рідко зустрічається у зловмисному ПЗ, але є приклади (Ursnif)
  • Легко визначити Serpent за довжиною реалізації (надзвичайно довга функція)

Ідентифікація

На наступному зображенні зверніть увагу, як використовується константа 0x9E3779B9 (зауважте, що ця константа також використовується іншими криптоалгоритмами, наприклад TEA — Tiny Encryption Algorithm).
Також зверніть увагу на розмір циклу (132) і кількість операцій XOR у дизасемблері та в прикладі коду:

Як було зазначено раніше, цей код зазвичай виглядає у декомпіляторі як дуже довга функція, оскільки в ній немає переходів. Декомпільований код може мати вигляд приблизно такий:

Отже, можна ідентифікувати цей алгоритм, перевіривши магічне число та початкові XOR-операції, помітивши дуже довгу функцію та порівнявши деякі інструкції довгої функції з реалізацією (наприклад зсув вліво на 7 і ротацію вліво на 22).

RSA (Asymmetric Crypt)

Характеристики

  • Складніший за симетричні алгоритми
  • Немає констант! (з власними реалізаціями важко працювати)
  • KANAL (crypto analyzer) не може дати підказки щодо RSA, оскільки покладається на константи.

Ідентифікація порівняннями

  • У рядку 11 (ліворуч) є +7) >> 3, що те саме, що й у рядку 35 (праворуч): +7) / 8
  • Рядок 12 (ліворуч) перевіряє modulus_len < 0x040, а рядок 36 (праворуч) — inputLen+11 > modulusLen

MD5 & SHA (hash)

Характеристики

  • 3 функції: Init, Update, Final
  • Схожі функції ініціалізації

Ідентифікація

Init

Обидва алгоритми можна ідентифікувати по константах. Зверніть увагу, що sha_init має одну константу, якої немає в MD5:

MD5 Transform

Зверніть увагу на використання великої кількості констант

CRC (hash)

  • Менші й ефективніші, оскільки їхня функція — знаходити випадкові зміни в даних
  • Використовують таблиці пошуку (тому ви можете ідентифікувати їх за константами)

Ідентифікація

Перевірте константи таблиці пошуку:

Алгоритм CRC виглядає приблизно так:

APLib (Compression)

Характеристики

  • Немає впізнаваних констант
  • Можна спробувати реалізувати алгоритм на Python і шукати схожі реалізації в інтернеті

Ідентифікація

Граф досить великий:

Перевірте 3 порівняння для розпізнавання:

Помилки реалізації підписів на еліптичних кривих

EdDSA: перевірка діапазону скалярів (малоеластичність HashEdDSA)

  • FIPS 186-5 §7.8.2 вимагає, щоб верифікатори HashEdDSA розкладали підпис sig = R || s і відхиляли будь-який скаляр з s \geq n, де n — порядок групи. Бібліотека elliptic пропустила цю перевірку на межі, тому будь-який атакуючий, який знає валідну пару (msg, R || s), може підробити альтернативні підписи s' = s + k·n і повторно кодувати sig' = R || s'.
  • Рoutines перевірки споживають лише s mod n, тому всі s', що конгруентні s, приймаються, хоча вони відрізняються як байтові рядки. Системи, що трактують підписи як канонічні токени (blockchain consensus, replay caches, DB keys тощо), можуть десинхронізуватись, оскільки суворі реалізації відхилятимуть s'.
  • Під час аудиту іншого коду HashEdDSA переконайтесь, що парсер перевіряє як точку R, так і довжину скаляра; спробуйте додати до відомого доброго s кратні n, щоб підтвердити, що верифікатор відмовляє коректно.

ECDSA: усічення проти leading-zero хешів

  • Верифікатори ECDSA повинні використовувати лише ліві log2(n) бітів хеша повідомлення H. У elliptic допоміжна функція усічення обчислювала delta = (BN(msg).byteLength()*8) - bitlen(n); конструктор BN відкидає початкові нульові октети, тому будь-який хеш, що починається з ≥4 нульових байтів на кривих на кшталт secp192r1 (порядок 192 біти), виглядав як 224 біти замість 256.
  • Верифікатор зсувуав праворуч на 32 біти замість 64, отримавши E, який не відповідає значенню, використаному підписувачем. Тому валідні підписи для таких хешів невдаються з ймовірністю ≈2^-32 для входів SHA-256.
  • Пропустіть як «нормальний» тест-вектор, так і варіанти з leading-zero (наприклад, Wycheproof ecdsa_secp192r1_sha256_test.json case tc296) у цікавий вам імплементаційний модуль; якщо верифікатор не погоджується з підписувачем, ви знайшли експлуатований баг усічення.

Використання Wycheproof-векторів проти бібліотек

  • Wycheproof постачає JSON тест-набори, що кодують некоректні точки, малеластичні скаляри, незвичні хеші та інші крайові випадки. Побудувати тестовий стенд навколо elliptic (або будь-якої крипто-бібліотеки) досить просто: завантажити JSON, десеріалізувати кожен тест-кейс і переконатися, що реалізація відповідає очікуваному прапорцю result.
for (const tc of ecdsaVectors.testGroups) {
const curve = new EC(tc.curve);
const pub = curve.keyFromPublic(tc.key, 'hex');
const ok = curve.verify(tc.msg, tc.sig, pub, 'hex', tc.msgSize);
assert.strictEqual(ok, tc.result === 'valid');
}
  • Несправності слід аналізувати й кваліфікувати, щоб відрізняти порушення специфікації від хибнопозитивів. У двох наведених помилках невдалі випадки Wycheproof одразу вказали на відсутні перевірки діапазону скалярів (EdDSA) та неправильне усічення хешу (ECDSA).
  • Інтегруйте harness у CI так, щоб регресії у розборі скалярів, обробці хешів або перевірці коректності координат негайно запускали тести після їх появи. Це особливо корисно для мов високого рівня (JS, Python, Go), де тонкі конвертації bignum легко виконати неправильно.

Посилання

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks