Python 3 Multi Threaded Ping Sweep Scanner

We know that nmap and other tools are great for scanning a network. What if we want to do it in python?

The following code is a demonstration of multi threading, using python 3 to sweep a network using pings on windows. The single threaded version took almost 2 minutes to check a network, but this version takes about 2 seconds.

Why not NMAP for a Ping Sweep?

Arguably, nmap is better. But you may not have nmap installed, or you might want to learn about multithreading! Regardless, there are many things learned from writing scripts like this.

Python Style

There are things done in this script that might be written more elegantly, but for learning the basics of multi-threading, doing a ping sweep is a great example.

Topics Learned in This Script

Programming is all about the big picture. If you can imagine a concept, the rest is just pieces of a puzzle. It’s useful to break down tasks into smaller and smaller tasks and solve them 1 by 1. However, unless you have a big picture goal in mind, your code gets more like spaghetti as you add features and rewrite your dream into reality.

In this script, if you understand each line, you will also understand all of the following components:

  • importing modules in python
  • hiding windows using subprocess
  • calling a subprocess from OS using python
  • coloring the CLI of python output
  • reading CIDR network addresses using python
  • measuring python program run time
  • python functions
  • passing data into python functions
  • basic python variables
  • creating a list in python
  • accessing members of a list
  • if else logic and skipping branches in python
  • while and for loops
  • creating a thread queue in python
  • python worker pool creation
  • locking print threads while workers finish
  • converting to string
  • Converting a thread to daemon so it dies gracefully
  • printing without a newline
  • Finding length of a list
  • list iteration/looping over a list
  • formatting a float to precision desired

Mulithreaded Ping Sweeper in Python 3 Code

5 thoughts on “Python 3 Multi Threaded Ping Sweep Scanner

  • September 18, 2019 at 11:09 pm
    Permalink

    I am having an issue:

    Traceback (most recent call last):
    File “pyipsweep.py”, line 63, in
    info = subprocess.STARTUPINFO()
    AttributeError: module ‘subprocess’ has no attribute ‘STARTUPINFO’

    I looked at few other scripts with the same subprocess.STARTUPINFO and get the same error. I am trying to understand why I get that error.

    Any help is much appreciated

    Reply
    • January 16, 2020 at 10:50 am
      Permalink

      When I comment out the line that says “import subprocess” I get the same error. Either you didn’t paste code correctly, or the module isn’t installed on your system.

      Reply
    • March 5, 2020 at 2:03 am
      Permalink

      Troy, those are windows specific pieces of code: you can import os and use something like this to make this a bit more multi-platform.

      # Configure subprocess to hide the console window in Windows
      try:
      info = subprocess.STARTUPINFO()
      info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
      info.wShowWindow = subprocess.SW_HIDE
      except Exception:
      pass

      # quick message/update
      print(‘Sweeping Network with ICMP: ‘, net_addr)

      # the actual ping definition and logic.
      # it’s called from a pool, repeatedly threaded, not serial
      def pingsweep(ip):

      # for windows: -n is ping count, -w is wait (ms)
      # for linux: -c is ping count, -W is wait (ms)
      # I didn’t test subprocess in linux, but know the ping count must change if OS changes
      if os.name ==’nt’:
      output = subprocess.Popen([‘ping’, ‘-n’, ‘1’, ‘-w’, ‘150’, str(all_hosts[ip])], stdout=subprocess.PIPE, startupinfo=info).communicate()[0]
      elif os.name == ‘posix’:
      output = subprocess.Popen([‘ping’, ‘-c’, ‘1’, ‘-W’, ‘1’, str(all_hosts[ip])], stdout=subprocess.PIPE).communicate()[0]

      Then further down you’ll want to add a “reply” response that is compatible with linux ping replies:

      if “Reply” in output.decode(‘utf-8’):
      print(str(all_hosts[ip]), ‘\033[90m’+ “is Online”)

      elif “icmp_seq” in output.decode(‘utf-8’): #icmp_seq may not be the best value to match on, but worked in my environment.
      print(str(all_hosts[ip]), ‘\033[90m’+”is Online”)

      Note: Dave, thanks for posting this.

      Reply
      • March 18, 2020 at 3:05 pm
        Permalink

        You’re welcome! Glad someone found it useful.

        Reply
  • July 20, 2020 at 11:24 pm
    Permalink

    This is exactly what I was looking for! Thank you!
    Also, I want to thank Adam for his Linux contribution. I merged them and have them working semi-reliably so far. I will be working to make it more reliable for my use.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.