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. Mysql Binlog日志详解

    一.Mysql Binlog格式介绍       Mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW! 1.Statement:每一条会修改数据的sql都会记录在 ...

  2. SCOI2015酱油记

    Orz怒跪ns高一进A队,常规还是年级rank1,把gerw都下了一跳. Day1还是拿了点分的,调了半天T3终于调出来了(果然xlk大神可信),加上T1暴力有120(跟爆蛋有什么区别).T1大概有2 ...

  3. android使用bintray发布aar到jcenter

    前言 这两天心血来潮突然想把自己的android library的aar放到jcenter里面,这样一来自己便可以在任何时间任何地点通过internet得到自己的library的引用了,况且现在and ...

  4. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

  5. [疑惑与解答] WxPython In Action -1

    在学<活学活用wxPython>第三章的时候,我遇到一点疑惑,那就是下面语句的区别是什么 例 3.1 第4,5行: panel = wx.Panel(self, -1) button = ...

  6. PHP安全编程:会话数据注入 比会话劫持更强大的攻击(转)

    一个与会话暴露类似的问题是会话注入.此类攻击是基于你的WEB服务器除了对会话存储目录有读取权限外,还有写入权限.因此,存在着编写一段允许其他用户添加,编辑或删除会话的脚本的可能.下例显示了一个允许用户 ...

  7. java.lang.Math中的基本方法

    java.lang.Math类提供的方法都是static的,“静态引入 ”使得不必每次在调用类方法时都在方法前写上类名:             import static java.lang.Mat ...

  8. Android(java)学习笔记240:多媒体之图形颜色的变化

    1.相信大家都用过美图秀秀中如下的功能,调整颜色: 2. 下面通过案例说明Android中如何调色: 颜色矩阵 ColorMatrix cm = new ColorMatrix(); paint.se ...

  9. Redis的AOF功能

    引言:  Redis是基于内存的数据库,同时也提供了若干持久化的方案,允许用户把内存中的数据,写入本地文件系统,以备下次重启或者当机之后继续使用.本文将描述如何基于Redis来设置AOF功能 什么是R ...

  10. codevs 1282 约瑟夫问题(线段树)

    #include<iostream> #include<cstdio> #include<cstring> #define maxn 30010 using nam ...