Security Incidents mailing list archives
Re: Recognizing compromised binaries
From: dbrumley () RTFM STANFORD EDU (David Brumley)
Date: Wed, 23 Feb 2000 09:59:23 -0800
We little toolbox's of compiled binaries (some static...not all because static semantics don't always work, esp. when trying to figure out a name that goes w/ a process. trivial mod, I know but it's worked great to date) at: http://security.stanford.edu/binaries/ Some of the directories are restricted per licensing (aka our license w/ sun), but linux is there. I just do a: mkdir /tmp/sec cd /tmp/sec tar zxvf anti-rootkit.tgz chmod 500 * export PATH=/tmp/sec:${PATH} not fool proof, but often kitty proof. -david On Mon, 21 Feb 2000, Dominique Brezinski wrote:
At 08:39 PM 2/18/00 -0800, Stephen Friedl wrote:vivid, but one small point I've not seen before in this forum. The bad guy had compromised most of the obvious system binaries (ls, ps, netstat, etc.) so it was hard to identify even what was wrong.I recommend making a little tool kit on read-only media (CD_ROM is good) that you can mount on a suspect system to do this kind of analysis (when you don't know if anything has happened that warrants serious forensic analysis). You should only use statically compiled binaries in this tool kit, and there are some environmental things to watch out for (I did a little presentation at BlackHat Briefings last year that you can check out here: http://www.blackhat.com/html/bh-usa-99/bh3-speakers.html) Here is the source to a little program that will print out stat info for a file *or* a directory and its contents (but will not recurse to subdirectories)--it is probably better than ls for forensic purposes. My employer nor myself express any warranty, explicit or implied, of any kind with regards to the following code or its fitness of use: --------CUT HERE-------------- #include <sys/stat.h> #include <stdio.h> #include <time.h> #include <errno.h> #include <dirent.h> #include <string.h> char* FixupArg(char*, char*, int); int main(int argc, char** argv) { char target[PATH_MAX + 1] = {'\0'}; struct stat statInfo; struct dirent* pDirEntryInfo = NULL; DIR* pDir = NULL; if (argc != 2) { printf("Usage: %s <filename or directory>\n", argv[0]); exit(1); } else { /* Initialize resources */ if (FixupArg(argv[1], target, PATH_MAX) == NULL) { exit(0); } } if (lstat(target, &statInfo)) { printf("failed to lstat() file - errno %d\n", errno); exit(1); } printf("\n%s\n", target); printf("ctime: %s", asctime(gmtime(&(statInfo.st_ctime)))); printf("atime: %s", asctime(gmtime(&(statInfo.st_atime)))); printf("mtime: %s", asctime(gmtime(&(statInfo.st_mtime)))); printf("owner: %d\ngroup: %d\nsize in bytes: %d\nINode number: %d\nfile gen number: %d\n", statInfo.st_uid, statInfo.st_gid, statInfo.st_size, statInfo.st_i no, statInfo.st_gen); if (S_ISDIR(statInfo.st_mode)) { /* we have a directory, so recurse through it calling lstat() on each * entry as we go. */ pDir = opendir(target); if (pDir == NULL) { printf("opendir() failed\n"); exit(1); } for (pDirEntryInfo = readdir(pDir); \ pDirEntryInfo != NULL; \ pDirEntryInfo = readdir(pDir)) { char targetFile[PATH_MAX + 1] = {'\0'}; if (!strncmp(pDirEntryInfo->d_name, ".", PATH_MAX) || !strncmp(pDirEntryInfo->d_name, "..", PATH_MAX)) { continue; } else { strncpy(targetFile, target, PATH_MAX); strncat(targetFile, "/", PATH_MAX - strlen(targetFile)); strncat(targetFile, pDirEntryInfo->d_name, PATH_MAX - strlen(targetFile)); } if (lstat(targetFile, &statInfo)) { printf("failed lstat() file %s -errno %d\n", targetFile, errno); continue; } else { printf("\n%s\n", targetFile); printf("ctime: %s", asctime(gmtime(&(statInfo.st_ctime)))); printf("atime: %s", asctime(gmtime(&(statInfo.st_atime)))); printf("mtime: %s", asctime(gmtime(&(statInfo.st_mtime)))); printf("owner: %d\ngroup: %d\nsize in bytes: %d\nINode number: %d\nfil e gen number: %d\n", statInfo.st_uid, statInfo.st_gid, statInfo.st_size, statInf o.st_ino, statInfo.st_gen); } } /* end for (readdir()) */ closedir(pDir); } /* end if (S_ISDIR) */ free(target); exit(0); } char* FixupArg(char* arg, char* fixedArg, int fixedArgLen) { /* check if the arg looks to be absolute path */ if (*arg == '/') { strncpy(fixedArg, arg, fixedArgLen); } else { /* looks like we have a relative path, so handle it appropriately */ if (strlen(arg) < PATH_MAX && fixedArgLen >= PATH_MAX) { if (realpath(arg, fixedArg) == NULL) { printf("relative/absolute path translation failed\n"); return (NULL); } } else { printf("Relative path given is too long or supplied buffer too small\n"); return (NULL); } } return (fixedArg); } ----------CUT HERE--------------------- The output looks like this: dbrez@it[104]>./stat ../rstat /home/dbrez/src/rstat ctime: Tue Feb 22 00:57:25 2000 atime: Tue Feb 22 00:57:56 2000 mtime: Tue Feb 22 00:57:25 2000 owner: 6254 group: 229 size in bytes: 4096 INode number: 4015042 file gen number: 0 /home/dbrez/src/rstat/stat ctime: Tue Feb 22 01:26:28 2000 atime: Tue Feb 22 01:26:28 2000 mtime: Tue Feb 22 01:26:28 2000 owner: 6254 group: 229 size in bytes: 24576 INode number: 4323271 file gen number: 0 /home/dbrez/src/rstat/rstat.c ctime: Tue Feb 22 01:26:22 2000 atime: Tue Feb 22 01:26:22 2000 mtime: Tue Feb 22 01:26:22 2000 owner: 6254 group: 229 size in bytes: 3319 INode number: 1048607 file gen number: 0 --- Dominique Brezinski Amazon.com Security office (206) 266-6900 pager (888) 916-2747 8312 ADAB C5B2 1916 CBD8 150E 37CE 044E F45F B5E4
-- #+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+# David Brumley - Stanford Computer Security - dbrumley () Stanford EDU Phone: +1-650-723-2445 WWW: http://www.stanford.edu/~dbrumley Fax: +1-650-725-9121 PGP: finger dbrumley-pgp () sunset Stanford EDU #+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+#+--+# c:\winnt> secure_nt.exe Securing NT. Insert Linux boot disk to continue...... "I have opinions, my employer does not."
Current thread:
- Recognizing compromised binaries Stephen Friedl (Feb 18)
- Re: Recognizing compromised binaries Dominique Brezinski (Feb 21)
- Re: Recognizing compromised binaries David Brumley (Feb 23)
- <Possible follow-ups>
- Re: Recognizing compromised binaries Dominique Brezinski (Feb 23)
- Re: Recognizing compromised binaries Dominique Brezinski (Feb 21)