Řešení 1:
Linuxový audit může pomoci. Alespoň lokalizuje uživatele a procesy vytvářející datagramová síťová připojení. Pakety UDP jsou datagramy.
Nejprve nainstalujte auditd
framework na vaší platformě a ujistěte se, že auditctl -l
vrátí něco, i když říká, že nejsou definována žádná pravidla.
Poté přidejte pravidlo, které bude sledovat systémové volání socket()
a označte jej pro pozdější snadné nalezení (-k
). Musím předpokládat, že používáte 64bitovou architekturu, ale můžete nahradit b32
místo b64
pokud nejste.
auditctl -a exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET
Chcete-li to sestavit, musíte si vybrat manuálové stránky a hlavičkové soubory, ale to, co zachycuje, je v podstatě toto systémové volání:socket(PF_INET, SOCK_DGRAM|X, Y)
, kde třetí parametr není specifikován, ale často je nulový. PF_INET
je 2 a SOCK_DGRAM
je 2. TCP spojení bude používat SOCK_STREAM
což by nastavilo a1=1
. (SOCK_DGRAM
ve druhém parametru může být OR s SOCK_NONBLOCK
nebo SOCK_CLOEXEC
, tedy &=
porovnání.) -k SOCKET
je naše klíčové slovo, které chceme později použít při hledání auditních záznamů. Může to být cokoliv, ale rád to zjednoduším.
Nechte pár okamžiků plynout a prohlédněte si auditní záznamy. Volitelně můžete vynutit několik paketů odesláním příkazu ping hostiteli ze sítě, což způsobí vyhledání DNS, které používá UDP, což by mělo vypnout naše upozornění na audit.
ausearch -i -ts today -k SOCKET
A zobrazí se výstup podobný sekci níže. Zkracuji to, abych zdůraznil důležité části
type=SYSCALL ... arch=x86_64 syscall=socket success=yes exit=1 a0=2 a1=2 ... pid=14510 ... auid=zlagtime uid=zlagtime ... euid=zlagtime ... comm=ping exe=/usr/bin/ping key=SOCKET
Ve výše uvedeném výstupu vidíme, že ping
příkaz způsobil otevření zásuvky. Potom bych mohl spustit strace -p 14510
na procesu, pokud stále běží. ppid
(ID rodičovského procesu) je také uvedeno v případě, že se jedná o skript, který často vytváří problémové dítě.
Nyní, pokud máte velký provoz UDP, nebude to dost dobré a budete se muset uchýlit k OProfile nebo SystemTap, které jsou v současné době mimo mé odborné znalosti.
To by mělo pomoci zúžit věci v obecném případě.
Až budete hotovi, odstraňte pravidlo auditu pomocí stejného řádku, který jste použili k jeho vytvoření, pouze nahraďte -a
s -d
.
auditctl -d exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET
Řešení 2:
Můžete použít netstat, ale potřebujete správné příznaky a funguje to pouze v případě, že proces, který odesílá data, je stále naživu. Nenajde stopy něčeho, co krátce ožilo, odeslalo provoz UDP a pak odešlo. Vyžaduje také místní oprávnění root. To řeklo:
Zde začínám ncat na svém místním hostiteli a odesílám UDP provoz na port 2345 na (neexistujícím) počítači 10.11.12.13:
[[email protected]]$ ncat -u 10.11.12.13 2345 < /dev/urandom
Zde je nějaký výstup tcpdump dokazující, že provoz běží:
[[email protected] ~]# tcpdump -n -n port 2345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:41:32.391750 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.399723 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.401817 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.407051 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.413492 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.417417 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
Tady je užitečná část pomocí netstat s parametrem -a (pro zobrazení podrobností o portu) a parametrem -p pro zobrazení podrobností o ID procesu. Je to příznak -p, který vyžaduje oprávnění root:
[[email protected] ~]# netstat -apn|grep -w 2345
udp 0 0 192.168.3.11:57550 10.11.12.13:2345 ESTABLISHED 9152/ncat
Jak můžete vidět, pid 9152 je označen jako mající otevřené připojení k portu 2345 na zadaném vzdáleném hostiteli. Netstat to také užitečně spustí přes ps a řekne mi, že název procesu je ncat
.
Snad to k něčemu bude.
Řešení 3:
Měl jsem úplně stejný problém a bohužel auditd
moc pro mě neudělal.
Provoz z některých mých serverů směřoval na adresy DNS společnosti Google, 8.8.8.8
a 8.8.4.4
. Nyní má můj správce sítě mírné OCD a chtěl vyčistit veškerý zbytečný provoz, protože máme naše interní mezipaměti DNS. Chtěl zakázat odchozí port 53 pro všechny kromě těchto vyrovnávacích serverů.
Takže po selhání s auditctl
, ponořím se do systemtap
. Přišel jsem s následujícím skriptem:
# cat >> udp_detect_domain.stp <<EOF
probe udp.sendmsg {
if ( dport == 53 && daddr == "8.8.8.8" ) {
printf ("PID %5d (%s) sent UDP to %15s 53\n", pid(), execname(), daddr)
}
}
EOF
Pak jednoduše spusťte:
stap -v udp_detect_domain.stp
Toto je výstup, který jsem dostal:
PID 3501 (python) sent UDP to 8.8.8.8 53
PID 3501 (python) sent UDP to 8.8.8.8 53
PID 3506 (python) sent UDP to 8.8.8.8 53
A je to! Po změně resolv.conf
tyto PID nezachytily změny.
Doufám, že to pomůže :)
Řešení 4:
Zde je možnost systemtap pomocí sond netfilter dostupných ve verzi stap 1.8 a novější. Viz také man probe::netfilter.ip.local_out
.
# stap -e 'probe netfilter.ip.local_out {
if (dport == 53) # or parametrize
printf("%s[%d] %s:%d\n", execname(), pid(), daddr, dport)
}'
ping[24738] 192.168.1.10:53
ping[24738] 192.168.1.10:53
^C
Řešení 5:
K zobrazení požadavků DNS bych použil síťový sniffer, jako je tcpdump nebo wireshark. Obsah dotazu může poskytnout představu o tom, jaký program je vydává.