UNPKG

reavetard

Version:

CoffeeScript modules that provide AP rotation support and a host of data management and general usability enhancements for Reaver-WPS Cracker and its partner in crime, Wash-WPS Scanner

220 lines (199 loc) 8.79 kB
# Reavetard - Reaver WPS (+Wash) extension scripts # wifi.coffee :: Overly complicated module to automate various wifi adapter tasks # such as enabling/disabling monitor mode, changing the MAC address, etc. # Author: Robbie Saunders http://eibbors.com/[/p/reavetard] # ============================================================================== # Module dependencies # ------------------------- {exec} = require 'child_process' cli = require './cli' # airmon-ng commands to start, stop, and check wlan adapter monitor mode # ---------------------------------------------------------------------- airmon = exports.airmon = # Execute airmon-ng + args and call back fancy parsed output run: (args, cb) -> if Array.isArray(args) then args = args.join ' ' if args then cmd = "airmon-ng #{args}" else cmd = "airmon-ng" exec cmd, {}, (err, stdout, stderr) => isIfaces = false results = {} if err then throw(err) else if stdout for section in stdout.split('\n\n') lines = section.split('\n') # Possible problem processes included in output if lines[0] is 'PID\tName' results.processes = {} for line in lines[1..] proc = /(\d+)\t(\w+)/.exec line if proc then results.processes[proc[1]] = { pid: proc[1], name: proc[2] } else oniface = /Process with PID (\d+) \((.*)\) is running on interface (.*)/.exec line if oniface then results.processes[oniface[1]].runningOn = oniface[3] # Grab interfaces, should there be any (these columns are always one section before) if /Interface\tChipset\t\tDriver/g.test section isIfaces = true else if isIfaces isIfaces = false results.interfaces = [] for line in lines # This regex was hard on my eyes for some reason, so I split it up into parts ifrow = /// ([^\t]+)\t+ ([^\t]+)\t+ (\w+)\s-\s \[(\w+)\] (\s+\(removed\))?///.exec line if ifrow then results.interfaces.push interface: ifrow[1] chipset: ifrow[2] driver: ifrow[3] phyid: ifrow[4] removed: ifrow[5] is ' (removed)' else monok = /\s+\(monitor mode enabled on (\w+)\)/.exec line if monok then results.enabledOn = monok[1] cb results, stdout, stderr # Run with no arguments, used to search for all compatible ifaces getInterfaces: (cb) -> @run undefined, (res) -> cb res.interfaces # Return results of above, categorized by phyical name ie: # { phy0: [{mon0}, {wlan2}], phy1: [{wlan1}] } # Useful for determining which cards aren't yet in monitor mode getPhysicalInterfaces: (cb) -> @getInterfaces (ifaces) -> phys = {} for iface in ifaces phys[iface.phyid] ?= [] phys[iface.phyid].push iface cb phys # Start monitor mode on an interface, return parsed results via callback # Optionally, restrict monitor mode to a single channel with channel arg start: (iface, cb, channel=false) -> cmd = ['start', iface] if channel then cmd.push channel @run cmd, (res) -> if res.enabledOn?.length > 0 res.success = true else res.success = false cb res # Stop monitor mode stop: (iface, cb) -> @run ['stop', iface], (res) -> res.success = false for iface in res.interfaces if iface.removed then res.success = true cb res # Check for possible `problem processes` check: (cb) -> @run ['check'], cb # Try to kill the processes returned by check/start kill: (cb) -> @run ['check', 'kill'], cb # iwconfig command - view/edit wireless adapter settings, # ---------------------------------------------------------------------- iwconfig = exports.iwconfig = # Execute iwconfig and call your cb function with its parsed output run: (args, cb) => if Array.isArray(args) then args = args.join ' ' if args then cmd = "iwconfig #{args}" else cmd = 'iwconfig' exec cmd, {}, (err, stdout, stderr) => if err then return cb err, false interfaces = [] # Split by 2 newlines (with(out) spaces too) in a row sections = stdout.split /\n\s*\n/ for section in sections # Parse the iface & supported 802.11 standards / "field-like" strings iwname = /(\w+)\s+IEEE 802\.11(\w+)/.exec section iwflds = section.match /\s\s+((\S+\s?)+)(:|=)\s?((\S+\s?)+)/g if iwname # Once we know its name we need to rename and trim our fields iwtmp = { name: iwname[1], supports: iwname[2].split('') } for flds in iwflds fld = flds.split(/(:|=)/) if fld.length > 3 # Fixes Access Point Bssid, which contains :'s fld[2] = fld[2..].join('') fld[0] = fld[0].replace('-', ' ').trim() fld[0] = fld[0].toLowerCase().replace(/(\s+\w)/g, (m) -> m.trim().toUpperCase()) fld[2] = fld[2].trim() iwtmp[fld[0]] = fld[2] interfaces.push iwtmp cb err, interfaces # Same as running with no args, but can be used to check for the existence of # or simply to filter out a single interface checkWifiSetup: (iface, cb) -> if iface @run '', (err, interfaces) -> for i in interfaces if i.name is iface return cb err, i cb "Error: Interface #{iface} not found!", false else @run '', cb # ifconfig - commands for configuring network interfaces # ---------------------------------------------------------------------- ifconfig = exports.ifconfig = # Execute ifconfig and parse the output... the output that seems horribly # inconsistently formatted. If I'm missing a pattern or trick to handling # all the different possibilities besides hardcoding them one by one as # I'm currently doing, please enlighten me! run: (args, cb) => if Array.isArray(args) then args = args.join ' ' if args then cmd = "ifconfig #{args}" else cmd = 'ifconfig' exec cmd, {}, (err, stdout, stderr) => if err then return cb err, false interfaces = [] # Split by 2 newlines (with(out) spaces too) in a row sections = stdout.split /\n\s*\n/ for section in sections lines = section.split '\n' for line in lines decl = /^(\w+)\s+Link encap:((\s?\w+)+) (HWaddr (\S+) )?/i.exec line if decl # Fairly straightforward if lastiface? then interfaces.push lastiface lastiface = { name: decl[1], type: decl[2], mac: decl[5] } decl = false else # I have to be missing a trick... Please clean me up! pieces = line.split(/\s\s+/) for piece in pieces[1..] attrs = piece.match(/(RX |TX |inet |inet6 )?((\S+):\s?(\S+))+/g) if attrs?.length? >= 1 attcat = attrs[0].split(' ') if attcat?.length is 1 # RX ...\n {child:val} || {Normal:val} ischild = /^([a-z]+):(.*)/g.exec attcat[0] if ischild and lastcat lastiface[lastcat][ischild[1]] = ischild[2] ismore = attrs[1].split ':' if ismore.length > 1 lastiface[lastcat][ismore[0]] = ismore[1] else attr = attcat[0].split(':') lastiface[attr[0]] = attr[1] else if attcat?.length is 2 # RX/TX/inet(6) a:1 b:2 ... lastcat = attcat[0] attr = attcat[1].split(':') lastiface[lastcat] ?= {} lastiface[lastcat][attr[0]] = attr[attr.length - 1] for attr in attrs[1..] attr = attr.split(':') lastiface[lastcat][attr[0]] = attr[attr.length - 1] else if attcat?.length is 3 # inet6 addr: 121:14:14:... lastcat = attcat[0] lastiface[lastcat] ?= {} lastiface[lastcat][attcat[1].replace(':','')] = attcat[2] else if /([A-Z]+ ?)+/g.test piece lastiface.flags = piece.split(' ') interfaces.push lastiface # push the final interface cb err, interfaces all: (cb) -> @run '-a', cb up: (iface, cb) -> @run "#{iface} up", (err) -> if err then cb err, false else cb null, true down: (iface, cb) -> @run "#{iface} down", (err) -> if err then cb err, false else cb null, true