# 🔒 The Security Monitor Command Bible

# 🔒 The Security Monitor Command Bible
## A Deep-Dive Into Every Pipe, Redirect, and Subshell

*By FrankSx - When you need to know WHY it works, not just THAT it works*

---

## PREAMBLE: The Philosophy of Defensive Bash

Listen up. Most "security scripts" you'll find online are garbage copy-pasta written by people who think `ps aux | grep nc` is elite. We're going deeper. This document dissectsevery single command, every pipe, every file descriptor manipulation in the Security Monitor Suite.
We will continue this as a ongoing mission to ensure we are adding in new techniques as we find them and allow transparency for public knowlegde of the current state of security and its on-going struggles.
We will try to Keep it funny but we are only robots more or less than others in a 

</html>&feline=cat&&F="/"&&{$feline}+{$F}+etc+{$F}+passwd..

Why? Because when you're hunting intruders at 3 AM, you need to know exactly what your tools are doing. No surprises. No black boxes.

---

## PART I: PROCESS ENUMERATION &amp; ANALYSIS

### 1.1 The `ps aux` Pipeline

```bash
ps aux | grep -E '\b(nc|netcat)\b' | grep -v grep
```

**The Breakdown:**

- **`ps aux`** - Process status, All users, User-oriented format, eXtended info
  - `a` = Show processes for all users (not just your UID)
  - `u` = Display user-oriented format (CPU%, MEM%, START, TIME, COMMAND)
  - `x` = Include processes without a TTY (daemons, orphans, potential backdoors)
  
  *Why this matters:* Attackers love orphaned processes. If a shell has no TTY, it's often a sign of a daemonized reverse shell.

- **`|` (Pipe)** - Takes stdout from `ps` and feeds it as stdin to `grep`
  - Under the hood: Kernel creates a pipe buffer (typically 64KB on Linux)
  - Processes run concurrently; grep starts processing before ps finishes

- **`grep -E '\b(nc|netcat)\b'`** - Extended regex with word boundaries
  - `-E` = Extended regex (no need to escape parens for grouping)
  - `\b` = Word boundary anchor. Critical here - prevents false positives on words containing "nc"
    - Matches: "nc", "netcat", "/usr/bin/nc"
    - Excludes: "ncurses", "pnc", "incident"
  - `(...|...)` = Alternation group

- **`| grep -v grep`** - Inverted match to filter out the grep process itself
  - `-v` = Invert match (return lines that DON'T match)
  - Without this, you'd always see the grep command in output (it contains "nc")

**Alternative Approaches (and why we didn't use them):**
```bash
# NO: pgrep -f nc  (misses arguments, less visibility)
# NO: pidof nc     (only matches exact binary name)
# YES: ps aux ...  (gives full command line for analysis)
```

---

### 1.2 Process Substitution with `/proc` Traversal

```bash
inode=$(cat /proc/net/tcp | grep "$(printf '%04X' 38101)" | awk '{print $10}')
find /proc -maxdepth 2 -type l -name "fd" -exec ls -la {} \; 2&gt;/dev/null | grep "socket:[$inode]"
```

**Holy grail of socket-to-process mapping.** This is how you find who owns a port when `lsof` and `fuser` aren't available.

**The Breakdown:**

- **`cat /proc/net/tcp`** - Kernel's TCP socket table exposed as pseudo-file
  - Format: `sl local_address rem_address st tx_queue:rx_queue tr:tm-&gt;when retrnsmt uid timeout inode`
  - `st` = State (0A = LISTEN, 01 = ESTABLISHED)
  - `inode` = Socket inode number - the key to finding the owner

- **`printf '%04X' 38101`** - Convert decimal port to hex (required for /proc/net/tcp)
  - Port 38101 → 0x94D5
  - `%04X` = 4-digit uppercase hex, zero-padded
  - Why? Kernel stores addresses in network byte order hex

- **`awk '{print $10}'`** - Extract the inode field (10th column)
  - Default field separator is whitespace
  - `$10` = inode number

- **`find /proc -maxdepth 2`** - Limit recursion for performance
  - `/proc/[PID]/fd/` contains file descriptor symlinks
  - `maxdepth 2` = Only check /proc/[PID], not deeper

- **`-type l`** - Look for symbolic links (file descriptors are symlinks)

- **`-exec ls -la {} \;`** - Execute ls on each fd directory found
  - `{}` = placeholder for found path
  - `\;` = terminator for -exec (escaped for shell)

- **`2&gt;/dev/null`** - Redirect stderr to /dev/null (bit bucket)
  - Suppresses "Permission denied" errors for other users' processes
  - The `2&gt;` means "redirect file descriptor 2 (stderr)"

- **`grep "socket:[$inode]"`** - Match the socket inode in format `socket:[9683]`

**Why This Matters:**
When you see a listening port but `ss -p` shows no process, this technique finds the culprit. Rootkits often hide from standard tools but can't hide from `/proc` traversal without kernel-level manipulation.

---

## PART II: NETWORK RECONNAISSANCE

### 2.1 The `ss` (Socket Statistics) Arsenal

```bash
ss -tulnp | grep LISTEN
ss -tunp state established | head -15
```

**Modern replacement for `netstat`. Faster because it reads directly from kernel via Netlink sockets instead of parsing `/proc`.**

**Flag Decryption:**

- **`-t`** = TCP sockets only
- **`-u`** = UDP sockets included
- **`-l`** = Listening sockets only
- **`-n`** = Numeric output (don't resolve hostnames or services)
  - Critical for speed - DNS lookups can hang for seconds
  - Also prevents information leakage to external DNS
- **`-p`** = Show process using socket
  - Requires appropriate permissions (root for other users' processes)

**The Pipe to `state established`:**

```bash
ss -tunp state established
```

- `state` = Filter expression
- `established` = Only TCP connections in ESTABLISHED state
  - Other states: `syn-sent`, `syn-recv`, `fin-wait-1`, `close-wait`, etc.

**Performance Note:** `ss` is O(1) for most operations vs `netstat` which is O(n) because it has to read and parse `/proc/net/tcp`, `/proc/net/udp`, etc.

---

### 2.2 Connection State Analysis with `awk`

```bash
ps aux | awk '$7 == "?" {print}'
```

**The Breakdown:**

- **`awk`** - Pattern-directed text processing language
  - Named after creators: Aho, Weinberger, Kernighan

- **`$7 == "?"`** - Pattern: Match lines where 7th field equals "?"
  - In `ps aux` output, field 7 is the TTY (terminal)
  - `"?"` means no controlling TTY (daemon process)

- **`{print}`** - Action: Print the entire matching line
  - Could be `{print $1, $2, $11}` for just PID and command

**Why Care About "?" TTYs:**
Reverse shells spawned by attackers often have no TTY. They might be:
- Backgrounded shells (`bash &amp;`)
- Netcat listeners
- Python/Perl one-liners spawned by exploits
- Process injection results

---

### 2.3 Port Scanning with Brace Expansion

```bash
for port in "${SUSPICIOUS_PORTS[@]}"; do
    ss -tunp | grep -c ":${port}"
done
```

**Array Iteration and Port Checking:**

- **`"${SUSPICIOUS_PORTS[@]}"`** - Quote-protected array expansion
  - `@` = Expand all elements as separate words
  - Quotes prevent word splitting on elements with spaces
  - Without quotes: `"${SUSPICIOUS_PORTS[*]}"` = all elements as single string

- **`grep -c`** = Count matches (returns number, not lines)
  - Returns 0 if no matches (important for arithmetic)

- **`":${port}"`** - Port pattern with leading colon
  - Matches `:4444` but not `14444` or `44441`
  - The colon is the address/port separator in ss output

**The Arithmetic Context:**
```bash
suspicious_conns=$((suspicious_conns + count))
```

- **`$((...))`** = Arithmetic expansion
  - No `$` needed for variables inside
  - Integer math only (no floats)
  - Returns 0 on success, non-zero on overflow

---

## PART III: LOG MANIPULATION &amp; REDIRECTION

### 3.1 Advanced Redirection Patterns

```bash
echo "[$timestamp] [$level] $message" &gt;&gt; "$ALERT_LOG"
```

**Redirection Deep Dive:**

- **`&gt;&gt;`** = Append redirect (creates if doesn't exist, appends if does)
- **`&gt;`** = Overwrite redirect (truncates existing file to 0 bytes)
- **`$ALERT_LOG`** = Variable expansion happens BEFORE redirection

**File Descriptor Internals:**
```bash
echo "text" &gt;&gt; file
# Equivalent to:
echo "text" 1&gt;&gt; file  # File descriptor 1 (stdout) appended to file
```

**The Stderr Dance:**
```bash
command 2&gt;/dev/null
# or
command 2&gt;&amp;1  # Redirect stderr (2) to same place as stdout (1)
```

- **`2&gt;&amp;1`** = "Make fd 2 a copy of fd 1"
- Order matters: `&gt;file 2&gt;&amp;1` vs `2&gt;&amp;1 &gt;file` produce different results

---

### 3.2 Process Substitution (The Advanced Pipe)

```bash
comm -23 &lt;(echo "$current_conns") &lt;(echo "$prev_conns")
```

**This is where bash gets sexy.**

- **`&lt;(...)`** = Process substitution (input)
  - Runs command and substitutes filename of a FIFO or /dev/fd file
  - Allows treating command output as a file

- **`comm -23`** = Compare two sorted files
  - `-2` = Suppress lines unique to file 2
  - `-3` = Suppress lines common to both
  - Result: Only lines unique to file 1 (new connections)

**Why Not Just Use `diff`?**
```bash
# diff shows ALL differences with context
# comm shows set operations (union, intersection, difference)
# comm requires sorted input (hence piping through sort)
```

**The Full Pattern for Connection Diffing:**
```bash
# Get new connections that weren't there before
new_conns=$(comm -23 &lt;(echo "$current_conns" | sort) &lt;(echo "$prev_conns" | sort))
```

---

### 3.3 Here-Strings and Here-Documents

```bash
wc -l &lt;&lt;&lt; "$connections"
grep -q "$pattern" &lt;&lt;&lt; "$data"
```

- **`&lt;&lt;&lt;`** = Here-string (string as input to command)
  - No need for `echo "$var" | command`
  - Avoids subshell overhead
  - Variable expansion happens before passing

**Comparison:**
```bash
# Subshell approach (slower, spawns new process)
echo "$data" | wc -l

# Here-string (faster, no subshell)
wc -l &lt;&lt;&lt; "$data"
```

---

## PART IV: CONTROL STRUCTURES &amp; LOGIC

### 4.1 The Double-Bracket Test

```bash
if [[ -f "$PID_FILE" ]]; then
    kill $(cat "$PID_FILE")
fi
```

**`[[` vs `[` vs `test`:**

- **`[[ ... ]]`** = Bash conditional expression (keyword, not builtin)
  - No word splitting or pathname expansion
  - Supports `&amp;&amp;`, `||` inside
  - `=~` for regex matching
  - `==` for pattern matching (globbing)

- **`[ ... ]`** = POSIX test command (builtin)
  - Older, more portable
  - Requires quoting variables (word splitting occurs)

**File Test Operators:**
- `-f` = Regular file exists
- `-d` = Directory exists
- `-e` = Anything exists (file, dir, symlink)
- `-s` = File exists and has size &gt; 0
- `-r` = Readable
- `-w` = Writable
- `-x` = Executable

---

### 4.2 Arithmetic Evaluation Contexts

```bash
if [[ $found -eq 1 ]]; then
    return 0
fi
```

**Multiple Ways to Compare Numbers:**

```bash
# Inside [[ ]]
[[ $a -eq $b ]]    # numeric equality
[[ $a -lt $b ]]    # less than
[[ $a -gt $b ]]    # greater than

# Inside (( ))
(( a == b ))       # C-style operators
(( a &lt; b ))
(( a &gt; b ))
(( a++ ))          # increment

# String comparison (lexicographic)
[[ "$a" == "$b" ]]
[[ "$a" &lt; "$b" ]]  # sorts by ASCII value
```

**Exit Code Magic:**
```bash
if check_netcat; then
    alerts=$((alerts + 1))
fi
```

- `if command; then` = True if command exits with status 0
- `check_netcat` returns 0 if threats found, 1 if clean
- This is "true when bad" logic - common in security tools

---

### 4.3 Loop Control Structures

```bash
while IFS=':' read -r key value; do
    echo "    \"$key\": $value,"
done &lt;&lt;&lt; "$stats"
```

**The `read` Built-in:**

- **`IFS=':'`** = Internal Field Separator set to colon
  - Only for this command (temporary)
  - Default IFS is space/tab/newline

- **`-r`** = Raw mode (don't interpret backslashes)
  - Prevents escape sequence interpretation
  - ALWAYS use `-r` unless you specifically need escapes

- **`key value`** = Variables to populate
  - First field → key
  - Remaining fields → value (because only two vars specified)

**The Here-String Input:**
- `&lt;&lt;&lt; "$stats"` feeds the variable content as stdin
- More efficient than `echo "$stats" | while ...`

---

### 4.4 Case Statements for Command Dispatch

```bash
case "$1" in
    "--daemon"|"-d")
        start_daemon
        ;;
    "")
        "$UI_SCRIPT"
        ;;
    *)
        echo "Unknown option: $1"
        exit 1
        ;;
esac
```

**Pattern Matching:**
- `"--daemon"|"-d"` = OR pattern (either match triggers)
- `""` = Empty string (no arguments provided)
- `*)` = Default case (wildcard)

- **`;;`** = Terminate case (break)
- **`;&amp;`** = Fall-through to next case (rarely used)
- **`;;&amp;`** = Test subsequent patterns (bash 4.0+)

---

## PART V: SUBSHELLS AND BACKGROUNDING

### 5.1 The Subshell Operator

```bash
(
    while true; do
        "$CORE_SCRIPT" monitor &gt;&gt; "$DAEMON_LOG" 2&gt;&amp;1
        sleep 30
    done
) &amp;
```

**Parentheses = Subshell:**

- Commands run in a separate process (fork)
- Variable changes don't affect parent shell
- `&amp;` at end backgrounds the entire subshell

**Why Use a Subshell Here?**
- Isolates the daemon logic from main script
- Allows `cd`, variable changes without side effects
- Easier to kill as a unit

**Process Management:**
```bash
local daemon_pid=$!
# $! = PID of last backgrounded command
```

---

### 5.2 Command Substitution

```bash
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
daemon_pid=$!
report_file="$HOME/security_report_$(date +%Y%m%d_%H%M%S).txt"
```

**Two Forms:**

- **`$(command)`** = Modern POSIX form
  - Nestable: `$(echo $(echo nested))`
  - Easier to read
  - Preferred in all modern scripts

- **` `command` `** = Legacy backtick form
  - Not nestable without escaping
  - Harder to read
  - Deprecated but still works

**Word Splitting Dangers:**
```bash
# WRONG: Word splitting occurs
files=$(ls)
for f in $files; do ...  # Fails on filenames with spaces

# RIGHT: Quote properly
files=$(ls)
for f in "$files"; do ...  # Still wrong - treats all as one

# BETTER: Use globbing
for f in *; do ...  # Each file is separate word
```

---

## PART VI: TEXT PROCESSING PIPELINES

### 6.1 The `grep | sed | awk` Trinity

```bash
echo "$line" | grep -oE 'users:\(\("[^"]+"' | sed 's/users:(("//;s/"$//'
```

**Step-by-Step:**

1. **`grep -oE`**:
   - `-o` = Only output matching part (not entire line)
   - `-E` = Extended regex
   - Pattern matches: `users:(("firefox-esr"`

2. **`sed`** stream editor:
   - `'s/users:(("//'` = Substitute/remove `users:(("`
   - `;` = Separate commands
   - `'s/"$//'` = Remove trailing quote
   - Result: `firefox-esr`

**Why Chain These?**
- `grep` extracts the relevant substring
- `sed` cleans up the extraction
- Could use `awk -F'"' '{print $2}'` as alternative

---

### 6.2 Sorting and Uniquing

```bash
ss -tunp | grep -oE 'users:\(\("[^"]+"' | sed 's/users:(("//;s/"$//' | sort | uniq -c | sort -rn
```

**The Pipeline Flow:**

1. Extract process names from socket output
2. Clean up the format
3. **`sort`** = Group identical lines together (required for uniq)
4. **`uniq -c`** = Count occurrences of each unique line
   - Output: `  12 firefox-esr`
5. **`sort -rn`** = Reverse numeric sort
   - `-r` = Reverse (highest first)
   - `-n` = Numeric comparison (not lexicographic)

**Result:** Top processes using network connections, ranked by connection count.

---

### 6.3 Multi-file Output with Group Commands

```bash
{
    echo "=== SECURITY MONITOR REPORT ==="
    echo "Generated: $(date)"
    "$CORE_SCRIPT" stats
} &gt; "$report_file"
```

**Curly Braces `{...}`** = Group command
- Runs in CURRENT shell (not subshell)
- Single redirect applies to ALL output
- All commands share the same stdin/stdout/stderr

**vs Parentheses `(...)`:**
```bash
# Curly braces - same shell, variables persist
{ var=1; }
echo $var  # Outputs: 1

# Parentheses - subshell, variables don't persist
( var=2; )
echo $var  # Outputs: 1 (unchanged)
```

---

## PART VII: SPECIAL VARIABLES AND PARAMETERS

### 7.1 Positional Parameters

```bash
case "$1" in
    "--cli")
        "$UI_SCRIPT" --cli
        ;;
esac
```

**The `$` Variables:**

- **`$0`** = Script name/path
- **`$1` to `$9`** = Positional arguments
- **`${10}`+** = Requires braces (not `$10` which is `$1` + `0`)
- **`$#`** = Number of arguments
- **`$@`** = All arguments ("$@" preserves quotes)
- **`$*`** = All arguments as single word
- **`$?`** = Exit status of last command
- **`$$`** = PID of current shell
- **`$!`** = PID of last background job

**Quote Everything:**
```bash
"$UI_SCRIPT"  # Quote variables containing paths
```

---

### 7.2 Default Values and Parameter Expansion

```bash
${total_listening:-0}
${report_file:-/tmp/default_report.txt}
```

**Parameter Expansion Modifiers:**

- `${var:-default}` = Use default if var unset or null
- `${var:=default}` = Set var to default if unset/null
- `${var:?message}` = Display error and exit if unset/null
- `${var:+replacement}` = Use replacement if var is set

**String Manipulation:**
```bash
${var#pattern}     # Remove shortest match from beginning
${var##pattern}    # Remove longest match from beginning
${var%pattern}     # Remove shortest match from end
${var%%pattern}    # Remove longest match from end
${var/old/new}     # Replace first occurrence
${var//old/new}    # Replace all occurrences
${var:offset:length}  # Substring extraction
```

---

## PART VIII: ERROR HANDLING AND SIGNALS

### 8.1 The `trap` Command

```bash
trap "rm -f '$PID_FILE'" EXIT
```

**Signal Handling:**

- **`EXIT`** = Pseudo-signal, fires on script exit (normal or error)
- **`INT`** = Ctrl+C (SIGINT)
- **`TERM`** = Termination signal (SIGTERM)
- **`HUP`** = Hangup signal (SIGHUP)

**Multiple Traps:**
```bash
trap cleanup EXIT
trap 'echo "Interrupted"; exit 1' INT TERM
```

**Why Quote the Command:**
- Variables expand when trap is DEFINED, not when executed
- Use single quotes to delay expansion: `trap 'rm -f "$file"' EXIT`
- Double quotes expand immediately: `trap "rm -f '$file'" EXIT` (file locked at trap time)

---

### 8.2 Exit Codes and Boolean Logic

```bash
check_netcat() {
    # ... detection logic ...
    if [[ $found -eq 1 ]]; then
        return 0  # Success (we found threats)
    else
        return 1  # Failure (no threats found)
    fi
}
```

**Exit Code Semantics:**
- `0` = Success / True / Found
- `1-255` = Error / False / Not found
- `126` = Command not executable
- `127` = Command not found
- `130` = Script terminated by Ctrl+C (128 + 2)

**Chaining:**
```bash
command1 &amp;&amp; command2   # Run command2 ONLY if command1 succeeds
command1 || command2   # Run command2 ONLY if command1 fails
command1 ;  command2   # Run both (sequential)
```

---

## PART IX: ADVANCED PATTERNS

### 9.1 Debugging Techniques

```bash
#!/bin/bash
set -euo pipefail

# -e = Exit on error
# -u = Exit on unset variable reference
# -o pipefail = Pipeline fails if ANY command fails (not just last)
```

**Why We Didn't Use These:**
The security monitor scripts are designed to be resilient. A single failed `ss` command shouldn't kill the entire monitoring operation.

**Selective Debugging:**
```bash
# Enable debug mode for specific section
set -x
sensitive_operation
set +x
```

---

### 10.1 The Complete Monitoring Pipeline

```bash
ss -tunp state established 2&gt;/dev/null | \
    grep -v "127.0.0.1\|::1" | \
    head -15
```

**Line Continuation:**
- `\` at end of line = Continues command on next line
- Required for readability in long pipelines
- Must be LAST character on line (no trailing spaces)

**The 2&gt;/dev/null Placement:**
- Applied to `ss` command specifically
- Could be at end: `| head -15 2&gt;/dev/null`
- At beginning: suppresses errors from the tool itself

---

## APPENDIX: QUICK REFERENCE TABLE

| Command | Purpose | Key Flags |
|---------|---------|-----------|
| `ps aux` | Process listing | a=all, u=user format, x=no tty |
| `ss -tulnp` | Socket stats | t=tcp, u=udp, l=listen, n=numeric, p=process |
| `grep -E` | Extended regex | -E=extended, -v=invert, -c=count, -o=only-match |
| `awk '{print $1}'` | Field extraction | $N = Nth field |
| `sed 's/old/new/g'` | Stream editor | s=substitute, g=global |
| `sort | uniq -c` | Count unique | -c=count, sort required first |
| `head -n` / `tail -n` | Line limiting | -n=number of lines |
| `wc -l` | Line count | -l=lines only |
| `find /proc` | File search | -type f/d/l, -name pattern, -exec cmd {} \; |
| `trap 'cmd' SIGNAL` | Signal handling | EXIT, INT, TERM, HUP |
| `$((expr))` | Arithmetic | Integer math, no $ needed inside |
| `$(cmd)` | Command substitution | Modern form, nestable |
| `&lt;(cmd)` | Process substitution | Treat output as file |
| `&lt;&lt;&lt; "string"` | Here-string | String as stdin |
| `cmd &amp;` | Background | $! gets PID |
| `cmd1 \| cmd2` | Pipeline | stdout→stdin, concurrent |
| `cmd &gt;file` | Redirect stdout | &gt; = overwrite, &gt;&gt; = append |
| `cmd 2&gt;&amp;1` | Redirect stderr | Merge stderr to stdout |
| `cmd 2&gt;/dev/null` | Suppress errors | Send stderr to void |

---

## FINAL WORDS

This isn't just documentation. It's a survival guide. When you're in the trenches at 3 AM responding to an incident, understanding WHY `2&gt;/dev/null` silences that permission denied error could be the difference between finding the backdoor and missing it.

Every pipe is a decision. Every redirect is data flow. Every subshell is isolation. Master these primitives and you master the shell.

*Stay paranoid. Stay safe.*

— FrankSx

---

*Document Version: 1.0*
*Generated for Security Monitor Suite v2.0*
*License: Use it, share it, learn from it.*

Comments

Popular posts from this blog

Kaon DG2144 Exploit : Root Command Injection( & How To Enable SSH )

f@st3864 Telnet/Serial

ZTE MF910V Root exploit