Ma machine fait continuellement une demande de trafic DNS udp. ce que je dois savoir, c'est le PID du processus générant ce trafic.
La manière normale dans la connexion TCP est d'utiliser netstat/lsof et d'obtenir le processus associé au pid.
Est UDP la connexion est stateles, donc, quand j'appelle netastat/lsof, je ne peux le voir que si le socket UDP est ouvert et qu'il envoie du trafic.
J'ai essayé avec lsof -i UDP
et avec nestat -anpue
, mais je ne trouve pas quel processus fait cette demande car j'ai besoin d'appeler lsof/netstat exactement quand le trafic udp est envoyé, si j'appelle lsof/netstat avant/après l'envoi du datagramme udp, il est impossible de voir le ouvert socket UDP.
Appel netstat/lsof exactement quand 3/4 paquet udp est envoyé est IMPOSSIBLE.
Comment puis-je identifier le processus infâme? J'ai déjà inspecté le trafic pour essayer d'identifier le PID envoyé à partir du contenu du paquet, mais il n'est pas possible de l'identifier à partir du contexte du trafic.
Est-ce que quelqu'un peut m'aider ?
Je suis root sur cette machine Fedora 12 Linux noise.company.lan 2.6.32.16-141.fc12.x86_64 # 1 SMP mer 7 juil 04:49:59 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
L'audit Linux peut vous aider. Il localisera au moins les utilisateurs et les processus établissant des connexions réseau de datagrammes. Les paquets UDP sont des datagrammes.
Tout d'abord, installez le framework auditd
sur votre plate-forme et assurez-vous que auditctl -l
Renvoie quelque chose, même s'il indique qu'aucune règle n'est définie.
Ensuite, ajoutez une règle pour surveiller l'appel système socket()
et étiquetez-la pour une recherche facile plus tard (-k
). Je dois supposer que vous êtes sur une architecture 64 bits, mais vous pouvez remplacer b32
À la place de b64
Si vous ne l'êtes pas.
auditctl -a exit,always -F Arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET
Vous devez parcourir les pages de manuel et les fichiers d'en-tête pour le créer, mais ce qu'il capture est essentiellement cet appel système: socket(PF_INET, SOCK_DGRAM|X, Y)
, où le troisième paramètre n'est pas spécifié mais souvent zéro. PF_INET
Vaut 2 et SOCK_DGRAM
Vaut 2. TCP utiliseraient SOCK_STREAM
Qui définirait a1=1
. (SOCK_DGRAM
Dans le deuxième paramètre peut être OR avec SOCK_NONBLOCK
Ou SOCK_CLOEXEC
, D'où la comparaison &=
.) Le -k SOCKET
Est notre mot-clé que nous voulons utiliser lors de la recherche de pistes d'audit plus tard. Cela peut être n'importe quoi, mais j'aime rester simple.
Laissez quelques instants passer en revue les pistes d'audit. Vous pouvez éventuellement forcer quelques paquets en envoyant une requête ping à un hôte sur le net, ce qui entraînera une recherche DNS, qui utilise UDP, ce qui devrait déclencher notre alerte d'audit.
ausearch -i -ts today -k SOCKET
Et une sortie similaire à la section ci-dessous apparaîtra. Je l'abrège pour mettre en évidence les parties importantes
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
Dans la sortie ci-dessus, nous pouvons voir que la commande ping
a provoqué l'ouverture du socket. Je pourrais alors exécuter strace -p 14510
Sur le processus, s'il était toujours en cours d'exécution. Le ppid
(ID de processus parent) est également répertorié au cas où il s'agirait d'un script qui engendre beaucoup le problème enfant.
Maintenant, si vous avez beaucoup de trafic UDP, cela ne sera pas suffisant et vous devrez recourir à OProfile ou SystemTap , les deux étant actuellement au-delà de mon expertise.
Cela devrait aider à réduire les choses dans le cas général.
Lorsque vous avez terminé, supprimez la règle d'audit en utilisant la même ligne que celle utilisée pour la créer, remplacez uniquement -a
Par -d
.
auditctl -d exit,always -F Arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET
Vous pouvez utiliser netstat, mais vous avez besoin des bons indicateurs, et cela ne fonctionne que si le processus qui envoie les données est toujours vivant. Il ne trouvera pas les traces de quelque chose qui est venu brièvement à la vie, a envoyé du trafic UDP, puis s'est envolé. Il nécessite également des privilèges root locaux. Cela dit:
Voici moi qui démarre un ncat sur mon hôte local, en envoyant du trafic UDP vers le port 2345 sur une machine (inexistante) 10.11.12.13:
[madhatta@risby]$ ncat -u 10.11.12.13 2345 < /dev/urandom
Voici une sortie tcpdump prouvant que le trafic va:
[root@risby ~]# 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
Voici le bit utile, en utilisant netstat avec le drapeau -a (pour voir les détails du port) et le drapeau -p pour voir les détails de l'ID de processus. C'est l'indicateur -p qui nécessite des privilèges root:
[root@risby ~]# netstat -apn|grep -w 2345
udp 0 0 192.168.3.11:57550 10.11.12.13:2345 ESTABLISHED 9152/ncat
Comme vous pouvez le voir, le pid 9152 est considéré comme ayant une connexion ouverte au port 2345 sur l'hôte distant spécifié. Netstat exécute également cela via ps et me dit que le nom du processus est ncat
.
J'espère que cela vous sera utile.
J'ai eu exactement le même problème et malheureusement auditd
n'a pas fait grand chose pour moi.
J'ai eu du trafic provenant de certains de mes serveurs vers des adresses DNS Google, 8.8.8.8
et 8.8.4.4
. Maintenant, mon administrateur réseau a un trouble obsessionnel-compulsif léger et il voulait nettoyer tout le trafic inutile puisque nous avons nos caches DNS internes. Il voulait désactiver le port sortant 53 pour tout le monde, à l'exception des serveurs de cache.
Donc, après avoir échoué avec auditctl
, je creuse dans systemtap
. Je viens avec le script suivant:
# 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
Exécutez ensuite simplement:
stap -v udp_detect_domain.stp
Voici la sortie que j'ai obtenue:
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
C'est ça! Après avoir changé resolv.conf
ces PID n'ont pas détecté les modifications.
J'espère que cela t'aides :)
Voici une option systemtap, utilisant les sondes netfilter disponibles dans stap verson 1.8 et versions ultérieures. Voir également 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
J'utiliserais un net-sniffer comme tcpdump ou cableshark pour afficher les requêtes DNS. Le contenu de la requête peut donner une idée du programme qui les émet.
Sachez que lorsque vous utilisez autitctl, nscd par exemple utilise un paramètre légèrement différent dans l'appel système de socket, lors d'une requête DNS:
socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP)
Donc, pour vous assurer que vous interceptez ces requêtes en plus de celles qui ont été mentionnées ci-dessus, vous pouvez ajouter un filtre supplémentaire, avec le même nom si vous le souhaitez:
auditctl -a exit,always -F Arch=b64 -F a0=2 -F a1=2050 -S socket -k SOCKET
Ici 2050 est un bit OR de SOCK_DGRAM (2) et SOCK_NONBLOCK (2048).
Ensuite, la recherche trouvera ces deux filtres avec la même clé, SOCKET
:
ausearch -i -ts today -k SOCKET
Les valeurs hexadécimales pour les constantes de socket que j'ai trouvées ici: https://golang.org/pkg/syscall/#pkg-constants
Comme je n'ai pas de points de réputation à commenter, j'ai ajouté ceci.