Virus honeypot with quarantine (initial implementation)
Michael Gerdts
Michael.Gerdts at usa.alcatel.com
Wed May 2 11:56:10 GMT 2001
I have implemented much of what I talk about below, in a proof of concept
type of way. Most of the code is stolen from skel.c and audit.c.
To compile and install:
cp quarantine.c samba/examples/VFS
cd samba/examples/VFS
patch -p0 < Makefile.patch (On solaris 8, anyway)
make quarantine.so
cp quarantine.so /opt/samba/lib/quarantine.so
mkdir /quarantine
chmod 1777 /quarantine
This was on Solaris 8. The Makefile patch is needed to create the shared
library.
Note that samba must be configured --with-vfs
smb.conf:
[trap]
comment = virus trap
browseable = yes
writable = yes
guest = yes
path = /trap
vfs object = /opt/samba/lib/quarantine.so
I think that I have documented things that are really broken with FIXME
tags. I welcome any comments you may have.
Mike
On Tue, May 01, 2001 at 09:18:07AM -0400, Michael Gerdts wrote:
> While analyzing samba logs on a test server, I have found several machines
> that are crawling through guest accessible shares. Each one of them was a
> rogue machine that was in violation of our virus scanning software policy.
>
> I now realize how easy it is to identify potentially virus-infected
> machines. I would like to be able to change that from "potentially" to
> "definitely". My first thoughts were to provide a mechanism within samba
> that has shares that appear to be writable, but any changed files are
> actually written off to a quarantined area. The original file should never
> be changed.
>
> Presumably this could be done with the VFS layer. I think that the
> open call would be the only think that needed to be modified. Its behavior
> would be:
>
> If mode is:
>
> read-only - default_vfs_ops.open()
>
> write-only - create the quarantine file
> /quarantine/%S/%m/%u/origfilename.unique_id
> open the quarantine file
>
> read-write - copy file to quarantine file
> open the quarantine file
>
> I would then run a virus scanning program on the UNIX server to identify
> infected files in quarantine area.
>
> Is there anything that I am missing that I should be aware of?
>
> Mike
--
Mike Gerdts (919) 850-5284
Unix Systems Administrator Michael.Gerdts at usa.alcatel.com
-------------- next part --------------
/*
* Skeleton VFS module. Implements passthrough operation of all VFS
* calls to disk functions.
*
* Copyright (C) Tim Potter, 1999-2000
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* FIXME - use the safe string functions instead of snprintf, strncpy */
#define _SAFE_STRING_H
#include "config.h"
#include <stdio.h>
#include <sys/stat.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <errno.h>
#include <string.h>
#include <includes.h>
#include <vfs.h>
#ifndef SYSLOG_FACILITY
#define SYSLOG_FACILITY LOG_USER
#endif
#ifndef SYSLOG_PRIORITY
#define SYSLOG_PRIORITY LOG_NOTICE
#endif
static char *mystrchr(char *path, int c) {
char *p;
for ( p = path ; p != NULL && *p != '\0' ; p++ ) {
if ( *p == c ) {
return(p);
}
}
return(NULL);
}
/* Function prototypes */
/* File operations */
int quarantine_open(struct connection_struct *conn, char *fname, int flags, mode_t mode);
/* VFS operations structure */
/*FIXME the ops listed below with FIXME tags should probably just
return EPERM */
struct vfs_ops quarantine_ops = {
/* Disk operations */
NULL, /* quarantine_connect, */
NULL, /* quarantine_disconnect, */
NULL, /* quarantine_disk_free, */
/* Directory operations */
NULL, /* quarantine_opendir, */
NULL, /* quarantine_readdir, */
NULL, /* FIXME quarantine_mkdir, */
NULL, /* FIXME quarantine_rmdir, */
NULL, /* quarantine_closedir, */
/* File operations */
quarantine_open,
NULL, /* quarantine_close, */
NULL, /* quarantine_read, */
NULL, /* quarantine_write, */
NULL, /* quarantine_lseek, */
NULL, /* quarantine_rename, */
NULL, /* quarantine_fsync, */
NULL, /* quarantine_stat, */
NULL, /* quarantine_fstat, */
NULL, /* quarantine_lstat, */
NULL, /* FIXME quarantine_unlink, */
NULL, /* quarantine_chmod, */
NULL, /* quarantine_chown, */
NULL, /* quarantine_chdir, */
NULL, /* quarantine_getwd, */
NULL, /* quarantine_utime, */
NULL, /* FIXME quarantine_ftruncate, */
NULL, /* quarantine_lock, */
/* NT File ACL operations */
NULL, /* quarantine_fget_nt_acl, */
NULL, /* quarantine_get_nt_acl, */
NULL, /* quarantine_fset_nt_acl, */
NULL, /* quarantine_set_nt_acl */
};
/* VFS initialisation - return vfs_ops function pointer structure */
struct vfs_ops *vfs_init(int *vfs_version)
{
openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY);
*vfs_version = SMB_VFS_INTERFACE_VERSION;
return(&quarantine_ops);
}
/* Implementation of VFS functions. Insert your useful stuff here */
extern struct vfs_ops default_vfs_ops; /* For passthrough operation */
int quarantine_open(struct connection_struct *conn, char *fname, int flags, mode_t mode)
{
char qfname[PATH_MAX+1];
char qfdir[PATH_MAX+1];
struct stat statbuf;
char *p, *file;
syslog(SYSLOG_PRIORITY, "quarantine_open(%s, 0%o, 0%o)\n",
fname, flags, mode);
/* FIXME for O_WRONLY and O_RDWR, if neither O_CREAT nor O_TRUNC
is given, the file (fname) should be copied to the quarantine
file (qfname) */
if (flags & (O_WRONLY | O_RDWR | O_CREAT | O_TRUNC | O_APPEND)) {
if (snprintf(qfname, PATH_MAX+1, "/quarantine/%s/%s/%s/%s",
conn->client_address, conn->user,
conn->origpath, fname)
> PATH_MAX) {
return(ENAMETOOLONG);
}
syslog(SYSLOG_PRIORITY, "quarantine_open: quarantine file is \"%s\"",
qfname);
strncpy(qfdir, qfname, PATH_MAX+1);
p = qfdir;
while ((p=mystrchr(p, '/')) != NULL) {
*p = '\0';
if (stat(qfdir,&statbuf) != 0) {
syslog(SYSLOG_PRIORITY, "quarantine_open: mkdir \"%s\"",
qfdir);
mkdir(qfdir, 01777);
}
*p = '/';
p++;
}
file = qfname;
}
else {
file = fname;
}
syslog(SYSLOG_PRIORITY, "quarantine_open: open(\"%s\", 0%o, 0%o)",
file, flags, mode);
return open(file, flags, mode);
}
/* vim: ts=8 sw=8
*/
-------------- next part --------------
Index: Makefile
===================================================================
RCS file: /cvsroot/samba/examples/VFS/Makefile,v
retrieving revision 1.3.4.2
diff -r1.3.4.2 Makefile
9a10
> #LIBTOOL =
25c26,27
< $(LIBTOOL) $(CC) -shared -o $@ $< $(LDFLAGS)
---
> #$(LIBTOOL) $(CC) -shared -o $@ $< $(LDFLAGS)
> ld -G -o $@ $< $(LDFLAGS)
More information about the samba-technical
mailing list