淺談端口滲透那些事

前期準(zhǔn)備


通過掃描端口快速發(fā)現(xiàn)目標(biāo)薄弱點,在這之前饲嗽,我們得準(zhǔn)備好端口掃描工具炭玫。
我接觸的掃描工具也不多,常用的端口掃描工具有:

nmap+masscan貌虾、御劍端口掃描工具2020

御劍端口掃描似乎不會顯示協(xié)議吞加,僅憑端口號判斷不夠精準(zhǔn),這時我們可以再用nmap的-sV識別具體服務(wù)尽狠。該工具主要用于快速掃描發(fā)現(xiàn)

在挖掘SRC的過程中衔憨,往往需要對整個C段進(jìn)行端口掃描,這時我們對掃描速度的要求沒那么高袄膏,可以追求更高的精確度践图。我們可以結(jié)合masscan的掃描速度和nmap的端口識別功能寫一個腳本,采用同步多線程沉馆,線程數(shù)默認(rèn)為5码党,masscan掃描速度默認(rèn)為100(可自行調(diào)整),我個人覺得速度100就基本不會出現(xiàn)遺漏的端口斥黑,速度越快越容易遺漏揖盘,我自己寫了個demo,大佬輕噴:

# -*- coding: UTF-8 -*-
import queue
import nmap
import datetime
import threading
import json
import os
import urllib3
import subprocess
import sys
import click

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

lock = threading.Lock()
final_domains = set()
insert = set()
ports = []
bad_ips = []


class PortScan(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self._queue = queue
    
    def run(self):
        while not self._queue.empty():
            scan_ip = self._queue.get()
            try:
                portscan(scan_ip)
            except Exception as e:
                print('run:', str(e))
                pass


# 調(diào)用masscan
def portscan(scan_ip):
    global count
    temp_ports = []  # 設(shè)定一個臨時端口列表
    name = scan_ip + '.json'
    command = 'masscan.exe ' + scan_ip +' -p21,22,23,25,53,67,68,80,81,82,83,84,85,86,87,88,89,110,139,143,161,300,' \
        '389,443,445,465,512,513,514,591,593,832,837,873,888,901,981,993,1010,1080,1100,1241,1311,1352,1433,1434,' \
        '1521,1527,1582,1583,1723,1944,2049,2082,2082,2086,2087,2095,2096,2181,2222,2301,2375,2480,3000,3128,3306,' \
        '3333,3389,4000,4001,4002,4100,4125,4243,4443,4444,4567,4711,4712,4848,4849,4993,5000,5104,5108,5432,5555,' \
        '5632,5800,5801,5802,5900,5901,5984,5985,5986,6082,6225,6346,6347,6379,6443,6480,6543,6789,6984,7000,7001,' \
        '7002,7396,7474,7674,7675,7777,7778,8000,8001,8002,8003,8004,8005,8006,8008,8009,8010,8014,8042,8069,8075,' \
        '8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8095,8016,8118,8123,8161,8172,8181,' \
        '8200,8222,8243,8280,8281,8333,8384,8403,8443,8500,8530,8531,8800,8806,8834,8880,8881,8887,8888,8910,8983,' \
        '8989,8990,8991,9000,9043,9060,9080,9090,9091,9200,9294,9295,9300,9443,9444,9800,9981,9988,9990,9999,10000,' \
        '10880,11211,11371,12043,12046,12443,15672,16225,16080,18091,18092,20000,20720,24465,27017,27018,28017,28080,' \
        '30821,43110,50070,61600 -oJ ' + name + ' --rate 100'
    child = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
    child.wait()  # 等待任務(wù)完成
    # 提取json文件中的端口
    if os.path.exists(name):
        with open(name, 'r') as f:
            for line in f:
                if line.startswith('{ '):
                    temp = json.loads(line[:-2])
                    temp1 = temp["ports"][0]
                    temp_ports.append(str(temp1["port"]))
    else:
        print('文件不存在')
        sys.exit()
    if len(temp_ports) > 40:
        count += 1
        print(scan_ip + ' 疑似存在waf')
        bad_ips.append(scan_ip)
        temp_ports.clear()  # 如果端口數(shù)量大于40锌奴,說明可能存在防火墻兽狭,屬于誤報,清空列表
    else:
        ports.append(temp_ports)  # 小于40則放到總端口列表里
        ips[scan_ip] = temp_ports
        if os.path.exists(name):
            os.remove(name)
            print('file detele')
        if ips.get(scan_ip):
            Scan(scan_ip)


# 調(diào)用nmap識別服務(wù)
def Scan(scan_ip):
    global count
    open_ports_list = ips[scan_ip]
    open_ports = ",".join(open_ports_list)
    nm = nmap.PortScanner()
    lock.acquire()
    click.secho(f'[*] 開始nmap掃描 ip: {scan_ip} => 端口: {open_ports}', fg='red')
    count += 1
    print('當(dāng)前是第', count, '個目標(biāo)')
    lock.release()
    try:
        ret = nm.scan(scan_ip, open_ports, arguments=nmap_arguments)
        try:
            output_item = ret['scan'][scan_ip]['tcp']
        except Exception:
            pass
        else:   # try語句無異常時執(zhí)行else語句
            for port, port_info in output_item.items():  # 返回可遍歷的(鍵, 值) 元組數(shù)組
                save_item = f"[+] {scan_ip} {port} {port_info['name']} {port_info['product']} {port_info['version']}"
                insert.add(scan_ip + '\t' + str(port) + '\t' + port_info['name'] + '\t' + port_info['product'] + ' '
                           + port_info['version'] + '\n')
                lock.acquire()
                print(save_item)
                lock.release()
            fw = open('ports3.txt', 'w+', encoding='utf-8')
            fw.writelines(insert)
            fw.close()
    except Exception as e:
        print(str(e))
        pass


def main():
    que = queue.Queue()
    try:
        # 要掃描的ip列表缨叫,一行一個
        f = open(r'ips.txt', 'r')
        for line in f.readlines():
            final_ip = line.strip()
            que.put(final_ip)
        f.close()
        threads = []
        thread_count = 5
        for i in range(thread_count):
            threads.append(PortScan(que))
        for t in threads:
            t.start()
        for t in threads:
            t.join()
    except Exception as e:
        print('Main:', e)
        pass
    spend_time = (datetime.datetime.now() - start_time).seconds
    print("疑似存在waf的IP:")
    print(bad_ips)
    print('程序共運行了: ' + str(spend_time) + '秒')


if __name__ == '__main__':
    ips = {}
    index = 1
    count = 0
    start_time = datetime.datetime.now()
    path = r"D:\Security-Tools\masscan1.0.4\x64"    # masscan所在路徑椭符,可自行修改
    os.chdir(path)
    nmap_arguments = "-sV -Pn"
    main()

掃描端口的腳本有了,接下來我們得清楚各種端口的利用方式

存在未授權(quán)風(fēng)險的端口服務(wù):

redis耻姥、svn销钝、Hadoop、vnc琐簇、mongodb蒸健、memcached座享、docker、zookeeper似忧、rsync渣叛、ldap、ftp盯捌、couchdb

存在爆破風(fēng)險的端口服務(wù):

rdp淳衙、vnc、redis饺著、ssh箫攀、mongodb、postgresql幼衰、mysql靴跛、oracle、ms-sql-s渡嚣、socks5梢睛、ldap、smtp识椰、ftp绝葡、zebra、snmp裤唠、netbios

那么多風(fēng)險點記不住咋辦挤牛?像對我這種沒有什么經(jīng)驗的菜鳥來說,可以把以上風(fēng)險點寫入腳本中:

對于未授權(quán)的端口服務(wù)种蘸,有能力的話最好能復(fù)現(xiàn)一遍墓赴,然后平時要收集一些利用腳本,下面這個未授權(quán)查詢腳本是在github上看到的航瞭,可以再自行添加

import socket
import pymongo
import requests
import ftplib
from tqdm import tqdm
import sys
from concurrent.futures import ThreadPoolExecutor

headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1464.0 Safari/537.36'}

def redis(ip):
    try:
        socket.setdefaulttimeout(5)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip, 6379))
        s.send(bytes("INFO\r\n", 'UTF-8'))
        result = s.recv(1024).decode()
        if "redis_version" in result:
            print(ip + ":6379 redis未授權(quán)")
        s.close()
    except Exception as e:
        pass
    finally:
        bar.update(1)

def mongodb(ip):
    try:
        conn = pymongo.MongoClient(ip, 27017, socketTimeoutMS=4000)
        dbname = conn.list_database_names()
        print(ip + ":27017 mongodb未授權(quán)")
        conn.close()
    except Exception as e:
        pass
    finally:
        bar.update(1)

def memcached(ip):
    try:
        socket.setdefaulttimeout(5)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip, 11211))
        s.send(bytes('stats\r\n', 'UTF-8'))
        if 'version' in s.recv(1024).decode():
            print(ip + ":11211 memcached未授權(quán)")
        s.close()
    except Exception as e:
        pass
    finally:
        bar.update(1)

def elasticsearch(ip):
    try:
        url = 'http://' + ip + ':9200/_cat'
        r = requests.get(url, headers=headers, timeout=15)
        if '/_cat/master' in r.content.decode():
            print(ip + ":9200 elasticsearch未授權(quán)")
    except Exception as e:
        pass
    finally:
        bar.update(1)

def zookeeper(ip):
    try:
        socket.setdefaulttimeout(5)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip, 2181))
        s.send(bytes('envi', 'UTF-8'))
        data = s.recv(1024).decode()
        s.close()
        if 'Environment' in data:
            print(ip + ":2181 zookeeper未授權(quán)")
    except:
        pass
    finally:
        bar.update(1)

def ftp(ip):
    try:
        ftp = ftplib.FTP.connect(ip,21,timeout=15)
        ftp.login('anonymous', 'Aa@12345678')       # 匿名訪問诫硕,用戶名為anonymous,密碼為空或任意郵箱
        print(ip + ":21 FTP未授權(quán)")                    # 弱口令,username:FTP  password:FTP或空
    except Exception as e:                              # username: USET    password: pass
        pass
    finally:
        bar.update(1)

def CouchDB(ip):
    try:
        url = 'http://' + ip + ':5984'+'/_utils/'
        r = requests.get(url, headers=headers, timeout=15)
        if 'couchdb-logo' in r.content.decode():
            print(ip + ":5984 CouchDB未授權(quán)")
    except Exception as e:
        pass
    finally:
        bar.update(1)

def docker(ip):
    try:
        url = 'http://' + ip + ':2375'+'/version'
        r = requests.get(url, headers=headers, timeout=15)
        if 'ApiVersion' in r.content.decode():
            print(ip + ":2375 docker api未授權(quán)")
    except Exception as e:
        pass
    finally:
        bar.update(1)


def Hadoop(ip):
    try:
        url = 'http://' + ip + ':50070'+'/dfshealth.html'
        r = requests.get(url, headers=headers, timeout=15)
        if 'hadoop.css' in r.content.decode():
            print(ip + ":50070 Hadoop未授權(quán)")
    except Exception as e:
        pass
    finally:
        bar.update(1)


def Jenkins(ip):
    try:
        url = 'http://' + ip + ':8080' + '/manage'
        r = requests.get(url, headers=headers, timeout=15)
        if 'Jenkins' in r.content.decode():
            print(ip + ":8080 Jenkins api未授權(quán)")
    except Exception as e:
        pass
    finally:
        bar.update(1)


if __name__ == '__main__':
    if len(sys.argv) == 1:
        print("Usage:python3 unauthorized-check.py url.txt")
    file = sys.argv[1]
    with open(file, "r", encoding='UTF-8') as f:
        line = [i for i in f.readlines()]
    bar = tqdm(total=len(line)*9)
    with ThreadPoolExecutor(max_workers=20) as pool:
        for target in line:
            target=target.strip()
            pool.submit(redis, target)
            pool.submit(Hadoop, target)
            pool.submit(docker, target)
            pool.submit(CouchDB, target)
            pool.submit(ftp, target)
            pool.submit(zookeeper, target)
            pool.submit(elasticsearch, target)
            pool.submit(memcached, target)
            pool.submit(mongodb, target)
            pool.submit(Jenkins, target)

有時候端口掃描會發(fā)現(xiàn)一些中間件服務(wù)刊侯,比如下圖:

針對這種情況章办,平時可以收集一些中間件漏洞總結(jié)的文章,或者在零組漏洞庫中查找相應(yīng)的漏洞

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載滨彻,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者藕届。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市亭饵,隨后出現(xiàn)的幾起案子休偶,更是在濱河造成了極大的恐慌,老刑警劉巖辜羊,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件踏兜,死亡現(xiàn)場離奇詭異词顾,居然都是意外死亡,警方通過查閱死者的電腦和手機碱妆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門肉盹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人疹尾,你說我怎么就攤上這事上忍。” “怎么了纳本?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵睡雇,是天一觀的道長。 經(jīng)常有香客問我饮醇,道長,這世上最難降的妖魔是什么秕豫? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任朴艰,我火速辦了婚禮,結(jié)果婚禮上混移,老公的妹妹穿的比我還像新娘祠墅。我一直安慰自己,他們只是感情好歌径,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布毁嗦。 她就那樣靜靜地躺著,像睡著了一般回铛。 火紅的嫁衣襯著肌膚如雪狗准。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天茵肃,我揣著相機與錄音腔长,去河邊找鬼。 笑死验残,一個胖子當(dāng)著我的面吹牛捞附,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播您没,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鸟召,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了氨鹏?” 一聲冷哼從身側(cè)響起欧募,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喻犁,沒想到半個月后槽片,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體何缓,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年还栓,在試婚紗的時候發(fā)現(xiàn)自己被綠了碌廓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡剩盒,死狀恐怖谷婆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辽聊,我是刑警寧澤纪挎,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站跟匆,受9級特大地震影響异袄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜玛臂,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一烤蜕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧迹冤,春花似錦讽营、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至堪藐,卻和暖如春莉兰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背礁竞。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工贮勃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人苏章。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓寂嘉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親枫绅。 傳聞我的和親對象是個殘疾皇子泉孩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355