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. java 基础(匿名内部类)

    匿名内部类 特点:不对外公开,进行实现功能,继承类,继承抽象类,实现某个接口的匿名内部类,实现相应的方法 特别注意:匿名内部类,匿名指的是 ,new 关键字右边的那个对象--如继承,或是接口    { ...

  2. Django admin进阶

    1. ModelAdmin.inlines 将有外键的子类包含进视图 ,实例: class Author(models.Model): name = models.CharField(max_leng ...

  3. Demo_玩家移动(主要注意动画的设置)

    using UnityEngine; using System.Collections; public class NewPlayerMove : MonoBehaviour { private fl ...

  4. [转]【基于zxing的编解码实战】精简Barcode Scanner篇

    通过<[搞定条形码]zxing项目源码解读(2.3.0版本,Android部分)>的分析,现在可以实现最终目标了:精简Barcode Scanner并将其中的编码和解码分离为两个独立的部分 ...

  5. Sql Server 2005 开发版亲測可用下载地址

    sqlserver2005开发版下载地址:http://222.132.81.146/rj/cs_sql_2005_dev_all_dvd.rar建议使用迅雷下载. sql server 2005 开 ...

  6. Android网络框架---OkHttp3

    1.添加依赖 compile 'com.squareup.okhttp3:okhttp:3.4.2' project Structure-->dependencied/搜索okhttp. com ...

  7. 在Ubuntu上下载、编译和安装Android最新源码

    看完了前面说的几本书之后,对Linux Kernel和Android有一定的认识了,是不是心里蠢蠢欲动,想小试牛刀自己编译一把Android源码了呢?一直习惯使用Windows系统,而Android源 ...

  8. 计数dp-hdu-4054-Number String

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4055 题目大意: 给一个只含‘I','D','?'三种字符的字符串,I表示当前数字大于前面的数字,D ...

  9. 三星笔记本R428安装xp win7双系统,切换系统重启才能进入系统解决办法。

    三星笔记本 XP win7 双系统切换重启解决方法 三星笔记本有个奇怪的现象,就是装有XP和win7双系统    xp切换到win7.进系统是会重启一次,并且bios回复光驱为第一启动项,win7切换 ...

  10. [转] Java中的容器

    在书写程序的时候,我们常常需要对大量的对象引用进行管理.为了实现有效的归类管理,我们常常将同类的引用放置在同一数据容器中. 由于数据容器中存放了我们随时可能需要使用到的对象引用,所以一般的数据容器要都 ...