1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 12:41:29 +00:00

Add STAT support to ftp-syst.nse

This commit is contained in:
dmiller
2017-07-26 21:29:32 +00:00
parent f17ac01db5
commit c0c397b5bb
2 changed files with 103 additions and 30 deletions

View File

@@ -1,7 +1,7 @@
# Nmap Changelog ($Id$); -*-text-*- # Nmap Changelog ($Id$); -*-text-*-
o [NSE] ftp-syst sends a SYST command to FTP servers to get system version o [NSE] ftp-syst sends SYST and STAT commands to FTP servers to get system
information. [Daniel Miller] version and connection information. [Daniel Miller]
o [NSE] FTP scripts like ftp-anon and ftp-brute now correctly handle o [NSE] FTP scripts like ftp-anon and ftp-brute now correctly handle
TLS-protected FTP services and use STARTTLS when necessary. [Daniel Miller] TLS-protected FTP services and use STARTTLS when necessary. [Daniel Miller]

View File

@@ -5,9 +5,11 @@ local string = require "string"
local table = require "table" local table = require "table"
description = [[ description = [[
Sends an FTP SYST command and returns the result. Sends FTP SYST and STAT commands and returns the result.
The canonical response of "UNIX Type: L8" is stripped or ignored, since it is meaningless. The canonical SYST response of "UNIX Type: L8" is stripped or ignored, since it
is meaningless. Typical FTP response codes (215 for SYST and 211 for STAT) are
also hidden.response codes (215 for SYST and 211 for STAT) are also hidden.
References: References:
* https://cr.yp.to/ftp/syst.html * https://cr.yp.to/ftp/syst.html
@@ -19,10 +21,55 @@ categories = {"default", "discovery", "safe"}
--- ---
-- @output -- @output
-- |_ftp-syst: UNIX MikroTik 6.39.2 -- | ftp-syst:
-- | SYST: UNIX MikroTik 6.34.3
-- | STAT:
-- | Enver Curri FTP server (MikroTik 6.34.3) status:
-- | Logged in as
-- | TYPE: ASCII; STRUcture: File; transfer MODE: Stream
-- | No data connection
-- |_End of status
--
-- | ftp-syst:
-- | STAT:
-- | FTP server status:
-- | Connected to 192.0.2.13
-- | Logged in as ftp
-- | TYPE: ASCII
-- | No session bandwidth limit
-- | Session timeout in seconds is 300
-- | Control connection is plain text
-- | Data connections will be plain text
-- | At session startup, client count was 1
-- | vsFTPd 2.0.5 - secure, fast, stable
-- |_End of status
--
-- | ftp-syst:
-- | SYST: Version: Linux 2.6.26.8-rt16
-- | STAT:
-- | HES_CPE FTP server status:
-- | ftpd (GNU inetutils) 1.4.1
-- | Connected to 72.14.177.105
-- | Waiting for user name
-- | TYPE: ASCII, FORM: Nonprint; STRUcture: File; transfer MODE: Stream
-- | No data connection
-- |_End of status
--
-- @xmloutput
-- <elem key="SYST">Version: Linux 3.10.73</elem>
-- <elem key="STAT">
-- FRITZ!Box7490 FTP server status:
-- Connected to 72.14.177.105
-- Waiting for user name
-- TYPE: ASCII, FORM: Nonprint; STRUcture: File; transfer MODE: Stream
-- No data connection
-- End of status</elem>
portrule = shortport.port_or_service({21,990}, {"ftp","ftps"}) portrule = shortport.port_or_service({21,990}, {"ftp","ftps"})
local function do_syst(socket, buffer)
end
action = function(host, port) action = function(host, port)
local socket, code, message, buffer = ftp.connect(host, port) local socket, code, message, buffer = ftp.connect(host, port)
if not socket then if not socket then
@@ -34,25 +81,27 @@ action = function(host, port)
return nil return nil
end end
-- SYST
local auth_done = false local auth_done = false
::TRY_AGAIN:: local syst
repeat
if not socket:send("SYST\r\n") then if not socket:send("SYST\r\n") then
return nil return nil
end end
code, message = ftp.read_reply(buffer) code, message = ftp.read_reply(buffer)
if not code then if not code then
stdnse.debug1("SYST error: %s", message) stdnse.debug1("SYST error: %s", message)
return nil break
end end
if code == 215 then if code == 215 then
local stripped = message:gsub("^UNIX Type: L8 *", "") local stripped = message:gsub("^UNIX Type: L8 *", "")
if stripped ~= "" then if stripped ~= "" then
return stripped syst = stripped
else
return nil
end end
break
elseif code < 300 then elseif code < 300 then
return ("%d %s"):format(code, message) syst = ("%d %s"):format(code, message)
break
elseif not auth_done and -- we haven't tried logging in yet elseif not auth_done and -- we haven't tried logging in yet
( code == 503 -- Command SYST not accepted during Connected ( code == 503 -- Command SYST not accepted during Connected
or code == 521 -- Not logged in - Secure authentication required or code == 521 -- Not logged in - Secure authentication required
@@ -62,10 +111,34 @@ action = function(host, port)
local status, code, message = ftp.auth(socket, buffer, "anonymous", "IEUser@") local status, code, message = ftp.auth(socket, buffer, "anonymous", "IEUser@")
if status then if status then
auth_done = true auth_done = true
goto TRY_AGAIN end
end
until not auth_done
-- STAT
if not socket:send("STAT\r\n") then
if syst then
return {SYST=syst}
else
return nil
end
end
local out = stdnse.output_table()
out.SYST = syst
local code, stat = ftp.read_reply(buffer)
if code then
if code == 211 then
out.STAT = "\n" .. stat
elseif code < 300 then
out.STAT = ("%d\n%s"):format(code, stat)
end end
end end
ftp.close(socket) ftp.close(socket)
if #out > 0 then
return out
end
end end