--- tcpdump-3.7.2/tcpdump.c Sat Dec 22 16:12:23 2001 +++ tcpdump-3.7.2-noroot/tcpdump.c Thu Jan 22 17:55:14 2004 @@ -58,6 +58,9 @@ #include #include +#include +#include + #include "interface.h" #include "addrtoname.h" @@ -91,6 +94,9 @@ int infodelay; int infoprint; +int uid = 0; /* the user id to run as */ +int gid = 0; /* the group id to run as */ + char *program_name; int32_t thiszone; /* seconds offset from gmt to local time */ @@ -101,6 +107,8 @@ static void dump_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); +void drop_privs(); + #ifdef SIGINFO RETSIGTYPE requestinfo(int); #endif @@ -218,7 +226,7 @@ opterr = 0; while ( - (op = getopt(argc, argv, "ac:C:deE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1) + (op = getopt(argc, argv, "ac:C:deE:fF:G:i:lm:nNOpqr:Rs:StT:uU:vw:xXY")) != -1) switch (op) { case 'a': @@ -260,6 +268,17 @@ infile = optarg; break; + case 'G': + { + struct group *gr = getgrnam(optarg); + + if (!gr) + error("invalid group `%s'.", optarg); + + gid = gr->gr_gid; + } + break; + case 'i': device = optarg; break; @@ -354,6 +373,17 @@ case 'u': ++uflag; break; + + case 'U': + { + struct passwd *pw = getpwnam(optarg); + + if (!pw) + error("invalid user `%s'", optarg); + + uid = pw->pw_uid; + } + break; case 'v': ++vflag; @@ -481,6 +511,10 @@ program_name, device); (void)fflush(stderr); } + + // Drop privileges to prevent root level compromises + drop_privs(); + if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) { (void)fprintf(stderr, "%s: pcap_loop: %s\n", program_name, pcap_geterr(pd)); @@ -619,6 +653,14 @@ default_print_unaligned(bp, length); } +void drop_privs() +{ + if (gid) + setregid(gid, gid); + if (uid) + setreuid(uid, uid); +} + #ifdef SIGINFO RETSIGTYPE requestinfo(int signo) { @@ -642,6 +684,8 @@ (void)fprintf(stderr, "\t\t[ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ]\n"); (void)fprintf(stderr, -"\t\t[ -T type ] [ -w file ] [ -E algo:secret ] [ expression ]\n"); +"\t\t[ -T type ] [ -w file ] [ -E algo:secret ] [ -U user ]\n"); + (void)fprintf(stderr, +"\t\t[ -G group ] [ expression ]\n"); exit(1); }