Python构造简单端口扫描程序
2018-01-03 09:37
676 查看
#-*- coding: UTF-8 -*- import optparse from socket import * from threading import * #由于线程同步导致扫描不同端口输出的次序会乱掉,因此设置一个信号量Semaphore,用来在输出时锁定线程,保证端口扫描输出依次打印 screenLock = Semaphore(value = 1) #定义一个信号量用于锁定线程 #用于连接指定的地址以及指定端口,建立连接发送信息,看是否有返回信息以确定端口是否开放 def connScan(tgtHost, tgtPort): try: ''' int socket(int domain, int type, int protocol); #参数domain用于设置网络通信的域 AF_INET,PF_INET IPv4 Internet协议 #参数type用于设置套接字通信的类型 SOCK_STREAM:Tcp连接,提供序列化的、可靠的、双向连接的字节流。支持带外数据传输 #参数protocol用于制定某个协议的特定类型 ''' connSkt = socket(AF_INET, SOCK_STREAM) #建立一个流式套接字 ''' int connect (int sockfd,struct sockaddr * serv_addr,int addrlen); connect函数通常用于客户端建立tcp连接。 参数sockfd:标识一个套接字。 参数serv_addr:套接字s想要连接的主机地址和端口号。 参数addrlen:name缓冲区的长度。 返回值:成功则返回0,失败返回-1,错误原因存于errno中。 ''' connSkt.connect((tgtHost, tgtPort)) #连接指定的地址和端口 ''' int send( SOCKET s,const char* buf,int len,int flags); 客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。 第一个参数指定发送端套接字描述符; 第二个参数指明一个存放应用程序要发送数据的缓冲区; 第三个参数指明实际要发送的数据的字节数; 第四个参数一般置0。 ''' connSkt.send('ViolentPython\r\n') #发送消息 ''' int recv(SOCKET s,char* buf,int len,int flags); 不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。 第一个参数指定接收端套接字描述符; 第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据; 第三个参数指明buf的长度; 第四个参数一般置0。 ''' results = connSkt.recv(100) #若端口开放,记录返回的消息 ''' 【信号量】用于控制对某资源访问的同一时间的并发量 semaphore.acquire(),没信号量可用时,将进行阻塞等 【如何释放】semaphore.release() ''' screenLock.acquire() #Lock锁定线程 print ('[+]%d/tcp open'% tgtPort) print ('[+] ' + str(results)) except: screenLock.acquire() print ('[-] %d/tcp closed'% tgtPort) finally: screenLock.release() #释放控制信号量 connSkt.close() #关闭 Socket 连接并释放所有关联的资源 #获取主机名,打印,调用connScan()进行扫描 def portScan(tgtHost,tgtPorts): try: tgtIP = gethostbyname(tgtHost) #返回的是 主机名 的IPv4 的地址格式 except: print ("[-] Cannot resolve '%s': Unknown host" %tgtHost) return try: tgtName = gethostbyaddr(tgtIP) #根据IP地址反向查找主机名称 print ('\n[+] Scan Results for:' + tgtName[0]) except: print ('\n[+] Scan Results for:' +tgtIP) setdefaulttimeout(1) #时间戳,通过socket模块的setdefaulttimeout函数来控制超时时间 for tgtPort in tgtPorts: ''' Thread是线程类,构造方法: Thread(group=None, target=None, name=None, args=(), kwargs={}) group: 线程组,目前还没有实现,库引用中提示必须是None; target: 要执行的方法; name: 线程名; args/kwargs: 要传入方法的参数。 ''' t = Thread(target = connScan, args=(tgtHost, int(tgtPort))) #创建线程,调用connScan() t.start() #启动线程 def main(): ''' MSG_USAGE = "myprog[ -f <filename>][-s <xyz>] arg1[,arg2..]" optParser = OptionParser(MSG_USAGE) 构造一个OptionParser的对象optParse,传入的值MSG_USAGE可被调用打印命令时显示出来 ''' parser = optparse.OptionParser("usage%prog"+"-H <target host> -p <target port>") ''' 调用OptionParser.add_option()添加选项 add_option()参数说明: action:存储方式,分为三种store、store_false、store_true type:类型 dest:存储的变量 default:默认值 help:帮助信息 ''' parser.add_option('-H', dest = 'tgtHost', type = 'string', help = 'specify target host') parser.add_option('-p', dest = 'tgtPort', type = 'string', help = 'specify target port[s] separated by comma') ''' 调用OptionParser.parse_args()剖析并返回一个directory和一个list options为是一个directory,它的内容fakeArgs为“参数/值 ”的键值对。 args 是一个list,它的内容是parser除去options后,剩余的输入内容。 ''' (options,args) = parser.parse_args() tgtHost = options.tgtHost #获取主机名 tgtPorts = str(options.tgtPort).split(',') #获取端口列表,端口间用逗号分隔 if(tgtHost == None) | (tgtPorts[0] == None): print (parser.usage) exit(0) portScan(tgtHost, tgtPorts) if __name__ == '__main__': main()
相关文章推荐
- 用Python写的一个简单的端口扫描程序
- Python端口扫描简单程序
- Python端口扫描简单程序
- 一个简单的端口扫描程序题
- PYTHON端口扫描小程序
- 一个简单的端口扫描程序
- 一个简单的端口扫描程序
- Python小练习-实现简单端口扫描~
- 基于Python socket的端口扫描程序实例代码
- 一个简单的端口扫描程序
- python扫描端口小程序
- Python之端口扫描程序
- 一个简单的端口扫描程序
- Python端口扫描程序原理解析
- linux c 简单端口扫描程序
- 通过编写一个简单的漏洞扫描程序学习Python基本语句
- 如何编写简单的端口扫描程序:
- python多线程端口扫描程序
- 基于Python socket的端口扫描程序
- C#网络编程 (五) 简单端口扫描程序