November 5, 2008

Wrap your shell commands

One of the most annoying matter I have met when administrating a server was following and fixing messes other users (who happen to have root password) would do on the server.

Random users with root passwords often know two things… “sh” and “history -c”… and of course “I didn’t do it”.

Now, while it is important to keep logs of activities on the server, it is even better to be able to pull up logs of every single commands entered plus their arguments.

Here is a little C wrapper once can use to wrap /bin/sh so that every commands gets logged.

Now, we first need to backup our current sh executable…  so

mv /bin/sh /bin/shb

[sourcecode language=‘c’]

#include #include #include #include #include #include

#define LOG_FILE “/var/log/sh.log” #define LOG_FLAGS O_CREAT|O_APPEND|O_WRONLY #define LOG_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH #define WRAPPER “/bin/shb”

int main (int argc, char **const argv) { FILE * logfile = fopen (LOG_FILE, “a”); const char * program = argv[0]; argv[0] = WRAPPER; if (logfile) { struct passwd *pw = getpwuid (geteuid ()); int i = 0; fprintf (logfile, “(%s)”, pw->pw_name);

for (i = 0; i < argc; ++i) fprintf (logfile, “ ‘%s’”, argv[i]);

fprintf (logfile, “\n”); fclose (logfile); chmod (LOG_FILE, LOG_MODE); }

execv (argv[0], argv);

exit (EXIT_FAILURE);

}

[/sourcecode]

Now, compile your code into an sh executable.

Move your newly compiled sh into /bin/

And voila :)… whenever someone executes /bin/sh… a log will be generated in /var/log/sh.log