Post

Php Part1

PHP Web Challenge

preg_replace()

Use in string manipulation that allows to search and replace specific pattern with strings.

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

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

1
2
3
4
5
6
7
8
9
10
11
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!
1
2
3
4
5
6
7
8
$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]."

1
2
3
4
5
6
7
8
9
10
11
$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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!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>

Above code can be divide into multiple part.

  1. Read Source Code
    1
    2
    3
    4
    
     if (isset($_GET['source'])) {
     highlight_file(__FILE__);
     die();
      }
    

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

  2. Get parameter
    1
    2
    
    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
    1
    2
    
    $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
    1
    
    if ($final_string === $intermediate_string)
    

    Lastly it will check final_strings with intermediate_string. If 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 pattern. it will replace the strings with $replace.

In this case, the $intermediate_string check with $your_entered_string

1
2
3
4
$your_entered_string = userinput
$intermediate_string = hellotherehooman

intermediate_string === final_string

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

image

Another CTF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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 input 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

image

Exploitation

PHP version 5.0 and below. Can execute /e/ modifier. http://URL/index.php?pat=/a/e/&rep=phpinfo();&sub="Payload"

image

Proof that we can bypass it.

PHP Type Jungling

Bug that only occurs in PHP mainly due to comparison another things.

There are strict (===) and loose(==) comparison.

The vulnerability occur in loose comparison.

1
2
3
4
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 endpoint /upload.php

Since the strcmp can be manipulate as array. Assign the $username as array to bypass comparison.

username[]=anything&password[]=anything

This post is licensed under CC BY 4.0 by the author.