Пастка (тарпіт) для вхідних SSH-з'єднань

Не секрет, що інтернет дуже вороже середовище. Як тільки ви піднімаєте сервер, він миттєво піддається масованим атакам і численним скануванням. На прикладі ханіпоту від безпечників можна оцінити масштаб цього сміттєвого трафіку. Фактично, на середньому сервері 99% трафіку може бути шкідливим.

Tarpit – це порт-пастка, який використовується для уповільнення вхідних з'єднань. Якщо стороння система підключається до цього порту, швидко закрити з'єднання не вийде. Їй доведеться витрачати свої системні ресурси та чекати, поки з'єднання не перерветься по таймууту, або вручну розривати його.

Найчастіше тарпіти застосовують для захисту. Техніку вперше розробили для захисту від комп'ютерних хробаків. А зараз її можна використати, щоб зіпсувати життя спамерам та дослідникам, які займаються широким скануванням усіх IP-адрес поспіль (приклади на Хабрі: Австрія, Україна).

Одному з сисадмінів на ім'я Кріс Веллонс, мабуть, набридло спостерігати за цим неподобством - і він написав маленьку програму Endlessh, тарпіт для SSH, що уповільнює вхідні з'єднання. Програма відкриває порт (за замовчуванням для тестування вказаний порт 2222) і прикидається SSH-сервером, а насправді встановлює нескінченне з'єднання з клієнтом, доки той не здасться. Це може тривати кілька днів або більше, доки клієнт не відпаде.

Установка утиліти:

$ make
$ ./endlessh &
$ ssh -p2222 localhost

Правильно реалізований тарпіт забере у зловмисника більше ресурсів, ніж у вас. Але річ навіть не в ресурсах. Автор пише, Що програма викликає звикання. Прямо зараз у його пастці 27 клієнтів, деякі з них підключені протягом тижнів. На піку активності в пастці сиділо 1378 клієнтів протягом 20 годин!

У робочому режимі сервер Endlessh потрібно ставити на звичайний порт 22, куди масово стукають хулігани. Стандартні рекомендації щодо безпеки завжди радять перемістити SSH на інший порт, що відразу на порядок скорочує розмір балок.

Кріс Веллонс каже, що його програма експлуатує один абзац із специфікації RFC 4253 на протокол SSH. Негайно після встановлення з'єднання TCP, але перед застосуванням криптографії обидві сторони мають надіслати ідентифікаційний рядок. І там же приписка: «Сервер МОЖЕ надіслати інші рядки даних перед відправкою рядка з версією». І немає обмеження на обсяг цих даних, просто кожен рядок потрібно починати з SSH-.

Саме цим займається програма Endlessh: вона відправляє нескінченний потік випадково згенерованих даних, які відповідають RFC 4253, тобто відправлення перед ідентифікацією, а кожен рядок починається з SSH- та не перевищує 255 символів, включаючи символ закінчення рядка. Загалом все за стандартом.

За промовчанням програма очікує 10 секунд між відправками пакетів. Це запобігає відключенню по таймууту, так що клієнт сидітиме в пастці вічно.

Оскільки надсилання даних здійснюється до застосування криптографії, програма виключно проста. У ній не потрібно впроваджувати жодних шифрів та підтримку безлічі протоколів.

Автор постарався, щоб утиліта споживала мінімум ресурсів та працювала абсолютно непомітно на машині. На відміну від сучасних антивірусів та інших систем безпеки, вона не повинна гальмувати комп'ютер. Йому вдалося мінімізувати і трафік, і споживання пам'яті за рахунок трохи хитрішої програмної реалізації. Якби він просто запускав окремий процес на нове з'єднання, потенційні зловмисники могли б провести DDoS-атаку, відкривши безліч з'єднань для вичерпання ресурсів на машині. По одному потоку на з'єднання теж не найкращий варіант, тому що ядро ​​витрачатиме ресурси на управління потоками.

Тому Кріс Веллонс вибрав для Endlessh найлегший варіант: однопотоковий сервер poll(2), де клієнти в пастці майже споживають зайвих ресурсів, крім об'єкта сокету в ядрі і ще 78 байт для відстеження в Endlessh. Щоб не виділяти буфери отримання та відправки для кожного клієнта, Endlessh відкриває сокет прямого доступу та прямо транслює пакети TCP, ігноруючи майже весь стек TCP/IP операційної системи. Буфер, що входить, взагалі не потрібен, тому що вхідні дані нас не цікавлять.

Автор каже, що на момент своєї програми не знав про існування пітонівського асиціо та інших тарпітів. Якби він знав про asycio, то свою утиліту міг би реалізувати всього в 18 рядках на Python:

import asyncio
import random

async def handler(_reader, writer):
try:
while True:
await asyncio.sleep(10)
writer.write(b'%xrn' % random.randint(0, 2**32))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 2222)
async with server:
await server.serve_forever()

asyncio.run(main())

Asyncio ідеально підходить для написання тарпітів. Наприклад, така пастка на багато годин підвісить Firefox, Chrome або іншого клієнта, який намагається підключитися до вашого HTTP-сервера:

import asyncio
import random

async def handler(_reader, writer):
writer.write(b'HTTP/1.1 200 OKrn')
try:
while True:
await asyncio.sleep(5)
header = random.randint(0, 2**32)
value = random.randint(0, 2**32)
writer.write(b'X-%x: %xrn' % (header, value))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 8080)
async with server:
await server.serve_forever()

asyncio.run(main())

Тарпіт - чудовий інструмент для покарання інтернет-хуліганів. Щоправда, є певний ризик, навпаки, привернути їхню увагу до незвичайної поведінки конкретного сервера. Хтось може подумати про помсту та націленої DDoS-атаці на ваш IP. Втім, поки що таких випадків не було, і тарпіти відмінно працюють.

Хаби:
Python, Інформаційна безпека, Софт, Системне адміністрування

Мітки:
SSH, Endlessh, tarpit, тарпіт, пастка, asycio
Пастка (тарпіт) для вхідних SSH-з'єднань

Не секрет, що інтернет дуже вороже середовище. Як тільки ви піднімаєте сервер, він миттєво піддається масованим атакам і численним скануванням. На прикладі ханіпоту від безпечників можна оцінити масштаб цього сміттєвого трафіку. Фактично, на середньому сервері 99% трафіку може бути шкідливим.

Tarpit – це порт-пастка, який використовується для уповільнення вхідних з'єднань. Якщо стороння система підключається до цього порту, швидко закрити з'єднання не вийде. Їй доведеться витрачати свої системні ресурси та чекати, поки з'єднання не перерветься по таймууту, або вручну розривати його.

Найчастіше тарпіти застосовують для захисту. Техніку вперше розробили для захисту від комп'ютерних хробаків. А зараз її можна використати, щоб зіпсувати життя спамерам та дослідникам, які займаються широким скануванням усіх IP-адрес поспіль (приклади на Хабрі: Австрія, Україна).

Одному з сисадмінів на ім'я Кріс Веллонс, мабуть, набридло спостерігати за цим неподобством - і він написав маленьку програму Endlessh, тарпіт для SSH, що уповільнює вхідні з'єднання. Програма відкриває порт (за замовчуванням для тестування вказаний порт 2222) і прикидається SSH-сервером, а насправді встановлює нескінченне з'єднання з клієнтом, доки той не здасться. Це може тривати кілька днів або більше, доки клієнт не відпаде.

Установка утиліти:

$ make
$ ./endlessh &
$ ssh -p2222 localhost

Правильно реалізований тарпіт забере у зловмисника більше ресурсів, ніж у вас. Але річ навіть не в ресурсах. Автор пише, Що програма викликає звикання. Прямо зараз у його пастці 27 клієнтів, деякі з них підключені протягом тижнів. На піку активності в пастці сиділо 1378 клієнтів протягом 20 годин!

У робочому режимі сервер Endlessh потрібно ставити на звичайний порт 22, куди масово стукають хулігани. Стандартні рекомендації щодо безпеки завжди радять перемістити SSH на інший порт, що відразу на порядок скорочує розмір балок.

Кріс Веллонс каже, що його програма експлуатує один абзац із специфікації RFC 4253 на протокол SSH. Негайно після встановлення з'єднання TCP, але перед застосуванням криптографії обидві сторони мають надіслати ідентифікаційний рядок. І там же приписка: «Сервер МОЖЕ надіслати інші рядки даних перед відправкою рядка з версією». І немає обмеження на обсяг цих даних, просто кожен рядок потрібно починати з SSH-.

Саме цим займається програма Endlessh: вона відправляє нескінченний потік випадково згенерованих даних, які відповідають RFC 4253, тобто відправлення перед ідентифікацією, а кожен рядок починається з SSH- та не перевищує 255 символів, включаючи символ закінчення рядка. Загалом все за стандартом.

За промовчанням програма очікує 10 секунд між відправками пакетів. Це запобігає відключенню по таймууту, так що клієнт сидітиме в пастці вічно.

Оскільки надсилання даних здійснюється до застосування криптографії, програма виключно проста. У ній не потрібно впроваджувати жодних шифрів та підтримку безлічі протоколів.

Автор постарався, щоб утиліта споживала мінімум ресурсів та працювала абсолютно непомітно на машині. На відміну від сучасних антивірусів та інших систем безпеки, вона не повинна гальмувати комп'ютер. Йому вдалося мінімізувати і трафік, і споживання пам'яті за рахунок трохи хитрішої програмної реалізації. Якби він просто запускав окремий процес на нове з'єднання, потенційні зловмисники могли б провести DDoS-атаку, відкривши безліч з'єднань для вичерпання ресурсів на машині. По одному потоку на з'єднання теж не найкращий варіант, тому що ядро ​​витрачатиме ресурси на управління потоками.

Тому Кріс Веллонс вибрав для Endlessh найлегший варіант: однопотоковий сервер poll(2), де клієнти в пастці майже споживають зайвих ресурсів, крім об'єкта сокету в ядрі і ще 78 байт для відстеження в Endlessh. Щоб не виділяти буфери отримання та відправки для кожного клієнта, Endlessh відкриває сокет прямого доступу та прямо транслює пакети TCP, ігноруючи майже весь стек TCP/IP операційної системи. Буфер, що входить, взагалі не потрібен, тому що вхідні дані нас не цікавлять.

Автор каже, що на момент своєї програми не знав про існування пітонівського асиціо та інших тарпітів. Якби він знав про asycio, то свою утиліту міг би реалізувати всього в 18 рядках на Python:

import asyncio
import random

async def handler(_reader, writer):
try:
while True:
await asyncio.sleep(10)
writer.write(b'%xrn' % random.randint(0, 2**32))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 2222)
async with server:
await server.serve_forever()

asyncio.run(main())

Asyncio ідеально підходить для написання тарпітів. Наприклад, така пастка на багато годин підвісить Firefox, Chrome або іншого клієнта, який намагається підключитися до вашого HTTP-сервера:

import asyncio
import random

async def handler(_reader, writer):
writer.write(b'HTTP/1.1 200 OKrn')
try:
while True:
await asyncio.sleep(5)
header = random.randint(0, 2**32)
value = random.randint(0, 2**32)
writer.write(b'X-%x: %xrn' % (header, value))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 8080)
async with server:
await server.serve_forever()

asyncio.run(main())

Тарпіт - чудовий інструмент для покарання інтернет-хуліганів. Щоправда, є певний ризик, навпаки, привернути їхню увагу до незвичайної поведінки конкретного сервера. Хтось може подумати про помсту та націленої DDoS-атаці на ваш IP. Втім, поки що таких випадків не було, і тарпіти відмінно працюють.

Пастка (тарпіт) для вхідних SSH-з'єднань

Джерело: habr.com

Додати коментар або відгук