A BLOG FROM THE F*TURE

Shell Tricks for the Modern Hacker.

Edited: 5 months, 3 weeks ago.

I've spent my fair amount of time sitting in front of computers, mostly inside a terminal, the all-powerful tool that allows us hackers free-range of motion in cyberspace. While graphical counterparts exist, most of the cybersecurity space, pentesting and similar exercises are done from here. From the time spent bleaching my skin with the grayish blue light that my monitors shed, I've compiled this list of tips and tricks to help other fellow hackers both new and old navigate the complex tool of the terminal and the shell.

The Shell to your Ghost

Shells are command interpreters that provide you with a command-line interface (CLI) for interacting with the operating system. It is what runs behind your terminal emulator, and it allows granular control over input/output, hence why it's the preferred tool for hackers to execute stuff. Plus, it's way faster than using a graphical user interface (GUI) program.

[~] Tip:
To change your login shell, read up on the chsh command.

In most Linux distributions, it is common to see bash (Bourne Again Shell) come preinstalled by default. For many that might be enough, but I prefer zsh (Z Shell) due to its plugins and extensibility. Almost all shells are configured per-user via a file that sits in your /home directory, called .<name-of-your-shell>rc, so all edits and extra functionality you want to configure go there.

[?] Info:
The term "rc" traces back to the Runcom files used in the early days of Unix, meaning "run commands". When a user starts a new shell session, the system reads and executes the commands from the user's "rc" files to set up the shell environment according to the user's preferences.

To start, you might want to check what shell you're working with. Based on the information the following command will give you, you can choose to change your shell for another one, or follow this guide by installing and enabling zsh as your login shell. Since your current shell is exported to an environment variable, you don't need any special tools to check, just a simple echo will do:

echo $SHELL

There are many frameworks to get you up and running with zsh. Think of them as the libraries you use in your code; they save you time and brainpower to get things up and running very fast. Some of the more popular ones include zim and ohmyzsh, but I'm sure there are many others.

I personally pair my zsh config with OhMyZSH. Their themes are pretty (and what would hacking be without style points anyway) and their documentation is well fleshed-out. The installation is as simple as running a script. However, whichever one you pick will do just fine, so long as they accept plugins (which zsh does natively, so probably all of them).

Plugins for Everyone

OhMyZSH comes with the git plugin by default for easy version control of your projects, giving you cool colors based on git status and more. You can find the full list of OhMyZSH plugins, but any plugin for zsh will work; it will just be harder to keep up-to-date since ohmyzsh has updates for itself and whatever plugin you might have that comes from their repo.

Plugin Functionality
colored-man-pages It does exactly what you'd expect, but I swear, reading man pages has never been better.
safe-paste Avoids your stupidity by preventing copied code immediately running after pasting it.
urltools Neat little plugin that will encode or decode URL-formatted strings, useful when web-app pentesting.
z Tracks your most used directories and lets you jump back into them with very little keystrokes. Incredibly useful for project/directory management.
z-bell Sends a notification after a command finishes when running for too long. Useful for long scans and fuzzing.
zsh-autosuggestions, zsh-syntax-highlighting and zsh-autocomplete1 Useful to navigate around in your terminal, know if your command syntax is right, and more.

I suggest adding the ones that suit your needs, and reading the appropriate documentation as some of these can be further customized by the user, allowing very fine-grained customization and getting you a system that is tailor-made (nothing feels better than truly knowing your system, trust me).

Aliases, your Shell's Best Friend

Aliases let you set up quick shortcuts for commands so you don't have to repeat your recipe all the time. They even allow you to extend some functionality into preexisting commands. For these edits to persist, they need to be added to either your shell's rc file, or in a separate file called .zsh_aliases that has to be sourced in your shell's rc (so, there has to be a line like source ~/.zsh_aliases in it).

[~] Tip:
The alias command will work in every POSIX compliant shell, so aliases will work in bash just as well as zsh.

Some aliases I added are just useful and good practice (the exit alias is good housekeeping when getting out of remote shells), while others were shown to me by pry0cc in his 0x00sec post; prepending grc, the generic colorizer, to tools like nmap so their output becomes easier to read.

Alias Functionality
alias exit="kill -9 $$" Sends a KILL signal when exiting that cannot be caught.
alias path="print -l $path" Prints your path in tidy, separate lines.
alias pubip="curl -sS https://icanhazip.com/" Fetches your public IP and prints it out on the terminal.
alias nmap="grc nmap" Colorizes nmap output. You can also use the same alias syntax with other programs like ip, ps, ping, netstat and tcpdump.

With this trick, some commands become way easier to read, so you'll be much faster getting to the information that matters. Compare the following picture to your regular nmap scan and you'll immediately know the difference.

A Network Mapper (nmap) scan with Generic Colorizer (grc) prepended through an alias definition, displaying the relevant results with colors.

Network Mapper (nmap) scan with Generic Colorizer (grc) prepended through an alias definition.

It clearly highlights the target, if it's alive or not, the ports, protocols and their alleged services! Neat and useful trick.

Exports, your Quick-Draw Holster

Those who are a bit more experienced with GNU/Linux distributions will know of the ability to export variables while your session lasts. What I mean by "session lasting" is literally your terminal window, once you close it, that variable you exported is gone.

export name=value

Exports from one session will be available to that session only (since it "exists" only for that process and its child processes), meaning that you can export the same variable with different values, so long as you do it in different windows. In the following example we have two terminals side-by-side, exporting a variable named "A" with different values.

<img style="display: block; margin: 0 auto;" src="https://i.ibb.co/hW62YPk/terminalsidebyside.png" alt="Side-by-side comparison of a variable "A" being exported in two different terminal windows."/>

Side-by-side comparison of a variable "A" being exported in two different terminal windows.

This is incredibly useful for pentesting, as you can export target IP's, wordlists, port ranges, etc, and then use those variable names in your commands! Plus, since what you exported only lasts for the session, you can use a terminal window per-target, or one only for password cracking with the wordlists you need exported.

Here's a more-or-less real life example of something I would do if I needed to keep track of the target IP and some wordlists to help me fuzz the website.

export TARGET=192.169.0.1
export DIRS_SMALL=/pentest/seclists/Discovery/Web-Content/raft-small-directories.txt
export BIG=/pentest/seclists/Discovery/Web-Content/big.txt

You can then use these in commands! Here are some widely used tools such as nmap, ffuf and gobuster:

nmap -A -T3 $TARGET
ffuf -w $DIRS_SMALL -u http://$TARGET/fuzz -c -v
gobuster -w $BIG -u http://$TARGET

If you use some of these exports very frequently (like a really good wordlist, for example) you can always define them in your shell's configuration file, and they'll persist reboots as well as sessions.

Function Definitions for Extensibility

Functions are easy ways to extend your shell's capabilities. They allow you to automate tasks via shell scripting (do note that the syntax is dependent on your shell).

The shell starter I recommended, OhMyZSH, comes with it's own set of predefined functions that you can read about here. Some of these are incredibly useful if you want to be the power user you always dreamed of, and were highlighted to me through bbatsov's incredible article on the topic.

function take() {
  if [[ $1 =~ ^(https?|ftp).*\.tar\.(gz|bz2|xz)$ ]]; then
    takeurl "$1"
  elif [[ $1 =~ ^([A-Za-z0-9]\+@|https?|git|ssh|ftps?|rsync).*\.git/?$ ]]; then
    takegit "$1"
  else
    takedir "$@"
  fi
}
# ipinfo == query ipinfo for info on a target ip.
ipinfo() {
  if [ ! -n "$1" ]; then
    echo "Enter a valid IP address."
  else
    curl -sS https://ipinfo.io/$1 | jq
  fi
}

#emailrep == get information about an email address.
emailrep() {
  if [ ! -n "$1" ]; then
    echo "Enter a valid email address."
  else
    curl -sS http://emailrep.io/$1 | jq
  fi
}

# shodanscan == get port info for a host from shodan.
shodanscan() {
  if [ ! -n "$1" ]; then
    echo "Enter a valid IP address."
  else
    curl -sS https://internetdb.shodan.io/$1 | jq
  fi
}

Since the responses are passed in JSON format, I'm sure with more time you can build more tools around these responses, or even parse them with something like Python to automate them further.

The Terminal, The Window to Your Shell

Welcome to your terminal, your home, the place of your greatest pwns and your most terrible mistakes. The window you see is your terminal emulator, a program that allows you to type in commands, and return the output of those. We already spoke of what runs behind it (answer: your shell), but let's see this beautiful piece of technology a bit more in-depth.

You might be wondering on the "emulator" part; In the early days of computing, terminals were the physical devices that were used to communicate with the mainframe computers. They consisted of a keyboard and a display screen, either all in one big and clunky package, or in a solitary room adjacent to the big mainframe that would take up literal walls of space.

DEC VT100 Terminal

A DEC VT100 Terminal, taken from Wikipedia under Creative Commons CC BY-SA 4.0

As technology progressed, the need for these clunky physical terminals diminished, and software-based solutions emerged to replicate the functionality of a terminal on a computer screen. Hence, the "terminal emulators" were born, and are kept until today.

[?] Info:
Terminals in GNU/Linux and older Unix systems were usually a class of device called a "teletypewriter", shortened to "tty". Nowadays, terminals keep that convention, being "connected" to the /dev/tty file in modern GNU/Linux systems.

Analysis Paralysis: Choosing a Terminal Emulator

If you installed a prepackaged Linux distribution and you like whatever terminal emulator came out of the box, then that is great! Stick with it and learn your tooling. However, Linux is modular by design, meaning you can get whatever terminal emulator is compatible and run it.

Main problem is that there's way too many of them, like xfce-terminal, urxvt, iterm2, gnome-terminal, konsole, tmux, alacritty, kitty, just to name a few off the top of my head. Heck, there's even a Wikipedia Article just for this; what do you choose?

While there is no cookie-cutter answer for this, my take is the following; stick with what came out of the box if you feel like it suits you and your particular option. For beginners, that specific terminal will also (generally) be the most suited for your distribution, and might even have a customized shell configuration file already done.

On the other hand, my personal choice is kitty. It is cross-platform, GPU-accelerated (most semi-modern laptops have an integrated or dedicated GPU anyway) terminal emulator which also supports tiling; that is creating separate windows and/or tabs.

This is incredibly useful for multitasking. My ideal hacking setup always tends to be one for recon/scanning, another one for manual pages and general help with commands, and another two for the actual hacking, like getting reverse shells, ssh connections and/or running tooling against the server.

Window tiling in the kitty terminal emulator.

Window tiling inside the kitty terminal emulator.

This multitasking ability is incredible in Desktop Environments like GNOME or KDE, as opposed to a tiling Window Manager which already allows you to spawn a bunch of windows with a single keyboard shortcut. If you don't know what a Desktop Environment [DE] even is, or what is the difference between that and a Window Manager [WM], you might wanna read up on this article.

It is very important to note that your terminal emulator also has a separate configuration file. It is dependent on what terminal emulator you chose if it even allows for configuring, but it will usually allow you to set up some specific keyboard shortcuts and implement more advanced functionality (for example, kitty has image rendering through icat). Refer to your terminal emulator's manual for more info.

The Almighty Manual and Other Help Utilities

There is no other tool you will use more than the manual pages, namely the man command. Reading through them might be a pain at first, but as you grow used to them they become easier and easier. They will give you the information you need, so use them as much as you can.

Usually running man <something> will yield you the page you need, but it is important to know that manual pages have sections, so here they are so you know how to navigate them accordingly to find more niche stuff. You can access these with man <page number> utility:

Just like the manual, I like the package tldr a lot, specially for cybersecurity applications. While not as complete as the manual pages, it usually gives you enough info on the syntax of a command, as well as some use-cases for it. Here is an example of tldr for ffuf, a fuzzing utility:

TLDR (Too Long, Didn't Read) utility page for FFUF, the fuzzy finder.

The tldr utility page for ffuf a fuzzing tool for Linux.

Other useful commands for moving around are find, grep, cat, ls, cd and more, and it would do you great good to be proficient with them. The terminal might be a scary tool, but so long as you know how to manipulate it, it should not bite your a$$ too harshly.

Keyboard Shortcuts

Learning the terminal at first is usually preluded with "hey, Ctrl-C shuts off your command!". But did you know there's a whole array of keyboard shortcuts to turn your noob hands into those of a power user? These will greatly speed up your terminal wizardry.

Shortcut Function
ALT-B Jump words backwards (left).
ALT-F Jump words forward (right).
ALT-. Pastes the previous command's argument. Great for passing in the same URL or IP to multiple commands.
CTRL-A Moves your cursor to the beginning of the line. Useful if you forget something at the start of a command, like sudo or grc.
CTRL-B Moves your cursor backwards by one character (left). Same as pressing your left arrow.
CTRL-C Cancels a running command or program "gracefully" by sending a SIGINT signal.
CTRL-D If no characters present, it closes your current terminal session and logs you out, else it deletes characters.
CTRL-F Moves your cursor forward by one character (right). Same as pressing your right arrow.
CTRL-K Deletes everything past the cursor. Useful when editing long commands quickly.
CTRL-L Clears your terminal screen, instead of typing clear every single time.
CTRL-N Searches for a command forward in time. Same as your down arrow.
CTRL-P Pastes your previous command into the buffer.
CTRL-R Searches for a command interactively into your history.
CTRL-S Stops output to screen. Very useful for commands with super long outputs.
CTRL-Q Resume output to screen that was previously stopped via ctrl-s.
CTRL-U Clears the line and stores it. This is dependent on what your $EDITOR variable is set to.
CTRL-Y Restores the line cleared with ctrl-u. This is dependent on what your $EDITOR variable is set to.
CTRL-X-E Edits your current buffer. This is dependent on what your $EDITOR variable is set to.
CTRL-W Deletes whatever is behind your cursor line.
CTRL-Z Suspends the current process and sends it to the background (you can bring it back by running fg).

Knowing keyboard shortcuts will make you very proficient at using the terminal, and since that is the main tool you use for hacking and coding, these will supercharge your productivity like nothing else. The faster a wizard casts a spell, the better they are (or something like that).

Conclusion

The terminal is the main tool we hackers use due to the granularity and control it gives us over our operating systems. Due to this, proficiency with this tool can only be a force for good, and will allow you to be faster and better when using it. I sincerely hope this list (albeit small, but with plans to update it as soon as I get more tips) will help you out, and make you a bit faster when doing that next pentest or that assignment. Best of luck to you all.

- Ked

  1. Useful install guide of these plugins.

#hacking #linux #post #shell #terminal