欢迎,来自IP地址为:216.73.216.171 的朋友


Python 语言的网络功能十分强大,可以用以下代码实现一个简单的端口扫描工具:

import socket
from datetime import datetime

print("=" * 50)
print("  Python Port Scanner")
print("=" * 50)

target = input("\nEnter IP address or domain to scan: ")

print("\nTarget:     " + target)
print("Started:    " + str(datetime.now()))
print("-" * 50)

open_ports = []

for port in range(1, 1025):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(0.5)
        result = sock.connect_ex((target, port))
        if result == 0:
            print("[OPEN]   Port " + str(port))
            open_ports.append(port)
        sock.close()
    except KeyboardInterrupt:
        print("\nScan interrupted.")
        break
    except socket.gaierror:
        print("Could not resolve hostname.")
        break

print("-" * 50)
print("Scan complete. Open ports: " + str(open_ports))

代码是如何工作的呢?

很显然,脚本的核心是以下四行:

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
        sock.settimeout(0.5) 
        result = sock.connect_ex((target, port)) 
        if result == 0:

首先使用 socket.socket(AF_INET, SOCK_STREAM) 方法创建一个 TCP 套接字。”AF_INET”代表 IPv4,”SOCK_STREAM”代表使用 TCP 连接。这与浏览器加载网站时建立的连接类型相同。

sock.settimeout(0.5) 指示套接字在 0.5 秒内如果没有响应就放弃连接。如果没有此设置,扫描器会在过滤后的端口上无限期地等待,耗时数小时才能完成扫描。

sock.connect_ex((target, port)) 方法 尝试与目标主机上的指定端口建立完整的 TCP 连接。这与 connect() 函数不同– connect_ex 返回一个整数错误代码,而不是抛出异常。如果返回数值 0,则表示连接成功。端口已打开,并且有服务正在监听。

这就是端口扫描的全部概念:尝试建立连接,并记录连接是否成功。

Nmap 工具执行相同的基本操作,并在此基础上添加了更多功能–服务版本检测、操作系统指纹识别、脚本扫描等等。但归根结底,它的核心仍然是:尝试建立 TCP 连接,记录结果。

理解了这一点,Nmap 就不再像个黑匣子了。

测试脚本

执行这个脚本,并输入有效的 IP 地址,就可以对该 IP 进行商品扫描了,首先可以试一下”127.0.0.1″对本机进行扫描:

事实上,有很多工具都可以用来进行扫描端口,例如之前提到过的 Nmap。但我们并不理解它实际的运行机制。

构建扫描器脚本让我们思考了以下问题:

  • 什么是套接字?为什么每个端口都需要创建和关闭套接字?
  • 为什么 settimeout 很重要?如果没有它会发生什么?
  • connect_ex 和 connect 函数在底层实际执行的操作有何不同?
  • 为什么在套接字编程中返回 0 表示成功?

这些问题在运行 Nmap 时是不会出现的,它们是在编写代码时才会想到的。

这就是使用工具和理解工具之间的区别,两者都对网络安全至关重要。但只有真正理解工具,才能让各种软件工具以正确的方式发挥威慑力。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注