WebJob - Download and execute a program over HTTP/HTTPS
webjob {-e|--execute} {-f|--file} config program [options]
webjob {-h|--hashsum} {-t|--type} digest file
webjob {-v|--version}
Note: Command line arguments are position dependent, and argument snuggling (e.g., '-ef' or '-ht') is not supported. All arguments and their values (if any) must be separated by whitespace. However, any options associated with the specified program are not bound by these restrictions. Instead, they are bound to the argument syntax for the specified program.
WebJob downloads and executes a program in one unified operation. WebJob's runtime behavior is controlled through a config file identified by the --file argument. Among other things, this file identifies a Web resource willing to satisfy WebJob GET requests. Once initialized, WebJob downloads the target program, stores it in on the local file system, and executes it in a sub-process. The options, if any, are bound to the target program at invocation. By default, any output generated by the target program is directed to stdout/stderr. However, output may also be directed to a Web resource through a WebJob PUT request. When compiled with OpenSSL, WebJob supports HTTPS requests and certificate authentication.
WebJob's GET/PUT requests may be bound to any available outbound port. This increases the likelihood that distant Web resources can be reached in spite of firewalls and filtering routers.
WebJob is roughly split into three stages: GET, RUN, and PUT. Each stage provides an independent timer. In the event that a given stage doesn't complete within the alloted time, WebJob will attempt to abort gracefully. A timeout value of zero means there is no time limit.
WebJob also has the ability to compute a message digest of a specified file or stdin. This is useful in situations where the downloaded executable needs to compute a hash, but the target platform lacks the necessary hashing tools.
The modes of operation described in this section are mutually exclusive. In other words, only one mode may be specified per invocation.
Use config file settings to download and execute the specified program. The config file, as specified by the --file argument, may be the name of a regular file or '-' which indicates that configuration information is to be read from stdin. Note: Path information in the program argument is not allowed. The options, if any, are bound to the target program at invocation. The various config file controls and syntax rules are described in the CONFIGURATION CONTROLS section of this document.
Use digest algorithm, as specified by the --type argument, to compute a hash of file. If file is specified as '-', then input will be read from stdin. Currently, the following algorithms are supported: MD5, SHA1, and SHA256. The value for this option is not case sensitive.
Display version information and exit.
This section describes the various controls that WebJob recognizes. In general, controls either shape runtime behavior or provide information needed by the application to perform a specific function. Controls and their values, one pair/line, are written to a file having the following format.
<control> = <value>
All controls are case insensitive, but, in general, their values are not. Comments may occur anywhere on a given line, and must begin with a pound character (i.e. '#'). In any given line, all text to the right of the first comment will be ignored. White space surrounding controls and values is ignored.
This section describes each control that may be specified, defines what values it may have, and states which modes of operation recognize the control.
Applies to execute.
ClientId is required. It defines the identity of the client for which the GET/PUT requests are being made. Typically, the ClientId and URLUsername are the same when basic authentication is enabled. However, this is not a requirement.
Applies to execute.
DsvCertificateTree is optional. This control specifies a directory that contains one or more PEM-encoded certificates whose public keys may be used to verify the payload's signature -- invalid and non-PEM-encoded files are silently ignored. Each certificate in the certificate tree is used, in turn, to verify the payload's integrity. The verification process does not stop until a match is found or all certificates have been tried. Note that WebJob will not search for certificates in sub-directories of the specified tree. This control is ignored if DsvVerifySignature is disabled.
For more information on signing and verifying payloads refer to the
WebJob-DsvTool man page (i.e., webjob-dsvtool(1)
). That document also provides examples of how to create the necessary
PEM-encoded keys and certificates.
Note: If DsvCertificateTree does not exist or does not contain at least one valid certificate, the program will abort.
Note: Digital Signature Verification (DSV) support is a compile-time option, which is enabled by default. However, if DSV support is not compiled into the binary, WebJob will abort with an error if you try to use this (or any) DSV control in the config file. To determine if DSV support is compiled into the binary, run the following command:
webjob --version
Applies to execute.
DsvVerifySignature is optional. When enabled ('Y' or 'y'), it instructs the application to verify the signature of the requested payload. Signatures are verified against one or more certificates located in DsvCertificateTree. The default value is 'N'.
If this control is enabled and the payload's signature is missing or invalid, WebJob will abort, and the downloaded payload will not be executed. This helps to protect the client in the case where the WebJob server can no longer be trusted (e.g., because it has been compromised).
Note: Certificate chains and expiration dates are not checked in the verification process. It is the responsibility of the WebJob administrator to periodically manage (i.e., add, remove, update) any certificates installed on the clients.
Note: Digital Signature Verification (DSV) support is a compile-time option, which is enabled by default. However, if DSV support is not compiled into the binary, WebJob will abort with an error if you try to use this (or any) DSV control in the config file. To determine if DSV support is compiled into the binary, run the following command:
webjob --version
Applies to execute.
GetHookCommandLine is required when GetHookEnable is enabled. The value of this control is a command or pipeline that will be executed by the system's command interpreter once the requested file has been downloaded. If GetHookSuffix is defined, a variant of the target program is requested. This variant must be transformed by the specified command to produce the target program. If the command is successful, as defined by GetHookStatus, then the target program will be executed as usual. Otherwise, the target program will not be executed. The tokens '%tp', '%vp', '%pid', and '%s' may be used as place holders in the specified command line. When the hook is activated, these tokens are expanded as the target program, variant program, current Process ID, and suffix, respectively. The character '%' may be used to produce a literal token. For example, '%%tp' would be expanded to '%tp'.
Applies to execute.
GetHookEnable is optional. When enabled ('Y' or 'y'), the caller has the ability to interrupt or hook the normal course of events by running a single system command. This mechanism provides users with the ability veto or bless, as the case may be, subsequent execution of the target program. The default value is 'N'.
Applies to execute.
GetHookStatus is required when GetHookEnable is enabled. The value of this control determines the meaning of success for
the hook. If the specified value matches the exit status as returned by
system(3),
then the target program will be executed as usual. Otherwise, the target program will not be executed.
Applies to execute.
GetHookSuffix is optional when GetHookEnable is enabled. The hook suffix is appended to the target (program) name to create a variant name. This variant name takes the place of the target name in the GET request. To maintain order, the hook command must transform the downloaded variant into the target program. If this control is not defined, then the variant and target names will be the same, and no transformation would be required.
Applies to execute.
GetTimeLimit is optional. The value of this control specifies how long the program is willing wait before giving up on download (i.e. GET) requests. If GetTimeLimit is non zero and the time limit expires, the program will abort. If GetTimeLimit is not set or is set to zero, no limit will be imposed. The default value is zero.
Applies to execute.
HashType is optional. This control specifies the hash algorithm that is to be used when calculating message digests. Currently, the following algorithms are supported: MD5, SHA1, and SHA256. If not specified, HashType defaults to MD5. This control is not case sensitive.
Applies to execute.
Import is optional. When specified, the directives contained in the file referenced by this control are included in the current configuration. Multiple instances of this control are allowed per file, and recursion is permitted up to three levels deep. Imports may be specified using a relative path.
Applies to execute.
OverwriteExecutable is optional. When enabled ('Y' or 'y'), existing executables in the specified TempDirectory will be overwritten by subsequent GET requests. The default value is 'N'.
Applies to execute.
PutTimeLimit is optional. The value of this control specifies how long the program is willing wait before giving up on upload (i.e. PUT) requests. If PutTimeLimit is non zero and the time limit expires, the program will abort. If PutTimeLimit is not set or is set to zero, no limit will be imposed. The default value is zero.
Applies to execute.
RunTimeLimit is optional. The value of this control specifies how long the program is willing wait for the target application to finish. If RunTimeLimit is non zero and the time limit expires, the program will kill the spawned process and abort. If RunTimeLimit is not set or is set to zero, no limit will be imposed. The default value is zero.
Note: Killing the spawned (i.e., child) process is done via
TerminateProcess()
and kill()
on Windows- and
UNIX-based platforms, respectively. This may result in orphaned grandkids
in either case. To help prevent this situation, proactively identify
processes that block or take a long time to run and make sure that they run
as kids. Using the shell's built-in exec or the family of
exec()
calls can help in this regard.
Applies to execute.
RunType is optional. This control sets a corresponding flag that classifies uploaded data as linktest or snapshot, The value of this control does not affect the format or content of WebJob output. When output is uploaded to a Web server, the value of this control may be used to determine how the data is processed. If not specified, RunType defaults to snapshot.
Applies to execute.
SSLBundledCAsFile is required when SSLVerifyPeerCert is enabled. This control specifies the name of a PEM (Privacy Enhanced Mail) encoded file that contains a bundled set of Certificate Authority (CA) certificates. Any validated peer certificate that is signed by one of these CAs will be accepted provided that the SSLMaxChainLength and SSLExpectedPeerCN checks are also satisfied. SSLBundledCAsFile may be specified as a relative path.
Applies to execute.
SSLExpectedPeerCN is required when SSLVerifyPeerCert is enabled. The value of this control represents the peer's expected Common Name (CN). Conventionally, CNs are specified as fully qualified domain names. This control eliminates the need to perform a DNS lookup at the time of certificate validation. This, in turn, may help to prevent attacks involving DNS spoofing.
Applies to execute.
SSLMaxChainLength is optional when SSLVerifyPeerCert is enabled. The value of this control determines how deep a certificate chain may be before it is considered invalid. If not specified, this control defaults to a value of 1.
Applies to execute.
SSLPassPhrase is optional when SSLUseCertificate is enabled. Its value, if specified, is used to decrypt the contents of the client's private key file (see SSLPrivateKeyFile). If a passphrase is required to load the private key and this control has not been set, the user will be prompted for one. Naturally, this will cause problems for automated tasks, so keep that in mind.
Applies to execute.
SSLPrivateKeyFile is required when SSLUseCertificate is enabled. This control specifies the name of a PEM (Privacy Enhanced Mail) encoded key file that can be used to sign SSL certificates. SSLPrivateKeyFile may be specified as a relative path.
Applies to execute.
SSLPublicCertFile is required when SSLUseCertificate is enabled. This control specifies the name of a PEM (Privacy Enhanced Mail) encoded certificate to be used during SSL handshakes. SSLPublicCertFile may be specified as a relative path.
Applies to execute.
SSLUseCertificate is optional. When enabled ('Y' or 'y'), it instructs the application to provide client side certificate authentication, if necessary. The default value is 'N'.
Applies to execute.
SSLVerifyPeerCert is optional. When enabled ('Y' or 'y'), it instructs the application to verify the credentials of the peer server. The default value is 'N'.
Applies to execute.
TempDirectory is optional. This control specifies a directory in which all temporary files are to be created. If TempDirectory is not specified, the program attempts to obtain its value from the environment. First, it looks for TMPDIR (TEMP for WIN32). Next, it looks for TMP (all platforms). If a suitable environment variable is not found, TempDirectory defaults to /tmp (\temp for WIN32). TempDirectory may be specified as a relative path.
Note: If TempDirectory does not exist, the program will abort.
Note: If an environment variable is defined but exceeds the maximum allowed length, it will be rejected.
Applies to execute.
TimeoutSignal is optional. When the run timer expires (see RunTimeLimit), the signal specified by this control is sent to the spawned process. This control is rarely needed, and it should be used with care. Sending the wrong signal to a child process may not yield the desired result. However, there are cases when sending the default signal (SIGKILL = 9) is not the preferred course of action either. For example, you may want to run a tool that will perform an orderly shutdown upon receipt of a particular signal (e.g., SIGINT = 2).
Note: This control is UNIX-specific, and its value must be a valid signal number (e.g., 1, 2, 9, etc.). Because the number of signals can vary from OS to OS, you should check the man pages to determine what values are valid for your systems. On many systems, the following command will produce a mapping of signal names to their assigned numbers:
$ kill -l
Applies to execute.
URLAuthType is optional. It identifies what authentication scheme to use when issuing HTTP/HTTPS requests. The value specified by this control applies to any requests involving URLGetURL or URLPutURL. When URLAuthType is set to basic, user credentials are base 64 encoded and incorporated into the request header. User credentials specified in the URL take precedence over credentials specified in the URLUsername and URLPassword controls. If not specified, URLAuthType defaults to none.
Applies to execute.
URLDownloadLimit is optional. The value of this control specifies how much data the client is willing to receive for any given HTTP/HTTPS request. If URLDownloadLimit is not set or is set to zero, no limit will be imposed. The default value is zero.
Applies to execute.
URLGetURL is required. It defines the scheme, user credentials, host address, port, and CGI application to be used when making requests. If a username/password pair is specified in the URL, that pair takes precedence over the values specified by URLUsername/URLPassword, if any. The tokens '%user' and '%pass' may be used as place holders in the specified URL. Before a GET/PUT request is issued, these tokens are replaced with the actual values assigned to URLUsername and URLPassword, respectively. URLs must use a scheme of http or https and satisfy the following regular expression:
scheme://(user(:pass)?@)?host(:port)?/(path(\?query)?)?
Applies to execute.
URLPassword is optional. It identifies the password to use when accessing a remote Web server. The value specified by this control is used in conjunction with URLGetURL and URLPutURL unless those controls supply their own username/password pair.
Applies to execute.
URLPutURL is optional. It defines the scheme, user credentials, host address, port, and CGI application to be used when making PUT requests. If a username/password pair is specified in the URL, that pair takes precedence over the values specified by URLUsername/URLPassword, if any. In any event, user credentials are only sent when basic authentication has been requested (See URLAuthType). URLPutURL uses the same syntax as URLGetURL.
Applies to execute.
URLUsername is optional. It identifies the username to use when accessing a remote Web server. The value specified by this control is used in conjunction with URLGetURL and URLPutURL unless those controls supply their own username/password pair.
Applies to execute.
UnlinkExecutable is optional. When enabled ('Y' or 'y'), the downloaded executable is deleted before the program exits. The default value is 'N'.
Applies to execute.
UnlinkOutput is optional. When enabled ('Y' or 'y'), any output files are unlinked before the program exits. This control has no effect when output data is directed to stdout/stderr. The default value is 'N'.
Applies to execute.
UploadOnGetFailure is optional. When enabled ('Y' or 'y'), the program will attempt to upload its results even if the GET fails. Normally, attempting to upload results after a failed download is futile (e.g., authentication failures). However, there may be times when this behavior is desired. For example, suppose that URLGetURL and URLPutURL point to different servers. In this scenario, a GET failure does not imply that the PUT will fail too, so by monitoring uploads, you could detect jobs that aren't functioning properly. The default value for this control is 'N'.
Upon successful completion, a value of 0 (XER_OK) is returned. Otherwise, one of the following error codes is returned:
1 = XER_Abort
2 = XER_Usage
3 = XER_BootStrap
4 = XER_ProcessArguments
5 = XER_ReadProperties
6 = XER_CheckDependencies
7 = XER_Configure
8 = XER_GetStage
9 = XER_RunStage
10 = XER_PutStage
11 = XER_MultiStage
A value of 1 (XER_Abort) means the program encountered a critical error and had to abort immediately. If the command line does not conform to the required syntax, a value of 2 (XER_Usage) is returned. The remaining exit codes roughly indicate which subsystem encountered the fatal error. If the error code is XER_MultiStage, then multiple stages (e.g., GET/RUN/PUT) failed.
The config file specified on the command line contains a set of controls that are used to configure WebJob's runtime behavior. For more details on what controls may be specified, see the CONFIGURATION CONTROLS section of this document.
The program specified on the command line is retrieved from the Web resource and written to the local file system. The exact location varies depending on the value of TempDirectory. When UnlinkExecutable is enabled, the program is deleted before WebJob exits. However, if the WebJob aborts, this file may not be deleted.
The values for <time>, <nonce>, and <suffix> are the job epoch in seconds, a random hex string used to help prevent name collisions and guessing attacks, and one of {out,err,env}, respectively. The suffix is used to associate a given file with its corresponding output stream -- i.e. std{out,err,env}. When URLPutURL has been set, the sub-process writes its data to the named out and err streams/files. Once the sub-process has finished, WebJob writes information regarding environment settings and exit status to the env stream/file. When UnlinkOutput is enabled, these files are deleted after they have been uploaded and before WebJob exits. However, if the WebJob aborts or the upload fails, these files may not be deleted.
When SSLUseCertificate has been enabled, WebJob expects to find certificate and key files in the locations specified by SSLPublicCert and SSLPrivateKey controls, respectively. If these files do not exist or have the proper format, WebJob will abort.
When SSLUseCertificate has been enabled, WebJob expects to find a bundled certificate authorities file in the location specified by SSLBundledCAs control. If this file does not exist or have the proper format, WebJob will abort.
The server-side CGI script, nph-webjob.cgi, writes log messages to BaseDirectory/logfiles/nph-webjob.log (see nph-webjob.cfg). This file contains the following fields separated by whitespace in the given order: DateTime, JobId, RemoteUser, RemoteAddress, RequestMethod, ClientId, ClientFilename, ContentLength, ServerContentLength, Duration, ReturnStatus, and ErrorMessage. A single hyphen, '-', is used to denote the fact that a particular field had an empty or undefined value. The ErrorMessage field is set off from the other fields with a double hyphen '--' because it uses a free form text format that can include whitespace.
The server-side CGI script, nph-webjob.cgi, writes trigger-related log messages to BaseDirectory/logfiles/nph-webjob-trigger.log. This file contains the following fields separated by whitespace in the given order: Date, Time, JobId, RequestMethod, ClientId, ClientFilename, PidLabel, Pid, State, and Message. A single hyphen, '-', is used to denote the fact that a particular field had an empty or undefined value. The Message field is set off from the other fields with a double hyphen '--' because it uses a free form text format that can include whitespace.
The following examples are intended to demonstrate different ways of configuring and using WebJob. Any text encapsulated between '--- XXX ---' delimiters represents config file content.
This example demonstrates how to download and run ps(1)
with
output being directed to stdout/stderr. It is assumed that a Web resource
has already been configured to serve the appropriate ps(1)
binary for the system in question. Also, assume that the following
information has been provided.
ClientId = client_1 URL = http://trusted.server.net/cgi-client/nph-webjob.cgi Username = client_1 Password = access
The simplest configuration file that will carry out this task is as follows:
--- example1.cfg --- ClientId=client_1 URLGetURL=http://client_1:access@trusted.server.net/cgi-client/nph-webjob.cgi URLAuthType=basic --- example1.cfg ---
or, alternatively
--- example1.cfg --- ClientId=client_1 URLGetURL=http://trusted.server.net/cgi-client/nph-webjob.cgi URLUsername=client_1 URLPassword=access URLAuthType=basic --- example1.cfg ---
Once the config file has been created, WebJob may be invoked as follows:
webjob -e -f example1.cfg ps -aux
or
webjob -e -f - example1.cfg ps -aux < example1.cfg
One item to note is that WebJob will store the downloaded program in the directory specified by TempDirectory. In this case, TempDirectory hasn't been specified, so data will be written to the default directory (i.e. /tmp). To automatically remove this file after program completion, enable the UnlinkExecutable control.
Suppose that you want to direct the output of ps(1)
to a Web
resource instead of stdout/stderr. Given that that the URL from example one
may be used for both GET and PUT requests, the config file becomes:
--- example2.cfg --- ClientId=client_1 URLGetURL=http://trusted.server.net/cgi-client/nph-webjob.cgi URLPutURL=http://trusted.server.net/cgi-client/nph-webjob.cgi URLUsername=client_1 URLPassword=access URLAuthType=basic RunType=snapshot --- example2.cfg ---
This job may be started as follows:
webjob -e -f example2.cfg ps -aux
One item to note is that WebJob will create three files of the form webjob_<time>_<nonce>.<suffix> where <time> is the job epoch in seconds, <nonce> is a random hex string, and <suffix> is one of {out,err,env}. The exact location of the files depends on the value of TempDirectory. These files contain the output data that will be uploaded to the WebJob server in a PUT request. To automatically remove these files after they have been successfully uploaded, enable the UnlinkOutput control.
Suppose that you want to run netstat(1)
over a secure,
authenticated channel. Further, suppose you also want to delete the
downloaded
program and its associated output files upon job completion. Assuming that the Web
resource is properly configured, then the information provided below is
sufficient to create the following config file.
GET/PUT URL = https://secure.server.net:443/cgi-client/nph-webjob.cgi SSL Public Cert File = /usr/local/webjob/ssl/mycrt.pem SSL Private Key File = /usr/local/webjob/ssl/mykey.pem SSL Bundled CAs File = /usr/local/webjob/ssl/CAs.pem SSL PassPhrase = flimflam Certificate Chain Length = 2 Web Resource Validates Client Certificates = Y
--- example3.cfg --- ClientId=client_1 URLGetURL=https://secure.server.net:443/cgi-client/nph-webjob.cgi URLPutURL=https://secure.server.net:443/cgi-client/nph-webjob.cgi URLUsername=client_1 URLPassword=access URLAuthType=basic RunType=snapshot UnlinkOutput=Y UnlinkExecutable=Y SSLUseCertificate=Y SSLPublicCertFile=/usr/local/webjob/ssl/mycrt.pem SSLPrivateKeyFile=/usr/local/webjob/ssl/mykey.pem SSLPassPhrase=flimflam SSLVerifyPeerCert=Y SSLBundledCAsFile=/usr/local/webjob/ssl/CAs.pem SSLExpectedPeerCN=secure.server.net SSLMaxChainLength=2 --- example3.cfg ---
This job may be started as follows:
webjob -e -f example3.cfg netstat -an
To compute the MD5 hash of /bin/ps, run the following command:
webjob --hashsum --type md5 /bin/ps
or in short form:
webjob -h -t md5 /bin/ps
To compute the SHA1 hash of /bin/ps, run the following command:
webjob --hashsum --type sha1 /bin/ps
or in short form:
webjob -h -t sha1 /bin/ps
This example demonstrates how to download and run a gzipped copy of
ps(1).
It is assumed that a Web resource has already been
configured to serve unzipped or zipped copies of ps(1)
as ps
or ps.gz, respectively.
The first step is to enable GetHook in the client's config file and define the appropriate hook command, suffix, and return status. The following config file snippet shows how this is done.
--- example6.cfg --- ... GetHookEnable=Y GetHookCommandLine=gzip -d %vp GetHookStatus=0 GetHookSuffix=.gz ... --- example6.cfg ---
In general, any valid command or pipeline may be specified for the hook as long as it produces a valid ps executable. When the following WebJob command is issued, the hook modifies the GET request such that ps.gz is requested. After ps.gz has been downloaded, the hook executes the specified command. In this case, '%vp' will be expanded to 'ps.gz'. If the hook command returns a zero status, then the operation is deemed successful and normal WebJob execution ensues. If the return status is not zero, the target command will not be executed.
webjob -e -f example6.cfg ps -aux
This example demonstrates how to download and run a GPG signed copy of
ps(1).
It is assumed that a Web resource has already been
configured to serve unsigned or signed copies of ps(1)
as ps
or ps.gpg, respectively.
The first step is to enable GetHook in the client's config file and define the appropriate hook command, suffix, and return status. The following config file snippet shows how this is done.
--- example7.cfg --- ... GetHookEnable=Y GetHookCommandLine=gpg --batch --decrypt %vp > %tp GetHookStatus=0 GetHookSuffix=.gpg ... --- example7.cfg ---
When the following WebJob command is issued, the hook modifies the GET request such that ps.gpg is requested. After ps.gpg has been downloaded, the hook executes the specified command. In this case, '%tp' and '%vp' will be expanded to 'ps' and 'ps.gpg', respectively. If the hook command returns a zero status, then the operation is deemed successful and normal WebJob execution ensues. If the return status is not zero, the target command will not be executed.
webjob -e -f example7.cfg ps -aux
This example demonstrates how to log, using logger(1),
the
fact that WebJob downloaded and attempted to run ps(1).
It is assumed that a
Web resource has already been configured to serve copies of
ps(1)
as ps.
The first step is to enable GetHook in the client's config file and define the appropriate hook command and return status. The following config file snippet shows how this is done. Note how the suffix is commented out -- it could be left blank also.
--- example8.cfg --- ... GetHookEnable=Y GetHookCommandLine={ logger -p user.alert -t "webjob[%pid]" "%vp ---> %tp" ; true ; } GetHookStatus=0 #GetHookSuffix= ... --- example8.cfg ---
When the following WebJob command is issued, the hook does not modify the GET request because a
suffix was not defined. After ps has been downloaded, the hook executes the
specified command. In this case, '%tp', '%vp', and '%pid' will be expanded
to 'ps', 'ps', and the current Process ID (PID), respectively. The
specified command always returns a zero status due to true(1),
so normal
WebJob execution ensues.
webjob -e -f example8.cfg ps -aux
openssl(1),
webjob-dsvtool(1)
Klayton Monroe
WebJob was initially written to assist Incident Response Handlers in their efforts to investigate potentially compromised systems. Often, these Handlers must work around the constraints imposed by the surrounding environment. For example, lack of physical or shell access, untrusted diagnostic programs, lack of encryption, many machines in need of investigation, and so on. Therefore, I felt that Handlers, or their eyes and ears in the field, needed an efficient way to import and run known good diagnostic tools when investigating live systems.
WebJob is lightweight, portable, and easy to use. This makes it a good candidate for establishing a foothold on the target system. Once there, all that is needed to begin diagnostics is a small configuration file and access to a remote WebJob server. When there are many machines to investigate, WebJob can be deployed in parallel, and all harvested output can be directed to and aggregated on a single server. This reduces the amount of manual data processing involved in collecting, tagging, and storing evidence. It also significantly reduces the amount time, effort, and resources needed to arrive at a determination.