Двойка вам, или аудит со взломом

Habrahabr 2

Как всегда без имен и названий, и так как я дополнительно связан подписью о неразглашении, еще и с немного видоизменённой историей (и опуская некоторые подробности, на публикацию которых я не получил разрешения). Ниже следует реальная история проникновения на компьютер сотрудника… ну скажем некоторого частного банка. События, о которых повествует ваш покорный слуга, происходили в некоторой европейской стране не так что бы давно, еще до DSGVO (GDPR, RGPD) но в процессе становления оного, в преддверии так сказать.

Собственно началось всё с аудита безопасности — ..., интервью, разглядывания под лупой всего и вся, поиском и проработкой потенциальных лазеек и узких мест на пролезть (как туда, так и оттуда), ..., и собственно разбора полётов. На котором заказчик получил в итоге неутешительный для него вывод — "троечка с натяжкой".

Опустим слова, которые пришлось выслушать от краснеющих на глазах IT-безопасников, но общий лирический посыл таков — я бросаюсь голословными обвинениями, а у них — всё на замке, а ключ у CSO в кармане под сердцем.

Попытки объяснить, что система безопасности выстроенная вокруг firewall+proxy+webwasher like content-filter & antivirus, без какой-либо худо-бедно настроенной гибридной IDS (HIDS+APIDS), хонепотов и т.д. и т.п., во первых по определению не является безопасной, во вторых я же как бы показал уже несколько мест, где оно как минимум не комильфо. Попытки вернуться к конструктивному диалогу (собственно обратно к разбору) разбивались о трехэтажную стену обиды, выстроенную всем отделом.

Свернув совещание и отпустив сотрудников, CSO вкупе с двумя важными начальниками попытался всё-таки честно выяснить у меня где собака порылась и понять как дальше жить как собственно и что конкретно, по моему скромному мнению, нужно делать.

Т.к. проблеска понимания в дальнейшем тоже не наблюдалось, с воодушевлением встретил предложение показать на практике. После объяснения что де прямо сейчас ну никак не получится, улаживания формальностей (подписывания еще нескольких бумаг и т.п.) я получил добро на "взлом".

Замечание о том, что работать "вслепую" не очень люблю (муторно, долго и дорого, да и пентестинг, то дело такое — на удачу) и просьба предоставить поэтому некоторую дополнительную информацию (например некоторые личные данные отдельных сотрудников, как то разрабов и безопасников), встречного понимания не встретила тоже.

Ты хакер или нет?! (вообще-то нет, я разраб, а то — больше хобби).

Я не буду долго останавливаться на дальнейшей дискуссии — убедил как всегда фактор деньги и время (т.е. собственно те же деньги).

Т.е. в результате имеем какое-никакое знание о структуре защиты компании (полученное в результате предварительного аудита), а также ФИО и краткую биографию 4-х администраторов и 3-х разработчиков.

Почему собственно админы и разрабы, ведь можно же было спросить за "девочек-бухгалтеров", отправить им какого-нибудь "котика" с приложенным каким-нибудь гораздо менее безопасным зверьком в придачу (или провернуть что-нибудь подобное из соц-инженерной области). Но… Однако очень многие компании как правило не очень любят когда им на презентации PoC начнут за такое рассказывать, т.е. "система взлома" базирующаяся на происках из области соц-инженерии как минимум не приветствуется, как бы гениально она не была бы построена.

Возвращаясь же к технарям, они во первых не менее "социальны" (что совсем не значит, что они запустят какого-либо "котика", но пока важен сам факт), во вторых как правило обладают более "развитым" в функциональном плане компьютером (чего там только не встретишь). И что более интересно, кроме того нередко имеют какие-нибудь "привилегии" в отличии от той же девочки бухгалтера, т.е. могут либо быть менее ущемлены в правах в плане безопасности и системных ограничений (типа policies и ко — надо же например как-то запускать только что скомпилированный exe-шник) и/или могут сами пролазить через "стену", построенную безопасниками (например пробросив туннель через прокси) и т.д. и т.п.

Опять же пролезть сквозь защиту, используя при этом комп программиста или админа, звучит уже совершенно по другому, чем например "заставив" запустить троян бухгалтера.

Т.е. исходные получены, задачи озвучены — поехали...

Первым делом сбор информации о "клиентах" — кто, что, где, когда.

Тут не буду сильно отвлекаться, статья не совсем об этом, поэтому просто скажу — остановился на довольно социальном пареньке, с фасебуками и ко, в том числе собственным youtube-каналом (ютубой, Вася!), несколькими опенсорсными проектами (как в группе, так и собственными) и просто гигантской contribution activity (спрашивается а он вообще на основном месте работает).

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

Затормозить же на нем меня заставило в том числе и моё природное чутьё тот факт, что в одной из коммьюнити наш герой занимался более-менее активной поддержкой в чате, причём используя IRC-клиента, который в user-info предоставлял помимо IP, откуда ноги растут, еще и название и версию себя любимого, ну и оное славилось багами/дырами и по умолчанию было обёрнуто плагинами почём зря.

Ну и как водится, как-то вечером, домашние уснули, по ящику одна муть, наши опять проигрывают:) я в том самом чате обнаружил знакомый ник, как активного пользователя с коннектом длиннее 12 часов (судя по логу с промежуточными отключениями/пере-подключениями, ибо корпоративный прокси такая штука, но уже более полдня с момента первого соединения), с нужного мне IP адреса т.е. с "логином" вида max.mustermann@proxyext.our-company.example.com.

Т. е. либо у нашего клиента день — 24 часа, либо что более вероятно (ибо с момента его последнего сообщения прошло уже 2 часа) он просто не выключил рабочий компьютер и оставил IRC-клиент активным.

А может он и усыпил компьютер, но (тут снова ошибка безопасников или админов) бывает что последний просыпается сам, например чтобы накатить обновления для винды (и после 4-х часовой паузы перезагрузиться) или просто тупо словив wake-on-lan сигнал...

Как бы то ни было, у меня было некоторое количество времени, чтобы потрепать компьютер, вернее IRC-клиент нашей "жертвы".

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

И оно нашлось таки, даже относительно быстро!

Перехватить контроль позволило наличии небезопасного вызова sprintf на буфер из стека с %s внутри от плохо-отфильтрованного foreign-input (в совокупности с инжектом по encoding), позволяющее записать в стек в нужное место "загрузчик кода эксплойта" (спасибо разрабам клиента за код, Microsoft за lowland stack и удачному стечению обстоятельств).

Хотя помучится всё-таки пришлось — т.к. имеем DEP, исполнять напрямую из стека нельзя, нужно записать в стек копию "программного кода" для исполнения, найти memcpy вызов с ret в конце, чтобы скопировать в нужное место (переписать мало используемый класс), перенаправить выход из нескольких процедур в нужное место, перезаписать несколько значений VTABLE, чтобы по вызову следующего виртуального метода сгенерировать событие, вызывающее в результате некоторый питоний код в качестве плагина (да и поменять этот питон-код на свой, как загрузчик из сломанных сообщений, чтобы уже собрать готовый эксплойт-тулкит).

Ах да, еще нужно было собрать у себя плагин (снова спасибо разрабам клиента за такой щедрый функционал), в качестве прокси, меняющее сообщения налету (добавляющее обёртку для инициации инъекции, ломающее ему encoding, при этом вставляя неполные суррогаты в нужном месте, и т.д.), закодировать инициальный загрузчик сообщения-инъекции, и т.п. Кроме того, пришлось собрать небольшой питоний скрипт в виде нового плагина-клиента для целевой системы в качестве эмулятора консоли (принимающий мои сообщения в его stdin, и отправляющих stdout+stderr приватным сообщением обратно на мой ник).

Собрав это всё на коленке, запустил у себя тот IRC-клиент, чтобы попробовать себя в качестве жертвы, т.е. увидеть как оно будет в полном, готовом виде.

И отправив через свой плагин из другой сессии из второй запущенной версии приложения, несколько приватных сообщений-инъекций, обрадовано увидел ответом привычное питонье приветствие >>> (который я в эмуляторе воткнул, для наглядности — питон же).

Довольный как слон (отметив что атакуемое приложение не упало), увидел что творится в его окне вывода сообщений — оно пестрело различными non-ascii символами, самым заметным из которых был  с порядковым номером 90h (что как минимум не комильфо, а то и выдаёт с головой попытку взлома), подумал что нужно таки переделать загрузчик, чтобы маскировать следующие сообщения (вдруг он всё-таки еще работает и заметит).

Заглянул в код, а там на выдаче ждут NTS-строчку, решил сильно не заморачиваться и тупо переписать первый байт сообщения после загрузки нулём (с надеждой что выдача на экран сообщения будет по событию немного позже).

Повторив весь процесс, и дождавшись желанного >>> снова взглянул в другое окно и не обнаружив там ничего лишнего в чате (я всё-таки гений), решил продолжить тест. Следом улетело сообщение from glob import glob as ls; ls('*') и я радостно увидел ответом список из папок и файлов, содержащихся в папке приложения.

Правда я увидел это же сообщение в окне атакующего клиента как отправленное на мой ник. Пришлось также и тут положить 0-байт (NTS) в начало строчки после отправки его мне.

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

Поехали...

Сообщения-инъекции ушли… И через несколько долгих секунд (видимо диск спал или прокси тупил) я вновь увидел приглашающий >>>. Как я прыгал по комнате, я тут всё же не буду рассказывать (то зрелище не для слабонервных, ибо в результате неконтролируемого процесса проявления радости, я таки засандалил мизинцем ноги о ножку стула).

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

Первым делом проверка на всякий случай а там ли мы вообще.

>>>
import os; os.environ['userdomain']

и ответ:

'OUR-COMPANY'
>>>

Ну всё, руки развязаны… Поехали.

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

>>>
from glob import glob as ls; ls(r'C:\Program Files\*')

а в ответе, не веря своей удаче, среди много всего интересного увидел следующее:

[...,'C:\\Program Files\\TeamViewer',...]
>>>

Т.е. уже не нужно совершать лишние телодвижения — не надо ничего качать, компилить и искать папку куда можно записать это всё без нарушения каких-нибудь полиси.

А следом тем временем полетело:

>>>
import subprocess; subprocess.call([r'C:\Program Files\TeamViewer\TeamViewer.exe'])

ну и после вернувшегося ответа:

0
>>>

Подождав немного, чтобы TeamViewer успел пробраться через proxy и сервер выдал ему ID (с паролем), я запустил туда скрипт, ищущий окошко TeamViewer, снимающий с него screenshot и посылающий его обратно мне в виде base64-строчки, в которой, развернув её обратно в bitmap, я с удовлетворением нашел и ID и пароль для соединения.

...

Наутро мне уже звонил удивлённый CSO, получивший сначала письмо от меня (но почему-то пришедшее с внутреннего Exchange аккаунта своего сотрудника), а затем испуганный звонок от того же сотрудника со словами "Шеф, усё пропало — нас поломали", обнаружившего утром открытое окошко Word'а с крупным текстом внутри "Двойка вам по безопасности. Вас взломали!", дата, подпись.

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

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

Ну и ладно, как говорят в Германии "Man sieht sich immer zweimal im Leben", что значит "Обязательно встретимся еще раз".