zoukankan      html  css  js  c++  java
  • 主机漏洞扫描告警与nmap指纹

    和URL扫描的QPS太高把业务告警打挂相匹配的情况:HOST主机漏洞扫描遇到碰瓷的端口服务。

    扫描器经常会遇到内网中的某些端口开放的服务,不接收特定格式外的数据,一收到就会报错甚至挂掉,也不用写poc,浏览器贴上 http://ip: 端口直接导致服务报错。形如碰瓷一般,躺在内网中。
    一般的说法是,这一块属于业务或者框架方负责,需要做数据校验,校验到不合规的数据,不进行处理抛弃。
    但是在报错的处理上,有的业务可以选择直接忽视掉,比如flume某开源服务,发送如http的数据会直接报错,但报错是dba自己接收,可以选择不要,所以直接捕获不抛出就好了。但是作为服务框架,会据理力争报错不能直接丢弃,使用该服务框架的业务也可能传入不正确的数据,业务正常需求上需要报错。
    所以在与某中台框架服务商讨后,采用了另一个方案:
    框架上设置指纹功能,当发送特定数据的时候,返回特定指纹。

    扫描器需要做的:
    1.采用nmap端口扫描的时候,建立起连接后发送的框架指纹检测数据包应该是最高优先级的,也就是最早发的。
    2.端口扫描识别到框架后,该端口在正常流程中不进入扫描,不传递给插件,除非插件选择了二级指纹或其他的配资,需要对该框架进行检测。

    第二点比较好实现,下面探讨的是第一点的实现方式:采用nmap指纹或端口扫描插件中做处理

    (半年一年前采用nmap指纹来做,最近在业务反馈后,花了一天的时间改了端口扫描的代码,更稳定可控。也不是说Nmap本身改探针不好,反复测是第一发包检测出业务的端口,就不会发其他探针了,但-sV偶尔抽一下,发了点别的包,业务拿着报错来找又没法复现,挺打脸的..)

    Nmap服务探测 (探针优先级)  https://www.cnblogs.com/rab3it/articles/12020756.html

    0X01 nmap指纹编写

    指纹探针的编写这里写的挺好挺全的,再抄一遍没什么意义
    https://www.cnblogs.com/liun1994/p/6986544.html

    顺序上,探针的发送顺序是
    NULL -> 端口匹配上的探针 -> 端口不匹配的或者没有ports的探针
    且nmap只发送 rarity 重要级别在设置以下的探针(级别越低越重要)
    tips: ports不匹配也会进行扫描
    所以要想探针在最开始的时候被发送,ports 匹配1-65535,否则还会被端口匹配的探针抢在前面。

    这一段放在NULL前(其实NULL的下一个也一样,尽量靠前)

    vi /usr/share/nmap/nmap-service-probes
    
    
    ##############################MYSELF my_server NEXT PROBE##############################
    
    Probe TCP MYServer q|x12x11
    	|
    rarity 1
    ports 1-65535
    
    match my_server m|x00x00i| p/my_server/
    
    ##############################NEXT PROBE##############################
    

    缺点
    a) 本身不稳定,可能收到预期外的数据包导致业务方程序报错
    b) 每一个节点都需要保证nmap的nmap-service-probes是正确的
    优点
    a) 用nmap本身的指纹,高端优雅

    0x02 python nmap插件中略过服务方指纹

    只有加上-sV在,在扫描指纹的情况下,才会发送数据。
    所以可以先扫描出存活的端口,筛选出非业务服务的端口,-sV扫描其他端口的指纹,不会对业务方的脆弱碰瓷端口发送预期外的数据。

    缺点:比较麻烦
    优点:稳定易控易修改

    import nmap
    import time
    
    
    def check_server_port(target, port):
        # 业务端口返回True
        # 非业务端口正常返回False
        return False
    
    
    def scan_port(target):
        portlist_info = dict()
        start = time.time()
    
        nmap_arguments = '-Pn -sT -max-scan-delay 5 -max-retries 2 -T4 -n --host-timeout 1200 --min-parallelism 100'
        connect_argument = nmap_arguments + " -p 1-65535"
        scanner = nmap.PortScanner()
        scanner.scan(target, arguments=connect_argument)
        if scanner[target].get('tcp'):
            # 扫描存活
            for port in scanner[target]['tcp']:
                if scanner[target].state() == 'up' and scanner[target]['tcp'] and 
                        scanner[target]['tcp'][int(port)]['state'] == 'open':
                    portlist_info[port] = ""
            print(time.time() - start)
            # SCF检测,不扫描指纹
            service_port = list(portlist_info.keys())
            for port in service_port:
                if check_server_port(target, port):
                    portlist_info[port] = "my_server"
                    service_port.remove(port)
            service_port_str = ",".join([str(port) for port in service_port])
            # 扫描指纹
            version_argument = nmap_arguments + " -p %s -sV" % service_port_str
            scanner.scan(target, arguments=version_argument)
            if scanner[target].get('tcp'):
                for port in scanner[target]['tcp']:
                    if scanner[target].state() == 'up' and scanner[target]['tcp'] and 
                            scanner[target]['tcp'][int(port)]['state'] == 'open':
                        product = scanner[target]['tcp'][int(port)]['product']
                        portlist_info[port] = product
        end = time.time()
        print(end-start)
        return portlist_info
    
    
    if __name__ == '__main__':
        print(scan_port("127.0.0.1"))
    
    
  • 相关阅读:
    web工程导入新环境的注意事项
    Mysql group by,order by,dinstict优化
    Dijkstra and Floyd算法
    百度面试题
    腾讯面试题
    百度笔试3
    百度笔试2
    百度笔试1
    百度2011实习生招聘笔试题
    百度2011.10.16校园招聘会笔试题
  • 原文地址:https://www.cnblogs.com/huim/p/13090662.html
Copyright © 2011-2022 走看看