欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python 实现简单的端口扫描器

程序员文章站 2022-05-15 22:09:52
...

这个任务从去年末师傅布置下来一直拖到现在,(惭愧到不行

现在边写边在这里记录遇到的问题~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

实现对特定 (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地址)之间,如下

                                           Python 实现简单的端口扫描器

        Socket建立连接过程如图:

                                              Python 实现简单的端口扫描器

                   
        可以看到客户端想要与服务器建立连接,必须先由s.bind()绑定ip和端口号,并且开始由s.accept()监听端口,此时已经打开了所绑定的端口。如果服务器端口已打开,c.connect()就会正常建立连接。

        那么我们如何判断是否建立了连接从而认定是否打开相应端口呢?    

                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队列的使用

        -等待编辑



上一篇: TCP端口扫描

下一篇: mergeheap