Python 渗透测试 - 快速指南


Python 渗透测试 - 简介

笔测试或渗透测试可以定义为通过模拟针对计算机系统的网络攻击以利用漏洞来评估 IT 基础设施的安全性的尝试。

漏洞扫描和渗透测试有什么区别?漏洞扫描只是识别所指出的漏洞,而渗透测试,如前所述,是一种利用漏洞的尝试。渗透测试有助于确定系统中是否可能存在未经授权的访问或任何其他恶意活动。

我们可以使用手动或自动技术对服务器、Web 应用程序、无线网络、移动设备和任何其他潜在暴露点进行渗透测试。由于渗透测试,如果我们利用任何类型的漏洞,则必须将其转发给 IT 和网络系统管理员以得出战略结论。

渗透(笔)测试的意义

在本节中,我们将了解渗透测试的意义。考虑以下几点来了解其重要性 -

组织安全

渗透测试的重要性可以从以下角度来理解:它通过对组织安全性的详细评估为组织提供保证。

保护组织的机密

借助渗透测试,我们可以在面临任何损害之前发现潜在威胁并保护该组织的机密性。

安全政策的实施

渗透测试可以确保我们了解组织中安全策略的实施。

管理网络效率

借助渗透测试,可以管理网络的效率。它可以检查防火墙、路由器等设备的安全性。

确保组织安全

假设如果我们想要对网络设计进行任何更改或更新软件、硬件等,那么渗透测试可以确保组织免受任何类型漏洞的安全。

谁是优秀的渗透测试员?

渗透测试人员是软件专业人员,他们通过识别漏洞来帮助组织加强对网络攻击的防御。渗透测试人员可以使用手动技术或自动化工具进行测试。

现在让我们考虑一个好的渗透测试仪的以下重要特征 -

网络和应用程序开发知识

优秀的渗透测试人员必须具备应用程序开发、数据库管理和网络方面的知识,因为他/她需要处理配置设置和编码。

杰出的思想家

渗透测试人员必须是一位杰出的思考者,并且会毫不犹豫地在特定任务上应用不同的工具和方法以获得最佳输出。

程序知识

优秀的渗透测试人员必须具备确定每次渗透测试范围的知识,例如其目标、局限性和程序的合理性。

最新技术

渗透测试人员必须掌握最新的技术技能,因为技术随时可能发生变化。

擅长报告制作

成功实施渗透测试后,渗透测试人员必须在最终报告中提及所有发现结果和潜在风险。因此,他/她必须具备良好的报告制作技能。

对网络安全充满热情

一个充满激情的人可以获得人生的成功。同样,如果一个人对网络证券充满热情,那么他/她就可以成为一名优秀的渗透测试员。

渗透测试范围

我们现在将了解渗透测试的范围。以下两种测试可以定义渗透测试的范围 -

无损检测(NDT)

无损检测不会使系统面临任何风险。NDT 用于在缺陷变得危险之前发现缺陷,而不损害系统、物体等。在进行渗透测试时,NDT 执行以下操作 -

扫描远程系统

此测试扫描并识别远程系统是否存在可能的漏洞。

确认

发现漏洞后,它还会验证所有发现的漏洞。

正确利用远程系统

在无损检测中,渗透测试仪将正确利用远程系统。这有助于避免中断。

- 另一方面,在进行渗透测试时,NDT 不会执行拒绝服务 (DoS) 攻击

破坏性测试

破坏性测试可能会使系统面临风险。它比无损检测更昂贵并且需要更多的技能。在进行渗透测试时,破坏性测试执行以下操作 -

  • 拒绝服务 (DoS) 攻击- 破坏性测试执行 DoS 攻击。

  • 缓冲区溢出攻击- 它还执行缓冲区溢出攻击,这可能导致系统崩溃。

练习渗透测试需要安装什么?

渗透测试技术和工具只能在您拥有或有权运行这些工具的环境中执行。我们绝不能在我们无权的环境中实践这些技术,因为未经许可的渗透测试是非法的。

评估方法

近年来,政府和私人组织都将网络安全作为战略重点。网络犯罪分子经常通过使用不同的攻击媒介将政府和私人组织作为他们的软目标。不幸的是,由于缺乏有效的政策、标准和信息系统的复杂性,网络犯罪分子拥有大量目标,并且他们在利用系统和窃取信息方面也取得了成功。

渗透测试是一种可用于减轻网络攻击风险的策略。渗透测试的成功取决于高效且一致的评估方法。

我们有多种与渗透测试相关的评估方法。使用方法的好处是它允许评估者一致地评估环境。以下是一些重要的方法 -

  • 开源安全测试方法手册 (OSSTMM)

  • 开放 Web 应用程序安全项目 (OWASP)

  • 美国国家标准与技术研究院 (NIST)

  • 渗透测试执行标准 (PTES)

什么是 PTES?

PTES,渗透测试执行标准,顾名思义是渗透测试的评估方法论。它涵盖了与渗透测试相关的所有内容。我们在 PTES 内有许多与评估员可能遇到的不同环境相关的技术指南。这是新评估人员使用 PTES 的最大优势,因为技术指南提供了在行业标准工具内解决和评估环境的建议。

在下一节中,我们将了解 PTES 的不同阶段。

PTES 的七个阶段

渗透测试执行标准(PTES)由七个阶段组成。这些阶段涵盖了与渗透测试相关的所有内容 - 从渗透测试背后的初始沟通和推理,到测试人员在幕后工作的情报收集和威胁建模阶段。通过漏洞研究、利用和后利用,可以更好地了解受测试的组织。在这里,测试人员的技术安全专业知识与对参与的业务理解进行了严格的结合,最后形成报告,以对客户有意义并为其提供最大价值的方式捕获整个过程。

我们将在后续章节中了解 PTES 的七个阶段 -

参与前互动阶段

这是 PTES 的第一个也是非常重要的阶段。此阶段的主要目的是解释可用的工具和技术,这有助于成功完成渗透测试的预参与步骤。实施此阶段时的任何错误都可能对评估的其余部分产生重大影响。此阶段包括以下内容 -

请求评估

此阶段开始的第一部分是创建组织评估请求。向评估人员提供一份征求建议书 (RFP)文件,其中包含有关环境、所需评估类型和组织期望的详细信息。

投标

现在,根据RFP文件,多家评估公司或个人有限责任公司(LLC)将投标,投标与要求的工作、价格和其他一些具体参数相匹配的一方将获胜。

签署聘书 (EL)

现在,该组织与中标方将签署一份Engagement Letter(EL)合同。该信函将包含工作说明书 (SOW)和最终产品。

范围界定会议

一旦签署 EL,就可以开始对范围进行微调。这样的会议有助于组织和政党调整特定范围。范围界定会议的主要目标是讨论要测试的内容。

处理范围蔓延

范围蔓延是指客户可能会尝试增加或扩展承诺的工作水平,以获得比承诺支付的更多的成果。这就是为什么由于时间和资源的原因,应仔细考虑对原始范围的修改。它还必须以某种文件形式填写,例如电子邮件、签名文件或授权信等。

问卷调查

在与客户的初步沟通过程中,客户必须回答几个问题,才能正确估计参与范围。这些问题旨在帮助客户更好地了解客户希望从渗透测试中获得什么;为什么客户希望对其环境进行渗透测试;以及他们是否希望在渗透测试期间执行某些类型的测试。

进行测试的方式

预参与阶段的最后一部分是决定进行测试的程序。有多种测试策略可供选择,例如白盒测试、黑盒测试、灰盒测试、双盲测试。

以下是可能要求的评估的一些示例 -

  • 网络渗透测试
  • Web应用渗透测试
  • 无线网络渗透测试
  • 物理渗透测试
  • 社会工程学
  • 网络钓鱼
  • 互联网语音协议 (VOIP)
  • 内部网络
  • 外部网络

情报收集阶段

情报收集是PTES的第二阶段,是我们对目标进行初步调查,收集尽可能多的信息,以便在漏洞评估和利用阶段渗透目标时使用。它帮助组织通过评估团队确定外部暴露。我们可以将信息收集分为以下三个层次 -

1 级信息收集

自动化工具几乎可以完全获得这种级别的信息。1 级信息收集工作应适当以满足合规性要求。

2 级信息收集

此级别的信息可以通过使用级别 1 的自动化工具以及一些手动分析来获得。该级别需要对业务有很好的了解,包括物理位置、业务关系、组织结构图等信息。2 级信息收集工作应适当满足合规性要求以及其他需求,例如长期安全策略、收购较小的制造商等

3 级信息收集

这种级别的信息收集用于最先进的渗透测试。第 3 级信息收集需要来自第 1 级和第 2 级的所有信息以及大量手动分析。

威胁建模阶段

这是 PTES 的第三阶段。正确执行渗透测试需要威胁建模方法。威胁建模可以用作渗透测试的一部分,或者它可能会面临基于许多因素的威胁。如果我们使用威胁建模作为渗透测试的一部分,那么在第二阶段收集的信息将回滚到第一阶段。

以下步骤构成威胁建模阶段 -

  • 收集必要的相关信息。

  • 需要对主要和次要资产进行识别和分类。

  • 需要识别威胁和威胁社区并对其进行分类。

  • 需要针对主要和次要资产绘制威胁社区图。

威胁社区和代理

下表列出了相关威胁社区和代理及其在组织中的位置 -

地点 内部的 外部的
威胁代理/社区 雇员 商业合作伙伴
管理人员 承包商
管理员(网络、系统) 竞争对手
工程师 供应商
技术人员 民族国家
普通用户社区 黑客

在进行威胁建模评估时,我们需要记住威胁的位置可以是内部的。只需一封网络钓鱼电子邮件或一名恼怒的员工就可以通过广播凭据来危及组织的安全。

漏洞分析阶段

这是 PTES 的第四阶段,评估人员将确定进一步测试的可行目标。在PTES的前三个阶段中,仅提取了有关组织的详细信息,评估者没有触及任何测试资源。这是 PTES 最耗时的阶段。

以下阶段构成漏洞分析 -

漏洞测试

它可以被定义为发现主机和服务的系统和应用程序中的错误配置和不安全的应用程序设计等缺陷的过程。在进行漏洞分析之前,测试人员必须正确确定测试范围和期望的结果。漏洞测试可以有以下类型 -

  • 主动测试
  • 被动测试

我们将在后续部分详细讨论这两种类型。

主动测试

它涉及与正在测试安全漏洞的组件的直接交互。这些组件可以处于低级别(例如网络设备上的 TCP 堆栈),也可以处于高级别(例如基于 Web 的界面)。主动测试可以通过以下两种方式完成 -

自动化主动测试

它利用该软件与目标进行交互,检查响应并根据这些响应确定组件中是否存在漏洞。与手动主动测试相比,自动化主动测试的重要性可以从以下事实看出:如果系统上有数千个 TCP 端口,而我们需要手动连接所有端口进行测试,则将花费相当多的时间。然而,使用自动化工具可以减少大量的时间和劳动力需求。网络漏洞扫描、端口扫描、横幅抓取、Web应用程序扫描可以借助自动化主动测试工具来完成。

手动主动测试

与自动主动测试相比,手动有效测试更有效。自动化流程或技术始终存在误差幅度。这就是为什么始终建议对目标系统上可用的每个协议或服务执行手动直接连接,以验证自动化测试的结果。

被动测试

被动测试不涉及与组件的直接交互。它可以借助以下两种技术来实现 -

元数据分析

该技术涉及查看描述文件的数据而不是文件本身的数据。例如,MS Word 文件具有作者姓名、公司名称、文档上次修改和保存的日期和时间等元数据。如果攻击者可以被动访问元数据,就会出现安全问题。

流量监控

它可以被定义为连接到内部网络并捕获数据以进行离线分析的技术。它主要用于捕获交换网络上的“数据泄漏” 。

验证

漏洞测试后,对结果进行验证是非常必要的。可以借助以下技术来完成 -

工具之间的相关性

如果评估人员使用多个自动化工具进行漏洞测试,那么为了验证结果,非常有必要在这些工具之间建立关联。如果工具之间不存在这种相关性,那么研究结果可能会变得复杂。它可以分为项目的特定相关性和项目的类别相关性。

协议特定验证

验证也可以借助协议来完成。VPN、Citrix、DNS、Web、邮件服务器可用于验证结果。

研究

在发现并验证系统中的漏洞后,必须确定问题识别的准确性并研究渗透测试范围内漏洞的潜在可利用性。研究可以公开或私下进行。在进行公共研究时,可以使用漏洞数据库和供应商公告来验证所报告问题的准确性。另一方面,在进行私人研究时,可以设置副本环境,并应用模糊测试或测试配置等技术来验证所报告问题的准确性。

开发阶段

这是 PTES 的第五阶段。此阶段的重点是通过绕过安全限制来获取对系统或资源的访问权限。在此阶段,前面阶段完成的所有工作都会导致获得系统的访问权限。以下是一些用于访问系统的常用术语 -

  • 爆开
  • 带壳
  • 破裂
  • 被剥削

在利用阶段,登录系统可以借助代码、远程利用、创建利用、绕过防病毒软件来完成,也可以像通过弱凭据登录一样简单。获得准入后,即确定了主要切入点后,评估人员必须重点关注识别高价值的目标资产。如果漏洞分析阶段正确完成,那么应该已经编制了高价值目标列表。最终,攻击向量应考虑成功概率和对组织的最大影响。

开发后阶段

这是 PTES 的第六阶段。评估员在此阶段进行以下活动 -

基础设施分析

渗透测试期间使用的整个基础设施的分析都是在此阶段完成的。例如,可以借助接口、路由、DNS 服务器、缓存 DNS 条目、代理服务器等来完成网络或网络配置的分析。

掠夺

它可以被定义为从目标主机获取信息。该信息与预评估阶段定义的目标相关。该信息可以从系统上安装的程序、特定服务器(例如数据库服务器、打印机等)获取。

数据泄露

在此活动中,评估人员需要对所有可能的渗透路径进行映射和测试,以便可以进行控制强度测量,即检测和阻止来自组织的敏感信息。

创造持久力

此活动包括安装需要身份验证的后门、在需要时重新启动后门以及创建具有复杂密码的备用帐户。

清理

顾名思义,此过程涵盖了渗透测试完成后清理系统的要求。此活动包括恢复系统设置、应用程序配置参数的原始值,以及删除所有安装的后门和创建的任何用户帐户。

报告

这是 PTES 的最后也是最重要的阶段。在这里,客户根据渗透测试完成后的最终报告付款。该报告基本上反映了评估员对该系统的调查结果。以下是一份好的报告的基本部分 -

执行摘要

这是一份向读者传达渗透测试的具体目标和测试练习的高水平结果的报告。目标受众可以是首席顾问委员会的成员。

故事Plotly

该报告必须包含一个故事Plotly,其中将解释在参与过程中所做的事情、实际的安全发现或弱点以及组织已建立的积极控制措施。

概念证明/技术报告

概念证明或技术报告必须包含测试的技术细节以及预参与练习中商定为关键成功指标的所有方面/组件。技术报告部分将详细描述测试的范围、信息、攻击路径、影响和修复建议。

网络通信入门

我们一直听说,要执行渗透测试,渗透测试人员必须了解基本的网络概念,例如 IP 地址、有类子网、无类子网、端口和广播网络。第一个原因是,诸如哪些主机处于批准的范围内以及它们开放和响应哪些服务、端口和功能之类的活动将决定评估人员将在渗透测试中执行什么样的活动。环境不断变化,系统经常重新分配。因此,旧的漏洞很可能会再次出现,并且如果没有良好的网络扫描知识,则可能需要重做初始扫描。在后续部分中,我们将讨论网络通信的基础知识。

参考模型

参考模型提供了一种标准化方法,这种方法在全世界范围内都可以接受,因为使用计算机网络的人们分布在广泛的物理范围内,并且他们的网络设备可能具有异构体系结构。为了提供异构设备之间的通信,我们需要一个标准化的模型,即参考模型,它可以为我们提供这些设备之间的通信方式。

我们有两个参考模型,例如 OSI 模型和 TCP/IP 参考模型。然而,OSI 模型是一个假设模型,而 TCP/IP 是一个实用模型。

开放系统互连模型

开放系统接口是由国际标准化组织(ISO)设计的,因此也称为ISO-OSI模型。

OSI 模型由七层组成,如下图所示。每一层都有特定的功能,但每一层都向上一层提供服务。

开放系统互连模型

物理层

物理层负责以下活动 -

  • 激活、维护和停用物理连接。

  • 定义传输所需的电压和数据速率。

  • 将数字位转换为电信号。

  • 决定连接是单工、半双工还是全双工。

数据链路层

数据链路层执行以下功能 -

  • 对物理链路上传输的信息进行同步和差错控制。

  • 启用错误检测,并向要传输的数据添加错误检测位。

网络层

网络层执行以下功能 -

  • 将信号通过各种通道路由到另一端。

  • 充当网络控制器,决定数据应采用哪条路由。

  • 将传出消息分成数据包,并将传入数据包组装成更高级别的消息。

传输层

传输层执行以下功能 -

  • 它决定数据传输应该在并行路径还是单路径上进行。

  • 它对数据执行复用、拆分。

  • 它将数据组分解为更小的单元,以便网络层更有效地处理它们。

传输层保证数据从一端到另一端的传输。

会话层

会话层执行以下功能 -

  • 管理消息并同步两个不同应用程序之间的对话。

  • 它控制登录和注销、用户识别、计费和会话管理。

表示层

表示层执行以下功能 -

  • 该层确保信息以接收系统能够理解和使用的形式传递。

应用层

应用层执行以下功能 -

  • 它提供不同的服务,例如以多种方式操作信息、重新传输信息文件、分发结果等。

  • 登录或密码检查等功能也由应用层执行。

TCP/IP模型

传输控制协议和互联网协议(TCP/IP)模型是一种实用模型,用于互联网中。

TCP/IP 模型将两层(物理链路层和数据链路层)合并为一层——主机到网络层。下图显示了 TCP/IP 模型的各个层 -

TCP/IP模型

应用层

该层与 OSI 模型的层相同,执行以下功能 -

  • 它提供不同的服务,例如以多种方式操作信息、重新传输信息文件、分发结果等。

  • 应用层还执行登录或密码检查等功能。

  • 以下是应用层使用的不同协议 -

    • 远程登录
    • 文件传输协议
    • 邮件传输协议
    • DN
    • HTTP协议
    • 国家结核病防治计划

传输层

它的功能与 OSI 模型中的传输层相同。考虑以下与传输层相关的要点 -

  • 它使用TCP和UDP协议进行端到端传输。

  • TCP 是一种可靠且面向连接的协议。

  • TCP 还处理流量控制。

  • UDP 不可靠,无连接协议不执行流量控制。

  • 该层采用TCP/IP 和UDP 协议。

互联网层

该层的功能是允许主机将数据包插入网络,然后使它们独立地传输到目的地。但是,接收数据包的顺序可能与发送数据包的顺序不同。

互联网层采用互联网协议(IP)。

主机到网络层

这是 TCP/IP 模型中的最低层。主机必须使用某种协议连接到网络,以便可以通过网络发送 IP 数据包。该协议因主机和网络的不同而不同。

该层使用的不同协议是 -

  • 阿帕网
  • 卫星网
  • 局域网
  • 分组无线电

有用的架构

以下是一些用于网络通信的有用架构 -

以太网帧结构

1973 年,一位名叫 Robert Metcalfe 的工程师首先发明了以太网,该网络根据 IEEE 标准 802.3 定义。它首先用于在工作站和打印机之间互连和发送数据。超过 80% 的 LAN 使用以太网标准,因为其速度快、成本低且易于安装。另一方面,如果我们谈论帧,那么数据就会以这种方式从一个主机传输到另一个主机。帧由 MAC 地址、IP 标头、起始和结束分隔符等各种组件构成。

以太网帧以前导码和 SFD 开始。以太网标头包含源 MAC 地址和目标 MAC 地址,之后是帧的有效负载。最后一个字段是CRC,用于检测错误。基本以太网帧结构在 IEEE 802.3 标准中定义,解释如下 -

以太网 (IEEE 802.3) 帧格式

以太网数据包传输以太网帧作为其有效负载。以下是以太网帧的图形表示以及每个字段的描述 -

字段名称 前言 SFD(帧开始定界符) 目的地MAC地址 源MAC 类型 数据 CRC
大小(以字节为单位) 7 1 6 6 2 46-1500 4

前言

以太网帧前面有一个 7 字节大小的前导码,它通知接收系统帧正在开始,并允许发送方和接收方建立位同步。

SFD(帧开始分隔符)

这是一个 1 字节字段,用于表示目标 MAC 地址字段从下一个字节开始。有时SFD字段被认为是前导码的一部分。这就是为什么前导码在很多地方被认为是 8 字节的原因。

  • 目标 MAC - 这是一个 6 字节字段,其中包含接收系统的地址。

  • 源 MAC - 这是一个 6 字节字段,其中包含发送系统的地址。

  • 类型- 它定义帧内的协议类型。例如,IPv4 或 IPv6。它的大小是2个字节。

  • 数据- 这也称为有效负载,实际数据插入此处。它的长度必须在 46-1500 字节之间。如果长度小于 46 字节,则添加填充 0 以满足最小可能长度,即 46。

  • CRC(循环冗余校验) - 这是一个包含 32 位 CRC 的 4 字节字段,可检测损坏的数据。

扩展以太网帧(Ethernet II 帧)格式

以下是扩展以太网帧的图形表示,使用它我们可以获得大于 1500 字节的有效负载 -

字段名称 目的地MAC地址 源MAC 类型 数字化SAP 安全性评估计划 控制键 数据 CRC
大小(以字节为单位) 6 6 2 1 1 1 >46 4

与 IEEE 802.3 以太网帧不同的字段描述如下:

DSAP(目的地服务接入点)

DSAP 是一个 1 字节长的字段,表示打算接收消息的网络层实体的逻辑地址。

SSAP(源服务访问点)

SSAP 是一个 1 字节长的字段,表示创建消息的网络层实体的逻辑地址。

控制键

这是一个 1 字节的控制字段。

IP数据包架构

Internet 协议是 TCP/IP 协议族中的主要协议之一。该协议工作在 OSI 模型的网络层和 TCP/IP 模型的 Internet 层。因此,该协议负责根据主机的逻辑地址来识别主机,并通过底层网络在它们之间路由数据。IP 提供了一种通过 IP 寻址方案唯一标识主机的机制。IP采用尽力而为的传送方式,即它不保证数据包一定能传送到目的地主机,但会尽最大努力到达目的地。

在后续部分中,我们将了解两个不同版本的 IP。

IPv4

这是互联网协议版本 4,它使用 32 位逻辑地址。以下是 IPv4 标头的图表以及字段的描述 -

IPv4

版本

这是所使用的互联网协议版本;例如,IPv4。

国际人道法

互联网标头长度;整个IP报头的长度。

数字化SCP

差异化服务代码点;这是服务类型。

电子通讯网络

明确的拥塞通知;它携带有关路线中所见拥塞的信息。

总长度

整个IP数据包的长度(包括IP标头和IP负载)。

鉴别

如果IP数据包在传输过程中被分片,则所有分片都包含相同的标识号。

旗帜

根据网络资源的要求,如果 IP 数据包太大而无法处理,这些“标志”会告诉它们是否可以分段。在这个 3 位标志中,MSB 始终设置为“0”。

片段偏移

该偏移量告诉原始 IP 数据包中片段的确切位置。

生存时间

为了避免网络中出现循环,每个数据包在发送时都会设置一些 TTL 值,该值告诉网络该数据包可以穿过多少个路由器(跳)。在每一跳,其值都会减一,当该值达到零时,数据包将被丢弃。

协议

告诉目的主机的网络层这个数据包属于哪个协议,即下一级协议。例如,ICMP的协议号为1,TCP为6,UDP为17。

标头校验和

该字段用于保存整个标头的校验和值,然后用于检查数据包是否无误接收。

源地址

数据包发送者(或源)的 32 位地址。

目的地地址

数据包接收方(或目的地)的 32 位地址。

选项

这是一个可选字段,如果 IHL 的值大于 5,则使用该字段。这些选项可能包含安全、记录路由、时间戳等选项的值。

如果您想详细研究IPv4,请参考此链接 - www.tutorialspoint.com/ipv4/index.htm

IPv6

互联网协议版本 6 是最新的通信协议,与其前身 IPv4 一样,工作在网络层(第 3 层)。除了提供大量的逻辑地址空间之外,该协议还具有丰富的功能,可以解决 IPv4 的缺点。以下是 IPv4 标头的图表以及字段的描述 -

IPv6

版本(4 位)

它代表互联网协议的版本——0110。

流量类别(8 位)

这8位分为两部分。最高有效 6 位用于服务类型,让路由器知道应向该数据包提供哪些服务。最低有效 2 位用于显式拥塞通知 (ECN)。

流标签(20 位)

该标签用于维护属于通信的数据包的顺序流。源标记序列以帮助路由器识别特定数据包属于特定信息流。该字段有助于避免数据包的重新排序。它专为流媒体/实时媒体而设计。

有效负载长度(16 位)

该字段用于告诉路由器特定数据包在其有效负载中包含多少信息。有效负载由扩展标头和上层数据组成。采用16位,最多可指示65535字节;但如果扩展头包含Hop-by-Hop扩展头,则有效负载可能超过65535字节,并且该字段设置为0。

下一个标头(8 位)

该字段要么用于指示扩展标头的类型,要么如果扩展标头不存在,则它指示上层 PDU。上层 PDU 类型的值与 IPv4 的相同。

跳数限制(8 位)

该字段用于阻止数据包在网络中无限循环。这与 IPv4 中的 TTL 相同。Hop Limit 字段的值在通过链路(路由器/跳)时减 1。当该字段达到0时,数据包被丢弃。

源地址(128 位)

该字段指示数据包的发起者的地址。

目标地址(128 位)

该字段提供数据包的预期接收者的地址。

如果您想详细研究 IPv6,请参考此链接 — www.tutorialspoint.com/ipv6/index.htm

TCP(传输控制协议)报头架构

我们知道,TCP 是一种面向连接的协议,在开始通信之前,两个系统之间会建立会话。一旦通信完成,连接就会关闭。TCP 使用三向握手技术在两个系统之间建立连接套接字。三向握手意味着三个消息——SYN、SYN-ACK 和 ACK,在两个系统之间来回发送。两个系统(启动系统和目标系统)之间的工作步骤如下 -

步骤 1 - 设置了 SYN 标志的数据包

首先,尝试启动连接的系统以设置了 SYN 标志的数据包开始。

步骤 2 - 设置了 SYN-ACK 标志的数据包

现在,在这一步中,目标系统返回一个带有 SYN 和 ACK 标志集的数据包。

步骤 3 - 设置了 ACK 标志的数据包

最后,发起系统将向原始目标系统返回一个设置了 ACK 标志的数据包。

以下是 TCP 标头的图表以及字段的描述 -

设置了 ACK 标志的 TCP 数据包

源端口(16 位)

它标识发送设备上应用程序进程的源端口。

目标端口(16 位)

它标识接收设备上应用程序进程的目标端口。

序列号(32 位)

会话中段的数据字节的序列号。

确认号(32 位)

当 ACK 标志被设置时,该数字包含预期数据字节的下一个序列号,并作为对先前接收到的数据的确认。

数据偏移(4 位)

该字段表示 TCP 标头的大小(32 位字)以及当前数据包中数据在整个 TCP 段中的偏移量。

保留(3 位)

保留供将来使用并默认设置为零。

标志(每个 1 位)

  • NS - 显式拥塞通知信令过程使用此 Nonce Sum 位。

  • CWR - 当主机接收到设置了 ECE 位的数据包时,它会设置“拥塞窗口减少”以确认已收到 ECE。

  • ECE - 它有两个含义 -

    • 如果 SYN 位清除为 0,则 ECE 表示 IP 数据包已设置其 CE(拥塞经历)位。

    • 如果 SYN 位设置为 1,ECE 表示设备具有 ECT 功能。

  • URG - 表示紧急指针字段具有重要数据,应进行处理。

  • ACK - 表示确认字段具有重要意义。如果ACK清为0,则表明数据包不包含任何确认。

  • PSH - 设置后,它是对接收站的请求,将数据(一旦到达)推送到接收应用程序而不对其进行缓冲。

  • RST - 重置标志具有以下功能 -

    • 它用于拒绝传入连接。

    • 它用于拒绝一个段。

    • 它用于重新启动连接。

  • SYN - 该标志用于在主机之间建立连接。

  • FIN - 该标志用于释放连接,此后不再交换任何数据。由于带有 SYN 和 FIN 标志的数据包具有序列号,因此它们会按正确的顺序进行处理。

窗户尺寸

该字段用于两个站之间的流量控制,并指示接收器为段分配的缓冲区量(以字节为单位),即接收器期望有多少数据。

  • 校验和- 该字段包含标头、数据和伪标头的校验和。

  • 紧急指针- 如果 URG 标志设置为 1,则它指向紧急数据字节。

  • 选项- 它促进了常规标头未涵盖的附加选项。选项字段始终以 32 位字描述。如果该字段包含小于 32 位的数据,则使用填充来覆盖剩余位以达到 32 位边界。

如果你想详细学习TCP,请参考这个链接 — https://www.tutorialspoint.com/data_communication_computer_network/transmission_control_protocol.htm

UDP(用户数据报协议)报头架构

UDP 是一种简单的无连接协议,与面向连接的协议 TCP 不同。它涉及最少量的通信机制。在 UDP 中,接收方不会生成对已接收数据包的确认,而发送方也不会等待对已发送数据包的任何确认。这个缺点使得该协议不可靠并且更容易处理。以下是 UDP 标头的图表以及字段的描述 -

UPD

源端口

该 16 位信息用于识别数据包的源端口。

目的端口

此 16 位信息用于识别目标计算机上的应用程序级别服务。

长度

长度字段指定UDP数据包的整个长度(包括报头)。它是一个16位字段,最小值为8字节,即UDP报头本身的大小。

校验和

该字段存储发送方在发送前生成的校验和值。IPv4 将此字段作为可选字段,因此当校验和字段不包含任何值时,它将设为 0 并且其所有位都设置为零。

要详细研究 TCP,请参考此链接 —用户数据报协议

套接字及其方法

套接字是双向通信通道的端点。它们可以在进程内、同一机器上的进程之间或不同机器上的进程之间进行通信。类似地,网络套接字是在计算机网络(例如 Internet)上运行的两个程序之间的通信流中的一个端点。它纯粹是一个虚拟的东西,不代表任何硬件。网络套接字可以通过 IP 地址和端口号的唯一组合来标识。网络套接字可以通过许多不同的通道类型(例如 TCP、UDP 等)来实现。

网络编程中使用的与套接字相关的不同术语如下:

领域

域是用作传输机制的协议族。这些值是常量,例如 AF_INET、PF_INET、PF_UNIX、PF_X25 等。

类型

类型表示两个端点之间的通信类型,通常为面向连接的协议的 SOCK_STREAM 和无连接协议的 SOCK_DGRAM。

协议

这可用于识别域和类型内协议的变体。它的默认值为 0。这通常被忽略。

主机名

它用作网络接口的标识符。主机名可以是字符串、点分四组地址或冒号(也可能是点)表示法的 IPV6 地址。

港口

每台服务器都会监听一个或多个端口上的客户端调用。端口可以​​是 Fixnum 端口号、包含端口号的字符串或服务名称。

Python 的 Socket 模块用于套接字编程

要在python中实现socket编程,我们需要使用Socket模块。以下是创建 Socket 的简单语法 -

import socket
s = socket.socket (socket_family, socket_type, protocol = 0)

这里,我们需要导入socket库,然后制作一个简单的socket。以下是创建套接字时使用的不同参数 -

  • socket_family - 这是 AF_UNIX 或 AF_INET,如前所述。

  • socket_type - 这是 SOCK_STREAM 或 SOCK_DGRAM。

  • 协议- 这通常被忽略,默认为 0。

套接字方法

在本节中,我们将了解不同的套接字方法。下面描述了三组不同的套接字方法 -

  • 服务器套接字方法
  • 客户端套接字方法
  • 通用套接字方法

服务器套接字方法

在客户端-服务器架构中,有一台集中式服务器提供服务,许多客户端从该集中式服务器接收服务。客户端也向服务器发出请求。该架构中的一些重要的服务器套接字方法如下 -

  • socket.bind() - 此方法将地址(主机名、端口号)绑定到套接字。

  • socket.listen() - 此方法基本上侦听与套接字建立的连接。它启动 TCP 侦听器。Backlog 是此方法的一个参数,它指定排队连接的最大数量。其最小值为 0,最大值为 5。

  • socket.accept() - 这将接受 TCP 客户端连接。(conn,address)对是该方法的返回值对。这里,conn是一个新的socket对象,用于在连接上发送和接收数据,address是绑定到socket的地址。在使用该方法之前,必须使用socket.bind()和socket.listen()方法。

客户端套接字方法

客户端-服务器架构中的客户端向服务器请求并接收来自服务器的服务。为此,只有一种专用于客户的方法 -

  • socket.connect(address) - 此方法主动建立服务器连接,或者简单地说,此方法将客户端连接到服务器。参数地址表示服务器的地址。

通用套接字方法

除了客户端和服务器套接字方法之外,还有一些通用套接字方法,它们在套接字编程中非常有用。一般套接字方法如下 -

  • socket.recv(bufsize) - 顾名思义,此方法从套接字接收 TCP 消息。参数 bufsize 代表缓冲区大小,定义该方法在任一时间可以接收的最大数据。

  • socket.send(bytes) - 此方法用于将数据发送到连接到远程计算机的套接字。参数 bytes 将给出发送到套接字的字节数。

  • socket.recvfrom(data, address) - 此方法从套接字接收数据。此方法返回两对(数据、地址)值。Data定义了接收到的数据,address指定了发送数据的socket地址。

  • socket.sendto(data, address) - 顾名思义,此方法用于从套接字发送数据。此方法返回两对(数据、地址)值。数据定义发送的字节数,地址指定远程机器的地址。

  • socket.close() - 此方法将关闭套接字。

  • socket.gethostname() - 此方法将返回主机的名称。

  • socket.sendall(data) - 此方法将所有数据发送到连接到远程计算机的套接字。它会不小心地传输数据,直到发生错误,如果发生错误,它会使用 socket.close() 方法关闭套接字。

建立服务器和客户端之间的连接的程序

为了建立服务器和客户端之间的连接,我们需要编写两个不同的Python程序,一个用于服务器,另一个用于客户端。

服务器端程序

在这个服务器端套接字程序中,我们将使用socket.bind()方法将其绑定到特定的 IP 地址和端口,以便它可以侦听该 IP 和端口上的传入请求。稍后,我们使用socket.listen()方法将服务器置于监听模式。数字(例如 4)作为socket.listen()方法的参数意味着,如果服务器繁忙,则 4 个连接将保持等待,如果第 5 个套接字尝试连接,则连接将被拒绝。我们将使用socket.send()方法向客户端发送消息。最后,我们分别使用socket.accept()socket.close()方法来启动和关闭连接。以下是服务器端程序 -

import socket
def Main():
   host = socket.gethostname()
   port = 12345
   serversocket = socket.socket()
   serversocket.bind((host,port))
   serversocket.listen(1)
   print('socket is listening')
   
   while True:
      conn,addr = serversocket.accept()
      print("Got connection from %s" % str(addr))
      msg = 'Connecting Established'+ "\r\n"
      conn.send(msg.encode('ascii'))
      conn.close()
if __name__ == '__main__':
   Main()

客户端程序

在客户端socket程序中,我们需要制作一个socket对象。然后我们将连接到服务器运行的端口 - 在我们的示例中为 12345。之后我们将使用socket.connect()方法建立连接。然后通过使用socket.recv()方法,客户端将接收来自服务器的消息。最后,socket.close()方法将关闭客户端。

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = socket.gethostname()
port = 12345

s.connect((host, port))
msg = s.recv(1024)

s.close()
print (msg.decode('ascii'))

现在,运行服务器端程序后,我们将在终端上得到以下输出 -

socket is listening
Got connection from ('192.168.43.75', 49904)

运行客户端程序后,我们将在其他终端上得到以下输出 -

Connection Established

处理网络套接字异常

有两个块,即tryexcept,可用于处理网络套接字异常。以下是用于处理异常的 Python 脚本 -

import socket
host = "192.168.43.75"
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

try:
   s.bind((host,port))
   s.settimeout(3)
   data, addr = s.recvfrom(1024)
   print ("recevied from ",addr)
   print ("obtained ", data)
   s.close()
except socket.timeout :
   print ("No connection between client and server")
   s.close()

输出

上述程序生成以下输出 -

No connection between client and server

在上面的脚本中,首先我们创建了一个套接字对象。接下来是提供运行我们的服务器的主机 IP 地址和端口号 — 在我们的示例中为 12345。稍后,使用 try 块,并在其中使用socket.bind()方法,我们将尝试绑定 IP 地址和端口。我们使用socket.settimeout()方法来设置客户端的等待时间,在我们的示例中我们设置为 3 秒。使用 except 块,如果服务器和客户端之间未建立连接,它将打印一条消息。

Python 网络扫描器

端口扫描可以定义为一种监视技术,用于定位特定主机上可用的开放端口。网络管理员、渗透测试人员或黑客都可以使用此技术。我们可以根据需要配置端口扫描器,以从目标系统获取最多的信息。

现在,考虑运行端口扫描后我们可以获得的信息 -

  • 有关开放端口的信息。

  • 有关每个端口上运行的服务的信息。

  • 目标主机的操作系统和MAC地址信息。

端口扫描就像一个小偷想要进入一个房子,通过检查每扇门窗来看看哪些是开着的。如前所述,用于通过互联网进行通信的 TCP/IP 协议簇由 TCP 和 UDP 两个协议组成。这两种协议都有 0 到 65535 端口。由于始终建议关闭我们系统中不必要的端口,因此本质上有超过 65000 个门(端口)需要锁定。这些 65535 端口可以分为以下三个范围 -

  • 系统或众所周知的端口:从0到1023

  • 用户或注册端口:从 1024 到 49151

  • 动态或私有端口:全部 > 49151

使用 Socket 的端口扫描器

在上一章中,我们讨论了套接字是什么。现在,我们将使用套接字构建一个简单的端口扫描器。以下是使用套接字进行端口扫描的 Python 脚本 -

from socket import *
import time
startTime = time.time()

if __name__ == '__main__':
   target = input('Enter the host to be scanned: ')
   t_IP = gethostbyname(target)
   print ('Starting scan on host: ', t_IP)
   
   for i in range(50, 500):
      s = socket(AF_INET, SOCK_STREAM)
      
      conn = s.connect_ex((t_IP, i))
      if(conn == 0) :
         print ('Port %d: OPEN' % (i,))
      s.close()
print('Time taken:', time.time() - startTime)

当我们运行上面的脚本时,它会提示输入主机名,您可以提供任何主机名,例如任何网站的名称,但要小心,因为端口扫描可能被视为或解释为犯罪。未经您所针对的服务器或计算机所有者的明确书面许可,我们绝不应对任何网站或 IP 地址执行端口扫描程序。端口扫描类似于去某人的房子检查他们的门窗。这就是为什么建议在本地主机或您自己的网站(如果有)上使用端口扫描器。

输出

上面的脚本生成以下输出 -

Enter the host to be scanned: localhost
Starting scan on host: 127.0.0.1
Port 135: OPEN
Port 445: OPEN
Time taken: 452.3990001678467

输出显示,在 50 到 500 的范围内(如脚本中提供的),此端口扫描器发现两个端口 - 端口 135 和 445,处于打开状态。我们可以更改此范围并检查其他端口。

使用 ICMP 的端口扫描器(网络中的实时主机)

ICMP 不是端口扫描,而是用于 ping 远程主机以检查主机是否已启动。当我们必须检查网络中的许多活动主机时,此扫描非常有用。它涉及向主机发送 ICMP ECHO 请求,如果该主机处于活动状态,它将返回 ICMP ECHO 答复。

使用 ICMP 的端口扫描器

上述发送ICMP请求的过程也称为ping扫描,它是由操作系统的ping命令提供的。

Ping 扫描的概念

实际上,从某种意义上说,ping 扫描也称为 ping 扫描。唯一的区别是 ping 扫描是在特定网络范围内查找多台计算机可用性的过程。例如,假设我们要测试完整的IP地址列表,那么使用ping扫描,即操作系统的ping命令,一一扫描IP地址将非常耗时。这就是为什么我们需要使用 ping 扫描脚本。以下是使用 ping 扫描查找活动主机的 Python 脚本 -

import os
import platform

from datetime import datetime
net = input("Enter the Network Address: ")
net1= net.split('.')
a = '.'

net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
oper = platform.system()

if (oper == "Windows"):
   ping1 = "ping -n 1 "
elif (oper == "Linux"):
   ping1 = "ping -c 1 "
else :
   ping1 = "ping -c 1 "
t1 = datetime.now()
print ("Scanning in Progress:")

for ip in range(st1,en1):
   addr = net2 + str(ip)
   comm = ping1 + addr
   response = os.popen(comm)
   
   for line in response.readlines():
      if(line.count("TTL")):
         break
      if (line.count("TTL")):
         print (addr, "--> Live")
         
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: ",total)

上面的脚本分为三个部分。它首先选择要进行 ping 扫描扫描的 IP 地址范围,并将其分成几部分。接下来是使用该功能,该功能会根据操作系统选择进行 ping 扫描的命令,最后给出有关主机的响应以及完成扫描过程所需的时间。

输出

上面的脚本生成以下输出 -

Enter the Network Address: 127.0.0.1
Enter the Starting Number: 1
Enter the Last Number: 100

Scanning in Progress:
Scanning completed in: 0:00:02.711155

上面的输出显示没有实时端口,因为防火墙已打开并且 ICMP 入站设置也已禁用。更改这些设置后,我们可以获得输出中提供的 1 到 100 范围内的实时端口列表。

使用 TCP 扫描的端口扫描器

要建立 TCP 连接,主机必须执行三次握手。请按照以下步骤执行操作 -

步骤 1 - 设置了 SYN 标志的数据包

在此步骤中,尝试启动连接的系统以设置了 SYN 标志的数据包开始。

步骤 2 - 设置了 SYN-ACK 标志的数据包

在此步骤中,目标系统返回带有 SYN 和 ACK 标志集的数据包。

步骤 3 - 设置了 ACK 标志的数据包

最后,发起系统将向原始目标系统返回一个设置了 ACK 标志的数据包。

然而,这里出现的问题是,如果我们可以使用 ICMP 回显请求和回复方法(ping 扫描扫描仪)进行端口扫描,那么为什么我们需要 TCP 扫描?其背后的主要原因是,假设如果我们关闭 ICMP ECHO 回复功能或对 ICMP 数据包使用防火墙,则 ping 扫描扫描器将无法工作,我们需要 TCP 扫描。

import socket
from datetime import datetime
net = input("Enter the IP address: ")
net1 = net.split('.')
a = '.'

net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
t1 = datetime.now()

def scan(addr):
   s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   socket.setdefaulttimeout(1)
   result = s.connect_ex((addr,135))
   if result == 0:
      return 1
   else :
      return 0

def run1():
   for ip in range(st1,en1):
      addr = net2 + str(ip)
      if (scan(addr)):
         print (addr , "is live")
         
run1()
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: " , total)

上面的脚本工作