Python实现TCP端口扫描:从基础到多线程与Nmap集成

小林子
小林子
发布时间:2026-10-14 | 5人浏览过
原创

本文详细介绍如何使用Python进行TCP端口扫描。从利用socket库建立全连接扫描器开始,演示如何检测主机开放端口。接着通过发送数据捕获应用标识以识别服务类型。为解决扫描延迟问题,引入多线程技术实现并发扫描。最后对比展示了使用nmap库进行扫描的方法,帮助读者掌握不同场景下的端口扫描技巧。

TCP端口扫描基础原理

对目标主机执行操作的第一步,通常是对该主机的端口进行扫描,以确认哪些端口处于开放状态。

构建Socket扫描器

首先构建一个基于TCP全连接的扫描器,利用socket模块来创建连接对象。

执行端口扫描

执行端口开放状态的扫描测试。


#测试当前主机和端口是否开放,直接使用socket连接
def connScan(host,port):
  try:
    connSkt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    connSkt.connect((host,port))
    print("tcp open port:" + str(port))
  except:
    print('tcp closed:'+str(port))

def portScan(tgtHost, tgtPorts):  
  try:    
    tgtIP = socket.gethostbyname(tgtHost) 
  except:    
    print("[-] Cannot resolve '%s': Unknown host" % tgtHost)    
    return  
  try:    
    tgtName = socket.gethostbyaddr(tgtIP)  print('\n[+] Scan Results for: ' + tgtName[0])
  except:    
    print('\n[+] Scan Results for: ' + tgtIP)
  socket.setdefaulttimeout(1)  
  for tgtPort in tgtPorts:    
    print('Scanning port ' + str(tgtPort))    connScan(tgtHost, int(tgtPort))

portScan('www.baidu.com', [80,443,3389,1433,23,445])

百度端口扫描示例

以百度主机为例,对其指定端口进行扫描操作。


[+] Scan Results for: 61.135.169.125
Scanning port 80
tcp open port:80
Scanning port 443
tcp open port:443
Scanning port 3389
tcp closed:3389
Scanning port 1433
tcp closed:1433
Scanning port 23
tcp closed:23
Scanning port 445
tcp closed:445

应用标识捕获

捕获应用标识信息。

为了从目标主机获取应用标识,需要在connScan函数中增加额外的验证逻辑。当发现端口开放时,向该端口发送一段字符串数据并等待响应。通过收集这些响应内容,可以推断出目标主机端口上运行的应用程序类型。


#测试当前主机和端口是否开放,直接使用socket连接
def connScan(host,port):
  try:
    connSkt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    connSkt.connect((host,port))
    connSkt.send('Python\r\n')
    results = connSkt.recv(100)
    print("tcp open port:" + str(port))
    print('[+] ' + str(results)) 
  except:
    print('tcp closed:'+str(port))
def portScan(tgtHost, tgtPorts):  
  try:    
    tgtIP = socket.gethostbyname(tgtHost) 
  except:    
    print("[-] Cannot resolve '%s': Unknown host" % tgtHost)    
    return  
  try:    
    tgtName = socket.gethostbyaddr(tgtIP)    
    print('\n[+] Scan Results for: ' + tgtName[0])
  except:    
    print('\n[+] Scan Results for: ' + tgtIP)
  socket.setdefaulttimeout(1)  
  for tgtPort in tgtPorts:    
    print('Scanning port ' + str(tgtPort))    
    connScan(tgtHost, int(tgtPort))

portScan('www.qq.com', [22,80,443,3389,1433,23,445])

多线程并发扫描优化

采用多线程技术进行扫描。

由于每个socket连接存在时间延迟,单次扫描耗时数秒看似微不足道,但在扫描大量端口和主机时,总延迟会迅速累积。理想情况下,我们希望这些socket能够并行处理。引入Python的线程机制可以实现并发执行。在扫描代码中,只需调整portScan()函数的迭代逻辑,将每个connScan()调用封装为独立线程。在迭代过程中创建的线程将同时运行,从而提升扫描效率。


for tgtPort in tgtPorts:
  print('Scanning port ' + str(tgtPort))
  t = threading.Thread(target=connScan, args=(tgtHost,
  int(tgtPort)))
  t.start()

集成Nmap进行扫描

使用nmap库进行扫描。


import nmap
def nmapScan(tgtHost, tgtPort):
  nmScan = nmap.PortScanner()
  results = nmScan.scan(tgtHost, tgtPort)
  state = results['scan'][tgtHost]['tcp'][int(tgtPort)]['state']
  print(" [*] " + tgtHost + " tcp/" + tgtPort + " " + state)
  nmapScan('10.108.x.x','8080')

以上即为本文的全部内容,希望对读者的学习有所帮助,也欢迎大家继续支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表