About port Scanners
The Port Scan Tool (ports Scanner) is a tool for probing server or host open ports. is often used by computer administrators to confirm security policies and is used by attackers to identify operational network services on the target host.
A port scan definition is a client that sends a corresponding request to a range of server ports to confirm the ports that can be used. Although it is not a malicious network activity in itself, it is also an important means for network attackers to probe the target host service to exploit known vulnerabilities in the service. The primary use of port scanning is still to confirm the availability of a service for a remote machine.
Scanning multiple hosts to obtain a specific port is called Port Sweep (Portsweep) to obtain a specific service. For example, a computer worm based on a SQL service cleans up the same port on a large number of hosts to establish a TCP connection on port 1433.
Python implementation
The principle of the port scanner is very simple, is nothing more than the operation of the socket, can connect to determine that the port is open.
Import Socket DEF scan (port): s = socket.socket () if s.connect_ex ((' localhost ', port) = = 0: print port, ' ope N ' s.close () if __name__ = = ' __main__ ':
So one of the simplest port scanners came out.
Wait, hello, half a day did not respond, that is because the socket is blocked, each connection to wait a long time to timeout.
We add it ourselves to the timeout.
S.settimeout (0.1)
Run again, it feels much faster.
Multi-threaded version
Import Socket Import Threading def scan (port): s = socket.socket () s.settimeout (0.1) if S.CONNECT_EX (' localhost ', port) = = 0: print port, ' open ' s.close () if __name__ = = ' __main__ ': threads = [Threading. Thread (Target=scan, args= (i,)) for I in Xrange (1,65536)]
Run it, whoa, come on, come on, throw the wrong. Thread.error:can ' t start new thread.
Think about it, this process opened 65,535 threads, there are two possible, one is more than the maximum number of threads, one is more than the maximum number of socket handle. Linux can be modified by Ulimit.
If you do not modify the maximum limit, how to use multithreading do not error it?
Add a queue, turn into producer-consumer mode, and open a fixed thread.
Multithreading + Queue version
Import socket import threading from queue import Queue def scan (port): s = socket.socket () s.settimeout (0.1) If S.CONNECT_EX (' localhost ', port) = = 0: print port, ' open ' s.close () def worker (): While not Q.empty (): port = q.get () try: scan (port) finally: q.task_done () if __name__ = = ' __main__ ': q = Queue () map (Q.put,xrange (1,65535)) threads = [Threading. Thread (Target=worker) for I in xrange (+)] map (lambda X:x.start (), threads)
Here, 500 threads are opened, and the task is continuously taken from the queue.
multiprocessing+ Queue version
You can't open 65,535 of processes? Or with the producer-consumer model
Import multiprocessing def scan (port): s = socket.socket () s.settimeout (0.1) if S.CONNECT_EX (' localhost ', port) = = 0: print port, ' open ' s.close () def worker (Q): While not Q.empty (): port = Q.get () try: scan (port) finally: q.task_done () if __name__ = = ' __main__ ': q = Multiprocessing. Joinablequeue () map (Q.put,xrange (1,65535)) jobs = [multiprocessing. Process (Target=worker, args= (Q,)) for I in Xrange (100)]
Note here that the queue is passed as a parameter to the worker, because it is the queue of the safe of the process, otherwise it will error.
Also useful is joinablequeue (), as the name implies is can join ().
Gevent version of Spawn
from gevent import Monkey; Monkey.patch_all (); Import gevent Import Socket ... if __name__ = = ' __main__ ': threads = [Gevent.spawn (scan, i) for I in Xrange (1,65536)]
Note that the monkey patch must be exception before the patch, or keyerror. For example, you can't import threading first, then monkey patches.
Pool version of Gevent
from gevent import Monkey; Monkey.patch_all (); Import socket from Gevent.pool Import Pool ... if __name__ = = ' __main__ ': pool = Pool (+) Pool.map (Scan,xrange (1, 65536))
Concurrent.futures version
Import socket from queue import queue from Concurrent.futures import Threadpoolexecutor ... if __name__ = = ' __main__ ':
q = Queue () map (Q.put,xrange (1,65536)) with Threadpoolexecutor (max_workers=500) as executor: for i in Range (500):