Skip to content

Instantly share code, notes, and snippets.

@bcoles
Last active June 21, 2022 21:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcoles/1231055 to your computer and use it in GitHub Desktop.
Save bcoles/1231055 to your computer and use it in GitHub Desktop.
nntp-options.nse - Retrieves the available commands and banners from a listening NNTP daemon.
description = [[
Retrieves the available commands and banners from a listening NNTP daemon.
The Network News Transfer Protocol (NNTP) is an Internet application protocol used for transporting Usenet news articles (netnews) between news servers and for reading and posting articles by end user client applications.
For more information about NNTP, see:
http://tools.ietf.org/html/rfc3977
http://tools.ietf.org/html/rfc6048
http://en.wikipedia.org/wiki/Network_News_Transfer_Protocol
]]
---
-- @usage
-- nmap --script nntp-options --script-args nntp-options.timeout=10 -p <port> <host>
--
-- @args nntp-options.timeout
-- Set the timeout in seconds. The default value is 10.
--
-- @output
-- PORT STATE SERVICE REASON
-- 119/tcp open nntp syn-ack
-- | nntp-options:
-- | Banners:
-- | news.example.com - colobus 2.1 ready - (posting ok).
-- | Colobus 2.1
-- | Commands:
-- | authinfo user Name|pass Password
-- | article [MessageID|Number]
-- | body [MessageID|Number]
-- | check MessageID
-- | group newsgroup
-- | head [MessageID|Number]
-- | list [active|active.times|newsgroups|subscriptions]
-- | listgroup newsgroup
-- | mode stream
-- | mode reader
-- | newgroups yymmdd hhmmss [GMT] [<distributions>]
-- | newnews newsgroups yymmdd hhmmss [GMT] [<distributions>]
-- | stat [MessageID|Number]
-- | takethis MessageID
-- | xgtitle [group_pattern]
-- | xhdr header [range|MessageID]
-- | xover [range]
-- |_ xpat header range|MessageID pat [morepat...]
--
-- @changelog
-- 2011-06-28 - v0.1 - created by Brendan Coles <bcoles@gmail.com>
--
author = "Brendan Coles"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery"}
local stdnse = require "stdnse"
local comm = require "comm"
local shortport = require "shortport"
portrule = shortport.port_or_service (119, "nntp", {"tcp"})
action = function(host, port)
local result = {}
local banners = {}
local commands = {}
-- Set timeout
local timeout = tonumber(nmap.registry.args[SCRIPT_NAME .. '.timeout'])
if not timeout or timeout < 0 then timeout = 10 end
-- Connect and retrieve banner and commands
local command = "HELP\n"
stdnse.print_debug(1, ("%s: Connecting to %s:%s [Timeout: %ss]"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, timeout))
local status, data = comm.exchange(host, port, command,{lines=100, proto=port.protocol, timeout=timeout*1000})
if not status or not data then
stdnse.print_debug(1, ("%s: Retrieving data from %s:%s failed [Timeout expired]"):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
return
end
-- Parse NNTP banners and commands
stdnse.print_debug(1, ("%s: Parsing data from %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
for line in string.gmatch(data, "[^\r^\n]+") do
if line ~= "" then
if string.match(line, "^500") then
stdnse.print_debug(1, ("%s: Server returned an error: %s"):format(SCRIPT_NAME, line))
return
elseif string.match(line, "^100") then
stdnse.print_debug(1, ("%s: Server returned help text (%s:%s)"):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
elseif string.match(line, "^20[01] (.+)$") then
local banner = string.match(line, "^20[01] (.+)$")
table.insert(banners, string.format("%s", banner))
elseif string.match(line, "^ ([a-zA-Z]+)") then
-- commands with help description text
local cmd = string.match(line, "^ ([a-zA-Z]+ .+)$")
if cmd then
table.insert(commands, string.format("%s", cmd))
else
-- commands only - no help description text
local cmd = string.match(line, "^ ([a-zA-Z]+)$")
if cmd then table.insert(commands, string.format("%s", cmd)) end
end
end
end
end
-- Add banners to results table
if next(banners) == nil then
stdnse.print_debug(1, ("%s: No banners were returned by %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
else
table.insert(result, "Banners:")
table.insert(result, banners)
end
-- Add commands to results table
if next(commands) == nil then
stdnse.print_debug(1, ("%s: No commands were returned by %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number))
else
table.insert(result, "Commands:")
table.insert(result, commands)
end
-- Return results
return stdnse.format_output(true, result)
end
@digitalhuman
Copy link

Doesn't work

@bcoles
Copy link
Author

bcoles commented Dec 24, 2017

@digitalhuman

nmap NSE has changed in the past 6 years since this script was written. In particular, the version of lua in use and the way libraries are loaded.

I've updated the gist appropriately.

local stdnse = require "stdnse"
local comm = require "comm"
local shortport = require "shortport"

Nmap now loads the script successfully. This may or may not fix the issues you're encountering.

I've tried it out on a couple of servers with the above changes. The script returned the banner successfully, although failed to enumerate the available options. It's possible that there's an issue with the regex. In many instances, the NNTP server will require valid authentication credentials before providing the a response to the HELP command, in which case the script will return only the banner.

@bcoles
Copy link
Author

bcoles commented Dec 24, 2017

There was an issue with the regex for identifying commands in instances where the NTTP server returned only a list of commands without associated help text describing each command.

I've fixed this.

There's another issue with the regex for identifying commands in instances where the commands aren't indented with two spaces. Ideally the script should be updated to parse the response properly - ie, identify a 100 response before attempting to parse the command list. I'll leave this as an exercise for someone else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment