Command Injection — preg_replace() PHP Function exploit

Ishara Abeythissa
3 min readFeb 9, 2020

Today we gonna exploit most commonly using php function called preg_replace.

Let’s now look at the preg_replace function that performs a pattern match and then replaces the pattern with something else.

Here we go with simple vulnerable code

if(!isset($_POST[‘swearwords’]) || !isset($_POST[‘to’]) || !isset($_POST[‘subject’]) || !isset($_POST[‘message’])) return header(‘Location: dashboard.php’);

function clean($str){

$swearwords = $_POST[‘swearwords’];

foreach ($swearwords as $badword => $replacement)
{
$str = preg_replace($badword, $replacement, $str);
}

return $str;
}

Mostly developers used this function for words filtering techniques. such as email bad words filters. above code took from that kind of scenario. This code will take a user inputs when user send an emails from massage body and replace good words if they are using any bad words which developers attached to the application. as an example, if user input a word like “whore” then that word will replace with a good word.

Request header

for some reasons I won’t mention HTTP method and HOST in here. you can see the massage section in data body I’m sending the word “whore”. according to the script and data section word should replace with “escort”.

Response header

Now for further exploitation need to replace i modifier with e modifier which will cause PHP to execute the result of preg_replace() operation as PHP code.

Command Injection request header

exploit code :- swearwords[/whore/e]=system(‘id’);

Response header

After injecting a command id you can see as output came default user of apache server in linux.

Prevention –

PHP provides a handy function named as preg_quote() which will quote all nasty characters in the input string and prevent this code execution vulnerability.

function clean($str){

$swearwords = $_POST[‘swearwords’];

foreach ($swearwords as $badword => $replacement)
{
$str = preg_replace(‘#’ .preg_quote($badword, ‘#’). ’#’, $replacement, $str);
}

return $str;
}

Using the above function i.e. preg_quote() renders all the regex characters, so if you need to allow some access to use regular expressions, you’ll need to escape your delimitation character by hand.

Ultimately the use of such a function is always going to be a problem. Instead we should be using functions which allow us to specify the search strings and replacement strings as separate parameters, removing control from the attacker.

--

--