Tool-BarfreeBSD ArticlesSearch Our SiteHOMEfreeBSD LinksContribute to FreeBSD HelpFreeBSD FilesFreeBSD Script Corner

Securing Your Users' Command History

It is sometimes the case that a user on a Unix system will attempt to conceal their command history. This often can become bothersome to a sysadmin and perhaps lead to increased suspicion. If you do not already know, there are a few simple ways that you as an administrator can avoid many instances of this attempted evasion. Let's take a look at a couple of the more common methods taken by the user to conceal their history and discuss possible solutions.

Everything which we are about to discuss can be done on any soft of computer or laptop, whether the individual is using Free Mobile Broadband or another internet connection. It is common techniques that are broadly recognised. We hope the following is helpful to you.

 It is often seen that a user's attempt at concealment will involve the alteration/deletion of the history file. A few examples:

- frequent removal of the history file ( i.e. before each logout )

- symbolic linking of the history file to the null(4) device ( all data
  passed to the history file is thrown away )
- substitution of the history file with a directory

 One important benefit of a BSD-based Operation System which can aid in overall security of the File System is BSD's advent of file flags via chflags(1). As shown, all of the above examples involve at least the one initial deletion of the history file. This can be easily protected against with the simple addition of a file flag. Referenced from chflags(1):

sappnd set the system append-only flag (super-user only)

 The sappnd flag will allow for the normal addition of data to the file while locking it in every other way. The append-only flag is well suitable for protecting the history file as it still allows the shell to continue dumping its new command history while protecting against deletion and modification of the already existing bits.

Example Usage ( using bash as an example )

# whoami
# cd /home/example
# test -f .bash_history || { rm -rf .bash_history ; touch .bash_history; \
> chown example.example .bash_history; }
# chflags sappnd .bash_history

>From the user's perspective:

$ whoami
$ rm .bash_history
rm: .bash_history: Operation not permitted
$ echo > .bash_history
bash: .bash_history: Operation not permitted

 It should be stated that these restrictions also affect root and can only be defeated with the removal of the append-only flag by root via chflags. By running the system in kernel securelevel 1 or greater the removal of a sappnd flag from any file by any user can be protected against. Please refer to init(8) for more information on securelevel.


* The following section of this document will focus particularly on * the Bash shell. For the most part, variance between any of the 'Bourne * family' shells will not be examined although perhaps briefly commented  * about. Manual pages should be referred to for further information.

 Another tactic commonly seen is that the user will attempt to alter the shell's environment variable that defines the history file.
On bash for instance, this variable is $HISTFILE. A few examples:

- unset HISTFILE

This will expunge of the variable, therefore preventing the shell from
writing the history data to a destination.

- HISTFILE=/dev/null

This will redefine HISTFILE as /dev/null, telling the shell to write it's
history to this file. As mentioned earlier, all data passed to null device
is thrown away.

 A similar possibility is that the user will tamper with $HISTFILESIZE.
or $HISTSIZE. On Bourne-type shells $HISTSIZE controls the number of commands
stored in the history buffer, which will eventually be dumped to $HISTFILE.
On bash, $HISTFILESIZE variable sets the amount of data that will be written
to $HISTFILE. If either variable were set to 0, $HISTFILE would be rendered

 In this type of situation, it so happens that there is a builtin feature
of Bourne shells that we can use to our advantage. The 'readonly' command
is embedded in the shell and serves to prevent the modification of shell
variables. Using our combined knowledge of both file flags and the readonly
command let's look at another example:

# whoami
# cd /home/example
# echo "readonly HISTFILE" >> .profile
# echo "readonly HISTFILESIZE" >> .profile
# echo "readonly HISTSIZE" >> .profile
# chflags sappnd .profile

* You may also choose to repeat this with the files .shrc, .bashrc, etc.
* Reference sh(1), bash(1), or ksh(1) for information on the shell startup
* process and the role of these files.

* If you are performing this on a system with a large amount of users, it
* is recommended that you edit the global profile - /etc/profile. The
* modifications to this file will affect all users at login.

* It is also suggested that for convenience these changes should be
* made to /usr/share/skel/dot.profile as well. The files contained in skel/
* are defaults copied over to the home directories of newly added users.

>From the user's perspective:

$ whoami
$ unset HISTFILE
bash: unset: HISTFILE: cannot unset: readonly variable
$ HISTFILE=/dev/null
bash: HISTFILE: readonly variable
bash: HISTFILESIZE: readonly variable

 It should be understood that this method of protection is by no means full
proof. The user could perhaps invoke a new shell avoiding all of the startup
scripts. However, the readonly command also supports read only protection of
shell functions and could further be used to help divert the user from
accomplishing this. For example, let's suppose we constructed a small shell
function 'bash' and appended it to the user's login profile:

# cd /home/example
# echo "bash () { /usr/local/bin/bash --login ; } ; readonly bash" >> .profile

* Again, you may wish to make this modification to the system wide profile
* or the example dot.profile that lies in /usr/share/skel.

>From the user's perspective:

$ bash --noprofile --norc
$ HISTFILE=/dev/null
$ bash: HISTFILE: readonly variable

 It is shown that when the user enters the command 'bash' the shell
interprets this as the internal shell function 'bash' that we have created.
(It is standard protocol that when a command is passed to the shell it will
first search for shell functions and internal commands before referencing
for external ones) Our function 'bash' calls the bash shell with '--login'
telling it to act as a login shell and therefore read and execute commands
from the standard startup scripts which will include the .profile that will
set HISTFILE and HISTFILESIZE as readonly.

 Again, it should be made clear that this is not a workaround but rather a
simple diversion of sorts. This could obviously be avoided if the user were
to specify an absolute path or ignore the function ( i.e. the 'command'
builtin, symbolic link etc. ).

 There are undisputedly other methods apart from the above mentioned that
a user could employ to evade the shell command history ( i.e. in bash, the
remotion of the shell's history list via the 'history' builtin ). Arguably,
this discussion could have perhaps extend for several more pages. However,
the most commonly observed tactics have been discussed, along with a majority
of central ideas providing a basis for increased securement without involving
the editing of source code, which ultimately is the only guaranteed method
for achieving a full securement of shell history ( i.e. passing all lines
parsed by the shell to syslog ). The following section refers to another,
and very different approach to gathering user history. In some ways, more
effective and often preferred as this technique is relatively impossible for
the user to circumvent.


System Accounting

System accounting is a powerful tool for an administrator which serves
to collect not only the history of commands executed on a system but information
such as the amount of cpu time that processes' used, and their start and exit
times. The previous discussion above referred simply to shell command history.
It must be understood that system accounting is independent of this and
functions on the entire system, recording information on all processes called
by execve(2).

 Accounting is indeed a proficient method for viewing preceded command and
process information on the system, but should not be thought of as a valid
alternative to, but rather a complement to shell history. The shell's history
file will store recorded data of user inputs while system accounting will
record processed commands without their arguments and may or may not show
the specific command entered which spawned a specific process. The two should
be used in conjunction for a more extensive collection of data.

 If not already set up on your system, accounting should be enabled with
these steps:

# touch /var/account/acct
# chmod o-r /var/account/acct   ** Let's prevent normal users from viewing
                 ** our accounting data.
# accton /var/account/acct              

* And to have accounting enabled at startup:

# echo 'accounting_enable="YES"' >> /etc/rc.conf

 If you have enabled system accounting, the proper way to gather the
information recorded will be via the lastcomm(1) and sa(8) commands. An
example usage of the two:

# users
root example
# lastcomm -cS example | head -5
w       -    example      ttyv2   0.00 secs Fri Feb 2 01:07
locate    -    example      ttyv2   1.75 secs Thu Feb 1 21:05
gnuls     -    example      ttyv2   0.00 secs Thu Feb 1 21:05
gnuls     -    example      ttyv2   0.00 secs Thu Feb 1 21:05
cat      -    example      ttyv2   0.00 secs Thu Feb 1 21:05
# sa -m | grep example
example       685     1.88cpu    44122tio   635983k*sec

* Where cpu is total time in minutes, tio is total number of I/O operations
* and k*sec is CPU storage integral, in 1k-core seconds.

 This is only a small sample of possible uses for 'sa' and 'lastcomm'.
For brevity's sake these examples will not be furthered explained nor
will other uses be discussed. For more and in depth information of system
accounting the manual pages acct(2), acct(5), accton(8), lastcomm(1), sa(8)
should be referenced.


This article was written for the purpose of merely providing possible
insight into potential methods for securing command history and was not in any
way intended as a definitive guide to doing so. The techniques described are
not claimed to be fully sound and were intended as examples that would
hopefully serve to encourage further investigation and perhaps lead to more
full proofed methods of achievement. Furthermore, the subject matter discussed
in this document was not intended to be suggestive but instead aimed to
relieve possible incognizance of the topic and has hopefully succeeded in
doing so.


© 1997 - 20013 Defcon1, , Copyrights for all materials on this web site are held by the individual authors, artists, photographers or creators. Materials may not be reproduced or otherwise distributed without permission of and the content's original author.

Tool-Bar-2Defcon1  Webmail