Question

On linux, I'd like to quickly tie a running process to a promiscuous interface it created. For instance, tcpdump will change an interface when it starts and ends, and I'd like to efficiently associate that process to the promiscuous interface while it's running.

For instance, I would want this method to detect rogue malware that is sniffing.

Normally I could ps -ef | grep tcpdump, but in the malware case I may not know the process doing the work.

Also, for bonus points... if the process is no longer running, how would you determine how an interface was made promiscuous? (assuming it's not in .history)

Was it helpful?

Solution

Kernel will printk() a message when an interface is put into promiscuous mode. That message should end up in the system logs (usually in /var/log), though most likely your intruder will be smart enough to censor logs and hide his/her/its trail. The only correct answer to this challenge, in my humble opinion, is to have a remote logging server where at least some of the system messages are redirected in addition to storing them to a local disk.

To get more information into logs you could turn on kernel auditing by adding audit=1 to kernel command line.

An interface can be in promiscuous mode without any process actively "keeping" it as such. Actually, you can just turn on promiscuous mode for an interface with ip link set <interface> promisc on. Try it on your loopback interface with ip link set lo promisc on, see what netstat -i produces on your terminal, then turn promiscuous mode again off with ip link set lo promisc off and check once again with netstat -i how flags for the loopback interface have changed.

To answer your first question: there is no way to know which process keeps an interface in promiscuous mode as there might be such a process in the first place. The kernel doesn't have detailed process information at the point of __dev_set_promiscuity():

if (dev->flags != old_flags) {
        pr_info("device %s %s promiscuous mode\n",
                dev->name, 
                dev->flags & IFF_PROMISC ? "entered" : "left");
        if (audit_enabled) {
                current_uid_gid(&uid, &gid);
                audit_log(current->audit_context, GFP_ATOMIC,
                        AUDIT_ANOM_PROMISCUOUS,
                        "dev=%s prom=%d old_prom=%d auid=%u uid=%u gid=%u ses=%u",
                        dev->name, (dev->flags & IFF_PROMISC),
                        (old_flags & IFF_PROMISC),
                        from_kuid(&init_user_ns, audit_get_loginuid(current)),
                        from_kuid(&init_user_ns, uid),
                        from_kgid(&init_user_ns, gid),
                        audit_get_sessionid(current));
        }

For details, see file net/core/dev.c in the Linux kernel source tree.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top