Самооборона по-хакерски. Ловим нарушителя на уровне сети

Содержание статьи

  • Сетевой сниффер
  • Сканирование портов
  • Обнаружение перехвата трафика
  • Обнаружение вредоносных DHCP/DHCPv6/SLAAC-серверов
  • Спуфинг NetBIOS
  • Honeypot
  • SSH
  • SMB MS17-010
  • Выводы

В этой статье мы рас­смот­рим прос­тые, но эффектив­ные при­емы компь­ютер­ной само­обо­роны, которые помогут тебе выявить хакеров, уже успевших про­ник­нуть в локаль­ную сеть. Мы научим­ся находить приз­наки про­ник­новения и ловить зло­умыш­ленни­ков при помощи спе­циаль­ных хит­рых скрип­тов. Нач­нем с самого пер­вого уров­ня: уров­ня сети.

Ког­да хакер пыта­ется про­ник­нуть к тебе отку­да‑то изда­лека, ата­куя твои сер­висы на внеш­нем перимет­ре, ког­да его и тебя раз­деля­ют десят­ки хопов, Tor, Proxy, VPN — хакер поис­тине неуло­вим. Он с лег­костью может сме­нить IP-адрес, прыг­нуть на любой кон­тинент или, нап­ротив, подоб­рать выход­ную точ­ку поб­лиже к цели. И нам ничего не оста­ется, кро­ме как тер­петь его ата­ки сно­ва и сно­ва. Одна­ко если на тво­ем перимет­ре все окей, то боять­ся нечего.

Но что, если хакер уже где‑то рядом с тобой? Каким‑то неведо­мым обра­зом он смог про­ник­нуть в твою внут­реннюю сеть. Мож­но ли его как‑то заметить теперь? Ведь в этом слу­чае он пред­став­ляет уже реаль­ную угро­зу.

Тут в игру всту­пает SOC, так­же извес­тный как Blue Team. Но далеко не в каж­дой ком­пании име­ется «кибер­патруль». Во мно­гих ком­пани­ях мероп­риятия по обес­печению безопас­ности силь­но тор­мозят­ся бюрок­ратичес­кой машиной либо они прос­то меша­ют биз­несу: ведь то, что безопас­но, ред­ко быва­ет удоб­но. Поэто­му внед­рить тяжелые и дорогие средс­тва защиты порой ока­зыва­ется не так‑то прос­то. Ну а если в ком­пании нет «кибер­полиции», край­не важ­но знать прос­тые при­емы кибер­само­обо­роны.

Об­щаясь с безопас­никами, я замечал, что далеко не все они зна­ют отно­ситель­но прос­тые тех­ничес­кие при­емы, которые помога­ют отсле­дить зло­умыш­ленни­ков в про­цес­се ата­ки. Мне, как пен­тесте­ру с дос­таточ­но боль­шим опы­том, хорошо вид­ны раз­личные мес­та, где они могут попасть­ся, если знать, что про­верять.

В этом цик­ле ста­тей речь пой­дет про прос­тые, но эффектив­ные при­емы компь­ютер­ной само­обо­роны, которые помогут тебе выявить хакеров, что уже успе­ли про­ник­нуть в твою локаль­ную сеть. Или толь­ко еще собира­ются, про­гули­ваясь вдоль перимет­ра и изу­чая твои Wi-Fi-сети.

Мы научим­ся обра­щать вни­мание не толь­ко на шум­ные мес­та, но и на вещи, которые мно­гие хакеры счи­тают дос­таточ­но тихими, но которые все же име­ют свои харак­терные чер­ты. Ловить хакеров мы будем тоже по‑хакер­ски — запус­кая осо­бые хит­рые скрип­ты. Наше defence-кунг‑фу будет нап­равле­но про­тив наибо­лее общих, а зна­чит, наибо­лее веро­ятных атак.

И раз это само­обо­рона, то при­менять ее смо­жет любой поль­зователь — все пред­ложен­ные мною защит­ные при­емы не пот­ребу­ют никаких исклю­читель­ных прав. Их мож­но будет про­водить с рядовой рабочей стан­ции, не имея рас­ширен­ного дос­тупа к логам сер­веров или к сетево­му обо­рудо­ванию — ничего такого, чего нет у обыч­ного поль­зовате­ля. А зна­чит, обна­ружить зло­умыш­ленни­ка смо­жет любой сот­рудник — защитить свою ком­панию под силу каж­дому!

Уви­деть невиди­мое будет нашей целью. Уро­вень сети — это началь­ный этап прод­вижения хакера по внут­ренней инфраструк­туре. Его пер­вые шаги — те дей­ствия, которые зло­умыш­ленник будет совер­шать на ран­ней ста­дии сво­его про­ник­новения, то есть ког­да у него еще нет учет­ной записи в Active Directory и он ничего не зна­ет о тво­ей сети. И на этом эта­пе его дей­ствия могут быть дос­таточ­но спон­танны­ми и шум­ными.

Это пер­вый раунд нашего про­тивос­тояния с хакером. Край­не желатель­но успеть обна­ружить зло­умыш­ленни­ка на этом эта­пе, при­чем как мож­но рань­ше, пока он может еще не так мно­го и пока его дей­ствия оставля­ют сле­ды. Ведь чем даль­ше хакер прод­винет­ся, тем силь­нее он будет усколь­зать от нас, а ког­да он най­дет свою пер­вую домен­ную учет­ку, этот раунд завер­шится. Поэто­му defence-при­емы пред­став­лены в поряд­ке рос­та воз­можнос­тей хакера по мере его про­ник­новения в инфраструк­туру.

 

Сетевой сниффер

На­личие в сети сниф­фера не счи­тает­ся сетевой ата­кой, зато может быть хорошей пред­посыл­кой для выяв­ления наруши­телей. Порядоч­ный поль­зователь сниф­фер запус­кать не ста­нет, толь­ко если это не админ… Или хакер.

Очень час­то на ран­них ста­диях ата­ки, ког­да зло­умыш­ленник толь­ко получил дос­туп в сеть, он запус­кает сниф­фер. Это дает ему хоть какую‑то информа­цию о тво­ей сети. По дефол­ту некото­рые сниф­феры вмес­то IP-адре­са пыта­ются показать имя хос­та. Это озна­чает, что они резол­вят каж­дый новый IP-адрес услы­шан­ного пакета. Нап­ример, неак­курат­но запущен­ный популяр­ный сниф­фер tcpdump будет вес­ти себя подоб­ным обра­зом.

Ха­кер запус­кает сниф­фер

И на этой осо­бен­ности мож­но пой­мать любоз­натель­ного хакера, ведь его компь­ютер будет отправ­лять пред­ска­зуемые DNS-зап­росы. Но как нам узнать, что DNS-зап­рос был отправ­лен? Ведь логи DNS-сер­вера читать может далеко не каж­дый. Все прос­то: исполь­зуем нерекур­сивный DNS-зап­рос или зап­рос к его кешу.

В кор­поратив­ной сети DNS-сер­веры, как пра­вило, свои и общие для всех хос­тов. И если мы отпра­вим DNS-зап­рос на получе­ние какого‑либо име­ни и выс­тавим флаг norecurse, DNS-сер­вер будет обя­зан выдать нам имя толь­ко на осно­вании сво­его кеша. Если этот IP-адрес ник­то, кро­ме нас, не резол­вил, то мы всег­да будем получать пус­той ответ.

Зап­рос к кешу DNS-сер­вера несущес­тву­ющей записи

Но если этот адрес кто‑либо в сети резол­вил за пос­леднее вре­мя, мы уви­дим сле­дующую кар­тину.

При­мер неяв­ного DNS-резол­ва

Пов­торный DNS-зап­рос к кешу даст это понять, и мы уви­дим иную кар­тину.

Зап­рос к кешу DNS-сер­вера сущес­тву­ющей записи

По­доб­ное мож­но выпол­нить и для пре­обра­зова­ния IP-адре­са в DNS-имя. Выходит, если меж­ду DNS-зап­росами на всю под­сеть широко­веща­тель­но или тар­гетиро­ван­но отправ­лять пакет в дру­гие под­сети от име­ни некото­рого непопу­ляр­ного IP-адре­са, обла­дающе­го DNS-име­нем, то запущен­ный у кого‑то сниф­фер выдаст себя DNS-зап­росом, резуль­тат которо­го потом ося­дет в кеше кор­поратив­ного DNS-сер­вера.

Ха­кер­ский сниф­фер выда­ет себя

В рас­смот­ренном при­мере узел 10.0.1.137 (хакер) сра­зу пос­ле при­нятия пакета с адре­сом 176.34.0.3 (любой внеш­ний IP с сущес­тву­ющим DNS-име­нем) выпол­няет раз­решение его IP в DNS-имя. И про­исхо­дит это при получе­нии единс­твен­ного сетево­го пакета. Этот ICMP-пакет не пред­назна­чен какому‑либо при­ложе­нию, он обра­баты­вает­ся на уров­не ОС, и при нор­маль­ных обсто­ятель­ствах на такой пакет прос­то нечему реаги­ровать DNS-зап­росом. Поэто­му с высокой долей веро­ятности мож­но сде­лать зак­лючение, что на этом узле запущен сетевой сниф­фер.

Вот при­мер неболь­шой авто­мати­зации опи­сан­ной выше про­вер­ки:

defence/sniffer.py#!/usr/bin/python3from scapy.all import *from netaddr import IPNetworkfrom time import sleepfrom sys import argvfrom os import systemIPS_WITH_PTR = IPNetwork("176.34.0.0/24")targets = []dns_servers = []conf.verb = 0alerts = []def alert(ip): if ip in alerts: return print("[!] sniffer detected %s" % ip) system("zenity --warning --title='sniffer detected' --text='sniffer detected: %s' &" % ip) #system("echo 'sniffer detected' | festival --tts --language english") alerts.append(ip)n = 1def get_source(): global n while True: ip = str(IPS_WITH_PTR[n]) if not dns_no_recurse(ip): return ip n += 1def dns_no_recurse(ip): def rev(ip): ip = ip.split(".") ip.reverse() return ".".join(ip) for dns_server in dns_servers: try: answer = sr1(IP(dst=dns_server)/UDP(dport=53)/DNS(rd=0, qd=DNSQR(qname=rev(ip)+".in-addr.arpa", qtype='PTR'))) if answer[DNS].ancount > 0: return True except: print(f"[-] {dns_server} has no answer")def probe(src, dst): send(IP(src=src, dst=dst)/ICMP())with open(argv[1]) as f: for line in f: targets.append( line.split("n")[0] )with open(argv[2]) as f: for line in f: dns_servers.append( line.split("n")[0] )src = get_source()while True: for dst in targets: probe(src, dst) sleep(1) if dns_no_recurse(src): alert(dst) src = get_source() sleep(60)

С этим скрип­том мы можем про­верять сниф­феры на любых IP-адре­сах, даже из дру­гих под­сетей, методич­но засылая им пакет и про­веряя, не сре­зол­вил ли какой‑либо хост этот адрес.

Де­тект сниф­фера

Кто‑то еще, кро­ме нас, зап­рашивал это имя, и узнать его мог толь­ко сниф­фер.

 

Сканирование портов

Про­бив сетевой периметр, хакер нач­нет смот­реть по сто­ронам, ска­нируя сетевые пор­ты. Это поз­волит ему понять, есть ли хос­ты рядом с ним, что­бы потом их ата­ковать, прод­винуть­ся даль­ше и еще более надеж­но зак­репить­ся в сети.

Ска­ниро­вание сетевых пор­тов — пер­вый и, пожалуй, обя­затель­ный этап любой сетевой ата­ки. Поэто­му было бы хорошо обна­ружить хакера уже на этом ран­нем эта­пе.

Как пра­вило, ска­ниру­ют пор­ты с помощью Nmap, и мало кто нас­тра­ивает этот инс­тру­мент в пла­не про­изво­дитель­нос­ти, осо­бен­но в мень­шую сто­рону. По дефол­ту Nmap дос­таточ­но силь­но шумит и отправ­ляет ров­но 100 пакетов TCP SYN в секун­ду для одной цели, про­веряя око­ло 1000 сетевых пор­тов. При нор­маль­ных усло­виях ни одна из легитим­ных прог­рамм такой сетевой активнос­ти не соз­дает. Так­же мож­но учесть харак­терную осо­бен­ность Nmap: он сту­чит­ся в каж­дый порт ров­но два раза. Это дефол­тное поведе­ние.

Дру­гой слу­чай исполь­зования Nmap — ска­ниро­вание малого количес­тва пор­тов на широком диапа­зоне хос­тов. Такой вари­ант ска­ниро­вания может исполь­зовать­ся для пред­варитель­ного опре­деле­ния «живых» хос­тов в сети или поис­ка так называ­емых низ­ко висящих фрук­тов (лег­кодос­тупных целей).

Но неваж­но, какой прог­раммой хакер ска­ниру­ет твои ресур­сы — Nmap, Masscan или чем‑то иным. Даже дру­гие более узкоспе­циали­зиро­ван­ные инс­тру­мен­ты (NBTscan, CrackMapExec, BloodHound) будут соз­давать исхо­дящие под­клю­чения, которые мож­но засечь.

Ес­ли хакер выпол­няет ска­ниро­вание, то, ско­рее все­го, и твой компь­ютер ока­жет­ся прос­каниро­ван. Поэто­му все, что нам нуж­но, — это монито­рить вхо­дящие под­клю­чения:

defence/tcp.py#!/usr/bin/python3import logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *from os import systemfrom sys import argvMAX_PORTS_ALLOWED = 2clients = {}alerts = []def alert(src_ip): if src_ip in alerts: return print("[!] port scanning %s" % src_ip) system("zenity --warning --title='port scanning detected' --text='port scanning detected' &") #system("echo 'port scanning detected' | festival --tts --language english") alerts.append(src_ip)def parse(p): if IP in p and TCP in p: src_ip = p[IP].src src_port = p[TCP].sport dst_port = p[TCP].dport print("[+] %s:%d -> %s:%d" % (src_ip, src_port, ip, dst_port)) if not src_ip in clients: clients[src_ip] = set() clients[src_ip].add(dst_port) if len(clients[src_ip]) > MAX_PORTS_ALLOWED: alert(src_ip)conf.iface = argv[1]ip = conf.iface.ipsniff(iface=conf.iface, prn=parse, filter='tcp[tcpflags] == tcp-syn and dst host %s'%ip)

Да­же если хакер будет тише, чем MAX_PORTS_ALLOWED, в логе скрип­та мы все рав­но уви­дим попыт­ку вхо­дяще­го под­клю­чения.

Де­тект ска­ниро­вания пор­тов

А в этом слу­чае хакер пре­высил MAX_PORTS_ALLOWED и попал­ся на ска­ниро­вании все­го трех пор­тов.

Ха­кер ска­ниро­вал сетевые пор­ты

При нор­маль­ных обсто­ятель­ствах кли­ент­ские ОС не будут под­клю­чать­ся к друг дру­гу, по край­ней мере более чем на один‑два пор­та. Так что, если ты запус­тишь этот скрипт на обыч­ной рабочей стан­ции, он с боль­шой долей веро­ятности смо­жет задетек­тить зло­умыш­ленни­ка.

Опи­сан­ная про­вер­ка, пожалуй, одна из наибо­лее дей­ствен­ных.

 

Обнаружение перехвата трафика

Ата­ки перех­вата тра­фика мож­но детек­тировать дву­мя метода­ми:

  • обна­ружи­вая пред­шес­тву­ющие ата­ки на соот­ветс­тву­ющие про­токо­лы (ARP, DHCP, CDP, HSRP, etc.);
  • выяв­ляя уже сам факт изме­нения мар­шру­тиза­ции.

Пы­тать­ся выявить ата­ки на тот же ARP мож­но раз­ными спо­соба­ми и тут же при­думать спо­соб обхо­да. Поэто­му надеж­нее вто­рой спо­соб, ведь всё так или ина­че ведет к нему.

Есть один прос­той, но вер­ный при­ем, который поз­воля­ет понять, что твой тра­фик перех­ватыва­ется. Как извес­тно, каж­дый узел, через который про­ходит тра­фик, умень­шает IP.ttl на еди­ницу. При этом его началь­ное зна­чение фик­сирован­ное — 255, 128, 64, 32. Это поз­воля­ет как минимум видеть дли­ну сетево­го мар­шру­та до опре­делен­ного узла.

Ата­ки перех­вата тра­фика час­то реали­зуют­ся в пре­делах сетево­го сег­мента, ког­да ата­кующий ста­новит­ся меж­ду нами и шлю­зом. Шлюз — это бли­жай­шее к нам сетевое устрой­ство, пересы­лающее наш тра­фик даль­ше. Сле­дова­тель­но, мы можем про­верять перех­ват сво­его тра­фика, прос­то пин­гуя шлюз.

IP.ttl шлю­за не меня­ется

У сетевых устрой­ств Cisco началь­ный IP.ttl час­то равен 255, и мы видим, что он не меня­ется, — зна­чит, меж­ду нами и шлю­зом никого нет. Но если в этот момент хакер, находя­щий­ся где‑то рядом с нами, начал шалить, кар­тина изме­нит­ся.

Ха­кер перех­ватыва­ет тра­фик всей под­сети

Мы тут же уви­дим это по умень­шению IP.ttl.

Из­менение рас­сто­яния до шлю­за жертв ата­ки перех­вата тра­фика

А выпол­нив трас­сиров­ку, мы уви­дим рас­положе­ние наг­леца, встав­шего перед шлю­зом.

По­явля­ется допол­нитель­ный хоп

И вспом­нив, что у Windows ttl = 128, а у Linux — 64, по тому же пин­гу мы понима­ем, что сре­ди офис­ных ком­пов на Windows появил­ся кто‑то на Linux, воз­можно даже Kali.

IP.ttl выда­ет опе­раци­онную сис­тему хакера

Це­лое рас­сле­дова­ние было про­веде­но лишь при помощи баналь­ного ping.

По­доб­ным обра­зом мы можем выяв­лять ата­ки перех­вата тра­фика даже в дру­гих под­сетях. Ведь мы в сос­тоянии засылать ping на любой узел и монито­рить, как изме­няет­ся его IP.ttl.

Вы­явле­ние ата­ки перех­вата тра­фика в даль­нем сетевом сег­менте

А еще мы можем опре­делить путь сле­дова­ния.

Вы­явле­ние хакер­ско­го компь­юте­ра, вме­шав­шегося в сетевой тра­фик в дру­гом сег­менте

Источник: xakep.ru

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *