PortSwigger: All Command Injection Labs Walkthrough

 
 

In this post, I will cover the Apprentice level JSON Web Token labs located at PortSwigger Academy as well as providing some context regarding what JSON Web Tokens are and the vulnerabilities associated with them.


Command Injection Vulnerabilities


Deep Dive into Command Injection


Lab 1 - OS command injection, simple case

Once we start the lab, we can see a normal looking shop page:

If we navigate to a product page, such as the first one seen, we can see in the URL that it includes a productId query parameter in the URL that likely specifies the number to identify this product:

Let’s take a look at that request in Burp Suite:

Nothing seems out of the ordinary. It is a fairly simple GET request. With this in mind, we can try some command injection in the productId field just as a test - it may be running a script on the backend that requires the productId as a parameter:

After using the semicolon syntax and using the whoami command, let’s observe the response below:

We can get an invalid product ID - no worries! Just as a good rule of thumb, we can try some different syntax such as the pipe symbol instead of the semicolon:

As we can see above, we get the same 400 HTTP response indicating that there is an invalid product ID. With this in mind, we can try to look for any additional functionality that may appear on the page.

Looking through and scrolling down to the bottom of a product page, we see that there seems to be some functionality that allows us to check the stock of a certain product:

With a store selected, let’s hit the Check Stock button and observe what happens:

Here, we can see that the units appear in the page itself. To analyze further, let’s take a look at that request in Burp Suite:

It appears to be a POST request. However, more interestingly, we see an additional parameter being sent in the body - storeId - alongside the one already appearing in the URL which is the productId.

With this POST request sent to Repeater, let’s resend the request and observe what the normal response looks like:

It’s a normal 200 OK response. With this in mind, and a new parameter to start fuzzing, we can try and use the pipe operator in the storeId parameter and append another command such as “ls”:

With this injection, let’s send it forward and observe the response:

Interesting. We see a different output - this time it returns the string “stockreport.sh”. This appears to be a script file that is likely responsible for checking the stock of a product (guessing off the file name).

If this is true, and the stock check is done via a BASH or script file, then it is likely vulnerable to more command injection.

To test this theory, we can try a different command such as “pwd” and see if the output differs again:

It does! This time, we see the current working directory which tells us we are in the home/peter-FKRV9Y directory.

With this in mind, we can know confirm that this is vulnerable. To complete the lab, we simply need to execute the whoami command. To do this, we can simply replace our existing command:

And, let’s observe the response:

Bingo! We see that we are the peter-FKR9VY user. From here, you could get even more malicious and start unleashing your inner evil. However, as we see in the browser, we have successfully completed the lab at this point:


Lab 2 - Blind OS command injection with time delays

As always, we start the lab and see the same shop as before:

Now, let’s play around and start mapping the application. Let’s look at the product page since it was vulnerable in the last lab:

There is no comment section this time. However, if you look at the top right of the home page, there is a link to submit feedback which likely includes multiple different fields we can enter data into for submitting our feedback:

And we are correct. There are 4 fields that we can now test for. However, before trying to exploit, let’s send some dummy data and observe the normal functionality:

Once we hit the submit feedback button, a message appears at the bottom telling us that our feedback was submitted:

Now, we don’t really get any response from this submission form so this is likely a blind injection. With this in mind, let’s take a look at the feedback submissions request in Burp Suite:

Above, we can see 4 fields that we can likely try and fuzz:

  • name

  • email

  • subject

  • message

With this in mind, if we are dealing with a blind injection, we will need to get creative. As discussed in the theory section, we can use a command like the sleep command.

Doing a little bit of research on this reveals that it simply introduces a delay for a specified time and the syntax is “sleep [NUMBER]” with the number being in seconds:

With this in mind, let’s first try the name field by injecting the following syntax:

& sleep 10#

Once inputted, we need to make sure to URL encode this before sending it forward as a precaution:

Once we are ready, we can send this request, and observe the time it takes for us to get a response:

Above, we can see that this response took 192 milliseconds - definitely not the 10 seconds we set in the sleep command. Whilst you could play around and try different syntax and such, for this lab, we can move on to the next field - email - and use the same command and URL encode it:

Once ready, we can send it forward as always and look at the response:

This time, the response returns immediately and tells us that it “Could not save”. What does that mean? Well, we forgot to comment out the rest. In order to do that, we can use a variety of syntax, but in this case, I used the double pipe operator:

With this configured, let’s send it forward and wait for the response:

Look at the bottom right - it took over 10,000 milliseconds (10 seconds) to return the response to us, likely indicating that we have command injection.

With this in mind, if we go back to the home page, the congratulatory banner has dropped down:

Additionally, as discussed above, it is possible to also use the ping command to cause a time delay. For example, we could use the following syntax:

& ping -c 10 127.0.0.1||

Finally, we can observe that the response still takes a long time - this time taking 9,361 milliseconds - which is not 10 seconds but is still long enough to confirm that we have blind command injection:


Lab 3 - Blind OS command injection with output redirection

Again, we start the lab and notice the shop site:

With this, we can go into the submit feedback form again due to the previous lab having the vulnerability in the feedback form:

As before, we submit some dummy data to observe normal functionality:

After we submit our feedback, we don’t see what we submitted or any sort of indicating that it succeeded apart from the success message.

Let’s take a look further at this request by analyzing it in Burp Suite:

Here, we can see the same 4 fields as before - name, email, subject and message.

Like the previous lab, we can try injecting the same ping command in the email field and see if it is still vulnerable to blind injection:

Before sending it, we must URL encode it in Repeater to get the following:

Once sent, let’s view the response:

We see a 200 OK response which is good, but is not the important thing to note. Looking at the bottom right, we can see that the response took over 9 seconds to return, indicating that we do have valid command injection since our ping command got executed.

However, whilst this is good, how do we create an impact? Well, we can use output redirection. However, in order to do that, we need to find a place where we can write to.

As a good rule of thumb, we can see if we can identify the folder that images are stored in on the web app by checking the source code:

Above, we can see that the image source is /image followed by the filename. If we simply navigate to the /image directory, we get an error message:

However, if we specify a filename query parameter and the image exists, then the image gets returned to us:

With this in mind, it’s important to know that most web servers - at least on Linux - are ran from a directory called /var/www. Inside that folder, there is also likely an images folder where the websites images are stored.

Now that we understand this, we can try running the pwd command and redirecting the output to a file located in /var/www/images/pwd.txt:

Once we are ready, we can URL encode it and see if anything happens in the response:

Nothing appears since this is blind command injection. However, if it worked, then a file should exist in the images directory called pwd.txt.

To access this file, we can navigate to /image?filename=pwd.txt and view the contents (if it worked):

It did! And we can see the output of the pwd command in this text file. Now, we can run a different command - say whoami - and output that to a file called whoami.txt:

Once done, we can URL encode once again, send it off and view the response:

We get a 200 OK response - this is good. Then, all that is left to do is read the contents of the whoami.txt file as we did with the pwd.txt file to see what user we are running as:

Above, we can see that we are the peter-rKSwRc user. And with that, if we take a look at the home page, the banner drops down telling us that we solved the lab:


Lab 4 - Blind OS command injection with out-of-band interaction

As with every other lab, we spawn it and see the shop again:

Then, we also see the same feedback form with the same fields as before:

Now, as before, we can send some dummy data and see if there are any changes in the POST request that gets sent:

Once sent, let’s check Burp Suite and see what is happening:

Here, we see the same 4 fields as many times before. With this, if it is the same as previous labs, we know that the email field is vulnerable to command injection.

With this, we can try using the double pipe operator and appending another command such as “id”:

Once we URL encode it, we can send it over and see if anything different happens:

Spoiler alert - it doesn’t. However, if we use the same sleep command, it will work and alert us to the fact that this is vulnerable to blind command injection (do this on your own).

Now, to make blind command injection useful, we can extract information. However, in order to do that, we can use an out of band technique by using Burp Collaborator.

To do this, we can navigate to the Collaborator tab and copy the URL to our clipboard. This will generate a URL for us that we can use:

Now, once we have the URL copied, we can go back to Repeater and modify our request to the following:

& nslookup URL||

This will initiate a DNS request to our collaborator domain (if blind command injection exists):

Once inserted, we URL encode it and send it off:

Now, if we go back to the Collaborator tab and hit the “Poll now” button, we should see some DNS requests appear:

This confirms that the lab did initiate a DNS request to our collaborator domain and shows us that blind command injection is working.

Another way to do this is by using the cURL command instead of nslookup. To do that, we can modify the payload as such below:

Once we send it and poll collaborator again, we can see an HTTP request with the user agent set to cURL telling us that cURL also works to complete this lab:

Finally, if we go back to the home page, we can see the banner that drops down and we complete the lab:


Lab 5 - Blind OS command injection with out-of-band data exfiltration

Onto the final lab and once we start it, the same shop appears again:

As with previous labs, we submit feedback using dummy data to see what fields are being sent in the POST request:

Once sent, let’s check Burp Suite and see what parameters there are:

No changes which means we should be able to breeze through this lab. To do this, we can first navigate to the Collaborator tab and copy the URL to our clipboard:

Once done, we can use the same nslookup command as in the previous lab to test if we can still get interaction with our collaborator domain through blind injection:

Before sending it, we URL encode it as always:

Then, we send it and observe the response:

A 200 OK response comes back indicating that it worked. To check this, we can go back to the Collaborator window and see if any DNS requests came through:

There are, indicating that our blind command injection payload worked successfully.

Now, with this in mind, we can use the same payload, but this time use the backtick character to make it execute another command that appears inside our backticks. For example, below we can execute the whoami command before our collaborator domain and prepend it to the front so we can see it in the DNS request that will get sent to us:

Once configured, let’s URL encode it as always:

Perfect! Finally, let’s send it forward and watch:

A 200 OK response comes back again which is what we want to see.

Now, if we check our Collaborator tab, we can see additional DNS requests. However, more importantly, if we check the details of the query, we can see what appears to be a username before the first dot in our domain:

It appears the whoami command result got prepended to our DNS request, allowing us to exfiltrate data. With that in mind, if we look at the web page, we can see that we successfully completed the lab:

As an additional note, we can also use the $() syntax to execute the same command if backticks are filtered or escaped by some sort of WAF.

To do this, we can use the same payload, but just modify the syntax slightly:

Then, we URL encode it and see the 200 OK response as always - this is good.

Finally, we check the Collaborator DNS requests once again and we see the same results as before:

It performed the exact same command, but just using different syntax. It’s important to note this different syntax as some might be filtered or escaped via some sort of web app defense in real-life scenarios, so knowing multiple different ways to achieve the same task is a vital skill.

And with that, every command injection lab is completed.

Next
Next

PortSwigger: All File Upload Lab Walkthroughs