使用nmap扫描外租机开放的端口并识别

使用nmap扫描外租机开放的端口并识别

使用nmap扫描外租机开放的端口并识别 需要用到pubapi来写入数据库 不适用于所有环境,脚本只做技术储备

from requests.packages import urllib3
from BasicInterface import executeMysqlData
from base64 import b64encode
import json, time,re,requests,datetime
urllib3.disable_warnings()
#将cmdb的ip地址提交到gcp的nmap接口去扫描开放端口
def isPublicIpv4(ip):
    pattern = r'^(?:(?:(?:[1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}{?:[1-9]?\d|1\d\d|2[0-4]\d|25[θ-5]))$'
    private_pattern = r'^(?:(?:10|127)\.\d{1,3}\.\d{1,3}\.\d{1,3}|(?:172\.(?:1[6-9]|2\d|3[01]))\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}}$'
    return re.match(pattern,ip) is not None and re.match(private_pattern,ip) is None
    #只要7天内有扫过的 ip就不会再扫描了,所以这里抓出7天内有扫描过的
    ipqueryIPExist = "SELECT ip FROM ScanResult WHERE ScanTime >= CURDATE() - INTERVAL 6 DAY AND ScanTime <=CURDATE() GROUP BY ip;"
    resultQuery = executeMysqlData(1,'read',queryIPExist)
    resultList = []
    for q in resultQuery:
        for r in q:
            resultList.append(r)
            cookies = {'sso' : '<ssoKey>'}
            #脚本中的接口有多页,所以做了一个遍历,n为页面编号
n=1
ipListJson = {}
#本地手动添加的ip列表,如果有需要增加的,则按格式添加即可
ipList = ['<ipaddress>']
while 1:
    response = requests.get('<serverUrl>'%n, cookies= cookies , verify= False)
    status_code = response.status_code
    response = json.loads(response.text)
    if status_code != 404:
        for m in range (θ,len(response['result'])):
            name = response['result'][m]['name']
            ip = response['result'][m]['ip']
            user = response['result'][m]['user']
            app = response['result'][m]['app']
            #有些ip地址栏里写了乱七八糟的东西,所以为了确保获取到正确的 ip,所以限制了长度
            if isPublicIpv4(ip) == True and ip != '0.0.0.0' and ip != '1.1.1.1' and ip != 'N/a' and ip!='θ' and ip !' and ip !='127.0.0.1':
                ipListJson[name] = {}
                ipListJson[name]['ip'] = ip
                ipListJson[name]['user'] = user
                ipListJson[name]['app'] = app
            else:
                break
            n += 1
for i in ipList:
    ipListJson[i] = {}
    ipListJson[i]['ip'] = i
    ipListJson[i]['user'] = ''
    #外租机的 ip和端口,外租机上使用 flask开放了1080端口用来接收数据,只能接收文本 text格式的数据
    url='<serverurl>'
    #使用 for循环进行发送数据,每个 ip发送一次
    for j in ipListJson:
        currentDatetime = datetime.datetime.now()
        mysqlDateFormat = "'" + currentDatetime.strftime('%Y-%m-%d %H:%M:%S') + "'"
        ip = ipListJson[j]['ip']
        if ip.split('.')[-1] == '255':
            print (f'该ip地址{ip}无法进行扫描, 忽略。。。')
        else:
            if ip not in resultList:
                print (f'{ip}提交到接口进行扫描')
                n=θ
                while 1:
                    try:
                        if n != 3:
                            response = requests.post(url, data= ip, timeout=1800)
                            break
                        else:
                            print (f'重试{n}次失败, 跳过。。。。')
                            break
                    except:
                        n += 1
                        print (f'扫描失败, 正在进行第{n}次重试')
                        time.sleep(30)
                if ipListJson[j][' user'] is not None:
                    #这里有的时候会扫描失败,造成返回不了 json数据,所以 try一下,无法格式化的 ip默认扫描失败,跳过
                    if isinstance(ipListJson[j]['user'], str):
                        userStr = "'" + ipListJson[j]['user'] + "'"
                    elif isinstance(ipListJson[j]['user'],list):
                        userStr = "'" + ", ". join(ipListJson[j][' user']) + "'"
                    else:
                        print (ipListJson[j]['user'])
                else:
                    userStr = "'" + ' unknown' + "'"
                try:
                    scanResultJson = response.json()
                    for k in scanResultJson:
                        #有些 ip地址所有的端口都是关闭的,所以扫描的时候返回的 portstatus的 key是没有的导致出问题,所以 try一下,如果失败的就当作扫描失败,跳过
                        try:
                            portStr = scanResultJson[k]['portstatus']
                        except:
                            sql= f"""INSERT INTO ScanResult (ScanTime, ip, user) VALUES ({mysqlDateFormat},{"'" + k + "'"},{userStr})"""
                            print (f'no port scaned open, will insert into sql through {sql}')
                            executeMysqlData(1,'write', sql)
                            #使用 for循环进行行放的端口读取并写入到数据库,按端口进行存入
                        for l in scanResultJson[k]['portstatus']:
                            applicationStr = scanResultJson[k]['portstatus'][l]['application']
                            if applicationStr == '':
                                applicationStr = "'" + 'Unknown' + "'"
                            serviceStr = "'" + scanResultJson[k]['portstatus'][l]['service'] + "'"
                            sql= f"""INSERT INTO ScanResult (ScanTime, application, ip, name, openport, service, user) VALUES  〔{mysqlDateFormat},{applicationStr},{"'" + k + "'"},{"'" + j + "'"},{"'" + l + "'"},{serviceStr},{userStr})"""
                            executeMysqlData(1,'write', sql)
                except:
                    sql= f"""INSERT INTO ScanResult (ScanTime, ip, user) VALUES〔{mysqlDateFormat},{"'" + ip + "'"},{userStr})"""
                    executeMysqlData(1,'write', sql)
                    #这里使用 for循环去读取 json数据,将数据提取出来以后,再写入数据库
            else:
                print (fˈip:{ip}已经扫描完毕, 忽略。。。')