<?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: MuneebAhmedKhan-writing</title>
    <description>The latest articles on DEV Community by MuneebAhmedKhan-writing (@muneebahmedkhanwriting).</description>
    <link>https://dev.to/muneebahmedkhanwriting</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%2F4064070%2F0b7013cc-c71f-42bc-a19b-91904806f596.png</url>
      <title>DEV Community: MuneebAhmedKhan-writing</title>
      <link>https://dev.to/muneebahmedkhanwriting</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/muneebahmedkhanwriting"/>
    <language>en</language>
    <item>
      <title>One Address, Many Spellings: CIDR Host Counts and the Loopback Notations SSRF Filters Miss</title>
      <dc:creator>MuneebAhmedKhan-writing</dc:creator>
      <pubDate>Sat, 22 Aug 2026 10:37:22 +0000</pubDate>
      <link>https://dev.to/muneebahmedkhanwriting/one-address-many-spellings-cidr-host-counts-and-the-loopback-notations-ssrf-filters-miss-4hni</link>
      <guid>https://dev.to/muneebahmedkhanwriting/one-address-many-spellings-cidr-host-counts-and-the-loopback-notations-ssrf-filters-miss-4hni</guid>
      <description>&lt;p&gt;A number has one value and many notations. This walks through counting usable hosts in a CIDR block from memory, then writing &lt;code&gt;127.0.0.1&lt;/code&gt; five ways — the set a filter that pattern-matches on notation, rather than resolving to the value, fails to catch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Comfort with powers of two up to 2²⁴&lt;/li&gt;
&lt;li&gt;A calculator for the large multiplications&lt;/li&gt;
&lt;li&gt;No tools, VM, or network — this is math and notation only&lt;/li&gt;
&lt;li&gt;Prior exposure to what SSRF is, and why loopback is the target of a bypass&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Part 1 — CIDR host counts
&lt;/h2&gt;

&lt;p&gt;The method, once: 32 − prefix = free bits, then 2^(free bits) − 2. The −2 removes the network address and the broadcast address, neither assignable to a host. This holds for &lt;code&gt;/30&lt;/code&gt; and larger; &lt;code&gt;/31&lt;/code&gt; and &lt;code&gt;/32&lt;/code&gt; are special cases, covered at the end of this part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Compute /24.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;32 − 24 = 8 free bits → 2⁸ = 256 → 256 − 2 = &lt;strong&gt;254 usable hosts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Compute /16.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;32 − 16 = 16 free bits → 2¹⁶ = 65,536 → &lt;strong&gt;65,534 usable hosts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Compute /8.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;32 − 8 = 24 free bits → 2²⁴ = 16,777,216 → &lt;strong&gt;16,777,214 usable hosts&lt;/strong&gt; (~16.7 million).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. State the pattern.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every 1 you subtract from the prefix doubles the host count: &lt;code&gt;/24&lt;/code&gt; → &lt;code&gt;/23&lt;/code&gt; goes from 254 to 510, and on up. Remember the doubling and you never need the table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Note the two special cases.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;/31&lt;/code&gt; has no room for the −2 — it would compute to zero. RFC 3021 instead makes both addresses usable, giving 2 hosts, because point-to-point links don't need a network or broadcast address. A &lt;code&gt;/32&lt;/code&gt; is a single host: one address, no subtraction. Below &lt;code&gt;/30&lt;/code&gt;, the −2 rule stops applying.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2 — Five spellings of 127.0.0.1
&lt;/h2&gt;

&lt;p&gt;Each octet has a positional value: 256³, 256², 256¹, 256⁰. Every representation below points at the same loopback address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. As a single decimal integer.&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 × 256³ + 0 × 256² + 0 × 256¹ + 1 × 256⁰
= 127 × 16,777,216 + 1
= 2,130,706,433
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ &lt;code&gt;2130706433&lt;/code&gt;. Some parsers accept this bare integer as a host — which ones is exactly what a bypass attempt is testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. As hex.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two hex digits per octet, concatenated: 127 = &lt;code&gt;7f&lt;/code&gt;, 0 = &lt;code&gt;00&lt;/code&gt;, 0 = &lt;code&gt;00&lt;/code&gt;, 1 = &lt;code&gt;01&lt;/code&gt; → &lt;code&gt;0x7f000001&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. As octal.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each octet in base 8, with a leading zero to signal octal: 127 = &lt;code&gt;0177&lt;/code&gt;, so &lt;code&gt;0177.0.0.1&lt;/code&gt;. The leading zero is load-bearing — without it the octet is read as decimal, and 177 is a different value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. As the short form.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;127.1&lt;/code&gt;. Parsers using the traditional &lt;code&gt;inet_aton&lt;/code&gt; behavior read the final part as a 24-bit value filling the remaining octets, so &lt;code&gt;127.1&lt;/code&gt; resolves to &lt;code&gt;127.0.0.1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. As the two IPv6 forms — and know the difference.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[::1]&lt;/code&gt; is IPv6's own native loopback: not a conversion of the IPv4 address, its own separate concept. &lt;code&gt;[::ffff:127.0.0.1]&lt;/code&gt; is an IPv4-mapped IPv6 address, embedding the actual IPv4 address inside IPv6 syntax. They are not interchangeable, and a filter may handle one but not the other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why the list exists.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A filter written as &lt;code&gt;if "127.0.0.1" in url: block&lt;/code&gt; checks one spelling of an address that has many. Each of the five forms above reaches the identical machine while walking straight past that check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verification check
&lt;/h2&gt;

&lt;p&gt;Reverse the decimal conversion: 2,130,706,433 ÷ 16,777,216 = 127 remainder 1. The whole-number quotient is the first octet, the remainder resolves to the last — confirming &lt;code&gt;127.x.x.1&lt;/code&gt;. If the quotient isn't exactly 127, recheck the arithmetic before trusting the value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;These are the traps inherent to the math, not runtime errors — there's nothing to run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Host count off by two.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The −2 was skipped or applied twice. It removes exactly two reserved addresses (network + broadcast) for &lt;code&gt;/30&lt;/code&gt; and larger. Sanity anchor: a &lt;code&gt;/30&lt;/code&gt; has 4 total, 2 usable. If you're working below &lt;code&gt;/30&lt;/code&gt;, use the special cases in Part 1, step 5 instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Octal form read as decimal.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dropping the leading zero — &lt;code&gt;177.0.0.1&lt;/code&gt; instead of &lt;code&gt;0177.0.0.1&lt;/code&gt; — changes the value: 177 decimal is a different address. The zero is what signals base 8.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Treating &lt;code&gt;[::1]&lt;/code&gt; as a conversion of &lt;code&gt;127.0.0.1&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It isn't derived from the IPv4 address; it's IPv6's separate loopback. The genuine cross-protocol encoding is &lt;code&gt;[::ffff:127.0.0.1]&lt;/code&gt;. Conflating the two produces a bypass list that misrepresents what each entry is — which matters when you're explaining a filter gap in a report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;CIDR math and the loopback notation list look unrelated, but both come down to one habit: a number has a single value and many notations, and anything that pattern-matches on notation instead of resolving to the value is the thing you're looking for.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Drafted and revised with Claude; all math verified by me.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Downloading and Running a Kali Linux VM in VirtualBox on Windows</title>
      <dc:creator>MuneebAhmedKhan-writing</dc:creator>
      <pubDate>Sat, 22 Aug 2026 10:21:06 +0000</pubDate>
      <link>https://dev.to/muneebahmedkhanwriting/downloading-and-running-a-kali-linux-vm-in-virtualbox-on-windows-51hl</link>
      <guid>https://dev.to/muneebahmedkhanwriting/downloading-and-running-a-kali-linux-vm-in-virtualbox-on-windows-51hl</guid>
      <description>&lt;p&gt;By the end of this guide you will have VirtualBox installed and a Kali Linux virtual machine imported and running — an isolated environment for security practice that leaves your host system untouched.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows 11 Pro (64-bit)&lt;/li&gt;
&lt;li&gt;At least 8 GB RAM, so you can give the VM 4 GB and leave the host enough&lt;/li&gt;
&lt;li&gt;30 GB free disk space (the VM's disk grows as you install tools — more headroom is better)&lt;/li&gt;
&lt;li&gt;Hardware virtualization (VT-x or AMD-V) enabled in BIOS/UEFI&lt;/li&gt;
&lt;li&gt;7-Zip, for extracting the archive&lt;/li&gt;
&lt;li&gt;No prior virtualization experience required&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Download VirtualBox.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Get it from the official site, virtualbox.org/wiki/Downloads. Use the Windows hosts package. Avoid third-party mirror and download sites — a virtualization host is not something to install from an unverified source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Install VirtualBox.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the installer with default options. Expect: a brief network interruption partway through, which is normal — the installer adds virtual network adapters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Download the Kali VirtualBox image.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Get it from kali.org/get-kali/ and choose the VirtualBox 64-bit image, a &lt;code&gt;.7z&lt;/code&gt; archive of several GB. Note the SHA256 value shown on the download page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Verify the checksum before extracting.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open PowerShell in your download folder and run:&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="n"&gt;Get-FileHash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;kali-linux-&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;-virtualbox-amd64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;7z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Algorithm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SHA256&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expect: a hash that matches the value on Kali's page exactly. If it doesn't match, delete the file and download again — do not extract it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Extract the archive.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Right-click the &lt;code&gt;.7z&lt;/code&gt; file and extract it with 7-Zip. Expect: a folder containing a &lt;code&gt;.vbox&lt;/code&gt; file and a large &lt;code&gt;.vdi&lt;/code&gt; disk image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Add the VM to VirtualBox.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open VirtualBox, click &lt;strong&gt;Add&lt;/strong&gt; (the machine menu, not File → Import Appliance), and select the &lt;code&gt;.vbox&lt;/code&gt; file from the extracted folder. Expect: the VM appears in the left-hand list.&lt;/p&gt;

&lt;p&gt;If your download extracted to a single &lt;code&gt;.ova&lt;/code&gt; file instead of a &lt;code&gt;.vbox&lt;/code&gt; + &lt;code&gt;.vdi&lt;/code&gt; pair, use &lt;strong&gt;File → Import Appliance&lt;/strong&gt; and select the &lt;code&gt;.ova&lt;/code&gt;. Kali ships the prebuilt image in either form depending on the release; the rest of this guide is the same once the VM is in the list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Check the allocated resources.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Right-click the VM, open &lt;strong&gt;Settings&lt;/strong&gt;, then &lt;strong&gt;System → Motherboard&lt;/strong&gt; for RAM and &lt;strong&gt;System → Processor&lt;/strong&gt; for CPU cores. Keep RAM at or below half your host's total, and leave at least two cores for the host. Expect: the sliders stay in the green range.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Start the VM.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Select it and click &lt;strong&gt;Start&lt;/strong&gt;. Expect: a boot sequence, then the Kali login screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Log in.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the default credentials, &lt;code&gt;kali&lt;/code&gt; / &lt;code&gt;kali&lt;/code&gt;. These are specific to Kali's prebuilt VM image — a Kali installer ISO sets its own credentials during install instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verification
&lt;/h2&gt;

&lt;p&gt;The VM boots to the Kali desktop and the terminal opens. Run this inside the VM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see an interface with an address, confirming networking works. A VM that boots but has no network is only half-configured.&lt;/p&gt;

&lt;p&gt;If the desktop is stuck at a small resolution or clipboard sharing doesn't work, the Guest Additions version in the image doesn't match your VirtualBox. It's not a failure — the VM is running. Reinstalling Guest Additions from the VirtualBox Devices menu fixes the display and clipboard when you want them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;VirtualBox only offers 32-bit options, or the VM fails to start.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hardware virtualization is disabled. Reboot into BIOS/UEFI and enable VT-x (Intel) or AMD-V (AMD). The setting is usually under CPU or Advanced.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The VM starts but is extremely slow, or throws a VT-x error on Windows 11.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hyper-V is holding the virtualization layer, and VirtualBox can't use it at the same time. Disable Hyper-V, Windows Hypervisor Platform, and Virtual Machine Platform in "Turn Windows features on or off," then reboot. Memory integrity under Windows Security → Device security → Core isolation also enables Hyper-V silently; turn it off too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The checksum doesn't match.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Delete the file and download it again. A mismatch means the download was corrupted or the file was tampered with. Do not extract or import it either way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The extraction fails or the folder looks incomplete.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Extract to a path with no spaces or non-English characters, and make sure you have twice the archive size free — 7-Zip needs room for both the archive and the expanded disk image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;The point of the VM is separation. Anything you install, break, or get compromised by inside Kali stays inside Kali, and the host system is never touched.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Drafted and revised with Claude; every step tested by me.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>linux</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Send an HTTP Request by Hand With Netcat</title>
      <dc:creator>MuneebAhmedKhan-writing</dc:creator>
      <pubDate>Sun, 16 Aug 2026 11:05:18 +0000</pubDate>
      <link>https://dev.to/muneebahmedkhanwriting/send-an-http-request-by-hand-with-netcat-m4</link>
      <guid>https://dev.to/muneebahmedkhanwriting/send-an-http-request-by-hand-with-netcat-m4</guid>
      <description>&lt;p&gt;Type a raw HTTP request into a TCP socket, read back a real &lt;code&gt;200 OK&lt;/code&gt;, then watch one wrong character kill it. No browser, no library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Linux terminal (any distro; a VM is fine)&lt;/li&gt;
&lt;li&gt;bash or zsh&lt;/li&gt;
&lt;li&gt;Internet access&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Check for netcat and identify the variant.&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;which nc &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; nc &lt;span class="nt"&gt;-h&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expect: a path such as &lt;code&gt;/usr/bin/nc&lt;/code&gt;, then a line naming the build — &lt;code&gt;OpenBSD netcat&lt;/code&gt; or &lt;code&gt;Ncat 7.xx&lt;/code&gt;. Write down which one; steps 11 and 12 use a different flag on each. Anything else, such as a bare version like &lt;code&gt;[v1.10-47]&lt;/code&gt;, is netcat-traditional — use the flags exactly as written. If nothing prints, continue to step 2. Otherwise skip to step 3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Install netcat.&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="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;netcat-openbsd     &lt;span class="c"&gt;# Debian, Ubuntu&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;nmap-ncat          &lt;span class="c"&gt;# Fedora, RHEL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On other distros, install your package manager's OpenBSD netcat package. Re-run step 1. Expect: a path and a variant name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Confirm outbound port 80 works.&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;nc &lt;span class="nt"&gt;-vz&lt;/span&gt; example.com 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expect: a success message naming the port. A timeout or a name-resolution error means your network blocks outbound port 80 or cannot resolve the host — nothing below will work until you move to a network that permits both. If &lt;code&gt;-z&lt;/code&gt; is rejected, see Troubleshooting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Store the request.&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="nv"&gt;REQ&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use single quotes. They stop the shell from expanding anything inside the string, which matters once you add header values containing &lt;code&gt;$&lt;/code&gt; or a backtick.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Send the request.&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="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%b'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REQ&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | nc example.com 80 | &lt;span class="nb"&gt;tee &lt;/span&gt;response.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;%b&lt;/code&gt; makes &lt;code&gt;printf&lt;/code&gt; interpret the &lt;code&gt;\r\n&lt;/code&gt; escapes instead of printing them as text; &lt;code&gt;tee&lt;/code&gt; writes to the file and the screen at once.&lt;/p&gt;

&lt;p&gt;Expect: &lt;code&gt;HTTP/1.1 200 OK&lt;/code&gt;, a block of headers, a blank line, then HTML. The body scrolls past — read it from the file in the steps below. Re-running overwrites the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Read the status line.&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="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; response.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expect: three parts in order — protocol version, status code, reason phrase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Read the header block.&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="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'1,/^\r$/p'&lt;/span&gt; response.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for &lt;code&gt;Content-Length&lt;/code&gt; or &lt;code&gt;Transfer-Encoding&lt;/code&gt;, and for &lt;code&gt;Allow&lt;/code&gt;. Any of them may be absent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Open the whole response.&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;less response.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every header line ends in &lt;code&gt;^M&lt;/code&gt;, as do the chunk-size lines further down. That is the carriage return you sent, not corruption. Press &lt;code&gt;q&lt;/code&gt; to exit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Find the first line after the headers.&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="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'/^\r$/{n;p;q;}'&lt;/span&gt; response.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;{n;p;q;}&lt;/code&gt; advances one line past the blank line, prints it, and stops. Applies only if step 7 showed &lt;code&gt;Transfer-Encoding: chunked&lt;/code&gt;. Expect: a short hex number such as &lt;code&gt;22f&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Read the end of the response.&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="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-2&lt;/span&gt; response.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Applies only to a chunked response. Expect: a lone &lt;code&gt;0&lt;/code&gt;, then a line that looks blank. It isn't — it holds the carriage return from the terminating chunk's own CRLF, the same &lt;code&gt;^M&lt;/code&gt; you saw in step 8.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11. Break the terminator on purpose.&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="nv"&gt;BAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close/r/n/r/n'&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%b'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BAD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | nc &lt;span class="nt"&gt;-w&lt;/span&gt; 5 example.com 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On &lt;code&gt;nmap-ncat&lt;/code&gt;, use &lt;code&gt;-i 5&lt;/code&gt; instead of &lt;code&gt;-w 5&lt;/code&gt; — its &lt;code&gt;-w&lt;/code&gt; times the connect only and will not close an idle socket.&lt;/p&gt;

&lt;p&gt;Expect: nothing — no status line, no error, no body. The flag closes the socket after five idle seconds. Press Ctrl+C to exit early.&lt;/p&gt;

&lt;p&gt;Silence is what you see inside that window. Drop the timeout and wait, and some servers eventually answer &lt;code&gt;408 Request Timeout&lt;/code&gt; — the same finding stated differently. The server never saw a complete request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12. Repeat with more headers.&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="nv"&gt;BAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'GET / HTTP/1.1\r\nHost: example.com\r\nUser-Agent: curl\r\nAccept: */*\r\nConnection: close/r/n/r/n'&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%b'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BAD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | nc &lt;span class="nt"&gt;-w&lt;/span&gt; 5 example.com 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same flag swap as step 11 on &lt;code&gt;nmap-ncat&lt;/code&gt;. Expect: identical silence. Four headers behave exactly like two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verification check
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%b'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REQ&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | nc example.com 80 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exactly one line prints: &lt;code&gt;HTTP/1.1 200 OK&lt;/code&gt;. Anything else means the request is malformed. If nothing prints, re-run step 3 — a success there means the port is open and the fault is in your request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No output — the command sits, then returns to the prompt.&lt;/strong&gt;&lt;br&gt;
Copy the command rather than retyping it. The terminator needs backslashes: &lt;code&gt;\r\n\r\n&lt;/code&gt;. &lt;code&gt;printf&lt;/code&gt; gives forward slashes no special meaning, so &lt;code&gt;/r/n/r/n&lt;/code&gt; lands inside the last header value as text and the terminator never gets sent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nothing happens and &lt;code&gt;echo "$REQ"&lt;/code&gt; prints an empty line.&lt;/strong&gt;&lt;br&gt;
Re-run step 4. Shell variables do not survive a new terminal window or tab.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11 or 12 hangs and never returns.&lt;/strong&gt;&lt;br&gt;
You are on &lt;code&gt;nmap-ncat&lt;/code&gt;, where &lt;code&gt;-w&lt;/code&gt; covers the connect only. Use &lt;code&gt;-i 5&lt;/code&gt;. Ctrl+C to break out of the current run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your netcat rejects &lt;code&gt;-z&lt;/code&gt; as an unknown option.&lt;/strong&gt;&lt;br&gt;
Not all builds include it. Use &lt;code&gt;nc -vw 5 example.com 80 &amp;lt; /dev/null&lt;/code&gt; instead. &lt;code&gt;-w&lt;/code&gt; is correct on every variant here, since this test only needs the connect to succeed or fail. The &lt;code&gt;-v&lt;/code&gt; prints the result — without it you get silence whether the port is open or closed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You expected &lt;code&gt;400 Bad Request&lt;/code&gt; and got silence.&lt;/strong&gt;&lt;br&gt;
Treat the hang as the normal symptom of a broken terminator, not a network fault. With no terminator, the server has nothing to reject — it is still listening.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Header values are not parsed as expected.&lt;/strong&gt;&lt;br&gt;
Put one space after every colon when you add your own headers. &lt;code&gt;Host:example.com&lt;/code&gt; is widely tolerated but not guaranteed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;One wrong character — &lt;code&gt;/&lt;/code&gt; for &lt;code&gt;\&lt;/code&gt; — is the difference between a page and total silence. HTTP is plain text over a socket, and it has no tolerance for text that is almost right.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Drafted and revised with Claude; every command tested by me.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>beginners</category>
      <category>networking</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Organizing Bug Bounty Notes in Obsidian: A Vault Structure for Beginners</title>
      <dc:creator>MuneebAhmedKhan-writing</dc:creator>
      <pubDate>Sun, 09 Aug 2026 19:25:25 +0000</pubDate>
      <link>https://dev.to/muneebahmedkhanwriting/organizing-bug-bounty-notes-in-obsidian-a-vault-structure-for-beginners-43fn</link>
      <guid>https://dev.to/muneebahmedkhanwriting/organizing-bug-bounty-notes-in-obsidian-a-vault-structure-for-beginners-43fn</guid>
      <description>&lt;p&gt;By the end of this guide, you will have a working Obsidian vault structured for bug bounty research, with a reusable target template you can drop into every new target note instead of rebuilding structure from scratch each time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Obsidian installed (any OS). No prior Obsidian experience required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Download Obsidian from obsidian.md and open it. The first screen gives you the option to create a new vault. Name it something dedicated to security research, such as security-notes, kept separate from your personal notes.&lt;/li&gt;
&lt;li&gt;Click the new folder icon in the left sidebar and create three folders: Targets, Methodology, and Templates.&lt;/li&gt;
&lt;li&gt;Create a note called Target Template inside Templates, and give it a reusable structure:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Scope&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; 

&lt;span class="gu"&gt;## Subdomains Found&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; 

&lt;span class="gu"&gt;## Endpoints Tested&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; 

&lt;span class="gu"&gt;## Findings&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; 

&lt;span class="gu"&gt;## Status&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Recon
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Testing
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Reporting
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Submitted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a new note inside Targets for an actual target. Type [[ and Obsidian auto-pairs it to [[]], placing your cursor in the middle. Type the note name, Target Template, and select it from the dropdown. This creates a link: [[Target Template]].&lt;/li&gt;
&lt;li&gt;Clicking that link navigates you away to the template note, which is not what you want for a reusable structure. Instead, use ![[Target Template]] to embed the full content directly into the new note.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Verification
&lt;/h2&gt;

&lt;p&gt;The new target note shows the full template content inline, including headings, checklist, and sections, without needing to open a separate note.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Typing [[ auto-pairs to [[]]. This is expected, not an error; your cursor sits ready in the middle.&lt;/li&gt;
&lt;li&gt;Clicking a [[link]] navigates away to the linked note, which is not what you want for a reusable template.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Fix
&lt;/h2&gt;

&lt;p&gt;Use ![[Target Template]], with the exclamation mark and no space, to embed the note instead of linking to it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Outlined and reviewed with Claude; written and tested by me.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cybersecurity</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Capturing Your First Web Request with Wireshark on Windows</title>
      <dc:creator>MuneebAhmedKhan-writing</dc:creator>
      <pubDate>Fri, 07 Aug 2026 03:08:24 +0000</pubDate>
      <link>https://dev.to/muneebahmedkhanwriting/capturing-your-first-web-request-with-wireshark-on-windows-3f43</link>
      <guid>https://dev.to/muneebahmedkhanwriting/capturing-your-first-web-request-with-wireshark-on-windows-3f43</guid>
      <description>&lt;p&gt;A live packet capture in Wireshark, filtered down to a single request and response, so you can see exactly what your browser sends and receives at the network level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Windows 11 Pro (64-bit), Wireshark installed, connected to Wi-Fi. No prior networking experience required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open Wireshark. You will see a list of interfaces (Wi-Fi, Ethernet, Loopback) with live traffic graphs.&lt;/li&gt;
&lt;li&gt;Double-click your Wi-Fi interface to start capturing.&lt;/li&gt;
&lt;li&gt;Open your browser and visit &lt;a href="http://example.com" rel="noopener noreferrer"&gt;http://example.com&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Return to Wireshark and click the red square to stop the capture.&lt;/li&gt;
&lt;li&gt;In the display filter bar, type http and press Enter to narrow the list to HTTP traffic.&lt;/li&gt;
&lt;li&gt;Find your GET request to example.com in the list, right-click it, and choose Conversation Filter → TCP to isolate just that exchange.&lt;/li&gt;
&lt;li&gt;Click on the GET request packet, then expand Hypertext Transfer Protocol in the details pane to see the request.&lt;/li&gt;
&lt;li&gt;Click on the matching 200 OK response packet to see the reply.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Verification
&lt;/h2&gt;

&lt;p&gt;The filtered list shows a short, self-contained exchange: a few TCP setup packets, one GET request, and one 200 OK response, instead of the full, unfiltered flood of background traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The unfiltered capture shows an overwhelming number of unrelated IP addresses moving constantly. This is normal background traffic (Windows Update, background apps), not something you did wrong. Filtering with http and Conversation Filter narrows it to what matters.&lt;/li&gt;
&lt;li&gt;The first HTTP packet you click on may not be your own browser traffic at all. Windows generates its own background HTTP traffic, such as update checks. Generate your own traffic deliberately by visiting a known site, rather than clicking the first packet you see.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Outlined and reviewed with Claude; written and tested by me.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>beginners</category>
      <category>networking</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Intercepting Your First Request with Burp Suite Community Edition on Windows</title>
      <dc:creator>MuneebAhmedKhan-writing</dc:creator>
      <pubDate>Thu, 06 Aug 2026 16:12:14 +0000</pubDate>
      <link>https://dev.to/muneebahmedkhanwriting/intercepting-your-first-request-with-burp-suite-community-edition-on-windows-fg0</link>
      <guid>https://dev.to/muneebahmedkhanwriting/intercepting-your-first-request-with-burp-suite-community-edition-on-windows-fg0</guid>
      <description>&lt;p&gt;By the end of this guide, you will have a working Burp Suite setup that intercepts, freezes, and forwards live web traffic. This is the foundational skill every web app security exercise afterward depends on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Windows 11 Pro (64 bit), Burp Suite Community Edition installed. No prior networking or proxy experience required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Launch Burp, choose Temporary Project, use Burp defaults, and click Start Burp.&lt;/li&gt;
&lt;li&gt;Confirm the proxy listener is active. Go to Proxy → Proxy Settings and check that 127.0.0.1:8080 is enabled.&lt;/li&gt;
&lt;li&gt;Open Burp's built in browser. Go to Proxy → Intercept → Open Browser. This avoids manual proxy and certificate setup entirely, which makes it the simplest starting point for a beginner.&lt;/li&gt;
&lt;li&gt;Turn Intercept on.&lt;/li&gt;
&lt;li&gt;Visit a test site, for example &lt;a href="http://example.com" rel="noopener noreferrer"&gt;http://example.com&lt;/a&gt;, and watch the request freeze in Burp.&lt;/li&gt;
&lt;li&gt;Forward the request in the Intercept tab and confirm the page loads.&lt;/li&gt;
&lt;li&gt;Check Proxy → HTTP History to see the logged request.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Verification
&lt;/h2&gt;

&lt;p&gt;The frozen raw HTTP request appears in the Intercept tab. After forwarding, the same request shows up in HTTP History with the full request and response detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;If the site does not freeze in Intercept, the most common cause is browser cache. If you have visited the site before in the same browser session, it may load from cache instead of sending a new network request. Fix this by disabling cache in DevTools (F12 → Network → Disable cache), doing a hard reload with Ctrl+Shift+R, or clearing browser history and cache.&lt;br&gt;
Intercept and Intruder are easy to confuse. Intercept, under the Proxy tab, freezes live traffic. Intruder is a separate tool for automated attacks and shows nothing unless you send a captured request to it manually.&lt;br&gt;
Testing against major sites like Google can trigger CAPTCHA or bot detection pages, since proxied traffic looks suspicious to sites with strong bot protection. Stick to neutral test domains like example.com while learning.&lt;/p&gt;

&lt;p&gt;Written while learning web application security. More tutorials from this journey coming soon.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Outlined and reviewed with Claude; written and tested by me.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>beginners</category>
      <category>burpsuite</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
