description = [[ Attempts to find rogue AP devices using common signatures from HTTP banners and OS fingerprints. ]] --- --@output -- Interesting ports on scanme.nmap.org (64.13.134.52): -- PORT STATE SERVICE -- 80/tcp open http -- |_ rogueap: Possible Rogue AP Found: "WRT54" author = "Joshua Wright" -- Most of these code was from Diman Todorov's htlm-title.nse script license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"default", "discovery", "safe"} local url = require 'url' local dns = require 'dns' local http = require 'http' local ipOps = require 'ipOps' local stdnse = require 'stdnse' portrule = function(host, port) local svc = { std = { ["http"] = 1, ["http-alt"] = 1 }, ssl = { ["https"] = 1, ["https-alt"] = 1 } } if port.protocol ~= 'tcp' or not ( svc.std[port.service] or svc.ssl[port.service] ) then return false end -- Don't bother running on SSL ports if we don't have SSL. if (svc.ssl[port.service] or port.version.service_tunnel == 'ssl') and not nmap.have_ssl() then return false end return true end -- Nmap OS fingerprints for WAP devices as of Nmap 5.21 -- grep -B1 WAP nmap-os-db | grep ^Fingerprint | sed 's/^Fingerprint //' ossigs = { "2Wire 1701HG wireless ADSL modem", "2Wire 1701HG wireless ADSL modem", "2Wire 2700HG, 2700HG-B, 2701HG-B, or RG2701HG wireless ADSL modem", "2Wire 2700HG-B wireless ADSL modem", "2Wire 2701HG wireless ADSL modem", "2Wire 2701HG-B wireless ADSL modem", "2Wire Shasta wireless broadband router", "3Com OfficeConnect 3CRWDR100A-72 wireless ADSL modem", "3Com OfficeConnect 3CRWE554G72T wireless broadband router", "3Com OfficeConnect 3CRWER100-75 wireless broadband router", "3Com OfficeConnect 3CRWER100-75 wireless router", "Wireless broadband router (3Com OfficeConnect 3CRWDR100A-72, Philips SNB6500, Sinus 154, SMC SMCWEBT-G, or SMC SMCWBR14-G2)", "Aastra 6731i VoIP phone or Apple AirPort Express WAP", -- Excluding non-WiFi WAP (DECT) -- "Aastra RFP L32 IP DECT WAP", "Acorp W400G or W422G wireless ADSL modem (MontaVista embedded Linux 2.4.17)", "Actiontec R3010UW wireless broadband router", "WAP: Airnet AWR014G; D-Link DI-524, DI-604, DI-624, or WBR-2310; or TRENDnet TEW-432BRP or TEW-452BRP (ThreadX)", "AirSpan ProST WiMAX access point", "Alvarion BreezeACCESS II broadband wireless access system 4.5.17", "Alvarion CPE-Si-E-2.3 BreezeMAX WiMAX WAP", "Apple AirPort Extreme WAP or Time Capsule NAS device (NetBSD)", "Apple AirPort Express WAP", "Apple AirPort Express WAP v6.3", "Apple AirPort Extreme WAP", "Apple AirPort Extreme WAP v7.3.2", "VxWorks: Apple AirPort Extreme v5.7 or AirPort Express v6.3; Canon imageRUNNER printer (5055, C3045, C3380, or C5185); Kyocera FS-4020DN printer; or Xerox Phaser 8860MFP printer", "Asus WL-500gP wireless broadband router", "AVM FRITZ!Box FON WLAN 7050, Linksys WAG200G, or Netgear DG834GT wireless broadband router", "AVM FRITZ!Box FON WLAN 7170 WAP", "Belkin F5D8233 WAP", "Belkin F6D4630-4 v1 WAP", "Belkin Wireless Pre-N Router", "Belkin F5D7633, Inventel Livebox, or T-Sinus 1054 wireless broadband router; or USRobotics SureConnect 9105 or ZTE ZXDSL 831 ADSL modem", "BinTec R1200 WAP", "Aastra 480i GT or 9133i IP phone, Allen-Bradley ControlLogix 1756-EWEB web server module, Canon imageRUNNER 2570Ci printer, Compex WPE54G WAP, Harmonic MaxLink HLT 7806R optical network transmitter, Hitachi WMS 100 SAN controller, Inter-tel 8662 VoIP phone, Netgear SC101 Storage Central NAS device, Sony LocationFree media server, Scopus IVG-7100 media server, Westell WireSpeed Dual Connect broadband router, or Xerox Phaser 6120/N printer", "Cisco 800-series, 1801, 2000-series, 3800, 4000, or 7000-series router; or 1100 or 1242G WAP (IOS 12.2 - 12.4)", "Cisco Aironet 1240AG or 1250 WAP, 1811 or 2800 router, or VG 224 VoIP gateway (IOS 12.4)", "Cisco 1131AG WAP (IOS 12.3)", "Cisco Aironet 1200 WAP (IOS 12.3)", "Cisco Aironet 1230 or 1240-series WAP (IOS 12.3)", "Cisco Aironet 1231G WAP (IOS 12.3)", "Cisco Aironet 1250 WAP (IOS 12.4)", "Cisco Aironet 350 or 1200 WAP", "Cisco Aironet 350, 1100, 1200, or 1131AG WAP; or Cisco Catalyst 2600 router (IOS 12.3)", "Cisco Aironet AIR-AP1141N WAP (IOS 12.4)", "Cisco AP340 WAP (VxWorks 5.4)", "Compaq iPAQ CP-2W Connection Point WAP", "D-Link DPR-1260 print server; or DGL-4300, DIR-625, or DIR-655 WAP", "D-Link DI-524 or DI-604, SMC SMC7004VBR, or ZyXEL Prestige 320W broadband router", "D-Link DI-524 or WBR-2310 wireless broadband router", "D-Link DI-524 wireless broadband router", "D-Link DI-524 wireless broadband router", "D-Link DI-714P+ wireless broadband router", "D-Link DI-824VUP Wireless VPN Router", "D-Link DSA-3100 or Linksys WRT54GL (DD-WRT v23) WAP, or Peplink Balance 30 router", "D-Link DWL-2100AP wireless access point", "D-Link DWL-624+ or DWL-2000AP, or TRENDnet TEW-432BRP WAP", "D-Link DWL-900AP+ or USRobotics USR5450 WAP", "D-Link DWL-G700AP WAP", "D-Link DWL-G810 WAP", "WAP (Cisco Aironet 1010, D-Link DWL-2100AP, Linksys WAP51AB or WAP55AG, Netgear WPN824, or Proxim ORiNOCO AP-4000M), Lights-Out remote server management, or ReplayTV 5500 DVR", "D-Link DIR-100, or Netgear KWRGR614 or RT614 broadband router (Linux 2.4)", "D-Link DSL-G624T wireless ADSL router (MontaVista embedded Linux 2.4.17), or Netgear DG834Bv3 ADSL router or DG834G WAP", "Enterasys RBT-8400 WAP", "DD-WRT v24 (Linux 2.6.22)", "Gemtek P360 WAP or Siemens Gigaset SE515dsl wireless broadband router", "HP ProCurve MSM422 WAP", "Kaiomy AL-2014PW wireless ADSL modem or Planet ADE-4110 ADSL modem", "KCorp KLG-575 WAP", "Lancom L-54ag WAP (LCOS)", "Lancom L-54g WAP (LCOS)", "Linksys BEFSR41 or RT31P2 router, or WRK54G WAP", "Linksys WRT54GX2 WAP", "ADSL modem: Linksys AM300, Philips CGA5722 or SNA6500, Siemens Gigaset SX541, T-Sinus 111, or USRobotics USR9111", "Linksys AM300 wireless ADSL modem", "Linksys BEFW11S4 WAP", "Linksys BEFW11S4 WAP", "Linksys BEFW11S4 WAP", "Linksys WAP11 WAP or SMC SMCWBR14-G broadband router", "Linksys WAP54G WAP", "Linksys WAP54G WAP", "Linksys WET54GS5 WAP or Xerox WorkCentre Pro 265 printer", "Linksys WRK54G WAP", "Linksys WRT54G or WRT54G2, or Netgear WGR614 or WPN824v2 wireless broadband router", "Linksys WRT54G v8 wireless broadband router", "Linksys WRT54GC or TRENDnet TEW-431BRP wireless broadband router", "OpenWrt White Russian 0.9 (Linux 2.4.30)", "DD-WRT (Linux 2.4.35s)", "DD-WRT v23 (Linux 2.4.34)", "DD-WRT v23 (Linux 2.4.36)", "DD-WRT v23 - v24 (Linux 2.4.20 - 2.4.37)", "DD-WRT v24 SP1 (Linux 2.4)", "DD-WRT v24 SP2 (Linux 2.4.36)", "OpenWrt (Linux 2.4.30 - 2.4.34)", "OpenWrt (Linux 2.4.32)", "OpenWrt (Linux 2.4.32)", "OpenWrt 0.9 - 7.09 (Linux 2.4.30 - 2.4.34)", "OpenWrt 0.9 - 7.09 (Linux 2.4.30 - 2.4.34)", "OpenWrt Kamikaze 8.09 (Linux 2.4.35.4)", "OpenWrt White Russian 0.9 (Linux 2.4.30)", "Sveasoft (Linux 2.4.20)", "OpenWrt Kamikaze 7.09 (Linux 2.6.17 - 2.6.21)", "OpenWrt Kamikaze 7.09 (Linux 2.6.22)", "MicroNet SP2267 wireless ADSL router", "Microsoft MN-700 wireless broadband router", "Motorola SURFboard SBG900 wireless cable modem", "Netgear WGT624 WAP", "Netgear DG834GB wireless broadband router", "Netgear ProSafe WG302 v2 WAP", "Netgear WGR614v7 WAP", "Netgear WGR614v7 wireless broadband router", "Netgear WGR614v7, WGT624v3, or WPN824v2 WAP (VxWorks 5.4.2)", "Netgear HE102 WAP (VxWorks)", "Novatel MiFi 2200 3G WAP", "Orange Livebox wireless DSL router or Sagem F@st 334 DSL router", "PheeNet WAP-854GP WAP", "Pirelli DRG A226M wireless ADSL modem", "Planet WAP-1950 WAP", "Planet WAP-4000 v2 WAP", "Proxim Tsunami MP.11a WAP", "Senao NL-2611CB3 PLUS WAP", "Siemens Gigaset SE567 WAP or SpeedStream 4200 ADSL modem", "Siemens Gigaset SE551 wireless broadband router", "Siemens Gigaset SE551 wireless broadband router", "Sitecom WL-174 wireless ADSL router or ZyXEL B-3000 WAP", "SMC SMCWBR14-G2 Barricade N WAP", "Belkin F5D7230-4 WAP or SMC SMC7008ABR router", "SMC 7904WBRA-N wireless ADSL router", "SMC SMC2804WBRP-G wireless broadband router", "SMC SMC7904WBRA wireless ADSL router or T-Home Speedport W 700V WAP", "SMC SMC7904WBRB2 wireless broadband router", "Symbol Spectrum24 4131 Access Point", "Symbol WS5000 wireless switch", "Symbol WS5000 wireless switch", "T-Home Speedport W 700V WAP", "T-Home Speedport W 700V WAP", "USRobotics USR5450 WAP", "WatchGuard Firebox X5w firewall/WAP", "XAVi X7868r wireless ADSL modem", "Xirrus XS8 WAP", "Pi-Point", "ZyXEL G-3000H WAP (ZyNOS 3.50)" } bannersigs = { "SetExpress.shm", "D-Link DI-1750", "D-Link DI-824", "D-Link DI-784", "D-Link DI-774", "D-Link DI-764", "D-Link DI-754", "D-Link DI-714", "D-Link DI-713", "D-Link DI-624", "DI-624+", "D-Link DI-614", "D-Link DI-524", "D-Link DI-514", "D-Link DSA-3100", "Cisco AP340", "Cisco AP350", "Linksys WAP", 'Linksys WRT', "Linksys BEFW", "Linksys WPG", "Linksys WRV", "SOHO Version", 'BUFFALO WBR-G54', 'WWW-Authenticate: Basic R2 Wireless Access Platform', 'MR814', 'FM114P', 'MA101', 'MR314', 'ME102', 'DG824M', 'DG834G', 'PS111W', 'CG814M', 'FVM318', 'ME103', 'HE102', 'HR314', 'Ral-WAP3', 'WG101', 'WG302', 'WG602', 'WGR614', 'FWAG114', 'FM114P', 'WKPC', 'WCG', 'WET', 'BEFW', 'WAP11', 'WAP51', 'WAP54', 'WAP55', 'WRT54', 'WRT55', 'WRT300', 'WRV200', 'WRTSL', "BCM430", "OfficePortal 1800HW", "HomePortal 180HW", "Portal 1000HG", "Portal 1000HW", "Portal 1000SW", "Portal 1700HG", "Portal 1700HW", "Portal 1700SG", "HomePortal 180HG", "HomePortal 2000", "Wireless 11a/b/g Access Point", "AT-WA1004G", "AT-WA7500", "AT-WL2411", "RTW020", "RTA040W", "RTW010", "The setup wizard will help you to configure the Wireless", 'Access-Product', "USR8054", "WGR614", "WGR624", "Linksys WET11", "wireless/wireless_tab1.jpg", "wireless/use_as_access_point", "Gateway 11G Router", "Gateway 11B Router", "MN-500", "MN-700", "MN-510", "SBG900", "SBG1000", "WA840G", "WL1200-AB", "WL5400AP", "LANCOM Wireless L-11", "LANCOM L-54g Wireless", "LANCOM L-54ag Wireless", "Linksys BEFW11", "Server: DCS-", "Cisco WGB350", "Wi-LAN AWE", "WRT400N", "WRT160N", "WRT120N", "WRT160NL", "WRT320N", "WRT610N", "WRT310N", "WRT110", "WRT54G2", "E4200", "E3000", "E3200", "E2000", "E1200", "E2100", "E1000", "E1500", "DD-WRT v24-sp2", "DD-WRT", -- Generic indicator if the previous DD-WRT specific types don't match 'PiPoint', "OWRT" } action = function(host, port) local data, result, redir, loc, bannermatch, sig, hostprint -- Check OS fingerprints first if host and host.os ~= nil then for _,hostprint in ipairs(host.os) do for _,sig in ipairs(ossigs) do if hostprint == sig then result = "Possible Rogue AP Found: \""..sig.."\"\n" end end if result ~= nil and result ~= "" then return result end end end -- OS signatures did not match any recognized WAP's, continue with banner checks data = http.get( host, port, '/' ) -- check for a redirect if data and data.status and tostring( data.status ):match( "30%d" ) and data.header and data.header.location then redir = ("Did not follow redirect to %s"):format( data.header.location ) local url = url.parse( data.header.location ) local loc = redirect_ok( url, host, port ) if loc then -- follow redirect redir = ("Requested resource was %s://%s%s%s"):format( url.scheme or port.service, loc.host, (url.port and (":%s"):format(url.port)) or "", loc.path ) data = http.get( loc.host, loc.port, loc.path ) else loc = nil -- killed so we know we didn't follow a redirect end end -- check that body was received if data.body and data.body ~= "" then result = nil else -- debug msg and no output; or no debug msg and some output if we were redirected. if not redir then stdnse.print_debug( "rogueap.nse: %s did not respond with any data.", host.targetname or host.ip ) end return (redir and ("%s %s no page was returned."):format( redir, (loc and ", but") or "and" )) or nil end -- Debugging included to make it easier to collect signature information if nmap.debugging() > 0 then for hdrtag,hdrval in pairs(data.header) do stdnse.print_debug( 1, "%s: HTTP Header: %s -> %s", SCRIPT_NAME, hdrtag, hdrval) end stdnse.print_debug( 1, "%s: HTTP Payload:\n%s", SCRIPT_NAME, data.body) end for _,sig in ipairs(bannersigs) do bannermatch = string.match(data.body, sig) if bannermatch and bannermatch ~= "" then result = "Possible Rogue AP Found: \""..sig.."\"\n" else -- iterate through each of the header AVPs for hdrtag,hdrval in pairs(data.header) do bannermatch = string.match(hdrval,sig) if bannermatch and bannermatch ~= "" then result = "Possible Rogue AP Found: \""..sig.."\"\n" break end end end end return (redir and ("%s\n%s"):format( result, redir )) or result end -- Check if the given URL is okay to redirect to. Return a table with keys -- "host", "port", and "path" if okay, nil otherwise. function redirect_ok(url, host, port) -- A battery of tests a URL is subjected to in order to decide if it may be -- redirected to. They incrementally fill in loc.host, loc.port, and loc.path. local rules = { function (loc, url, host, port) -- bail if userinfo is present return ( url.userinfo and false ) or true end, function (loc, url, host, port) -- if present, url.host must be the same scanned target -- loc.host must be set if returning true if not url.host then loc.host = ( host.targetname or host.ip ) return true end if url.host and url.host == host.ip or url.host == host.targetname or url.host == ( host.name ~= '' and host.name ) then loc.host = url.host return true end return false end, function (loc, url, host, port) -- if present, url.port must be the same as the scanned port -- loc.port must be set if returning true if (not url.port) or tonumber(url.port) == port.number then loc.port = port return true end return false end, function (loc, url, host, port) -- if url.scheme is present then it must match the scanned port if url.scheme and url.port then return true end if url.scheme and url.scheme ~= port.service then return false end return true end, function (loc, url, host, port) -- path cannot be unchanged unless host has changed -- loc.path must be set if returning true if ( not url.path or url.path == "/" ) and url.host == ( host.targetname or host.ip) then return false end if not url.path then loc.path = "/"; return true end loc.path = ( ( url.path:sub(1,1) == "/" and "" ) or "/" ) .. url.path -- ensuring leading slash return true end, function (loc, url, host, port) -- always true - jut add the query to loc.path if url.query then loc.path = ("%s?%s"):format( loc.path, url.query ) end return true end } local loc = {} for i, rule in ipairs( rules ) do if not rule( loc, url, host, port ) then return nil end end if loc.host and loc.port and loc.path then return loc else return nil end end