The following is an example of using shell parameter expansion to overcome the limitation of using spaces in a command injection vulnerability found in a web application parameter.

A simple test to try if you suspect a parameter is being passed to a shell script, binary or executable on the system would be to add ;whoami after the final parameter, or test for a blind injection by adding ;ping -c <your ip>. So for example

http://10.161.23.15?zoom=5&direction=up;whoami

The semicolon in Bash is used to signify the end of one command and the beginning of another. We need to include that first to end whatever command the application was attempting to run and begin executing the command we are trying to inject. If you wanted to chain two commands together you could use ;whoami&&id. I mention that because the && will be an important part of getting our command injection to work.

code execution

We can see in Burp Repeater’s Response pane that the output that our command was executed and displayed just below the text ‘Camera Adjusted’. whoami returned daemon and id returned uid=2(daemon), gid=2(daemon), group=2(daemon), 1(bin), 4(adm).

But when trying to execute a command with a space in it

http://10.161.23.15?zoom=5&direction=up;cat%20/etc/passwd

we get don’t get any output from our command.

Keep in mind that entering a space to any part of a url in your browser’s url bar will cause that space to be hex encoded automatically before it is sent to the server. However in Burp you can send the request directly to the server as an unencoded space. Most of the time this will cause a server error, but sometimes not, so it’s worth trying. In this instance sending the command with an unencoded space caused the web application to return a 400 bad request error, so the parameters we send to the server need to be url encoded.

We can assume that the hex encoded space (represented by the value %20) is causing the command to fail because the hex encoding is being passed directly to the system shell, and since cat%20/etc/passwd is not valid syntax in Bash the command fails.

So at this point we have command injection but we’re limited to only using single commands without any spaces, which isn’t all that useful. A possible way around this could be to use shell parameter expansion to convert cat /etc/passwd into a string that doesn’t throw an error when tacked onto the end of the url parameter and that also executes when passed to the Bash shell.

To see this working directly in your own linux terminal, paste CMD=$'\x20/etc/passwd'&&cat$CMD into Bash (this failed for me in zsh so make sure you’re using Bash), and it will execute cat /etc/passwd successfully. To break down the parts of the entire command, first we create a variable CMD and assign it the value $'\x20/etc/passwd', which will add the string /etc/password preceded by a space to the variable CMD. Second, the && tells bash to execute the next command if the previous command completed successfully. This is necessary because the syntax cat$'\x20/etc/passwd' is also not valid. Finally, cat$CMD will transform into cat /etc/passwd when executed in the system shell.

We can see from our output below that our command was successful

code execution via parameter expansion

Here’s an article with examples and use cases for parameter expansion at gnu.org. All of the examples on that site use braces instead of quotes, but quotes are also valid in place of braces.