Lucene search

K
nmapRon BowesNMAP:HTTP-MALWARE-HOST.NSE
HistorySep 16, 2009 - 2:15 p.m.

http-malware-host NSE Script

2009-09-1614:15:13
Ron Bowes
nmap.org
242

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.973 High

EPSS

Percentile

99.8%

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/&gt;. This is done by requesting the page /ts/in.cgi?open2 and looking for an errant 302 (it attempts to detect servers that always return 302). Thanks to Denis from the above link for finding this technique!

Script Arguments

slaxml.debug

See the documentation for the slaxml library.

http.host, http.max-body-size, http.max-cache-size, http.max-pipeline, http.pipeline, http.truncated-ok, http.useragent

See the documentation for the http library.

smbdomain, smbhash, smbnoguest, smbpassword, smbtype, smbusername

See the documentation for the smbauth library.

Example Usage

nmap -sV --script=http-malware-host &lt;target&gt;

Script Output

Interesting ports on www.sopharma.bg (84.242.167.49):
PORT     STATE SERVICE    REASON
80/tcp   open  http       syn-ack
|_ http-malware-host: 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/

Requires


local http = require "http"
local nmap = require "nmap"
local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"

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 <code>/ts/in.cgi?open2</code> and
looking for an errant 302 (it attempts to detect servers 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-malware-host: 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"

license = "Same as Nmap--See https://nmap.org/book/man-legal.html"

categories = {"malware", "safe"}


portrule = shortport.http

action = function(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 stdnse.format_output(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 stdnse.format_output(false, "Unknown pages return a 302 response; unable to check")
  end

  -- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the test
  if ( result_404 == 200 ) then
    stdnse.debug1("Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", host.ip, port.number)
    return false
  end

  -- Perform a GET request on the file
  result = http.get(host, port, "/ts/in.cgi?open2")
  if(not(result)) then
    return stdnse.format_output(false, "Couldn't perform GET request")
  end

  if(result.status == 302) then
    local response = {}
    if(result.header.location) then
      table.insert(response, string.format("Host appears to be infected (/ts/in.cgi?open2 redirects to %s)", result.header.location))
    else
      table.insert(response, "Host appears to be infected (/ts/in.cgi?open2 return a redirect")
    end
    table.insert(response, "See: http://blog.unmaskparasites.com/2009/09/11/dynamic-dns-and-botnet-of-zombie-web-servers/")
    return stdnse.format_output(true, response)
  end

  -- Not infected
  if(nmap.verbosity() > 0) then
    return "Host appears to be clean"
  else
    return nil
  end
end

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.973 High

EPSS

Percentile

99.8%

Related for NMAP:HTTP-MALWARE-HOST.NSE