0x 00 Before Coding

  当端口打开时,向端口发送 TCP SYN 请求,会返回一个 ACK 响应:

  

  当端口关闭,返回的是 RST 响应:

  

  0x 01 Coding 

  可以用 socket 编写一个小脚本来测试主机端口的开启情况,基本代码如下:

  

 # coding: utf-8

 import socket
from datetime import datetime # Set time-out to get the scanning fast
socket.setdefaulttimeout(0.5) # Ask for input
remote_server = raw_input("Enter a remote host to scan:")
remote_server_ip = socket.gethostbyname(remote_server) # Print a nice banner with info on which host we are about to scan
print '-' * 60
print 'Please wait, scanning remote host ', remote_server_ip
print '-' * 60 # Check what time the scan started
t1 = datetime.now() # Using the range function to specify ports(1 - 1024)
# We also put in some error handling for catching errors
try:
for port in range(1,1025):
sock = socket.socket(2,1) # 2:socket.AF_INET 1:socket.SOCK_STREAM
res = sock.connect_ex((remote_server_ip,port))
if res == 0:
print 'Port {}: OPEN'.format(port)
sock.close() except socket.gaierror:
print 'Hostname could not be resolved.Exiting' except socket.error:
print "Could't connect to the server" # Check the time now
t2 = datetime.now() # Calculates the difference of time
total = t2 - t1 # Print the info to screen
print 'Scanning Completed in: ', total

  参考:http://www.pythonforbeginners.com/code-snippets-source-code/port-scanner-in-python/

  程序测试结果如下:

  

  看出来 在 socket 的超时时间设置为0.5的前提下 依然需要花费 8分27秒才能够把周知端口号扫完,有没有其他方式加快扫描速度?答案是有的。

  //////////////////// ******************** 该部分可以略过,一个小坑 ************************ ////////////////////

  打开 抓到的数据包列表,发现 timeout 包都会发送2个“伪重传”,发送这两个一般没什么用的数据包会占用 CPU的处理时间,

  所以在想能不能不让程序发这两个包来提高效率??

  自己分析连续两个端口的时间间隔就会发现:间隔是0.5s(由 39号、46号、53号数据包分析得出),这恰好是在程序中设置的超时时间,

  也就是说超时重传的包并不会占用专门的时间,所以这种想法就被干掉了。

  这样的话,1个端口0.5的超时等待,扫描一个主机的 1- 1024 号端口所用时间是可以大致估算下的:

  1024 * 0.5 / 60 = 8.53 分钟左右。和上面程序实际扫描的时间(8分27秒)相符合。

  //////////////////// ******************** 坑结束  ************************ ////////////////////

  0x 02 Better Coding 

  所以对于这种时间主要花费在 socket 连接( 非 CPU 计算密集型 )的程序 可以使用 多线程来提升效率,

  这里选择使用内建的库 multiprocessing.dummy 来实现多线程扫描:

# coding: utf-8
'''
  多线程 Socket TCP 端口扫描器 by: EvilCLAY
'''
import socket
from datetime import datetime
from multiprocessing.dummy import Pool as ThreadPool remote_server = raw_input("Enter a remote host to scan:")
remote_server_ip = socket.gethostbyname(remote_server)
ports = [] print '-' * 60
print 'Please wait, scanning remote host ', remote_server_ip
print '-' * 60 socket.setdefaulttimeout(0.5) def scan_port(port):
try:
s = socket.socket(2,1)
res = s.connect_ex((remote_server_ip,port))
if res == 0: # 如果端口开启 发送 hello 获取banner
print 'Port {}: OPEN'.format(port)
s.close()
except Exception,e:
print str(e.message) for i in range(1,1025):
ports.append(i) # Check what time the scan started
t1 = datetime.now() pool = ThreadPool(processes = 8)
results = pool.map(scan_port,ports)
pool.close()
pool.join() print 'Multiprocess Scanning Completed in ', datetime.now() - t1

  扫描的结果如下:

  

  可以发现 8 个线程并行发起请求,效率有很大的提升。

  在被扫描主机未安装连接限制软件的前提下,测试了开启不同线程扫描所花费的时间 :

  16 个线程 使用 32 秒扫完;
  32个线程,使用 16 秒扫完;
  64个线程,使用 8 秒扫完;
  128个线程,使用 4 秒扫完;
  256个线程,使用 2 秒扫完;
  512个线程,使用 1.50 秒扫完;
  1024个线程,使用 1.25 秒扫完;   获取 Banner
  把 函数修改成如下 即可:
def scan_port(port):
try:
s = socket.socket(2,1)
res = s.connect_ex((remote_server_ip,port))
if res == 0: # 如果端口开启 发送 hello 获取banner try:
s.send('hello')
banner = s.recv(1024) except Exception,e:
print 'Port {}: OPEN'.format(port)
print str(e.message)
else:
print 'Port {}: OPEN'.format(port)
print 'Banner {}'.format(banner) s.close()
except Exception,e:
print str(e.message)

  晚上研究下 Zmap 与 ZGrab 分析下  这两款神器牛在什么地方 ~~

 

『Python』 多线程 端口扫描器的更多相关文章

  1. 『Python』 多线程 共享变量的实现

    简介: 对于Python2而言,对于一个全局变量,你的函数里如果只使用到了它的值,而没有对其赋值(指a = XXX这种写法)的话,就不需要声明global. 相反,如果你对其赋了值的话,那么你就需要声 ...

  2. 再议perl写多线程端口扫描器

    再议perl写多线程端口扫描器 http://blog.csdn.net/sx1989827/article/details/4642179 perl写端口多线程扫描器 http://blog.csd ...

  3. Python脚本写端口扫描器(socket,python-nmap)

    目录 Socket模块编写 扫描给定主机是否开放了指定的端口 python-nmap模块编写 扫描给定ip或给定网段内指定端口是否开放 一个用python写的简单的端口扫描器,python环境为 3. ...

  4. 『Python』__getattr__()特殊方法

    self的认识 & __getattr__()特殊方法 将字典调用方式改为通过属性查询的一个小class, class Dict(dict): def __init__(self, **kw) ...

  5. 『Python』 ThreadPool 线程池模板

    Python 的 简单多线程实现 用 dummy 模块 一句话就可以搞定,但需要对线程,队列做进一步的操作,最好自己写个线程池类来实现. Code: # coding:utf-8 # version: ...

  6. 『Python』多进程处理

    尝试学习python的多进程模组,对比多线程,大概的区别在: 1.多进程的处理速度更快 2.多进程的各个子进程之间交换数据很不方便 多进程调用方式 进程基本使用multicore() 进程池优化进程的 ...

  7. 『Python』多进程

    Python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在Python中大部分情况需要使用多进程.Python提供了multiprocessin ...

  8. 『Python』 爬取 WooYun 论坛所有漏洞条目的相关信息

    每个漏洞条目包含: 乌云ID,漏洞标题,漏洞所属厂商,白帽子,漏洞类型,厂商或平台给的Rank值 主要是做数据分析使用:可以分析某厂商的各类型漏洞的统计:或者对白帽子的能力进行分析..... 数据更新 ...

  9. 『Python』Python 调用 ZoomEye API 批量获取目标网站IP

    #### 20160712 更新 原API的访问方式是以 HTTP 的方式访问的,根据官网最新文档,现在已经修改成 HTTPS 方式,测试可以正常使用API了. 0x 00 前言 ZoomEye 的 ...

随机推荐

  1. C - How Many Tables - HDU-1213

    某个人举办生日宴会邀请了很多人来参加,不过呢,这些人有个毛病他们只会与熟悉人的坐在一起,当然他们也信奉朋友的朋友也是朋友这一法则,所以问最少需要多少张桌子...... 好吧我承认这才是裸并查集.... ...

  2. 使用jquery trigger 触发a标签的click事件取代window.open方法

    var ohtml='<div class="friend-dialog tac pt15 pb20">'+ '<div class="f-h32&qu ...

  3. C++设计模式---职责链模式

    职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这个对象连成一条链,并沿这条链传递该请求,直到有一个对象处理它为止. 这里发出这个请求的客户端并不知道这当中的哪一 ...

  4. Fluent-EDEM耦合计算颗粒流动

    虽然说Fluent提供了很多方法用于处理颗粒在流体中的运动行为,然而这些方法都有其各自的适用性.DPM适用于稀薄颗粒的情况,欧拉模型.Mixture模型及DDPM模型虽然可以考虑稠密颗粒相,但并不能考 ...

  5. Excel导入数据库(三)——SqlBulkCopy

    上篇博客中介绍了批量导入数据库的方法:下面介绍一下批量导入过程的核心——SqlBulkCopy类. 下面先介绍一些原理性的东西:SQLBulkCopy类,通常用于数据库之间大批量的数据传递.即使表结构 ...

  6. POJ 2418 ,ZOJ 1899 Hardwood Species - from lanshui_Yang

    Description Hardwoods are the botanical group of trees that have broad leaves, produce a fruit or nu ...

  7. 【剑指Offer学习】【面试题43 : n 个锻子的点数】

    题目:把n个骰子扔在地上,全部骰子朝上一面的点数之和为s.输入n.打印出s 的全部可能的值出现的概率. 解题思路 解法一:基于通归求解,时间效率不够高. 先把n个骰子分为两堆:第一堆仅仅有一个.还有一 ...

  8. [转] TCP数据包重组实现分析

    PS: 这个实现对于某些特定情况未必是最佳实现,可以用数组来代替队列来实现 参照TCP/IP详解第二卷24~29章,详细论述了TCP协议的实现,大概总结一下TCP如何向应用层保证数据包的正确性.可靠性 ...

  9. MySQL存储过程(一)

    1.1 CREATE  PROCEDURE (创建) CREATE PROCEDURE存储过程名 (参数列表) BEGIN SQL语句代码块 END 注意: 由括号包围的参数列必须总是存在.如果没有参 ...

  10. 转:android 自定义RadioButton样式

    http://gundumw100.iteye.com/blog/1146527  上面这种3选1的效果如何做呢?用代码写? 其实有更简单的办法,忘了RadioButton有什么特性了吗? 我就用Ra ...