-
Notifications
You must be signed in to change notification settings - Fork 370
/
hostmap-crtsh.nse
115 lines (99 loc) · 3.21 KB
/
hostmap-crtsh.nse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
description = [[
Finds subdomains of a web server by querying Google's
Certificate Transparency logs database (https://crt.sh).
NSE implementation of ctfr.py (https://github.com/UnaPibaGeek/ctfr.git) by Sheila Berta.
References:
* www.certificate-transparency.org
]]
---
-- @args hostmap.prefix If set, saves the output for each host in a file
-- called "<prefix><target>". The file contains one entry per line.
-- @args newtargets If set, add the new hostnames to the scanning queue.
-- This the names presumably resolve to the same IP address as the
-- original target, this is only useful for services such as HTTP that
-- can change their behavior based on hostname.
--
-- @usage
-- nmap --script hostmap-crtsh --script-args 'hostmap-crtsh.prefix=hostmap-' <targets>
-- @usage
-- nmap -sn --script hostmap-crtsh <target>
-- @output
-- Host script results:
-- | hostmap-crtsh:
-- | subdomains:
-- | svn.nmap.org
-- | www.nmap.org
-- |_ filename: output_nmap.org
-- @xmloutput
-- <table key="subdomains">
-- <elem>svn.nmap.org</elem>
-- <elem>www.nmap.org</elem>
-- </table>
-- <elem key="filename">output_nmap.org</elem>
---
author = "Paulino Calderon <calderon@websec.mx>"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"external", "discovery"}
local ipOps = require "ipOps"
local io = require "io"
local http = require "http"
local stdnse = require "stdnse"
local string = require "string"
local target = require "target"
local table = require "table"
local shortport = require "shortport"
hostrule = function(host)
return shortport.http
end
local function query_ctlogs(host)
local query = string.format("/?q=%%.%s&output=json", host.targetname)
local response
response = http.get("crt.sh", 443, query )
local hostnames = {}
if not response.status then
return string.format("Error: could not GET http://%s%s", "crt.sh", query)
end
for domain in string.gmatch(response.body, "name_value\":\"(.-)\"") do
if not stdnse.contains(hostnames, domain) and domain ~= "" then
if target.ALLOW_NEW_TARGETS then
local status, err = target.add(domain)
end
table.insert(hostnames, domain)
end
end
if #hostnames<1 then
if not string.find(response.body, "no results") then
return "Error: found no hostnames but not the marker for \"name_value\" (pattern error?)"
end
end
return hostnames
end
local function write_file(filename, contents)
local f, err = io.open(filename, "w")
if not f then
return f, err
end
f:write(contents)
f:close()
return true
end
action = function(host)
local filename_prefix = stdnse.get_script_args("hostmap.prefix")
local hostnames = {}
local hostnames_str, output_str
local output_tab = stdnse.output_table()
hostnames = query_ctlogs(host)
output_tab.subdomains = hostnames
--write to file
if filename_prefix then
local filename = filename_prefix .. stdnse.filename_escape(host.targetname or host.ip)
hostnames_str = stdnse.strjoin("\n", hostnames)
local status, err = write_file(filename, hostnames_str)
if status then
output_tab.filename = filename
else
stdnse.debug1("There was an error saving the file %s:%s", filename, err)
end
end
return output_tab
end