mirror of
https://github.com/nmap/nmap.git
synced 2025-12-12 18:59:03 +00:00
Added a script called http-malware-host.nse. Its future intention is to discover hosts that are serving malware (for example, that are compromised and have malicious code inserted). At the moment, it checks for one specific attack discussed here: http://blog.unmaskparasites.com/2009/09/11/dynamic-dns-and-botnet-of-zombie-web-servers/
This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
# Nmap Changelog ($Id$); -*-text-*-
|
# Nmap Changelog ($Id$); -*-text-*-
|
||||||
|
|
||||||
|
o Added a script called http-malware-host.nse. Its future intention
|
||||||
|
is to discover hosts that are serving malware (for example, that
|
||||||
|
are compromised and have malicious code inserted). At the moment,
|
||||||
|
it checks for one specific attack discussed here:
|
||||||
|
http://blog.unmaskparasites.com/2009/09/11/dynamic-dns-and-botnet-of-zombie-web-servers/
|
||||||
|
[Ron]
|
||||||
|
|
||||||
o Added a check for a SMBv2 vulnerability (CVE-2009-3103) to
|
o Added a check for a SMBv2 vulnerability (CVE-2009-3103) to
|
||||||
smb-check-vulns. Due to its nature (it performs a DoS, then checks
|
smb-check-vulns. Due to its nature (it performs a DoS, then checks
|
||||||
if the system is still online), the script isn't run by default
|
if the system is still online), the script isn't run by default
|
||||||
|
|||||||
90
scripts/http-malware-host.nse
Normal file
90
scripts/http-malware-host.nse
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
description = [[
|
||||||
|
Looks for signature of known server compromises. Currently, the only signature it looks for is
|
||||||
|
the one discussed here:
|
||||||
|
<http://blog.unmaskparasites.com/2009/09/11/dynamic-dns-and-botnet-of-zombie-web-servers/>
|
||||||
|
|
||||||
|
This is done by requesting the page /ts/in.cgi?open2 and looking for an errant 302 (it attempts
|
||||||
|
to detect srevers that always return 302).
|
||||||
|
|
||||||
|
Thanks to Denis from the above link for finding this technique!
|
||||||
|
]]
|
||||||
|
|
||||||
|
---
|
||||||
|
--@output
|
||||||
|
-- Interesting ports on www.sopharma.bg (84.242.167.49):
|
||||||
|
-- PORT STATE SERVICE REASON
|
||||||
|
-- 80/tcp open http syn-ack
|
||||||
|
-- |_ http-infected: Host appears to be clean
|
||||||
|
-- 8080/tcp open http-proxy syn-ack
|
||||||
|
-- | http-malware-host: Host appears to be infected (/ts/in.cgi?open2 redirects to http://last-another-life.ru:8080/index.php)
|
||||||
|
-- |_ See: http://blog.unmaskparasites.com/2009/09/11/dynamic-dns-and-botnet-of-zombie-web-servers/
|
||||||
|
--
|
||||||
|
|
||||||
|
author = "Ron Bowes <ron@skullsecurity.net>"
|
||||||
|
|
||||||
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
|
||||||
|
categories = {"malware"}
|
||||||
|
|
||||||
|
require 'stdnse'
|
||||||
|
require 'http'
|
||||||
|
require 'stdnse'
|
||||||
|
|
||||||
|
portrule = function(host, port)
|
||||||
|
local svc = { std = { ["http"] = 1, ["http-alt"] = 1, ["http-proxy"] = 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
|
||||||
|
|
||||||
|
local function go(host, port)
|
||||||
|
-- Check what response we get for a 404
|
||||||
|
local result, result_404, known_404 = http.identify_404(host, port)
|
||||||
|
if(result == false) then
|
||||||
|
return false, "Couldn't identify 404 message: " .. result_404
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If the 404 result is a 302, we're going to have trouble
|
||||||
|
if(result_404 == 302) then
|
||||||
|
return false, "Unknown pages return a 302 response; unable to check"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Perform a GET request on the file
|
||||||
|
result = http.get_url("http://" .. host.ip .. ":" .. port.number .. "/ts/in.cgi?open2")
|
||||||
|
if(result == nil) then
|
||||||
|
return false, "Couldn't perform GET request"
|
||||||
|
end
|
||||||
|
|
||||||
|
if(result.status == 302) then
|
||||||
|
if(result.header.location) then
|
||||||
|
return true, string.format("Host appears to be infected (/ts/in.cgi?open2 redirects to %s)\nSee: http://blog.unmaskparasites.com/2009/09/11/dynamic-dns-and-botnet-of-zombie-web-servers/", result.header.location)
|
||||||
|
else
|
||||||
|
return true, string.format("Host appears to be infected (/ts/in.cgi?open2 return a redirect)\nSee: http://blog.unmaskparasites.com/2009/09/11/dynamic-dns-and-botnet-of-zombie-web-servers/")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
action = function(host, port)
|
||||||
|
local status, result = go(host, port)
|
||||||
|
|
||||||
|
if(status == false) then
|
||||||
|
if(nmap.debugging() > 0) then
|
||||||
|
return "ERROR: " .. result
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ Entry { filename = "http-enum.nse", categories = { "discovery", "intrusive", "vu
|
|||||||
Entry { filename = "http-favicon.nse", categories = { "default", "discovery", } }
|
Entry { filename = "http-favicon.nse", categories = { "default", "discovery", } }
|
||||||
Entry { filename = "http-headers.nse", categories = { "discovery", } }
|
Entry { filename = "http-headers.nse", categories = { "discovery", } }
|
||||||
Entry { filename = "http-iis-webdav-vuln.nse", categories = { "intrusive", "vuln", } }
|
Entry { filename = "http-iis-webdav-vuln.nse", categories = { "intrusive", "vuln", } }
|
||||||
|
Entry { filename = "http-malware-host.nse", categories = { "malware", } }
|
||||||
Entry { filename = "http-open-proxy.nse", categories = { "default", "discovery", "external", "intrusive", } }
|
Entry { filename = "http-open-proxy.nse", categories = { "default", "discovery", "external", "intrusive", } }
|
||||||
Entry { filename = "http-passwd.nse", categories = { "intrusive", "vuln", } }
|
Entry { filename = "http-passwd.nse", categories = { "intrusive", "vuln", } }
|
||||||
Entry { filename = "http-trace.nse", categories = { "discovery", } }
|
Entry { filename = "http-trace.nse", categories = { "discovery", } }
|
||||||
|
|||||||
Reference in New Issue
Block a user