Nmap smb-psexec NSE Script


This page contains detailed information about how to use the smb-psexec NSE script. For list of all NSE scripts, visit the Nmap NSE Library.

Select:
Overview
Error Messages

Script Overview


Script source code: https://github.com/nmap/nmap/tree/master/scripts/smb-psexec.nse
Script categories: intrusive
Target service / protocol: smb, netbios, tcp, udp
Target network port(s): 137, 139, 445
List of CVEs: -

Script Description


The smb-psexec.nse script implements remote process execution similar to the Sysinternals' psexec tool, allowing a user to run a series of programs on a remote machine and read the output. This is great for gathering information about servers, running the same tool on a range of system, or even installing a backdoor on a collection of computers.

This script can run commands present on the remote machine, such as ping or tracert, or it can upload a program and run it, such as pwdump6 or a backdoor. Additionally, it can read the program's stdout/stderr and return it to the user (works well with ping, pwdump6, etc), or it can read a file that the process generated (fgdump, for example, generates a file), or it can just start the process and let it run headless (a backdoor might run like this).

To use this, a configuration file should be created and edited. Several configuration files are included that you can customize, or you can write your own. This config file is placed in nselib/data/psexec (if you aren't sure where that is, search your system for default.lua), then is passed to Nmap as a script argument (for example, myconfig.lua would be passed as --script-args=config=myconfig.

The configuration file consists mainly of a module list. Each module is defined by a lua table, and contains fields for the name of the program, the executable and arguments for the program, and a score of other options. Modules also have an 'upload' field, which determines whether or not the module is to be uploaded. Here is a simple example of how to run net localgroup administrators, which returns a list of users in the "administrators" group (take a look at the examples.lua configuration file for these examples):

mod = {}
mod.upload           = false
mod.name             = "Example 1: Membership of 'administrators'"
mod.program          = "net.exe"
mod.args             = "localgroup administrators"
table.insert(modules, mod)

mod.upload is false, meaning the program should already be present on the remote system (since 'net.exe' is on every version of Windows, this should be the case). mod.name defines the name that the program will have in the output. mod.program and mod.args obviously define which program is going to be run. The output for this script is this:

|  Example 1: Membership of 'administrators'
|  | Alias name     administrators
|  | Comment        Administrators have complete and unrestricted access to the computer/domain
|  |
|  | Members
|  |
|  | -------------------------------------------------------------------------------
|  | Administrator
|  | ron
|  | test
|  | The command completed successfully.
|  |
|  |_

That works, but it's really ugly. In general, we can use mod.find, mod.replace, mod.remove, and mod.noblank to clean up the output. For this example, we're going to use mod.remove to remove a lot of the useless lines, and mod.noblank to get rid of the blank lines that we don't want:

mod = {}
mod.upload           = false
mod.name             = "Example 2: Membership of 'administrators', cleaned"
mod.program          = "net.exe"
mod.args             = "localgroup administrators"
mod.remove           = {"The command completed", "%-%-%-%-%-%-%-%-%-%-%-", "Members", "Alias name", "Comment"}
mod.noblank          = true
table.insert(modules, mod)

We can see that the output is now much cleaner:

|  Example 2: Membership of 'administrators', cleaned
|  | Administrator
|  | ron
|  |_test

For our next command, we're going to run Windows' ipconfig.exe, which outputs a significant amount of unnecessary information, and what we do want isn't formatted very nicely. All we want is the IP address and MAC address, and we get it using mod.find and mod.replace:

mod = {}
mod.upload           = false
mod.name             = "Example 3: IP Address and MAC Address"
mod.program          = "ipconfig.exe"
mod.args             = "/all"
mod.maxtime          = 1
mod.find             = {"IP Address", "Physical Address", "Ethernet adapter"}
mod.replace          = {{"%. ", ""}, {"-", ":"}, {"Physical Address", "MAC Address"}}
table.insert(modules, mod)

This module searches for lines that contain "IP Address", "Physical Address", or "Ethernet adapter". In these lines, a ". " is replaced with nothing, a "-" is replaced with a colon, and the term "Physical Address" is replaced with "MAC Address" (arguably unnecessary). Run ipconfig /all yourself to see what we start with, but here's the final output:

|  Example 3: IP Address and MAC Address
|  | Ethernet adapter Local Area Connection:
|  |    MAC Address: 00:0C:29:12:E6:DB
|  |_   IP Address: 192.168.1.21|  Example 3: IP Address and MAC Address

Another interesting part of this script is that variables can be used in any script fields. There are two types of variables: built-in and user-supplied. Built-in variables can be anything found in the config table, most of which are listed below. The more interesting ones are:

  • $lhost: The address of the scanner
  • $rhost: The address being scanned
  • $path: The path where the scripts are uploaded
  • $share: The share where the script was uploaded

User-supplied arguments are given on the commandline, and can be controlled by mod.req_args in the configuration file. Arguments are given by the user in --script-args; for example, to set $host to '1.2.3.4', the user would pass in --script-args=host=1.2.3.4. To ensure the user passes in the host variable, mod.req_args would be set to {'host'}.

Here is a module that pings the local ip address:

mod = {}
mod.upload           = false
mod.name             = "Example 4: Can the host ping our address?"
mod.program          = "ping.exe"
mod.args             = "$lhost"
mod.remove           = {"statistics", "Packet", "Approximate", "Minimum"}
mod.noblank          = true
mod.env              = "SystemRoot=c:\\WINDOWS"
table.insert(modules, mod)

And the output:

|  Example 4: Can the host ping our address?
|  | Pinging 192.168.1.100 with 32 bytes of data:
|  | Reply from 192.168.1.100: bytes=32 time<1ms TTL=64
|  | Reply from 192.168.1.100: bytes=32 time<1ms TTL=64
|  | Reply from 192.168.1.100: bytes=32 time<1ms TTL=64
|  |_Reply from 192.168.1.100: bytes=32 time<1ms TTL=64

And this module pings an arbitrary address that the user is expected to give:

mod = {}
mod.upload           = false
mod.name             = "Example 5: Can the host ping $host?"
mod.program          = "ping.exe"
mod.args             = "$host"
mod.remove           = {"statistics", "Packet", "Approximate", "Minimum"}
mod.noblank          = true
mod.env              = "SystemRoot=c:\\WINDOWS"
mod.req_args         = {'host'}
table.insert(modules, mod)

And the output (note that we had to up the timeout so this would complete; we'll talk about override values later):

$ ./nmap -n -d -p445 --script=smb-psexec --script-args=smbuser=test,smbpass=test,config=examples,host=1.2.3.4 192.168.1.21
[...]
|  Example 5: Can the host ping 1.2.3.4?
|  | Pinging 1.2.3.4 with 32 bytes of data:
|  | Request timed out.
|  | Request timed out.
|  | Request timed out.
|  |_Request timed out.

For the final example, we'll use the upload command to upload fgdump.exe, run it, download its output file, and clean up its logfile. You'll have to put fgdump.exe in the same folder as the script for this to work:

mod = {}
mod.upload           = true
mod.name             = "Example 6: FgDump"
mod.program          = "fgdump.exe"
mod.args             = "-c -l fgdump.log"
mod.url              = "http://www.foofus.net/fizzgig/fgdump/"
mod.tempfiles        = {"fgdump.log"}
mod.outfile          = "127.0.0.1.pwdump"
table.insert(modules, mod)

The -l argument for fgdump supplies the name of the logfile. That file is listed in the mod.tempfiles field. What, exactly, does mod.tempfiles do? It simply gives the service a list of files to delete while cleaning up. The cleanup process will be discussed later.

mod.url is displayed to the user if mod.program isn't found in nselib/data/psexec/. And finally, mod.outfile is the file that is downloaded from the system. This is required because fgdump writes to an output file instead of to stdout (pwdump6, for example, doesn't require mod.outfile.

Now that we've seen a few possible combinations of fields, I present a complete list of all fields available and what each of them do. Many of them will be familiar, but there are a few that aren't discussed in the examples:

  • upload (boolean) true if it's a local file to upload, false if it's already on the host machine. If upload is true, program has to be in nselib/data/psexec.
  • name (string) The name to display above the output. If this isn't given, program .. args are used.
  • program (string) If upload is false, the name (fully qualified or relative) of the program on the remote system; if upload is true, the name of the local file that will be uploaded (stored in nselib/data/psexec).
  • args (string) Arguments to pass to the process.
  • env (string) Environmental variables to pass to the process, as name=value pairs, delimited, per Microsoft's spec, by NULL characters (string.char(0)).
  • maxtime (integer) The approximate amount of time to wait for this process to complete. The total timeout for the script before it gives up waiting for a response is the total of all maxtime fields.
  • extrafiles (string[]) Extra file(s) to upload before running the program. These will not be renamed (because, presumably, if they are then the program won't be able to find them), but they will be marked as hidden/system/etc. This may cause a race condition if multiple people are doing this at once, but there isn't much we can do. The files are also deleted afterwards as tempfiles would be. The files have to be in the same directory as programs (nselib/data/psexec), but the program doesn't necessarily need to be an uploaded one.
  • tempfiles (string[]) A list of temporary files that the process is known to create (if the process does create files, using this field is recommended because it helps avoid making a mess on the remote system).
  • find (string[]) Only display lines that contain the given string(s) (for example, if you're searching for a line that contains "IP Address", set this to {'IP Address'}. This allows Lua-style patterns, see: http://lua-users.org/wiki/PatternsTutorial (don't forget to escape special characters with a %). Note that this is client-side only; the full output is still returned, the rest is removed while displaying. The line of output only needs to match one of the strings given here.
  • remove (string[]) Opposite of find; this removes lines containing the given string(s) instead of displaying them. Like find, this is client-side only and uses Lua-style patterns. If remove and find are in conflict, then remove takes priority.
  • noblank (boolean) Setting this to true removes all blank lines from the output.
  • replace (table) A table of values to replace in the strings returned. Like find and replace, this is client-side only and uses Lua-style patterns.
  • headless (boolean) If headless is set to true, the program doesn't return any output; rather, it runs detached from the service so that, when the service ends, the program keeps going. This can be useful for, say, a monitoring program. Or a backdoor, if that's what you're into (a Metasploit payload should work nicely). Not compatible with: find, remove, noblank, replace, maxtime, outfile.
  • enabled (boolean) Set to false, and optionally set disabled_message, if you don't want a module to run. Alternatively, you can comment out the process.
  • disabled_message (string) Displayed if the module is disabled.
  • url (string) A module where the user can download the uploadable file. Displayed if the uploadable file is missing.
  • outfile (string) If set, the specified file will be returned instead of stdout.
  • req_args (string[]) An array of arguments that the user must set in --script-args.

Any field in the configuration file can contain variables, as discussed. Here are some of the available built-in variables:

  • $lhost: local IP address as a string.
  • $lport: local port (meaningless; it'll change by the time the module is uploaded since multiple connections are made).
  • $rhost: remote IP address as a string.
  • $rport: remote port.
  • $lmac: local MAC address as a string in the xx:xx:xx:xx:xx:xx format (note: requires root).
  • $path: the path where the file will be uploaded to.
  • $service_name: the name of the service that will be running this program
  • $service_file: the name of the executable file for the service
  • $temp_output_file: The (ciphered) file where the programs' output will be written before being renamed to $output_file
  • $output_file: The final name of the (ciphered) output file. When this file appears, the script downloads it and stops the service
  • $timeout: The total amount of time the script is going to run before it gives up and stops the process
  • $share: The share that everything was uploaded to
  • (script args): Any value passed as a script argument will be replaced (for example, if Nmap is run with --script-args=var3=10, then $var3 in any field will be replaced with 10. See the req_args field above. Script argument values take priority over config values.

In addition to modules, the configuration file can also contain overrides. Most of these aren't useful, so I'm not going to go into great detail. Search smb-psexec.nse for any reference to the config table; any value in the config table can be overridden with the overrides table in the module. The most useful value to override is probably timeout.

Before and after scripts are run, and when there's an error, a cleanup is performed. in the cleanup, we attempt to stop the remote processes, delete all programs, output files, temporary files, extra files, etc. A lot of effort was put into proper cleanup, since making a mess on remote systems is a bad idea.

Now that I've talked at length about how to use this script, I'd like to spend some time talking about how it works.

Running a script happens in several stages:

  1. An open fileshare is found that we can write to. Finding an open fileshare basically consists of enumerating all shares and seeing which one(s) we have access to.
  2. A "service wrapper", and all of the uploadable/extra files, are uploaded. Before they're uploaded, the name of each file is obfuscated. The obfuscation completely renames the file, is unique for each source system, and doesn't change between multiple runs. This obfuscation has the benefit of preventing filenames from overlapping if multiple people are running this against the same computer, and also makes it more difficult to determine their purposes. The reason for keeping them consistent for every run is to make cleanup possible: a random filename, if the script somehow fails, will be left on the system.
  3. A new service is created and started. The new service has a random name for the same reason the files do, and points at the 'service wrapper' program that was uploaded.
  4. The service runs the processes. One by one, the processes are run and their output is captured. The output is obfuscated using a simple (and highly insecure) xor algorithm, which is designed to prevent casual sniffing (but won't deter intelligent attackers). This data is put into a temporary output file. When all the programs have finished, the file is renamed to the final output file
  5. The output file is downloaded, and the cleanup is performced. The file being renamed triggers the final stage of the program, where the data is downloaded and all relevant files are deleted.
  6. Output file, now decrypted, is formatted and displayed to the user.

And that's how it works!

Please post any questions, or suggestions for better modules, to [email protected].

And, as usual, since this tool can be dangerous and can easily be viewed as a malicious tool -- use this responsibly, and don't break any laws with it.

Some ideas for later versions (TODO):

  • Set up a better environment for scripts (PATH, SystemRoot, etc). Without this, a lot of programs (especially ones that deal with network traffic) behave oddly.
  • Abstract the code required to run remote processes so other scripts can use it more easily (difficult, but will ultimately be well worth it later). (May actually not be possible. There is a lot of overhead and specialized code in this module. We'll see, though.)
  • Let user specify an output file (per-script) so they can, for example, download binary files (don't think it's worthwhile).
  • Consider running the external programs in parallel (not sure if the benefits outweigh the drawbacks).
  • Let the config request the return code from the process instead of the output (not sure if doing this would be worth the effort).
  • Check multiple shares in a single session to save packets (and see where else we can tighten up the amount of traffic).

Smb-psexec NSE Script Arguments


This is a full list of arguments supported by the smb-psexec.nse script:

cleanup

Set to only clean up any mess we made (leftover files, processes, etc. on the host OS) on a previous run of the script. This will attempt to delete the files from every share, not just the first one. This is done to prevent leftover files if the OS changes the ordering of the shares (there's no guarantee of shares coming back in any particular order) Note that cleaning up is still fairly invasive, since it has to re-discover the proper share, connect to it, delete files, open the services manager, etc.

config

The config file to use (eg, default). Config files require a .lua extension, and are located in nselib/data/psexec.

key

Script uses this value instead of a random encryption key (useful for debugging the crypto).

nocipher

Set to disable the ciphering of the returned text (useful for debugging).

nocleanup

Set to not clean up at all; this leaves the files on the remote system and the wrapper service installed. This is bad in practice, but significantly reduces the network traffic and makes analysis easier.

nohide

Don't set the uploaded files to hidden/system/etc.

share

Set to override the share used for uploading. This also stops shares from being enumerated, and all other shares will be ignored. No checks are done to determine whether or not this is a valid share before using it. Reqires sharepath to be set.

sharepath

The full path to the share (eg, "c:\windows"). This is required when creating a service.

time

The minimum amount of time, in seconds, to wait for the external module to finish (default: 15)

smbdomain

The domain to log in with. If you aren't in a domain environment, then anything will (should?) be accepted by the server.

smbhash

A password hash to use when logging in. This is given as a single hex string (32 characters) or a pair of hex strings (both 32 characters, optionally separated by a single character). These hashes are the LanMan or NTLM hash of the user's password, and are stored on disk or in memory. They can be retrieved from memory using the fgdump or pwdump tools.

smbnoguest

Use to disable usage of the 'guest' account.

smbpassword

The password to connect with. Be cautious with this, since some servers will lock accounts if the incorrect password is given. Although it's rare that the Administrator account can be locked out, in the off chance that it can, you could get yourself in trouble. To use a blank password, leave this parameter off altogether.

smbtype

The type of SMB authentication to use. These are the possible options:

  • v1: Sends LMv1 and NTLMv1.
  • LMv1: Sends LMv1 only.
  • NTLMv1: Sends NTLMv1 only (default).
  • v2: Sends LMv2 and NTLMv2.
  • LMv2: Sends LMv2 only.
  • NTLMv2: Doesn't exist; the protocol doesn't support NTLMv2 alone. The default, NTLMv1, is a pretty decent compromise between security and compatibility. If you are paranoid, you might want to use v2 or lmv2 for this. (Actually, if you're paranoid, you should be avoiding this protocol altogether!). If you're using an extremely old system, you might need to set this to v1 or lm, which are less secure but more compatible. For information, see smbauth.lua.

smbusername

The SMB username to log in with. The forms "DOMAIN\username" and "username@DOMAIN" are not understood. To set a domain, use the smbdomain argument.

randomseed

Set to a value to change the filenames/service names that are randomly generated.

smbbasic

Forces the authentication to use basic security, as opposed to "extended security". Against most modern systems, extended security should work, but there may be cases where you want to force basic. There's a chance that you'll get better results for enumerating users if you turn on basic authentication.

smbport

Override the default port choice. If smbport is open, it's used. It's assumed to be the same protocol as port 445, not port 139. Since it probably isn't possible to change Windows' ports normally, this is mostly useful if you're bouncing through a relay or something.

smbsign

Controls whether or not server signatures are checked in SMB packets. By default, on Windows, server signatures aren't enabled or required. By default, this library will always sign packets if it knows how, and will check signatures if the server says to. Possible values are:

  • force: Always check server signatures, even if server says it doesn't support them (will Probably fail, but is technically more secure).
  • negotiate: [default] Use signatures if server supports them.
  • ignore: Never check server signatures. Not recommended.
  • disable: Don't send signatures, at all, and don't check the server's. not recommended. More information on signatures can be found in smbauth.lua.

- - -
To use these script arguments, add them to the Nmap command line using the --script-args arg1=value,[arg2=value,..] syntax. For example:

nmap --script=smb-psexec --script-args cleanup=value,config=value <target>

Smb-psexec NSE Script Example Usage


Here's an example of how to use the smb-psexec.nse script:

nmap --script smb-psexec.nse --script-args=smbuser=<username>,smbpass=<password>[,config=<config>] -p445 <host>

sudo nmap -sU -sS --script smb-psexec.nse --script-args=smbuser=<username>,smbpass=<password>[,config=<config>] -p U:137,T:139 <host>

Smb-psexec NSE Script Example Output


Here's a sample output from the smb-psexec.nse script:

Host script results:
|  smb-psexec:
|  |  Windows version
|  |  |_ Microsoft Windows 2000 [Version 5.00.2195]
|  |  IP Address and MAC Address from 'ipconfig.exe'
|  |  |  Ethernet adapter Local Area Connection 2:
|  |  |         MAC Address: 00:50:56:A1:24:C2
|  |  |         IP Address: 10.0.0.30
|  |  |  Ethernet adapter Local Area Connection:
|  |  |_        MAC Address: 00:50:56:A1:00:65
|  |  User list from 'net user'
|  |  |  Administrator            TestUser3                Guest
|  |  |  IUSR_RON-WIN2K-TEST      IWAM_RON-WIN2K-TEST      nmap
|  |  |  rontest123               sshd                     SvcCOPSSH
|  |  |_ test1234                 Testing                  TsInternetUser
|  |  Membership of 'administrators' from 'net localgroup administrators'
|  |  |  Administrator
|  |  |  SvcCOPSSH
|  |  |  test1234
|  |  |_ Testing
|  |  Can the host ping our address?
|  |  |  Pinging 10.0.0.138 with 32 bytes of data:
|  |  |_ Reply from 10.0.0.138: bytes=32 time<10ms TTL=64
|  |  Traceroute back to the scanner
|  |  |_   1   <10 ms   <10 ms   <10 ms  10.0.0.138
|  |  ARP Cache from arp.exe
|  |  |    Internet Address      Physical Address      Type
|  |  |_   10.0.0.138            00-50-56-a1-27-4b     dynamic
|  |  List of listening and established connections (netstat -an)
|  |  |    Proto  Local Address          Foreign Address        State
|  |  |    TCP    0.0.0.0:22             0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:25             0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:80             0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:135            0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:443            0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:445            0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:1025           0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:1028           0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:1029           0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING
|  |  |    TCP    0.0.0.0:4933           0.0.0.0:0              LISTENING
|  |  |    TCP    10.0.0.30:139          0.0.0.0:0              LISTENING
|  |  |    TCP    127.0.0.1:2528         127.0.0.1:2529         ESTABLISHED
|  |  |    TCP    127.0.0.1:2529         127.0.0.1:2528         ESTABLISHED
|  |  |    TCP    127.0.0.1:2531         127.0.0.1:2532         ESTABLISHED
|  |  |    TCP    127.0.0.1:2532         127.0.0.1:2531         ESTABLISHED
|  |  |    TCP    127.0.0.1:5152         0.0.0.0:0              LISTENING
|  |  |    TCP    127.0.0.1:5152         127.0.0.1:2530         CLOSE_WAIT
|  |  |    UDP    0.0.0.0:135            *:*
|  |  |    UDP    0.0.0.0:445            *:*
|  |  |    UDP    0.0.0.0:1030           *:*
|  |  |    UDP    0.0.0.0:3456           *:*
|  |  |    UDP    10.0.0.30:137          *:*
|  |  |    UDP    10.0.0.30:138          *:*
|  |  |    UDP    10.0.0.30:500          *:*
|  |  |    UDP    10.0.0.30:4500         *:*
|  |  |_   UDP    127.0.0.1:1026         *:*
|  |  Full routing table from 'netstat -nr'
|  |  |  ===========================================================================
|  |  |  Interface List
|  |  |  0x1 ........................... MS TCP Loopback interface
|  |  |  0x2 ...00 50 56 a1 00 65 ...... VMware Accelerated AMD PCNet Adapter
|  |  |  0x1000004 ...00 50 56 a1 24 c2 ...... VMware Accelerated AMD PCNet Adapter
|  |  |  ===========================================================================
|  |  |  ===========================================================================
|  |  |  Active Routes:
|  |  |  Network Destination        Netmask          Gateway       Interface  Metric
|  |  |           10.0.0.0    255.255.255.0        10.0.0.30       10.0.0.30      1
|  |  |          10.0.0.30  255.255.255.255        127.0.0.1       127.0.0.1      1
|  |  |     10.255.255.255  255.255.255.255        10.0.0.30       10.0.0.30      1
|  |  |          127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1      1
|  |  |          224.0.0.0        224.0.0.0        10.0.0.30       10.0.0.30      1
|  |  |    255.255.255.255  255.255.255.255        10.0.0.30               2      1
|  |  |  ===========================================================================
|  |  |  Persistent Routes:
|  |  |    None
|_ |_ |_ Route Table

Smb-psexec NSE Script Example XML Output


There is no sample XML output for this module. However, by providing the -oX <file> option, Nmap will produce a XML output and save it in the file.xml file.

Author


  • Ron Bowes

References


See Also


Related NSE scripts to the smb-psexec.nse script:

Visit Nmap NSE Library for more scripts.

The smb-psexec.nse script may fail with the following error messages. Check for the possible causes by using the code snippets highlighted below found in the script source code. This can often times help in identifying the root cause of the problem.

Error generating service name: %s


Here is a relevant code snippet related to the "Error generating service name: %s" error message:

553:	  local status, service_name, service_file, temp_output_file, output_file
554:	
555:	  -- Get the name of the service
556:	  status, service_name = smb.get_uniqueish_name(host)
557:	  if(status == false) then
558:	    return false, string.format("Error generating service name: %s", service_name)
559:	  end
560:	  stdnse.debug1("Generated static service name: %s", service_name)
561:	
562:	  -- Get the name and service's executable file (with a .txt extension for fun)
563:	  status, service_file = smb.get_uniqueish_name(host, "txt")

Error generating remote filename: %s


Here is a relevant code snippet related to the "Error generating remote filename: %s" error message:

560:	  stdnse.debug1("Generated static service name: %s", service_name)
561:	
562:	  -- Get the name and service's executable file (with a .txt extension for fun)
563:	  status, service_file = smb.get_uniqueish_name(host, "txt")
564:	  if(status == false) then
565:	    return false, string.format("Error generating remote filename: %s", service_file)
566:	  end
567:	  stdnse.debug1("Generated static service name: %s", service_name)
568:	
569:	  -- Get the temporary output file
570:	  status, temp_output_file = smb.get_uniqueish_name(host, "out.tmp")

Error generating remote filename: %s


Here is a relevant code snippet related to the "Error generating remote filename: %s" error message:

567:	  stdnse.debug1("Generated static service name: %s", service_name)
568:	
569:	  -- Get the temporary output file
570:	  status, temp_output_file = smb.get_uniqueish_name(host, "out.tmp")
571:	  if(status == false) then
572:	    return false, string.format("Error generating remote filename: %s", temp_output_file)
573:	  end
574:	  stdnse.debug1("Generated static service filename: %s", temp_output_file)
575:	
576:	  -- Get the actual output file
577:	  status, output_file = smb.get_uniqueish_name(host, "out")

Error generating remote output file: %s


Here is a relevant code snippet related to the "Error generating remote output file: %s" error message:

574:	  stdnse.debug1("Generated static service filename: %s", temp_output_file)
575:	
576:	  -- Get the actual output file
577:	  status, output_file = smb.get_uniqueish_name(host, "out")
578:	  if(status == false) then
579:	    return false, string.format("Error generating remote output file: %s", output_file)
580:	  end
581:	  stdnse.debug1("Generated static output filename: %s", output_file)
582:	
583:	  -- Return everything
584:	  return true, service_name, service_file, temp_output_file, output_file

Entering cleanup() -- errors here can generally be ignored


Here is a relevant code snippet related to the "Entering cleanup() -- errors here can generally be ignored" error message:

598:	  -- If the user doesn't want to clean up, don't
599:	  if(stdnse.get_script_args( "nocleanup" )) then
600:	    return
601:	  end
602:	
603:	  stdnse.debug1("Entering cleanup() -- errors here can generally be ignored")
604:	  -- Try stopping the service
605:	  status, err = msrpc.service_stop(host, config.service_name)
606:	  if(status == false) then
607:	    stdnse.debug1("[cleanup] Couldn't stop service: %s", err)
608:	  end

Error opening %s: %s


Here is a relevant code snippet related to the "Error opening %s: %s" error message:

643:	
644:	  -- check for absolute path or relative to current directory
645:	  if(filename_full == nil) then
646:	    local f, err = io.open(filename, "rb")
647:	    if f == nil then
648:	      stdnse.debug1("Error opening %s: %s", filename, err)
649:	      f, err = io.open(filename .. "." .. extension, "rb")
650:	      if f == nil then
651:	        stdnse.debug1("Error opening %s.%s: %s", filename, extension, err)
652:	        return nil -- unnecessary, but explicit
653:	      else

Error opening %s.%s: %s


Here is a relevant code snippet related to the "Error opening %s.%s: %s" error message:

646:	    local f, err = io.open(filename, "rb")
647:	    if f == nil then
648:	      stdnse.debug1("Error opening %s: %s", filename, err)
649:	      f, err = io.open(filename .. "." .. extension, "rb")
650:	      if f == nil then
651:	        stdnse.debug1("Error opening %s.%s: %s", filename, extension, err)
652:	        return nil -- unnecessary, but explicit
653:	      else
654:	        f:close()
655:	        return filename .. "." .. extension
656:	      end

Setting the 'share' script-arg requires the 'sharepath' to be set as well.


Here is a relevant code snippet related to the "Setting the 'share' script-arg requires the 'sharepath' to be set as well." error message:

713:	  if(nmap.registry.args.share ~= nil) then
714:	    share = nmap.registry.args.share
715:	    shares = {share}
716:	    path = nmap.registry.args.sharepath
717:	    if(path == nil) then
718:	      return false, "Setting the 'share' script-arg requires the 'sharepath' to be set as well."
719:	    end
720:	
721:	    stdnse.debug1("Using share chosen by the user: %s (%s)", share, path)
722:	  else
723:	    -- Try and find a share to use.

(May not have an administrator account)


Here is a relevant code snippet related to the " (May not have an administrator account)" error message:

721:	    stdnse.debug1("Using share chosen by the user: %s (%s)", share, path)
722:	  else
723:	    -- Try and find a share to use.
724:	    status, share, path, shares = smb.share_find_writable(host)
725:	    if(status == false) then
726:	      return false, share .. " (May not have an administrator account)"
727:	    end
728:	    if(path == nil) then
729:	      return false, string.format("Couldn't find path to writable share (we probably don't have admin access): '%s'", share)
730:	    end
731:	    stdnse.debug1("Found usable share %s (%s) (all writable shares: %s)", share, path, table.concat(shares, ", "))

Couldn't find path to writable share (we probably don't have admin access): '%s'


Here is a relevant code snippet related to the "Couldn't find path to writable share (we probably don't have admin access): '%s'" error message:

724:	    status, share, path, shares = smb.share_find_writable(host)
725:	    if(status == false) then
726:	      return false, share .. " (May not have an administrator account)"
727:	    end
728:	    if(path == nil) then
729:	      return false, string.format("Couldn't find path to writable share (we probably don't have admin access): '%s'", share)
730:	    end
731:	    stdnse.debug1("Found usable share %s (%s) (all writable shares: %s)", share, path, table.concat(shares, ", "))
732:	  end
733:	
734:	  return true, share, path, shares

Couldn't locate config file: file not found (make sure it has a .lua extension and is in nselib/data/psexec/)


Here is a relevant code snippet related to the "Couldn't locate config file: file not found (make sure it has a .lua extension and is in nselib/data/psexec/)" error message:

795:	  config.disabled_modules = {}
796:	
797:	  -- Find the config file
798:	  filename = locate_file(filename or 'default', 'lua')
799:	  if(filename == nil) then
800:	    return false, "Couldn't locate config file: file not found (make sure it has a .lua extension and is in nselib/data/psexec/)"
801:	  end
802:	
803:	  -- Load the config file
804:	  local env = setmetatable({modules = {}; overrides = {}; module = function() stdnse.debug1("WARNING: Selected config file contains an unnecessary call to module()") end}, {__index = _G})
805:	  stdnse.debug1("Attempting to load config file: %s", filename)

WARNING: Selected config file contains an unnecessary call to module()


Here is a relevant code snippet related to the "WARNING: Selected config file contains an unnecessary call to module()" error message:

799:	  if(filename == nil) then
800:	    return false, "Couldn't locate config file: file not found (make sure it has a .lua extension and is in nselib/data/psexec/)"
801:	  end
802:	
803:	  -- Load the config file
804:	  local env = setmetatable({modules = {}; overrides = {}; module = function() stdnse.debug1("WARNING: Selected config file contains an unnecessary call to module()") end}, {__index = _G})
805:	  stdnse.debug1("Attempting to load config file: %s", filename)
806:	  local file = loadfile(filename, "t", env)
807:	  if(not(file)) then
808:	    return false, "Couldn't load module file:\n" .. filename
809:	  end

Couldn't load module file:n


Here is a relevant code snippet related to the "Couldn't load module file:n" error message:

803:	  -- Load the config file
804:	  local env = setmetatable({modules = {}; overrides = {}; module = function() stdnse.debug1("WARNING: Selected config file contains an unnecessary call to module()") end}, {__index = _G})
805:	  stdnse.debug1("Attempting to load config file: %s", filename)
806:	  local file = loadfile(filename, "t", env)
807:	  if(not(file)) then
808:	    return false, "Couldn't load module file:\n" .. filename
809:	  end
810:	
811:	  -- Run the config file
812:	  file()
813:	  local modules = env.modules

Couldn't get socket information:


Here is a relevant code snippet related to the "Couldn't get socket information: " error message:

838:	  end
839:	
840:	  -- Get information about the socket; it's a bit out of place here, but it should go before the mod loop
841:	  status, config.lhost, config.lport, config.rhost, config.rport, config.lmac = smb.get_socket_info(host)
842:	  if(status == false) then
843:	    return false, "Couldn't get socket information: " .. config.lhost
844:	  end
845:	
846:	  -- Get the names of the files we're going to need
847:	  status, config.service_name, config.service_file, config.temp_output_file, config.output_file = get_service_files(host)
848:	  if(not(status)) then

Configuration file (%s) doesn't have a proper 'modules' table.


Here is a relevant code snippet related to the "Configuration file (%s) doesn't have a proper 'modules' table." error message:

851:	
852:	  -- Make sure the modules loaded properly
853:	  -- NOTE: If you're here because of an error that 'modules' is undefined, it's likely because your configuration file doesn't have a
854:	  -- proper modules table, or your configuration file has a module() declaration at the top.
855:	  if(not(modules) or #modules == 0) then
856:	    return false, string.format("Configuration file (%s) doesn't have a proper 'modules' table.", filename)
857:	  end
858:	
859:	  -- Make sure we got a proper modules array
860:	  if(type(modules) ~= "table") then
861:	    return false, string.format("The chosen configuration file, %s.lua, \z

Configuration error: '%s': module doesn't have a program


Here is a relevant code snippet related to the "Configuration error: '%s': module doesn't have a program" error message:

870:	    local enabled = true
871:	    -- Do some sanity checking
872:	    if(mod.program == nil) then
873:	      enabled = false
874:	      if(mod.name) then
875:	        mod.disabled_message = string.format("Configuration error: '%s': module doesn't have a program", mod.name)
876:	      else
877:	        mod.disabled_message = string.format("Configuration error: Module #%d doesn't have a program", i)
878:	      end
879:	    end
880:	

Configuration error: Module #%d doesn't have a program


Here is a relevant code snippet related to the "Configuration error: Module #%d doesn't have a program" error message:

872:	    if(mod.program == nil) then
873:	      enabled = false
874:	      if(mod.name) then
875:	        mod.disabled_message = string.format("Configuration error: '%s': module doesn't have a program", mod.name)
876:	      else
877:	        mod.disabled_message = string.format("Configuration error: Module #%d doesn't have a program", i)
878:	      end
879:	    end
880:	
881:	    -- Set some defaults, if the user didn't specify
882:	    mod.name    = mod.name or (string.format("%s %s", mod.program, mod.args or ""))

Configuration error: '%s': 'upload' field is required


Here is a relevant code snippet related to the "Configuration error: '%s': 'upload' field is required" error message:

883:	    mod.maxtime = mod.maxtime or 1
884:	
885:	    -- Check if they forgot the uploadibility
886:	    if(mod.upload == nil) then
887:	      enabled = false
888:	      mod.disabled_message = string.format("Configuration error: '%s': 'upload' field is required", mod.name)
889:	    end
890:	
891:	    -- Check if the upload field is set wrong
892:	    if(mod.upload ~= true and mod.upload ~= false) then
893:	      enabled = false

Configuration error: '%s': 'upload' field has to be true or false


Here is a relevant code snippet related to the "Configuration error: '%s': 'upload' field has to be true or false" error message:

889:	    end
890:	
891:	    -- Check if the upload field is set wrong
892:	    if(mod.upload ~= true and mod.upload ~= false) then
893:	      enabled = false
894:	      mod.disabled_message = string.format("Configuration error: '%s': 'upload' field has to be true or false", mod.name)
895:	    end
896:	
897:	    -- Check for incompatible fields with 'headless'
898:	    if(mod.headless) then
899:	      if(mod.find or mod.remove or mod.noblank or mod.replace or (mod.maxtime > 1) or mod.outfile) then

Configuration error: '%s': 'headless' is incompatible with find, remove, noblank, replace, and maxtime


Here is a relevant code snippet related to the "Configuration error: '%s': 'headless' is incompatible with find, remove, noblank, replace, and maxtime" error message:

896:	
897:	    -- Check for incompatible fields with 'headless'
898:	    if(mod.headless) then
899:	      if(mod.find or mod.remove or mod.noblank or mod.replace or (mod.maxtime > 1) or mod.outfile) then
900:	        enabled = false
901:	        mod.disabled_message = string.format("Configuration error: '%s': 'headless' is incompatible with find, remove, noblank, replace, and maxtime", mod.name)
902:	      end
903:	    end
904:	
905:	    -- Check for improperly formatted 'replace'
906:	    if(mod.replace) then

Configuration error: '%s': 'replace' has to be a table of one-element tables (eg. replace = {{'a'='b'}, {'c'='d'}})


Here is a relevant code snippet related to the "Configuration error: '%s': 'replace' has to be a table of one-element tables (eg. replace = {{'a'='b'}, {'c'='d'}})" error message:

904:	
905:	    -- Check for improperly formatted 'replace'
906:	    if(mod.replace) then
907:	      if(type(mod.replace) ~= "table") then
908:	        enabled = false
909:	        mod.disabled_message = string.format("Configuration error: '%s': 'replace' has to be a table of one-element tables (eg. replace = {{'a'='b'}, {'c'='d'}})", mod.name)
910:	      end
911:	
912:	      for _, v in ipairs(mod.replace) do
913:	        if(type(v) ~= 'table') then
914:	          enabled = false

Configuration error: '%s': 'replace' has to be a table of one-element tables (eg. replace = {{'a'='b'}, {'c'='d'}})


Here is a relevant code snippet related to the "Configuration error: '%s': 'replace' has to be a table of one-element tables (eg. replace = {{'a'='b'}, {'c'='d'}})" error message:

910:	      end
911:	
912:	      for _, v in ipairs(mod.replace) do
913:	        if(type(v) ~= 'table') then
914:	          enabled = false
915:	          mod.disabled_message = string.format("Configuration error: '%s': 'replace' has to be a table of one-element tables (eg. replace = {{'a'='b'}, {'c'='d'}})", mod.name)
916:	        end
917:	      end
918:	    end
919:	
920:	    -- Set some default values

Configuration error: Required argument(s) ('%s') weren't given.


Here is a relevant code snippet related to the "Configuration error: Required argument(s) ('%s') weren't given." error message:

940:	      end
941:	
942:	      if(#missing_args > 0) then
943:	        enabled = false
944:	        mod.disabled_message = {}
945:	        table.insert(mod.disabled_message, string.format("Configuration error: Required argument(s) ('%s') weren't given.", table.concat('", missing_args, "')))
946:	        table.insert(mod.disabled_message, "Please add --script-args=[arg]=[value] to your commandline to run this module")
947:	        if(#missing_args == 1) then
948:	          table.insert(mod.disabled_message, string.format("For example: --script-args=%s=123", missing_args[1]))
949:	        else
950:	          table.insert(mod.disabled_message, string.format("For example: --script-args=%s=123,%s=456...", missing_args[1], missing_args[2]))

Couldn't generate name for uploaded file:


Here is a relevant code snippet related to the "Couldn't generate name for uploaded file: " error message:

971:	        stdnse.debug1("Found: %s", mod.filename)
972:	
973:	        -- Generate a name to upload them as (we don't upload with the original names)
974:	        status, mod.upload_name = smb.get_uniqueish_name(host, "txt", mod.filename)
975:	        if(not(status)) then
976:	          return false, "Couldn't generate name for uploaded file: " .. mod.upload_name
977:	        end
978:	        stdnse.debug1("Will upload %s as %s", mod.filename, mod.upload_name)
979:	      end
980:	    end
981:	

Couldn't find required file to upload: %s


Here is a relevant code snippet related to the "Couldn't find required file to upload: %s" error message:

991:	      mod.extrafiles_paths = {}
992:	      for i, extrafile in ipairs(mod.extrafiles) do
993:	        stdnse.debug1("Looking for extra module: %s", extrafile)
994:	        mod.extrafiles_paths[i] = locate_file(extrafile)
995:	        if(mod.extrafiles_paths[i] == nil) then
996:	          return false, string.format("Couldn't find required file to upload: %s", extrafile)
997:	        end
998:	        stdnse.debug1("Found: %s", mod.extrafiles_paths[i])
999:	      end
1000:	    end
1001:	

Couldn't upload the service file: %sn


Here is a relevant code snippet related to the "Couldn't upload the service file: %sn" error message:

1127:	  stdnse.debug1("Uploading: %s => \\\\%s\\%s", config.local_service_file, config.share, config.service_file)
1128:	  local status, err
1129:	  status, err = smb.file_upload(host, config.local_service_file, config.share, "\" .. config.service_file, overrides, is_xor_encoded)
1130:	  if(status == false) then
1131:	    cleanup(host, config)
1132:	    return false, string.format("Couldn't upload the service file: %s\n", err)
1133:	  end
1134:	  stdnse.debug1("Service file successfully uploaded!")
1135:	
1136:	  -- Upload the modules and all their extras
1137:	  stdnse.debug1("Attempting to upload the modules")

Couldn't upload module %s: %sn


Here is a relevant code snippet related to the "Couldn't upload module %s: %sn" error message:

1140:	    if(mod.upload) then
1141:	      stdnse.debug1("Uploading: %s => \\\\%s\\%s", mod.filename, config.share, mod.upload_name)
1142:	      status, err = smb.file_upload(host, mod.filename, config.share, "\" .. mod.upload_name, overrides)
1143:	      if(status == false) then
1144:	        cleanup(host, config)
1145:	        return false, string.format("Couldn't upload module %s: %s\n", mod.program, err)
1146:	      end
1147:	    end
1148:	
1149:	    -- If it requires extra files, upload them, too
1150:	    if(mod.extrafiles) then

Couldn't upload extra file %s: %sn


Here is a relevant code snippet related to the "Couldn't upload extra file %s: %sn" error message:

1159:	
1160:	        stdnse.debug1("Uploading extra file: %s => \\\\%s\\%s", extrafile_local, config.share, extrafile)
1161:	        status, err = smb.file_upload(host, extrafile_local, config.share, extrafile, overrides)
1162:	        if(status == false) then
1163:	          cleanup(host, config)
1164:	          return false, string.format("Couldn't upload extra file %s: %s\n", extrafile_local, err)
1165:	        end
1166:	      end
1167:	    end
1168:	  end
1169:	  stdnse.debug1("Modules successfully uploaded!")

Service is stuck in 'being deleted' phase on remote machine; try setting script-args=randomseed=abc for now


Here is a relevant code snippet related to the "Service is stuck in 'being deleted' phase on remote machine; try setting script-args=randomseed=abc for now" error message:

1181:	  if(status == false) then
1182:	    stdnse.debug1("Couldn't create the service: %s", err)
1183:	    cleanup(host, config)
1184:	
1185:	    if(string.find(err, "MARKED_FOR_DELETE")) then
1186:	      return false, "Service is stuck in 'being deleted' phase on remote machine; try setting script-args=randomseed=abc for now"
1187:	    else
1188:	      return false, string.format("Couldn't create the service on the remote machine: %s", err)
1189:	    end
1190:	  end
1191:	

Couldn't create the service on the remote machine: %s


Here is a relevant code snippet related to the "Couldn't create the service on the remote machine: %s" error message:

1183:	    cleanup(host, config)
1184:	
1185:	    if(string.find(err, "MARKED_FOR_DELETE")) then
1186:	      return false, "Service is stuck in 'being deleted' phase on remote machine; try setting script-args=randomseed=abc for now"
1187:	    else
1188:	      return false, string.format("Couldn't create the service on the remote machine: %s", err)
1189:	    end
1190:	  end
1191:	
1192:	  return true
1193:	end

Couldn't start the service on the remote machine: %s


Here is a relevant code snippet related to the "Couldn't start the service on the remote machine: %s" error message:

1235:	--@return err    An error message if status is false.
1236:	local function start_service(host, config, params)
1237:	  local status, err = msrpc.service_start(host, config.service_name, params)
1238:	  if(status == false) then
1239:	    stdnse.debug1("Couldn't start the service: %s", err)
1240:	    return false, string.format("Couldn't start the service on the remote machine: %s", err)
1241:	  end
1242:	
1243:	  return true
1244:	end
1245:	

Couldn't read the file from the remote machine: %s


Here is a relevant code snippet related to the "Couldn't read the file from the remote machine: %s" error message:

1262:	    if(not(status) and result ~= "NT_STATUS_OBJECT_NAME_NOT_FOUND") then
1263:	      -- An unexpected error occurred
1264:	      stdnse.debug1("Couldn't read the file: %s", result)
1265:	      cleanup(host, config)
1266:	
1267:	      return false, string.format("Couldn't read the file from the remote machine: %s", result)
1268:	    end
1269:	
1270:	    if(not(status) and result == "NT_STATUS_OBJECT_NAME_NOT_FOUND") then
1271:	      -- An expected error occurred; if this happens, we just wait
1272:	      if(i == 0) then

Error in remote service: output file was never created!


Here is a relevant code snippet related to the "Error in remote service: output file was never created!" error message:

1268:	    end
1269:	
1270:	    if(not(status) and result == "NT_STATUS_OBJECT_NAME_NOT_FOUND") then
1271:	      -- An expected error occurred; if this happens, we just wait
1272:	      if(i == 0) then
1273:	        stdnse.debug1("Error in remote service: output file was never created!")
1274:	        cleanup(host, config)
1275:	
1276:	        return false, "Error in remote service: output file was never created"
1277:	      end
1278:	

Error in remote service: output file was never created


Here is a relevant code snippet related to the "Error in remote service: output file was never created" error message:

1271:	      -- An expected error occurred; if this happens, we just wait
1272:	      if(i == 0) then
1273:	        stdnse.debug1("Error in remote service: output file was never created!")
1274:	        cleanup(host, config)
1275:	
1276:	        return false, "Error in remote service: output file was never created"
1277:	      end
1278:	
1279:	      stdnse.debug1("Output file %s doesn't exist yet, waiting for %d more seconds", config.output_file, i)
1280:	      stdnse.sleep(1)
1281:	      i = i - 1

Server's response wasn't formatted properly; if you can reproduce, place report to [email protected]


Here is a relevant code snippet related to the "Server's response wasn't formatted properly; if you can reproduce, place report to [email protected]" error message:

1388:	        -- Go to the next module, and make sure it exists
1389:	        mod = config.enabled_modules[module_num + 1]
1390:	        if(mod == nil) then
1391:	          stdnse.debug1("Server's response wasn't formatted properly (mod %d); if you can reproduce, place report to [email protected]", module_num)
1392:	          stdnse.debug1("--\n" .. string.gsub("%%", "%%", data) .. "\n--")
1393:	          return false, "Server's response wasn't formatted properly; if you can reproduce, place report to [email protected]"
1394:	        end
1395:	
1396:	        -- Save this result
1397:	        if(result ~= nil) then
1398:	          table.insert(results, result)

Couldn't log in to check for remote files:


Here is a relevant code snippet related to the "Couldn't log in to check for remote files: " error message:

1487:	    end
1488:	
1489:	    -- Check if any of the files exist
1490:	    status, result, files = smb.files_exist(host, config.share, config.all_files, {})
1491:	    if(not(status)) then
1492:	      return stdnse.format_output(false, "Couldn't log in to check for remote files: " .. result)
1493:	    end
1494:	    if(result > 0) then
1495:	      local response = {}
1496:	      table.insert(response, "One or more output files already exist on the host, and couldn't be removed. Try:")
1497:	      table.insert(response, "* Running the script with --script-args=cleanup=1 to force a cleanup (passing -d and looking for error messages might help),")

* Running the script with --script-args=cleanup=1 to force a cleanup (passing -d and looking for error messages might help),


Here is a relevant code snippet related to the "* Running the script with --script-args=cleanup=1 to force a cleanup (passing -d and looking for error messages might help)," error message:

1492:	      return stdnse.format_output(false, "Couldn't log in to check for remote files: " .. result)
1493:	    end
1494:	    if(result > 0) then
1495:	      local response = {}
1496:	      table.insert(response, "One or more output files already exist on the host, and couldn't be removed. Try:")
1497:	      table.insert(response, "* Running the script with --script-args=cleanup=1 to force a cleanup (passing -d and looking for error messages might help),")
1498:	      table.insert(response, "* Running the script with --script-args=randomseed=ABCD (or something) to change the name of the uploaded files,")
1499:	      table.insert(response, "* Changing the share and path using, for example, --script-args=share=C$,sharepath=C:, or")
1500:	      table.insert(response, "* Deleting the affected file(s) off the server manually (\\\" .. config.share .. "\" .. table.concat(files, ", \\\" .. config.share .. "\") .. ")")
1501:	      return stdnse.format_output(false, response)
1502:	    end

Couldn't parse output:


Here is a relevant code snippet related to the "Couldn't parse output: " error message:

1545:	
1546:	  -- Build the output into a nice table
1547:	  local response
1548:	  status, response = parse_output(config, result)
1549:	  if(status == false) then
1550:	    return stdnse.format_output(false, "Couldn't parse output: " .. response)
1551:	  end
1552:	
1553:	  -- Add a warning if nothing was enabled
1554:	  if(#config.enabled_modules == 0) then
1555:	    if(#response == 0) then

No modules were enabled! Please fix any errors displayed above, or check your configuration file.


Here is a relevant code snippet related to the "No modules were enabled! Please fix any errors displayed above, or check your configuration file." error message:

1553:	  -- Add a warning if nothing was enabled
1554:	  if(#config.enabled_modules == 0) then
1555:	    if(#response == 0) then
1556:	      response = {"No modules were enabled! Please check your configuration file."}
1557:	    else
1558:	      table.insert(response, "No modules were enabled! Please fix any errors displayed above, or check your configuration file.")
1559:	    end
1560:	  end
1561:	
1562:	  -- Return the string
1563:	  return stdnse.format_output(true, response)

Version


This page has been created based on Nmap version 7.92.

Go back to menu.