nick
nick

Reputation: 1

New to Python Threading - It doesn't appear to make a difference

I've cobbled together an automatic vnc scanner. It cycles through IP addresses and if it detects an open port 5900 it attempts a screen shot. It isn't pretty, and poorly constructed but it works. It is however slow. I've tried threading the processes but I've been struggling. You can see I've added in a timer so I can see how long it takes to scan 30 ip's. I've tried multiple types of threading and threading libraries. This current iteration is probably the fastest I've had it, but it is only a few seconds faster than without threading. I'd be grateful if you could provide some feedback.

Many thanks

    import socket
    import nmap
    from vncdotool import *
    from ipaddress import *
    import pexpect
    import time
    from multiprocessing import Pool, freeze_support
    from multiprocessing.dummy import Pool as ThreadPool
    import itertools



    def vncconnect(tgtHost):
        try:
            ip = str(tgtHost)
            command = 'vncdotool -v -s ' + ip + ' --delay=1000 capture %s' % (ip + '.jpg')
            child = pexpect.spawn(command)
            child.expect ('INFO:root:connecting')
            time.sleep (10)
            print 'attempting screenshot on ' + ip
            child.expect (pexpect.EOF)
        except:
            pass

    def nmapScan(tgtHost,tgtPort):

        try:
            nmScan = nmap.PortScanner()
            result = nmScan.scan(str(tgtHost),str(tgtPort))
            if (result['nmap']['scanstats']['uphosts'] == '1'):
            print 'Trying ' + tgtHost + ' - appears open: attempting to connect'
            vncconnect(tgtHost)
            f = open('database', 'r+')
                f.write(tgtHost + ' Banner: ' + result['scan']['190.81.24.103']['tcp'][5900]['name'] + result['scan']['190.81.24.103']['tcp'][5900] /               ['version'] + '/n')

            else:
            print 'Trying ' + tgtHost + ' - is not open'
        except:
            pass


    def main():
        net4 = IPv4Address(u'170.0.0.0')
        y = 0
        start = time.time()
        numberofhoststoscan = 30
        while y < numberofhoststoscan:
            try:            

                port = '5900'
                y = y + 1
                z = str(net4)
                nmapScan(z, port)
                net4 = net4 + 1

            except:
                pass            
                net4 = net4 + 1
        end = time.time()
        total = (end - start)   
        print 'total scan time = ' + str(total) + ', scanned ' + str(numberofhoststoscan) + ' hosts'

    if __name__ == "__main__":
        freeze_support()
        pool = ThreadPool(4)
        pool.map(main())
        pool.close() 
        pool.join()

Upvotes: 0

Views: 167

Answers (1)

dsh
dsh

Reputation: 12214

It looks like:

  1. You perform the entire scan before you start the thread pool: pool.map(main()). Don't call main, just pass the object: pool.map(main)
  2. Each thread will start scanning the same set of IP addresses. You would want each thread to scan a different set of IP addresses in order to divide the work between them.


Update: I would use a generator to produce the addresses to scan

def addressesToScan(firstAddress, numberofhoststoscan):
    net4 = IPv4Address(firstAddress)
    for y in range(numberofhoststoscan):
        yield net4
        net4 = net4 + 1

To use it, you need a function that accepts the address. To measure the total time, you need that measurement outside of the thread's worker.

def worker(targetHost):
    port = '5900'
    try:
        nmapScan(targetHost, port)
    except:
        pass

if __name__ == "__main__":
    freeze_support()
    pool = ThreadPool(4)
    start = time.time()
    pool.map(worker, addressesToScan(u'170.0.0.0', 30))
    pool.close()
    pool.join()

    end = time.time()
    total = (end - start)   
    print 'total scan time = ' + str(total) + ', scanned ' + str(numberofhoststoscan) + ' hosts'

Upvotes: 3

Related Questions