From 4742ed7845ed720bdf603100a0d5abfee4fc0610 Mon Sep 17 00:00:00 2001 From: fyodor Date: Tue, 27 May 2008 07:36:05 +0000 Subject: [PATCH] update SMTPcommands with new code from Jason which works better against Postfix and some other systems. Also, I made it less verbose and changed the ID to SMTPcommands to match the filename. --- scripts/SMTPcommands.nse | 151 +++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 63 deletions(-) diff --git a/scripts/SMTPcommands.nse b/scripts/SMTPcommands.nse index d013cc672..14131967f 100644 --- a/scripts/SMTPcommands.nse +++ b/scripts/SMTPcommands.nse @@ -1,87 +1,112 @@ -- SMTP supported commands gathering script -- Version History -- 1.0.0.0 - 2007-06-12 + -- 1.1.0.0 - 2007-10-12 -- + added HELP command in addition to EHLO + -- 1.2.0.0 - 2008-05-19 -- + made output single line, comma-delimited, instead of -- CR LF delimited on multi-lines +-- + was able to use regular text and not hex codes + +-- 1.3.0.0 - 2008-05-21 +-- + more robust handling of problems +-- + uses verbosity and debugging to decide if you need to +-- see certain errors and if the output is in a line or +-- in , for lack of a better word, fancy format +-- + I am not able to do much testing because my new ISP blocks +-- traffic going to port 25 other than to their mail servers as +-- a "security" measure. + +-- 1.3.1.0 - 2008-05-22 +-- + minor tweaks to get it working when one of the requests fails +-- but not both of them. -- Cribbed heavily from Thomas Buchanan's SQL version detection -- script and from Arturo 'Buanzo' Busleiman's SMTP open relay -- detector script. -id = "SMTP" +id = "SMTPcommands" description = "Attempts to use EHLO and HELP to gather the Extended commands an SMTP server supports." author = "Jason DePriest " license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"discovery", "safe"} require "shortport" +require "stdnse" portrule = shortport.port_or_service({25, 587, 465}, "smtp") action = function(host, port) - local socket = nmap.new_socket() - socket:set_timeout(5000) - - local result1 - local result2 - local result - local commands - local mailservername - local status = true - local table1 - local nocr_regex - - local catch = function() - socket:close() - end - - local try = nmap.new_try(catch) - - try(socket:connect(host.ip, port.number, port.protocol)) - result = try(socket:receive_lines(1)) - - -- ASCII for "EHLO example.org\n" - -- for some reason it wouldn't reply unless I did it like this - local query = "EHLO example.org\r\n" - try(socket:send(query)) - result1 = try(socket:receive_lines(1)) - - if not string.match(result1, "^250") then - socket:close() - -- TODO: use print_debug instead - return "EHLO with errors or timeout. Enable --script-trace to see what is happening." - end - - result1 = string.gsub(result1, "250 OK\r\n", "") -- 250 OK (needed to have the \r\n in there) - -- get rid of the 250- at the beginning of each line in the response - result1 = string.gsub(result1, "250%-", "") -- 250- - result1 = string.gsub(result1,"[\r\n]+$", "") -- no final CR LF - result1 = string.gsub(result1, "\r\n", ", ") -- CR LF to comma - result1 = "EHLO reply: " .. result1 .. "\n" - - local query = "HELP\r\n" - try(socket:send(query)) - result2 = try(socket:receive_lines(1)) - - if not string.match(result2, "^214") then - socket:close() - -- TODO: use print_debug instead - return "HELP with errors or timeout. Enable --script-trace to see what is happening." - end - - -- get rid of the 214 at the beginning of the lines in the response - result2 = string.gsub(result2, "214%-", "") -- 214- - result2 = string.gsub(result2, "214 ", "") -- 214 - result2 = string.gsub(result1,"[\r\n]+$", "") -- no final CR LF - result2 = string.gsub(result1, "\r\n", ", ") -- CR LF to comma - result2 = "HELP reply: " .. result2 .. "\n" - - result = result1 .. result2 - - return result - -end \ No newline at end of file + local socket = nmap.new_socket() + socket:set_timeout(5000) + + local result + local resultEHLO + local resultHELP + + local catch = function() + socket:close() + --return + end + + local try = nmap.new_try(catch) + + local attempt = try(socket:connect(host.ip, port.number, port.protocol)) + if attempt then + if nmap.verbosity() >= 2 or nmap.debugging() >= 1 then -- only tell you it fails if you are debugging or verbose X 2 + return "Problem connecting to " .. host.ip .. " on port " .. port.number .. " using protocol " .. port.protocol + else + return -- if you aren't debugging, just return with nothing + end + end + + result = try(socket:receive_lines(1)) + + local query = "EHLO example.org\r\n" + try(socket:send(query)) + resultEHLO = try(socket:receive_lines(1)) + + if not (string.match(resultEHLO, "^250")) then +-- stdnse.print_debug("1",resultEHLO) +-- stdnse.print_debug("1","EHLO with errors or timeout. Enable --script-trace to see what is happening.") + resultEHLO = "" + end + + if resultEHLO ~= "" then + + resultEHLO = string.gsub(resultEHLO, "250 OK[\r\n]", "") -- 250 OK (needed to have the \r\n in there) + -- get rid of the 250- at the beginning of each line in the response + resultEHLO = string.gsub(resultEHLO, "250%-", "") -- 250- + resultEHLO = string.gsub(resultEHLO,"[\r\n]+$", "") -- no final CR LF + resultEHLO = string.gsub(resultEHLO, "\r\n", ", ") -- CR LF to comma + resultEHLO = "\nEHLO " .. resultEHLO + end + + local query = "HELP\r\n" + try(socket:send(query)) + resultHELP = try(socket:receive_lines(1)) + + if not (string.match(resultHELP, "^214")) then +-- stdnse.print_debug("1",resultHELP) +-- stdnse.print_debug("1","HELP with errors or timeout. Enable --script-trace to see what is happening.") + resultHELP = "" + end + if resultHELP ~= "" then + resultHELP = string.gsub(resultHELP, "214%-", "") -- 214- + -- get rid of the 214 at the beginning of the lines in the response + resultHELP = string.gsub(resultHELP, "214 ", "") -- 214 + resultHELP = string.gsub(resultHELP,"[\r\n]+$", "") -- no final CR LF + resultHELP = string.gsub(resultHELP, "[\r\n]", ", ") -- CR LF to comma + resultHELP = "\nHELP " .. resultHELP + end + + result = resultEHLO .. resultHELP + + socket:close() + + return result + +end