Python 实现简单的端口扫描器
这个任务从去年末师傅布置下来一直拖到现在,(惭愧到不行
现在边写边在这里记录遇到的问题~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
实现对特定 (ip,port_number) 的扫描
从最简单入手,昨天在i春秋上看了python网络编程的课,并且自己实现了一次简单c/s架构的客户端服务器响应,对socket有了初步的认识(去年看到socket就看不下去了)。
这里简单介绍下Socket:
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目客户软件将插头插到不同编号的插座,就可以得到不同的服务。 ——源自 百度百科
(kali拨号困难,没法v6 google,凑活看(逃
在 TCP/IP四层网络模型中,socket通常被用在应用层和传输层(提供端口号和ip地址)之间,如下
Socket建立连接过程如图:
那么我们如何判断是否建立了连接从而认定是否打开相应端口呢?
s.connect_ex():connect()函数的扩展版本,出错时返回出错码,而不是抛出异常,正常时返回0。
不能成功连接也有可能因为防火墙或者数据包被过滤等原因
(更多python socket方法参见(W3Cschool):点击打开链接)
代码如下:
#coding=utf-8
import socket
#creat a socket
TCP_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #定义socket的协议及类型,具体参数可google
TCP_sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEPORT,1) #端口可复用
TCP_sock.settimeout(5) #规定超时
port_number = '80'
try:
result = TCP_sock.connect_ex(('111.13.101.208',81))
if result == 0:
print '%s OPEN'%port_number
else:
print port_number,'CLOSE'
TCP_sock.close()
except socket.error as e:
print port_number,'CLOSE'
pass
基于此原理,我们就可以用各种姿势来扫描端口了,使用多线程......
使用多线程扫描主机的所有端口
开始想的比较简单,想要简单粗暴的建立65536个子线程进行扫描,忘记了线程数限制这个问题,现在结果是........sublime崩溃了.......emmmmmmmmm
重新整理一下思路,使用队列queue库这个思路,同时自定义线程数,从队列中进行取数。
先把代码贴出来吧:
#coding=utf-8
import socket
import threading
import Queue
import sys
class DoRun(threading.Thread):
def __init__(self,queue):
threading.Thread.__init__(self)
self._queue = queue
def run(self): #重写run方法
while not self._queue.empty():
key = self._queue.get()
PortScan('111.13.101.208',key,1)
def PortScan(ipaddr,port_number,delay):
#creat a socket
TCP_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
TCP_sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEPORT,1)
TCP_sock.settimeout(delay)
try:
result = TCP_sock.connect_ex((ipaddr,int(port_number)))
if result == 0:
sys.stdout.write('%s OPEN\n'%port_number)
else:
sys.stdout.write('%s CLOSE\n'%port_number)
TCP_sock.close()
except socket.error as e:
sys.stdout.write('%s CLOSE\n'%port_number)
#
def main():
threads = []
threads_count = 100 #定义线程数
queue = Queue.Queue()
for i in range(0,1000):
queue.put(i)
for i in range(threads_count):
threads.append(DoRun(queue))
for i in threads:
i.start()
for i in threads:
i.join()
if __name__ == '__main__':
main()
记一下要复习的知识点:重写run方法,Queue队列的使用
-等待编辑