nmap favicon url
This commit is contained in:
parent
61486d7dab
commit
72a9c62d4a
168
http-favicon-url.nse
Normal file
168
http-favicon-url.nse
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
local datafiles = require "datafiles"
|
||||||
|
local http = require "http"
|
||||||
|
local nmap = require "nmap"
|
||||||
|
local shortport = require "shortport"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local string = require "string"
|
||||||
|
local url = require "url"
|
||||||
|
|
||||||
|
local openssl = stdnse.silent_require "openssl"
|
||||||
|
|
||||||
|
description = [[
|
||||||
|
Gets the favicon url ("favorites icon").
|
||||||
|
|
||||||
|
If the script argument <code>favicon.uri</code> is given, that relative URI is
|
||||||
|
always used to find the favicon. Otherwise, first the page at the root of the
|
||||||
|
web server is retrieved and parsed for a <code><link rel="icon"></code>
|
||||||
|
element. If that fails, the icon is looked for in <code>/favicon.ico</code>. If
|
||||||
|
a <code><link></code> favicon points to a different host or port, it is ignored.
|
||||||
|
]]
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @args favicon.uri URI that will be requested for favicon.
|
||||||
|
-- @args favicon.root Web server path to search for favicon.
|
||||||
|
--
|
||||||
|
-- @usage
|
||||||
|
-- nmap --script=http-favicon-url.nse \
|
||||||
|
-- --script-args favicon.root=<root>,favicon.uri=<uri>
|
||||||
|
-- @output
|
||||||
|
-- |_ http-favicon: http://hostname:80/favicon.ico
|
||||||
|
|
||||||
|
-- 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 https://nmap.org/book/man-legal.html"
|
||||||
|
|
||||||
|
categories = {"default", "discovery", "safe"}
|
||||||
|
|
||||||
|
|
||||||
|
portrule = shortport.http
|
||||||
|
|
||||||
|
action = function(host, port)
|
||||||
|
local md5sum,answer
|
||||||
|
local match
|
||||||
|
local status, favicondb
|
||||||
|
local result
|
||||||
|
local favicondbfile="nselib/data/favicon-db"
|
||||||
|
local index, icon
|
||||||
|
local root = ""
|
||||||
|
local url
|
||||||
|
local hostname = host.targetname or (host.name ~= "" and host.name) or host.ip
|
||||||
|
|
||||||
|
status, favicondb = datafiles.parse_file( favicondbfile, {["^%s*([^%s#:]+)[%s:]+"] = "^%s*[^%s#:]+[%s:]+(.*)"})
|
||||||
|
if not status then
|
||||||
|
stdnse.debug1("Could not open file: %s", favicondbfile )
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if(stdnse.get_script_args('favicon.root')) then
|
||||||
|
root = stdnse.get_script_args('favicon.root')
|
||||||
|
end
|
||||||
|
local favicon_uri = stdnse.get_script_args("favicon.uri")
|
||||||
|
if(favicon_uri) then
|
||||||
|
-- If we got a script arg URI, always use that.
|
||||||
|
answer = http.get( host, port, root .. "/" .. favicon_uri)
|
||||||
|
stdnse.debug4("Using URI %s", favicon_uri)
|
||||||
|
url = favicon_uri
|
||||||
|
else
|
||||||
|
-- Otherwise, first try parsing the home page.
|
||||||
|
index = http.get( host, port, root .. "/" )
|
||||||
|
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
|
||||||
|
stdnse.debug1("Got icon URL %s.", icon)
|
||||||
|
local icon_host, icon_port, icon_path = parse_url_relative(icon, hostname, port.number, root)
|
||||||
|
if (icon_host == host.ip or
|
||||||
|
icon_host == host.targetname or
|
||||||
|
icon_host == (host.name ~= '' and host.name)) and
|
||||||
|
icon_port == port.number then
|
||||||
|
-- request the favicon
|
||||||
|
answer = http.get( icon_host, icon_port, icon_path )
|
||||||
|
url = port.service.."://"..hostname..":"..port.number.."/"..root.."/"..icon_path
|
||||||
|
else
|
||||||
|
answer = nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
answer = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If that didn't work, try /favicon.ico.
|
||||||
|
if not answer or answer.status ~= 200 then
|
||||||
|
answer = http.get( host, port, root .. "/favicon.ico" )
|
||||||
|
url = port.service.."://"..hostname..":"..port.number.."/"..root.."favicon.ico"
|
||||||
|
stdnse.debug4("Using default URI.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- check for 200 response code
|
||||||
|
if answer and answer.status == 200 then
|
||||||
|
result = url
|
||||||
|
else
|
||||||
|
stdnse.debug1("No favicon found.")
|
||||||
|
return
|
||||||
|
end --- status == 200
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dirname(path)
|
||||||
|
local dir
|
||||||
|
dir = string.match(path, "^(.*)/")
|
||||||
|
return dir or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return a URL's host, port, and path, filling in the results with the given
|
||||||
|
-- host, port, and path if the URL is relative. Return nil if the scheme is not
|
||||||
|
-- "http" or "https".
|
||||||
|
function parse_url_relative(u, host, port, path)
|
||||||
|
local scheme, abspath
|
||||||
|
u = url.parse(u)
|
||||||
|
scheme = u.scheme or "http"
|
||||||
|
if not (scheme == "http" or scheme == "https") then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
abspath = u.path or ""
|
||||||
|
if not string.find(abspath, "^/") then
|
||||||
|
abspath = dirname(path) .. "/" .. abspath
|
||||||
|
end
|
||||||
|
return u.host or host, u.port or url.get_default_port(scheme), abspath
|
||||||
|
end
|
||||||
|
|
||||||
|
function parseIcon( body )
|
||||||
|
local _, i, j
|
||||||
|
local rel, href, word
|
||||||
|
|
||||||
|
-- Loop through link elements.
|
||||||
|
i = 0
|
||||||
|
while i do
|
||||||
|
_, i = string.find(body, "<%s*[Ll][Ii][Nn][Kk]%s", i + 1)
|
||||||
|
if not i then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
-- Loop through attributes.
|
||||||
|
j = i
|
||||||
|
while true do
|
||||||
|
local name, quote, value
|
||||||
|
_, j, name, quote, value = string.find(body, "^%s*(%w+)%s*=%s*([\"'])(.-)%2", j + 1)
|
||||||
|
if not j then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if string.lower(name) == "rel" then
|
||||||
|
rel = value
|
||||||
|
elseif string.lower(name) == "href" then
|
||||||
|
href = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for word in string.gmatch(rel or "", "%S+") do
|
||||||
|
if string.lower(word) == "icon" then
|
||||||
|
return href
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
16
index.php
16
index.php
@ -22,14 +22,24 @@
|
|||||||
</header>
|
</header>
|
||||||
<div class="ui main text container">
|
<div class="ui main text container">
|
||||||
<div class="ui link selection list">
|
<div class="ui link selection list">
|
||||||
<?php foreach (scandir("./site") as $file) {
|
<?php
|
||||||
if (strrpos($file, ".xml")) {
|
if (! function_exists('str_ends_with')) {
|
||||||
|
function str_ends_with(string $haystack, string $needle): bool
|
||||||
|
{
|
||||||
|
$needle_len = strlen($needle);
|
||||||
|
return ($needle_len === 0 || 0 === substr_compare($haystack, $needle, - $needle_len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (scandir("./site") as $file) {
|
||||||
|
if (str_ends_with($file, ".xml")) {
|
||||||
$site = str_replace(".xml", "", $file);
|
$site = str_replace(".xml", "", $file);
|
||||||
if (file_exists("scans/$site.xml")) {
|
if (file_exists("scans/$site.xml")) {
|
||||||
echo " <a href='site/$site.xml' class='item'>$site</a>\n";
|
echo " <a href='site/$site.xml' class='item'>$site</a>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?>
|
}
|
||||||
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
10
results.xsl
10
results.xsl
@ -25,6 +25,7 @@
|
|||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<meta http-equiv="refresh" content="300" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="ui fixed blue inverted menu">
|
<header class="ui fixed blue inverted menu">
|
||||||
@ -70,7 +71,14 @@
|
|||||||
<xsl:otherwise>ui fluid mini left icon action input error</xsl:otherwise>
|
<xsl:otherwise>ui fluid mini left icon action input error</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
<i class="icon"><img class="ui image" src="http://{$scannedHostAddress}/favicon.ico" alt="" /></i>
|
<xsl:choose>
|
||||||
|
<xsl:when test="$scannedHost/ports/port/script[@id='http-favicon-url']/@output">
|
||||||
|
<i class="icon"><img class="ui image" src="{$scannedHost/ports/port/script[@id='http-favicon-url']/@output}" alt="" /></i>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<i class="server icon"></i>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
<input type="text" readonly="">
|
<input type="text" readonly="">
|
||||||
<xsl:attribute name="value">
|
<xsl:attribute name="value">
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
|
20
scan_all.php
20
scan_all.php
@ -1,8 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
if (! function_exists('str_ends_with')) {
|
||||||
|
function str_ends_with(string $haystack, string $needle): bool
|
||||||
|
{
|
||||||
|
$needle_len = strlen($needle);
|
||||||
|
return ($needle_len === 0 || 0 === substr_compare($haystack, $needle, - $needle_len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!file_exists("scans")) mkdir("scans");
|
if (!file_exists("scans")) mkdir("scans");
|
||||||
|
|
||||||
foreach (scandir("./site") as $file) {
|
foreach (scandir("./site/") as $file) {
|
||||||
if (strrpos($file, ".yaml")) {
|
if (str_ends_with($file, ".yaml")) {
|
||||||
$site = str_replace(".yaml", "", $file);
|
$site = str_replace(".yaml", "", $file);
|
||||||
$yaml = yaml_parse_file("site/$file");
|
$yaml = yaml_parse_file("site/$file");
|
||||||
|
|
||||||
@ -33,12 +41,12 @@ foreach (scandir("./site") as $file) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$targets = array_keys($targets);
|
|
||||||
$services = array_keys($services);
|
|
||||||
$xml->asXML("site/$site.xml");
|
$xml->asXML("site/$site.xml");
|
||||||
|
|
||||||
exec("nmap -v -Pn -p ".join($services, ",")." --script smb-enum-shares.nse -oX 'scans/$site.xml' ".join($targets, " ")."\n");
|
$targets = join(array_keys($targets), " ");
|
||||||
|
$services = join(array_keys($services), ",");
|
||||||
|
|
||||||
|
exec("nmap -v -Pn -p $services --script smb-enum-shares.nse,http-errors,./http-favicon-url.nse --script-args=httpspider.maxpagecount=1 -oX 'scans/$site.xml' $targets\n");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user