Аутентификация и шифрование в варианте PAS Web Shell

  1. Вступление Во время недавнего инцидента с инцидентом нам было поручено определить точку входа для...
  2. Как мы это обнаружили?
  3. Анализ кода веб-оболочки PAS
  4. Сводка результатов

Вступление

Во время недавнего инцидента с инцидентом нам было поручено определить точку входа для злоумышленника, который скомпрометировал всю сеть Windows. Среди прочего, мы обнаружили доказательства атак на веб-приложения, нацеленных на общедоступный веб-портал компании, за которыми последовала веб-оболочка, загруженная на портал.

Впоследствии веб-оболочка была определена как вариант веб-оболочки PAS PHP. Это тот же тип веб-оболочки, который, как было установлено, также сыграл ключевую роль в недавней кампании APT, получившей название Grizzly Steppe, предположительно с участием российских участников киберугроз (см. Стр. 5 Гризли Степной отчет APT ).

В трассировке пакетов было найдено одно свидетельство того, что это вариант веб-оболочки PAS. Трассировка перехватила связь между оболочкой и внешним IP-адресом злоумышленника после того, как злоумышленник вызвал функцию оболочки reverse_connect TCP веб-оболочки PAS.

Хотя наборы инструментов для веб-оболочки PHP являются довольно распространенным средством получения постоянного доступа к скомпрометированному веб-порталу, мы считаем, что этот конкретный вариант имеет большое значение. В отличие от типичных веб-оболочек, которые используют методы кодирования и / или запутывания, чтобы избежать обнаружения и затруднить анализ кода, эта веб-оболочка использует необычную форму шифрования своего PHP-кода, чтобы помешать попыткам получить доступ и / или проанализировать веб-оболочку. возможностей.

Веб-оболочка PAS

Веб-оболочка PAS относится к категории полнофункциональных веб-оболочек PHP, которые используются злоумышленниками после первоначальной эксплуатации для обеспечения постоянного доступа к взломанному веб-порталу.

Существует множество вариантов веб-оболочки PAS, и ее функции и возможности аналогичны другим наиболее распространенным веб-оболочкам, таким как WSO / FilesMan.

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

  • В большинстве вариантов используется либо легко обратимое кодирование (например, base64), либо сочетание сжатия (gzdeflate) и кодирования.
  • Другие используют собственные методы запутывания и процедуры для удаления запутывания. Они запускают код веб-оболочки PHP, включенный в сам файл PHP веб-оболочки.
  • Хотя это редко, некоторые используют парольную фразу, которая необходима для входа в оболочку (часто предоставляется через cookie или HTTP-запрос POST). В таких случаях MD5 парольной фразы используется для подтверждения правильности ввода. MD5 - это хеш, который относительно легко перехватить и восстановить парольную фразу в виде открытого текста. Это делает этот метод менее устойчивым к предотвращению ручного анализа. Этот метод, однако, не имеет отношения к виду используемого кодирования или запутывания. Он служит только для аутентификации доступа к веб-оболочке.
  • Еще более редкими являются варианты, которые используют более продвинутые методы аутентификации. Так обстоит дело с вариантом, который является целью нашего анализа сегодня.

Ниже приведены некоторые скриншоты веб-оболочки PAS PHP:

Рисунок 1: Экран входа в веб-оболочку PAS
Рисунок 1: Экран входа в веб-оболочку PAS

Рисунок 2: Главный экран веб-оболочки PAS
Рисунок 2: Главный экран веб-оболочки PAS

Рисунок 3: Интерфейс файлового менеджера PAS
Рисунок 3: Интерфейс файлового менеджера PAS

Рисунок 4: Веб-оболочка PAS TCP_bind и оболочки обратного соединения
Рисунок 4: Веб-оболочка PAS TCP_bind и оболочки обратного соединения

Как мы это обнаружили?

Первоначальный намек на то, что веб-портал, вероятно, был взломан, поступил в виде трассировки пакетов, которая была передана затрагиваемой стороне. Трассировка пакетов показывает, что появляется для связи / взаимодействия между веб-порталом и внешним IP-адресом. На рисунке ниже показан восстановленный поток TCP, показывающий это взаимодействие между веб-порталом и внешним IP-адресом.

Рисунок 5: Трассировка пакетов, показывающая обратную связь TCP reverse_connect
Рисунок 5: Трассировка пакетов, показывающая обратную связь TCP reverse_connect

Сразу стоит отметить строку «Привет из PAS BackConnect». Наш предварительный анализ трассировки также показал, что веб-портал устанавливает соединение с обратной оболочкой TCP по внешнему IP-адресу. Известно, что веб-оболочка PHP, известная как PAS, устанавливает этот тип бэкдора. PAS - это известный, хотя и не очень распространенный тип веб-оболочки PHP, используемый в качестве инструмента для пост-эксплуатации на скомпрометированных веб-сайтах.

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

Как правило, веб-оболочки PHP содержат строки, которые легко отключить и использовать для поиска по всем файлам внутри корневого каталога на наличие веб-оболочки. Однако в этом случае это было невозможно, поскольку код содержал значительное количество двоичных данных с очень небольшим количеством строк ascii (удобочитаемых для человека).

Однако настойчивость окупилась, и мы наконец смогли найти веб-оболочку, которая, в конце концов, была названа просто pas.php.

Специальный привет моему менеджеру (и участнику этого блога), Thanassis Diogos, который смог обнаружить оболочку на портале, выполнив поиск следующих текстовых строк в удобочитаемой для человека форме:

Рисунок 6: Строковые IoC для обнаружения веб-оболочки PAS
Рисунок 6: Строковые IoC для обнаружения веб-оболочки PAS

Ключевой источник различных версий веб-оболочки PAS: hxxps: //github.com/wordfence/grizzly

который архивирует образцы версий и вариантов веб-оболочки PAS.

Рисунок 7: Онлайн-источник вариантов веб-оболочки PAS
Рисунок 7: Онлайн-источник вариантов веб-оболочки PAS

Сравнив код веб-оболочки, найденный на скомпрометированном портале, с вариантами, доступными на github, мы поняли, что наша версия оболочки PAS уникальна. Фактически он отличался от известных вариантов тем, как он обрабатывал аутентификацию, и способом, которым он «шифровал», а не кодировал (или обфусцировал) код PHP, чтобы избежать обнаружения и усложнить анализ.

Анализ кода веб-оболочки PAS

Давайте посмотрим на веб-оболочку PAS, которую мы нашли:

Рисунок 8: Начало фрагмента кода веб-оболочки PAS, показывающего двоичное содержимое
Рисунок 8: Начало фрагмента кода веб-оболочки PAS, показывающего двоичное содержимое

Рисунок 9: Конец фрагмента кода веб-оболочки PAS
Рисунок 9: Конец фрагмента кода веб-оболочки PAS

Код, показанный на приведенных выше рисунках, - это не весь код, а лишь краткие фрагменты из начала и конца кода.

Ясно, что код представляет собой PHP-скрипт, в котором автор определяет переменную J__WP (выделена зеленым цветом и двумя подчеркиваниями между символами j и WP) для хранения некоторых двоичных данных (выделено желтым цветом).

Эти двоичные данные на самом деле являются зашифрованным кодом веб-оболочки, тогда как остальная часть сценария PHP предназначена для получения внешнего «секрета» через запрос HTTP POST от злоумышленника. Затем сценарий использует этот секрет для расшифровки двоичных данных и запуска извлеченного кода веб-оболочки PHP на скомпрометированном портале.

Итак, давайте посмотрим на этот php-код и попытаемся упростить и очистить его, чтобы его было легче понять.

Во-первых, давайте заменим три непонятных имени переменных, j_WP (с одним подчеркиванием), j__WP (с двумя подчеркиваниями) и j___WP (с тремя подчеркиваниями), на имена переменных SECRET, BIN и LOOPCTR соответственно, чтобы сделать код легче читать. Выбор этих новых имен переменных не является случайным и предназначен для передачи типа данных, которые содержат переменные, или типа роли, которую они играют в выполнении кода.

Рисунок 10: j__WP заменен на BIN
Рисунок 10: j__WP заменен на BIN

Рисунок 11: j_WP заменен на SECRET, а j___WP заменен на LOOPCTR
Рисунок 11: j_WP заменен на SECRET, а j___WP заменен на LOOPCTR

Теперь давайте заменим двоичное содержимое, хранящееся в переменной BIN, строкой «ENCRYPTED_BIN_CODE» во многом как заполнитель. Это сделает код более чистым для чтения в редакторе. Наконец, мы «украсим» код, чтобы его было легче читать и анализировать, как показано ниже.

Рисунок 12: Усовершенствованная версия кода без двоичного содержимого
Рисунок 12: Усовершенствованная версия кода без двоичного содержимого

Теперь мы можем лучше понять, как работает этот вариант веб-оболочки PAS.

Приведенный выше код хранит двоичное содержимое в переменной с именем BIN. Затем он сохраняет данные, полученные через запрос HTTP POST, в переменной с именем SECRET. Если данные не получены через запрос POST, он проверяет, установлен ли cookie, и соответственно инициализирует значение переменной SECRET. Если ни данные из запроса POST не получены, ни cookie не установлены, то для переменной SECRET устанавливается значение NULL.

Если переменная SECRET заполнена (например, она не равна NULL), сценарий расшифрует двоичный код, используя следующую логику:

Рисунок 13: Логика для расшифровки двоичного кода
Рисунок 13: Логика для расшифровки двоичного кода

Вышеуказанная логика может быть объяснена следующим образом:

  1. Рассчитайте длину переменной SECRET (количество символов в парольной фразе, предоставляемой через запрос HTTP POST или как установлено в Cookie). Давайте назовем это л.
  2. Обратитесь к строке парольной фразы и вычислите ее хэш MD5
  3. Создайте подстроку хеша MD5 (начиная с начала значения хеша и с длиной подстроки = l + 1)
  4. Объедините хэш MD5 парольной фразы с этой (под) строкой, сгенерированной на шаге 3 выше.
  5. Обновите значение переменной SECRET по сравнению с ее исходным значением (это была фраза-пароль, полученная с помощью запроса POST) со строкой, вычисленной на шаге 4.
  6. Расшифруйте двоичное содержимое, используя формулу, выделенную желтым в приведенном выше фрагменте кода внутри цикла, который выполняется от LOOPCTR = 0 до LOOPCTR = 15587 (т.е. 15588 раз).
  7. Для каждого выполнения цикла обновляйте значение переменной SECRET, объединяя значение $ BIN [$ LOOPCTR] с его предыдущим значением, вычисленным на шаге, выделенном желтым цветом. Например, при первом выполнении цикла значение переменной SECRET обновляется до значения SECRET, объединенного со значением, вычисленным для $ BIN [0] ($ LOOPCTR = 0 при первом запуске цикла) и, в более общем случае, значением переменная SECRET во время i-го выполнения цикла будет значением переменной SECRET после (i-1) -го выполнения цикла, объединенного со значением $ BIN [i].
  8. Если злоумышленник предоставил правильную парольную фразу, новым значением BIN будет сжатая версия кода веб-оболочки PHP. В этом случае операция gzinflate приведет к «интерпретируемому» PHP-коду, который может выполнить интерпретатор PHP на скомпрометированном портале, предоставляя злоумышленнику доступ к веб-оболочке.
  9. Если злоумышленник предоставил неверную парольную фразу, новое значение переменной BIN после выполнения цикла не будет допустимым сжатым сжатым кодом PHP в коде gzip, и операция gzinflate этого кода завершится неудачно.
  10. Таким образом, автор вредоносного ПО гарантирует, что код PHP будет выполняться только в том случае, если известен правильный секрет, тем самым предотвращая как AV-обнаружение, так и любые попытки анализа.

Код PHP также может быть визуально представлен следующим образом:

Рисунок 14: Поток выполнения кода - визуальное представление
Рисунок 14: Поток выполнения кода - визуальное представление

Сводка результатов

Ниже приведены результаты наших выводов:

  • Секрет или фраза-пароль, предоставленная злоумышленником либо через запрос HTTP POST, либо через cookie-файл, играет ключевую роль в дешифровании зашифрованного двоичного кода, хранящегося в переменной j__WP в этом варианте веб-оболочки PAS.
  • Нет ограничений по размеру парольной фразы или символьного пространства для парольной фразы. Нам пришлось бы прибегнуть к словарю, грубой силе или гибридной атаке, чтобы обнаружить СЕКРЕТ, который успешно расшифровывает код. Даже если используется метод грубой силы, нам придется делать предположения как о максимальной длине, так и о пространстве символов. Если мы предполагаем, что злоумышленники используют большую максимальную длину и / или включают сложное символьное пространство (т. Е. Максимальная длина = 16 и символьное пространство = A..Z, a..z, 0..9 и специальные символы), то это может привести к грубому перебору. сила очень сложная.
  • Практически невозможно расшифровать код веб-оболочки и проанализировать его функции и возможности без ключевой фразы.
  • Такой подход к аутентификации и шифрованию кода чаще используется в случае наборов эксплойтов и других расширенных вредоносных программ, но очень редко встречается в случае веб-оболочек. В большинстве веб-оболочек используется либо простая кодировка base64 (которая легко обратима), либо пользовательская обфускация (в которой функции / процедуры для деобфускации и запуска кода PHP доступны в самом коде веб-оболочки PHP). Как правило, они также используют сравнение хэшей MD5 для проверки правильности введенной фразы-пароля, и она не играет никакой роли в деобфускировании кода PHP.

Спасибо Thanassis Diogos за его вклад в исследования, описанные в этом посте.

Как мы это обнаружили?