<summary><strong>Learn AWS hacking from zero to hero with</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
If `==` is used in PHP, then there are unexpected cases where the comparison doesn't behave as expected. This is because "==" only compare values transformed to the same type, if you also want to compare that the type of the compared data is the same you need to use `===`.
*`"0xAAAA" == "43690" -> True` Strings composed by numbers in dec or hex format can be compare to other numbers/strings with True as result if the numbers were the same (numbers in a string are interpreted as numbers)
*`"0e12334" == "0" --> True` This is very interesting because in some cases you can control the string input of "0" and some content that is being hashed and compared to it. Therefore, if you can provide a value that will create a hash starting with "0e" and without any letter, you could bypass the comparison. You can find **already hashed strings** with this format here: [https://github.com/spaze/hashes](https://github.com/spaze/hashes)
More info in [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
If this function is used for **any authentication check** (like checking the password) and the user controls one side of the comparison, he can send an empty array instead of a string as the value of the password (`https://example.com/login.php/?username=admin&password[]=`) and bypass this check:
Even if `===` is **being used** there could be errors that makes the **comparison vulnerable** to **type juggling**. For example, if the comparison is **converting the data to a different type of object before comparing**:
**`preg_match()`** could be used to **validate user input** (it **checks** if any **word/regex** from a **blacklist** is **present** on the **user input** and if it's not, the code can continue it's execution).
However, when delimiting the start of the regexp`preg_match()` **only checks the first line of the user input**, then if somehow you can **send** the input in **several lines**, you could be able to bypass this check. Example:
If you can send to `preg_match()` a valid very **large input**, it **won't be able to process it** and you will be able to **bypass** the check. For example, if it is blacklisting a JSON you could send:
Trick from: [https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223](https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223) and [https://mizu.re/post/pong](https://mizu.re/post/pong)
In short the problem happens because the `preg_*` functions in PHP builds upon the [PCRE library](http://www.pcre.org/). In PCRE certain regular expressions are matched by using a lot of recursive calls, which uses up a lot of stack space. It is possible to set a limit on the amount of recursions allowed, but in PHP this limit [defaults to 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) which is more than fits in the stack.
[This Stackoverflow thread](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) was also linked in the post where it is talked more in depth about this issue. Our task was now clear:\
**Send an input that would make the regex do 100\_000+ recursions, causing SIGSEGV, making the `preg_match()` function return `false` thus making the application think that our input is not malicious, throwing the surprise at the end of the payload something like `{system(<verybadcommand>)}` to get SSTI --> RCE --> flag :)**.
Well, in regex terms, we're not actually doing 100k "recursions", but instead we're counting "backtracking steps", which as the [PHP documentation](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) states it defaults to 1\_000\_000 (1M) in the `pcre.backtrack_limit` variable.\
To reach that, `'X'*500_001` will result in 1 million backtracking steps (500k forward and 500k backwards):
If PHP is redirecting to another page but no **`die`** or **`exit`** function is **called after the header `Location`** is set, the PHP continues executing and appending the data to the body:
```php
<?php
// In this page the page will be read and the content appended to the body of
* **register\_globals**: In **PHP < 4.1.1.1** or if misconfigured, **register\_globals** may be active (or their behavior is being mimicked). This implies that in global variables like $\_GET if they have a value e.g. $\_GET\["param"]="1234", you can access it via **$param. Therefore, by sending HTTP parameters you can overwrite variables** that are used within the code.
* The **PHPSESSION cookies of the same domain are stored in the same place**, therefore if within a domain **different cookies are used in different paths** you can make that a path **accesses the cookie of the path** setting the value of the other path cookie.\
This way if **both paths access a variable with the same name** you can make the **value of that variable in path1 apply to path2**. And then path2 will take as valid the variables of path1 (by giving the cookie the name that corresponds to it in path2).
* When you have the **usernames** of the users of the machine. Check the address: **/\~\<USERNAME>** to see if the php directories are activated.
* [**LFI and RCE using php wrappers**](../../../pentesting-web/file-inclusion/)
The supported algorithms are: `PASSWORD_DEFAULT` and `PASSWORD_BCRYPT` (starts with `$2y$`). Note that **PASSWORD\_DEFAULT is frequently the same as PASSWORD\_BCRYPT.** And currently, **PASSWORD\_BCRYPT** has a **size limitation in the input of 72bytes**. Therefore, when you try to hash something larger than 72bytes with this algorithm only the first 72B will be used:
If a **PHP page is printing errors and echoing back some input provided by the user**, the user can make the PHP server print back some **content long enough** so when it tries to **add the headers** into the response the server will throw and error.\
In the following scenario the **attacker made the server throw some big errors**, and as you can see in the screen when php tried to **modify the header information, it couldn't** (so for example the CSP header wasn't sent to the user):
This function within php allows you to **execute code that is written in a string** in order to **return true or false** (and depending on this alter the execution). Usually the user variable will be inserted in the middle of a string. For example:\
`assert("strpos($_GET['page']),'..') === false")` --> In this case to get **RCE** you could do:
You will need to **break** the code **syntax**, **add** your **payload**, and then **fix it again**. You can use **logic operations** such as "**and" or "%26%26" or "|"**. Note that "or", "||" doesn't work because if the first condition is true our payload won't get executed. The same way ";" doesn't work as our payload won't be executed.
If you can **upload** a **.htaccess**, then you can **configure** several things and even execute code (configuring that files with extension .htaccess can be **executed**).
If you find a vulnerability that allows you to **modify env variables in PHP** (and another one to upload files, although with more research maybe this can be bypassed), you could abuse this behaviour to get **RCE**.
* [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/#ld\_preload-and-ld\_library\_path): This env variable allows you load arbitrary libraries when executing other binaries (although in this case it might not work).
* **`PHPRC`** : Instructs PHP on **where to locate its configuration file**, usually called `php.ini`. If you can upload your own config file, then, use `PHPRC` to point PHP at it. Add an **`auto_prepend_file`** entry specifying a second uploaded file. This second file contains normal **PHP code, which is then executed** by the PHP runtime before any other code.
1. Upload a PHP file containing our shellcode
2. Upload a second file, containing an **`auto_prepend_file`** directive instructing the PHP preprocessor to execute the file we uploaded in step 1
* Get more info on how to execute this chain [**from the original report**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/).
* If you **cannot upload files**, you could use in FreeBSD the "file" `/dev/fd/0` which contains the **`stdin`**, being the **body** of the request sent to the `stdin`:
If yo are debugging a PHP application you can globally enable error printing in`/etc/php5/apache2/php.ini` adding `display_errors = On` and restart apache : `sudo systemctl restart apache2`
PHP Wrappers ad protocols could allow you to **bypass write and read protections** in a system and compromise it. For [**more information check this page**](../../../pentesting-web/file-inclusion/#lfi-rfi-using-php-wrappers-and-protocols).
If you see that **Xdebug** is **enabled** in a `phpconfig()` output you should try to get RCE via [https://github.com/nqxcode/xdebug-exploit](https://github.com/nqxcode/xdebug-exploit)
So, if you can **execute arbitrary PHP without numbers and letters** you can send a request like the following abusing that payload to execute arbitrary PHP:
```
POST: /action.php?_=system&__=cat+flag.php
Content-Type: application/x-www-form-urlencoded
comando=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);
```
For a more in depth explanation check [https://ctf-wiki.org/web/php/php/#preg\_match](https://ctf-wiki.org/web/php/php/#preg\_match)
lt;>/'^'{{{{'; --> _GET` `${$_}[_](${$_}[__]); --> $_GET[_]($_GET[__])` `So, the function is inside $_GET[_] and the parameter is inside $_GET[__]` http --form POST "http://victim.com/index.php?_=system&__=$CMD" "input=$CODE"
<summary><strong>Learn AWS hacking from zero to hero with</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.