Показать сообщение отдельно

  #3  
Старый 01.08.2017, 19:34
SooLFaa
Постоянный
Регистрация: 17.03.2014
Сообщений: 530
С нами: 6398966

Репутация: 154


По умолчанию

Обещал скриптик, который бы чекал IPMI даже если нет его открытых портов.

Собственно вот

.SpoilerTarget" type="button">Spoiler: Вывод


Код:
local creds = require "creds"
local nmap = require "nmap"
local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local tab = require "table"
local sslcert = require "sslcert"
local tls = require "tls"

description = [[Check ipmi by http headers and ssl certificates.]]
author = "Morozov Alexey"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"discovery", "same"}

local comm =  require "comm"
require "shortport"

portrule = function(host, port)
        return ((port.number == 80 or port.number == 443 or port.number == 5901 or port.number == 5900 or port.number == 623)
               and port.protocol == "tcp" and port.state == "open") or (port.number == 623 and port.protocol == "udp" and port.state == "open")
end

local NON_VERBOSE_FIELDS = { "commonName", "organizationName",
"stateOrProvinceName", "countryName" }

function table_find(t, value)
  local i, v
  for i, v in ipairs(t) do
    if v == value then
      return i
    end
  end
  return nil
end

function date_to_string(date)
  if not date then
    return "MISSING"
  end
  if type(date) == "string" then
    return string.format("Can't parse; string is \"%s\"", date)
  else
    return stdnse.format_timestamp(date)
  end
end

local function maybe_decode(str)
  -- If length is not even, then return as-is
  if #str  0 and str:byte(2) == 0 then
    -- little-endian UTF-16
    return unicode.transcode(str, unicode.utf16_dec, unicode.utf8_enc, false, nil)
  elseif str:byte(1) == 0 and str:byte(2) > 0 then
    -- big-endian UTF-16
    return unicode.transcode(str, unicode.utf16_dec, unicode.utf8_enc, true, nil)
  else
    return str
  end
end

function stringify_name(name)
  local fields = {}
  local _, k, v
  if not name then
    return nil
  end
  for _, k in ipairs(NON_VERBOSE_FIELDS) do
    v = name[k]
    if v then
      fields[#fields + 1] = string.format("%s=%s", k, maybe_decode(v) or '')
    end
  end
  if nmap.verbosity() > 1 then
    for k, v in pairs(name) do
      -- Don't include a field twice.
      if not table_find(NON_VERBOSE_FIELDS, k) then
        if type(k) == "table" then
          k = stdnse.strjoin(".", k)
        end
        fields[#fields + 1] = string.format("%s=%s", k, maybe_decode(v) or '')
      end
    end
  end
  return stdnse.strjoin("/", fields)
end

local function output_str(cert)
  local lines = {}

  lines[#lines + 1] = "Subject: " .. stringify_name(cert.subject)
  if cert.extensions then
    for _, e in ipairs(cert.extensions) do
      if e.name == "X509v3 Subject Alternative Name" then
        lines[#lines + 1] = "Subject Alternative Name: " .. e.value
        break
      end
    end
  end

  if nmap.verbosity() > 0 then
    lines[#lines + 1] = "Issuer: " .. stringify_name(cert.issuer)
  end

  if nmap.verbosity() > 0 then
    lines[#lines + 1] = "Public Key type: " .. cert.pubkey.type
    lines[#lines + 1] = "Public Key bits: " .. cert.pubkey.bits
    lines[#lines + 1] = "Signature Algorithm: " .. cert.sig_algorithm
  end

  lines[#lines + 1] = "Not valid before: " ..
  date_to_string(cert.validity.notBefore)
  lines[#lines + 1] = "Not valid after:  " ..
  date_to_string(cert.validity.notAfter)

  if nmap.verbosity() > 0 then
    lines[#lines + 1] = "MD5:   " .. stdnse.tohex(cert:digest("md5"), { separator = " ", group = 4 })
    lines[#lines + 1] = "SHA-1: " .. stdnse.tohex(cert:digest("sha1"), { separator = " ", group = 4 })
  end

  if nmap.verbosity() > 1 then
    lines[#lines + 1] = cert.pem
  end
  return stdnse.strjoin("\n", lines)
end

action = function(host, port)

        local resports = {}
        if (port.number == 623 or port.number == 5900 or port.number == 5901) or (port.number == 623 and port.protocol == "udp") then
                port.version.name = "ipmi"
                nmap.set_port_version(host, port)
                -- return
        end

        local domains = {}
        -- domains['name'] = 'IPMI_DETECT_BY_PORT'

        if (port.number == 80) then
                local status, result = comm.exchange(host, port, "GET / HTTP/1.0\r\n\r\n", {bytes=260, proto=port.protocol})
                if (status) then
                        -- print(result)
                        local goAheads = string.find(result, 'GoAhead-Webs', 1, true)
                        print(goAheads)

                        if (goAheads ~= nil) then
                                 table.insert(domains, 'DETECTED IPMI')
                        end
                end
        end

        if (port.number == 443) then
                -- host.targetname = tls.servername(host)
                local status, cert = sslcert.getCertificate(host, port)
                if (status) then
                        local res_cert = output_str(cert)
                        local certIpmi = string.find(res_cert, 'IPMI', 1, true)
                        local certAmi =  string.find(res_cert, 'American Megatrends', 1, true)

                        if (certIpmi ~= nil) or (certAmi ~= nil) then
                                table.insert(domains, 'DETECTED IPMI')
                        end

                end
        end

        -- if (result ~= "HTTP/1.0 404 Not Found\r\n\r\n") then
        --        return
        -- end
        -- So far so good, now see if we get random data for another request
        -- status, result = comm.exchange(host, port,
        --        "random data\r\n\r\n", {bytes=15, proto=port.protocol})

        -- if (not status) then
        --         return
        -- end
        -- if string.match(result, "[^%s!-~].*[^%s!-~].*[^%s!-~]") then
                -- Detected
        --        port.version.name = "skype2"
        --
        --        nmap.set_port_version(host, port)
        --        return
        return stdnse.format_output(true, domains)
end
 
Ответить с цитированием