
Классическое переполнение буфера на стеке в SLMail 5.1, показывающее, как ранние почтовые серверы могли быть скомпрометированы через чрезмерно большие SMTP и POP3 команды.
Классическое переполнение буфера в стеке в SLMail 5.5, показывающее, как ранние почтовые серверы могли быть скомпрометированы через слишком длинные команды SMTP и POP3.
Этот репозиторий является частью материалов, которые я использую при обучении эксплуатации повреждения памяти (в дополнение к моей основной работе, я также преподаю на различных курсах по кибербезопасности, где помогаю обучать следующее поколение реверс-инженеров).
CVE-2003-0264 — один из первых примеров, которые я представляю при обучении классическим переполнениям буфера в стеке через сетевой протокол. Он чистый, хорошо документирован, и путь эксплуатации прямолинеен: ни SEH, ни egghunter, ни ограничений по размеру. Студент отправляет полезную нагрузку, перезаписывает EIP, попадает на инструкцию JMP ESP и получает шелл. Именно эта ясность делает его полезным в качестве отправной точки.
SLMail 5.5 — это устаревший почтовый сервер Windows. Уязвимость находится в службе POP3, а именно в обработчике команды PASS, который копирует пользовательский ввод напрямую в стековый буфер фиксированного размера без проверки длины. Что делает этот случай особенно полезным для обучения, так это минимальное количество задействованных элементов:
Эта комбинация — сетевое взаимодействие, отсутствие аутентификации, прямая перезапись EIP, отсутствие современных средств защиты — делает CVE-2003-0264 одним из самых чистых реальных примеров классического переполнения стека, которое все еще работает на современных версиях Windows.
SLMail — это почтовый сервер Windows, предоставляющий услуги SMTP, POP3 и администрирования. Служба POP3 прослушивает TCP-порт 110 и обрабатывает стандартные команды получения почты. Уязвимость находится в обработчике команды PASS, который обрабатывает аргумент пароля, отправленный подключающимся клиентом.
Ключевые технические детали:
Служба POP3 SLMail обрабатывает команду PASS, копируя предоставленный аргумент пароля в стековый буфер фиксированного размера с помощью небезопасной функции без проверки длины. Упрощенная версия уязвимой логики выглядит так:
char password_buffer[256];
strcpy(password_buffer, pass_argument);
Отправка достаточно длинной строки в качестве аргумента PASS приводит к тому, что копирование выходит за пределы буфера, повреждая стек до тех пор, пока не будет перезаписан сохраненный обратный адрес. Когда функция возвращается, процессор загружает контролируемое атакующим значение из стека в EIP и переходит на него.
Крах можно воспроизвести, отправив через POP3 чрезмерно длинный аргумент PASS. Действительные учетные данные не требуются. Пример на Python:
import socket
HOST = '127.0.0.1'
PORT = 110
payload = b"A" * 3000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.recv(1024)
s.send(b"USER username\r\n")
s.recv(1024)
s.send(b"PASS " + payload + b"\r\n")
s.close()
При выполнении под отладчиком крах показывает, что EIP перезаписан контролируемыми пользователем данными:
EIP = 41414141
что подтверждает повреждение сохраненного обратного адреса переполнением.
Цель этого репозитория — не только продемонстрировать крах, но и пошагово провести через весь процесс эксплуатации, от фаззинга до работающего обратного шелла.
Чтобы основной README оставался чистым, подробные заметки по эксплуатации, скрипты и шаги отладчика помещены в папку Vulnerability 📂 этого репозитория.
Там вы найдете полный рабочий процесс, используемый для эксплуатации этой CVE, включая: