mirror of
https://github.com/nmap/nmap.git
synced 2025-12-15 12:19:02 +00:00
Update afp-ls, nfs-ls, smb-ls to use ls.lua. See #106
This commit is contained in:
@@ -2,8 +2,7 @@ local afp = require "afp"
|
||||
local nmap = require "nmap"
|
||||
local shortport = require "shortport"
|
||||
local stdnse = require "stdnse"
|
||||
local tab = require "tab"
|
||||
local table = require "table"
|
||||
local ls = require "ls"
|
||||
|
||||
description = [[
|
||||
Attempts to get useful information about files from AFP volumes.
|
||||
@@ -12,45 +11,88 @@ The output is intended to resemble the output of <code>ls</code>.
|
||||
|
||||
---
|
||||
--
|
||||
--@output
|
||||
-- @usage
|
||||
-- nmap -sS -sV -p 548 --script=afp-ls target
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 548/tcp open afp syn-ack
|
||||
-- | afp-ls:
|
||||
-- | Macintosh HD
|
||||
-- | PERMISSION UID GID SIZE TIME FILENAME
|
||||
-- | -rw-r--r-- 501 80 15364 2010-06-13 17:52 .DS_Store
|
||||
-- | ---------- 0 80 0 2009-10-05 07:42 .file
|
||||
-- | drwx------ 501 20 0 2009-11-04 17:28 .fseventsd
|
||||
-- | -rw------- 0 0 393216 2010-06-14 01:49 .hotfiles.btree
|
||||
-- | drwx------ 0 80 0 2009-11-04 18:19 .Spotlight-V100
|
||||
-- | d-wx-wx-wx 0 80 0 2009-11-04 18:25 .Trashes
|
||||
-- | drwxr-xr-x 0 0 0 2009-05-18 21:29 .vol
|
||||
-- | drwxrwxr-x 0 80 0 2009-04-28 00:06 Applications
|
||||
-- | drwxr-xr-x 0 0 0 2009-05-18 21:43 bin
|
||||
-- | drwxr-xr-x 501 80 0 2010-08-10 22:55 bundles
|
||||
-- | Patrik Karlsson's Public Folder
|
||||
-- | PERMISSION UID GID SIZE TIME FILENAME
|
||||
-- | -rw------- 501 20 6148 2010-12-27 23:45 .DS_Store
|
||||
-- | -rw-r--r-- 501 20 0 2007-07-24 21:17 .localized
|
||||
-- | drwx-wx-wx 501 20 0 2009-06-19 04:01 Drop Box
|
||||
-- | patrik
|
||||
-- | PERMISSION UID GID SIZE TIME FILENAME
|
||||
-- | -rw------- 501 20 11281 2010-06-14 22:51 .bash_history
|
||||
-- | -rw-r--r-- 501 20 33 2011-01-19 20:11 .bashrc
|
||||
-- | -rw------- 501 20 3 2007-07-24 21:17 .CFUserTextEncoding
|
||||
-- | drwx------ 501 20 0 2010-09-12 14:52 .config
|
||||
-- | drwx------ 501 20 0 2010-09-12 12:29 .cups
|
||||
-- | -rw-r--r-- 501 20 15364 2010-06-13 18:34 .DS_Store
|
||||
-- | drwxr-xr-x 501 20 0 2010-09-12 14:13 .fontconfig
|
||||
-- | -rw------- 501 20 102 2010-06-14 01:46 .lesshst
|
||||
-- | -rw-r--r-- 501 20 241 2010-06-14 01:45 .profile
|
||||
-- | -rw------- 501 20 218 2010-09-12 16:35 .recently-used.xbel
|
||||
-- | Information retrieved as patrik
|
||||
-- | Volume Macintosh HD
|
||||
-- | maxfiles limit reached (10)
|
||||
-- | PERMISSION UID GID SIZE TIME FILENAME
|
||||
-- | -rw-r--r-- 501 80 15364 2010-06-13 17:52 .DS_Store
|
||||
-- | ---------- 0 80 0 2009-10-05 07:42 .file
|
||||
-- | drwx------ 501 20 0 2009-11-04 17:28 .fseventsd
|
||||
-- | -rw------- 0 0 393216 2010-06-14 01:49 .hotfiles.btree
|
||||
-- | drwx------ 0 80 0 2009-11-04 18:19 .Spotlight-V100
|
||||
-- | d-wx-wx-wx 0 80 0 2009-11-04 18:25 .Trashes
|
||||
-- | drwxr-xr-x 0 0 0 2009-05-18 21:29 .vol
|
||||
-- | drwxrwxr-x 0 80 0 2009-04-28 00:06 Applications
|
||||
-- | drwxr-xr-x 0 0 0 2009-05-18 21:43 bin
|
||||
-- | drwxr-xr-x 501 80 0 2010-08-10 22:55 bundles
|
||||
-- |
|
||||
-- | Information retrieved as: patrik
|
||||
-- |_ Output restricted to 10 entries per volume. (See afp-ls.maxfiles)
|
||||
--
|
||||
-- @args afp-ls.maxfiles If set, limits the amount of files returned by the script (default 10).
|
||||
-- | Volume Patrik Karlsson's Public Folder
|
||||
-- | PERMISSION UID GID SIZE TIME FILENAME
|
||||
-- | -rw------- 501 20 6148 2010-12-27 23:45 .DS_Store
|
||||
-- | -rw-r--r-- 501 20 0 2007-07-24 21:17 .localized
|
||||
-- | drwx-wx-wx 501 20 0 2009-06-19 04:01 Drop Box
|
||||
-- |
|
||||
-- | Volume patrik
|
||||
-- | maxfiles limit reached (10)
|
||||
-- | PERMISSION UID GID SIZE TIME FILENAME
|
||||
-- | -rw------- 501 20 11281 2010-06-14 22:51 .bash_history
|
||||
-- | -rw-r--r-- 501 20 33 2011-01-19 20:11 .bashrc
|
||||
-- | -rw------- 501 20 3 2007-07-24 21:17 .CFUserTextEncoding
|
||||
-- | drwx------ 501 20 0 2010-09-12 14:52 .config
|
||||
-- | drwx------ 501 20 0 2010-09-12 12:29 .cups
|
||||
-- | -rw-r--r-- 501 20 15364 2010-06-13 18:34 .DS_Store
|
||||
-- | drwxr-xr-x 501 20 0 2010-09-12 14:13 .fontconfig
|
||||
-- | -rw------- 501 20 102 2010-06-14 01:46 .lesshst
|
||||
-- | -rw-r--r-- 501 20 241 2010-06-14 01:45 .profile
|
||||
-- | -rw------- 501 20 218 2010-09-12 16:35 .recently-used.xbel
|
||||
-- |_
|
||||
--
|
||||
-- @xmloutput
|
||||
-- <table key="volumes">
|
||||
-- <table>
|
||||
-- <elem key="volume">Storage01</elem>
|
||||
-- <table key="files">
|
||||
-- <table>
|
||||
-- <elem key="permission">drwx------</elem>
|
||||
-- <elem key="uid">0</elem>
|
||||
-- <elem key="gid">100</elem>
|
||||
-- <elem key="size">0</elem>
|
||||
-- <elem key="time">2015-06-26 17:17</elem>
|
||||
-- <elem key="filename">Backups</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="permission">drwxr-xr-x</elem>
|
||||
-- <elem key="uid">0</elem>
|
||||
-- <elem key="gid">37</elem>
|
||||
-- <elem key="size">0</elem>
|
||||
-- <elem key="time">2015-06-19 06:36</elem>
|
||||
-- <elem key="filename">Network Trash Folder</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="permission">drwxr-xr-x</elem>
|
||||
-- <elem key="uid">0</elem>
|
||||
-- <elem key="gid">37</elem>
|
||||
-- <elem key="size">0</elem>
|
||||
-- <elem key="time">2015-06-19 06:36</elem>
|
||||
-- <elem key="filename">Temporary Items</elem>
|
||||
-- </table>
|
||||
-- </table>
|
||||
-- </table>
|
||||
-- </table>
|
||||
-- <table key="info">
|
||||
-- <elem>information retrieved as nil</elem>
|
||||
-- </table>
|
||||
-- <table key="total">
|
||||
-- <elem key="files">3</elem>
|
||||
-- <elem key="bytes">0</elem>
|
||||
-- </table>
|
||||
|
||||
-- Version 0.1
|
||||
-- Created 04/03/2011 - v0.1 - created by Patrik Karlsson
|
||||
@@ -59,34 +101,17 @@ The output is intended to resemble the output of <code>ls</code>.
|
||||
author = "Patrik Karlsson"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"discovery", "safe"}
|
||||
|
||||
|
||||
dependencies = {"afp-brute"}
|
||||
|
||||
portrule = shortport.portnumber(548, "tcp")
|
||||
|
||||
local function createFileTable()
|
||||
local filetab = tab.new()
|
||||
|
||||
tab.add(filetab, 1, "PERMISSION")
|
||||
tab.add(filetab, 2, "UID")
|
||||
tab.add(filetab, 3, "GID")
|
||||
tab.add(filetab, 4, "SIZE")
|
||||
tab.add(filetab, 5, "TIME")
|
||||
tab.add(filetab, 6, "FILENAME")
|
||||
tab.nextrow(filetab)
|
||||
|
||||
return filetab
|
||||
end
|
||||
|
||||
portrule = shortport.port_or_service(548, {"afp"})
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local afpHelper = afp.Helper:new()
|
||||
local args = nmap.registry.args
|
||||
local users = nmap.registry.afp or { ['nil'] = 'nil' }
|
||||
local maxfiles = tonumber(stdnse.get_script_args("afp-ls.maxfiles") or 10)
|
||||
local output = {}
|
||||
local maxfiles = ls.config("maxfiles")
|
||||
local output = ls.new_listing()
|
||||
|
||||
if ( args['afp.username'] ) then
|
||||
users = {}
|
||||
@@ -122,12 +147,12 @@ action = function(host, port)
|
||||
for _, vol in ipairs( vols ) do
|
||||
local status, tbl = afpHelper:Dir( vol )
|
||||
if ( not(status) ) then
|
||||
table.insert(
|
||||
ls.report_error(
|
||||
output,
|
||||
("ERROR: Failed to list the contents of %s"):format(vol))
|
||||
else
|
||||
local file_tab = createFileTable()
|
||||
local counter = maxfiles or 10
|
||||
ls.new_vol(output, vol, true)
|
||||
local continue = true
|
||||
for _, item in ipairs(tbl[1]) do
|
||||
if ( item and item.name ) then
|
||||
local status, result = afpHelper:GetFileUnixPermissions(
|
||||
@@ -135,27 +160,30 @@ action = function(host, port)
|
||||
if ( status ) then
|
||||
local status, fsize = afpHelper:GetFileSize( vol, item.name)
|
||||
if ( not(status) ) then
|
||||
table.insert(
|
||||
ls.report_error(
|
||||
output,
|
||||
("\n\nERROR: Failed to retrieve file size for %/%s"):format(vol, item.name))
|
||||
("ERROR: Failed to retrieve file size for %/%s"):format(vol, item.name))
|
||||
else
|
||||
local status, date = afpHelper:GetFileDates( vol, item.name)
|
||||
if ( not(status) ) then
|
||||
table.insert(
|
||||
ls.report_error(
|
||||
output,
|
||||
("\n\nERROR: Failed to retrieve file dates for %/%s"):format(vol, item.name))
|
||||
else
|
||||
tab.addrow(file_tab, result.privs, result.uid, result.gid, fsize, date.create, item.name)
|
||||
counter = counter - 1
|
||||
continue = ls.add_file(output, {
|
||||
result.privs, result.uid, result.gid,
|
||||
fsize, date.create, item.name
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if ( counter == 0 ) then break end
|
||||
if not continue then
|
||||
ls.report_info(output, ("maxfiles limit reached (%d)"):format(maxfiles))
|
||||
break
|
||||
end
|
||||
end
|
||||
local result_part = { name = vol }
|
||||
table.insert(result_part, tab.dump(file_tab))
|
||||
table.insert(output, result_part)
|
||||
ls.end_vol(output)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -164,13 +192,9 @@ action = function(host, port)
|
||||
status, response = afpHelper:CloseSession()
|
||||
|
||||
-- stop after first successful attempt
|
||||
if ( output and #output > 0 ) then
|
||||
table.insert(output, "")
|
||||
table.insert(output, ("Information retrieved as: %s"):format(username))
|
||||
if ( maxfiles > 0 ) then
|
||||
table.insert(output, ("Output restricted to %d entries per volume. (See afp-ls.maxfiles)"):format(maxfiles))
|
||||
end
|
||||
return stdnse.format_output(true, output)
|
||||
if #output["volumes"] > 0 then
|
||||
ls.report_info(output, ("information retrieved as %s"):format(username))
|
||||
return ls.end_listing(output)
|
||||
end
|
||||
end
|
||||
return
|
||||
|
||||
@@ -2,7 +2,7 @@ local rpc = require "rpc"
|
||||
local shortport = require "shortport"
|
||||
local stdnse = require "stdnse"
|
||||
local string = require "string"
|
||||
local tab = require "tab"
|
||||
local ls = require "ls"
|
||||
local table = require "table"
|
||||
local nmap = require "nmap"
|
||||
|
||||
@@ -29,47 +29,99 @@ These access permissions are shown only with NFSv3:
|
||||
* Extend: Write new data or add directory entries.
|
||||
* Delete: Delete an existing directory entry.
|
||||
* Execute: Execute file (no meaning for a directory).
|
||||
|
||||
Recursive listing is not implemented.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -p 111 --script=nfs-ls <target>
|
||||
-- nmap -sV --script=nfs-ls <target>
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 111/tcp open rpcbind
|
||||
-- | nfs-ls:
|
||||
-- | Arguments:
|
||||
-- | maxfiles: 10 (file listing output limited)
|
||||
-- |
|
||||
-- | NFS Export: /mnt/nfs/files
|
||||
-- | NFS Access: Read Lookup NoModify NoExtend NoDelete NoExecute
|
||||
-- | PERMISSION UID GID SIZE MODIFICATION TIME FILENAME
|
||||
-- | drwxr-xr-x 1000 100 4096 2010-06-17 12:28 /mnt/nfs/files
|
||||
-- | drwxr--r-- 1000 1002 4096 2010-05-14 12:58 sources
|
||||
-- | -rw------- 1000 1002 23606 2010-06-17 12:28 notes
|
||||
-- |
|
||||
-- | NFS Export: /home/storage/backup
|
||||
-- | NFS Access: Read Lookup Modify Extend Delete NoExecute
|
||||
-- | PERMISSION UID GID SIZE MODIFICATION TIME FILENAME
|
||||
-- | drwxr-xr-x 1000 100 4096 2010-06-11 22:31 /home/storage/backup
|
||||
-- | -rw-r--r-- 1000 1002 0 2010-06-10 08:34 filetest
|
||||
-- | drwx------ 1000 100 16384 2010-02-05 17:05 lost+found
|
||||
-- | -rw-r--r-- 0 0 5 2010-06-10 11:32 rootfile
|
||||
-- |_ lrwxrwxrwx 1000 1002 8 2010-06-10 08:34 symlink
|
||||
--
|
||||
-- @args nfs-ls.maxfiles If set, limits the amount of files returned by
|
||||
-- the script. If set to 0
|
||||
-- or less, all files are shown. The default value is 10.
|
||||
-- @args nfs-ls.human If set to <code>1</code> or <code>true</code>,
|
||||
-- shows file sizes in a human readable format with suffixes like
|
||||
-- <code>KB</code> and <code>MB</code>.
|
||||
-- @args nfs-ls.time Specifies which one of the last mac times to use in
|
||||
-- the files attributes output. Possible values are:
|
||||
-- * <code>m</code>: last modification time (mtime)
|
||||
-- * <code>a</code>: last access time (atime)
|
||||
-- * <code>c</code>: last change time (ctime)
|
||||
-- The default value is <code>m</code> (mtime).
|
||||
-- @args nfs.version The NFS protocol version to use
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 111/tcp open rpcbind
|
||||
-- | nfs-ls:
|
||||
-- | Volume /mnt/nfs/files
|
||||
-- | access: Read Lookup NoModify NoExtend NoDelete NoExecute
|
||||
-- | PERMISSION UID GID SIZE MODIFICATION TIME FILENAME
|
||||
-- | drwxr-xr-x 1000 100 4096 2010-06-17 12:28 /mnt/nfs/files
|
||||
-- | drwxr--r-- 1000 1002 4096 2010-05-14 12:58 sources
|
||||
-- | -rw------- 1000 1002 23606 2010-06-17 12:28 notes
|
||||
-- |
|
||||
-- | Volume /home/storage/backup
|
||||
-- | access: Read Lookup Modify Extend Delete NoExecute
|
||||
-- | PERMISSION UID GID SIZE MODIFICATION TIME FILENAME
|
||||
-- | drwxr-xr-x 1000 100 4096 2010-06-11 22:31 /home/storage/backup
|
||||
-- | -rw-r--r-- 1000 1002 0 2010-06-10 08:34 filetest
|
||||
-- | drwx------ 1000 100 16384 2010-02-05 17:05 lost+found
|
||||
-- | -rw-r--r-- 0 0 5 2010-06-10 11:32 rootfile
|
||||
-- | lrwxrwxrwx 1000 1002 8 2010-06-10 08:34 symlink
|
||||
-- |_
|
||||
--
|
||||
-- @xmloutput
|
||||
-- <table key="volumes">
|
||||
-- <table>
|
||||
-- <elem key="volume">/mnt/nfs/files</elem>
|
||||
-- <table key="files">
|
||||
-- <table>
|
||||
-- <elem key="permission">drwxr-xr-x</elem>
|
||||
-- <elem key="uid">1000</elem>
|
||||
-- <elem key="gid">100</elem>
|
||||
-- <elem key="size">4096</elem>
|
||||
-- <elem key="time">2010-06-11 22:31</elem>
|
||||
-- <elem key="filename">/mnt/nfs/files</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="permission">-rw-r--r--</elem>
|
||||
-- <elem key="uid">1000</elem>
|
||||
-- <elem key="gid">1002</elem>
|
||||
-- <elem key="size">0</elem>
|
||||
-- <elem key="time">2010-06-10 08:34</elem>
|
||||
-- <elem key="filename">filetest</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="permission">drwx------</elem>
|
||||
-- <elem key="uid">0</elem>
|
||||
-- <elem key="gid">0</elem>
|
||||
-- <elem key="size">16384</elem>
|
||||
-- <elem key="time">2010-02-05 17:05</elem>
|
||||
-- <elem key="filename">lost+found</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="permission">-rw-r--r--</elem>
|
||||
-- <elem key="uid">0</elem>
|
||||
-- <elem key="gid">0</elem>
|
||||
-- <elem key="size">5</elem>
|
||||
-- <elem key="time">2010-06-10 11:32</elem>
|
||||
-- <elem key="filename">rootfile</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="permission">lrwxrwxrwx</elem>
|
||||
-- <elem key="uid">1000</elem>
|
||||
-- <elem key="gid">1002</elem>
|
||||
-- <elem key="size">8</elem>
|
||||
-- <elem key="time">2010-06-10 08:34</elem>
|
||||
-- <elem key="filename">symlink</elem>
|
||||
-- </table>
|
||||
-- </table>
|
||||
-- <table key="info">
|
||||
-- <elem>access: Read Lookup NoModify NoExtend NoDelete NoExecute</elem>
|
||||
-- </table>
|
||||
-- </table>
|
||||
-- </table>
|
||||
-- <table key="total">
|
||||
-- <elem key="files">5</elem>
|
||||
-- <elem key="bytes">20493</elem>
|
||||
-- </table>
|
||||
|
||||
-- Created 05/28/2010 - v0.1 - combined nfs-dirlist and nfs-acls scripts
|
||||
-- Revised 06/04/2010 - v0.2 - make NFS exports listing with their acls
|
||||
@@ -185,14 +237,12 @@ local function table_dirlist(nfs, mount, dirlist)
|
||||
break
|
||||
end
|
||||
|
||||
if v.name ~= ".." and v.name ~= "." then
|
||||
if v.attributes then
|
||||
table.insert(files, v.name)
|
||||
attrs[files[idx]] = table_attributes(nfs, v.name, v.attributes)
|
||||
idx = idx + 1
|
||||
else
|
||||
stdnse.debug1("ERROR attributes: %s", v.name)
|
||||
end
|
||||
if v.attributes then
|
||||
table.insert(files, v.name)
|
||||
attrs[files[idx]] = table_attributes(nfs, v.name, v.attributes)
|
||||
idx = idx + 1
|
||||
else
|
||||
stdnse.debug1("ERROR attributes: %s", v.name)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -210,53 +260,59 @@ local function unmount_nfs(mount, mnt_obj, nfs_obj)
|
||||
rpc.Helper.UnmountPath(mnt_obj, mount)
|
||||
end
|
||||
|
||||
local function nfs_ls(nfs, mount, results, access)
|
||||
local function nfs_ls(nfs, mount, output)
|
||||
local dirs, attr, acs = {}, {}, {}
|
||||
local nfsobj = rpc.NFS:new()
|
||||
local mnt_comm, nfs_comm, fhandle
|
||||
|
||||
mnt_comm, fhandle = procedures.MountPath(nfs.host, mount)
|
||||
if mnt_comm == nil then
|
||||
return false, fhandle
|
||||
ls.report_error(output, fhandle)
|
||||
return false
|
||||
end
|
||||
|
||||
local nfs_comm, status = procedures.NfsOpen(nfs.host)
|
||||
if nfs_comm == nil then
|
||||
rpc.Helper.UnmountPath(mnt_comm, mount)
|
||||
return false, status
|
||||
ls.report_error(output, status)
|
||||
return false
|
||||
end
|
||||
|
||||
-- check if NFS and Mount versions are compatible
|
||||
-- RPC library will check if the Mount and NFS versions are supported
|
||||
if (nfs_comm.version == 1) then
|
||||
unmount_nfs(mount, mnt_comm, nfs_comm)
|
||||
return false, string.format("NFS v%d not supported", nfs_comm.version)
|
||||
unmount_nfs(mount, mnt_comm, nfs_comm)
|
||||
ls.report_error(output,
|
||||
string.format("NFS v%d not supported", nfs_comm.version))
|
||||
return false
|
||||
elseif ((nfs_comm.version == 2 and mnt_comm.version > 2) or
|
||||
(nfs_comm.version == 3 and mnt_comm.version ~= 3)) then
|
||||
unmount_nfs(mount, mnt_comm, nfs_comm)
|
||||
return false, string.format("versions mismatch, NFS v%d - Mount v%d",
|
||||
nfs_comm.version, mnt_comm.version)
|
||||
(nfs_comm.version == 3 and mnt_comm.version ~= 3)) then
|
||||
unmount_nfs(mount, mnt_comm, nfs_comm)
|
||||
ls.report_error(output,
|
||||
string.format("versions mismatch, NFS v%d - Mount v%d",
|
||||
nfs_comm.version, mnt_comm.version))
|
||||
return false
|
||||
end
|
||||
|
||||
status, attr = nfsobj:GetAttr(nfs_comm, fhandle)
|
||||
if not status then
|
||||
unmount_nfs(mount, mnt_comm, nfs_comm)
|
||||
return status, attr
|
||||
ls.report_error(output, attr)
|
||||
return status
|
||||
end
|
||||
|
||||
table.insert(results, table_attributes(nfs, mount, attr))
|
||||
|
||||
if nfs_comm.version == 3 then
|
||||
status, acs = nfsobj:Access(nfs_comm, fhandle, 0x0000003F)
|
||||
if status then
|
||||
acs.str = rpc.Util.format_access(acs.mask, nfs_comm.version)
|
||||
table.insert(access, acs.str)
|
||||
ls.report_info(output, string.format("access: %s", acs.str))
|
||||
end
|
||||
|
||||
status, dirs = nfsobj:ReadDirPlus(nfs_comm, fhandle)
|
||||
if status then
|
||||
for _,v in ipairs(table_dirlist(nfs, mount, dirs.entries)) do
|
||||
table.insert(results, v)
|
||||
ls.add_file(output, {v.type .. v.mode, v.uid, v.gid, v.size,
|
||||
v.time, v.filename})
|
||||
end
|
||||
end
|
||||
elseif nfs_comm.version == 2 then
|
||||
@@ -265,67 +321,39 @@ local function nfs_ls(nfs, mount, results, access)
|
||||
local lookup = {}
|
||||
for _, v in ipairs(dirs.entries) do
|
||||
if ((0 < nfs.maxfiles) and (#lookup >= nfs.maxfiles)) then
|
||||
break
|
||||
break
|
||||
end
|
||||
|
||||
if v.name ~= ".." and v.name ~= "." then
|
||||
local f = {}
|
||||
status, f = nfsobj:LookUp(nfs_comm, fhandle, v.name)
|
||||
f.name = v.name
|
||||
table.insert(lookup, f)
|
||||
end
|
||||
local f = {}
|
||||
status, f = nfsobj:LookUp(nfs_comm, fhandle, v.name)
|
||||
f.name = v.name
|
||||
table.insert(lookup, f)
|
||||
end
|
||||
|
||||
for _, v in ipairs(table_dirlist(nfs, mount, lookup)) do
|
||||
table.insert(results, v)
|
||||
ls.add_file(output, {v.type .. v.mode, v.uid, v.gid, v.size,
|
||||
v.time, v.filename})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unmount_nfs(mount, mnt_comm, nfs_comm)
|
||||
return status, dirs
|
||||
end
|
||||
|
||||
local function report(nfs, table)
|
||||
local outtab, time = tab.new(), ""
|
||||
|
||||
if nfs.time == "mtime" then
|
||||
time = "MODIFICATION TIME"
|
||||
elseif nfs.time == "atime" then
|
||||
time = "ACCESS TIME"
|
||||
elseif nfs.time == "ctime" then
|
||||
time = "CHANGE TIME"
|
||||
end
|
||||
|
||||
tab.add(outtab, 1, "PERMISSION")
|
||||
tab.add(outtab, 2, "UID")
|
||||
tab.add(outtab, 3, "GID")
|
||||
tab.add(outtab, 4, "SIZE")
|
||||
tab.add(outtab, 5, time)
|
||||
tab.add(outtab, 6, "FILENAME")
|
||||
tab.nextrow(outtab)
|
||||
|
||||
for _,f in pairs(table) do
|
||||
local perm = f.type .. f.mode
|
||||
tab.addrow(outtab, perm, f.uid, f.gid,
|
||||
f.size, f.time, f.filename)
|
||||
end
|
||||
return tab.dump(outtab)
|
||||
return status
|
||||
end
|
||||
|
||||
local mainaction = function(host)
|
||||
local o, results, mounts, status = {}, {}, {}
|
||||
local results, mounts, status = {}, {}
|
||||
local nfs_info =
|
||||
{
|
||||
host = host,
|
||||
--recurs = tonumber(nmap.registry.args['nfs-ls.recurs']) or 1,
|
||||
}
|
||||
local output = ls.new_listing()
|
||||
|
||||
nfs_info.version, nfs_info.maxfiles, nfs_info.time,
|
||||
nfs_info.human = stdnse.get_script_args('nfs.version',
|
||||
'nfs-ls.maxfiles','nfs-ls.time','nfs-ls.human')
|
||||
|
||||
nfs_info.maxfiles = tonumber(nfs_info.maxfiles) or 10
|
||||
nfs_info.version, nfs_info.time = stdnse.get_script_args('nfs.version',
|
||||
'nfs-ls.time')
|
||||
nfs_info.maxfiles = ls.config('maxfiles')
|
||||
nfs_info.human = ls.config('human')
|
||||
|
||||
if nfs_info.time == "a" or nfs_info.time == "A" then
|
||||
nfs_info.time = "atime"
|
||||
@@ -335,15 +363,6 @@ local mainaction = function(host)
|
||||
nfs_info.time = "mtime"
|
||||
end
|
||||
|
||||
if nfs_info.maxfiles > 0 then
|
||||
local args = {}
|
||||
args['name'] = 'Arguments:'
|
||||
table.insert(args,
|
||||
string.format("maxfiles: %d (file listing output limited)",
|
||||
nfs_info.maxfiles))
|
||||
table.insert(o, args)
|
||||
end
|
||||
|
||||
status, mounts = procedures.ShowMounts(nfs_info.host)
|
||||
if not status or mounts == nil then
|
||||
if mounts then
|
||||
@@ -354,22 +373,13 @@ local mainaction = function(host)
|
||||
end
|
||||
|
||||
for _, v in ipairs(mounts) do
|
||||
local results, access, err = {}, {}
|
||||
status, err = nfs_ls(nfs_info, v.name, results, access)
|
||||
if not status then
|
||||
table.insert(o, string.format("\nNFS Export %s", v.name))
|
||||
table.insert(o, string.format("ERROR: %s", err))
|
||||
else
|
||||
table.insert(o,
|
||||
string.format("\nNFS Export: %s", results[1].filename))
|
||||
if #access ~= 0 then
|
||||
table.insert(o, string.format("NFS Access: %s", access[1]))
|
||||
end
|
||||
table.insert(o, {report(nfs_info, results)})
|
||||
end
|
||||
local err
|
||||
ls.new_vol(output, v.name, true)
|
||||
status = nfs_ls(nfs_info, v.name, output)
|
||||
ls.end_vol(output)
|
||||
end
|
||||
|
||||
return stdnse.format_output(true, o)
|
||||
return ls.end_listing(output)
|
||||
end
|
||||
|
||||
hostaction = function(host)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
local bit = require 'bit'
|
||||
local smb = require 'smb'
|
||||
local string = require 'string'
|
||||
local stdnse = require 'stdnse'
|
||||
local tab = require 'tab'
|
||||
local table = require "table"
|
||||
local ls = require 'ls'
|
||||
|
||||
local openssl= stdnse.silent_require 'openssl'
|
||||
|
||||
description = [[
|
||||
@@ -13,32 +14,97 @@ The output is intended to resemble the output of the UNIX <code>ls</code> comman
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -p 445 <ip> --script smb-ls --script-args 'share=c$,path=\temp'
|
||||
-- nmap -p 445 <ip> --script smb-enum-shares,smb-ls
|
||||
--
|
||||
-- @args smb-ls.share (or smb-ls.shares) the share (or a colon-separated list
|
||||
-- of shares) to connect to (default: use shares found by smb-enum-shares)
|
||||
-- @args smb-ls.path the path, relative to the share to list the contents from
|
||||
-- (default: root of the share)
|
||||
-- @args smb-ls.pattern the search pattern to execute (default: *)
|
||||
-- @args smb-ls.checksum download each file and calculate a checksum
|
||||
-- (default: false)
|
||||
--
|
||||
-- @output
|
||||
-- Host script results:
|
||||
-- | smb-ls:
|
||||
-- | Directory of \\192.168.56.101\c$\
|
||||
-- | 2007-12-02 00:20:09 0 AUTOEXEC.BAT
|
||||
-- | 2007-12-02 00:20:09 0 CONFIG.SYS
|
||||
-- | 2007-12-02 00:53:39 <DIR> Documents and Settings
|
||||
-- | 2009-09-08 13:26:10 <DIR> e5a6b742d36facb19c5192852c43
|
||||
-- | 2008-12-01 02:06:29 <DIR> Inetpub
|
||||
-- | 2007-02-18 00:31:38 94720 msizap.exe
|
||||
-- | 2007-12-02 00:55:01 <DIR> Program Files
|
||||
-- | 2008-12-01 02:05:52 <DIR> temp
|
||||
-- | 2011-12-16 14:40:18 <DIR> usr
|
||||
-- | 2007-12-02 00:42:40 <DIR> WINDOWS
|
||||
-- |_ 2007-12-02 00:22:38 <DIR> wmpub
|
||||
--
|
||||
-- @args smb-ls.share [optional] the share to connect to
|
||||
-- @args smb-ls.shares [optional] a colon-separated list of shares to connect to
|
||||
-- @args smb-ls.path [optional] the path, relative to the share to list the contents from
|
||||
-- @args smb-ls.pattern [optional] the search pattern to execute (default: *)
|
||||
-- @args smb-ls.maxdepth [optional] the maximum depth to recurse into a directory (default: no recursion)
|
||||
-- @args smb-ls.maxfiles [optional] return only a certain amount of files
|
||||
-- @args smb-ls.checksum [optional] download each file and calculate a SHA1 checksum
|
||||
-- @args smb-ls.errors [optional] report connection errors
|
||||
-- | Volume \\192.168.56.101\c$\
|
||||
-- | SIZE TIME FILENAME
|
||||
-- | 0 2007-12-02 00:20:09 AUTOEXEC.BAT
|
||||
-- | 0 2007-12-02 00:20:09 CONFIG.SYS
|
||||
-- | <DIR> 2007-12-02 00:53:39 Documents and Settings
|
||||
-- | <DIR> 2009-09-08 13:26:10 e5a6b742d36facb19c5192852c43
|
||||
-- | <DIR> 2008-12-01 02:06:29 Inetpub
|
||||
-- | 94720 2007-02-18 00:31:38 msizap.exe
|
||||
-- | <DIR> 2007-12-02 00:55:01 Program Files
|
||||
-- | <DIR> 2008-12-01 02:05:52 temp
|
||||
-- | <DIR> 2011-12-16 14:40:18 usr
|
||||
-- | <DIR> 2007-12-02 00:42:40 WINDOWS
|
||||
-- | <DIR> 2007-12-02 00:22:38 wmpub
|
||||
-- |_
|
||||
--
|
||||
-- @xmloutput
|
||||
-- <table key="volumes">
|
||||
-- <table>
|
||||
-- <table key="files">
|
||||
-- <table>
|
||||
-- <elem key="size">0</elem>
|
||||
-- <elem key="time">2007-12-02 00:20:09</elem>
|
||||
-- <elem key="filename">AUTOEXEC.BAT</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size">0</elem>
|
||||
-- <elem key="time">2007-12-02 00:20:09</elem>
|
||||
-- <elem key="filename">CONFIG.SYS</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size"><DIR></elem>
|
||||
-- <elem key="time">2007-12-02 00:53:39</elem>
|
||||
-- <elem key="filename">Documents and Settings</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size"><DIR></elem>
|
||||
-- <elem key="time">2009-09-08 13:26:10</elem>
|
||||
-- <elem key="filename">e5a6b742d36facb19c5192852c43</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size"><DIR></elem>
|
||||
-- <elem key="time">2008-12-01 02:06:29</elem>
|
||||
-- <elem key="filename">Inetpub</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size">94720</elem>
|
||||
-- <elem key="time">2007-02-18 00:31:38</elem>
|
||||
-- <elem key="filename">msizap.exe</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size"><DIR></elem>
|
||||
-- <elem key="time">2007-12-02 00:55:01</elem>
|
||||
-- <elem key="filename">Program Files</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size"><DIR></elem>
|
||||
-- <elem key="time">2008-12-01 02:05:52</elem>
|
||||
-- <elem key="filename">temp</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size"><DIR></elem>
|
||||
-- <elem key="time">2011-12-16 14:40:18</elem>
|
||||
-- <elem key="filename">usr</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size"><DIR></elem>
|
||||
-- <elem key="time">2007-12-02 00:42:40</elem>
|
||||
-- <elem key="filename">WINDOWS</elem>
|
||||
-- </table>
|
||||
-- <table>
|
||||
-- <elem key="size"><DIR></elem>
|
||||
-- <elem key="time">2007-12-02 00:22:38</elem>
|
||||
-- <elem key="filename">wmpub</elem>
|
||||
-- </table>
|
||||
-- </table>
|
||||
-- <elem key="volume">\\192.168.1.2\Downloads</elem>
|
||||
-- </table>
|
||||
-- </table>
|
||||
|
||||
author = "Patrik Karlsson"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
@@ -49,10 +115,6 @@ local arg_shares = stdnse.get_script_args(SCRIPT_NAME .. '.shares')
|
||||
local arg_share = stdnse.get_script_args(SCRIPT_NAME .. '.share')
|
||||
local arg_path = stdnse.get_script_args(SCRIPT_NAME .. '.path') or '\\'
|
||||
local arg_pattern = stdnse.get_script_args(SCRIPT_NAME .. '.pattern') or '*'
|
||||
local arg_maxfiles = tonumber(stdnse.get_script_args(SCRIPT_NAME .. '.maxfiles'))
|
||||
local arg_maxdepth = stdnse.get_script_args(SCRIPT_NAME .. '.maxdepth')
|
||||
local arg_checksum = stdnse.get_script_args(SCRIPT_NAME .. '.checksum')
|
||||
local arg_errors = stdnse.get_script_args(SCRIPT_NAME .. '.errors')
|
||||
|
||||
hostrule = function(host)
|
||||
return ( smb.get_port(host) ~= nil and
|
||||
@@ -65,7 +127,45 @@ local function is_dir(fe)
|
||||
return ( bit.band(fe.attrs, 16) == 16 )
|
||||
end
|
||||
|
||||
local function fail(err) return stdnse.format_output(false, err) end
|
||||
local function list_files(host, share, smbstate, path, options, output, maxdepth, basedir)
|
||||
basedir = basedir or ""
|
||||
local continue
|
||||
|
||||
for fe in smb.find_files(smbstate, path .. '\\' .. arg_pattern, options) do
|
||||
if basedir == "" or (fe.fname ~= "." and fe.fname ~= "..") then
|
||||
if ls.config('checksum') and not(is_dir(fe)) then
|
||||
local status, content = smb.file_read(host, share, path .. '\\' .. fe.fname, nil, {file_create_disposition=1})
|
||||
local sha1 = status and stdnse.tohex(openssl.sha1(content)) or ""
|
||||
continue = ls.add_file(output, {is_dir(fe) and '<DIR>' or fe.eof,
|
||||
fe.created, basedir .. fe.fname, sha1})
|
||||
else
|
||||
continue = ls.add_file(output, {is_dir(fe) and '<DIR>' or fe.eof,
|
||||
fe.created, basedir .. fe.fname})
|
||||
end
|
||||
if not continue then
|
||||
return false
|
||||
end
|
||||
if is_dir(fe) then
|
||||
continue = true
|
||||
if maxdepth > 0 then
|
||||
continue = list_files(host, share, smbstate,
|
||||
path .. '\\' .. fe.fname, options,
|
||||
output, maxdepth - 1,
|
||||
basedir .. fe.fname .. '\\')
|
||||
elseif maxdepth < 0 then
|
||||
continue = list_files(host, share, smbstate,
|
||||
path .. '\\' .. fe.fname, options,
|
||||
output, -1,
|
||||
basedir .. fe.fname .. '\\')
|
||||
end
|
||||
if not continue then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
action = function(host)
|
||||
|
||||
@@ -78,91 +178,40 @@ action = function(host)
|
||||
arg_shares = host.registry['smb_shares']
|
||||
end
|
||||
|
||||
-- arg_maxdepth defaults to 1 (no recursion)
|
||||
if arg_maxdepth == nil then
|
||||
arg_maxdepth = 1
|
||||
else
|
||||
arg_maxdepth = tonumber(arg_maxdepth)
|
||||
end
|
||||
|
||||
local output = {}
|
||||
local output = ls.new_listing()
|
||||
|
||||
for _, share in ipairs(arg_shares) do
|
||||
local status, smbstate = smb.start_ex(host, true, true, share,
|
||||
nil, nil, nil)
|
||||
if ( not(status) ) then
|
||||
if arg_errors then
|
||||
table.insert(
|
||||
output,
|
||||
("Failed to authenticate to server (%s) for directory of \\\\%s\\%s%s"):format(smbstate, stdnse.get_hostname(host), share, arg_path))
|
||||
table.insert(output, "")
|
||||
end
|
||||
ls.report_error(
|
||||
output,
|
||||
("Failed to authenticate to server (%s) for directory of \\\\%s\\%s%s"):format(smbstate, stdnse.get_hostname(host), share, arg_path))
|
||||
else
|
||||
|
||||
table.insert(output, "")
|
||||
|
||||
-- remove leading slash
|
||||
arg_path = ( arg_path:sub(1,2) == '\\' and arg_path:sub(2) or arg_path )
|
||||
|
||||
-- fixup checksum argument
|
||||
arg_checksum = ( arg_checksum == 'true' or arg_checksum == '1' ) and true or false
|
||||
|
||||
local options = { max_depth = arg_maxdepth, max_files = arg_maxfiles }
|
||||
local options = {}
|
||||
local depth, path, dirs = 0, arg_path, {}
|
||||
local file_count, dir_count, total_bytes = 0, 0, 0
|
||||
local continue = true
|
||||
|
||||
repeat
|
||||
-- we need three columns per row, plus one for checksum if
|
||||
-- requested
|
||||
local lstab = tab.new((arg_checksum and 4 or 3))
|
||||
|
||||
for fe in smb.find_files(smbstate, path .. '\\' .. arg_pattern, options ) do
|
||||
if ( arg_checksum and not(is_dir(fe)) ) then
|
||||
local status, content = smb.file_read(host, share, path .. '\\' .. fe.fname, nil, {file_create_disposition=1})
|
||||
local sha1 = ( status and stdnse.tohex(openssl.sha1(content)) or "" )
|
||||
tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname, sha1)
|
||||
else
|
||||
tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname)
|
||||
end
|
||||
|
||||
arg_maxfiles = ( arg_maxfiles and arg_maxfiles - 1 )
|
||||
if ( arg_maxfiles == 0 ) then
|
||||
break
|
||||
end
|
||||
|
||||
if ( is_dir(fe) ) then
|
||||
dir_count = dir_count + 1
|
||||
if ( fe.fname ~= '.' and fe.fname ~= '..' ) then
|
||||
table.insert(dirs, { depth = depth + 1, path = path .. '\\' .. fe.fname } )
|
||||
end
|
||||
else
|
||||
total_bytes = total_bytes + fe.eof
|
||||
file_count = file_count + 1
|
||||
end
|
||||
end
|
||||
table.insert(output, { name = ("Directory of %s"):format( '\\\\' .. stdnse.get_hostname(host) .. '\\' .. share .. path), tab.dump(lstab) })
|
||||
|
||||
path = nil
|
||||
if ( #dirs ~= 0 ) then
|
||||
local dir = table.remove(dirs, 1)
|
||||
depth = dir.depth
|
||||
if ( not(arg_maxdepth) or ( dir.depth < arg_maxdepth ) ) then
|
||||
path = dir.path
|
||||
table.insert(output, "")
|
||||
end
|
||||
end
|
||||
until(not(path) or arg_maxfiles == 0)
|
||||
|
||||
ls.new_vol(
|
||||
output,
|
||||
'\\\\' .. stdnse.get_hostname(host) .. '\\' .. share .. path,
|
||||
false)
|
||||
continue = list_files(host, share, smbstate, path, options,
|
||||
output, ls.config('maxdepth'))
|
||||
if not continue then
|
||||
ls.report_info(
|
||||
output,
|
||||
string.format("maxfiles limit reached (%d)", ls.config('maxfiles')))
|
||||
end
|
||||
ls.end_vol(output)
|
||||
smb.stop(smbstate)
|
||||
|
||||
local summary = { name = "Total Files Listed:",
|
||||
("%8d File(s)\t%d bytes"):format(file_count, total_bytes),
|
||||
("%8d Dir(s)"):format(dir_count) }
|
||||
table.insert(output, "")
|
||||
table.insert(output, summary)
|
||||
table.insert(output, "")
|
||||
end
|
||||
end
|
||||
|
||||
return stdnse.format_output(true, output)
|
||||
return ls.end_listing(output)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user