jvns / dnspeep

spy on the DNS queries your computer is making
MIT License
1.35k stars 57 forks source link

Print out PID of process that made the DNS query #14

Open jvns opened 3 years ago

jvns commented 3 years ago

Possibly using a similar approach to dnssnoop on Linux. I'm not sure how to do this on Mac though.

zenfish commented 3 years ago

If you use apple's tcpdump the -Q & -k switches you can get & control various associated metadata about traffic (process name, pid, etc; see the man page for tcpdump.) For instance to get all port 53 TCP/UDP calls you could simply do (as root or have network traffic read rights)-

# Example trace: a user doing a dig google.com call from the command line # tcpdump -k A port 53
tcpdump: data link type PKTAP tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on pktap, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes 16:00:49.184297 (en0, proc dig:47431:5bebfcad-8c40-3123-a6e8-44f8e4f03d0e, svc BE, out, so) IP lucky.50878 > flying.fish2.com.domain: 61587+ [1au] A? google.com. (39) 16:00:49.210408 (en0, proc dig:47431:5bebfcad-8c40-3123-a6e8-44f8e4f03d0e, svc BE, in, so) IP flying.fish2.com.domain > lucky.50878: 61587 1/4/9 A 142.251.33.78 (303) ^C 2 packets captured 9007 packets received by filter 0 packets dropped by kernel

No idea if rust supports that sort of metadata reading... I suppose you could run tcpdump inside rust and get pcap data from the source vs their lib ;) Linux has eBPF (which dnssnoop uses) and other means to get the details, of course. (Dtrace is essentially dead in macos, alas, or you could have used that... using NKEs might be fruitful as well, but w/e works for ya.) There's a nifty tool that looks up apps associated w traffic (https://github.com/imsnif/bandwhich), but it seems to use lsof running in the background for its magic, which would be too slow to catch DNS queries.

Thanks for putting out the tools-n-schtuff, knowledge is always great to spread around.

jvns commented 3 years ago

@zenfish That tidbit about the -k flag is really interesting. I'm a bit confused about it though -- tcpdump on my Linux machine definitely doesn't have a -k option and I don't see it in the tcpdump man page on their official site.

Rust definitely supports anything that tcpdump can do (it's a programming language!), so if we could figure out how tcpdump is printing out the process name on your machine it would definitely be possible to do the same thing.

zenfish commented 3 years ago

Apparently Apple added some low-level functionality (how rare for them!) on their network interfaces and called in PKTAP (packet tap?); at least some of it is open source, so in theory Linux could use it, but I don't know of any who do.

Linux does have ePBF, which is sort of Dtrace on steroids (and actually works on modern systems)... it's what dnspoof uses (as you say in your writeup) - and actually, the code for dnspoof is really small (like, ~100 lines or so) and relatively easy to understand (I'm sure you could - heck, it looks like you even wrote up a bit using rust and eBPF!)

For macs, the rust dox at least mention PKTAP - https://docs.rs/pcap/0.8.1/pcap/struct.Linktype.html - perhaps some small changes would make your code suck up the extra metadata? I've not touched rust (yet? :)), but I see you use a slightly different way to get your pcaps, so this may or may not be what you want.....

Hopefully this helps a bit... if the above isn't clear feel free to ask for clarification or whatnot, happy to help if I can.

thomasmerz commented 2 years ago

Are there any news regarding this? In https://github.com/jvns/dnspeep/issues/26 it took me some time to get the root cause (process) that is querying so much nameservers (solution: it was my regular dnsping on some upstream dns resolvers 😉 )