Métodos para ocultar el historial de bash

Bash mantiene el listado de comandos que se están ejecutando en memoria y que se escriben en $HISTFILE (~/.bash_history) cuando un usuario cierra la sesión.
$ echo $HISTFILE
/home/usuario/.bash_history
Hoy recopilamos un cheatsheet de secbytes en el que recogen un buen número de métodos que un atacante puede utilizar para que sus comandos no queden almacenados, tanto en memoria como en disco.

Poniendo un espacio antes de cada comando

Es posible que no esté habilitado de forma predeterminada en algunas distribuciones pero, en la mayoría, si ponemos antes de cada comando un espacio el mismo no se almacenará en el historial:
$ echo "hello"
hello
$  echo "ritsec"
ritsec
$ history 
    1  ls
    2  echo "hello"
    3  history 

Observad que el comando $echo "hola" se guardó el historial a diferencia del $echo "ritsec". Eso es posible debido a la variable de entorno HISTCONTROL:
$ head -2 /etc/os-release
 NAME="Ubuntu" 
 VERSION="18.04.3 LTS (Bionic Beaver)" 
$ echo $HISTCONTROL
 ignoredups:ignorespace

HISTFILE

La variable de entorno HISTFILE especifica el archivo bash history:
$ man bash
HISTFILE
  The  name  of the file in which command history is saved (see HISTORY be‐
  low).  The default value is ~/.bash_history.  If unset, the command  his‐
  tory is not saved when a shell exits.
  the  value of HISTIGNORE.  The pattern matching honors the setting of the
  extglob shell option.
$ echo $HISTFILE
/home/usuario/.bash_history

Para evitar guardar comandos en el archivo en $HISTFILE, se puede establecer el valor HISTFILE a /dev/null
$ HISTFILE=/dev/null
o
$ export HISTFILE=/dev/null

Uso de unset
man bash
unset
  Remove variable or function names

Podemos usar también unset para eliminar la variable HISTFILE para la sesión actual:
$ echo $HISTFILE
/root/.bash_history
$ unset HISTFILE
$ echo $HISTFILE

HISTSIZE & HISTFILESIZE

HISTSIZE es el número de líneas o comandos que se almacenan en memoria mientras la sesión de bash está en curso.
$ man bash

HISTSIZE
  The number of commands to remember in the command  history  (see  HISTORY
  below).   If  the value is 0, commands are not saved in the history list.
  Numeric values less than zero result in every command being saved on  the
  history  list  (there  is no limit).  The shell sets the default value to
  500 after reading any startup files.

Para eliminar todos los comandos de la lista del historial en la memoria, se puede cambiar el tamaño a 0:
$ echo $HISTSIZE
1000
$ HISTSIZE=0  # OR export HISTSIZE=0
$ echo $HISTSIZE
0

HISTFILESIZE es el número de líneas o comandos que:
  • están permitidos en el archivo de historial en el momento del inicio de una sesión, y
  • se almacenan en el archivo de historial al final de la sesión de bash para usar en futuras sesiones.
$ man bash

HISTFILESIZE
  The  maximum  number  of  lines contained in the history file.  When this
  variable is assigned a value, the history file is  truncated,  if  neces‐
  sary, to contain no more than that number of lines by removing the oldest
  entries.  The history file is also truncated to this size  after  writing
  it  when a shell exits.  If the value is 0, the history file is truncated
  to zero size.  Non-numeric values and numeric values less than  zero  in‐
  hibit truncation.  The shell sets the default value to the value of HIST‐
  SIZE after reading any startup files.
$ echo $HISTFILESIZE
2000
$ HISTFILESIZE=0  # OR export HISTFILESIZE=0

Las herramientas builtin Set & Shopt

Estas herramientas del sistema permiten cambiar los valores de las opciones de la shell y establecer los parámetros posicionales, o mostrar los nombres y valores de las variables de la shell. Usando set podemos evitar grabar nuevos comandos en la lista del historial en la memoria. Y, como no se guarda en la memoria, no se puede grabar tampoco en un archivo.

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

El nombre de la opción aquí es history y está habilitado de forma predeterminada. El uso de "+" en lugar de "-" hace que estas opciones se desactiven:
$ set +o history

Usando ‘-’ podemos habilitarlo nuevamente.

De forma alternativa, podemos usar también el comando del sistema shopt que permite adicionalmente cambiar otros comportamientos de la shell.
-u Disable (unset) each optname. ` -o Restricts the values of optname to be those defined for the -o option to the set builtin
$ shopt -ou history

Se puede volver a habilitar usando el flag -s;

    -s Enable (set) each optname.
$ shopt -os history

Limpiando el history

En lugar de deshabilitar el historial de comandos, podemos borrar el historial en la shell actual de bash simplemente usando el comando history con el parámetro -c (clear)
$ history -c

Luego, para asegurarnos de los cambios en el disco usamos el parámetro -w
$ history -w

Esto solo borra la historia de la shell actual. Los comandos ejecutados en otras shells permanecerán en el disco.

Machacando (shredding) el history

$ man shred
  shred - overwrite a file to hide its contents, and optionally delete it

El comando shred sobrescribe el archivo de destino haciéndolo ilegible
$ cat $HISTFILE
ls
history -w
$ shred $HISTFILE
$ cat $HISTFILE
 ,Iç!hù2g2V?ƥf[Æ{L´w٘Ì˿vCÓ/Zs
PìPõä{K{ëúJ :i6­ÚûR܈?ÄñW?äÆn6»¬ËoûD;NGÖËÓâ¯TRú&Í__tÇÙ
?ÏG5Ãö-òyÞÈ
           OËã
...

Después de usar el comando shred, el archivo de historial contiene un montón de datos binarios que no tienen sentido.

El hecho de que el archivo esté sobrescrito puede considerarse en sí mismo evidencia de actividad maliciosa. Pero podemos incluso eliminar eso combinando el comando shred con las flags -zu

     -u desasignar y eliminar el archivo después de sobrescribir
     -z una sobrescritura final con ceros para ocultar la destrucción

$ cat $HISTFILE
ls
history -w$ docker exec -ti 6e0aec73e61c bash

$ shred -zu $HISTFILE
$ cat $HISTFILE
cat: /root/.bash_history: No such file or directory

Matando el proceso de bash

Usando el comando kill podemos salir de la sesión sin guardar comandos en la memoria en el disco usando;
$ kill -9 $$

Usando more

Podemos ocultar un comando para que no se guarde en la memoria usando la capacidad de more para ejecutar comandos.

!<cmd> o :!<cmd> ejecuta <cmd> en una subshell

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

En el prompt de more debemos escribir ! p :! seguido del comando.

Esta misma técnica se puede usar con otros GTFBIN como vim.

Comentarios