Недостатки xor-шифрования

Сегодня у нас срыв покровов с некачественного шифрования полезной нагрузки. 

Шифрование с использованием операции xor довольно популярная процедура, в силу простоты исполнения:

Проблемы

Короткий ключик

В 32-битном ассемеблере проще всего манипулировать размером в 4 байта, поэтому чаще всего xor-ключ имеет длину 4.

В целом, перебрать все ключи на 4 байта не составляет особого труда, но есть и более оригинальные алгоритмы:

Поиск pe32

Что бы найти ключ надо знать хотя бы часть открытого текста, и в вирусах она известна  — PE, MZh
Ксорим первые байты на MZh и пробуем полученный ключ на следующих структурах. Подобрать ключ от 1 до 4 байт очень быстро.

Поиск ссылок

Есть не так много вариантов шифрования строки «https://», имея все варианты с ключом от 1 до 4 можно очень быстро найти совпадения и проверить синтаксис расшифрованной части.

Инструменты

XORSearch

xorsearch

Существует готовая утилита для подобных задач, от некого Didier Stevens. Она перебирает свой внутренний список подозрительных строк с разными вариантами шифрования.

Поддерживает не только Xor но и ROL, ROT, SHIFT и даже ADD. Недавно вышла python-версия!

Balbuzard

balba

Ещё одна утилита для извлечения скрытых данных, использует YARA и поддерживает плагины.

Also

  • https://github.com/hellman/xortool
  • https://github.com/fireeye/flare-floss

Стандартные алгоритмы

Можно использовать что-то проверенное в бою, вроде RC4, но у часто используемых алгоритмов есть свой недостаток — существует утилиты, которые сигнализируют об использовании того или иного метода, например использование md5 легко отличить по сигнатурам :

Что же делать?

  1. Использовать нестандартные алгоритмы шифрования
  2. Использовать длинные ключи (исходник в начале статьи это позволяет)
  3. Ключ желательно не держать в открытом виде, а вычислять динамически

3 thoughts on “Недостатки xor-шифрования

  1. Даже при коротком изначальном ключе (1 байт), можно написать хитрый алгоритм динамического вычисления ключа для каждого байта.
    Особенностью этого метода является то, что код ксорится всегда на разные значения по неочевидной последовательности.

    Достаточно условный пример (Синтаксис: FASM под x86):
    mov edx, %CodeAddr% ; Откуда (рас)шифруем.
    mov ecx, %CodeSz% ; Сколько байт (рас)шифруем.

    mov al, %Key% ; Начальный ключ. 1 байт.

    lp:
    test al, 1 ; Тут проверяем чётность ключа
    jnz od

    en: ; Чётное
    add al, 3h
    jmp ce
    od: ; Нечетное
    sub al, 1h

    ce:
    xor byte [edx], al ; Ксорим по полученному ключу

    inc edx
    loop lp

    ; В случае с изначальным ключом = 01h и размером кода в 15 байт,
    ; ключ по итерациям будет выглядеть так: 0 3 2 5 4 7 6 9 8 B A D C F E

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

    P.S. Вы в жабе отвечаете?

    1. Как вообще можно ругать гаммирование, RC4 ксорит по одному байту генерируя поток из ключа… Речь идёт исключительно об элементарных ксорах на статик ключ.
      root@vxlab.info (серт все еще старый, не пугайтесь)

Добавить комментарий