在函数 `_process_packet` 中,这段代码的功能是进行启发式分析,特别是针对端口扫描和感染扫描的检测。这段代码是函数的一部分,用于处理捕获到的单个原始IP层数据包。
代码中的 `try` 块尝试执行以下操作:
1. **检查启发式分析是否启用**:
- `if config.USE_HEURISTICS:`: 如果启用了启发式分析,则继续执行。
2. **获取锁**:
- `if _locks.connect_sec:`: 如果存在 `_locks.connect_sec` 锁,则尝试获取该锁。
- `_locks.connect_sec.acquire()`: 获取 `_connect_sec` 锁。
3. **更新全局变量**:
- `connect_sec = _connect_sec`: 更新全局变量 `_connect_sec` 为当前时间戳。
- `_connect_sec = sec`: 将当前时间戳赋值给全局变量 `_connect_sec`。
4. **释放锁**:
- `if _locks.connect_sec:`: 如果之前成功获取了锁,则释放锁。
- `_locks.connect_sec.release()`: 释放 `_connect_sec` 锁。
5. **执行启发式分析**:
- `if sec > connect_sec:`: 如果当前时间戳大于上次更新时间戳,则进行端口扫描和感染扫描的检测。
- `for key in _connect_src_dst:`: 遍历 `_connect_src_dst` 字典,其中存储了源IP地址和目的IP地址的映射。
- `_src_ip, _dst = key.split('~')`: 将键分割成源IP和目的IP。
- `if not _dst.isdigit() and len(_connect_src_dst[key]) > PORT_SCANNING_THRESHOLD:`: 如果目的IP不是数字,并且该键对应的值列表长度大于端口扫描阈值,则继续检测。
- `if not check_whitelisted(_src_ip):`: 如果源IP地址不在白名单中,则记录事件。
- `_dst_ip = _dst`: 将目的IP地址赋值给 `_dst_ip`。
- `for _ in _connect_src_details[key]:`: 遍历 `_connect_src_details` 字典,其中存储了源IP地址、源端口、目的IP地址和目的端口的映射。
- `log_event((sec, usec, _src_ip, _[2], _dst_ip, _[3], PROTO.TCP, TRAIL.IP, _src_ip, "potential port scanning", "(heuristic)"), packet)`: 记录事件,包括时间戳、源IP、目的IP、协议类型、轨迹类型、轨迹描述和原始数据包。
6. **清除数据**:
- `_connect_src_dst.clear()`: 清除 `_connect_src_dst` 字典。
- `_connect_src_details.clear()`: 清除 `_connect_src_details` 字典。
7. **重复执行类似操作**:
- `for key in _path_src_dst:`: 遍历 `_path_src_dst` 字典,其中存储了源IP地址、源端口、目的IP地址、目的端口和路径的映射。
- `if len(_path_src_dst[key]) > WEB_SCANNING_THRESHOLD:`: 如果该键对应的值列表长度大于网络扫描阈值,则记录事件。
8. **清除数据并重复执行类似操作**:
- `_path_src_dst.clear()`: 清除 `_path_src_dst` 字典。
- `_path_src_dst_details.clear()`: 清除 `_path_src_dst_details` 字典。
函数的总体功能是通过启发式分析检测可能的端口扫描和感染扫描活动。这包括检查源IP地址与目的IP地址的映射,以及源IP地址、源端口、目的IP地址和目的端口的组合。如果检测到可能的扫描活动,函数会记录事件,并将相关信息存储在