summaryrefslogtreecommitdiffstats
path: root/scripts/pop3-brute.nse
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/pop3-brute.nse')
-rw-r--r--scripts/pop3-brute.nse136
1 files changed, 136 insertions, 0 deletions
diff --git a/scripts/pop3-brute.nse b/scripts/pop3-brute.nse
new file mode 100644
index 0000000..9712d47
--- /dev/null
+++ b/scripts/pop3-brute.nse
@@ -0,0 +1,136 @@
+local brute = require "brute"
+local comm = require "comm"
+local creds = require "creds"
+local nmap = require "nmap"
+local pop3 = require "pop3"
+local shortport = require "shortport"
+local string = require "string"
+
+description = [[
+Tries to log into a POP3 account by guessing usernames and passwords.
+]]
+
+---
+-- @args pop3loginmethod The login method to use: <code>"USER"</code>
+-- (default), <code>"SASL-PLAIN"</code>, <code>"SASL-LOGIN"</code>,
+-- <code>"SASL-CRAM-MD5"</code>, or <code>"APOP"</code>. Defaults to <code>"USER"</code>,
+--
+-- @output
+-- PORT STATE SERVICE
+-- 110/tcp open pop3
+-- | pop3-brute-ported:
+-- | Accounts:
+-- | user:pass => Login correct
+-- | Statistics:
+-- |_ Performed 8 scans in 1 seconds, average tps: 8
+
+author = {"Philip Pickering", "Piotr Olma"}
+license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
+
+categories = {"intrusive", "brute"}
+
+Driver = {
+ new = function(self, host, port, login_function, is_apop)
+ local o = {}
+ setmetatable(o, self)
+ self.__index = self
+ o.port = port
+ o.host = host
+ o.login_function = login_function
+ o.is_apop = is_apop
+ return o
+ end,
+
+ -- Attempts to connect to the POP server
+ -- @return true on success
+ -- @return false, brute.Error object on failure
+ connect = function(self)
+
+ self.socket = brute.new_socket()
+ local opts = {timeout=10000, recv_before=true}
+ local best_opt, line, _
+ self.socket, _, best_opt, line = comm.tryssl(self.host, self.port, "" , opts)
+
+ if not self.socket then
+ local err = brute.Error:new("Failed to connect.")
+ err:setAbort(true)
+ return false, err
+ end --no connection
+ if not pop3.stat(line) then
+ local err = brute.Error:new("Failed to make a pop-connection.")
+ err:setAbort(true)
+ return false, err
+ end -- no pop-connection
+
+ if self.is_apop then
+ self.additional = string.match(line, "<[%p%w]+>") --apop challenge
+ end
+ return true
+ end, --connect
+
+ -- Attempts to login to the POP server
+ --
+ -- @param username string containing the login username
+ -- @param password string containing the login password
+ -- @return status, true on success, false on failure
+ -- @return brute.Error object on failure
+ -- creds.Account object on success
+ login = function(self, username, password)
+ local pstatus
+ local perror
+ pstatus, perror = self.login_function(self.socket, username, password, self.additional)
+ if pstatus then
+ return true, creds.Account:new(username, password, creds.State.VALID)
+ else
+ local err
+ if (perror == pop3.err.pwError) then
+ err = brute.Error:new("Wrong password.")
+ elseif (perror == pop3.err.userError) then
+ err = brute.Error:new("Wrong username.")
+ err:setInvalidAccount(username)
+ else
+ err = brute.Error:new("Login failed.")
+ end
+ return false, err
+ end
+ end, --login
+
+ disconnect = function(self)
+ self.socket:close()
+ end, --disconnect
+
+ check = function(self)
+ return true
+ end, --check
+}
+
+portrule = shortport.port_or_service({110, 995}, {"pop3","pop3s"})
+
+action = function(host, port)
+ local pMeth = nmap.registry.args.pop3loginmethod
+ if (not pMeth) then pMeth = nmap.registry.pop3loginmethod end
+ if (not pMeth) then pMeth = "USER" end
+
+ --determine function we will use to login to server
+ local is_apop = false
+ local login_function
+ if (pMeth == "USER") then
+ login_function = pop3.login_user
+ elseif (pMeth == "SASL-PLAIN") then
+ login_function = pop3.login_sasl_plain
+ elseif (pMeth == "SASL-LOGIN") then
+ login_function = pop3.login_sasl_login
+ elseif (pMeth == "SASL-CRAM-MD5") then
+ login_function = pop3.login_sasl_crammd5
+ elseif (pMeth == "APOP") then
+ login_function = pop3.login_apop
+ is_apop = true
+ else
+ login_function = pop3.login_user
+ end
+
+ local engine = brute.Engine:new(Driver, host, port, login_function, is_apop)
+ engine.options.script_name = SCRIPT_NAME
+ local status, accounts = engine:start()
+ return accounts
+end