diff --git a/scripts/favicon-db b/scripts/favicon-db new file mode 100644 index 000000000..ab40d63c8 --- /dev/null +++ b/scripts/favicon-db @@ -0,0 +1,50 @@ +68B329DA9893E34099C7D8AD5CB9C940:1 byte invalid Favicon +AF999538CD3D4D0370F3EA92E0A6070F:H-Sphere Hosting Control Panel +10BD6AD7B318DF92D9E9BD03104D9B80:Plone CMS +A34DEA4BD04BDB816BEA176619C29063:Confixx Hosting Control Panel +2C0067D9382A7F1751FED2D200F38DB7:Point2 Real State Website (Point2 Real State Marketing Solution) +63B982EDDD64D44233BAA25066DB6BC1:Joomla! CMS +E9E6C56F63122FB05E6899E1DEDD0734:Worldsoft CMS +F30B5ED270A57EABEA60BEB935E2B800:FC2 Blog/.fc2.com domain/hosted website +EC49973C1991BF39FCDB53260467F39F:Parallels H-Sphere Hosting Control Panel +292B586171617B56E77EE694485B1052:hover costumer (www.hover.com) +E52C40433AA5F9256E521D7C139A05BD:GovOffice (Governmental Office CMS) +4644F2D45601037B8423D45E13194C93:Apache Tomcat +2C338C26309E13987D315D85F499D7F2:e107 CMS +BEFCDED36AEC1E59EA624582FCB3225C:Thomson/Speedtouch Device +61E029C99ABC5CF058ABC77562A69F98:SchoolCenter Pro (Schoolar CMS) +D16A0DA12074DAE41980A6918D33F031:Thomson/Speedtouch 605 Device +EDAAEF7BBD3072A3A0C3FB3B29900BCB:Powered by Reynolds Web Solutions (Car sales CMS) +A31552D4FCC0EA68D69153E458FE6AB2:Google pages Favicon +73778A17B0D22FFBB7D6C445A7947B92:Apple's Favicon +7194D8AFD9E3A6DD0048149C3F66D60A:Blank Favicon +D99217782F41E71BCAA8E663E6302473:Parallels Plesk Hosting Control Panel +CA79ABA701B8ED97D4505BCD766DF6F3:Favicon seen on Spam Websites +B25DBE60830705D98BA3AAF0568C456A:Netscape iPlanet 6.0 Web Server +325472601571F31E1BF00674C368D335:XSite by a la mode, inc. (Web Site Sollution) +0C46689B7D84E977E3C3683C6F316122:phpBB hosted in Free Forum Services (forumotion.com, forumactif.fr and others) +81ED5FA6453CF406D1D82233BA355B9A:E-zekiel (Church CMS) +226FFC5E483B85EC261654FE255E60BE:Netscape Favicon +FF2C8612B75B5F9A6175E016FE4AA609:Apache Web Server (seen on SuSE, Linux Tux Favicon) +639B61409215D770A99667B446C80EA1:IBM Lotus Notes Collaboration Software +4EB846F1286AB4E7A399C851D7D84CCA:Plone CMS +FA54DBF2F61BD2E0188E47F5F578F736:Wordpress Publishing Plataform (Blog CMS) +C1201C47C81081C7F0930503CAE7F71A:vBulletin Forum Sollution +389A8816C5B87685DE7D8D5FEC96C85B:XOOPS CMS +A5220EF442813C2FC6EE8CF13560278F:.republika.pl domain/hosted website +59A0C7B6E4848CCDABCEA0636EFDA02B:Blogger Favicon +B7EBD6E8609ECBF0F053BAF5F550CB04:Blank Favicon +A28EBCAC852795FE30D8E99A23D377C1:SunOne Web Server +4EE75CA12A52425B9514EE6DE25D23FE:Hostmonster hosted website +6F767458B952D4755A795AF0E4E0AA17:Yahoo! Favicon +7DBE9ACC2AB6E64D59FA67637B1239DF:IBM Lotus Domino Collaboration Software +ECAA88F7FA0BF610A5A26CF545DCD3AA:3 bytes invalid favicon: Domain Sellers Websites +5B0E3B33AA166C88CEE57F83DE1D4E55:DotNetNuke CMS and Framework for ASP.NET +1CE0C63F8BD1E5D3376EC0AE95A41C08:Parallels Plesk Hosting Control Panel +E1E8BDC3CE87340AB6EBE467519CF245:bluehost hosted website +A8FE5B8AE2C445A33AC41B33CCC9A120:Arris Touchstone Device +5E1E9CC940D3BFAA59F51282D9FEC510:.free.fr domain/hosted website +64CA706A50715E421B6C2FA0B32ED7EC:Parallels Plesk Hosting Control Panel +DCEA02A5797CE9E36F19B7590752563E:Parallels Plesk Hosting Control Panel +9CEAE7A3C88FC451D59E24D8D5F6F166:Parallels Plesk Hosting Control Panel +D41D8CD98F00B204E9800998ECF8427E:Zero byte invalid Favicon diff --git a/scripts/http-favicon.nse b/scripts/http-favicon.nse new file mode 100644 index 000000000..4b8c060c9 --- /dev/null +++ b/scripts/http-favicon.nse @@ -0,0 +1,129 @@ +description = [[ +Gets the favicon.ico from the root of a web service and tries to enumerate it +]] + +--- +-- @args favicon.uri Uri that will be requested for favicon +-- @output +-- |_ http-favicon: Found favicon from Socialtext + +-- HTTP default favicon enumeration script +-- rev 1.2 (2009-03-11) +-- Original NASL script by Javier Fernandez-Sanguino Pena + +author = "Vlatko Kosturjak " + +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" + +categories = {"default", "discovery"} + +require "shortport" +require "http" +require "stdnse" +require "datafiles" +require "nsedebug" + +portrule = shortport.port_or_service({80, 443, 8080, 8443}, + {"http", "https", "http-alt", "https-alt"}) + +action = function(host, port) + local md5sum,answer + local match + local status, favicondb + local result= "" + local favicondbfile="favicon-db" + local index, icon + local root = "" + + status, favicondb = datafiles.parse_file( favicondbfile, {["^%s*([^%s#:]+)[%s:]+"] = "^%s*[^%s#:]+[%s:]+(.*)"}) + if not status then + stdnse.print_debug( 1, "Could not open file: %s", favicondbfile ) + return + end + + if not pcall(require,'openssl') then + stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.", filename ) + return + end + + if(nmap.registry.args['favicon.root']) then + root = nmap.registry.args['favicon.root'] + end + + if(nmap.registry.args['favicon.uri']) then + answer = http.get( host, port, root .. "/" .. nmap.registry.args['favicon.uri']) + stdnse.print_debug( 4, "Using URI %s", nmap.registry.args['favicon.uri']) + else + answer = http.get( host, port, root .. "/favicon.ico" ) + stdnse.print_debug( 4, "Using default URI.") + end + + -- if we didn't find a correct favicon, let's parse the first page and search for one! + if answer.status ~= 200 then + stdnse.print_debug( 1, "No favicon found on root of web server, parsing initial page for favicon.") + index = http.get( host, port, root .. "/" ) + -- if we get the first page + if index.status == 200 or index.status == 503 then + -- find the favicon pattern + icon = parseIcon( index.body ) + -- if we find a pattern + if icon then + -- check if the path is in './' format, what means that we must replace it by the root directory + if string.match(icon, "^%.") then + icon = string.gsub(icon, "^%.", root, 1) + end + -- request the favicon + answer = http.get( host, port, icon ) + else + answer = nil + end + end + end + + + --- check for 200 response code + if answer and answer.status == 200 then + md5sum=string.upper(stdnse.tohex(openssl.md5(answer.body))) + match=favicondb[md5sum] + if match then + result = result .. "Found favicon from " .. match .. "." + else + result="Unknown favicon MD5: " .. md5sum + end + else + stdnse.print_debug( 1, "No favicon found.") + return + end --- status == 200 + return result +end + +function parseIcon( body ) + local icon, absolute_icon, parsed_icon + local tag_start, tag_end, tag + local tags = {} + + -- separate tags + tag_start, tag_end = string.find(body,'(<.->)') + while tag_start do + tag = string.sub(body, tag_start, tag_end) + body = string.sub(body, tag_end) + tags[#tags+1] = tag + tag_start, tag_end = string.find(body,'(<.->)') + end + + -- check each tag for our favicon tag + for k, v in ipairs(tags) do + icon = string.match( v, '<(%s-link.-rel%s-=%s-".-icon".-/?)>') + if icon then + icon = string.match( icon, 'href%s*=%s*"(.-)"') + -- if favicon is in absolute format, we need to parse it! + absolute_icon = string.match(icon, '^http://') + if absolute_icon then + parsed_icon = url.parse(icon) + icon = parsed_icon.path + end + break + end + end + return icon +end diff --git a/scripts/script.db b/scripts/script.db index 969b27f43..e32bede50 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -16,6 +16,7 @@ Entry { filename = "http-auth.nse", categories = { "auth", "default", "intrusive Entry { filename = "http-date.nse", categories = { "discovery", "safe", } } Entry { filename = "http-enum.nse", categories = { "discovery", "intrusive", "vuln", } } Entry { filename = "http-headers.nse", categories = { "discovery", } } +Entry { filename = "http-favicon.nse", categories = { "default", "discovery", } } Entry { filename = "http-iis-webdav-vuln.nse", categories = { "intrusive", "vuln", } } Entry { filename = "http-open-proxy.nse", categories = { "default", "discovery", "external", "intrusive", } } Entry { filename = "http-passwd.nse", categories = { "intrusive", "vuln", } }