Re: Incident investigation methodologies
Valdis.Kletnieks_at_vt.edu
Date: 06/04/04
- Previous message: Jon Coller: "Re: Incident investigation methodologies"
- In reply to: Paul Schmehl: "Re: Incident investigation methodologies"
- Next in thread: Harlan Carvey: "Re: Incident investigation methodologies"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
To: Paul Schmehl <pauls@utdallas.edu> Date: Fri, 04 Jun 2004 15:14:58 -0400
On Fri, 04 Jun 2004 10:42:46 CDT, Paul Schmehl <pauls@utdallas.edu> said:
> For example, a statically compiled copy of ls on a CD is going to show you
> what's on the hard drive of a unix machine no matter what the rootkit may
> have done.
Umm.. No. ;) A statically linked /bin/ls will protect you against a
trojaned libc.a, but it won't protect you against a kernel that's actively
lying to you.
Consider that every copy of /bin/ls I've encountered in 25 years basically
relied on things like readdir() and stat() returning the information requested.
If the kernel returns bogus values on stat(), /bin/ls will report the bogus
values.
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=121292
for an actual real-life example of a bug caused by /bin/ls reporting the Wrong
Thing because a system call *fails* (in this case, it does a stat() call, which
fails, and it then blindly reports the file owner as 'root' because the
never-filled-in 'struct stat' happened to have st_uid == 0).
Now... consider what happens to your statically-linked /bin/ls if it issues a
stat() system call, and this code (from the Linux 2.6.7-rc2-mm2 kernel fs/
inode.c):
void generic_fillattr(struct inode *inode, struct kstat *stat)
{
stat->dev = inode->i_sb->s_dev;
stat->ino = inode->i_ino;
stat->mode = inode->i_mode;
stat->nlink = inode->i_nlink;
stat->uid = inode->i_uid;
stat->gid = inode->i_gid;
stat->rdev = inode->i_rdev;
stat->atime = inode->i_atime;
stat->mtime = inode->i_mtime;
stat->ctime = inode->i_ctime;
stat->size = i_size_read(inode);
stat->blocks = inode->i_blocks;
stat->blksize = inode->i_blksize;
}
is modified by the rootkit to do this instead:
static struct kstat fake_binsu = {...} /* initialized to pre-trojaned stat() of /bin/su */
void malicious_fillattr(struct inode *inode, struct kstat *stat)
{
stat->dev = inode->i_sb->s_dev;
stat->ino = inode->i_ino;
stat->mode = inode->i_mode;
stat->nlink = inode->i_nlink;
stat->uid = inode->i_uid;
stat->gid = inode->i_gid;
stat->rdev = inode->i_rdev;
stat->atime = inode->i_atime;
stat->mtime = inode->i_mtime;
stat->ctime = inode->i_ctime;
stat->size = i_size_read(inode);
stat->blocks = inode->i_blocks;
stat->blksize = inode->i_blksize;
if (current->uid != 666 && (stat->dev == fake_binsu.dev) &&
(stat->ino == fake_binsu.ino)) {
stat = fake_binsu;
}
}
Hmm.. what do you know.. unless you're running as UID 666, doing a stat() on
/bin/su will report the old pre-trojaned size, mtime, atime, ctime, and permissions...
At that point, there's nothing ls can do about it.
If you have a program on that CD that opens the raw /dev/disk partition and
starts poking around the file system structure to find the actual inode out on
the oxide platter (a statically linked copy of the Linux ext2progs 'debugfs' or
the Solaris 'fsdb_ufs' or similar program appropriate for the file system)
would probably work well here), you might be in luck if the rootkit doesn't
fake the read() and write() calls for raw disk access (which none do as far as
I know). However, even that can fail - think about why there's a *reason*
you're not supposed to fsck a mounted partition...
- application/pgp-signature attachment: stored
- Previous message: Jon Coller: "Re: Incident investigation methodologies"
- In reply to: Paul Schmehl: "Re: Incident investigation methodologies"
- Next in thread: Harlan Carvey: "Re: Incident investigation methodologies"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|