<?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>Forem: Dharmil Chhadva</title>
    <description>The latest articles on Forem by Dharmil Chhadva (@dharmil18).</description>
    <link>https://forem.com/dharmil18</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F433915%2Fd5ec73a3-27f0-4813-968e-b9fae5e76705.jpg</url>
      <title>Forem: Dharmil Chhadva</title>
      <link>https://forem.com/dharmil18</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dharmil18"/>
    <language>en</language>
    <item>
      <title>Docker Swarm vs Kubernetes</title>
      <dc:creator>Dharmil Chhadva</dc:creator>
      <pubDate>Sat, 30 Mar 2024 14:14:08 +0000</pubDate>
      <link>https://forem.com/dharmil18/docker-swarm-vs-kubernetes-576g</link>
      <guid>https://forem.com/dharmil18/docker-swarm-vs-kubernetes-576g</guid>
      <description>&lt;p&gt;Automating the deployment pipeline is becoming increasingly important in today's fast-evolving world, where applications are broken down into microservices. This is where Docker and Kubernetes come into play.&lt;/p&gt;

&lt;p&gt;Before we dive deep into Docker and Kubernetes, let's first understand what containers are.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are containers?
&lt;/h2&gt;

&lt;p&gt;A container packages the application code and its dependencies in one unit, which then can be executed on any infrastructure. It's lightweight and includes everything required to run the app, such as code, runtime environment, system libraries, and external dependencies. The core aim is to quickly deploy the application, which executes the same regardless of the underlying architecture.&lt;/p&gt;

&lt;p&gt;Containers eliminate the "works on my machine" 🤣 phrase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F796dxmxxszvkewe7ykqa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F796dxmxxszvkewe7ykqa.jpg" alt="Huge production bug, but developer says works on my machine" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Now that we understand containers let's move on to Docker Swarm.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Docker Swarm?
&lt;/h2&gt;

&lt;p&gt;Docker Swarm is a container orchestration tool that allows you to manage and deploy applications using containerization. It's an open -source and popular as it is quick to set up and easy to use. Docker Swarm is called &lt;code&gt;swarm mode&lt;/code&gt; and is a native Docker mode. &lt;code&gt;Swarm mode&lt;/code&gt; allows DevOps engineers to create a cluster of Docker nodes and deploy services to run on these nodes. This cluster is called Swarm.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;swarm&lt;/code&gt; cluster consists of manager nodes, which manage the cluster and worker nodes, which are instructed to run tasks by the manager nodes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Swarm Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0xo6rkw7gjd17d7h3q7w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0xo6rkw7gjd17d7h3q7w.jpg" alt="Swarm Architecture" width="650" height="468"&gt;&lt;/a&gt;&lt;br&gt;Image Credit: &lt;a href="https://betterstack.com/community/guides/scaling-docker/docker-swarm-kubernetes/"&gt;Docker Swarm vs Kubernetes: A Practical Comparison&lt;/a&gt;
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Pros of Docker Swarm:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Familiarity as &lt;code&gt;swarm mode&lt;/code&gt; is a part of Docker.&lt;/li&gt;
&lt;li&gt;Easy to install and set up.&lt;/li&gt;
&lt;li&gt;Has its own Swarm API.&lt;/li&gt;
&lt;li&gt;Smooth integration with Docker Compose and Docker CLI.&lt;/li&gt;
&lt;li&gt;Intelligent node selection for picking optimal nodes.&lt;/li&gt;
&lt;li&gt;Built-in load balancing feature, eliminating the need to define load balancer files manually.&lt;/li&gt;
&lt;li&gt;Roll back to the previous version of the service in case of hazardous events such as failures.&lt;/li&gt;
&lt;li&gt;Fault tolerance, wherein &lt;code&gt;swarm&lt;/code&gt; automatically checks for node failures and replaces them with new ones. &lt;/li&gt;
&lt;li&gt;It can scale up and down as per demand.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons of Docker Swarm:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Limited customizations and extensions.&lt;/li&gt;
&lt;li&gt;Less functionality and lesser automation capabilities compared to Kubernetes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Swarm mode CLI commands:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;swarm init&lt;/strong&gt;: Initialize a swarm. The Docker Engine this command targets becomes a manager in the newly created single-node Swarm.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; docker swarm init --advertise-addr 192.168.99.121

Swarm initialized: current node (bvz81updecsj6wjz393c09vti) is now a manager.

To add a worker to this Swarm, run the following command:

    docker swarm join --token SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx 172.17.0.2:2377

To add a manager to this Swarm, run 'docker swarm join-token manager' and follow the instructions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Swarm join&lt;/strong&gt;: Join a node to a swarm. The node joins as a manager node or worker node based on the token you pass with the --token flag. If you pass a manager token, the node joins as a manager. If you pass a worker token, the node joins as a worker.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; docker swarm join --token SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2 192.168.99.121:2377
This node joined a swarm as a manager.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Find more Swarm CLI at &lt;a href="https://docs.docker.com/engine/swarm/#whats-next"&gt; Docker Docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What is Kubernetes?
&lt;/h2&gt;

&lt;p&gt;Kubernetes is also a container orchestration tool which allows you to deploy and manage applications. It's open-source, portable, and highly configurable. These features make it an optimal choice for deploying complex applications. A cluster in Kubernetes consists of &lt;strong&gt;worker nodes&lt;/strong&gt;, which are managed by Kubernetes &lt;strong&gt;master&lt;/strong&gt;. The &lt;strong&gt;master&lt;/strong&gt; controls, monitors and manages all the resources in the cluster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kubernetes Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gqa4t0sc67575rkzv3c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gqa4t0sc67575rkzv3c.jpg" alt="Swarm Architecture" width="455" height="650"&gt;&lt;/a&gt;&lt;br&gt;Image Credit: &lt;a href="https://betterstack.com/community/guides/scaling-docker/docker-swarm-kubernetes/"&gt;Docker Swarm vs Kubernetes: A Practical Comparison&lt;/a&gt;
  &lt;/p&gt;

&lt;p&gt;The above diagram depicts the components involved in Kubernetes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Controller Plane:&lt;/strong&gt; It manages the operation of the Kubernetes cluster.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kube API Server:&lt;/strong&gt; Facilitates external communication with the cluster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Etcd:&lt;/strong&gt; Stores configuration data and cluster state in a key-value store.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduler:&lt;/strong&gt; Allocates pod placement based on resource needs and availability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kube Controller Manager:&lt;/strong&gt; Maintains desired component states.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes Node:&lt;/strong&gt; Executes control plane assigned tasks, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kubelet:&lt;/strong&gt; Manages containers and their lifecycle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pod:&lt;/strong&gt; Smallest component of the cluster. Represents a running process instance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Execution Workflow:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;External clients interact with the cluster via &lt;code&gt;kubectl&lt;/code&gt; commands.&lt;/li&gt;
&lt;li&gt;The controller plane delegates tasks to Kubernetes nodes.&lt;/li&gt;
&lt;li&gt;Nodes create pods for container execution.&lt;/li&gt;
&lt;li&gt;External users access deployed apps through a load balancer.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Pros of Kubernetes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Wide range of functionalities such as service discovery, load balancing, storage orchestration, self-healing, horizontal scalability, automated rollout and rollbacks and batch execution.&lt;/li&gt;
&lt;li&gt;Open-source with a highly active community.&lt;/li&gt;
&lt;li&gt;Allows you to store and manage configuration data and secrets securely.&lt;/li&gt;
&lt;li&gt;Allows flexible management of resources when deploying an application.&lt;/li&gt;
&lt;li&gt;Is highly extensible through plugins.&lt;/li&gt;
&lt;li&gt;Interact with Kubernetes components via its API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons of Kubernetes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Learning Kubernetes and managing its master requires specialized knowledge due to its steep learning curve.&lt;/li&gt;
&lt;li&gt;Frequent updates from the open-source community need careful patching to prevent workload disruptions.&lt;/li&gt;
&lt;li&gt;Kubernetes is too heavy for solo developers who are handling simple apps with occasional deployments.&lt;/li&gt;
&lt;li&gt;Teams require tools like kubectl CLI, CI/CD workflows, and DevOps practices to manage access, identity, governance, and security.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Docker Swarm Vs Kubernetes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Feature&lt;/th&gt;
      &lt;th&gt;Docker Swarm&lt;/th&gt;
      &lt;th&gt;Kubernetes&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Set up&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Easy with &lt;b&gt;docker&lt;/b&gt; command&lt;/td&gt;
      &lt;td&gt;Setting up a Kubernetes cluster manually can be complicated.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Container support&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Works only with Docker containers&lt;/td&gt;
      &lt;td&gt;Works with &lt;b&gt;containerd&lt;/b&gt;, &lt;b&gt;Docker&lt;/b&gt;, etc. &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Networking&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Basic&lt;/td&gt;
      &lt;td&gt;Advanced&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Learning Curve&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Easy to get started&lt;/td&gt;
      &lt;td&gt;Steep curve&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Complexity&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Simple &amp;amp; lightweight&lt;/td&gt;
      &lt;td&gt;Complicated &amp;amp; heavyweight&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Load Balancing&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Automatic&lt;/td&gt;
      &lt;td&gt;Manual&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;CLIs&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Comes when installing Docker&lt;/td&gt;
      &lt;td&gt;Need to install &lt;b&gt;kubectl&lt;/b&gt; CLI&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Scalability&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;No automatic scaling&lt;/td&gt;
      &lt;td&gt;Automatic Scaling&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Security&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Only TLS support&lt;/td&gt;
      &lt;td&gt;Supports SSL/TLS, RBAC &amp;amp; secret management&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, while Docker Swarm and Kubernetes serve as container orchestration tools, they have distinct characteristics and functionalities.&lt;/p&gt;

&lt;p&gt;Docker &lt;code&gt;swarm&lt;/code&gt; offers easy setup and simplicity, making it ideal for smaller projects with straightforward deployment needs. However, it lacks the advanced features and scalability of Kubernetes.&lt;/p&gt;

&lt;p&gt;On the other hand, &lt;strong&gt;Kubernetes&lt;/strong&gt; provides a comprehensive set of features for managing complex applications at scale. Although it has a steep learning curve and requires specialized knowledge, Kubernetes offers extensive functionality, including advanced networking, automated scaling, and robust security features.&lt;/p&gt;

&lt;p&gt;Ultimately, the choice between Docker Swarm and Kubernetes depends on the specific requirements and complexity of the project. Docker Swarm may suffice for simpler deployments, while Kubernetes is better suited for larger, more intricate applications that demand advanced orchestration capabilities.&lt;/p&gt;




&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.ibm.com/blog/docker-swarm-vs-kubernetes-a-comparison/"&gt;Docker Swarm vs. Kubernetes: A Comparison&lt;/a&gt;&lt;br&gt;
&lt;a href="https://betterstack.com/community/guides/scaling-docker/docker-swarm-kubernetes/"&gt;Docker Swarm vs Kubernetes: A Practical Comparison&lt;/a&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Note: This article is a part of the curriculum in the DevOps course. My student ID is C0884179.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Check Out My Previous Articles
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dev.to/dharmil18/changing-the-mac-address-using-python-564j"&gt;Changing the MAC Address using Python&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/dharmil18/writing-a-network-scanner-using-python-3b80"&gt;Writing a Network Scanner using Python&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/dharmil18/man-in-the-middle-attack-mitm-part-1-arp-spoofing-3747"&gt;Man In The Middle Attack (MITM) Part 1 — ARP Spoofing&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/dharmil18/man-in-the-middle-attack-mitm-part-2-packet-sniffer-1nch"&gt;Man In The Middle Attack (MITM) Part 2 — Packet Sniffer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>kubernetes</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Man In The Middle Attack (MITM) Part 2 — Packet Sniffer</title>
      <dc:creator>Dharmil Chhadva</dc:creator>
      <pubDate>Tue, 27 Feb 2024 01:08:19 +0000</pubDate>
      <link>https://forem.com/dharmil18/man-in-the-middle-attack-mitm-part-2-packet-sniffer-1nch</link>
      <guid>https://forem.com/dharmil18/man-in-the-middle-attack-mitm-part-2-packet-sniffer-1nch</guid>
      <description>&lt;p&gt;Building a packet sniffer using Python 🐍 that extracts visited URLs and user credentials.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is part 2 of Man In The Middle (MITM) attack. If you haven’t read part 1 then I strongly suggest you read that before reading part 2. You can find the link to Part 1 in the next section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is a Packet Sniffer?
&lt;/h2&gt;

&lt;p&gt;A packet sniffer is a tool that is used to monitor networks and to diagnose any network problems. It is commonly used by network technicians. Hackers often use this to spy on user’s network traffic and for extracting passwords.&lt;/p&gt;

&lt;p&gt;Packet sniffers log network traffic on a network &lt;strong&gt;interface&lt;/strong&gt; that they have access to. It can see every &lt;a href="https://computer.howstuffworks.com/question525.htm#pt0" rel="noopener noreferrer"&gt;packet&lt;/a&gt; that flows to and from an interface.&lt;/p&gt;

&lt;p&gt;You’d be wondering that we are designing a packet sniffer but the title says Man In The Middle Attack. This is because in &lt;a href="https://levelup.gitconnected.com/man-in-the-middle-attack-part-1-arp-spoofing-6f5b174dec59" rel="noopener noreferrer"&gt;Part 1&lt;/a&gt; we wrote a Python script (ARP Spoofing) that allows us to become a Man In The Middle. The purpose of the packet sniffer is to capture the victim’s (the user which has been attacked using ARP Spoofing) network traffic and extract visited URLs and credentials.&lt;br&gt;
&lt;a href="https://levelup.gitconnected.com/man-in-the-middle-attack-part-1-arp-spoofing-6f5b174dec59" rel="noopener noreferrer"&gt;&lt;strong&gt;Man In The Middle Attack (MITM) Part 1 — ARP Spoofing&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Modules Used:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.python.org/3.4/library/subprocess.html" rel="noopener noreferrer"&gt;argparse&lt;/a&gt;: To understand what this does read my first article &lt;a href="https://medium.com/@dharmilch18/changing-mac-address-using-python-8a16fc4a3563" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://scapy.readthedocs.io/en/latest/extending.html" rel="noopener noreferrer"&gt;Scapy&lt;/a&gt;: Enables the user to send, sniff and dissect and forge network packets. This capability allows the development of tools that can probe, scan, or attack networks. It can forge or decode packets of a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more. It easily handles most tasks like scanning, tracerouting, probing, unit tests, attacks, or network discovery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.python.org/3/library/time.html" rel="noopener noreferrer"&gt;time&lt;/a&gt;: We only use the time module to generate a delay of 2 seconds. To learn more about this module read the docs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  What functionality the Python 🐍 script must have?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;get_args() — A function to get command-line arguments. In this case, we need an input value from the user for the **interface **on which we want to sniff the packets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;sniffer(interface) — A function that takes the **interface **value as an input and sniffs the packets on that interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;process_packet(packet) — A function that is called by the sniffer function for every new packet that is sniffed. This checks whether the packet is of type HTTP Request or not. For this use case, we only need the packets which are of the HTTP Request type because the information we want is sent in this packet. It then uses get_url(packet) and get_credentials(packet) functions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_url(packet) — A function that extracts the URL from the packet that was passed to it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_credentials(packet) — A function that also takes packet as input and extracts credentials such as username and password.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without further ado, let’s start writing the script in Python.&lt;/p&gt;
&lt;h2&gt;
  
  
  Python Script for Packet Sniffer
&lt;/h2&gt;

&lt;p&gt;In this section, we’ll build the script step by step. I’ll explain everything in each step, so read carefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Importing Necessary Modules&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
&lt;strong&gt;Step 2: Writing the **get_args() **function&lt;/strong&gt;&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The above function adds functionality which allows the user to pass user input values as the command-line arguments. After the addition of the above code, the user will be able to pass the name of the interface on which the packets are supposed to be sniffed in the same instruction that is used to run the script. For example,
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~# python3 sniffer.py -i interface_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;OR&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~# python3 sniffer.py --interface interface_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;To learn how exactly this function works, read the entire &lt;strong&gt;Step 2&lt;/strong&gt; from the article on how to &lt;a href="https://medium.com/@dharmilch18/changing-mac-address-using-python-8a16fc4a3563" rel="noopener noreferrer"&gt;change MAC Address of a device&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Writing the **sniffer(interface) **function&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The above gist contains the definition of the sniffer(interface) function. It takes an &lt;strong&gt;interface&lt;/strong&gt; name as an input that is used inside it. It uses a method called sniff provided by the scapy module. The methodsniff requires an interface name iface as an input. The next argument, store tells scapy whether to store the packets in memory or not. store = False tells scapy not to store the packets. The last argument is prn, it tells scapy which function to be called each time a new packet is sniffed. In this case, process_packet function is called for every new packet.

&lt;p&gt;&lt;strong&gt;Step 4: Writing the&lt;/strong&gt; process_packet(packet) &lt;strong&gt;function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before jumping into the function, let’s take a look at how a scapy packet looks like.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;###[ Ethernet ]###
dst       = 52:54:00:12:35:00
src       = 08:00:27:35:21:2e
type      = IPv4
###[ IP ]###
version   = 4
ihl       = 5
tos       = 0x0
len       = 441
id        = 22651
flags     = DF
frag      = 0
ttl       = 64
proto     = tcp
chksum    = 0xf1f9
src       = 10.0.2.9
dst       = 176.28.50.165
\options   \
###[ TCP ]###
sport     = 48556
dport     = http
seq       = 790303956
ack       = 327206
dataofs   = 5
reserved  = 0
flags     = PA
window    = 64240
chksum    = 0xf075
urgptr    = 0
options   = []
###[ HTTP 1 ]###
###[ HTTP Request ]###
Method    = 'GET'
Path      = '/login.php'
Http_Version= 'HTTP/1.1'
A_IM      = None
Accept    = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
Accept_Charset= None
Accept_Datetime= None
Accept_Encoding= 'gzip, deflate'
Accept_Language= 'en-US,en;q=0.5'
Access_Control_Request_Headers= None
Access_Control_Request_Method= None
Authorization= None
Cache_Control= 'max-age=0'
Connection= 'keep-alive'
Content_Length= None
Content_MD5= None
Content_Type= None
Cookie    = None
DNT       = None
Date      = None
Expect    = None
Forwarded = None
From      = Non
Front_End_Https= None
HTTP2_Settings= None
Host      = 'testphp.vulnweb.com'
If_Match  = None
If_Modified_Since= None
If_None_Match= None
If_Range  = None
If_Unmodified_Since= None
Keep_Alive= None
Max_Forwards= None
Origin    = None
Permanent = None
Pragma    = None
Proxy_Authorization= None
Proxy_Connection= None
Range     = None
Referer   = '[http://testphp.vulnweb.com/login.php](http://testphp.vulnweb.com/login.php')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above block shows the contents of the packet. The line that starts with ###[text]### is called a layer. The lines after that are the fields that come under that layer until the next layer is encountered. For instance, from the above block, ###[ Ethernet ]### is a layer and the following lines are the fields under the Ethernet. These fields contain information about Ethernet. Similarly, ###[ TCP ]###, ###[ HTTP Request ]###, etc. are layer. Now, let's jump to the &lt;strong&gt;process_packet&lt;/strong&gt; function.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
This function needs the sniffed packet as an input. In this function, we are first checking if the packet has a HTTP Request layer. This is done by using a method provided by scapy called haslayer(). If the packet does not has the layer then it is not processed.

&lt;p&gt;If it has the HTTP Request layer then, we perform two operations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Call get_url(packet) function to extract URL from the packet. It takes the packet as an input. This function returns a URL, we store this is in a variable called url and then we print the value of url.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then we call another function called get_credentials(packet). It also takes packet as an input. It checks the packet for possible credentials and if found any then it returns those credentials. We store it in a variable named cred and then we print its value.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’ll explain get_url(packet) and get_credentials(packet) functions in the later steps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Writing the&lt;/strong&gt; get_url(packet) &lt;strong&gt;function&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The get_url(packet) function also needs a packet as an input to extract the URL within the packet. The function extracts the contents of theHost and Path subfields of the HTTPRequest layer of the packet. We then join both the parts and return the URL extracted from the packet. The following is an example of the contents present in Host and Path subfields.
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Path      = '/login.php'
Host      = 'testphp.vulnweb.com'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The code packet[http.HTTPRequest] allows us to access the layers and is possible because of Scapy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Writing the **get_credentials(packet) **function&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
In the above code, you can see a Python tuple named keywords . Before understanding why it is required let's understand the function itself.

&lt;p&gt;This function also needs a packet to work with. Now, when we looked at the contents of the packet at the beginning of step 4, there was no such layer called Raw . This layer is crucial for what we are trying to achieve because the additional information such as credentials is added to the Raw layer. The below code block shows the Raw layer. It also shows that the credentials are stored inside a subfield called load.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;###[ Raw ]###
load = 'uname=hdhd&amp;amp;pass=hshs'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Now back to the function. At first, the function checks whether the packet has the Raw layer. If the packet has the layer, then it extracts the value of the load subfield and stores it in a variable called &lt;strong&gt;field_load&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The next step is using a for loop to loop over the tuple we discussed earlier. The tuple contains the keywords that are potential names of the form fields used at the time of making an HTML Form. These keywords are derived by guessing common names given to HTML Form elements that are used to design HTML Signup and Login forms.&lt;/p&gt;

&lt;p&gt;The for loop loops over each element in the tuple and checks whether any of the keywords is present the &lt;strong&gt;field_load **variable. If anyone keyword matched then the **field_load&lt;/strong&gt; is returned to the process_packet(packet) function to display potential credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Final Step&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, all that's left to do is call get_args() and sniffer(interface) function.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
With this, we complete the entire script and all that's left to do is test it.
&lt;h2&gt;
  
  
  Entire Script
&lt;/h2&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Working Demo
&lt;/h2&gt;

&lt;p&gt;Okay, before jumping to writing the code in Python I’ll tell you about the setup that I have: I am currently on Windows 10 and I have &lt;a href="https://www.virtualbox.org/" rel="noopener noreferrer"&gt;Virtualbox &lt;/a&gt;running with two VMs (1. Kali Linux and 2. Windows 10). I will execute the python script that we made in Part 1 — ARP Spoofing on my Kali Linux machine and attack my Windows 10 VM to become Man In The Middle. Then, I’ll execute the packet sniffer script from this part on my Kali Linux Machine. After that, I’ll log in to a website and see whether the sniffer script is able to extract the credentials or not.&lt;/p&gt;

&lt;p&gt;Note: The VMs are configured to use &lt;strong&gt;NatNetwork&lt;/strong&gt; in Virtualbox. When the VMs are set to use **NatNetwork, **the VMs thinks the host as the router (access point). To know more about NatNetwork and how to configure a VM to use it, read &lt;a href="https://www.techrepublic.com/article/how-to-create-multiple-nat-networks-in-virtualbox/" rel="noopener noreferrer"&gt;this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note: The packet sniffer only works on websites using the HTTP protocol. It does not work with HTTPS. To test, use this website — &lt;a href="http://testphp.vulnweb.com/login.php" rel="noopener noreferrer"&gt;Test Vuln Login&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kali Linux Machine
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IP Address = &lt;strong&gt;10.0.2.9&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAC Address = &lt;strong&gt;08:00:27:35:21:2e&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Windows 10
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IP Address = &lt;strong&gt;10.0.2.15&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAC Address = &lt;strong&gt;08:00:27:e6:e5:59&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Access Point or Default Gateway
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IP Address = &lt;strong&gt;10.0.2.1&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAC Address = &lt;strong&gt;52:54:00:12:35:00&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AMhXoV7VA7Q2Xu5CvbEnkvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AMhXoV7VA7Q2Xu5CvbEnkvw.png" alt="**Becoming Man In The Middle using ARP Spoofing**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ADJ9TmYiF-82G3fu2WR4FUA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ADJ9TmYiF-82G3fu2WR4FUA.png" alt="**Proof that we are the MITM**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MITM — Man In The Middle&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AOyWMAQm_Q21HX-wwZfcUbQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AOyWMAQm_Q21HX-wwZfcUbQ.png" alt="**Executing Packet Sniffer Script**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A9UVcQytOQvBuZauigh8jFg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A9UVcQytOQvBuZauigh8jFg.png" alt="**Testing Form**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A5UcVFqtMFSVFeAGufbW8mA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A5UcVFqtMFSVFeAGufbW8mA.png" alt="**Testing Form with credentials**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2628%2F1%2A0Exhwo9fgveHL1hJG8zS-w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2628%2F1%2A0Exhwo9fgveHL1hJG8zS-w.png" alt="**Extracted URLs**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2702%2F1%2AruKdfc3R8sd-6XtMbtTIvA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2702%2F1%2AruKdfc3R8sd-6XtMbtTIvA.png" alt="**Extracted Credentials**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above image, you can see that we have extracted the captured username and password from the packet that was sniffed. In the testing form, we entered username = test_user and password = test_user123 and in the above image, you can see that we are getting the same username and password value in the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We successfully wrote a Python 🐍 script to capture packets. We also tested it with Man In The Middle Attack — ARP Spoofing. The script works perfectly as we wanted it to.&lt;/p&gt;

&lt;p&gt;You can find the entire script on my &lt;a href="https://github.com/dharmil18/Packet-Sniffer" rel="noopener noreferrer"&gt;Github Repository&lt;/a&gt;. Thank You 😃 for reading.&lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>tutorial</category>
      <category>security</category>
    </item>
    <item>
      <title>Man In The Middle Attack (MITM) Part 1 — ARP Spoofing</title>
      <dc:creator>Dharmil Chhadva</dc:creator>
      <pubDate>Tue, 27 Feb 2024 01:04:12 +0000</pubDate>
      <link>https://forem.com/dharmil18/man-in-the-middle-attack-mitm-part-1-arp-spoofing-3747</link>
      <guid>https://forem.com/dharmil18/man-in-the-middle-attack-mitm-part-1-arp-spoofing-3747</guid>
      <description>&lt;h2&gt;
  
  
  What is Address Resolution Protocol (ARP)?
&lt;/h2&gt;

&lt;p&gt;In a network, computers use the &lt;strong&gt;IP Address&lt;/strong&gt; to communicate with other devices, however, in reality, the communication happens over the &lt;strong&gt;MAC Address. ARP is used to find out the MAC Address of a particular device whose IP address is known.&lt;/strong&gt; For instance, a device wants to communicate with the other device on the network, then the sending device uses ARP to find the MAC Address of the device that it wants to communicate with. ARP involves two steps to find the MAC address:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The sending device sends an &lt;strong&gt;ARP Request&lt;/strong&gt; containing the IP Address of the device it wants to communicate with. This request is broadcasted meaning every device in the network will receive this but only the device with the intended IP address will respond.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After receiving the broadcast message, the device with the IP address equal to the IP address in the message will send an &lt;strong&gt;ARP Response&lt;/strong&gt; containing its MAC Adress to the sender.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If it is still not clear what ARP is and how it works then refer to the images below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4634%2F1%2Amda_kqjm4ONDM7jQnKZ7TQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4634%2F1%2Amda_kqjm4ONDM7jQnKZ7TQ.jpeg" alt="**Fig 1. ARP Request**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4954%2F1%2ALTdIvgRjXx9XewTRZVeAyg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4954%2F1%2ALTdIvgRjXx9XewTRZVeAyg.jpeg" alt="**Fig 2. ARP Response**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ARP Spoofing?
&lt;/h2&gt;

&lt;p&gt;ARP spoofing is a &lt;strong&gt;Man In The Middle (MITM)&lt;/strong&gt; attack in which the attacker (hacker) sends forged ARP Messages. This allows the attacker to pretend as a legitimate user as it links the attacker machine’s MAC Address to the legitimate IP Address. Once the MAC Address has been linked the attacker will now receive the messages intended for the legitimate IP Address. Furthermore, ARP Spoofing allows the attacker can intercept, modify, and drop the incoming messages.&lt;/p&gt;

&lt;p&gt;ARP Spoofing is only possible on 32-bit IP Addresses (IPv4) and not on IPv6.However, it is widely used because most of the internet still works on IPv4.&lt;/p&gt;

&lt;p&gt;Let’s understand ARP Spoofing more clearly with the help of diagrams 😃.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4520%2F1%2A4WJ1yUmr9tOEW5S6mzraQQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4520%2F1%2A4WJ1yUmr9tOEW5S6mzraQQ.jpeg" alt="**Fig 3. Normal Network**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fig 3. demonstrates the working of a normal network (no malicious activity) and how a device (hacker or victim) access the Internet with the help of an access point. All the messages pass through the access point. For instance, a device (hacker or victim) sends requests to access the resources on the Internet and in turn, receives responses. These &lt;strong&gt;requests **and **responses **always pass through the access point and therefore the access point is called the **Gateway&lt;/strong&gt; to the Internet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: In this article, the words &lt;strong&gt;“Gateway”&lt;/strong&gt;, &lt;strong&gt;“Access Point”, “Router”&lt;/strong&gt; and &lt;strong&gt;“Default Gateway” *&lt;em&gt;are used interchangeably. Also the words *&lt;/em&gt;“attacker”&lt;/strong&gt; and &lt;strong&gt;“hacker” *&lt;em&gt;are used similarly. The words *&lt;/em&gt;“target”&lt;/strong&gt; and &lt;strong&gt;“victim”&lt;/strong&gt; means the same.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4800%2F1%2ANz1e4AfW6HGcgXde_eIwUg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4800%2F1%2ANz1e4AfW6HGcgXde_eIwUg.jpeg" alt="**Fig 4. Overview of ARP Spoofing**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fig 4. illustrates how the ARP Spoofing affects the normal flow of &lt;strong&gt;requests&lt;/strong&gt; and &lt;strong&gt;responses **in a network. In ARP Spoofing, the hacker simply fools the **access point&lt;/strong&gt; and the &lt;strong&gt;victim **by pretending as the **access point&lt;/strong&gt; in front of the &lt;strong&gt;victim&lt;/strong&gt; and as the &lt;strong&gt;victim&lt;/strong&gt; in front of the &lt;strong&gt;access point&lt;/strong&gt;. Now, let’s see how the hacker manages to pretend and fool the access point and the victim.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5520%2F1%2AmgmPwYZR7cw0NaIHSO2YtA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5520%2F1%2AmgmPwYZR7cw0NaIHSO2YtA.jpeg" alt="**Fig 5. ARP Spoofing**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the help of Fig 5. we can understand how the attacker is able to fool both the access point as well as the victim. The figure shows the IP Address and MAC Address of every device present in the network. To understand how ARP Spoofing works you must completely understand the figure first. In order to carry out ARP spoofing the attacker/hacker sends an ARP Response to the access point and the victim.&lt;/p&gt;

&lt;p&gt;Before we dive deeper into Fig 5., let’s first understand ARP Response and what different fields it contains. We already covered what ARP Response is and when it is used. Now, let’s take a look inside an ARP Response to understand what kind of information it holds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A0-kCRo73fZ333N_i6rTTNA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A0-kCRo73fZ333N_i6rTTNA.png" alt="**Fig 6. ARP Response Example**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fig 6. displays an ARP Response packet captured in &lt;a href="https://www.wireshark.org/" rel="noopener noreferrer"&gt;Wireshark&lt;/a&gt;. There are several fields inside of it using which it communicates with other devices in the network. Out of all the fields, the most important ones for us are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Opcode — When its value is **2 **it means its an ARP Response and when it is **1 **it means its an ARP Request. In the figure above the value of Opcode is **2 **which means its an ARP Response.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sender MAC Address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sender IP Address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target MAC Address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target IP Address&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, to pretend as the victim in front of the Access Point, the attacker/hacker uses ARP Response to its advantage. The attacker sends an ARP Response message to the Access Point with the following information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Opcode = &lt;strong&gt;2&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sender MAC Address = *&lt;em&gt;08:00:11:1a:25:ff *&lt;/em&gt;(Attacker’s MAC Address)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sender IP Address = &lt;strong&gt;10.0.2.15&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target MAC Address = &lt;strong&gt;08:22:55:2a:ab:35&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target IP Address = &lt;strong&gt;10.0.2.1&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This shows that the attacker is forging an ARP Response message by setting the &lt;strong&gt;victim’s IP Address as the Sender’s IP Address&lt;/strong&gt;. This &lt;strong&gt;fools the access point in thinking that the ARP Response was sent by the victim (a legitimate device), however, in reality, it was sent by the attacker.&lt;/strong&gt; The attacker also &lt;strong&gt;sets its own machine’s MAC Address&lt;/strong&gt; &lt;strong&gt;as the Sender MAC Address&lt;/strong&gt;. Due to this, the access point updates the MAC Address of the IP Address &lt;strong&gt;10.0.2.15&lt;/strong&gt; to the MAC Address of the attacker in its ARP table and therefore linking the attacker’s machine with a legitimate IP Address. With this, any message intended for *&lt;em&gt;10.0.2.15 **will now be sent to the attacker’s machine. This is what *&lt;/em&gt;“10.0.2.15 is at 08:00:11:1a:25:ff” **means in Figure 5.&lt;/p&gt;

&lt;p&gt;Read about ARP Table &lt;a href="https://www.javatpoint.com/arp-table" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Similarly, to pretend as the Access Point in front of the victim, the attacker again uses ARP Response and sends it to the victim machine using the following information in it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Opcode = 2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sender MAC Address = *&lt;em&gt;08:00:11:1a:25:ff *&lt;/em&gt;(Attacker’s MAC Address)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sender IP Address = &lt;strong&gt;10.0.2.1&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target MAC Address = &lt;strong&gt;00:22:11:55:33:aa&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target IP Address = &lt;strong&gt;10.0.2.15&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ARP Response is received by the victim and thinks that this was sent by the Access point, and thus, updates the MAC Address of the access point’s IP Address with the attacker’s MAC Address in its ARP table. This fools the victim and the attacker successfully pretends to be the access point. This means that any message intended for the access point is now being sent to the attacker.&lt;/p&gt;

&lt;p&gt;Now, as the only way to access the resources on the internet is through the Access Point itself, the victim’s requests now pass through the attacker’s machine instead of the actual access point. This gives a chance to the attacker to intercept, modify, or stop the data transit. The attacker can also relay the requests and responses to and from the victim and the access point without any changes.&lt;/p&gt;

&lt;p&gt;After this, the communication between the victim and the access point happens through the attacker’s machine just as it is shown in Figure 4.&lt;/p&gt;

&lt;p&gt;At this moment, I assume that you have understood how ARP Spoofing is carried out, so let’s jump on to the coding part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is ARP Spoofing possible?
&lt;/h2&gt;

&lt;p&gt;ARP was designed for security. There are two reasons why ARP spoofing is possible.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The machines in a network accept ARP Responses even if they haven’t sent an ARP Request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The machines trust these ARP Responses without any verification.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Modules Used:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.python.org/3.4/library/subprocess.html" rel="noopener noreferrer"&gt;argparse&lt;/a&gt;: To understand what this does read my first article &lt;a href="https://medium.com/@dharmilch18/changing-mac-address-using-python-8a16fc4a3563" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://scapy.readthedocs.io/en/latest/extending.html" rel="noopener noreferrer"&gt;Scapy&lt;/a&gt;: Enables the user to send, sniff and dissect and forge network packets. This capability allows the development of tools that can probe, scan, or attack networks. It can forge or decode packets of a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more. It easily handles most tasks like scanning, tracerouting, probing, unit tests, attacks, or network discovery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.python.org/3/library/time.html" rel="noopener noreferrer"&gt;time&lt;/a&gt;: We only use the time module to generate a delay of 2 seconds. To learn more about this module read the docs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Okay, before jumping to writing the code in Python I’ll tell you about the setup that I have: I am currently on Windows 10 and I have &lt;a href="https://www.virtualbox.org/" rel="noopener noreferrer"&gt;Virtualbox &lt;/a&gt;running with two VMs (1. Kali Linux and 2. Windows 10). I will execute the python script on my Kali Linux machine and try to attack my Windows 10 VM. Note: The VMs are configured to use **NatNetwork **in Virtualbox. When the VMs are set to use **NatNetwork, **the VMs thinks the host as the router (access point). To know more about NatNetwork and how to configure a VM to use it, read &lt;a href="https://www.techrepublic.com/article/how-to-create-multiple-nat-networks-in-virtualbox/" rel="noopener noreferrer"&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Python Script for ARP Spoofing
&lt;/h2&gt;

&lt;p&gt;In this section, we’ll build the entire script from scratch that will enable us to carry out an ARP spoofing attack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Import the modules discussed above.
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Step 2: Implementing the functionality to allow the users to pass command line arguments.
&lt;/h3&gt;

&lt;p&gt;To add this feature to our script, we’ll need to make use of the &lt;strong&gt;argparse&lt;/strong&gt; module that we imported in Step 1. The script needs the IP Address of the victim(target) as well as the access point(gateway).&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
To know more about how argparse works and what does the above part of the script does and what functionality it adds to the script, read the entire &lt;strong&gt;Step 2&lt;/strong&gt; from my previous article on how to &lt;a href="https://medium.com/@dharmilch18/changing-mac-address-using-python-8a16fc4a3563" rel="noopener noreferrer"&gt;change MAC Address of a device&lt;/a&gt;

&lt;p&gt;The above code allows the user to provide the input values for &lt;strong&gt;target&lt;/strong&gt; and &lt;strong&gt;gateway&lt;/strong&gt; IP Address to be used in the script and it does this as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~# python3 arp_spoofer.py -t target_ip -g gateway_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;OR&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~# python3 arp_spoofer.py --target target_ip --gateway gateway_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;target_ip = IP Address of the victim (target). In our example above, it’s &lt;strong&gt;10.0.2.15&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;gateway_ip = IP Address of the access point (gateway). In our example above, it’s &lt;strong&gt;10.0.2.1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These values of &lt;strong&gt;target_ip&lt;/strong&gt; and &lt;strong&gt;gateway_ip&lt;/strong&gt; are used by another function that fools the victim and the access point. We’ll discuss that function in the later steps.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3: Writing a function to get the current MAC Address
&lt;/h3&gt;

&lt;p&gt;This function takes the IP Address as an input and returns its MAC Address. We need this function to get the MAC Address of the victim and the access point.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
Still, now we are not using this function anywhere in our code but we’ll use it inside another function that fools both the victim and the access point. To know technical details about the &lt;strong&gt;get_mac(IP) **function, read the entire step 3 of this &lt;a href="https://medium.com/@dharmilch18/writing-a-network-scanner-using-python-a41273baf1e2#29e2" rel="noopener noreferrer"&gt;article&lt;/a&gt;. The only difference is that the function name in the linked article is **scan(ip) **instead of **get_mac(ip).&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Writing the spoof function that fools both the access point and the victim.
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Now, there’s a lot going on in this function so let’s break it down line by line so that we understand it completely.

&lt;p&gt;The **spoof(target_ip, spoof_ip) **accepts two IP Addresses as an input, the **target_ip **is the IP Address of the machine that we want to fool and the **spoof_ip **is the IP Address of the machine whose IP Address we’ll use to fool the other (target) machine.&lt;/p&gt;

&lt;p&gt;The first line, inside the &lt;strong&gt;spoof(target_ip, spoof_ip) **function definition, is where we make use of the **get_mac(ip)&lt;/strong&gt; function that we wrote in step 3.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;target_mac = get_mac(target_ip)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This returns the MAC Address of the target_ip and stores it inside the &lt;strong&gt;target_mac&lt;/strong&gt; variable.&lt;/p&gt;

&lt;p&gt;In the next line, we create an ARP Response packet using scapy’s ARP class. We achieve this using the following line of code.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spoof_packet = scapy.ARP(op = 2, pdst = target_ip, hwdst = target_mac, psrc = spoof_ip)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above line of code creates an ARP Response with the field values as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Opcode (op) = 2 — which means its an ARP Response. We’ve already covered this above.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Destination IP Address (pdst) — Target’s IP Address is set to **target_ip **that the function accepts as an input.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Destination Hardware Address (hwdst) — Target’s MAC Address is set to the target_mac variable that was used to store the value returned by the get_mac(ip) function in the previous line.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Source IP Address (psrc) — Sender’s IP Address is set to &lt;strong&gt;spoof_ip.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I know all of these do not make sense but if we consider the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;target_ip = &lt;strong&gt;10.0.2.1&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;spoof_ip = &lt;strong&gt;10.0.2.15&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;target_mac = get_mac(target_ip)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, the ARP Response that we are created in the 2nd line of the function has the following information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Opcode = &lt;strong&gt;2&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sender MAC Address = Unknown&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sender IP Address = spoof_ip = &lt;strong&gt;10.0.2.15&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target MAC Address = target_mac = &lt;strong&gt;08:22:55:2a:ab:35&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target IP Address = target_ip = &lt;strong&gt;10.0.2.1&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, you would be wondering why we are not setting our MAC Address to fool the access point and pretend as the victim in this ARP Response? This is because the Scapy module adds the MAC Address of the machine where the ARP Response packet is created. In our case, the attacker would be us and therefore the Scapy packet is created on our machine so scapy will automatically add our MAC Address in the ARP Response message.&lt;/p&gt;

&lt;p&gt;Also, note that the sender’s IP Address is set to **spoof_ip **so upon receiving, the access point thinks that the ARP Response is from the victim and this is how the attacker sends an ARP Response to the access point pretending to be the victim (legitimate machine).&lt;/p&gt;

&lt;p&gt;Similarly, we can also fool the victim to think that the attacker is the access point.&lt;/p&gt;

&lt;p&gt;Now, the third line of the function sends the ARP Response packet that we created on the second line.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scapy.send(spoof_packet, verbose = False)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The scapy.send() function requires the packet to be sent as a mandatory argument. The &lt;strong&gt;verbose = False&lt;/strong&gt; argument tells the scapy to not print any output of its own.&lt;/p&gt;

&lt;p&gt;This marks the end of the spoof function, all that’s left to do is call the function to start fooling both (victim and access point) machines.&lt;/p&gt;

&lt;p&gt;Next, after the **spoof **function, the next three lines give us the input values of target_ip and the gateway_ip that are passed using the command line arguments in Step 2.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;options = get_args()
target_ip = options.target_ip
gateway_ip = options.gateway_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;After these lines, there is a **“try ” **block where we put a block of code that we think would generate an error. In this case, the script will generate an error when we press Control + C to end the execution of the script. We do this because when we want to quit the script execution we still need to restore the changes (fooling) that we did in the network.&lt;/p&gt;

&lt;p&gt;In the try block, we start a while loop that will loop indefinitely as we want to continue to fool both the machines until we stop the execution.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try:
    while True:
        spoof(target_ip, gateway_ip)
        spoof(gateway_ip, target_ip)
        packets_sent += 2
        print("\r[+] Packets Sent: {}".format(packets_sent), end = "")
        time.sleep(2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Inside the while loop, the first &lt;strong&gt;spoof()&lt;/strong&gt; function call will &lt;strong&gt;fool&lt;/strong&gt; the &lt;strong&gt;victim&lt;/strong&gt; to &lt;strong&gt;think&lt;/strong&gt; that the &lt;strong&gt;attacker&lt;/strong&gt; is the &lt;strong&gt;access point&lt;/strong&gt; and the second &lt;strong&gt;spoof()&lt;/strong&gt; function call will fool the &lt;strong&gt;access point&lt;/strong&gt; to &lt;strong&gt;think&lt;/strong&gt; that the &lt;strong&gt;attacker&lt;/strong&gt; is the &lt;strong&gt;victim&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packets_sent += 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above line simply calculates the number of packets sent in every iteration. As we call the &lt;strong&gt;spoof()&lt;/strong&gt; function twice for every iteration, we send two packets every iteration and therefore we increment packets_sent by 2.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;time.sleep(2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The time.sleep(2) line, generates a delay of 2 seconds before executing the next iteration.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 5: Writing the restore function.
&lt;/h3&gt;

&lt;p&gt;In this step, we create a &lt;strong&gt;restore **function that would restore the state of the network that was before the ARP Spoofing attack as soon as we encounter an error on KeyboardInterrupt Control + C .&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
**What is Restore Function?&lt;/p&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5520%2F1%2AGbiRHJak_yXfsuMhQ-HVbQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5520%2F1%2AGbiRHJak_yXfsuMhQ-HVbQ.jpeg" alt="**Fig 7. Restoring**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Fig 7., we can see that the attacker sends ARP Requests to both the machines (victim and access point) in order to restore the network into a normal state. The attacker sends the ARP requests with genuine information inside it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Restore Function&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def restore(source_ip, destination_ip):
    source_mac = get_mac(source_ip)
    destination_mac = get_mac(destination_ip)
    restore_packet = scapy.ARP(op = 2, pdst = destination_ip, hwdst = destination_mac, psrc = source_ip, hwsrc = source_mac)
    scapy.send(restore_packet, count =1, verbose = False)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The restore function accepts two IP Addresses i.e. source_ip and destination_ip. Similarly to **spoof() **function, the **restore() **function also creates an ARP Response but instead of forging information, it creates the Request with genuine information.&lt;/p&gt;

&lt;p&gt;You can see that the values of the pdst, hwdst, psrc and hwsrc is legitimate values as we want to restore the state. Also, note that in this function, online the &lt;strong&gt;spoof()&lt;/strong&gt; function, we explicitly set the MAC Address of the sender.&lt;/p&gt;

&lt;p&gt;In this function, we use &lt;strong&gt;get_mac() **function to get the MAC Address of the Source IP Address and the Destination IP Address. We store these values in two variables in order to access them later. Then, we create a **restore_packet **with genuine IP and MAC Addresses. After that, we send the **restore_packet **with **scapy.send()&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Remember that we called the spoof() function in the try block and we did not mention the code block in except. We’ll use this **restore() **function inside the except block when we encounter a **KeyboardInterrupt **Control + C error. We call the **restore() **twice because we need to restore the normal state on both sides i.e. the access point and the victim as shown in Fig 7.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;except KeyboardInterrupt:
    print("\n[-] Detected Ctrl + C..... Restoring the ARP Tables..... Be Patient")
    restore(target_ip, gateway_ip)
    restore(gateway_ip, target_ip)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above code executes as soon as it encounters KeyboardInterrupt and restores the state on both the sides by calling the **restore() **function twice.&lt;/p&gt;

&lt;p&gt;This is where the Python script ends and we have successfully implemented an ARP Spoofing attack. Now, all that’s left to do is to test the script by executing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working Demo
&lt;/h2&gt;

&lt;p&gt;Okay, before jumping to writing the code in Python I’ll tell you about the setup that I have: I am currently on Windows 10 and I have &lt;a href="https://www.virtualbox.org/" rel="noopener noreferrer"&gt;Virtualbox &lt;/a&gt;running with two VMs (1. Kali Linux and 2. Windows 10). I will execute the python script on my Kali Linux machine and try to attack my Windows 10 VM. Note: The VMs are configured to use **NatNetwork **in Virtualbox. When the VMs are set to use **NatNetwork, **the VMs thinks the host as the router (access point). To know more about NatNetwork and how to configure a VM to use it, read &lt;a href="https://www.techrepublic.com/article/how-to-create-multiple-nat-networks-in-virtualbox/" rel="noopener noreferrer"&gt;this&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kali Linux Machine
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IP Address = &lt;strong&gt;10.0.2.9&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAC Address = &lt;strong&gt;08:00:27:35:21:2e&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Windows 10
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IP Address = &lt;strong&gt;10.0.2.15&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAC Address = &lt;strong&gt;08:00:27:e6:e5:59&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Access Point or Default Gateway
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IP Address = &lt;strong&gt;10.0.2.1&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAC Address = &lt;strong&gt;52:54:00:12:35:00&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Obtaining IP Address and the MAC Address of the target and the access point using a Network Scanner. If you haven’t read my article on how to build a network scanner then read &lt;a href="https://medium.com/@dharmilch18/writing-a-network-scanner-using-python-a41273baf1e2" rel="noopener noreferrer"&gt;Writing a Network Scanner using Python&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A3BZqNm6n6GfHpy6DD3LxnQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A3BZqNm6n6GfHpy6DD3LxnQ.png" alt="**Fig 8. Finding IP and MAC Addresses using Network Scanner**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Access Point or Default Gateway of Windows 10 before attacking.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2066%2F1%2A7yYMZTIOjnsHMMQyHYLpuw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2066%2F1%2A7yYMZTIOjnsHMMQyHYLpuw.png" alt="**Fig 9. Before the Attack**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that, before the ARP Spoofing attack, the access point with the IP Address &lt;strong&gt;10.0.2.1&lt;/strong&gt; has a MAC Address **52:54:00:12:35:00, **which is the normal network flow.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Attacking the Windows 10.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AWcHwGCCX56Rbfiz743LqWw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AWcHwGCCX56Rbfiz743LqWw.png" alt="**Fig 10. ARP Packet**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this step, we have started our ARP Spoofing attack by specifying the IP Addresses of the target (victim) and the access point (gateway) as the command line argument.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ARP Table.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2086%2F1%2AZb4tVKrBwO6H30My4SEvkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2086%2F1%2AZb4tVKrBwO6H30My4SEvkg.png" alt="**Fig 11. ARP Table**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Fig 11., you can see that after carrying out the attack, the access point or the gateway’s MAC Address is the MAC Address of the Kali Linux Machine i.e. **08:00:27:35:21:2e. **As soon as this happens all the messages intended for the access point from Windows 10 will pass to the attacker (Kali Linux).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Restoring to the normal state.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2310%2F1%2A8OK3wPN6dEhePQ23Ic5HDg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2310%2F1%2A8OK3wPN6dEhePQ23Ic5HDg.png" alt="**Fig 12. Restoring to the normal state**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ARP Table after Restoring.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2058%2F1%2A0vs--aTaZRgHBbEFJ3ZJcQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2058%2F1%2A0vs--aTaZRgHBbEFJ3ZJcQ.png" alt="**Fig 13. ARP Table After Restoring**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fig 13. displays the ARP Table after the attack was stopped and the network was restored to the normal state. See the second table where the access point’s MAC Address is the original IP Address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: When the Windows 10 machine is being ARP spoofed, you cannot use the Internet (as shown in Fig 4.) unless you run a special command in your Kali Linux Machine.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**echo 1 &amp;gt; /proc/sys/net/ipv4/ip_forward**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The above command will make sure that the Internet works completely fine in Windows 10. The command enables IP Forwarding in Kali Linux which effectively says Kali Linux to forward the packets to the access point.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where Part 1 of the Man In The Middle (MITM) attack ends. Stay tuned for more parts in this series where we will intercept credentials, modify network traffic, replacing downloading files, etc. You can find the entire code for this tutorial on my &lt;a href="https://github.com/dharmil18/ARP-Spoofer" rel="noopener noreferrer"&gt;Github Repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading. For any queries, you can ask me and any constructive feedback is always appreciated.&lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>arpspoofing</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Writing a Network Scanner using Python</title>
      <dc:creator>Dharmil Chhadva</dc:creator>
      <pubDate>Tue, 27 Feb 2024 00:52:19 +0000</pubDate>
      <link>https://forem.com/dharmil18/writing-a-network-scanner-using-python-3b80</link>
      <guid>https://forem.com/dharmil18/writing-a-network-scanner-using-python-3b80</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The following tutorial works on any Linux Distributions, provided you have the root access i.e. you’ll have to execute this script using the root user.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is a Network Scanner?
&lt;/h2&gt;

&lt;p&gt;A network scanner is a software tool that scans the network for connected devices. It is also used for diagnostic and investigative purposes to find and categorize what devices are running on a network. This tool takes an IP address or a range of IP addresses as input and then scans each IP Addresses sequentially and determines whether a device is present on that particular IP address or not. It scans the network and returns an IP address and it’s corresponding MAC address if the device is present. A popular tool that’s commonly used CyberSecurity professionals is &lt;a href="https://nmap.org/" rel="noopener noreferrer"&gt;**nmap&lt;/a&gt;**.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;To understand how the Network Scanner scans the entire network we need to first understand what is &lt;strong&gt;ARP (Address Resolution Protocol)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a network, most of the computers use the &lt;strong&gt;IP Address&lt;/strong&gt; to communicate with other devices, however, in reality, the communication happens over the &lt;strong&gt;MAC Address. ARP is used to find out the MAC Address of a particular device whose IP address is known.&lt;/strong&gt; For instance, a device wants to communicate with the other device on the network, then the sending device uses ARP to find the MAC Address of the device that it wants to communicate with. ARP involves two steps to find the MAC address:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The sending device sends an &lt;strong&gt;ARP Request&lt;/strong&gt; containing the IP Address of the device it wants to communicate with. This request is broadcasted meaning every device in the network will receive this but only the device with the intended IP address will respond.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After receiving the broadcast message, the device with the IP address equal to the IP address in the message will send an &lt;strong&gt;ARP Response&lt;/strong&gt; containing its MAC Adress to the sender.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Network Scanner uses ARP Request and Response to scan the entire network to find active devices on the network and also to find their MAC Addresses.&lt;/p&gt;

&lt;p&gt;If it is still not clear what ARP is and how it works then refer to the images below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4634%2F1%2Amda_kqjm4ONDM7jQnKZ7TQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4634%2F1%2Amda_kqjm4ONDM7jQnKZ7TQ.jpeg" alt="**Fig 1. ARP Request**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4954%2F1%2ALTdIvgRjXx9XewTRZVeAyg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4954%2F1%2ALTdIvgRjXx9XewTRZVeAyg.jpeg" alt="**Fig 2. ARP Response**"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we know how does the network scanner works internally, let’s start writing it in Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modules Used:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.python.org/3.4/library/subprocess.html" rel="noopener noreferrer"&gt;argparse&lt;/a&gt;: To understand what this does read my first article &lt;a href="https://medium.com/@dharmilch18/changing-mac-address-using-python-8a16fc4a3563#f878" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://scapy.readthedocs.io/en/latest/extending.html" rel="noopener noreferrer"&gt;Scapy&lt;/a&gt;: Enables the user to send, sniff and dissect and forge network packets. This capability allows the development of tools that can probe, scan, or attack networks. It can forge or decode packets of a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more. It easily handles most tasks like scanning, tracerouting, probing, unit tests, attacks, or network discovery.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Okay, before jumping to writing the code in Python I’ll tell you about the setup that I have: I am currently on Windows 10 and I have &lt;a href="https://www.virtualbox.org/" rel="noopener noreferrer"&gt;Virtualbox &lt;/a&gt;running with two VMs (1. Kali Linux and 2. Windows 10). I will execute the python script on my Kali Linux machine and try to scan the entire network. Note: The VMs are configured to use **NatNetwork **in Virtualbox. To know more about NatNetwork and how to configure a VM to use it, read &lt;a href="https://www.techrepublic.com/article/how-to-create-multiple-nat-networks-in-virtualbox/" rel="noopener noreferrer"&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Writing the Network Scanner
&lt;/h2&gt;

&lt;p&gt;As we know what modules are required, let’s start writing the script.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Import the modules discussed above.&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2:&lt;/strong&gt; &lt;strong&gt;Implementing the functionality to allow the users to pass command line arguments.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To add this feature to our script, we’ll need to make use of the &lt;strong&gt;argparse&lt;/strong&gt; module that we imported in Step 1.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
To know more about how argparse works and what does the above part of the script does and what functionality it adds to the script, read the entire &lt;strong&gt;Step 2&lt;/strong&gt; from my previous article of how to &lt;a href="https://medium.com/@dharmilch18/changing-mac-address-using-python-8a16fc4a3563#03c5" rel="noopener noreferrer"&gt;change MAC Address of a device&lt;/a&gt;.

&lt;p&gt;The above code allows the user to provide the input for &lt;strong&gt;interface&lt;/strong&gt; value as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~# python3 network_scanner.py -t IP_Address/IP_Addresses
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;OR&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~# python3 network_scanner.py --target IP_Address/IP_Addresses
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;IP_Address&lt;/strong&gt; = Specific IP Address that you want to scan to check whether there is a device that’s using this IP Address or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IP_Addresses&lt;/strong&gt; = Range of IP Addresses that you want to scan.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Writing function that scans the network&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In this function, we’ll have to do the following things to be able to scan the network:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create an ARP Request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an Ethernet Frame.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Place the ARP Request inside the Ethernet Frame.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send the combined frame and receive responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Parse the responses and print the results.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
Note that the function **scan **takes an IP Address as an argument. Now, let's break down the above code line by line.&lt;/p&gt;

&lt;p&gt;def scan(ip):&lt;br&gt;
    .....&lt;br&gt;
    .....&lt;/p&gt;

&lt;p&gt;scan('10.0.2.15')&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Now the first thing that we want to do is to create an ARP Request (See Fig 1.) frame using &lt;strong&gt;scapy&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arp_req_frame = scapy.ARP(pdst = ip)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above line of code creates an ARP Request frame using scapy’s ARP Class with the destination IP Address &lt;strong&gt;(pdst)&lt;/strong&gt; provided as an argument to the function. The destination IP Address is set to the IP Address passed to the function because we want to direct the ARP Request frame to the IP Address we want. For instance, if &lt;strong&gt;ip = ‘10.0.2.15’&lt;/strong&gt; then the ARP Request is targetted for that IP Address only.&lt;/p&gt;

&lt;p&gt;Now, the question is how did I come to know that destination IP Address is represented as **pdst **in ARP class? For this, scapy has a built-in function that we can use to find what member variables (variables) or fields a class has.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arp_req_frame = scapy.ARP(pdst = ip)
print(scapy.ls(scapy.ARP()))

**OUTPUT
**root@kali:~/Desktop/Network Scanner# python3 network_scanner.py -t 10.0.2.1/24

hwtype : XShortField        = 1               (1)
ptype  : XShortEnumField    = 2048            (2048)
hwlen  : FieldLenField      = None            (None)
plen   : FieldLenField      = None            (None)
op     : ShortEnumField     = 1               (1)
hwsrc  : MultipleTypeField  = **'08:00:27:35:21:2e'** (None)
psrc   : MultipleTypeField  = **'10.0.2.9'**      (None)
hwdst  : MultipleTypeField  = '00:00:00:00:00:00' (None)
pdst   : MultipleTypeField  = '0.0.0.0'       (None)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note: 10.0.2.1/24 means IP Addresses from 10.0.2.1 to 10.0.2.254&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;strong&gt;scapy.ls()&lt;/strong&gt; function returns the fields a particular class has. It works for every class that scapy provides. We just have to pass the class name as &lt;strong&gt;scapy.class_name()&lt;/strong&gt; to it. In the example above, we wanted to know about the fields or member variables the ARP class has and so we used the scapy.ls(scapy.ARP()). This function then gave us the response as shown in the output above. This function provides the name of the fields, a small description of that field, and the default value that each field holds.&lt;/p&gt;

&lt;p&gt;The main fields to know are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;*&lt;em&gt;hwsrc *&lt;/em&gt;= Source MAC Address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;*&lt;em&gt;psrc *&lt;/em&gt;= Source IP Address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;*&lt;em&gt;hwdst *&lt;/em&gt;= Destination MAC Address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;*&lt;em&gt;pdst *&lt;/em&gt;= Destination IP Address.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: The &lt;strong&gt;hwsrc&lt;/strong&gt; and &lt;strong&gt;psrc&lt;/strong&gt; will always have the default value of the machine on which the ARP Request packet was created. In our case, the IP Address of my Kali machine is &lt;strong&gt;‘10.0.2.9’&lt;/strong&gt; and MAC Address is &lt;strong&gt;‘08:00:27:35:21:2e’&lt;/strong&gt; and therefore the field &lt;strong&gt;psrc&lt;/strong&gt; and &lt;strong&gt;hwsrc&lt;/strong&gt; has these values in them. Also, the default value for &lt;strong&gt;hwdst *&lt;em&gt;and **pdst **will *&lt;/em&gt;‘00:00:00:00:00:00’&lt;/strong&gt; and **‘0.0.0.0’ **respectively.&lt;/p&gt;

&lt;p&gt;So, this is how we can change any field’s value as we want while creating an instance of the class. Additionally, we can also view the ARP Request itself by another function that scapy provides.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arp_req_frame = scapy.ARP(pdst = ip)
print(arp_req_frame.summary())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Upon execution of the above code, we get the following output. You can see that it says ‘&lt;strong&gt;who has 10.0.2.3 says 10.0.2.9’, **this means the packet is a request packet and it’s asking everyone that who has the IP Address of **10.0.2.3&lt;/strong&gt;. The second part i.e **says 10.0.2.9 **provides information about the source or sender of the ARP Request to all the receiving devices and thus the receiving device with the IP Address **10.0.2.3 **will know whom to send the ARP Response. You can see that the output generated below is the same as what Fig 1 illustrates.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~/Desktop/Network Scanner# python3 network_scanner.py -t 10.0.2.3

**OUTPUT
**root@kali:~/Desktop/Network Scanner# python3 network_scanner.py -t 10.0.2.3

**ARP who has 10.0.2.3 says 10.0.2.9**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Another useful function that scapy provides is &lt;strong&gt;show().&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arp_req_frame = scapy.ARP(pdst = ip)
print(arp_req_frame.show())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;After the execution, it generates the following output.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~/Desktop/Network Scanner# python3 network_scanner.py -t 10.0.2.3

**OUTPUT**
###[ ARP ]###
hwtype    = 0x1
ptype     = IPv4
hwlen     = None
plen      = None
op        = who-has
hwsrc     = 08:00:27:35:21:2e
psrc      = 10.0.2.9
hwdst     = 00:00:00:00:00:00
pdst      = 10.0.2.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above output shows the various fields of an ARP Request packet and its corresponding values. Note that the &lt;strong&gt;pdst (destination IP Address) **has a value of **10.0.2.3 **because when executing the code we provide a command-line argument for which IP Address to scan and this IP Address is then set to pdst. This is because at the time of creating an instance of the ARP class we provided the IP Address of the destination device using **scapy.ARP(pdst = ip) **where **ip&lt;/strong&gt; is a variable name and its value is taken from the command-line argument that was passed at the time of execution. We already covered how to add command-line argument functionality that accepts input in &lt;strong&gt;Step 2&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After creating the ARP Request packet we need to now create an &lt;a href="https://en.wikipedia.org/wiki/Ethernet_frame" rel="noopener noreferrer"&gt;Ethernet&lt;/a&gt; Frame. The Ethernet frame contains fields such as Source and Destination Hardware (MAC) among others. Now, as the communication inside a network is carried out using the MAC Address, we can set the value of destination hardware address field to theMAC Address to which we want to communicate. Learn more about &lt;a href="https://www.geeksforgeeks.org/ethernet-frame-format/" rel="noopener noreferrer"&gt;Ethernet Frame here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The ARP Request is supposed to be broadcasted (transmitted to every IP Address in a network). Therefore, to broadcast the ARP Request we set the &lt;strong&gt;Destination Address&lt;/strong&gt; field of Ethernet field to **‘ff:ff:ff:ff:ff:ff’ **as this is a broadcast MAC Address. We now do this using scapy.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;broadcast_ether_frame = scapy.Ether(dst = "ff:ff:ff:ff:ff:ff")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above line of code creates an Ethernet Frame with &lt;strong&gt;dst (Destination Address)&lt;/strong&gt; is set to **‘ff:ff:ff:ff:ff:ff’. **Note, we can use scapy.ls() and show() function on Ethernet class. The fields of the Ethernet frame can be viewed using scapy.ls() function similarly to how we did it on ARP Class. The show() function can also be used similarly as we did for ARP Class. Output for both the function can be seen below.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(scapy.ls(scapy.Ether()))

**OUTPUT
**dst  : DestMACField     = 'ff:ff:ff:ff:ff:ff' (None)
src  : SourceMACField   = '08:00:27:35:21:2e' (None)
type : XShortEnumField  = 36864           (36864)

--------------------------------------------------------------------

print(broadcast_ether_frame.show())

**OUTPUT
**###[ Ethernet ]###
dst       = ff:ff:ff:ff:ff:ff
src       = 08:00:27:35:21:2e
type      = 0x9000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The next step is to combine the ARP Request and the Ethernet Frame. We did this using scapy because it allows a very convenient way to combine frames. We do it by the following line of code.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;broadcast_ether_arp_req_frame = broadcast_ether_frame/arp_req_frame
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above code creates a new frame by combining the ARP Request and Ethernet Frame using the **‘/’ **sign. This is because scapy allows us to combine frames using this.&lt;/p&gt;

&lt;p&gt;Now if we call the &lt;strong&gt;show()&lt;/strong&gt; function we can see that the final combined frame consists of both Ethernet and ARP Request.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~/Desktop/Network Scanner# python3 network_scanner.py -t 10.0.2.3

**OUTPUT
**###[ Ethernet ]###
dst       = ff:ff:ff:ff:ff:ff
src       = 08:00:27:35:21:2e
type      = ARP

###[ ARP ]###
hwtype    = 0x1
ptype     = IPv4
hwlen     = None
plen      = None
op        = who-has
hwsrc     = 08:00:27:35:21:2e
psrc      = 10.0.2.9
hwdst     = 00:00:00:00:00:00
pdst      = 10.0.2.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;We can see that the type field of Ethernet Frame now holds ARP as its type. Also, the ARP part of the frame is identified as &lt;strong&gt;ARP Request **by the value of the **op **field. If **op = who-has&lt;/strong&gt; then it means its an &lt;strong&gt;ARP Request&lt;/strong&gt; and if &lt;strong&gt;op = is-at&lt;/strong&gt; then it is &lt;strong&gt;ARP Response&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now the only thing that is remaining is to sent the combined frame and to receive the responses. To send the requests and receive the responses we will use a function provided by scapy that not only sends the requests but also returns the responses.&lt;/p&gt;

&lt;p&gt;This function returns the captured responses as a python tuple out of which the first element of the tuple has the &lt;strong&gt;answered&lt;/strong&gt; responses where the devices responded and the second element has the responses which were &lt;strong&gt;unanswered&lt;/strong&gt;. The responses which are in the unanswered list mean that there are no devices that use those IP Addresses.&lt;/p&gt;

&lt;p&gt;The function that scapy provides to do the above tasks is called &lt;strong&gt;scapy.srp(). **This function takes the actual frame to be transmitted as an argument. You can see that we have passed **broadcast_ether_arp_req_frame (our final combined frame) **is passed to the function below. It also takes a **timeout **input which tells the scapy for how much time period it should wait to receive a response before moving further. What this means is, from the below example **timeout = 1&lt;/strong&gt; means the scapy will wait for 1 second for the response and if the response is not received it will move further to send the packet to the next IP Address. The argument &lt;strong&gt;verbose = False&lt;/strong&gt; is not important and it only stops the scapy from printing its own messages on the screen.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;answered_list= scapy.srp(broadcast_ether_arp_req_frame, timeout = 1, verbose = False)
    print('Total Number of Responses -&amp;gt;', len(answered_list))
    print('\n-----------Answered Responses---------')
    print('Number of Answered Responsed -&amp;gt;', len(answered_list[0]))
    print('\n')
    for i in range(0,len(answered_list[0])):
        print(answered_list[0][i])
        print('\n')
    print('\n-----------UnAnswered Responses---------')
    print('Number of UnAnswered Responsed -&amp;gt;', len(answered_list[1]))
    print('\n')
    for i in range(0,len(answered_list[1])):
        print(answered_list[1][i])
        print('\n')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above code displays the total number of answered (responded) responses and the actual responses itself. It also displays the total number of unanswered (not responded) responses and the actual responses.&lt;/p&gt;

&lt;p&gt;Note: This code is not used in the final script and is just for understanding the output returned by &lt;strong&gt;scapy.srp()&lt;/strong&gt; function. The above code generates the following output.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3756%2F1%2Aok3M83G4Ujj79XkY87hoqQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3756%2F1%2Aok3M83G4Ujj79XkY87hoqQ.png" alt="scapy.srp() function’s Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the above image, we can see that the total number of responses received was &lt;strong&gt;two. **This is because the tuple consists of two elements **answered&lt;/strong&gt; and &lt;strong&gt;unanswered&lt;/strong&gt;. Furthermore, we can see that the total answered responses are &lt;strong&gt;three&lt;/strong&gt; which means that only &lt;strong&gt;three&lt;/strong&gt; devices responded with ARP Response. Below this, we can also see the actual responses itself. After this, we see that the total unanswered responses are **253 **which means **253 **devices did not respond. We can also see some of the responses that scapy recorded for unanswered responses.&lt;/p&gt;

&lt;p&gt;The main aim of showing the above output was to make you understand that we only need the answered responses and not the unanswered one. Therefore, we can access only the answered responses using the following line of code.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;answered_list = scapy.srp(broadcast_ether_arp_req_frame, timeout = 1, verbose = False)[0]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;As the &lt;strong&gt;answered_list&lt;/strong&gt; is a tuple we can extract the individual elements by providing the index in square brackets. The above code will only store answered responses.&lt;/p&gt;

&lt;p&gt;Now, all that is left is to extract the IP Address and the MAC Address from each of the answered responses. We’ll use Python dictionaries inside of a list for that purpose.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result = []
    for i in range(0,len(answered_list)):
        client_dict = {"ip" : answered_list[i][1].psrc, "mac" : answered_list[i][1].hwsrc}
        result.append(client_dict)

print(result)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above code creates an empty list called &lt;strong&gt;result **and then creates a dictionary called **client_dict **for each response and then appends it to the **result&lt;/strong&gt; list. The &lt;strong&gt;client_dict *&lt;em&gt;has two keys *&lt;/em&gt;‘ip’&lt;/strong&gt; and &lt;strong&gt;‘mac’&lt;/strong&gt; which stores the IP Address and MAC Address respectively. The output of the above code for our case will be:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~/Desktop/Network Scanner# python3 network_scanner.py -t 10.0.2.1/24

[{'ip': '10.0.2.1', 'mac': '52:54:00:12:35:00'}, {'ip': '10.0.2.2', 'mac': '52:54:00:12:35:00'}, {'ip': '10.0.2.3', 'mac': '08:00:27:22:d8:10'}]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The next step in the &lt;strong&gt;scan()&lt;/strong&gt; function is to return the &lt;strong&gt;result&lt;/strong&gt; list. We’ll use the result list in another function to print the results in a certain format.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Writing function to print the results in a certain format.
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
The above display() function takes the result list as an input and displays the result in a certain format. It produces the output shown below.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@kali:~/Desktop/Network Scanner# python3 network_scanner.py -t 10.0.2.1/24
-----------------------------------
IP Address     MAC Address
-----------------------------------
10.0.2.1       52:54:00:12:35:00
10.0.2.2       52:54:00:12:35:00
10.0.2.3       08:00:27:22:d8:10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is where the script is complete and we have created a network scanner using Python successfully.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working Example
&lt;/h3&gt;

&lt;p&gt;I am using a Virtualbox setup with two VMs (Kali Linux and Windows 10). I’ll show you that the scanner that we created works perfectly fine. I’ll execute the script in Kali Linux and I will also start Windows 10 VM. The expectation is that the output should contain the IP Address and MAC Address of the Windows 10 VM also.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2038%2F1%2As7JrqxS0JWCTefI0tyH__w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2038%2F1%2As7JrqxS0JWCTefI0tyH__w.png" alt="Windows 10 VM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the above image, we can note two things about the Windows 10 VM:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;IP Address = 10.0.2.15&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAC Address = 08-00-27-e6-e5-59 (represented as Physical Address in the image below the Description field)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, the output generated by the script on the Kali Linux machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F1%2AJI3MNlVOdmBJd9ki-crvpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F1%2AJI3MNlVOdmBJd9ki-crvpw.png" alt="Script Output on Kali Linux VM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the above image, we can see that the network scanner script that we created scans the entire network including the Windows 10 VM which is in the same network.&lt;/p&gt;

&lt;p&gt;Thank You for reading. The entire code can found in my &lt;a href="https://github.com/dharmil18/Network-Scanner" rel="noopener noreferrer"&gt;Github Repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>security</category>
      <category>python</category>
      <category>cybersecurity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Changing the MAC Address using Python</title>
      <dc:creator>Dharmil Chhadva</dc:creator>
      <pubDate>Tue, 27 Feb 2024 00:48:12 +0000</pubDate>
      <link>https://forem.com/dharmil18/changing-the-mac-address-using-python-564j</link>
      <guid>https://forem.com/dharmil18/changing-the-mac-address-using-python-564j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The following tutorial works on any Linux Distributions, but you will need the root access to execute the system commands necessary in order to change the MAC Address successfully.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What is MAC Address?
&lt;/h3&gt;

&lt;p&gt;To learn how to change the MAC Address, it is essential to learn about what a MAC Address is. We all use various electronic gadgets such as smartphones, desktops, laptops, tablets, and many more to browse the internet, for entertainment, among other tasks. Each of these electronic gadgets has its own MAC Address. &lt;strong&gt;MAC&lt;/strong&gt; stands for &lt;strong&gt;Media Access Control&lt;/strong&gt; Address. Every device needs a MAC Address to be uniquely identified by others on the network. For instance, when you watch a video on Youtube, you send a request for the video via your device, and this request is transmitted through your default gateway (usually through a router for a private home network). The router then sends this request to the World Wide Web and receives a response. Now, the &lt;strong&gt;World Wide Web (which is public)&lt;/strong&gt; does not know who you are because your device has a &lt;strong&gt;private IP Address&lt;/strong&gt; that is only recognized by your router, so the response received by the router is then given to you because the router knows your MAC Address associated with the private IP Address of your device.&lt;/p&gt;

&lt;p&gt;MAC Address is a 48-bits hardware address that is hardcoded on the &lt;strong&gt;Network Interface Card (NIC)&lt;/strong&gt; at the time of manufacturing. MAC Address is also known as the &lt;strong&gt;Physical Address&lt;/strong&gt; of a device. MAC Addresses are used to transmit packets within the network.&lt;/p&gt;

&lt;p&gt;For example, &lt;strong&gt;00:1A:3F:F1:4C:C6&lt;/strong&gt; is a MAC Address. The first three octets (00:1A:3F) of the address identifies the manufacturer and is known as &lt;strong&gt;OUI (Organizational Unique Identifier). **The last three octets are **Network Interface Controller Specific&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Read more about &lt;strong&gt;NIC&lt;/strong&gt; &lt;a href="https://www.tutorialspoint.com/what-is-network-interface-card-nic"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do we need to change the MAC Address?
&lt;/h3&gt;

&lt;p&gt;There are several reasons why you would want to change the MAC Address of your device. Let’s look at them one by one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Increase Anonymity:&lt;/strong&gt; When on a public network, you might want to change the MAC Address to stay anonymous, if you don’t then there are chances that the network you are on might log your MAC Address and thus leaving behind a trail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Impersonate other devices:&lt;/strong&gt; When you want to carry out an attack (for testing purposes), changing the MAC Address can be useful to impersonate any legitimate device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bypassing filters:&lt;/strong&gt; If a MAC Address is blacklisted to use the network, and to overcome this is to change the MAC Address and fool the filters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to change the MAC Address?
&lt;/h3&gt;

&lt;p&gt;To change the MAC Address, we need to execute a few system commands. The first step is to identify the interface whose MAC Address you want to change and you can do this using the following command in Linux.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dcode@dcode-pop-os:~$ ifconfig
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above command produces the following output.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**enp0s3:** flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500
        inet 10.0.2.5  netmask 255.255.255.0  broadcast 10.0.2.255
        **ether 08:00:27:35:21:ff**  txqueuelen 1000  (Ethernet)
        RX packets 13962  bytes 17732985 (17.7 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7969  bytes 975852 (975.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;First of all, to change the MAC Address we need to know the &lt;strong&gt;interface name&lt;/strong&gt; and the existing &lt;strong&gt;MAC Address. **This information can be obtained by executing the **ifconfig&lt;/strong&gt; command. We can get the interface name and the existing MAC Address from the output produced by &lt;strong&gt;ifconfig&lt;/strong&gt;. For instance, from the above output, &lt;strong&gt;enp0s3 **is the name of the **interface **and the **ether&lt;/strong&gt; field on the third line has the MAC Address (&lt;strong&gt;08:00:27:35:21:ff&lt;/strong&gt; in our case).&lt;/p&gt;

&lt;p&gt;Now that we know the interface name whose MAC Address we want to change, we can move to the next command.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dcode@dcode-pop-os:~$ sudo ifconfig enp0s3 down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above command when executed, takes the interface down. What that means is you will no longer be able to connect to the internet. We need to take the interface down &lt;strong&gt;(disabling it)&lt;/strong&gt; first if we need to change the MAC Address. After this, the next command to be executed will change the MAC Address.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dcode@dcode-pop-os:~$ sudo ifconfig enps03 hw ether 00:11:22:33:44:55
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above command changes the existing MAC Address &lt;strong&gt;(08:00:27:35:21:FF)&lt;/strong&gt; to a new MAC Address &lt;strong&gt;(00:11:22:33:44:55)&lt;/strong&gt; specified in the command itself. Now the MAC Address of the interface enp0s3 has been changed but to use it, we need to enable the interface again using the following command.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dcode@dcode-pop-os:~$ sudo ifconfig enp0s3 up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;After executing the above command, you enable the interface again so that you can access the internet. To check whether the MAC Address was changed to what we specified, execute the &lt;strong&gt;ifconfig&lt;/strong&gt; command.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dcode@dcode-pop-os:~$ ifconfig
**enp0s3:** flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500
        inet 10.0.2.5  netmask 255.255.255.0  broadcast 10.0.2.255
        **ether 00:11:22:33:44:55**  txqueuelen 1000  (Ethernet)
        RX packets 13997  bytes 17737735 (17.7 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8892  bytes 1059117 (1.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;From the output, we can see that the MAC Address was changed to &lt;strong&gt;00:11:22:33:44:55&lt;/strong&gt; from &lt;strong&gt;08:00:27:35:21:ff&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using Python to change the MAC Address
&lt;/h3&gt;

&lt;p&gt;Up until now, we manually typed the commands and executed them but we can automate the entire process using Python so that we just have to provide the script with the interface name and the new MAC Address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modules Used:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.python.org/3.4/library/subprocess.html"&gt;subprocess&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.python.org/3/library/argparse.html"&gt;argparse&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.python.org/3/library/re.html"&gt;re&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;subprocess&lt;/strong&gt; module is used to execute system commands using Python. It contains several functions that can be used. We are going to focus on one particular function that is used to execute the system commands. It is called the **call() **function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;subprocess.call([‘ifconfig’])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This instruction executes the ifconfig command using Python.&lt;/p&gt;

&lt;p&gt;The **argparse **module makes it convenient to write user-friendly command-line interfaces. The program defines the arguments it requires and **argparse **will figure out how to parse these arguments. It also generates help and usage messages and issues errors when the user enters any invalid arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dcode@dcode-pop-os:~$ python3 programs_name.py -op1 option -op2 option
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;With the help of argparse we can provide the user with the ability to pass the input values using command-line arguments. Even if you don’t understand now, it will be clear once we start coding 😃.&lt;/p&gt;

&lt;p&gt;Next, the &lt;strong&gt;re **module provides **Regular Expression&lt;/strong&gt; matching operations. You’ll know for what we use the &lt;strong&gt;re&lt;/strong&gt; module as we progress ahead.&lt;/p&gt;
&lt;h3&gt;
  
  
  Python Script Coding
&lt;/h3&gt;

&lt;p&gt;This is where we start coding in Python.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;strong&gt;Import the modules discussed above.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;strong&gt;Implementing the functionality to allow the users to pass command line arguments.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To add this feature to our script, we’ll need to make use of the &lt;strong&gt;argparse&lt;/strong&gt; module that we imported in Step 1.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The above code allows the user to provide the input for &lt;strong&gt;interface&lt;/strong&gt; value and &lt;strong&gt;new MAC Address&lt;/strong&gt; as follows:

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dcode@dcode-pop-os:~$ python3 mac_changer.py -i interface_name -m new_mac_address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;OR&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dcode@dcode-pop-os:~$ python3 mac_changer.py --interface interface_name --mac new_mac_address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;interface_name = Name of the interface whose MAC Address you want to change.&lt;/p&gt;

&lt;p&gt;new_mac_address = MAC Address that you want to replace in place of the old one.&lt;/p&gt;

&lt;p&gt;The **options **stores the values provided by the user. When you print it the output is as follow:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(options)

**Output:** 
Namespace(interface='enp0s3', new_mac='00:55:22:33:44:11')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Individually accessing the **two **arguments is done as follows:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(options.interface)
print(options.new_mac)

**Output:** 
enp0s3
00:11:22:33:44:55
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: The &lt;strong&gt;dest **argument in the **add_argument() **method provides the name according to which the **parse_args()&lt;/strong&gt; stores its corresponding values in the **options **variable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The last thing in Step 2 is we created a variable &lt;strong&gt;command_args **and invoked the function **get_args()&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;command_args = get_args()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above statement will store the **options **returned by the **get_args() **hence giving us access to the argument values outside of the scope of the function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Writing a function that changes the MAC Address.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we have the two values that we require to change the MAC Address &lt;strong&gt;(interface and new MAC Address), *&lt;em&gt;we’ll write a function that changes the MAC Address using system commands.&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
Look at the function that we just wrote, it accepts **two **arguments *&lt;/p&gt;&lt;/em&gt;(interface and new_mac). **The two values are provided to **change_mac()&lt;/strong&gt; function by &lt;strong&gt;command_args&lt;/strong&gt; variable. It also checks whether the MAC Address provided is valid or not. After that, using the **subprocess **module we execute the system commands. Note: You require root access to execute these commands.&lt;/p&gt;

&lt;p&gt;Now, at this point, we have completed a Python script that changes the MAC Address, but we still need to be sure that the new MAC Address was applied. And for that, we need a write another function that returns the current MAC Address of the interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Writing a function to get the current MAC Address&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This function takes interface as an input and returns the current MAC Address of that interface. We are writing this function to check whether the new MAC address was applied or not.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
So, the &lt;strong&gt;get_current_mac()&lt;/strong&gt; function extracts the current MAC Address of the interface provided. Now, let’s break down this function.

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output = sub.check_output(['ifconfig', interface], universal_newllines = True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above statement is similar to &lt;strong&gt;sub.call()&lt;/strong&gt; in the &lt;strong&gt;change_mac()&lt;/strong&gt; function but there is one difference. The &lt;strong&gt;sub.check_output()&lt;/strong&gt; functions returns the output of the command whereas &lt;strong&gt;sub.call()&lt;/strong&gt; does not return anything. The returned output is stored in the variable &lt;strong&gt;output.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Also, the argument &lt;strong&gt;universal_newlines = True **is used because if this value is set to **False&lt;/strong&gt; then the output returned is in &lt;strong&gt;bytes.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Official Docs -&amp;gt; By default, this function will return the data as encoded bytes. The actual encoding of the output data may depend on the command being invoked, so the decoding to text will often need to be handled at the application level. This behavior may be overridden by setting &lt;em&gt;universal_newlines&lt;/em&gt; to True&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The next statement is,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search_mac = re.search(r"\w\w:\w\w:\w\w:\w\w:\w\w:\w\w", output)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is where the &lt;strong&gt;re&lt;/strong&gt; module is being used. &lt;strong&gt;re&lt;/strong&gt; stands for Regular Expressions and these are often used in string matching applications. The &lt;strong&gt;re.search()&lt;/strong&gt; function accepts the &lt;strong&gt;regular expression&lt;/strong&gt; and the &lt;strong&gt;string&lt;/strong&gt; in which the pattern is supposed to be matched. In our case, the string is stored inside the variable &lt;strong&gt;output. *&lt;em&gt;The *&lt;/em&gt;\w\w:\w\w:\w\w:\w\w:\w\w:\w\w **expression matches the MAC Address in the output variable which has the output of the **ifconfig&lt;/strong&gt; command. See the image below to understand it better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HQvrdjtQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2124/1%2A6kJTE176C7GJTuPsi2A8AA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HQvrdjtQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2124/1%2A6kJTE176C7GJTuPsi2A8AA.png" alt="Regex Demonstration" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see that the regular expression matches the MAC Address perfectly (Highlighted in green in the Match result box). &lt;a href="https://pythex.org/"&gt;Regular Expression Cheatsheet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Furthermore, there are chances that &lt;strong&gt;re.search()&lt;/strong&gt; might find more than one string that matches the regex (regular expression). Therefore, the below statement will make sure to return the first matched element only. What if it matches more than one string and returns the string which is not desired? In the output returned by &lt;strong&gt;ifconfig,&lt;/strong&gt; the chances of a getting string other than the desired one is next to zero.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search_mac.group(0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This sums up the &lt;strong&gt;get_current_mac()&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;Now, the only thing remaining is to check whether the MAC Address provided by the user was applied. For this, you can see that we have called &lt;strong&gt;get_current_mac()&lt;/strong&gt; function twice, once before calling &lt;strong&gt;change_mac()&lt;/strong&gt; function and once after calling the &lt;strong&gt;change_mac()&lt;/strong&gt; function. This ensures that we capture both the MAC Addresses (before and after change). We then compare &lt;strong&gt;changed_mac&lt;/strong&gt; and **command_args.new_mac **and if both matches then the MAC Address has been changed successfully.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if changed_mac == command_args.new_mac:
    print('Successfully Changed the MAC Address')
else:
    print('Could not change the MAC Address')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This where the script ends and to execute the script do the following: This was covered in &lt;strong&gt;Step 2.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dcode@dcode-pop-os:~$ python3 mac_changer.py -i interface_name -m new_mac_address

**OR**

dcode@dcode-pop-os:~$ python3 mac_changer.py --interface interface_name --mac new_mac_address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The entire code can be found on my &lt;a href="https://github.com/dharmil18/MAChanger"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>tutorial</category>
      <category>security</category>
    </item>
  </channel>
</rss>
