This post will cover the topic on Bash and ZSH History Tricks from the OSCP Syllabus Module 3 plus a bit extra on piping. These simple commands can be strung together to create an advanced search of the bash and ZSH history.
Linux can display what was previously typed in bash and zsh history if the Bash or ZSH history have not been erased. Pentesters/Hackers can take advantage of this and leverage the information previously issued on the machine reverse engineer security implementations. These commands should be remembered as they are used for Pentesting, OSCP, CTFs and Reverse Engineering.
Case Scenario
If an admin was making changes on a machine and did not clear the history, a hacker or pentester can take advantage of it and see what changes were made, what commands have been used, and what was previously done to the machine. This is important for reverse engineering changes done, to gain insight on directory or file locations, and attempting privilege escalation.
Bash and ZSH History Location
To view the location of .bash_history
or .zsh_history
, navigate to the root directory and type ls -la
to show all the hidden files, directories, and the read/write access.
┌──(kali㉿kali)-[~]
└─$ ls -la
total 340
drwxr-xr-x 32 kali kali 4096 May 7 20:48 .
drwxr-xr-x 3 root root 4096 Nov 17 07:31 ..
-rwxrwxrwx 1 kali kali 1 Nov 17 09:49 .bash_history
-rw-r--r-- 1 kali kali 220 Nov 17 07:31 .bash_logout
-rw-r--r-- 1 kali kali 4503 Nov 17 07:31 .bashrc
-rw-r--r-- 1 kali kali 3526 Nov 17 07:31 .bashrc.original
drwx------ 4 kali kali 4096 Mar 28 16:57 .BurpSuite
drwxr-xr-x 16 kali kali 4096 May 7 20:48 .cache
drwx------ 20 kali kali 4096 Apr 21 16:00 .config
drwxr-xr-x 4 kali kali 4096 Mar 10 19:06 .gem
drwx------ 4 kali kali 4096 Mar 12 18:48 .hashcat
drwxr-xr-x 11 kali kali 4096 Mar 16 20:38 idafree-7.0
drwxr-xr-x 2 kali kali 4096 Mar 16 21:25 .idapro
drwxr-xr-x 4 kali kali 4096 Mar 28 16:53 .java
drwx------ 2 kali kali 4096 Mar 15 19:41 .john
drwxr-xr-x 3 kali kali 4096 Jan 4 20:57 .maltego
-rw-r--r-- 1 kali kali 125 Mar 26 19:38 .ophcrackrc
drwxr-xr-x 3 kali kali 4096 Mar 28 16:50 .recon-ng
-rw------- 1 kali kali 4453 May 7 20:48 .xsession-errors
-rw------- 1 kali kali 4787 May 5 19:31 .xsession-errors.old
drwxr-xr-x 16 kali kali 4096 Mar 28 18:10 .ZAP
drwxr-xr-x 2 kali kali 4096 Apr 19 15:52 .zenmap
-rw-r--r-- 1 kali kali 76831 May 5 19:31 .zsh_history
The example above shows the hidden directories, files and read/write access.
Using Bash History
Once inside the root directory and bash is located type history
or ~/.bash_history
(depending on linux distro) to search the bash history.
┌──(kali㉿kali)-[~]
└─$ history
1380 locate HTTP2.pcap
1381 diff test.sh test2.sh
1382 apt-get install /home/kali/Downloads/ipscan_3.7.6_amd64.deb
1383 sudo apt-get install /home/kali/Downloads/ipscan_3.7.6_amd64.deb
1384 ipscan
1385 angryip
1386 netstat
1387 ifconfig
1388 sudo netdiscover -r 142.168.244.0/24
1389 dirbuster
1490 nmap -sV -sC 142.118.204.2
1491 sudo ifconfig eth0 up
1492 sudo dhclient eth0
1493 nmap -sV -sC 142.168.244.160
1494 less MD5test.txt
1495 touch MD5test.txt
1496 echo "Adding this to the test document. This is to add something in here" > MD5test.txt
1497 echo "Adding to the end of the MD5 test document" >> MD5test.txt
1498 cat MD5test.txt
1499 md5sum /home/kali/Desktop/MD5test.txt
1500 md5sum MD5test.txt
1501 cd home
1502 cd kali
1503 ls
1504 whoami
1505 sudo wireshark
1506 pwd
1507 clear
1508 cd Desktop
1509 ls -la
The above example shows previous commands that were recorded in the bash_history
.
Using ZSH History
To search the zsh[autocomplete] history type cat ~/.zsh_history
.
objdump -d /home/kali/Desktop/flag-x64 > disassembly.asm
objdump -M intel -d /home/kali/Desktop/flag-x64 > disassembly.asm
ltrace
sudo apt install ltrace
ltrace /home/kali/Desktop/flag-x64
ltrace /home/kali/Desktop/flag-x32
/home/kali/Desktop/Hashcat/
hashcat -m 5600 -O -o cracked2.txt /home/kali/Desktop/Hashcat/crackme.txt /home/kali/Desktop/Hashcat/rockyou.txt
tshark -r /home/kali/Desktop/torrent1.pcap -R 'bittorrent.piece.data and ip.dst_host == 1292.168.29.129' -T fields -e bittorrent.piece.index -e bittorrent.piece.begin -e bittorrent.piece.length -e bittorrent.piece.data -E separator=+ | sort | sed -re 's!.*\+!!' | sed -re 's!:!!g' | echo -n -e $(tr -d '[:space:]' | sed 's/../\\x&/g') > binout
tshark -r /home/kali/Desktop/torrent1.pcap -R -2 'bittorrent.piece.data and ip.dst_host == 1292.168.29.129' -T fields -e bittorrent.piece.index -e bittorrent.piece.begin -e bittorrent.piece.length -e bittorrent.piece.data -E separator=+ | sort | sed -re 's!.*\+!!' | sed -re 's!:!!g' | echo -n -e $(tr -d '[:space:]' | sed 's/../\\x&/g') > binout
tshark -r /home/kali/Desktop/torrent1.pcap -Y 'bittorrent.piece.data and ip.dst_host == 1292.168.29.129' -T fields -e bittorrent.piece.index -e bittorrent.piece.begin -e bittorrent.piece.length -e bittorrent.piece.data -E separator=+ | sort | sed -re 's!.*\+!!' | sed -re 's!:!!g' | echo -n -e $(tr -d '[:space:]' | sed 's/../\\x&/g') > binout
tshark -r /home/kali/Desktop/torrent\ 1.pcap -Y 'bittorrent.piece.data and ip.dst_host == 1292.168.29.129' -T fields -e bittorrent.piece.index -e bittorrent.piece.begin -e bittorrent.piece.length -e bittorrent.piece.data -E separator=+ | sort | sed -re 's!.*\+!!' | sed -re 's!:!!g' | echo -n -e $(tr -d '[:space:]' | sed 's/../\\x&/g') > binout
tshark -r /home/kali/Desktop/torrent\ 1.pcap -Y 'bittorrent.piece.data and ip.dst_host == 192.168.29.129' -T fields -e bittorrent.piece.index -e bittorrent.piece.begin -e bittorrent.piece.length -e bittorrent.piece.data -E separator=+ | sort | sed -re 's!.*\+!!' | sed -re 's!:!!g' | echo -n -e $(tr -d '[:space:]' | sed 's/../\\x&/g') > binout
tshark -r /home/kali/Desktop/torrent.pcap -Y 'bittorrent.piece.data and ip.dst_host == 192.168.29.129' -T fields -e bittorrent.piece.index -e bittorrent.piece.begin -e bittorrent.piece.length -e bittorrent.piece.data -E separator=+ | sort | sed -re 's!.*\+!!' | sed -re 's!:!!g' | echo -n -e $(tr -d '[:space:]' | sed 's/../\\x&/g') > binout
python /home/kali/Desktop/code.py
python /home/kali/Desktop/code.p50
python /home/kali/Desktop/code.py
javac -version
java -version
java /home/kali/Desktop/Hasher.class
git clone https://github.com/java-decompiler/jd-gui.git
The above example shows the previous commands that were recorded in the .zsh_ _history
.
Combining History with Piping
Combining history with piping can be used to quickly leverage the information by piping (stringing) into other command-line utilities. This can make searching through very long histories with thousands of entries quicker and more convenient. The following are a few useful commands to use on bash and zsh history when combined with piping.
Filtering Latest 30 History Results
To search the history of bash or zsh for a specific string and display the latest 30 results:
Bash: history | grep "Insert_Word_Here" | tail -n 30
ZSH: cat ~/.zsh_history | grep "Insert_Word_Here" | tail -n 30
┌──(kali㉿kali)-[~]
└─$ history | grep "apt-get" | tail -n 30
309 apt-get install zteg
613 sudo apt-get install java
614 sudo apt-get install javacc
666 sudo apt-get install stegsnow
698 sudo apt-get install steghide -y
712 sudo apt-get install xsteg
789 apt-get install fcrackzip
790 sudo apt-get install fcrackzip
801 sudo apt-get install stegdetect
805 sudo apt-get install stegcracker
825 sudo apt-get install stegosuite
827 sudo apt-get install outguess
872 sudo apt-get install grepcidr
888 sudo apt-get install epoch
933 sudo apt-get install logcat
1103 sudo apt-get install zenmap
1138 sudo apt-get update
1139 sudo apt-get install alien
1144 apt-get --fix-broken install
1145 sudo apt-get --fix-broken install
1199 sudo apt-get install go
1280 sudo apt-get install python=2.7.15~rc1-1
1284 sudo apt-get install python=2.7.18-2
1295 udo apt-get -f install
1296 sudo apt-get -f install
1297 sudo apt-get update -fix-missing
1298 sudo apt-get update --fix-missing
1383 apt-get install /home/kali/Downloads/ipscan_3.7.6_amd64.deb
1384 sudo apt-get install /home/kali/Downloads/ipscan_3.7.6_amd64.deb
1463 history | grep "apt-get" | tail -n 30
The example above shows how using bash history | grep “apt-get” | tail -n 30
will be displayed.
Practical Example: A history search for
apt-get
will search for any software installation and removal that was issued withapt-get
.
Displaying the Latest 30 History Entries
The following commands are used to display the latest 30 entries of either the bash or zsh history.
Bash: history | tail -n 30
ZSH: cat ~/.zsh_history | tail -n 30
Search History from Recent to Oldest
A general search of the history will show the oldest entries first, the can be a big list depending on when the history was cleared. Use the following commands to order the search from recent to oldest, as it makes finding the latest changes quick and easy.
Bash: history | tac | less
ZSH: cat ~/.zsh_history | tac | less
Reissue a Command Found in History
Often when searching through the list of history entries you encounter a command that you want to try and rerun. To do this you must remember the number next to the entry and use the command !NUMBER_HERE
(replace !NUMBER_HERE
with the number that is next to the entry you will use).
┌──(kali㉿kali)-[~]
└─$ !921
┌──(kali㉿kali)-[~]
└─$ cat /home/kali/Desktop/route53.log | awk '{print $9}' | sort | grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([0-9]{1,2})' | awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'
The example above shows the command !921
used to copy and autofill that specific entry from the bash history. This is important to use when you have a long or complex entry.
Why this is Useful
These commands are a quick and simple method used to leverage valuable information on a host machine. As admins and from a security standpoint this shows the importance of clearing the history and not becoming complacent about tasks!
TL;DR Bash and ZSH History Tricks
ls -la
View hidden directories.
View bash or ZSH history:
Bash: History
or cat ~/.bash_history
ZSH: cat ~/.zsh_history
Search a specific string and display latest 30 results:
Bash: history | grep "Insert_Word_Here" | tail -n 30
ZSH: cat ~/.zsh_history | grep "Insert_Word_Here" | tail -n 30
Display the last 30 entries:
Bash: history | tail -n 30
ZSH: cat ~/.zsh_history | tail -n 30
Search history from recent entries first:
Bash: history | tac | less
ZSH: cat ~/.zsh_history | tac | less
Rerun a command found in history:
!NUMBER_HERE