The first sixty seconds on an unknown target decide whether the engagement is methodical or random.
[LAB ENVIRONMENT — commands executed in a local throwaway sandbox]
# Throwaway reproduction sandbox (runs locally as unprivileged user; display_user="dev") mkdir -p ~/lab/{reports,scripts,.config} cd ~/lab echo "README content" > README.txt echo "status ok" > reports/q3.txt echo "API_TOKEN=example-not-a-real-token" > deploy.env chmod 640 deploy.env echo "rotate the deploy token before friday" > .reminder chmod 600 .reminder printf "todo: archive old reports\r\ntodo: rotate keys\r\n" > notes.txt printf "\x00\x01\x02\xfe\xff\x00\x00\x00CONNECT db.internal:5432\x00\xde\xad\xbe\xef\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00user=deploy\x00" > data.bin chmod 755 scripts What this level is
You land on a shell on a machine you have never seen. There is no map, no architecture diagram, and no administrator telling you what matters. What you do in the next sixty seconds determines whether the rest of the session is disciplined, repeatable, and effective or chaotic and noisy. Professional operators on both offensive engagements and incident response investigations begin with the same three fundamental questions: who am I, where am I, and what is here?
In this guide, we answer those questions against BreachLab's Ghost track, Level 0, titled "First Contact". The level page lists three foundational commands: ls, cd, and cat.
Behind those three simple commands lie decades of computer science history and operating system architecture. In this guide, we examine:
- Why identity in Unix is governed by kernel-level numeric IDs rather than environment variables.
- How the filesystem hierarchy and hidden dot-files originated from a historical shortcut.
- How the access matrix compresses into nine permission bits, and how discretionary access control creates predictable security vulnerabilities.
- Platform: BreachLab, a free, legal hands-on platform where every level is an isolated, real Linux environment.
- Track & Level: Ghost I · Level 0 — First Contact (100 points).
- Target Connection:
ssh ghost0@204.168.229.209 -p 2222 - Commands Covered:
whoami,pwd,ls,cd,cat,file,head,tail,strings,xxd,stat,type. - Level Objective: Locate the credentials for the next account (
ghost1).
Watch the full long-form video walkthrough: https://youtu.be/CJ459itJPeU
Follow along with the complete series playlist: https://www.youtube.com/playlist?list=PLUep6spDxjvo
Compliance Note: In strict adherence to BreachLab creator rules, this article teaches the underlying method, mechanics, and security theory. No passwords, flags, or copy-paste solutions are published.
Today's Topics
- The Orientation Loop: Executing the initial sixty-second triage using
whoami,pwd, andls -la. - SSH Protocol Mechanics: Understanding TCP handshakes, Diffie-Hellman key agreement, and host verification.
- Identity and Complete Mediation: Why the kernel evaluates effective UIDs rather than shell variables.
- Filesystem Enumeration: Walking directory tables, understanding inodes, and unmasking dot-files.
- Permission Bit Triads: Decoding octal modes, directory traversal mechanics, and access matrix theory.
- Path Traversal with Shell Builtins: Why
cdmust execute inside the parent shell process. - Defensive Content Inspection: Safely examining unknown streams using
file,cat -A, andstrings. - Unsecured Credentials in Files (T1552.001): Real-world impact, kill chain positioning, and honeytoken detection.
Orienting on an Unknown Target: whoami and pwd
When I first connect to a remote target, before typing any complex commands or running automated scripts, I establish orientation. I need to know the security context of the process running my shell and my exact position in the directory hierarchy.
Figure 1: The opening moments on an unknown shell determine the course of the investigation.
I begin by asking the kernel for my active identity. I run whoami:
$ whoami dev The command returns dev (or ghost0 when logged into the live target). Behind this single word, the whoami utility executed the geteuid() system call to fetch the numeric effective user ID from the operating system kernel, then performed a lookup against /etc/passwd.
To illustrate why this matters, consider what happens if I rely on the common $USER environment variable instead:
$ echo $USER dev $ USER=root $ echo $USER root $ whoami dev The environment variable $USER is completely under user-space control. An adversary or a misconfigured script can alter it at will. The kernel's reference monitor completely ignores $USER when enforcing access permissions; it consults only the numeric UID bound to the process structure in memory.
Next, I check my location in the filesystem with pwd:
$ pwd /home/dev/lab The pwd (print working directory) command prints the absolute path of the current directory. This path serves as the anchor point for every relative path resolution performed by the kernel during system calls like open() and execve().
Takeaway: Always query the kernel directly for process identity rather than trusting environment variables that user space can manipulate.
Figure 2: BreachLab provides authentic Linux environments over SSH.
Anatomy of an SSH Connection
To reach Level 0, we initiate an SSH connection to port 2222:
$ ssh ghost0@204.168.229.209 -p 2222 Figure 3: Breakdown of an SSH connection string: binary, target account, host address, and non-standard port.
This command initiates a multi-stage protocol exchange:
- Transport Layer Handshake: The client opens a TCP connection to port 2222. Port 2222 is chosen by convention for secondary or containerised SSH daemons, avoiding privileged port binding (ports below 1024 require root privileges).
- Version Exchange: Both client and server exchange identification strings (e.g.,
SSH-2.0-OpenSSH_8.9p1). - Key Exchange (KEX): Both sides agree on cryptographic algorithms and execute a Diffie-Hellman or elliptic curve exchange to establish a shared session key without transmitting it over the wire.
- Server Authentication: The server signs the exchange with its private host key. The client verifies this signature against its local
~/.ssh/known_hostsfile. - User Authentication: Once encryption is established, the client sends user authentication credentials (in Level 0, password authentication; in hardened environments, Ed25519 public keys or certificates).
Takeaway: SSH ensures confidentiality, integrity, and server authentication before a single credential character is sent across the network.
Enumerating the Filesystem: ls and What Else You Could Use
With identity and working directory confirmed, the next priority is inventorying what is present.
Figure 4: The orientation triage answering who am I, where am I, and what is here.
I start with a plain ls:
$ ls README.txt data.bin deploy.env notes.txt reports scripts A standard ls reads the directory data structure and outputs filenames alphabetically. However, a plain listing hides crucial information. In Unix, files whose names begin with a period (.) are excluded from default directory listings.
To see all entries, I supply the -a flag:
$ ls -a . .. .config .reminder README.txt data.bin deploy.env notes.txt reports scripts Notice what appeared: . (the current directory), .. (the parent directory), .config (a configuration directory), and .reminder (a hidden text file).
In security assessments, dot-files are prime locations for misconfigured credentials, shell histories (.bash_history), cloud tokens (.aws/), and private keys (.ssh/id_rsa).
To inspect file metadata, I combine flags into the standard enumeration command ls -la:
$ ls -la total 40 drwxrwxr-x 5 dev dev 4096 Oct 7 07:02 . drwxrwxr-x 3 dev dev 4096 Oct 7 07:02 .. drwxr-xr-x 2 dev dev 4096 Oct 7 07:02 .config -rw------- 1 dev dev 38 Oct 4 07:02 .reminder -rw-r--r-- 1 dev dev 80 Oct 7 07:02 README.txt -rw-r--r-- 1 dev dev 61 Sep 7 07:02 data.bin -rw-r----- 1 dev dev 67 Oct 2 07:02 deploy.env -rw-r--r-- 1 dev dev 46 Sep 28 07:02 notes.txt drwxr-xr-x 2 dev dev 4096 Oct 7 07:02 reports drwxr-xr-x 2 dev dev 4096 Oct 7 07:02 scripts Figure 5: Examining file metadata, hidden dot-entries, and permission triads with ls -la.
What if ls is not available?
In minimal Docker containers or restricted shells, the ls binary may be absent or restricted. Because filename expansion (globbing) is handled directly by the shell before command execution, we can enumerate files using built-in shell features:
$ echo * README.txt data.bin deploy.env notes.txt reports scripts When recursive enumeration is needed, find and tree provide structured visibility:
$ tree -a -L 2 . ├── .config │ └── app.conf ├── .reminder ├── README.txt ├── data.bin ├── deploy.env ├── notes.txt ├── reports │ ├── q3.txt │ └── q4.txt └── scripts └── backup.sh 4 directories, 9 files Takeaway: Plain ls conceals administrative configuration; standard enumeration requires ls -la or native shell globbing.
Decoding Access Rights: Reading a Permission String
The output of ls -la presents a 10-character string at the beginning of each line. Understanding this string is essential for recognizing privilege boundaries.
Figure 6: Anatomy of a Unix permission string and octal conversion.
Consider the line for deploy.env:
-rw-r----- 1 dev dev 67 Oct 2 07:02 deploy.env
We dissect the string from left to right:
- Character 1 (File Type):
-denotes a regular file. Adindicates a directory, whileldenotes a symbolic link. - Characters 2–4 (Owner Permissions):
rw-indicates the owner (dev) has read (r=4) and write (w=2) permissions, but no execute (x=1). Total =6. - Characters 5–7 (Group Permissions):
r--indicates members of the owning group (dev) have read permission only. Total =4. - Characters 8–10 (Others Permissions):
---indicates any user who is neither the owner nor a member of the group has zero permissions. Total =0.
The combined octal mode is 640.
We can verify this numeric representation directly using stat:
$ stat -c '%A %a %U:%G %s bytes %n' README.txt .reminder scripts/backup.sh deploy.env -rw-r--r-- 644 dev:dev 80 bytes README.txt -rw------- 600 dev:dev 38 bytes .reminder -rwxr-xr-x 755 dev:dev 40 bytes scripts/backup.sh -rw-r----- 640 dev:dev 67 bytes deploy.env The Crucial Difference for Directories
For files, r allows reading content, w allows modifying bytes, and x allows running the file as an executable program.
For directories, the bits have distinct meanings:
-
r(Read): Grants the ability to list the names of files inside the directory (e.g., withls). -
w(Write): Grants the ability to create, delete, or rename files within the directory (contingent on execute permissions). -
x(Execute/Search): Grants the ability to enter the directory (cd) and access the inodes of files inside it.
Takeaway: Without directory execute permissions, read permissions allow listing names but prevent accessing file contents or metadata.
Navigating the Hierarchy: Moving Around with cd
Navigating the directory tree is accomplished using cd (change directory).
Figure 7: Inspecting command implementations with type: builtins versus disk executables.
When we check the binary location of cd, we encounter a fundamental architectural distinction:
$ type cd ls cat pwd cd is a shell builtin ls is /usr/bin/ls cat is /usr/bin/cat pwd is a shell builtin ls and cat are independent executable binaries located in /usr/bin/. When invoked, the shell calls fork() to create a child process, followed by execve() to load the binary into memory.
cd, however, is a shell builtin. In Unix process architecture, a child process inherits a copy of its parent's working directory, but any modifications made by the child to its own working directory do not propagate back to the parent. If cd were an external executable binary, running /usr/bin/cd reports would change the directory of the child process, which would then immediately exit, leaving the user's interactive shell exactly where it started.
Common Navigation Patterns
We test navigation shortcuts across our lab hierarchy:
$ cd reports && pwd && cd .. && pwd && cd ~ && pwd && cd - && pwd /home/dev/lab/reports /home/dev/lab /home/dev /home/dev/lab /home/dev/lab Key shortcuts:
-
..: References the parent directory entry. -
~: Expands to the current user's home directory ($HOME). -
-: Returns to the previous working directory ($OLDPWD).
Takeaway: cd must be implemented inside the shell process because child processes cannot alter parent process state.
Inspecting Files Safely: cat and the Tools Around It
Once a target file is discovered, we must inspect its contents. The standard utility is cat (short for concatenate).
Figure 8: Examining files safely: content inspection, line terminators, and binary strings.
cat reads file streams sequentially and writes them to standard output. While effective for short text files, dumping arbitrary files directly with cat introduces risks:
- Long files scroll off the screen, obscuring terminal history.
- Binary files send control characters that can corrupt terminal settings or reprogram keyboard mappings.
To avoid this, we follow a two-step rule: identify first, read second.
We inspect file types using file:
$ file * README.txt: ASCII text data.bin: data deploy.env: ASCII text notes.txt: ASCII text, with CRLF line terminators reports: directory scripts: directory Notice notes.txt: it is flagged as containing CRLF line terminators (Windows-style \r\n).
If we view notes.txt with plain cat, the carriage return is invisible. But when we pass -A (show all invisible characters), the hidden control character becomes evident:
$ cat -A notes.txt todo: archive old reports^M$ todo: rotate keys^M$ The ^M represents carriage return (\r, ASCII 0x0D), while $ marks the newline (\n, ASCII 0x0A). If an automated script parses this file to extract a password or hostname, the carriage return remains attached to the string, causing subsequent authentication requests to fail silently.
Specialized Inspection Tools
When dealing with structured, binary, or large datasets, we use tailored utilities:
1. Inspecting Binaries with strings
Instead of dumping raw bytes from data.bin, strings extracts contiguous printable ASCII sequences (minimum length 4 by default):
$ strings data.bin CONNECT db.internal:5432 user=deploy 2. Exact Byte Inspection with xxd
To view hexadecimal representations and offsets:
$ xxd data.bin 00000000: 0001 02fe ff00 0000 434f 4e4e 4543 5420 ........CONNECT 00000010: 6462 2e69 6e74 6572 6e61 6c3a 3534 3332 db.internal:5432 00000020: 00de adbe ef00 0000 0000 0000 0000 0000 ................ 00000030: 0075 7365 723d 6465 706c 6f79 00 .user=deploy. 3. Bounded Inspection with head and tail
To read headers or trailing log entries without flooding standard output:
$ head -n 3 reports/q3.txt line 001: status ok line 002: status ok line 003: status ok 4. Recursive Content Searching with grep
When searching across an entire hierarchy for credentials:
$ grep -rn -i 'token' . 2>/dev/null ./.reminder:1:rotate the deploy token before friday ./deploy.env:2:API_TOKEN=example-not-a-real-token Takeaway: Always classify unknown files with file before reading, and use cat -A to catch invisible carriage returns that break scripts.
Solving Level 0 on the Target Machine
Now we apply our orientation methodology to the live BreachLab Ghost 0 target.
Figure 9: Step-by-step navigation through the target directory structure to locate the level credential.
We log in over SSH as ghost0. The session opens in /home/ghost0. We execute our triage loop:
$ whoami ghost0 $ pwd /home/ghost0 $ ls workspace The directory contains an entry named workspace. We move into it:
$ cd workspace $ ls archive Inside workspace is a directory named archive. In enterprise systems, archive directories are frequently overlooked during credential rotation sweeps. We descend into archive:
$ cd archive $ ls credentials We find a file named credentials. Before reading it, we verify its format:
$ file credentials credentials: ASCII text Finally, we display the credential:
$ cat credentials (The password output is intentionally redacted in accordance with BreachLab platform rules).
The password string displayed in this file represents the flag for Level 0 and serves as the SSH authentication password for ghost1. We immediately log this credential in an external secure password manager before proceeding to Level 1.
Takeaway: Level 0 requires zero exploit payloads; disciplined filesystem traversal and directory enumeration locate the credential directly.
[INFOGRAPHIC — replace with generated image]
Prompt: A detailed 16:9 vector infographic illustrating the Unix Reference Monitor and Access Matrix architecture, showing the barrier between User Space process execution and Kernel Space filesystem validation, complete mediation flowcharts, octal bit conversion breakdown (r=4, w=2, x=1), dark navy#111A2Ebackground with emerald#28E096and cyan#56C6E6structural nodes, high resolution, clean typography, no logos, no people.
Alt text: Architectural infographic detailing user-space process system calls passing through the kernel reference monitor to evaluate access matrices and inode permissions.
Figure 10: Complete mediation ensures that every system call requesting file access is validated against kernel process credentials.
Running It
Here is the complete orientation session as executed in our sandbox environment, demonstrating the unbroken workflow from initial connection to secret identification:
$ whoami dev $ pwd /home/dev/lab $ ls -la total 40 drwxrwxr-x 5 dev dev 4096 Oct 7 07:02 . drwxrwxr-x 3 dev dev 4096 Oct 7 07:02 .. drwxr-xr-x 2 dev dev 4096 Oct 7 07:02 .config -rw------- 1 dev dev 38 Oct 4 07:02 .reminder -rw-r--r-- 1 dev dev 80 Oct 7 07:02 README.txt -rw-r--r-- 1 dev dev 61 Sep 7 07:02 data.bin -rw-r----- 1 dev dev 67 Oct 2 07:02 deploy.env -rw-r--r-- 1 dev dev 46 Sep 28 07:02 notes.txt drwxr-xr-x 2 dev dev 4096 Oct 7 07:02 reports drwxr-xr-x 2 dev dev 4096 Oct 7 07:02 scripts $ stat -c '%A %a %U:%G %s bytes %n' deploy.env .reminder -rw-r----- 640 dev:dev 67 bytes deploy.env -rw------- 600 dev:dev 38 bytes .reminder $ file * README.txt: ASCII text data.bin: data deploy.env: ASCII text notes.txt: ASCII text, with CRLF line terminators reports: directory scripts: directory $ cat -A notes.txt todo: archive old reports^M$ todo: rotate keys^M$ $ grep -rn -i 'token' . 2>/dev/null ./.reminder:1:rotate the deploy token before friday ./deploy.env:2:API_TOKEN=example-not-a-real-token Reading it in groups:
- Identity & Context:
whoamiandpwdverify unprivileged user execution inside the lab root. - Surface Discovery:
ls -launmasks hidden entries (.config,.reminder) that default listings omit. - Permission Assessment:
statreveals that.reminderis restricted to mode600(owner read/write only), whiledeploy.envis mode640. - Stream Verification:
filealerts us to Windows-style CRLF terminators innotes.txt, confirmed viacat -A. - Targeted Extraction:
greprecursively isolates credential assignments without manual file crawling.
Theory: Why Unix Looks the Way It Does
Fifty years of hierarchical abstraction and the accident of dot-files.
Sources
- Ritchie & Thompson, The UNIX Time-Sharing System (Communications of the ACM, 1974)
- Unix Programmer's Manual, 1st Edition (Bell Laboratories, 1971)
- Filesystem Hierarchy Standard (FHS 3.0, Linux Foundation, 2015)
In 1969 at Bell Laboratories, Ken Thompson and Dennis Ritchie began designing a streamlined operating system on a discarded Digital Equipment Corporation PDP-7. The design principles they established remain the structural foundation of modern Linux systems.
Figure 11: The evolution of the Unix directory tree from the 1971 Programmer's Manual to modern FHS.
Ritchie and Thompson formulated four enduring architectural tenets:
- Hierarchical Namespace: A single rooted tree where directories contain file descriptors and pointers to subordinate directories.
- Unstructured Byte Streams: A file is simply an arbitrary sequence of bytes. The operating system imposes no record delimiters or indexed access methods; interpretation is delegated entirely to user space.
- Pervasive File Abstraction: Peripheral devices, storage disks, terminals (
/dev/tty), and inter-process communication channels are presented as file descriptors within the namespace. - Tool Composition: Modular utilities that perform a single task well, linked via unidirectional pipes (introduced by Douglas McIlroy in 1973).
In November 1971, the Unix Programmer's Manual (First Edition) formally documented ls, cat, and chdir (the predecessor to cd). In the 1974 CACM paper, directories were defined as simple lookup tables mapping character string names to numeric internal indices called i-numbers (inodes).
The Accident of Dot-Files
The convention of "hidden" files originated as a programming shortcut rather than a deliberate security mechanism. According to a widely cited historical account by Rob Pike, when Thompson and Ritchie added directory navigation, every directory received two structural entries: . (pointing to the directory itself) and .. (pointing to its parent). To prevent these two entries from cluttering directory listings, a check was added to ls: if the first character of a filename was ., the entry was skipped.
This simple prefix check inadvertently caused any file beginning with a period to be hidden from the default listing. Developers quickly adopted this behavior to stash user configuration files (.profile, .bashrc) out of everyday view. In modern security testing, this design artifact makes dot-files the primary repository for unmonitored credentials.
Under the Hood: Directory Inodes
In modern Linux filesystems (ext4, XFS), a directory is an inode containing data blocks filled with directory entries (struct linux_dirent64):
$ ls -i 5771093 README.txt 5771103 data.bin 5771104 deploy.env 5771095 notes.txt 5771100 reports 5771098 scripts The filename is merely a human-readable link pointing to an inode number. The permissions, file size, timestamps, and data block pointers reside entirely inside the inode table, not within the directory entry itself.
Theory: Why SSH Exists (History, Diffie-Hellman, and MITM)
From plaintext cleartext telnet to cryptographically authenticated sessions.
Sources
- Ylönen, SSH — Secure Shell Remote Login (1995)
- RFC 4251: The Secure Shell (SSH) Protocol Architecture (IETF, 2006)
- Diffie & Hellman, New Directions in Cryptography (IEEE Transactions on Information Theory, 1976)
Before SSH, remote administration relied on Telnet (RFC 854) and the Berkeley r-commands (rlogin, rsh). These protocols transmitted every packet across local networks and the ARPANET in plaintext. Anyone with network access could capture passwords and keystrokes using packet sniffers.
Figure 12: Diffie-Hellman key exchange mechanics preventing eavesdropping over untrusted networks.
In 1995, following a major password sniffing incident at the Helsinki University of Technology, Tatu Ylönen designed SSH-1 as a secure replacement. In 1999, the OpenBSD project developed OpenSSH, which became the global standard implementation, formalized as SSH-2 in RFCs 4251–4254 in 2006.
Cryptographic Foundation: The Diffie-Hellman Key Agreement
The central challenge of remote login across untrusted networks is key distribution: how can two machines agree on a shared secret without an eavesdropper deducing it?
Whitfield Diffie and Martin Hellman solved this in 1976 using modular arithmetic over a cyclic group. Here is a worked example using deliberately small numbers:
- Client and server publicly agree on a generator base $g = 5$ and a prime modulus $p = 23$.
- The client picks a private secret $a = 6$ and computes the public value $A = g^a \pmod p = 5^6 \pmod{23} = 15625 \pmod{23} = 8$. The client transmits $A = 8$.
- The server picks a private secret $b = 15$ and computes the public value $B = g^b \pmod p = 5^{15} \pmod{23} = 19$. The server transmits $B = 19$.
- The client computes the shared secret: $K = B^a \pmod p = 19^6 \pmod{23} = 47045881 \pmod{23} = 2$.
- The server computes the shared secret: $K = A^b \pmod p = 8^{15} \pmod{23} = 35184372088832 \pmod{23} = 2$.
Both sides obtain the shared secret $K = 2$. An adversary observing the network sees $g=5$, $p=23$, $A=8$, and $B=19$. Computing $a$ or $b$ requires solving the discrete logarithm problem ($g^x \equiv A \pmod p$), which is computationally infeasible when $p$ is a 2048-bit prime or an elliptic curve (Curve25519).
The Man-in-the-Middle (MITM) Threat
Diffie-Hellman establishes encryption against passive wiretapping, but it is vulnerable to an active attacker who intercepts communications and negotiates independent keys with each side.
To prevent this, the SSH server signs the key exchange using its asymmetric host key (RSA, ECDSA, or Ed25519). The client verifies this signature against its local known_hosts file. On the very first connection, the client must rely on Trust On First Use (TOFU), displaying the key fingerprint for manual user confirmation.
Theory: Identity and the Reference Monitor
Complete mediation, separation of identity, and the kernel boundary.
Sources
- Anderson, Computer Security Technology Planning Study (US Air Force, ESD-TR-73-51, 1972)
- Saltzer & Schroeder, The Protection of Information in Computer Systems (Proceedings of the IEEE, 1975)
In 1972, James P. Anderson introduced the foundational concept of the Reference Monitor: an abstract machine that mediates all access attempts by active subjects to passive objects.
Anderson defined three mandatory properties for any reference monitor:
- Complete Mediation: The monitor must be invoked on every single access attempt without exception.
- Tamper Resistance: The monitor mechanism itself must be protected from unauthorized modification.
- Verifiability: The monitor must be small and simple enough to be formally analyzed and proven correct.
In the Linux kernel, the Virtual Filesystem (VFS) and the Linux Security Module (LSM) hooks act as the reference monitor. When a process issues an open() or unlink() system call, the kernel intercepts execution, evaluates the credentials stored in the calling process's struct cred, and compares them with the target inode's mode and ownership fields.
The AAA Framework
Identity is partitioned across three distinct security operations:
- Authentication: Verifying who the entity is (e.g., SSH password verification).
- Authorization: Determining what the authenticated entity is permitted to do (e.g., filesystem permission bit checks).
- Accounting (Auditing): Recording what the entity actually did (e.g., Linux Audit logs via
auditd).
Real vs. Effective UIDs
Every Linux process maintains multiple UID attributes:
- Real UID (RUID): Identifies the actual user who spawned the process.
- Effective UID (EUID): Evaluated by the kernel for filesystem and IPC permission checks.
- Saved UID (SUID): Enables setuid binaries to drop and regain elevated privileges safely.
When an unprivileged user executes a command, RUID and EUID match. In subsequent Ghost levels, understanding the divergence between RUID and EUID becomes the cornerstone of privilege escalation analysis.
Theory: Enumeration as a Method (Kill Chain, ATT&CK, NIST)
Systematic discovery versus aimless exploration.
Sources
- Hutchins, Cloppert & Amin, Intelligence-Driven Computer Network Defense Informed by Analysis of Adversary Campaigns and Intrusion Kill Chains (Lockheed Martin, 2011)
- MITRE ATT&CK Framework: Discovery Tactic (TA0007) (2015–Present)
- NIST Special Publication 800-115, Technical Guide to Information Security Testing and Assessment (2008)
Security assessments and forensic investigations do not proceed through random trial and error; they operate within structured threat models.
1. The Intrusion Kill Chain
Published in 2011 by Lockheed Martin researchers, the Cyber Kill Chain defines the linear phases of a cyberattack:
Reconnaissance → Weaponization → Delivery → Exploitation → Installation → Command & Control (C2) → Actions on Objectives.
When an attacker establishes an interactive shell on a target, the engagement has passed the Exploitation phase. The attacker enters the initial phase of Actions on Objectives, where local internal discovery is required to understand the operating environment.
2. MITRE ATT&CK Mapping
The MITRE ATT&CK matrix decomposes adversary behavior into specific tactics and techniques. The actions in Level 0 map directly to the Discovery (TA0007) tactic:
- T1033 (System Owner/User Discovery): Running
whoamioridto identify the active user context. - T1083 (File and Directory Discovery): Executing
ls,find, ortreeto map directory trees and locate sensitive files. - T1552.001 (Credentials in Files): Accessing unencrypted configuration files, archives, and flat files to harvest credentials.
3. NIST SP 800-115 Methodology
NIST outlines four phases of penetration testing: Planning, Discovery, Attack, and Reporting. Discovery is the engine that drives exploitation: each command run on a target trades operational risk (generating audit logs) for information gain.
Attacker vs. Defender Trade-offs: Quiet vs. Loud Enumeration
- Quiet Enumeration: Running native shell builtins and a minimal set of standard utilities (
whoami,pwd,ls -la). This generates minimal telemetry and blends into normal administrative traffic. - Loud Enumeration: Running automated post-exploitation scripts (such as LinPEAS or automated find loops) that touch thousands of files in seconds. This provides rapid discovery but triggers volume-based detection rules in modern Endpoint Detection and Response (EDR) sensors.













