Skip to content

【Hacker】端口扫描器 #7

@famousczm

Description

@famousczm

前言

Python绝技:运用Python成为顶级黑客》第二章介绍了端口扫描器,对目标主机的端口进行扫描,寻找开放可用的端口。方法很简单,对目标主机的每个要检测端口建立连接,并发送数据请求,如果能成功建立连接则表示这个端口是开放的。

分析

单一的TCP连接扫描

核心代码:

# 创建一个信号量,同一时间线程数量上限为1
screenLock = threading.Semaphore(value=1)

# 尝试建立与目标主机和端口的连接,给信号量加锁来控制线程的运行
def connScan(tgtHost, tgtPort):
  try:
    connSkt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connSkt.connect((tgtHost, tgtPort))
    connSkt.send('ViolentPython\r\n')
    results = connSkt.recv(100)
    # 信号量加锁
    screenLock.acquire()
    print('%d/tcp open'%tgtPort)
    print('results: ' + str(results))
  except:
    screenLock.acquire()
    print('%d/tcp closed'%tgtPort)
  finally:
    # 信号量释放锁
    screenLock.release()
    connSkt.close()

def portScan(tgtHost, tgtPorts):
  try:
    # 获取主机名映射的ip地址
    tgtIP = socket.gethostbyname(tgtHost)
  except:
    print('Cannot resolve "%s": Unknown host'%tgtHost)
    return
  try:
    tgtName = socket.gethostbyaddr(tgtIP)
    print('Scan Results for: ' + tgtName[0])
  except:
    print('Scan Results for: ' + tgtIP)
  socket.setdefaulttimeout(1)
  # 扫描端口
  for tgtPort in tgtPorts:
    t = threading.Thread(target=connScan, args=(tgtHost, int(tgtPort)))
    t.start()

这个脚本再次用到了多线程的方式去扫描端口,提高效率。但是与之前不同的是增加了信号量和锁的概念。因为每个线程运行时都会执行输出信息到屏幕这段代码,所以多线程会导致多个线程同时执行输出命令,而使输出内容乱码,获取不到正确信息。所以引入了信号量的方法来控制每个线程能有序的执行完输出命令,当线程1开始输出信息的时候,信号量加锁 screenLock.acquire(),这时候其它线程不能输出信息。当线程1 finally 输出完了,释放锁 screenLock.release()。其它线程需要输出信息的时候也是一样。

NMAP 端口扫描

NMAP即 Network Mapper,是一个用于检测目标主机是否在线、端口开放情况、侦测执行的服务类型以及版本资讯、评估网络系统安全的开源工具包。由于是第三方库,所以要下载:

pip install python-nmap
brew install nmap 
brew link --overwrite nmap

安装完之后运行命令,nmap -V 如果有版本信息说明安装成功

使用也很简单:

def nmapScan(tgtHost, tgtPort):
  nmScan = nmap.PortScanner()
  try:
    nmScan.scan(tgtHost, tgtPort)
    # 端口状态:Open(开放)、Closed(关闭)、Filtered(过滤)、Unfiltered(未过滤)、Open|Filtered(开放或过滤)、Closed|Filtered(关闭或过滤)
    state = nmScan[tgtHost]['tcp'][int(tgtPort)]['state']
    print(tgtHost + ' tcp/' + tgtPort + ' ' + state)
  except:
    print('scan error')

最后的结果 state 就是端口的状态,可以看出除了开放和关闭状态外,它还有过滤状态,当服务器或防火墙过滤掉这个端口的请求,但是端口又没有关闭时,就是过滤状态。而单一的 TCP 连接扫描就只能显示关闭了。

示例代码

总结

端口扫描是入侵操作前的一次侦察,先派遣侦察兵寻找城池防守薄弱的点,是战术关键。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions