Содержание статьи
В моей предыдущей статье я показал, как, опираясь лишь на особенности сетевого трафика злоумышленников, можно узнавать весьма любопытные, порою неочевидные вещи. Но такая информация вряд ли поможет нам защититься от них.
Куда более интересный вопрос — как мы можем помешать злоумышленникам изучать наши ресурсы в интернете, сбить их с толку или — еще лучше — испортить этот процесс и даже встречно атаковать злоумышленников? И это будут не советы по защите, а, скорее, рекомендации по тому, как стать максимально неудобным для хакера.
В этой статье мы разложим с десяток граблей, на которые непременно наступит хакер, — и станем максимально неудобными для атакующего!
Замедляем сканирование портов
Как правило, хакерские атаки начинаются на сетевом уровне. Пока у атакующего нет информации об используемых сервисах и протоколах, он не может подняться выше — на уровень приложений. И самая первая сетевая атака, с которой столкнется любая компания, — это, конечно же, сканирование портов.
Так хакер проводит активную разведку и определяет программное обеспечение, в котором ему потом предстоит искать уязвимости. И уже на этом этапе мы можем вступить в противостояние с хакером.
info
Эта статья основана на фрагменте книги «Хакерская самооборона. Приемы обнаружения и предотвращения хакерских атак», которая сейчас готовится к публикации.
Одной из самых простых рекомендаций по затруднению сканирования портов может быть запрет отправки пакетов TCP-RST. Такую возможность можно активировать буквально в одну команду:
iptables -A OUTPUT -o eth0 -p tcp --tcp-flags RST RST -j DROP
Суть в том, что, когда порт закрыт, мы не говорим об этом хакеру, сразу отправляя ему пакет TCP-RST. Тем самым мы вынуждаем его тратить некоторое время на ожидание возможного ACK-пакета, который отправляется уже в случае открытого порта.
Давай сравним время сканирования топ-1000 TCP-портов с отправкой RST-пакетов и с запретом.

А теперь активируем правило, запрещающее пакеты TCP-RST. Вновь запустим сканирование топ-1000 портов.

Видно, что эта простая рекомендация в десятки тысяч раз замедляет классическое сканирование TCP-портов. А умножив его на количество IP-адресов нашего периметра, получаем не очень приятное для хакера значение.
Делаем все порты открытыми
Учитывая, что количество возможных портов равно 65 535 для TCP и столько же для UDP, а типичный сетевой периметр нередко состоит из сотен IP-адресов, для хакера может оказаться достаточно накладным полное сканирование портов. В таком случае хакеры могут довольствоваться лишь самыми распространенными портами (топ-1000) или самыми перспективными для проникновения (low hanged fruits). И отсюда вытекает самая распространенная защитная практика — перевешивать службы на нестандартные порты. Но целеустремленный хакер все же не испугается полного сканирования портов и непременно найдет спрятанный сервис, на каком бы порте он ни висел.

Но куда более действенной техникой против сканирования портов является имитация всех неиспользуемых портов как открытых. Этого легко можно достигнуть с помощью файрвола, например iptables на Linux-сервере, и любого пустого листенера.
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22 -j REDIRECT --to-ports 22iptables -t nat -A PREROUTING -i eth0 -p tcp -m conntrack --ctstate NEW -j REDIRECT --to-ports 1234while sleep 1; do nc -nv -lp 1234; doneПосле чего хакер увидит уже совсем иную, удручающую картину.

Все порты открыты. Теперь хакеру будет крайне затруднительно среди 65К открытых портов найти актуальные. Неопытные хакеры тут попадут еще в одну ловушку — часто они запускают сканирование портов с одновременной идентификацией служб, что в нашем случае еще сильнее замедлит сканирование и, скорее всего, не позволит им получить хоть какие‑то результаты.
Ложно открытые порты — относительно частая защитная мера коммерческих сетевых экранов. Но ее можно обойти, ведь за пакетом SYN-ACK с этого порта обычно ничего не приходит. Иными словами, эти порты не содержат никакой службы и хакеру видны как tcpwrapped или как порты с пустой версией.

Однако стоит признать, что потребуются колоссальные расходы трафика и времени на идентификацию всех возможных портов. Большинство хакеров обойдут этот узел стороной, и лишь самые целеустремленные и сумасшедшие продолжат атаки. Но мы тоже не сдаемся, в нашем арсенале есть еще ряд приемов…
Имитируем случайные сервисы
Раз хакер главным образом полагается все же не на сами открытые порты, а на службы, которые он идентифицирует на этих портах, то ударим ему по самому больному — сымитируем случайные службы! И на помощь нам вновь придет база фингерпринтов от Nmap.
Мы уже писали простой TCP/UDP-листенер для наблюдения за запросами хакеров. Теперь мы напишем листенер, который, вместо того чтобы молча принимать данные, станет слать хакеру особые байты, что будут казаться его сканеру каким‑либо сервисом. А эти байты мы возьмем из того же самого файла с фингерпринтами, используемого хакером.
В этот раз нам вновь предстоит распарсить базу фингерпринтов Nmap, только теперь нас будут интересовать уже не запросы, а ответы:
defence/services.py
#!/usr/bin/python3import socketimport rstr #pip3 install rstrimport randomdef get_random_match(): return random.choice(matches)matches = []with open("/usr/share/nmap/nmap-service-probes") as f: for line in f.readlines(): line = line.strip() if line.startswith("match "): matchtext = line[len("match "):] index = matchtext.index(" m") m = matchtext[index + 2] name = matchtext[:index] matchtext = matchtext[len(name):].strip() regx_start = 2 regx_end = matchtext.index(m, regx_start) regx = matchtext[regx_start:regx_end] try: matches.append( rstr.xeger(regx) ) except Exception as e: passs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)s.bind(("0.0.0.0", int(port)))s.listen(10)while True: c,info = s.accept() try: c.send(get_random_match().encode()) except: pass c.close()При каждом входящем подключении наш листенер будет отправлять случайно выбранный ответ из базы фингерпринтов Nmap.
Сетевой сканер Nmap парсит ответы от служб, опираясь на базу фингерпринтов, и делает это не по четкому совпадению, а по регулярному выражению. Поэтому мы, отправляя ответ, должны превратить случайно выбранную строку с регулярным выражением, содержащую в себе диапазон допустимых значений, во что‑то конкретное — в этом нам помогает библиотека rstr.
Мы запускаем наш «ответчик» на произвольном порте и ждем некоторое время, пока он распарсит Nmap-базу.

Хакер же при попытке просканировать этот порт и определить службу увидит совершенно случайный баннер.

Выглядит вполне правдоподобно. А что хакер увидит, когда мы совместим с этим трюк из предыдущего раздела? Сделаем все порты открытыми и направим их в этот листенер:
iptables -t nat -A PRETOUTING -i eth0 -p tcp --dport 22 -j REDIRECT --to-ports 22iptables -t nat -A PREROUTING -i eth0 -p tcp -m conntrack --ctstate NEW -j REDIRECT --to-ports 1234Теперь, когда хакер попробует просканировать большее количество портов, он увидит что‑то вроде такого.

Полная мешанина. На месте хакера я бы растерялся на какое‑то время. Такого большого количества разнообразных служб на одном компьютере быть не может. Но как среди этого найти настоящие сервисы?
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»
