Different techniques for preventing commands from being stored in $HISTFILE

❯ Bash history

Bash maintains the list of commands internally in memory while it’s running. They are written into $HISTFILE (i.e, ~/.bash_history ) when a user logs off.

Copy 1 ❯ echo $HISTFILE 2 /home/bad3r/.bash_history

This post is a cheat sheet for common methods attackers use to hide commands from being saved in the history file or in memory

❯ Leading Space

Might not be enabled by default in some distros

Starting each command with a leading space character

Copy 1 ❯ echo "hello" 2 hello 3 ❯ echo "ritsec" 4 ritsec 5 ❯ history 6 1 ls 7 2 echo "hello" 8 3 history

Notice that the command $echo "hello" was saved history unlike the commas with a leading space $ echo "ritsec" . This is possible because of HISTCONTROL environment variable

Copy 1 ❯ head -2 /etc/os-release 2 NAME="Ubuntu" 3 VERSION="18.04.3 LTS (Bionic Beaver)" 4 ❯ echo $HISTCONTROL 5 ignoredups:ignorespace

❯ HISTFILE

The HISTFILE environment variable specifies bash history file

Copy 1 ❯ man bash 2 HISTFILE 3 The name of the file in which command history is saved (see HISTORY be‐ 4 low). The default value is ~/.bash_history. If unset, the command his‐ 5 tory is not saved when a shell exits. 6 the value of HISTIGNORE. The pattern matching honors the setting of the 7 extglob shell option.

Copy 1 ❯ echo $HISTFILE 2 /home/bad3r/.bash_history

To avoid recording commands to the file in $HISTFILE set HISTFILE value to /dev/null

Copy 1 ❯ HISTFILE=/dev/null 2 OR 3 ❯ export HISTFILE=/dev/null

❯ Using unset

Copy 1 man bash 2 unset 3 Remove variable or function names

We can use unset to remove the variable HISTFILE for the current session

Copy 1 ❯ echo $HISTFILE 2 /root/.bash_history 3 ❯ unset HISTFILE 4 ❯ echo $HISTFILE 5 6 ❯

Note that it will only effect the current session. If you start another session the variable HISTFILE will still be set unlike changing $HISTILE value to /dev/null

❯ HISTSIZE & HISTFILESIZE

Notice the distinction between file : on disk - and list : in memory.

HISTSIZE is the number of lines or commands that are stored in memory in a history list while your bash session is ongoing.

Copy 1 ❯ man bash 2 3 HISTSIZE 4 The number of commands to remember in the command history (see HISTORY 5 below). If the value is 0, commands are not saved in the history list. 6 Numeric values less than zero result in every command being saved on the 7 history list (there is no limit). The shell sets the default value to 8 500 after reading any startup files.

In order to remove all commands from to the history list in memory change the size to 0

Copy 1 ❯ echo $HISTSIZE 2 1000 3 ❯ HISTSIZE=0 # OR export HISTSIZE=0 4 ❯ echo $HISTSIZE 5 0

HISTFILESIZE is the number of lines or commands that

are allowed in the history file at startup time of a session, and

are stored in the history file at the end of your bash session for use in future sessions.

Copy 1 ❯ man bash 2 3 HISTFILESIZE 4 The maximum number of lines contained in the history file. When this 5 variable is assigned a value, the history file is truncated, if neces‐ 6 sary, to contain no more than that number of lines by removing the oldest 7 entries. The history file is also truncated to this size after writing 8 it when a shell exits. If the value is 0, the history file is truncated 9 to zero size. Non-numeric values and numeric values less than zero in‐ 10 hibit truncation. The shell sets the default value to the value of HIST‐ 11 SIZE after reading any startup files.

Copy 1 ❯ echo $HISTFILESIZE 2 2000 3 ❯ HISTFILESIZE=0 # OR export HISTFILESIZE=0

❯ The Set & Shopt Builtin

The set builtin allows you to change the values of shell options and set the positional parameters, or to display the names and values of shell variables. Using set we can avoid recording new commands to the history list in memory. And, because it’s not being saved in memory, it can not be recorded to file

-o option-name: Set the option corresponding to option-name

The option name here is history and its enabled by default. Using ‘+’ rather than ‘-’ causes these options to be turned off

Copy 1 ❯ set +o history

Using ‘-’ we can enable it again;

Copy 1 ❯ set -o history

Alternatively the shopt builtin command can be used shopt builtin command allows you to change additional shell optional behavior.

-u Disable (unset) each optname. -o` Restricts the values of optname to be those defined for the -o option to the set builtin

Copy 1 ❯ shopt -ou history

Re-enable it using the -s flag;

-s Enable (set) each optname.

Copy 1 ❯ shopt -os history

❯ Clearing the History

Rather than disabling command history, we can clear the history on the current bash shell by simply using the history command with the -c (clear) flag

Copy 1 ❯ history -c

Then, to make certain the changes are written to disk, we need to tell the history command to write to disk with the -w flag

Copy 1 ❯ history -w

This only clears the history of the current shell. Commands run in other shells will remain on disk.

❯ Shredding the History

Copy 1 ❯ man shred 2 shred - overwrite a file to hide its contents, and optionally delete it

The shred command shreds the target file making it unreadable

Copy 1 ❯ cat $HISTFILE 2 ls 3 history -w 4 ❯ shred $HISTFILE 5 ❯ cat $HISTFILE 6 ,Iç!hù2g2V?ƥf[Æ{L´w٘Ì˿vCÓ/Zs 7 PìPõä{K{ëúJ :i6­ÚûR܈?ÄñW?äÆn6»¬ËoûD;NGÖËÓâ¯TRú&Í__tÇÙ 8 ?ÏG5Ãö-òyÞÈ 9 OËã 10 ...

After using the shred command the history file contains bunch of binary data that is nonsense.

The fact that the file is shredded may in itself be considered evidence of malicious activity. We can eliminate even that by combining the shred command with the -zu flags

-u deallocate and remove file after overwriting

deallocate and remove file after overwriting -z a final overwrite with zeros to hide shredding

Copy 1 ❯ cat $HISTFILE 2 ls 3 history -w❯ docker exec -ti 6e0aec73e61c bash 4 5 ❯ shred -zu $HISTFILE 6 ❯ cat $HISTFILE 7 cat: /root/.bash_history: No such file or directory

❯ Killing Bash Process

Using the kill command we can exit the session without saving commands in memory to disk using;

Copy 1 ❯ kill -9 $$

thanks to @ReigningShells

❯ Using More

We can hide a command from being saved in memory using more ability to excute commands by prepending them with !

!<cmd> or :!<cmd> Execute <cmd> in a subshell

Copy 1 ❯ ps -aef | more 2 UID PID PPID C STIME TTY TIME CMD 3 root 1 0 0 Jan20 ? 00:00:03 /sbin/init 4 root 2 0 0 Jan20 ? 00:00:00 [kthreadd] 5 root 3 2 0 Jan20 ? 00:00:00 [rcu_gp] 6 ... 7 !echo "thanks @13_0_0_0_0" 8 thanks @13_0_0_0_0 9 ------------------------

At the more prompt type ! or :! followed by your command.