Writeup: OS command injection, simple case @ PortSwigger Academy

This is a writeup for the Lab “OS command injection, simple case” from PortSwiggers Web Security Academy:

Python script: script.py

Lab description

  • OS command injection in the product stock checker
  • Application executes shell command with product and store IDs, returns raw output


  • Execute whoami



As usual, the first step is to browse around a bit. It is the usual showfront application known from previous labs. The new item here is the ability to check the availability of a product in different stores around the world:

Lets have a look how the request goes in Burp:

The request contains two parameter, productID and storeID, and returns a number as plain text in the response. Lets send the request to the repeater and see how it goes. As we have two parameter, I try to inject in both with different commands. This way, I can find out which parameter is injectable and in which order they are executed.

The script call might look something like this (likely not valid syntax, but the general idea is the same):

echo system("someScript.sh $_REQUEST['productID'] $_REQUEST['storeId']")

The parameters are used as arguments for the script, its output is directly echoed back onto the HTML.

There are multiple ways to execute multiple commands in one line in a shell, separating the individual commands with for example &, &&, |, ||, ;. All behave slightly different. On Unix systems, my favourite is ; as it completely separates the commands without side effects based on return conditions or execution order. In some conditions & is actually better as it backgrounds the command prior to my injection and runs my code without waiting for the other command to finish. Still, my favourite remains ;.

SomeScript.sh might return a fail status without its arguments. We don’t know the order of the arguments, and there might be more than just these two. Ideally, I want to just ignore the script completely and execute my injected command regardless.

Therefore I inject my command after a ; in the POST parameters. (On a side note: when using &, it must be URLencoded).

From the response it can be seen that both parameters are injectable, and they are executed in the order productId first, storeId second.

Solve the lab

What is missing now is just executing the whoami command to solve the lab. I comment out the remainder of the line after the whoami to avoid the error message of the second parameter:

After this request, the lab page updates to

And on a personal note, I like the stockreport script:

Originally published at https://github.com.




Tech nerd with a fable for all things cybersecurity. Doing a lot of security stuff for fun and some even as a job. But mostly fun.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

CS373 Fall 2020 Final Entry: Kevin Hao

How to start monitoring uptime with ELK heartbeat running in Kubernetes

Test to see if this IFTTT works

Working with NEO using Xcode and Swift

Social Sensing Workshop at GIScience Conference 2021

A Look at the Evolution of Benchling’s Search Architecture

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Frank Leitner

Frank Leitner

Tech nerd with a fable for all things cybersecurity. Doing a lot of security stuff for fun and some even as a job. But mostly fun.

More from Medium

Basic Pentesting CTF Walkthrough

TryHackMe:VulnNet: Node

Writeup: CSRF vulnerability with no defenses @ Portswigger Academy

HackTheBox Writeup — Previse