📄 env_audit.c
字号:
/* * env_audit - tests and records everything it can about its environment * This program is copyright (c) 2001-2002 * by Steve Grubb <linux_4ever@yahoo.com> ALL RIGHTS RESERVED * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Released 1.05 11/11/02 * Released 1.04 10/21/02 * Released 1.03 10/15/02 * Released 1.02 07/06/01 */#include <stdio.h>#include <unistd.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>#include <signal.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <netdb.h>#include <string.h>#include <sys/resource.h>#include <pwd.h>#include <grp.h>#include <termios.h>#include <stropts.h>#ifdef S_ISDOOR#include <door.h>#endif#ifdef _POSIX_CAP#include <sys/capability.h>#endif#ifndef PATH_MAX#define PATH_MAX 768#endif#ifndef SIGUNUSED#define SIGUNUSED NSIG-1#endif//#define NO_SIGTEST // <--- Uncomment if signal test annoys you #define VERSION "1.05"#define LOGFILE "/tmp/env_audit.log"extern char **environ;union val { int i_val; long l_val; char c_val[10]; struct linger linger_val; struct timeval timeval_val;#ifdef SO_PEERCRED struct ucred peercred;#endif} val;typedef union tsockaddr { struct sockaddr sa; struct sockaddr_in sa_in; struct sockaddr_in6 sa_in6; char pad[128];}xsockaddr;static char *str_flag(const union val *, int);static char *str_int(const union val *, int);static char *str_linger(const union val *, int);static char *str_timeval(const union val *, int);#ifdef SO_PEERCREDstatic char *str_cred(const union val *, int);#endifstatic void pr_limits(const char *name, int resource);#define print_limits(name) pr_limits(#name, name)static char *lookup_uid(int);static char *lookup_grp(int);static const char *lookup_family(int type);static void output_stream(int fd);static char *find_inode(int d, int leaked);struct sock_opts { const char *opt_str; int opt_level; int opt_name; char *(*opt_val_str)(const union val *, int);} sock_opts[] = { {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, str_flag}, {"SO_DEBUG", SOL_SOCKET, SO_DEBUG, str_flag}, {"SO_DONTROUTE", SOL_SOCKET, SO_DONTROUTE, str_flag}, {"SO_ERROR", SOL_SOCKET, SO_ERROR, str_int}, {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, str_flag}, {"SO_LINGER", SOL_SOCKET, SO_LINGER, str_linger}, {"SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE, str_flag}, {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, str_int}, {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, str_int}, {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, str_int}, {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, str_int}, {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, str_timeval}, {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, str_timeval}, {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, str_flag},#ifdef SO_REUSEPORT {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, str_flag},#else {"SO_REUSEPORT", 0, 0, NULL},#endif {"SO_TYPE", SOL_SOCKET, SO_TYPE, str_int},#ifdef SO_USELOOPBACK {"SO_USELOOPBACK", SOL_SOCKET, SO_USELOOPBACK, str_flag},#else {"SO_USELOOPBACK", 0, 0, NULL},#endif {"IP_TOS", IPPROTO_IP, IP_TOS, str_int}, {"IP_TTL", IPPROTO_IP, IP_TTL, str_int},#ifdef IPV6_ADDRFORM {"IPV6_ADDRFORM", IPPROTO_IPV6, IPV6_ADDRFORM, str_flag},#else {"IPV6_ADDRFORM", 0, 0, NULL},#endif#ifdef IPV6_IPV6ONLY {"IPV6_IPV6ONLY", IPPROTO_IPV6, IPV6_IPV6ONLY, str_flag},#else {"IPV6_IPV6ONLY", 0, 0, NULL},#endif {"TCP_MAXSEG", IPPROTO_TCP, TCP_MAXSEG, str_int}, {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, str_flag},#ifdef SO_PEERCRED {"SO_PEERCRED", SOL_SOCKET, SO_PEERCRED, str_cred},#endif {NULL, 0, 0, NULL}};FILE *f = 0;static char found_file[PATH_MAX+1];int main(int argc, char *argv[]){ int i, fn; char *ptr, **pptr, cwd_buf[128]; sigset_t sigset; /* * Check to see if this is being run from a web server */ if (getenv("HTTP_ACCEPT")) { f = stdout; fprintf(f, "Content-type: text/plain\n\n"); } else { unlink(LOGFILE); f = fopen(LOGFILE, "wt"); if (f == NULL) return 1; } fn = fileno(f); fprintf(f, "Environment Audit version %s\n\n", VERSION); /* * We start of looking at the process ID stuff */ fprintf(f, "Process ID: %d\n", getpid()); fprintf(f, "Parent Process ID: %d\n", getppid()); fprintf(f, "User ID: %d - %s\n", getuid(), lookup_uid(getuid())); fprintf(f, "Group ID: %d - %s\n", getgid(), lookup_grp(getgid())); fprintf(f, "Effective User ID: %d - %s\n", geteuid(), lookup_uid(geteuid()) ); if ((geteuid() == 0) && (geteuid() != getuid())) fprintf(f, "Security hole - Effective ID is root and UID isn't\n"); fprintf(f, "Effective Group ID: %d - %s\n", getegid(), lookup_grp(getegid())); if ((getegid() == 0) && (getegid() != getgid())) fprintf(f, "Security hole - Effective Group ID is root and GID isn't\n"); if (getgroups(0,0) > 0) { gid_t *list; int num_groups = getgroups(0,0); fprintf(f, "Supplemental Groups: "); list = (gid_t *)malloc(sizeof(gid_t)*num_groups); if (list) { int op = 0, my_gid = getgid(); getgroups(num_groups, list); for (i=0; i<num_groups; i++) { if (i == my_gid) continue; if (op) fprintf(f, ", %s", lookup_grp(list[i])); else { fprintf(f, " %s", lookup_grp(list[i])); op = 1; } } free(list); } fprintf(f, "\n"); } if (getuid() != 0) { if (setuid(0) == 0) fprintf(f, "Warning - was able to regain root!\n"); } fprintf(f, "Process Group ID: %d\n", getpgrp()); fprintf(f, "Session ID: %d\n", getsid(getpid())); fprintf(f, "Parent Session ID: %d\n", getsid(getppid())); getcwd(cwd_buf, 127); fprintf(f, "Current Working Dir: %s\n", cwd_buf); fprintf(f, "Umask: %o\n", umask(777)); fprintf(f, "Process Priority: %d\n", getpriority(PRIO_PROCESS, 0)); /* * Now, lets take a look at the inherited signals */ sigprocmask(0, NULL, &sigset); for (i=1; i<=SIGUNUSED; i++) { if (sigismember(&sigset, i)) fprintf(f, "Signal %d-%s masked\n", i, strsignal(i)); }#ifndef NO_SIGTEST /* * Make sure we aren't sending signals to init just in case it * doesn't handle signals well...it could be impossible to boot * the system if env_audit is in the inittab and init dies when * SIGUSR1 is sent to it. */ if (getppid() > 2) { if (kill(getppid(), SIGUSR1) == 0) fprintf(f, "WARNING the child program can send signals to the parent.\n"); }#endif /* Dump Command Line arguments */ if (argc > 1) { fprintf(f, "\n---\nCommand Line Arguments\n"); for (i=1; i<argc; i++) fprintf(f, "Command Line Arg %d: %s\n", i, argv[i]); } /* Dump environmental variables */ fprintf(f, "\n---\nEnvironmental Variables\n"); pptr = environ; while(*pptr) fprintf(f, "$%s\n", *pptr++); ptr = getenv("LD_LIBRARY_PATH"); if (ptr) fprintf(f, "WARNING LD_LIBRARY_PATH is defined.\n"); ptr = getenv("LD_PRELOAD"); if (ptr) fprintf(f, "WARNING LD_PRELOAD is defined.\n"); ptr = getenv("IFS"); if (!ptr) fprintf(f, "WARNING $IFS undefined\n"); ptr = getenv("TZ"); if (!ptr) fprintf(f, "WARNING $TZ undefined\n"); ptr = getenv("HOSTALIASES"); if (ptr) fprintf(f, "WARNING HOSTALIASES: %s will be used for gethostbyname.\n", ptr); /* Examine the process rlimits */ fprintf(f, "\n---\nResource Limits\n"); fprintf(f, "Name Current Max\n"); print_limits(RLIMIT_CORE); print_limits(RLIMIT_CPU); print_limits(RLIMIT_DATA); print_limits(RLIMIT_FSIZE);#ifdef RLIMIT_MEMLOCK print_limits(RLIMIT_MEMLOCK);#endif#ifdef RLIMIT_NOFILE print_limits(RLIMIT_NOFILE);#endif#ifdef RLIMIT_OFILE print_limits(RLIMIT_OFILE);#endif#ifdef RLIMIT_NPROC print_limits(RLIMIT_NPROC);#endif#ifdef RLIMIT_RSS print_limits(RLIMIT_RSS);#endif print_limits(RLIMIT_STACK);#ifdef RLIMIT_VMEM print_limits(RLIMIT_VMEM);#else#ifdef RLIMIT_AS print_limits(RLIMIT_AS);#endif#endif #ifdef _POSIX_CAP // This is where Posix Capabilities will go. // This needs research to complete... fprintf(f, "\n---\nPosix Capabilities\n"); { char *res = 0; ssize_t len = 0; cap_t caps = cap_get_proc(); if (caps) res = cap_to_text(caps, &len); if (res) { if ( (len == 1)||(strcmp(res, "all=") == 0) ) fprintf(f, "Capabilities = ALL\n"); else fprintf(f, "Capabilities: '%s'\n", res); } else fprintf(f, "Error reading capabilities\n"); if (caps) cap_free(caps); }#endif fflush(f); /* Examine the file descriptors */ for (i=0; i< 1024; i++) { struct stat st; int val, am, std = 0, leaked = 0; if ((i == fn)&&(i != fileno(stdout))) continue; if (fstat(i, &st) == -1) continue; fprintf(f, "\n---\n"); fprintf(f, "Open file descriptor: %d\n", i); fprintf(f, "User ID of File Owner: %s\n", lookup_uid(st.st_uid)); fprintf(f, "Group ID of File Owner: %s\n", lookup_grp(st.st_gid)); if (fileno(stdin) == i) { fprintf(f, "Descriptor is stdin.\n"); std = 1; } else if (fileno(stdout) == i) { fprintf(f, "Descriptor is stdout.\n"); std = 1; } else if (fileno(stderr) == i) { fprintf(f, "Descriptor is stderr.\n"); std = 1; } else { fprintf(f, "WARNING - Descriptor is leaked from parent.\n"); leaked = 1; } if (std) { int fore; struct termios term; fore = tcgetattr(i, &term); if (fore != -1) { fprintf(f, "WARNING - process has controlling terminal\n"); } else { fprintf(f, "No controlling terminal\n"); } } fprintf(f, "File type: "); if (S_ISREG(st.st_mode)) { char *filename; fprintf(f, "regular file, inode: %ld, device: %d\n", st.st_ino, (int)st.st_dev); filename = find_inode(i, leaked); if (filename) { if (stat(filename, &st) == 0) { fprintf(f, "File's actual permissions: %o\n", st.st_mode & (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)); } else fprintf(f, "Cannot stat actual file\n"); } } else if (S_ISDIR(st.st_mode)) fprintf(f, "directory\n"); else if (S_ISCHR(st.st_mode)) { char *tptr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -