CMD.exe Double Quote Error

I am trying to understand why it works and does not work.

I wrote a custom fixlet for Nessus agent link after install Nessus agent.

waithidden cmd.exe /C ""C:\<path>\nessuscli.exe"" agent link --key={parameter "_A"} --host={parameter "_B"} --port=#### >> "C:\xx.txt"

The fixlet showed completed with Exit Code = 0. But, it does not establish the link to the Nessus agent. The output file shows nothing.

Then I played around with double quotes and other things until I got it work. (two double quotes before the targeted path and one double quote after the targeted path)

waithidden cmd.exe /C ""C:\<path>\nessuscli.exe" agent link --key={parameter "_A"} --host={parameter "_B"} --port=#### >> "C:\xx.txt" 

The fixlet showed failed with Exit Code = 0. But, it did establish the link to the Nessus agent. The output file shows the result of link establishment.

Any idea why, it shows failed while it worked and why two double quotes before the path and one single double quote after the targeted path worked but not double double quotes on each end of the targeted path?

Please wrap your code in the “code” tag by highlighting it and clicking the code symbol, or use the markup tags by wrapping in single backtick ( ` ) symbols. image

Otherwise it’s hard to tell whether the Forum software has changed your "normal quotes" into “smart quotes”. In your second example some of your quotes are “smart quotes” and I don’t know whether those are really smart quotes in what you pasted, or whether the Forum software changed them.

The weird handling of doublequotes is a function of the CMD.EXE processor itself. If the /C is followed by a quoted command, that is all assumed to be one single filename with spaces, unless the command has embedded doublequotes within it. If there are embedded doublequotes, then then outer doublequotes are stripped, and the remaining inner command is executed as if it had been typed into a command line.

These are explained in the help of “cmd.exe /?”:

If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:

    1.  If all of the following conditions are met, then quote characters
        on the command line are preserved:

        - no /S switch
        - exactly two quote characters
        - no special characters between the two quote characters,
          where special is one of: &<>()@^|
        - there are one or more whitespace characters between the
          two quote characters
        - the string between the two quote characters is the name
          of an executable file.

    2.  Otherwise, old behavior is to see if the first character is
        a quote character and if so, strip the leading character and
        remove the last quote character on the command line, preserving
        any text after the last quote character.

What I think should be the correct usage of the command line you’re trying, is

waithidden cmd.exe /C ""C:<path>\nessuscli.exe" agent link --key={parameter "_A"} --host={parameter "_B"} --port=#### >> "C:\xx.txt" 2>&1"

This way, both the stdout and stderr messages are logged to the file, so you should get some info if it fails. In your last line you were missing the outer closing " symbol.

Now, if this is a Fixlet, the evaluation of “Success” or “Failed” depends on your Relevance. If the Relevance still evaluates to “True” after you run it (i.e. you don’t check whether the link is actually correct), then the Fixlet would be marked as Failed. You can use a “Custom Success Criteria” on the Action tab to change the criteria to “All lines of the script run successfully” to make it behave like a Task instead of a Fixlet; and add a line to the end of the ActionScript to check the exit code for success instead via
continue if {exit code of action = 0 }

3 Likes

I edited the original post to do this.

This can be a pain at times, to figure out the right combination of " and in the case of bash, also ' characters to wrap a command. You can generally test this on the command line manually without using BigFix and make sure it works that way first, particularly in the case of CMD. You will have to manually substitute the bigfix parameters. Also, be sure to put CMD /C in front of the command on the command line when testing to emulate what you would then do in bigfix.

Another thing to do is to look into the bigfix client logs and check the actual command being processed there and then test the same on the command line manually.

2 Likes