Pentestbook
  • Home
  • Type Juggling
    • PHP Loose comparison
Powered by GitBook
On this page
  • Loose comparison
  • Strict comparison
  • Some examples
  • Magic Hashes
  • Challenge
  1. Type Juggling

PHP Loose comparison

PreviousHome

Last updated 9 months ago

PHP has this particular functionality called Type juggling, it essentially tries to predict what a programmer wants to do with a variable, it usually checks whats's inside a variable and tries to convert it, for example if a string contains only numbers it will convert it to either an integer or a float, this behaviour can sometimes cause issues, especially when loose comparison is used.

PHP8 won't try to cast string into numbers anymore,

In PHP there are 2 main types of comparison

  • Strict comparison (===)

  • Loose comparison (==)

Loose comparison

Loose comparison compares only the value of the variable and not the type, it uses type juggling to try and predict the type of the variable


Strict comparison

Strict comparison instead compares both the value of the variable and the type, it doesn't do any kind of type juggling since it also compares the type of the variable

Some examples

these examples may work or not depending on the version of php that is currently in use

var_dump(15 == "15");  // bool(true)
var_dump('0xdeadbeef' == '3735928559');  // bool(true) works on versions before php7

another peculiar example is :

var_dump('10e3' == '1e4');  // bool(true)

Here PHP interprets boh the strings 10e3 and 1e4 as a scientific notation, PHP first converts this numbers into floats and the procedes with the comparison

Magic Hashes

Due to PHP juggling, when comparing hashes to another variable, if the hash starts with 0e it will again be interpreted as a scientific notation and it's value is going to equal to 0

var_dump('0e123' == '0'); # bool(true)
var_dump(md5('sQcRTBkePLSY') == md5('fQvn3oAoYNfo')); # bool(true)
// it translates to : var_dump('0e576163277785256730155739473379' == '0e935872100939536813194636270943');

Challenge

a simple ctf challenge showcasing this kind of vulnerability

10e3 becomes 10×102=100010×10 ^2 = 100010×102=1000

1e4 becomes 1×103=10001×10 ^3 = 10001×103=1000

You can find whole lists of magic hashes on various algorithms here :

https://github.com/spaze/hashes
https://websec.fr/level10/index.php
https://dustri.org/b/php8-from-a-security-point-of-view.html#:~:text=PHP8%20won't%20try%20to,Snuffleupagus'%20sloppy%20comparison%20prevention%20feature.
https://www.php.net/manual/en/types.comparisons.php
https://www.php.net/manual/en/types.comparisons.php