zl程序教程

您现在的位置是:首页 >  Python

当前栏目

Python 原生Socket实现端口扫描

2023-02-18 16:46:18 时间

端口扫描,就是逐个对一段端口或指定的端口进行扫描。通过扫描结果可以知道一台计算机上都提供了哪些服务,Python中使用Socket即可实现对特定端口的探测,以及对C段的扫描。

扫描目标主机Banner: 为了让函数获得完整的屏幕控制权,这里使用一个信号量,它能够阻止其他线程运行而避免出现多线程同时输出造成的乱码和失序等情况.

#coding=utf-8
from socket import *
from threading import *

#定义一个信号量
screenLock = Semaphore(value=1)

def ScanBanner(addr,port):
    try:
        conn = socket(AF_INET,SOCK_STREAM)
        conn.connect((addr,port))
        conn.send(bytes("hello lyshark\r\n",encoding="utf-8"))
        res = conn.recv(200)
        # 加锁
        screenLock.acquire()
        print("[+] 主机: {} Banner: {}".format(addr,res))
    except Exception:
        # 加锁
        screenLock.acquire()
        print("[-] 主机: {} 不存在或已经关闭.".format(addr))
        pass
    finally:
        # 执行释放锁的操作
        screenLock.release()
        conn.close()

setdefaulttimeout(1)
for i in range(0,25):
    a = "192.168.1.{}".format(i)
    t = Thread(target=ScanBanner,args=(a,80))
    t.start()

针对域名C段扫描: 首先通过域名解析出目标主机对应的IP地址,然后使用C段扫描找出该C段所有的主机IP.

import socket,threading
import argparse

def PortScan(addr, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        result = sock.connect_ex((addr, port))
        sock.close()
        if result==0:
            return 1
        else:
            return 0
    except Exception as err:
        return 0

def CalculationIP(Addr_Count):
    IP_List = []
    try:
        IP_Start = str(Addr_Count.split("-")[0]).split(".")
        IP_Heads = str(IP_Start[0] + "." + IP_Start[1] + "." + IP_Start[2] +".")
        IP_Start_Range = int(Addr_Count.split(".")[3].split("-")[0])
        IP_End_Range = int(Addr_Count.split("-")[1])
        for item in range(IP_Start_Range,IP_End_Range+1):
            IP_List.append(IP_Heads+str(item))
        return IP_List
    except Exception:
        return 0

def StartScanner(addr,port):
    for item in port:
        ret = PortScan(addr,item)
        if ret != 0:
            print("address => {} flag => {} port = > {}".format(addr,ret,item))

def Banner():
    print("  _          ____  _                _    ")
    print(" | |   _   _/ ___|| |__   __ _ _ __| | __")
    print(" | |  | | | \___ \| '_ \ / _` | '__| |/ /")
    print(" | |__| |_| |___) | | | | (_| | |  |   < ")
    print(" |_____\__, |____/|_| |_|\__,_|_|  |_|\_\\")
    print("       |___/                             \n")
    print("E-Mail: me@lyshark.com")

if __name__ == '__main__':
    # 使用方式: main.py -a 192.168.1.1-100 -p 80,443,445,135,139
    Banner()
    parser = argparse.ArgumentParser()
    parser.add_argument("-a", "--addr", dest="ip", help="设置要扫描的C段地址")
    parser.add_argument("-p", "--port", dest="port", help="设置要扫描的端口列表")
    args = parser.parse_args()

    # map = > 将 ['80','443'] 转为 => [80,443]
    temp = list(str(args.port).split(','))
    port = map(eval,temp)
    thread = []
    if args.ip and args.port:
        addr = CalculationIP(args.ip)
        for i in addr:
            t = threading.Thread(target=StartScanner,args=(i,port))
            t.start()
            thread.append(t)
    for t in thread:
        t.join()
    else:
        parser.print_help()

例如需要探测特定80,443,445,135,139端口:

  • main.py -a 192.168.1.1-100 -p 80,443,445,135,139