【Try to Hack】masscan

举报
开心星人 发表于 2022/06/28 21:34:58 2022/06/28
【摘要】 📒博客主页:开心星人的博客主页🔥系列专栏:Try to Hack🎉欢迎关注🔎点赞👍收藏⭐️留言📝📆首发时间:🌴2022年6月23日🌴🍭作者水平很有限,如果发现错误,还望告知,感谢!文章内容均来自互联网,仅作为自己学习的使用@toc 🍫masscan简述masscan号称是世界上最快的扫描软件,可以在3分钟内扫描整个互联网端口,但是这个是由条件的4核电脑,双端口10G网卡...

📒博客主页:开心星人的博客主页
🔥系列专栏:Try to Hack
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📆首发时间:🌴2022年6月23日🌴
🍭作者水平很有限,如果发现错误,还望告知,感谢!

文章内容均来自互联网,仅作为自己学习的使用

@toc

🍫masscan简述

masscan号称是世界上最快的扫描软件,可以在3分钟内扫描整个互联网端口,但是这个是由条件的4核电脑,双端口10G网卡。
扫描整个Imternet的权限归国防部所有,不要轻易扫描互联网。
masscan 0.0.0.0/0 -p0-65535 扫描全网

🍫为什么masscan比nmap快很多

采用了异步传输、无状态扫描方式(异步传输意味着扫描器在发送探测数据包之后不必等待回复)。

nmap需要记录tcp/ip的状态,而OS能处理的tcp/ip的最大链接数只有1500左右;masscan采用的是不建立完整的tcp链接方式,在收到SYN/ACK之后,直接发送RST结束链接(RST表示复位,用来结束关闭异常的链接)。 附:--banner除外

🍫常用参数

1、快速扫描,默认情况下,Masscan扫描速度为每秒100个数据包,这是相当慢的。为了增加这一点,只需提供该--rate选项并指定一个值。

扫描100个常见端口的B类子网,每秒2000个数据包
masscan 192.168.0.0/16 --top-ports 100 --rate 2000

2、扫描结果保存
-oX test.xml
-oJ test.json
-oL test.list

masscan 192.168.0.0/16 -p80 -oX test.xml

3、获取banner信息,支持少量的协议
--banners

4、指定和排除目标

--exclude <ip/range> IP地址范围黑名单,防止masscan扫描
--excludefile <filename> 指定IP地址范围黑名单文件
--includefile,-iL <filename> 读取一个范围列表进行扫描
--adapter-ip 指定发包的ip地址
--adapter-port指定发包源端口
--adapter-mac指定发包的源MAC地址
--router-mac指定网关MAC地址
--wait指定发包后的等待时间

masscan -p 0-65535 -iL test.txt --rate=2000

扫描全网,可以通过设置黑名单来让扫描器扫描时忽略一些网段。
masscan 0.0.0.0/0 -p0-65535 --excludefile exclude.txt -oJ res.json --max-rate 100000

5、主机存活扫描
--ping
masscan –-ping 192.168.88.132/24 --rate 1000

🍫nmap和masscan配合使用

先使用masscan快速的扫描端口后,masscan扫描完后会生成一个json文件,然后从中提取相关端口信息。再用nmap进行详细扫描,识别端口对应的服务。

github地址

# -*- coding: utf-8 -*-
#  首先运行2或3个并发的Masscan任务,所有的65535个端口分为4-5个更小的范围;
#  获取主机列表以及Masscan扫描出的开放端口的组合列表;
#  使用这些列表作为Nmap的扫描目标并执行常规Nmap扫描。

import subprocess
#  import pysnooper
import threading
import os
import nmap
import argparse
import re
import json
from IPy import IP

iolock = threading.Lock()
class Task:
    def __init__(self,ip,ports_list):
         self.ip=ip
         ports_list.sort()
         self.ports=','.join([str(x) for x in ports_list])

class Mas_Scanner(threading.Thread):  
    def __init__(self,task_list):
        threading.Thread.__init__(self)
        self.task_list=task_list
        self.result={}
    
    #  @pysnooper.snoop()
    def analyze(self,data,ip):#analyze and add task scan result to scanner result
        ports_list=[]
        for line in data.split('\n'):
            if line!='':
                port = line.split()[3] # xx/tcp
                port = port.split('/')[0] 
                ports_list.append(port)

        if ip in self.result:
            self.result[ip]=self.result[ip]+ports_list
        else:
            self.result[ip]=ports_list

        if ports_list !=[]:
            iolock.acquire()
            print('find ports on host:',ip,':')
            print(ports_list)
            iolock.release()

    #  @pysnooper.snoop()
    def start_task(self,task): #one task scan only one ip with different ports
        iolock.acquire()
        print("masscan scanning ip:",task.ip)
        iolock.release()
        cmd = 'masscan {ip} -p{ports} --wait 0 --rate 1500'.format(ip=task.ip,ports=task.ports)
        proc = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        proc.wait()
        stdoutdata=proc.stdout.read().decode('UTF-8')
        stderrdata = proc.stderr.read().decode('UTF-8')
        #  print(stdoutdata)
        self.analyze(stdoutdata,task.ip)
    
    def run(self):
        for task in self.task_list:
            self.start_task(task)
        # p = subprocessPopen(cmd,)

# for namp scanner, a task inlude one ip with its all ports
class Nmap_Scanner:
    def __init__(self,task_list):
        self.task_list = task_list
        self.result={}


    def start_task(self,task):
        print('start determine service/version of ports on host:',task.ip)
        nm = nmap.PortScanner()
        nm.scan(hosts=task.ip,ports=task.ports,arguments='-T4 -sV -Pn -sS',sudo=True)
        #  if task.ip in nm:
        self.result[task.ip]=nm[task.ip]
        #  else:
            #  self.result[task.ip]=None

    def print_scan_result(self):
        for ip in self.result:
            print('----------------------------------------------------')
            print('Host : {}'.format(ip))
            print('--------------------')
            ports_dict = sorted(self.result[ip]['tcp'])
            for port in ports_dict:
                portinfo=self.result[ip]['tcp'][port]
                str_buffer = 'port : {port}\tstate : {state}\t{name} {product} {version}'.format(port=port,
                                                                                               state=portinfo['state'],
                                                                                               name=portinfo['name'],
                                                                                               product=portinfo['product'],
                                                                                               version=portinfo['version'])
                print(str_buffer)
    def output_file(self,filename):
        json_data = {}
        for ip in self.result:
            ports_dict = sorted(self.result[ip]['tcp'])
            json_data[ip]={}
            for port in ports_dict:
                portinfo=self.result[ip]['tcp'][port]
                json_data[ip][port] = {
                    'state':portinfo['state'],
                   'name':portinfo['name'],
                   'product':portinfo['product'],
                   'version':portinfo['version']
                   }
        with open(filename, 'w') as f:
            json.dump(json_data, f)

    def run(self):
        for task in self.task_list:
            self.start_task(task)

# @pysnooper.snoop()
def split_task(ip): #split ports range in 5 pieces and return a list
    if not re.match(r'\d+\.\d+\.\d+.\d+', ip):
        raise Exception("Invalid IP format: '"+ip+"'")
    ports_list = [str(x) for x in range(1,65536)]
    n = int(65535/5)
    task_list = []
    for x in range(5):
        list_ = ports_list[n*x:n*x+n]
        task = Task(ip,list_)
        task_list.append(task)
    
    return task_list

    




#  @pysnooper.snoop()
def main():
    if os.getuid() != 0:
        print('please run this script with root!')
        exit()


    parser = argparse.ArgumentParser()
    parser.add_argument('host',nargs='?',help='read ip from a file',default=None)
    parser.add_argument('-r','--input',help='read ip from a file')
    parser.add_argument('-c','--cidr',help='scan a range of ip')
    parser.add_argument('-o','--output',help='output filename')
    args = parser.parse_args()
    task_list=[]
    if args.host != None:
        task_list += split_task(args.host)
    if args.input != None:
        f = open(args.input,'r')
        for line in f:
            task_list += split_task(line.replace('\n','').replace('\r',''))
        f.close()
    if args.cidr != None:
        for ip in IP(args.cidr):
            task_list += split_task(ip)

    if task_list==[]:
        print('Please input at least one target!')
        exit()

    masscaner_num = 2
    task_per_scanner = int(len(task_list)/masscaner_num)
    masscanner_list = []

    for x in range(masscaner_num):
        scanner = Mas_Scanner(task_list[x*task_per_scanner:x*task_per_scanner+task_per_scanner])
        masscanner_list.append(scanner)
        scanner.start()

    for scanner in masscanner_list:
        scanner.join()
        
    
    masscan_result = {}
    for scanner in masscanner_list:
        for ip in scanner.result:
            if ip not in masscan_result:
                masscan_result[ip]=scanner.result[ip]
            else:
                masscan_result[ip]+=scanner.result[ip]

    print('masscan scan complete:')
    print(masscan_result)
    nmap_task_list = []
    for ip in masscan_result:
        if len(masscan_result[ip])!=0:
            nmap_task_list.append(Task(ip,masscan_result[ip]))

    nm_scanner = Nmap_Scanner(nmap_task_list)
    nm_scanner.run()
    nm_scanner.print_scan_result()
    if args.output !=None:
        nm_scanner.output_file(args.output)


if __name__=='__main__':
    main()
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。